From d776e522d2b960195d35b5ff0cbaf9ec60915702 Mon Sep 17 00:00:00 2001 From: Simon H <5968653+dummdidumm@users.noreply.github.com> Date: Sun, 1 Sep 2024 20:57:17 +0200 Subject: [PATCH] fix: ensure reactive graph is fully traversed in the marking phase for non-runes mode (#13059) * fix: ensure signal status is set in legacy mode fixes #13051 * add (failing) test * alternative fix * add changeset * alternative fix * add comment --------- Co-authored-by: Rich Harris Co-authored-by: Dominic Gannaway --- .changeset/angry-weeks-design.md | 5 +++++ .../src/internal/client/reactivity/effects.js | 9 ++++++++- .../Child.svelte | 15 +++++++++++++++ .../_config.js | 18 ++++++++++++++++++ .../main.svelte | 8 ++++++++ .../state.js | 3 +++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 .changeset/angry-weeks-design.md create mode 100644 packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/Child.svelte create mode 100644 packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/_config.js create mode 100644 packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/main.svelte create mode 100644 packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/state.js diff --git a/.changeset/angry-weeks-design.md b/.changeset/angry-weeks-design.md new file mode 100644 index 000000000000..897f2e2192e0 --- /dev/null +++ b/.changeset/angry-weeks-design.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure reactive graph is fully traversed in the marking phase for non-runes mode diff --git a/packages/svelte/src/internal/client/reactivity/effects.js b/packages/svelte/src/internal/client/reactivity/effects.js index e0d97beaf244..585800d148de 100644 --- a/packages/svelte/src/internal/client/reactivity/effects.js +++ b/packages/svelte/src/internal/client/reactivity/effects.js @@ -33,7 +33,8 @@ import { UNOWNED, CLEAN, INSPECT_EFFECT, - HEAD_EFFECT + HEAD_EFFECT, + MAYBE_DIRTY } from '../constants.js'; import { set } from './sources.js'; import * as e from '../errors.js'; @@ -281,6 +282,12 @@ export function legacy_pre_effect_reset() { for (var token of context.l.r1) { var effect = token.effect; + // If the effect is CLEAN, then make it MAYBE_DIRTY. This ensures we traverse through + // the effects dependencies and correctly ensure each dependency is up-to-date. + if ((effect.f & CLEAN) !== 0) { + set_signal_status(effect, MAYBE_DIRTY); + } + if (check_dirtiness(effect)) { update_effect(effect); } diff --git a/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/Child.svelte b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/Child.svelte new file mode 100644 index 000000000000..58ec0f651639 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/Child.svelte @@ -0,0 +1,15 @@ + + +

{$copy}

diff --git a/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/_config.js b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/_config.js new file mode 100644 index 000000000000..7db95248aaa6 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/_config.js @@ -0,0 +1,18 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; +import { store } from './state.js'; + +export default test({ + html: '

0

', + + before_test() { + store.set({ value: 0 }); + }, + + async test({ assert, target }) { + const button = target.querySelector('button'); + flushSync(() => button?.click()); + + assert.htmlEqual(target.innerHTML, '

1

'); + } +}); diff --git a/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/main.svelte b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/main.svelte new file mode 100644 index 000000000000..1d7a9d6e8f60 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/main.svelte @@ -0,0 +1,8 @@ + + + + + diff --git a/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/state.js b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/state.js new file mode 100644 index 000000000000..030378b5e7d0 --- /dev/null +++ b/packages/svelte/tests/runtime-legacy/samples/store-updated-in-reactive-statement/state.js @@ -0,0 +1,3 @@ +import { writable } from 'svelte/store'; + +export const store = writable({ value: 0 });