diff --git a/.changeset/tricky-cooks-help.md b/.changeset/tricky-cooks-help.md new file mode 100644 index 0000000000..f61c7944a1 --- /dev/null +++ b/.changeset/tricky-cooks-help.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: in non-async mode, only push variable to current_sources when active_reaction is updating diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index a881403f58..d86c349445 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -100,7 +100,11 @@ export let current_sources = null; /** @param {Value} value */ export function push_reaction_value(value) { - if (active_reaction !== null && (!async_mode_flag || (active_reaction.f & DERIVED) !== 0)) { + if ( + active_reaction !== null && + ((!async_mode_flag && (active_reaction.f & REACTION_IS_UPDATING) !== 0) || + (active_reaction.f & DERIVED) !== 0) + ) { (current_sources ??= new Set()).add(value); } } diff --git a/packages/svelte/tests/signals/test.ts b/packages/svelte/tests/signals/test.ts index c1ebc3ec75..285dc1b3ce 100644 --- a/packages/svelte/tests/signals/test.ts +++ b/packages/svelte/tests/signals/test.ts @@ -1591,4 +1591,43 @@ describe('signals', () => { assert.equal(s.reactions, null); }; }); + + // https://github.com/sveltejs/svelte/issues/16814 + it('does not treat values created for inactive reactions as current', () => { + push({}, true); + + const trigger = state(false); + const value = state(0); + const log: number[] = []; + let inactive_reaction: Effect; + + const destroy = effect_root(() => { + render_effect(() => { + $.get(trigger); + inactive_reaction = $.active_reaction as Effect; + }); + + render_effect(() => { + $.get(trigger); + + const reaction = $.active_reaction; + $.set_active_reaction(inactive_reaction); + $.push_reaction_value(value); + $.set_active_reaction(reaction); + + log.push($.get(value)); + }); + }); + + try { + flushSync(); + flushSync(() => set(trigger, true)); + flushSync(() => set(value, 1)); + + assert.deepEqual(log, [0, 0, 1]); + } finally { + destroy(); + pop(); + } + }); });