From 1aa3db46416f05b4e94daf71a2b06e89cecf3e3e Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 21 Oct 2025 21:44:57 -0700 Subject: [PATCH] better API --- .../src/internal/client/reactivity/batch.js | 97 +++++++++---------- 1 file changed, 47 insertions(+), 50 deletions(-) diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index ff829cc445..1c1c3a380a 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -850,65 +850,62 @@ export function clear() { /** * @param {() => void} fn - * @returns {Promise<{ commit: () => void, discard: () => void }>} + * @returns {{ commit: () => void, discard: () => void }} */ export function fork(fn) { - /** @type {Promise<{ commit: () => void, discard: () => void }>} */ - const promise = new Promise((fulfil) => { - // TODO does qmt guarantee this will run outside a batch? - // because it needs to - queue_micro_task(async () => { - const batch = Batch.ensure(); - batch.is_fork = true; - - flushSync(fn); - const deferred_inspect_effects = inspect_effects; - - // revert state changes - for (const [source, value] of batch.previous) { - source.v = value; - } + if (current_batch !== null) { + throw new Error('cannot fork here'); // TODO better error + } - await batch.fork_settled(); + const batch = Batch.ensure(); + batch.is_fork = true; - fulfil({ - commit: () => { - if (!batches.has(batch)) { - throw new Error('Cannot commit this batch'); // TODO better error - } + const promise = batch.fork_settled(); - // delete all other forks - for (const b of batches) { - if (b !== batch && b.is_fork) { - batches.delete(b); - } - } + flushSync(fn); + const deferred_inspect_effects = inspect_effects; - for (const [source, value] of batch.current) { - source.v = value; - } + // revert state changes + for (const [source, value] of batch.previous) { + source.v = value; + } - const previous_inspect_effects = inspect_effects; + return { + commit: async () => { + if (!batches.has(batch)) { + throw new Error('Cannot commit this batch'); // TODO better error + } - try { - if (DEV && deferred_inspect_effects.size > 0) { - set_inspect_effects(deferred_inspect_effects); - flush_inspect_effects(); - } + // delete all other forks + for (const b of batches) { + if (b !== batch && b.is_fork) { + batches.delete(b); + } + } - batch.is_fork = false; - batch.activate(); - batch.revive(); - } finally { - set_inspect_effects(previous_inspect_effects); - } - }, - discard: () => { - batches.delete(batch); + await promise; + + for (const [source, value] of batch.current) { + source.v = value; + } + + const previous_inspect_effects = inspect_effects; + + try { + if (DEV && deferred_inspect_effects.size > 0) { + set_inspect_effects(deferred_inspect_effects); + flush_inspect_effects(); } - }); - }); - }); - return promise; + batch.is_fork = false; + batch.activate(); + batch.revive(); + } finally { + set_inspect_effects(previous_inspect_effects); + } + }, + discard: () => { + batches.delete(batch); + } + }; }