diff --git a/.changeset/lucky-dolls-yell.md b/.changeset/lucky-dolls-yell.md new file mode 100644 index 0000000000..d158f376d1 --- /dev/null +++ b/.changeset/lucky-dolls-yell.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: rerun derived that had an abort controller on reconnection diff --git a/packages/svelte/src/internal/client/runtime.js b/packages/svelte/src/internal/client/runtime.js index 2ebce07916..4458595d35 100644 --- a/packages/svelte/src/internal/client/runtime.js +++ b/packages/svelte/src/internal/client/runtime.js @@ -413,6 +413,8 @@ function remove_reaction(signal, dependency) { without_reactive_context(() => { /** @type {AbortController} */ (derived.ac).abort(STALE_REACTION); derived.ac = null; + // ensure it reruns right away next time instead of potentially returning a rejected promise as its value + set_signal_status(derived, DIRTY); }); } diff --git a/packages/svelte/tests/runtime-runes/samples/abort-signal-derived-rerun-on-reconnect/_config.js b/packages/svelte/tests/runtime-runes/samples/abort-signal-derived-rerun-on-reconnect/_config.js new file mode 100644 index 0000000000..7caf765e3b --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/abort-signal-derived-rerun-on-reconnect/_config.js @@ -0,0 +1,32 @@ +import { test } from '../../test'; +import { tick } from 'svelte'; + +export default test({ + async test({ assert, target }) { + const [increment, toggle, resolve] = target.querySelectorAll('button'); + const [div] = target.querySelectorAll('div'); + + assert.htmlEqual(div.innerHTML, 'loading'); + resolve.click(); + await tick(); + assert.htmlEqual(div.innerHTML, '0'); + + increment.click(); + await tick(); + assert.htmlEqual(div.innerHTML, 'loading'); + + toggle.click(); + await tick(); + assert.htmlEqual(div.innerHTML, ''); + + toggle.click(); + await tick(); + assert.htmlEqual(div.innerHTML, 'loading'); + + resolve.click(); // this one's for clearing the obsolete/aborted one from the queue + await tick(); + resolve.click(); + await tick(); + assert.htmlEqual(div.innerHTML, '2'); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/abort-signal-derived-rerun-on-reconnect/main.svelte b/packages/svelte/tests/runtime-runes/samples/abort-signal-derived-rerun-on-reconnect/main.svelte new file mode 100644 index 0000000000..a047afdd44 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/abort-signal-derived-rerun-on-reconnect/main.svelte @@ -0,0 +1,32 @@ + + + + + + +
+ {#if show} + {#await double} + loading + {:then value} + {value} + {:catch} + error + {/await} + {/if} +