diff --git a/force-app/lwc/signals/core.js b/force-app/lwc/signals/core.js index b10b0f4..1be69c4 100644 --- a/force-app/lwc/signals/core.js +++ b/force-app/lwc/signals/core.js @@ -329,4 +329,7 @@ function $resource(fn, source, options) { } }; } -export { $signal, $effect, $computed, $resource }; +function isASignal(anything) { + return !!anything && anything.brand === Symbol.for("lwc-signals"); +} +export { $signal, $effect, $computed, $resource, isASignal }; diff --git a/src/lwc/signals/__tests__/signal-identity.test.ts b/src/lwc/signals/__tests__/signal-identity.test.ts new file mode 100644 index 0000000..639dc71 --- /dev/null +++ b/src/lwc/signals/__tests__/signal-identity.test.ts @@ -0,0 +1,38 @@ +import { $signal, isASignal } from "../core"; + +describe("isASignal", () => { + test("checks that a value is a signal", () => { + const signal = $signal(0); + expect(isASignal(signal)).toBe(true); + }); + + test("checks that a computed is a signal", () => { + const signal = $signal(0); + const computed = $signal(() => signal.value); + expect(isASignal(computed)).toBe(true); + }); + + test("checks that a value is not a signal", () => { + expect(isASignal(0)).toBe(false); + }); + + test("checks that a function is not a signal", () => { + expect(isASignal(() => {})).toBe(false); + }); + + test("checks that an object is not a signal", () => { + expect(isASignal({})).toBe(false); + }); + + test("checks that an array is not a signal", () => { + expect(isASignal([])).toBe(false); + }); + + test("checks that undefined is not a signal", () => { + expect(isASignal(undefined)).toBe(false); + }); + + test("checks that null is not a signal", () => { + expect(isASignal(null)).toBe(false); + }); +}); diff --git a/src/lwc/signals/core.ts b/src/lwc/signals/core.ts index 96e3b1e..9fa1aef 100644 --- a/src/lwc/signals/core.ts +++ b/src/lwc/signals/core.ts @@ -534,4 +534,8 @@ function $resource( }; } -export { $signal, $effect, $computed, $resource }; +function isASignal(anything: unknown): anything is Signal { + return !!anything && (anything as Signal).brand === Symbol.for("lwc-signals"); +} + +export { $signal, $effect, $computed, $resource, isASignal };