From 64c446cfb794b1a11cd837c55eb4f56b57fd6aea Mon Sep 17 00:00:00 2001 From: Pauan Date: Tue, 13 Sep 2022 22:10:27 -0700 Subject: [PATCH 1/2] Changing batch to use a single flag instead of a counter --- packages/core/src/index.ts | 69 ++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index ea81d20d6..faaf0fc27 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,9 +2,7 @@ let currentSignal: Signal | undefined; let commitError: Error | null = null; -const pending = new Set(); -/** Batch calls can be nested. 0 means that there is no batching */ -let batchPending = 0; +let batchPending: Set | null = null; let oldDeps = new Set(); @@ -71,25 +69,15 @@ export class Signal { if (this._value !== value) { this._value = value; - let isFirst = pending.size === 0; - pending.add(this); - // in batch mode this signal may be marked already - if (this._pending === 0) { - mark(this); - } - // this is the first change, not a computed and we are not - // in batch mode: - if (isFirst && batchPending === 0) { - sweep(pending); - pending.clear(); - if (commitError) { - const err = commitError; - // Clear global error flag for next commit - commitError = null; - throw err; + batch(() => { + batchPending!.add(this); + + // in batch mode this signal may be marked already + if (this._pending === 0) { + mark(this); } - } + }); } } @@ -205,7 +193,10 @@ const tmpPending: Signal[] = []; * we don't have to care about topological sorting. */ function refreshStale(signal: Signal) { - pending.delete(signal); + if (batchPending) { + batchPending.delete(signal); + } + signal._pending = 0; signal._updater(); if (commitError) { @@ -270,20 +261,34 @@ export function effect(callback: () => void) { } export function batch(cb: () => T): T { - batchPending++; - try { + if (batchPending !== null) { return cb(); - } finally { - // Since stale signals are refreshed upwards, we need to - // add pending signals in reverse - let item: Signal | undefined; - while ((item = tmpPending.pop()) !== undefined) { - pending.add(item); - } - if (--batchPending === 0) { + } else { + const pending: Set = new Set(); + + batchPending = pending; + + try { + return cb(); + + } finally { + // Since stale signals are refreshed upwards, we need to + // add pending signals in reverse + let item: Signal | undefined; + while ((item = tmpPending.pop()) !== undefined) { + pending.add(item); + } + + batchPending = null; + sweep(pending); - pending.clear(); + if (commitError) { + const err = commitError; + // Clear global error flag for next commit + commitError = null; + throw err; + } } } } From f2ba3d657bf8169c6ba1d47c0827aa18cfe1c947 Mon Sep 17 00:00:00 2001 From: Marvin Hagemeister Date: Wed, 14 Sep 2022 08:36:18 +0200 Subject: [PATCH 2/2] Add changeset --- .changeset/curvy-moose-shave.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/curvy-moose-shave.md diff --git a/.changeset/curvy-moose-shave.md b/.changeset/curvy-moose-shave.md new file mode 100644 index 000000000..3e6822b03 --- /dev/null +++ b/.changeset/curvy-moose-shave.md @@ -0,0 +1,5 @@ +--- +"@preact/signals-core": patch +--- + +Simplify `batch()` to use a single flag instead of a counter