From a7c16935a511ea701cf571a312cdb21900ad14c0 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Fri, 18 Sep 2026 13:31:42 +0200 Subject: [PATCH] equality check against what the batch sees to update its value --- .../internal/client/reactivity/deriveds.js | 6 ++++++ .../src/internal/client/reactivity/sources.js | 9 ++++++++- .../samples/async-fork-write-back/_config.js | 17 ++++++++++++++++ .../samples/async-fork-write-back/main.svelte | 20 +++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/svelte/tests/runtime-runes/samples/async-fork-write-back/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/async-fork-write-back/main.svelte diff --git a/packages/svelte/src/internal/client/reactivity/deriveds.js b/packages/svelte/src/internal/client/reactivity/deriveds.js index 8fe8951a98..56bc0895f9 100644 --- a/packages/svelte/src/internal/client/reactivity/deriveds.js +++ b/packages/svelte/src/internal/client/reactivity/deriveds.js @@ -443,6 +443,12 @@ export function update_derived(derived) { return; } } + } else if ( + batch_values?.has(derived) && + !derived.equals(/** @type {any[]} */ (batch_values?.get(derived))[0]) + ) { + current_batch?.capture(derived, derived.v); + // TODO also bump wv_values? } // don't mark derived clean if we're reading it inside a diff --git a/packages/svelte/src/internal/client/reactivity/sources.js b/packages/svelte/src/internal/client/reactivity/sources.js index ed8f1a146f..5c65f9ba0d 100644 --- a/packages/svelte/src/internal/client/reactivity/sources.js +++ b/packages/svelte/src/internal/client/reactivity/sources.js @@ -37,7 +37,8 @@ import { batch_values, eager_block_effects, schedule_effect, - legacy_updates + legacy_updates, + current_batch } from './batch.js'; import { proxy } from '../proxy.js'; import { execute_derived } from './deriveds.js'; @@ -272,6 +273,12 @@ export function internal_set(source, value, updated_during_traversal = null) { if (!batch.is_fork && eager_effects.size > 0 && !eager_effects_deferred) { flush_eager_effects(); } + } else if ( + batch_values?.has(source) && + !source.equals(/** @type {any[]} */ (batch_values?.get(source))[0]) + ) { + current_batch?.capture(source, source.v); + // TODO also bump wv_values? } return value; diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-write-back/_config.js b/packages/svelte/tests/runtime-runes/samples/async-fork-write-back/_config.js new file mode 100644 index 0000000000..3d96cb58e6 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-write-back/_config.js @@ -0,0 +1,17 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const [create, commit] = target.querySelectorAll('button'); + const [p] = target.querySelectorAll('p'); + + create.click(); + await tick(); + assert.htmlEqual(p.innerHTML, '0:0'); + + commit.click(); + await tick(); + assert.htmlEqual(p.innerHTML, '0:0'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-write-back/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-fork-write-back/main.svelte new file mode 100644 index 0000000000..2d424c95aa --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-write-back/main.svelte @@ -0,0 +1,20 @@ + + + + + + +

{source}:{writable}