Rich Harris 8 months ago
parent 3b185b7ba9
commit 5bb5a8f767

@ -159,7 +159,9 @@ export function client_component(analysis, options) {
template_contains_script_tag: false template_contains_script_tag: false
}, },
namespace: options.namespace, namespace: options.namespace,
bound_contenteditable: false bound_contenteditable: false,
init_is_async: false,
update_is_async: false
}, },
events: new Set(), events: new Set(),
preserve_whitespace: options.preserveWhitespace, preserve_whitespace: options.preserveWhitespace,

@ -75,6 +75,9 @@ export interface ComponentClientTransformState extends ClientTransformState {
*/ */
template_contains_script_tag: boolean; template_contains_script_tag: boolean;
}; };
// TODO it would be nice if these were colocated with the arrays they pertain to
init_is_async: boolean;
update_is_async: boolean;
}; };
readonly preserve_whitespace: boolean; readonly preserve_whitespace: boolean;

@ -74,7 +74,9 @@ export function Fragment(node, context) {
template_contains_script_tag: false template_contains_script_tag: false
}, },
namespace, namespace,
bound_contenteditable: context.state.metadata.bound_contenteditable bound_contenteditable: context.state.metadata.bound_contenteditable,
init_is_async: false,
update_is_async: false
} }
}; };
@ -190,7 +192,7 @@ export function Fragment(node, context) {
} }
if (state.update.length > 0) { if (state.update.length > 0) {
body.push(build_render_statement(state.update)); body.push(build_render_statement(state.update, state.metadata.update_is_async));
} }
body.push(...state.after_update); body.push(...state.after_update);

