diff --git a/packages/signal-polyfill/src/wrapper.spec.ts b/packages/signal-polyfill/src/wrapper.spec.ts index 1b50ef8..be08e95 100644 --- a/packages/signal-polyfill/src/wrapper.spec.ts +++ b/packages/signal-polyfill/src/wrapper.spec.ts @@ -225,6 +225,20 @@ describe("Watcher", () => { signal.set(1); expect(mockGetPending).toBeCalled(); }); + + it("does not store duplicated watchers for the same signal", () => { + const watcher = new Signal.subtle.Watcher(() => {}); + const signal = new Signal.State(0); + const computed = new Signal.Computed(() => signal.get() + 1); + watcher.watch(signal); + watcher.watch(signal); + watcher.watch(computed); + watcher.watch(computed); + watcher.watch(computed); + expect(Signal.subtle.introspectSources(watcher).length).toBe(2); + expect(Signal.subtle.introspectSources(watcher)[0]).toBe(signal); + expect(Signal.subtle.introspectSources(watcher)[1]).toBe(computed); + }); }); describe("Expected class shape", () => { diff --git a/packages/signal-polyfill/src/wrapper.ts b/packages/signal-polyfill/src/wrapper.ts index a8eab3d..99cdb28 100644 --- a/packages/signal-polyfill/src/wrapper.ts +++ b/packages/signal-polyfill/src/wrapper.ts @@ -234,10 +234,15 @@ export namespace subtle { this.#assertSignals(signals); const node = this[NODE]; + assertConsumerNode(node); + node.dirty = false; // Give the watcher a chance to trigger again const prev = setActiveConsumer(node); + for (const signal of signals) { - producerAccessed(signal[NODE]); + if(!node.producerNode.includes(signal[NODE])) { + producerAccessed(signal[NODE]); + } } setActiveConsumer(prev); }