Skip to content

Commit 2fe198f

Browse files
committed
fix
1 parent 1588464 commit 2fe198f

File tree

4 files changed

+39
-27
lines changed

4 files changed

+39
-27
lines changed

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

+6-18
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ 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+
if (analysis.is_async) {
359+
const body = /** @type {ESTree.FunctionDeclaration} */ (template.body[0]);
360+
body.body.body.unshift(...instance.body);
361+
instance.body.length = 0;
362+
}
363+
358364
let component_block = b.block([
359365
...store_setup,
360366
...legacy_reactive_declarations,
@@ -367,24 +373,6 @@ export function client_component(analysis, options) {
367373
.../** @type {ESTree.Statement[]} */ (template.body)
368374
]);
369375

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-
388376
if (!analysis.runes) {
389377
// Bind static exports to props so that people can access them with bind:x
390378
for (const { name, alias } of analysis.exports) {

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

+15
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,21 @@ export function Fragment(node, context) {
204204
body.push(close);
205205
}
206206

207+
const async =
208+
state.metadata.init_is_async || (state.analysis.is_async && context.path.length === 0);
209+
210+
if (async) {
211+
// TODO need to create bookends for hydration to work
212+
return b.block([
213+
b.function_declaration(b.id('$$body'), [b.id('$$anchor')], b.block(body), true),
214+
215+
b.var('fragment', b.call('$.comment')),
216+
b.var('node', b.call('$.first_child', b.id('fragment'))),
217+
b.stmt(b.call(b.id('$$body'), b.id('node'))),
218+
b.stmt(b.call('$.append', b.id('$$anchor'), b.id('fragment')))
219+
]);
220+
}
221+
207222
return b.block(body);
208223
}
209224

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,17 @@ export function build_component(node, component_name, context, anchor = context.
167167

168168
if (should_wrap_in_derived) {
169169
const id = b.id(context.state.scope.generate(attribute.name));
170-
context.state.init.push(b.var(id, create_derived(context.state, b.thunk(value))));
171-
arg = b.call('$.get', id);
170+
171+
if (attribute.metadata.expression.is_async) {
172+
// TODO parallelise these
173+
context.state.init.push(
174+
b.var(id, b.await(b.call('$.async_derived', b.thunk(arg, true))))
175+
);
176+
arg = b.call(id);
177+
} else {
178+
context.state.init.push(b.var(id, create_derived(context.state, b.thunk(value))));
179+
arg = b.call('$.get', id);
180+
}
172181
}
173182

174183
push_prop(b.get(attribute.name, [b.return(arg)]));

packages/svelte/src/compiler/utils/builders.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@ export function assignment_pattern(left, right) {
3030
/**
3131
* @param {Array<ESTree.Pattern>} params
3232
* @param {ESTree.BlockStatement | ESTree.Expression} body
33+
* @param {boolean} async
3334
* @returns {ESTree.ArrowFunctionExpression}
3435
*/
35-
export function arrow(params, body) {
36+
export function arrow(params, body, async = false) {
3637
return {
3738
type: 'ArrowFunctionExpression',
3839
params,
3940
body,
4041
expression: body.type !== 'BlockStatement',
4142
generator: false,
42-
async: false,
43+
async,
4344
metadata: /** @type {any} */ (null) // should not be used by codegen
4445
};
4546
}
@@ -214,16 +215,17 @@ export function export_default(declaration) {
214215
* @param {ESTree.Identifier} id
215216
* @param {ESTree.Pattern[]} params
216217
* @param {ESTree.BlockStatement} body
218+
* @param {boolean} async
217219
* @returns {ESTree.FunctionDeclaration}
218220
*/
219-
export function function_declaration(id, params, body) {
221+
export function function_declaration(id, params, body, async = false) {
220222
return {
221223
type: 'FunctionDeclaration',
222224
id,
223225
params,
224226
body,
225227
generator: false,
226-
async: false,
228+
async,
227229
metadata: /** @type {any} */ (null) // should not be used by codegen
228230
};
229231
}
@@ -419,9 +421,7 @@ export function template(elements, expressions) {
419421
* @returns {ESTree.Expression}
420422
*/
421423
export function thunk(expression, async = false) {
422-
const fn = arrow([], expression);
423-
if (async) fn.async = true;
424-
return unthunk(fn);
424+
return unthunk(arrow([], expression, async));
425425
}
426426

427427
/**

0 commit comments

Comments
 (0)