Skip to content

Commit e2bc4d9

Browse files
committed
top-level await
1 parent 209f311 commit e2bc4d9

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

packages/svelte/src/compiler/phases/2-analyze/index.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,8 @@ export function analyze_component(root, source, options) {
450450
source,
451451
undefined_exports: new Map(),
452452
snippet_renderers: new Map(),
453-
snippets: new Set()
453+
snippets: new Set(),
454+
is_async: false
454455
};
455456

456457
if (!runes) {

packages/svelte/src/compiler/phases/2-analyze/visitors/AwaitExpression.js

+8
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@
66
* @param {Context} context
77
*/
88
export function AwaitExpression(node, context) {
9+
if (!context.state.analysis.runes) {
10+
throw new Error('TODO runes mode only');
11+
}
12+
913
if (context.state.expression) {
1014
context.state.expression.is_async = true;
1115
}
1216

17+
if (context.state.ast_type === 'instance' && context.state.scope.function_depth === 1) {
18+
context.state.analysis.is_async = true;
19+
}
20+
1321
context.next();
1422
}

packages/svelte/src/compiler/phases/3-transform/client/transform-client.js

+19-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ export function client_component(analysis, options) {
355355
const push_args = [b.id('$$props'), b.literal(analysis.runes)];
356356
if (dev) push_args.push(b.id(analysis.name));
357357

358-
const component_block = b.block([
358+
let component_block = b.block([
359359
...store_setup,
360360
...legacy_reactive_declarations,
361361
...group_binding_declarations,
@@ -367,6 +367,24 @@ export function client_component(analysis, options) {
367367
.../** @type {ESTree.Statement[]} */ (template.body)
368368
]);
369369

370+
if (analysis.is_async) {
371+
const body = b.function_declaration(
372+
b.id('$$body'),
373+
[b.id('$$anchor'), b.id('$$props')],
374+
component_block
375+
);
376+
body.async = true;
377+
378+
state.hoisted.push(body);
379+
380+
component_block = b.block([
381+
b.var('fragment', b.call('$.comment')),
382+
b.var('node', b.call('$.first_child', b.id('fragment'))),
383+
b.stmt(b.call(body.id, b.id('node'), b.id('$$props'))),
384+
b.stmt(b.call('$.append', b.id('$$anchor'), b.id('fragment')))
385+
]);
386+
}
387+
370388
if (!analysis.runes) {
371389
// Bind static exports to props so that people can access them with bind:x
372390
for (const { name, alias } of analysis.exports) {

packages/svelte/src/compiler/phases/types.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ export interface ComponentAnalysis extends Analysis {
8585
* Every snippet that is declared locally
8686
*/
8787
snippets: Set<AST.SnippetBlock>;
88+
/**
89+
* true if uses top-level await
90+
*/
91+
is_async: boolean;
8892
}
8993

9094
declare module 'estree' {

0 commit comments

Comments
 (0)