@ -409,7 +409,9 @@ export function RegularElement(node, context) {
b.block([ b.block([
...child_state.init, ...child_state.init,
...element_state.init, ...element_state.init,
child_state.update.length > 0 ? build_render_statement(child_state.update) : b.empty, child_state.update.length > 0
? build_render_statement(child_state.update, child_state.metadata.update_is_async)
: b.empty,
...child_state.after_update, ...child_state.after_update,
...element_state.after_update ...element_state.after_update
]) ])
@ -418,6 +420,9 @@ export function RegularElement(node, context) {
context.state.init.push(...child_state.init, ...element_state.init); context.state.init.push(...child_state.init, ...element_state.init);
context.state.update.push(...child_state.update); context.state.update.push(...child_state.update);
context.state.after_update.push(...child_state.after_update, ...element_state.after_update); context.state.after_update.push(...child_state.after_update, ...element_state.after_update);
context.state.metadata.init_is_async ||= child_state.metadata.init_is_async;
context.state.metadata.update_is_async ||= child_state.metadata.update_is_async;
} else { } else {
context.state.init.push(...element_state.init); context.state.init.push(...element_state.init);
context.state.after_update.push(...element_state.after_update); context.state.after_update.push(...element_state.after_update);
@ -627,9 +632,10 @@ function build_element_attribute_update_assignment(
if (attribute.metadata.expression.has_state) { if (attribute.metadata.expression.has_state) {
if (has_call) { if (has_call) {
state.init.push(build_update(update)); state.init.push(build_update(update, attribute.metadata.expression.is_async));
} else { } else {
state.update.push(update); state.update.push(update);
state.metadata.update_is_async ||= attribute.metadata.expression.is_async;
} }
return true; return true;
} else { } else {
@ -662,12 +668,16 @@ function build_custom_element_attribute_update_assignment(node_id, attribute, co
if (attribute.metadata.expression.has_state) { if (attribute.metadata.expression.has_state) {
if (has_call) { if (has_call) {
state.init.push(build_update(update)); state.init.push(build_update(update, attribute.metadata.expression.is_async));
} else { } else {
state.update.push(update); state.update.push(update);
state.metadata.update_is_async ||= attribute.metadata.expression.is_async;
} }
return true; return true;
} else { } else {
if (attribute.metadata.expression.is_async) {
throw new Error('TODO top-level await');
}
state.init.push(update); state.init.push(update);
return false; return false;
} }

@ -123,7 +123,12 @@ export function SvelteElement(node, context) {
/** @type {Statement[]} */ /** @type {Statement[]} */
const inner = inner_context.state.init; const inner = inner_context.state.init;
if (inner_context.state.update.length > 0) { if (inner_context.state.update.length > 0) {
inner.push(build_render_statement(inner_context.state.update)); inner.push(
build_render_statement(
inner_context.state.update,
inner_context.state.metadata.update_is_async
)
);
} }
inner.push(...inner_context.state.after_update); inner.push(...inner_context.state.after_update);
inner.push( inner.push(

@ -8,7 +8,7 @@ import { build_template_chunk } from './shared/utils.js';
* @param {ComponentContext} context * @param {ComponentContext} context
*/ */
export function TitleElement(node, context) { export function TitleElement(node, context) {
const { has_state, value } = build_template_chunk( const { has_state, is_async, value } = build_template_chunk(
/** @type {any} */ (node.fragment.nodes), /** @type {any} */ (node.fragment.nodes),
context.visit, context.visit,
context.state context.state
@ -18,7 +18,12 @@ export function TitleElement(node, context) {
if (has_state) { if (has_state) {
context.state.update.push(statement); context.state.update.push(statement);
context.state.metadata.update_is_async ||= is_async;
} else { } else {
if (is_async) {
throw new Error('TODO top-level await');
}
context.state.init.push(statement); context.state.init.push(statement);
} }
} }

@ -29,6 +29,7 @@ export function build_set_attributes(
state state
) { ) {
let has_state = false; let has_state = false;
let is_async = false;
/** @type {ObjectExpression['properties']} */ /** @type {ObjectExpression['properties']} */
const values = []; const values = [];
@ -63,6 +64,8 @@ export function build_set_attributes(
} }
values.push(b.spread(value)); values.push(b.spread(value));
} }
is_async ||= attribute.metadata.expression.is_async;
} }
const call = b.call( const call = b.call(
@ -80,6 +83,7 @@ export function build_set_attributes(
context.state.init.push(b.let(attributes_id)); context.state.init.push(b.let(attributes_id));
const update = b.stmt(b.assignment('=', attributes_id, call)); const update = b.stmt(b.assignment('=', attributes_id, call));
context.state.update.push(update); context.state.update.push(update);
context.state.metadata.update_is_async ||= is_async;
return true; return true;
} }
@ -104,7 +108,7 @@ export function build_style_directives(
const state = context.state; const state = context.state;
for (const directive of style_directives) { for (const directive of style_directives) {
const { has_state, has_call } = directive.metadata.expression; const { has_state, has_call, is_async } = directive.metadata.expression;
let value = let value =
directive.value === true directive.value === true
@ -129,10 +133,14 @@ export function build_style_directives(
); );
if (!is_attributes_reactive && has_call) { if (!is_attributes_reactive && has_call) {
state.init.push(build_update(update)); state.init.push(build_update(update, is_async));
} else if (is_attributes_reactive || has_state || has_call) { } else if (is_attributes_reactive || has_state || has_call) {
state.update.push(update); state.update.push(update);
state.metadata.update_is_async ||= is_async;
} else { } else {
if (is_async) {
throw new Error('TODO top-level await');
}
state.init.push(update); state.init.push(update);
} }
} }
@ -154,7 +162,7 @@ export function build_class_directives(
) { ) {
const state = context.state; const state = context.state;
for (const directive of class_directives) { for (const directive of class_directives) {
const { has_state, has_call } = directive.metadata.expression; const { has_state, has_call, is_async } = directive.metadata.expression;
let value = /** @type {Expression} */ (context.visit(directive.expression)); let value = /** @type {Expression} */ (context.visit(directive.expression));
if (has_call) { if (has_call) {
@ -167,10 +175,14 @@ export function build_class_directives(
const update = b.stmt(b.call('$.toggle_class', element_id, b.literal(directive.name), value)); const update = b.stmt(b.call('$.toggle_class', element_id, b.literal(directive.name), value));
if (!is_attributes_reactive && has_call) { if (!is_attributes_reactive && has_call) {
state.init.push(build_update(update)); state.init.push(build_update(update, is_async));
} else if (is_attributes_reactive || has_state || has_call) { } else if (is_attributes_reactive || has_state || has_call) {
state.update.push(update); state.update.push(update);
state.metadata.update_is_async ||= is_async;
} else { } else {
if (is_async) {
throw new Error('TODO top-level await');
}
state.init.push(update); state.init.push(update);
} }
} }

@ -82,7 +82,11 @@ export function process_children(nodes, initial, is_element, { visit, state }) {
state.init.push(build_update(update, is_async)); state.init.push(build_update(update, is_async));
} else if (has_state && !within_bound_contenteditable) { } else if (has_state && !within_bound_contenteditable) {
state.update.push(update); state.update.push(update);
state.metadata.update_is_async ||= is_async;
} else { } else {
if (is_async) {
throw new Error('TODO top-level await');
}
state.init.push(b.stmt(b.assignment('=', b.member(id, 'nodeValue'), value))); state.init.push(b.stmt(b.assignment('=', b.member(id, 'nodeValue'), value)));
} }
} }

@ -102,11 +102,12 @@ export function build_update(statement, is_async) {
/** /**
* @param {Statement[]} update * @param {Statement[]} update
* @param {boolean} is_async
*/ */
export function build_render_statement(update) { export function build_render_statement(update, is_async) {
return update.length === 1 return update.length === 1
? build_update(update[0]) ? build_update(update[0], is_async)
: b.stmt(b.call('$.template_effect', b.thunk(b.block(update)))); : b.stmt(b.call('$.template_effect', b.thunk(b.block(update), is_async)));
} }
/** /**

Loading…
Cancel
Save