diff --git a/.changeset/silent-rings-yell.md b/.changeset/silent-rings-yell.md new file mode 100644 index 0000000000..0b417103f7 --- /dev/null +++ b/.changeset/silent-rings-yell.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't reset status of uninitialized deriveds diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 906d68fbf0..d9578142eb 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -399,7 +399,14 @@ function remove_reaction(signal, dependency) { derived.f &= ~WAS_MARKED; } - update_derived_status(derived); + // In a fork it's possible that a derived is executed and gets reactions, then commits, but is + // never re-executed. This is possible when the derived is only executed once in the context + // of a new branch which happens before fork.commit() runs. In this case, the derived still has + // UNINITIALIZED as its value, and then when it's loosing its reactions we need to ensure it stays + // DIRTY so it is reexecuted once someone wants its value again. + if (derived.v !== UNINITIALIZED) { + update_derived_status(derived); + } // freeze any effects inside this derived freeze_derived_effects(derived); diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-if-derived/_config.js b/packages/svelte/tests/runtime-runes/samples/async-fork-if-derived/_config.js new file mode 100644 index 0000000000..4a03a54e7a --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-if-derived/_config.js @@ -0,0 +1,20 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const [, toggle] = target.querySelectorAll('button'); + + toggle?.click(); + await tick(); + assert.htmlEqual(target.innerHTML, ` 0`); + + toggle?.click(); + await tick(); + assert.htmlEqual(target.innerHTML, ` `); + + toggle?.click(); + await tick(); + assert.htmlEqual(target.innerHTML, ` 0`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-fork-if-derived/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-fork-if-derived/main.svelte new file mode 100644 index 0000000000..519857a9ce --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-fork-if-derived/main.svelte @@ -0,0 +1,13 @@ + + + + + +{#if show} + {d_count} +{/if}