Skip to content

Commit 9309a1a

Browse files
committed
fix: preserve SSR context when block expressions contain await
1 parent b7db8b3 commit 9309a1a

File tree

8 files changed

+50
-5
lines changed

8 files changed

+50
-5
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: preserve SSR context when block expressions contain `await`

packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/** @import { AwaitExpression, Expression } from 'estree' */
22
/** @import { Context } from '../types' */
33
import { save } from '../../../../utils/ast.js';
4-
import * as b from '../../../../utils/builders.js';
54

65
/**
76
* @param {AwaitExpression} node
@@ -14,5 +13,28 @@ export function AwaitExpression(node, context) {
1413
return save(argument);
1514
}
1615

16+
// we also need to restore context after block expressions
17+
let i = context.path.length;
18+
while (i--) {
19+
const parent = context.path[i];
20+
21+
if (
22+
parent.type === 'ArrowFunctionExpression' ||
23+
parent.type === 'FunctionExpression' ||
24+
parent.type === 'FunctionDeclaration'
25+
) {
26+
break;
27+
}
28+
29+
// @ts-ignore
30+
if (parent.metadata) {
31+
if (parent.type !== 'ExpressionTag' && parent.type !== 'Fragment') {
32+
return save(argument);
33+
}
34+
35+
break;
36+
}
37+
}
38+
1739
return argument === node.argument ? node : { ...node, argument };
1840
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { test } from '../../test';
2+
3+
export default test({
4+
mode: ['async-server'],
5+
6+
compileOptions: {
7+
// include `push_element` calls, so that we can check they
8+
// run with the correct ssr_context
9+
dev: true
10+
},
11+
12+
html: `
13+
<h1>hello!</h1>
14+
`
15+
});
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{#if await true}
2+
<h1>hello!</h1>
3+
{/if}

packages/svelte/tests/snapshot/samples/async-each-fallback-hoisting/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as $ from 'svelte/internal/server';
33

44
export default function Async_each_fallback_hoisting( $$renderer) {
55
$$renderer.child(async ( $$renderer) => {
6-
const each_array = $.ensure_array_like(await Promise.resolve([]));
6+
const each_array = $.ensure_array_like((await $.save(Promise.resolve([])))());
77

88
if (each_array.length !== 0) {
99
$$renderer.push('<!--[-->');

packages/svelte/tests/snapshot/samples/async-each-hoisting/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default function Async_each_hoisting( $$renderer) {
99
$$renderer.push(`<!--[-->`);
1010

1111
$$renderer.child(async ( $$renderer) => {
12-
const each_array = $.ensure_array_like(await Promise.resolve([first, second, third]));
12+
const each_array = $.ensure_array_like((await $.save(Promise.resolve([first, second, third])))());
1313

1414
for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1515
let item = each_array[$$index];

packages/svelte/tests/snapshot/samples/async-if-alternate-hoisting/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as $ from 'svelte/internal/server';
33

44
export default function Async_if_alternate_hoisting( $$renderer) {
55
$$renderer.child(async ( $$renderer) => {
6-
if (await Promise.resolve(false)) {
6+
if ((await $.save(Promise.resolve(false)))()) {
77
$$renderer.push('<!--[-->');
88
$$renderer.push(async () => $.escape(await Promise.reject('no no no')));
99
} else {

packages/svelte/tests/snapshot/samples/async-if-hoisting/_expected/server/index.svelte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as $ from 'svelte/internal/server';
33

44
export default function Async_if_hoisting( $$renderer) {
55
$$renderer.child(async ( $$renderer) => {
6-
if (await Promise.resolve(true)) {
6+
if ((await $.save(Promise.resolve(true)))()) {
77
$$renderer.push('<!--[-->');
88
$$renderer.push(async () => $.escape(await Promise.resolve('yes yes yes')));
99
} else {

0 commit comments

Comments
 (0)