diff --git a/.changeset/proud-poems-brake.md b/.changeset/proud-poems-brake.md new file mode 100644 index 0000000000..3f4e076e22 --- /dev/null +++ b/.changeset/proud-poems-brake.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: correctly set `is_updating` before flushing root effects diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 486c819f36..9f721f9ec4 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -644,8 +644,11 @@ function infinite_loop_guard() { } function flush_queued_root_effects() { + var was_updating_effect = is_updating_effect; + try { var flush_count = 0; + is_updating_effect = true; while (queued_root_effects.length > 0) { if (flush_count++ > 1000) { @@ -670,6 +673,7 @@ function flush_queued_root_effects() { } } finally { is_flushing = false; + is_updating_effect = was_updating_effect; last_scheduled_effect = null; if (DEV) { diff --git a/packages/svelte/tests/signals/test.ts b/packages/svelte/tests/signals/test.ts index 046f833e0e..ef4cf16d3b 100644 --- a/packages/svelte/tests/signals/test.ts +++ b/packages/svelte/tests/signals/test.ts @@ -1135,4 +1135,45 @@ describe('signals', () => { destroy(); }; }); + + test('unowned deriveds correctly update', () => { + const log: any[] = []; + + return () => { + const a = state(0); + const b = state(0); + const c = derived(() => { + return $.get(a); + }); + const d = derived(() => { + return $.get(b); + }); + + const destroy = effect_root(() => { + const e = derived(() => { + return $.get(c) === 1 && $.get(d) === 1; + }); + render_effect(() => { + log.push($.get(e)); + }); + }); + + assert.deepEqual(log, [false]); + + set(a, 1); + set(b, 1); + + flushSync(); + + assert.deepEqual(log, [false, true]); + + set(b, 9); + + flushSync(); + + assert.deepEqual(log, [false, true, false]); + + destroy(); + }; + }); });