From bd0256fe907c789af97c65790639de9cf513fe8d Mon Sep 17 00:00:00 2001 From: Issam Mani Date: Wed, 24 Apr 2024 04:09:16 +0200 Subject: [PATCH 1/2] fix: do not watch duplicated signals --- packages/signal-polyfill/src/wrapper.spec.ts | 14 ++++++++++++++ packages/signal-polyfill/src/wrapper.ts | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) 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..b500b57 100644 --- a/packages/signal-polyfill/src/wrapper.ts +++ b/packages/signal-polyfill/src/wrapper.ts @@ -234,10 +234,16 @@ 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); + + const producerNodeSet = new Set(node.producerNode); for (const signal of signals) { - producerAccessed(signal[NODE]); + if(!producerNodeSet.has(signal[NODE])) { + producerAccessed(signal[NODE]); + } } setActiveConsumer(prev); } From 0684e8a5315cd781822bff64a4cdbe38cbfdaf22 Mon Sep 17 00:00:00 2001 From: Issam Mani Date: Thu, 25 Apr 2024 17:01:26 +0200 Subject: [PATCH 2/2] fix: use array.includes instead of creating a set --- packages/signal-polyfill/src/wrapper.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/signal-polyfill/src/wrapper.ts b/packages/signal-polyfill/src/wrapper.ts index b500b57..99cdb28 100644 --- a/packages/signal-polyfill/src/wrapper.ts +++ b/packages/signal-polyfill/src/wrapper.ts @@ -239,9 +239,8 @@ export namespace subtle { node.dirty = false; // Give the watcher a chance to trigger again const prev = setActiveConsumer(node); - const producerNodeSet = new Set(node.producerNode); for (const signal of signals) { - if(!producerNodeSet.has(signal[NODE])) { + if(!node.producerNode.includes(signal[NODE])) { producerAccessed(signal[NODE]); } }