diff --git a/.changeset/silent-pigs-relax.md b/.changeset/silent-pigs-relax.md new file mode 100644 index 0000000000..5acf185ffe --- /dev/null +++ b/.changeset/silent-pigs-relax.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: restore batch along with effect context diff --git a/packages/svelte/src/internal/client/reactivity/async.js b/packages/svelte/src/internal/client/reactivity/async.js index 1ea1bbe561..65d004137f 100644 --- a/packages/svelte/src/internal/client/reactivity/async.js +++ b/packages/svelte/src/internal/client/reactivity/async.js @@ -73,11 +73,13 @@ function capture() { var previous_effect = active_effect; var previous_reaction = active_reaction; var previous_component_context = component_context; + var previous_batch = current_batch; return function restore() { set_active_effect(previous_effect); set_active_reaction(previous_reaction); set_component_context(previous_component_context); + previous_batch?.activate(); if (DEV) { set_from_async_derived(null); @@ -176,8 +178,8 @@ export function unset_context() { * @param {() => Promise} fn */ export async function async_body(fn) { - const unsuspend = suspend(); - const active = /** @type {Effect} */ (active_effect); + var unsuspend = suspend(); + var active = /** @type {Effect} */ (active_effect); try { await fn(); diff --git a/packages/svelte/src/internal/client/reactivity/batch.js b/packages/svelte/src/internal/client/reactivity/batch.js index 60fa03c56c..2c60fc8313 100644 --- a/packages/svelte/src/internal/client/reactivity/batch.js +++ b/packages/svelte/src/internal/client/reactivity/batch.js @@ -76,8 +76,8 @@ let queued_root_effects = []; let last_scheduled_effect = null; let is_flushing = false; - let is_flushing_sync = false; + export class Batch { /** * The current values of any sources that are updated in this batch @@ -678,6 +678,8 @@ export function suspend() { if (!pending) { batch.activate(); batch.decrement(); + } else { + batch.deactivate(); } unset_context(); diff --git a/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/Bar.svelte b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/Bar.svelte new file mode 100644 index 0000000000..f1ac9ab760 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/Bar.svelte @@ -0,0 +1,7 @@ + + +

bar: {bar}

diff --git a/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/Foo.svelte b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/Foo.svelte new file mode 100644 index 0000000000..e2029a3033 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/Foo.svelte @@ -0,0 +1,10 @@ + + +

foo: {foo}

+ + diff --git a/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/_config.js b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/_config.js new file mode 100644 index 0000000000..ca7965bf79 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/_config.js @@ -0,0 +1,42 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const [show, resolve] = target.querySelectorAll('button'); + + show.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + +

pending...

+ ` + ); + + resolve.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + +

pending...

+ ` + ); + + resolve.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + +

foo: foo

+

bar: bar

+ ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/main.svelte new file mode 100644 index 0000000000..bd0efaa4f8 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-nested-top-level/main.svelte @@ -0,0 +1,31 @@ + + + + + + + + + + {#if show} + + {/if} + + {#if $effect.pending()} +

pending...

+ {/if} + + {#snippet pending()} +

initializing...

+ {/snippet} +
diff --git a/packages/svelte/tests/runtime-runes/samples/async-redirect/_config.js b/packages/svelte/tests/runtime-runes/samples/async-redirect/_config.js index ebbe642860..fe92977c21 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-redirect/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/async-redirect/_config.js @@ -29,6 +29,7 @@ export default test({

c

+

b or c

` ); @@ -46,6 +47,7 @@ export default test({

b

+

b or c

` ); } diff --git a/packages/svelte/tests/runtime-runes/samples/async-redirect/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-redirect/main.svelte index bf5fdf9ed3..aead1b00e5 100644 --- a/packages/svelte/tests/runtime-runes/samples/async-redirect/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/async-redirect/main.svelte @@ -33,6 +33,10 @@

c

{/if} + {#if route === 'b' || route === 'c'} +

b or c

+ {/if} + {#snippet pending()}

pending...

{/snippet} diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/Foo.svelte b/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/Foo.svelte new file mode 100644 index 0000000000..e8a7c84137 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/Foo.svelte @@ -0,0 +1,8 @@ + + +

{foo} {bar}

diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/_config.js b/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/_config.js new file mode 100644 index 0000000000..2c7ffd3952 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/_config.js @@ -0,0 +1,41 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const [show, resolve] = target.querySelectorAll('button'); + + show.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + +

pending...

+ ` + ); + + resolve.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + +

pending...

+ ` + ); + + resolve.click(); + await tick(); + assert.htmlEqual( + target.innerHTML, + ` + + +

foo bar

+ ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/main.svelte new file mode 100644 index 0000000000..bd0efaa4f8 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-top-level-deriveds/main.svelte @@ -0,0 +1,31 @@ + + + + + + + + + + {#if show} + + {/if} + + {#if $effect.pending()} +

pending...

+ {/if} + + {#snippet pending()} +

initializing...

+ {/snippet} +