diff --git a/.changeset/happy-plums-greet.md b/.changeset/happy-plums-greet.md new file mode 100644 index 0000000000..695fbff8fd --- /dev/null +++ b/.changeset/happy-plums-greet.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure disconnected deriveds correctly connect again diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index c5223a6ae4..0be91d78ba 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -207,7 +207,9 @@ export function check_dirtiness(reaction) { for (i = 0; i < length; i++) { dependency = dependencies[i]; - if (!dependency?.reactions?.includes(reaction)) { + // We always re-add all reactions (even duplicates) if the derived was + // previously disconnected + if (is_disconnected || !dependency?.reactions?.includes(reaction)) { (dependency.reactions ??= []).push(reaction); } } diff --git a/packages/svelte/tests/runtime-runes/samples/derived-disconnect/_config.js b/packages/svelte/tests/runtime-runes/samples/derived-disconnect/_config.js new file mode 100644 index 0000000000..76e60b7402 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-disconnect/_config.js @@ -0,0 +1,96 @@ +import { flushSync } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target, logs }) { + let [b1, b2, b3, b4, b5] = target.querySelectorAll('button'); + + b1?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 1
+
Name: a

+
` + ); + + b2?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 2
+
Name: b

+
` + ); + + b3?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 3
+
Name: c

+
` + ); + + b4?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 4
+
Name: d

+
` + ); + + b5?.click(); + flushSync(); + + b5?.click(); + flushSync(); + + [b1, b2, b3, b4, b5] = target.querySelectorAll('button'); + + b1?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 1
+
Name: a

+
` + ); + + b2?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 2
+
Name: b

+
` + ); + + b3?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 3
+
Name: c

+
` + ); + + b4?.click(); + flushSync(); + + assert.htmlEqual( + target.innerHTML, + `
Current ID: 4
+
Name: d

+
` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/derived-disconnect/main.svelte b/packages/svelte/tests/runtime-runes/samples/derived-disconnect/main.svelte new file mode 100644 index 0000000000..8cb6ed2afd --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/derived-disconnect/main.svelte @@ -0,0 +1,23 @@ + + +
+ {#if visible} +
Current ID: {currentId}
+
Name: {currentItem.name}
+ {#each items as item} +
+ {/each} + {/if} +
+
+