Rich Harris 8 months ago
parent 1588464d3f
commit 2fe198f1ad

@ -355,6 +355,12 @@ export function client_component(analysis, options) {
const push_args = [b.id('$$props'), b.literal(analysis.runes)];
if (dev) push_args.push(b.id(analysis.name));
if (analysis.is_async) {
const body = /** @type {ESTree.FunctionDeclaration} */ (template.body[0]);
body.body.body.unshift(...instance.body);
instance.body.length = 0;
}
let component_block = b.block([
...store_setup,
...legacy_reactive_declarations,
@ -367,24 +373,6 @@ export function client_component(analysis, options) {
.../** @type {ESTree.Statement[]} */ (template.body)
]);
if (analysis.is_async) {
const body = b.function_declaration(
b.id('$$body'),
[b.id('$$anchor'), b.id('$$props')],
component_block
);
body.async = true;
state.hoisted.push(body);
component_block = b.block([
b.var('fragment', b.call('$.comment')),
b.var('node', b.call('$.first_child', b.id('fragment'))),
b.stmt(b.call(body.id, b.id('node'), b.id('$$props'))),
b.stmt(b.call('$.append', b.id('$$anchor'), b.id('fragment')))
]);
}
if (!analysis.runes) {
// Bind static exports to props so that people can access them with bind:x
for (const { name, alias } of analysis.exports) {

@ -204,6 +204,21 @@ export function Fragment(node, context) {
body.push(close);
}
const async =
state.metadata.init_is_async || (state.analysis.is_async && context.path.length === 0);
if (async) {
// TODO need to create bookends for hydration to work
return b.block([
b.function_declaration(b.id('$$body'), [b.id('$$anchor')], b.block(body), true),
b.var('fragment', b.call('$.comment')),
b.var('node', b.call('$.first_child', b.id('fragment'))),
b.stmt(b.call(b.id('$$body'), b.id('node'))),
b.stmt(b.call('$.append', b.id('$$anchor'), b.id('fragment')))
]);
}
return b.block(body);
}

@ -167,8 +167,17 @@ export function build_component(node, component_name, context, anchor = context.
if (should_wrap_in_derived) {
const id = b.id(context.state.scope.generate(attribute.name));
context.state.init.push(b.var(id, create_derived(context.state, b.thunk(value))));
arg = b.call('$.get', id);
if (attribute.metadata.expression.is_async) {
// TODO parallelise these
context.state.init.push(
b.var(id, b.await(b.call('$.async_derived', b.thunk(arg, true))))
);
arg = b.call(id);
} else {
context.state.init.push(b.var(id, create_derived(context.state, b.thunk(value))));
arg = b.call('$.get', id);
}
}
push_prop(b.get(attribute.name, [b.return(arg)]));

@ -30,16 +30,17 @@ export function assignment_pattern(left, right) {
/**
* @param {Array<ESTree.Pattern>} params
* @param {ESTree.BlockStatement | ESTree.Expression} body
* @param {boolean} async
* @returns {ESTree.ArrowFunctionExpression}
*/
export function arrow(params, body) {
export function arrow(params, body, async = false) {
return {
type: 'ArrowFunctionExpression',
params,
body,
expression: body.type !== 'BlockStatement',
generator: false,
async: false,
async,
metadata: /** @type {any} */ (null) // should not be used by codegen
};
}
@ -214,16 +215,17 @@ export function export_default(declaration) {
* @param {ESTree.Identifier} id
* @param {ESTree.Pattern[]} params
* @param {ESTree.BlockStatement} body
* @param {boolean} async
* @returns {ESTree.FunctionDeclaration}
*/
export function function_declaration(id, params, body) {
export function function_declaration(id, params, body, async = false) {
return {
type: 'FunctionDeclaration',
id,
params,
body,
generator: false,
async: false,
async,
metadata: /** @type {any} */ (null) // should not be used by codegen
};
}
@ -419,9 +421,7 @@ export function template(elements, expressions) {
* @returns {ESTree.Expression}
*/
export function thunk(expression, async = false) {
const fn = arrow([], expression);
if (async) fn.async = true;
return unthunk(fn);
return unthunk(arrow([], expression, async));
}
/**

Loading…
Cancel
Save