diff --git a/.changeset/rich-garlics-laugh.md b/.changeset/rich-garlics-laugh.md new file mode 100644 index 0000000000..c9230dfb80 --- /dev/null +++ b/.changeset/rich-garlics-laugh.md @@ -0,0 +1,5 @@ +--- +"svelte": patch +--- + +fix: improve handled of unowned derived signals diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 28428c1fb7..c1b8ee3e44 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -194,9 +194,21 @@ export function check_dirtiness(reaction) { // is also dirty. var version = dependency.version; - if (is_unowned && version > /** @type {import('#client').Derived} */ (reaction).version) { - /** @type {import('#client').Derived} */ (reaction).version = version; - return true; + if (is_unowned) { + if (version > /** @type {import('#client').Derived} */ (reaction).version) { + /** @type {import('#client').Derived} */ (reaction).version = version; + return true; + } else if (!current_skip_reaction && !dependency?.reactions?.includes(reaction)) { + // If we are working with an unowned signal as part of an effect (due to !current_skip_reaction) + // and the version hasn't changed, we still need to check that this reaction + // if linked to the dependency source – otherwise future updates will not be caught. + var reactions = dependency.reactions; + if (reactions === null) { + dependency.reactions = [reaction]; + } else { + reactions.push(reaction); + } + } } } } diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-5/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-unowned-5/_config.js new file mode 100644 index 0000000000..20c3cc112e --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-5/_config.js @@ -0,0 +1,12 @@ +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + // The test has a bunch of queueMicrotasks + await Promise.resolve(); + await Promise.resolve(); + await Promise.resolve(); + + assert.htmlEqual(target.innerHTML, `
Zeeba Neighba
`); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-unowned-5/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-unowned-5/main.svelte new file mode 100644 index 0000000000..3889869461 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-unowned-5/main.svelte @@ -0,0 +1,34 @@ + + + + +
{model.thing?.name}