Skip to content

Commit 456c8c4

Browse files
committed
fix: check boundary pending attribute at runtime on server
1 parent bb33c55 commit 456c8c4

File tree

5 files changed

+60
-14
lines changed

5 files changed

+60
-14
lines changed

.changeset/lazy-cooks-return.md

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: check boundary `pending` attribute at runtime on server

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

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22
/** @import { AST } from '#compiler' */
33
/** @import { ComponentContext } from '../types' */
44
import * as b from '#compiler/builders';
5-
import { block_close, block_open, block_open_else, build_attribute_value } from './shared/utils.js';
5+
import {
6+
block_close,
7+
block_open,
8+
block_open_else,
9+
build_attribute_value,
10+
build_template
11+
} from './shared/utils.js';
612

713
/**
814
* @param {AST.SvelteBoundary} node
@@ -13,6 +19,11 @@ export function SvelteBoundary(node, context) {
1319
const pending_attribute = /** @type {AST.Attribute} */ (
1420
node.attributes.find((node) => node.type === 'Attribute' && node.name === 'pending')
1521
);
22+
const is_pending_attr_nullish =
23+
pending_attribute &&
24+
typeof pending_attribute.value === 'object' &&
25+
!Array.isArray(pending_attribute.value) &&
26+
!context.state.scope.evaluate(pending_attribute.value.expression).is_defined;
1627

1728
const pending_snippet = /** @type {AST.SnippetBlock} */ (
1829
node.fragment.nodes.find(
@@ -21,20 +32,38 @@ export function SvelteBoundary(node, context) {
2132
);
2233

2334
if (pending_attribute || pending_snippet) {
24-
const pending = pending_attribute
25-
? b.call(
26-
build_attribute_value(
27-
pending_attribute.value,
28-
context,
29-
(expression) => expression,
30-
false,
31-
true
32-
),
33-
b.id('$$renderer')
35+
if (pending_attribute && is_pending_attr_nullish && !pending_snippet) {
36+
const callee = build_attribute_value(
37+
pending_attribute.value,
38+
context,
39+
(expression) => expression,
40+
false,
41+
true
42+
);
43+
const pending = b.call(callee, b.id('$$renderer'));
44+
const block = /** @type {BlockStatement} */ (context.visit(node.fragment));
45+
context.state.template.push(
46+
b.if(
47+
callee,
48+
b.block(build_template([block_open_else, pending, block_close])),
49+
b.block(build_template([block_open, block, block_close]))
3450
)
35-
: /** @type {BlockStatement} */ (context.visit(pending_snippet.body));
36-
37-
context.state.template.push(block_open_else, pending, block_close);
51+
);
52+
} else {
53+
const pending = pending_attribute
54+
? b.call(
55+
build_attribute_value(
56+
pending_attribute.value,
57+
context,
58+
(expression) => expression,
59+
false,
60+
true
61+
),
62+
b.id('$$renderer')
63+
)
64+
: /** @type {BlockStatement} */ (context.visit(pending_snippet.body));
65+
context.state.template.push(block_open_else, pending, block_close);
66+
}
3867
} else {
3968
const block = /** @type {BlockStatement} */ (context.visit(node.fragment));
4069
context.state.template.push(block_open, block, block_close);

packages/svelte/src/compiler/phases/scope.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,11 @@ class Evaluation {
260260
break;
261261
}
262262

263+
if (binding.initial?.type === 'SnippetBlock') {
264+
this.is_defined = true;
265+
break;
266+
}
267+
263268
if (!binding.updated && binding.initial !== null && !is_prop) {
264269
binding.scope.evaluate(/** @type {Expression} */ (binding.initial), this.values);
265270
break;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!--[--><!--[--><!---->awaited<!--]--><!--]-->
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
let pending = null;
3+
</script>
4+
<svelte:boundary {pending}>
5+
{await 'awaited'}
6+
</svelte:boundary>

0 commit comments

Comments
 (0)