diff --git a/.changeset/tough-pans-boil.md b/.changeset/tough-pans-boil.md new file mode 100644 index 0000000000..33c8dd8393 --- /dev/null +++ b/.changeset/tough-pans-boil.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: ensure await block scope transforms are isolated diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js index 62c61151bb..146f75d405 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/AwaitBlock.js @@ -18,27 +18,34 @@ export function AwaitBlock(node, context) { let catch_block; if (node.then) { - const argument = node.value && create_derived_block_argument(node.value, context); + const then_context = { + ...context, + state: { ...context.state, transform: { ...context.state.transform } } + }; + const argument = node.value && create_derived_block_argument(node.value, then_context); /** @type {Pattern[]} */ const args = [b.id('$$anchor')]; if (argument) args.push(argument.id); const declarations = argument?.declarations ?? []; - const block = /** @type {BlockStatement} */ (context.visit(node.then)); + const block = /** @type {BlockStatement} */ (then_context.visit(node.then, then_context.state)); then_block = b.arrow(args, b.block([...declarations, ...block.body])); } if (node.catch) { - const argument = node.error && create_derived_block_argument(node.error, context); + const catch_context = { ...context, state: { ...context.state } }; + const argument = node.error && create_derived_block_argument(node.error, catch_context); /** @type {Pattern[]} */ const args = [b.id('$$anchor')]; if (argument) args.push(argument.id); const declarations = argument?.declarations ?? []; - const block = /** @type {BlockStatement} */ (context.visit(node.catch)); + const block = /** @type {BlockStatement} */ ( + catch_context.visit(node.catch, catch_context.state) + ); catch_block = b.arrow(args, b.block([...declarations, ...block.body])); } diff --git a/packages/svelte/tests/migrate/samples/self-closing-elements/output.svelte b/packages/svelte/tests/migrate/samples/self-closing-elements/output.svelte index 6aee688bb8..6dc21840d1 100644 --- a/packages/svelte/tests/migrate/samples/self-closing-elements/output.svelte +++ b/packages/svelte/tests/migrate/samples/self-closing-elements/output.svelte @@ -2,4 +2,4 @@

- + \ No newline at end of file diff --git a/packages/svelte/tests/migrate/samples/svelte-self-name-conflict/output.svelte b/packages/svelte/tests/migrate/samples/svelte-self-name-conflict/output.svelte index 50f7e42112..7be4cf0d13 100644 --- a/packages/svelte/tests/migrate/samples/svelte-self-name-conflict/output.svelte +++ b/packages/svelte/tests/migrate/samples/svelte-self-name-conflict/output.svelte @@ -19,4 +19,4 @@ child -{/if} +{/if} \ No newline at end of file diff --git a/packages/svelte/tests/migrate/samples/svelte-self/output.svelte b/packages/svelte/tests/migrate/samples/svelte-self/output.svelte index 8a01edce69..30b65b7775 100644 --- a/packages/svelte/tests/migrate/samples/svelte-self/output.svelte +++ b/packages/svelte/tests/migrate/samples/svelte-self/output.svelte @@ -18,4 +18,4 @@ child -{/if} +{/if} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client/index.svelte.js b/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client/index.svelte.js new file mode 100644 index 0000000000..87fce120fd --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client/index.svelte.js @@ -0,0 +1,36 @@ +import "svelte/internal/disclose-version"; +import * as $ from "svelte/internal/client"; + +function increment(_, counter) { + counter.count += 1; +} + +var root = $.template(` `, 1); + +export default function Await_block_scope($$anchor) { + let counter = $.proxy({ count: 0 }); + const promise = $.derived(() => Promise.resolve(counter)); + var fragment = root(); + var button = $.first_child(fragment); + + button.__click = [increment, counter]; + + var text = $.child(button); + + $.reset(button); + + var node = $.sibling(button, 2); + + $.await(node, () => $.get(promise), null, ($$anchor, counter) => {}); + + var text_1 = $.sibling(node); + + $.template_effect(() => { + $.set_text(text, `clicks: ${counter.count ?? ""}`); + $.set_text(text_1, ` ${counter.count ?? ""}`); + }); + + $.append($$anchor, fragment); +} + +$.delegate(["click"]); \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/server/index.svelte.js new file mode 100644 index 0000000000..44c68a7c96 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/server/index.svelte.js @@ -0,0 +1,14 @@ +import * as $ from "svelte/internal/server"; + +export default function Await_block_scope($$payload) { + let counter = { count: 0 }; + const promise = Promise.resolve(counter); + + function increment() { + counter.count += 1; + } + + $$payload.out += ` `; + $.await(promise, () => {}, (counter) => {}, () => {}); + $$payload.out += ` ${$.escape(counter.count)}`; +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/await-block-scope/index.svelte b/packages/svelte/tests/snapshot/samples/await-block-scope/index.svelte new file mode 100644 index 0000000000..3dc6c66262 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/await-block-scope/index.svelte @@ -0,0 +1,16 @@ + + + + +{#await promise then counter}{/await} + +{counter.count}