From 3cd4ccdd99ebdd7068cf5b09684a5c8604571c4c Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 14 Sep 2025 12:53:35 -0400 Subject: [PATCH 1/6] chore: remove hoisted_promises --- .../src/compiler/phases/1-parse/utils/create.js | 4 +--- .../svelte/src/compiler/phases/2-analyze/index.js | 3 +-- .../phases/2-analyze/visitors/AwaitExpression.js | 8 -------- .../compiler/phases/2-analyze/visitors/Fragment.js | 12 ------------ .../phases/3-transform/server/transform-server.js | 2 -- .../3-transform/server/visitors/AwaitExpression.js | 14 -------------- .../phases/3-transform/server/visitors/Fragment.js | 6 ------ .../3-transform/server/visitors/TitleElement.js | 9 --------- packages/svelte/src/compiler/phases/types.d.ts | 1 - packages/svelte/src/compiler/types/template.d.ts | 1 - 10 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js diff --git a/packages/svelte/src/compiler/phases/1-parse/utils/create.js b/packages/svelte/src/compiler/phases/1-parse/utils/create.js index 0741abd7f201..c184f49ed2a6 100644 --- a/packages/svelte/src/compiler/phases/1-parse/utils/create.js +++ b/packages/svelte/src/compiler/phases/1-parse/utils/create.js @@ -12,9 +12,7 @@ export function create_fragment(transparent = false) { metadata: { transparent, dynamic: false, - has_await: false, - // name is added later, after we've done scope analysis - hoisted_promises: { id: b.id('$$promises'), promises: [] } + has_await: false } }; } diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index e303a16348e3..243773630fb9 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -542,8 +542,7 @@ export function analyze_component(root, source, options) { source, snippet_renderers: new Map(), snippets: new Set(), - async_deriveds: new Set(), - hoisted_promises: new Map() + async_deriveds: new Set() }; if (!runes) { diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js index 71da9c28371c..2725c1df9217 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js @@ -17,14 +17,6 @@ export function AwaitExpression(node, context) { context.state.fragment.metadata.has_await = true; } - if (context.state.fragment) { - // const len = context.state.fragment.metadata.hoisted_promises.promises.push(node.argument); - // context.state.analysis.hoisted_promises.set( - // node.argument, - // b.member(context.state.fragment.metadata.hoisted_promises.id, b.literal(len - 1), true) - // ); - } - suspend = true; } diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/Fragment.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/Fragment.js index 54890c325a6e..02d780dc0dc7 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/Fragment.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/Fragment.js @@ -7,16 +7,4 @@ */ export function Fragment(node, context) { context.next({ ...context.state, fragment: node }); - - // TODO this indicates whether the fragment contains an `await` expression (not inside - // a child fragment), which is necessary for ensuring that a `SnippetBlock` creates an - // async function in SSR. It feels like this is probably duplicative, but it's late - // and it works, so for now I'm doing it like this - node.metadata.is_async ||= node.metadata.hoisted_promises.promises.length > 0; - - if (node.metadata.hoisted_promises.promises.length === 1) { - // if there's only one promise in this fragment, we don't need to de-waterfall it - context.state.analysis.hoisted_promises.delete(node.metadata.hoisted_promises.promises[0]); - node.metadata.hoisted_promises.promises.length = 0; - } } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js index 6dc469cc9ade..9a3758371ae2 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js @@ -10,7 +10,6 @@ import { dev, filename } from '../../../state.js'; import { render_stylesheet } from '../css/index.js'; import { AssignmentExpression } from './visitors/AssignmentExpression.js'; import { AwaitBlock } from './visitors/AwaitBlock.js'; -import { AwaitExpression } from './visitors/AwaitExpression.js'; import { CallExpression } from './visitors/CallExpression.js'; import { ClassBody } from './visitors/ClassBody.js'; import { Component } from './visitors/Component.js'; @@ -59,7 +58,6 @@ const global_visitors = { /** @type {ComponentVisitors} */ const template_visitors = { - AwaitExpression, AwaitBlock, Component, ConstTag, diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js deleted file mode 100644 index 70070509d710..000000000000 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/AwaitExpression.js +++ /dev/null @@ -1,14 +0,0 @@ -/** @import { AwaitExpression } from 'estree' */ -/** @import { ComponentContext } from '../types.js' */ - -/** - * This is only registered for components, currently. - * @param {AwaitExpression} node - * @param {ComponentContext} context - */ -export function AwaitExpression(node, context) { - const hoisted = context.state.analysis.hoisted_promises.get(node.argument); - if (hoisted) { - node.argument = hoisted; - } -} diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/Fragment.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/Fragment.js index d27069f831c6..a44c7cfddd36 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/Fragment.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/Fragment.js @@ -52,12 +52,6 @@ export function Fragment(node, context) { /** @type {Statement[]} */ const statements = []; - if (node.metadata.hoisted_promises.promises.length > 0) { - statements.push( - b.const(node.metadata.hoisted_promises.id, b.array(node.metadata.hoisted_promises.promises)) - ); - } - statements.push(...state.init); statements.push(...build_template(state.template)); diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/TitleElement.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/TitleElement.js index f335a532c325..b1e076722ea1 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/TitleElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/TitleElement.js @@ -8,15 +8,6 @@ import { process_children, build_template, call_child_payload } from './shared/u * @param {ComponentContext} context */ export function TitleElement(node, context) { - if (node.fragment.metadata.hoisted_promises.promises.length > 0) { - context.state.init.push( - b.const( - node.fragment.metadata.hoisted_promises.id, - b.array(node.fragment.metadata.hoisted_promises.promises) - ) - ); - } - // title is guaranteed to contain only text/expression tag children const template = [b.literal('')]; process_children(node.fragment.nodes, { ...context, state: { ...context.state, template } }); diff --git a/packages/svelte/src/compiler/phases/types.d.ts b/packages/svelte/src/compiler/phases/types.d.ts index 1f6ceda35e40..40e41d4a7a9e 100644 --- a/packages/svelte/src/compiler/phases/types.d.ts +++ b/packages/svelte/src/compiler/phases/types.d.ts @@ -107,7 +107,6 @@ export interface ComponentAnalysis extends Analysis { * Every snippet that is declared locally */ snippets: Set<AST.SnippetBlock>; - hoisted_promises: Map<Expression, MemberExpression>; } declare module 'estree' { diff --git a/packages/svelte/src/compiler/types/template.d.ts b/packages/svelte/src/compiler/types/template.d.ts index 9b1a3dba8f6e..5c99e7d34e2f 100644 --- a/packages/svelte/src/compiler/types/template.d.ts +++ b/packages/svelte/src/compiler/types/template.d.ts @@ -59,7 +59,6 @@ export namespace AST { has_await: boolean; /** TODO document */ is_async: boolean; - hoisted_promises: { id: Identifier; promises: Expression[] }; }; } From 4a0aed3d5cb3a125151c57040d7845366e9a8be7 Mon Sep 17 00:00:00 2001 From: Rich Harris <rich.harris@vercel.com> Date: Sun, 14 Sep 2025 13:28:33 -0400 Subject: [PATCH 2/6] WIP optimise promises --- .../server/visitors/shared/component.js | 23 +++++++++-- .../server/visitors/shared/utils.js | 38 +++++++++++++++++-- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js index 3dd78a7638d8..b0840dfe3c54 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js @@ -1,10 +1,16 @@ /** @import { BlockStatement, Expression, Pattern, Property, SequenceExpression, Statement } from 'estree' */ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../../types.js' */ -import { empty_comment, build_attribute_value, call_child_payload } from './utils.js'; +import { + empty_comment, + build_attribute_value, + call_child_payload, + PromiseOptimiser +} from './utils.js'; import * as b from '#compiler/builders'; import { is_element_node } from '../../../../nodes.js'; import { dev } from '../../../../../state.js'; +import { get_attribute_chunks } from '../../../../../utils/ast.js'; /** * @param {AST.Component | AST.SvelteComponent | AST.SvelteSelf} node @@ -72,16 +78,26 @@ export function build_inline_component(node, expression, context) { } } + const optimiser = new PromiseOptimiser(); + for (const attribute of node.attributes) { if (attribute.type === 'LetDirective') { if (!slot_scope_applies_to_itself) { lets.default.push(attribute); } } else if (attribute.type === 'SpreadAttribute') { - props_and_spreads.push(/** @type {Expression} */ (context.visit(attribute))); + let expression = /** @type {Expression} */ (context.visit(attribute)); + props_and_spreads.push(optimiser.transform(expression, attribute.metadata.expression)); } else if (attribute.type === 'Attribute') { + const value = build_attribute_value( + attribute.value, + context, + false, + true, + optimiser.transform + ); + if (attribute.name.startsWith('--')) { - const value = build_attribute_value(attribute.value, context, false, true); custom_css_props.push(b.init(attribute.name, value)); continue; } @@ -90,7 +106,6 @@ export function build_inline_component(node, expression, context) { has_children_prop = true; } - const value = build_attribute_value(attribute.value, context, false, true); push_prop(b.prop('init', b.key(attribute.name), value)); } else if (attribute.type === 'BindDirective' && attribute.name !== 'this') { if (attribute.expression.type === 'SequenceExpression') { diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js index f9601e7878f4..81cd9f6fec3e 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js @@ -1,5 +1,5 @@ /** @import { AssignmentOperator, Expression, Identifier, Node, Statement, BlockStatement } from 'estree' */ -/** @import { AST } from '#compiler' */ +/** @import { AST, ExpressionMetadata } from '#compiler' */ /** @import { ComponentContext, ServerTransformState } from '../../types.js' */ import { escape_html } from '../../../../../../escaping.js'; @@ -183,13 +183,15 @@ export function build_template(template, out = b.id('$$payload'), operator = 'pu * @param {ComponentContext} context * @param {boolean} trim_whitespace * @param {boolean} is_component + * @param {(expression: Expression, metadata: ExpressionMetadata) => Expression} transform * @returns {Expression} */ export function build_attribute_value( value, context, trim_whitespace = false, - is_component = false + is_component = false, + transform = (expression) => expression ) { if (value === true) { return b.true; @@ -206,7 +208,10 @@ export function build_attribute_value( return b.literal(is_component ? data : escape_html(data, true)); } - return /** @type {Expression} */ (context.visit(chunk.expression)); + return transform( + /** @type {Expression} */ (context.visit(chunk.expression)), + chunk.metadata.expression + ); } let quasi = b.quasi('', false); @@ -224,7 +229,13 @@ export function build_attribute_value( : node.data; } else { expressions.push( - b.call('$.stringify', /** @type {Expression} */ (context.visit(node.expression))) + b.call( + '$.stringify', + transform( + /** @type {Expression} */ (context.visit(node.expression)), + node.metadata.expression + ) + ) ); quasi = b.quasi('', i + 1 === value.length); @@ -269,3 +280,22 @@ export function build_getter(node, state) { export function call_child_payload(body, async) { return b.stmt(b.call('$$payload.child', b.arrow([b.id('$$payload')], body, async))); } + +export class PromiseOptimiser { + /** @type {Expression[]} */ + expressions = []; + + /** + * + * @param {Expression} expression + * @param {ExpressionMetadata} metadata + */ + transform = (expression, metadata) => { + if (metadata.has_await) { + const length = this.expressions.push(expression); + return b.member(b.id('$$promises'), b.literal(length - 1), true); + } + + return expression; + }; +} From fdfea42f3da879880412aba7b6eef1389be50ebb Mon Sep 17 00:00:00 2001 From: Rich Harris <rich.harris@vercel.com> Date: Sun, 14 Sep 2025 14:00:06 -0400 Subject: [PATCH 3/6] WIP --- .../server/visitors/shared/component.js | 38 ++++++++++--------- .../server/visitors/shared/utils.js | 27 ++++++++++++- packages/svelte/src/compiler/utils/ast.js | 16 ++++++++ .../svelte/src/compiler/utils/builders.js | 12 +----- 4 files changed, 64 insertions(+), 29 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js index b0840dfe3c54..3a60b1e2ee18 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/component.js @@ -313,27 +313,29 @@ export function build_inline_component(node, expression, context) { node.type === 'SvelteComponent' || (node.type === 'Component' && node.metadata.dynamic); if (custom_css_props.length > 0) { - context.state.template.push( - b.stmt( - b.call( - '$.css_props', - b.id('$$payload'), - b.literal(context.state.namespace === 'svg' ? false : true), - b.object(custom_css_props), - b.thunk(b.block([statement])), - dynamic && b.true - ) + statement = b.stmt( + b.call( + '$.css_props', + b.id('$$payload'), + b.literal(context.state.namespace === 'svg' ? false : true), + b.object(custom_css_props), + b.thunk(b.block([statement])), + dynamic && b.true ) ); - } else { - if (dynamic) { - context.state.template.push(empty_comment); - } + } + + if (optimiser.expressions.length > 0) { + statement = call_child_payload(b.block([optimiser.apply(), statement]), true); + } + + if (dynamic && custom_css_props.length === 0) { + context.state.template.push(empty_comment); + } - context.state.template.push(statement); + context.state.template.push(statement); - if (!context.state.skip_hydration_boundaries) { - context.state.template.push(empty_comment); - } + if (!context.state.skip_hydration_boundaries && custom_css_props.length === 0) { + context.state.template.push(empty_comment); } } diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js index 81cd9f6fec3e..fb530de778d2 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js @@ -11,6 +11,7 @@ import { import * as b from '#compiler/builders'; import { sanitize_template_string } from '../../../../../utils/sanitize_template_string.js'; import { regex_whitespaces_strict } from '../../../../patterns.js'; +import { has_await } from '../../../../../utils/ast.js'; /** Opens an if/each block, so that we can remove nodes in the case of a mismatch */ export const block_open = b.literal(BLOCK_OPEN); @@ -293,9 +294,33 @@ export class PromiseOptimiser { transform = (expression, metadata) => { if (metadata.has_await) { const length = this.expressions.push(expression); - return b.member(b.id('$$promises'), b.literal(length - 1), true); + return b.id(`$$${length - 1}`); } return expression; }; + + apply() { + if (this.expressions.length === 1) { + return b.const('$$0', this.expressions[0]); + } + + return b.const( + b.array_pattern(this.expressions.map((_, i) => b.id(`$$${i}`))), + b.await( + b.call( + 'Promise.all', + b.array( + this.expressions.map((expression) => { + if (expression.type === 'AwaitExpression' && !has_await(expression.argument)) { + return expression.argument; + } + + return b.call(b.thunk(expression, true)); + }) + ) + ) + ) + ); + } } diff --git a/packages/svelte/src/compiler/utils/ast.js b/packages/svelte/src/compiler/utils/ast.js index a20b6888c794..d988cd98fb7e 100644 --- a/packages/svelte/src/compiler/utils/ast.js +++ b/packages/svelte/src/compiler/utils/ast.js @@ -609,3 +609,19 @@ export function build_assignment_value(operator, left, right) { ? b.logical(/** @type {ESTree.LogicalOperator} */ (operator.slice(0, -1)), left, right) : b.binary(/** @type {ESTree.BinaryOperator} */ (operator.slice(0, -1)), left, right); } + +/** + * @param {ESTree.Expression} expression + */ +export function has_await(expression) { + let has_await = false; + + walk(expression, null, { + AwaitExpression(_node, context) { + has_await = true; + context.stop(); + } + }); + + return has_await; +} diff --git a/packages/svelte/src/compiler/utils/builders.js b/packages/svelte/src/compiler/utils/builders.js index 03a946ff9c00..f69beed50936 100644 --- a/packages/svelte/src/compiler/utils/builders.js +++ b/packages/svelte/src/compiler/utils/builders.js @@ -2,6 +2,7 @@ import { walk } from 'zimmerframe'; import { regex_is_valid_identifier } from '../phases/patterns.js'; import { sanitize_template_string } from './sanitize_template_string.js'; +import { has_await } from './ast.js'; /** * @param {Array<ESTree.Expression | ESTree.SpreadElement | null>} elements @@ -443,16 +444,7 @@ export function thunk(expression, async = false) { export function unthunk(expression) { // optimize `async () => await x()`, but not `async () => await x(await y)` if (expression.async && expression.body.type === 'AwaitExpression') { - let has_await = false; - - walk(expression.body.argument, null, { - AwaitExpression(_node, context) { - has_await = true; - context.stop(); - } - }); - - if (!has_await) { + if (!has_await(expression.body.argument)) { return unthunk(arrow(expression.params, expression.body.argument)); } } From 0b506d743d00459d2d272313547c02e5ea4bb395 Mon Sep 17 00:00:00 2001 From: Rich Harris <rich.harris@vercel.com> Date: Sun, 14 Sep 2025 14:43:33 -0400 Subject: [PATCH 4/6] fix <slot> with await in prop --- .../server/visitors/SlotElement.js | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js index fee7cb6e027c..2d16a07b4eb9 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/SlotElement.js @@ -2,7 +2,12 @@ /** @import { AST } from '#compiler' */ /** @import { ComponentContext } from '../types.js' */ import * as b from '#compiler/builders'; -import { empty_comment, build_attribute_value } from './shared/utils.js'; +import { + empty_comment, + build_attribute_value, + PromiseOptimiser, + call_child_payload +} from './shared/utils.js'; /** * @param {AST.SlotElement} node @@ -15,13 +20,22 @@ export function SlotElement(node, context) { /** @type {Expression[]} */ const spreads = []; + const optimiser = new PromiseOptimiser(); + let name = b.literal('default'); for (const attribute of node.attributes) { if (attribute.type === 'SpreadAttribute') { - spreads.push(/** @type {Expression} */ (context.visit(attribute))); + let expression = /** @type {Expression} */ (context.visit(attribute)); + spreads.push(optimiser.transform(expression, attribute.metadata.expression)); } else if (attribute.type === 'Attribute') { - const value = build_attribute_value(attribute.value, context, false, true); + const value = build_attribute_value( + attribute.value, + context, + false, + true, + optimiser.transform + ); if (attribute.name === 'name') { name = /** @type {Literal} */ (value); @@ -50,5 +64,10 @@ export function SlotElement(node, context) { fallback ); - context.state.template.push(empty_comment, b.stmt(slot), empty_comment); + const statement = + optimiser.expressions.length > 0 + ? call_child_payload(b.block([optimiser.apply(), b.stmt(slot)]), true) + : b.stmt(slot); + + context.state.template.push(empty_comment, statement, empty_comment); } From b21cc8e7390c893c00e4e84ffcdd30cfee59a0cc Mon Sep 17 00:00:00 2001 From: Rich Harris <rich.harris@vercel.com> Date: Sun, 14 Sep 2025 14:47:19 -0400 Subject: [PATCH 5/6] tweak --- .../server/visitors/shared/utils.js | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js index fb530de778d2..dd754900be23 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/utils.js @@ -305,22 +305,17 @@ export class PromiseOptimiser { return b.const('$$0', this.expressions[0]); } + const promises = b.array( + this.expressions.map((expression) => { + return expression.type === 'AwaitExpression' && !has_await(expression.argument) + ? expression.argument + : b.call(b.thunk(expression, true)); + }) + ); + return b.const( b.array_pattern(this.expressions.map((_, i) => b.id(`$$${i}`))), - b.await( - b.call( - 'Promise.all', - b.array( - this.expressions.map((expression) => { - if (expression.type === 'AwaitExpression' && !has_await(expression.argument)) { - return expression.argument; - } - - return b.call(b.thunk(expression, true)); - }) - ) - ) - ) + b.await(b.call('Promise.all', promises)) ); } } From 1fcd13fcb1d903c676c4ddc5cd5128d2316d71b5 Mon Sep 17 00:00:00 2001 From: Rich Harris <rich.harris@vercel.com> Date: Sun, 14 Sep 2025 14:54:16 -0400 Subject: [PATCH 6/6] fix type error --- packages/svelte/src/compiler/phases/1-parse/utils/create.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/svelte/src/compiler/phases/1-parse/utils/create.js b/packages/svelte/src/compiler/phases/1-parse/utils/create.js index c184f49ed2a6..fbf5304d5540 100644 --- a/packages/svelte/src/compiler/phases/1-parse/utils/create.js +++ b/packages/svelte/src/compiler/phases/1-parse/utils/create.js @@ -12,7 +12,8 @@ export function create_fragment(transparent = false) { metadata: { transparent, dynamic: false, - has_await: false + has_await: false, + is_async: false } }; }