Skip to content

Commit 5bb5a8f

Browse files
committed
WIP
1 parent 3b185b7 commit 5bb5a8f

File tree

9 files changed

+59
-15
lines changed

9 files changed

+59
-15
lines changed

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,9 @@ export function client_component(analysis, options) {
159159
template_contains_script_tag: false
160160
},
161161
namespace: options.namespace,
162-
bound_contenteditable: false
162+
bound_contenteditable: false,
163+
init_is_async: false,
164+
update_is_async: false
163165
},
164166
events: new Set(),
165167
preserve_whitespace: options.preserveWhitespace,

packages/svelte/src/compiler/phases/3-transform/client/types.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ export interface ComponentClientTransformState extends ClientTransformState {
7575
*/
7676
template_contains_script_tag: boolean;
7777
};
78+
// TODO it would be nice if these were colocated with the arrays they pertain to
79+
init_is_async: boolean;
80+
update_is_async: boolean;
7881
};
7982
readonly preserve_whitespace: boolean;
8083

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ export function Fragment(node, context) {
7474
template_contains_script_tag: false
7575
},
7676
namespace,
77-
bound_contenteditable: context.state.metadata.bound_contenteditable
77+
bound_contenteditable: context.state.metadata.bound_contenteditable,
78+
init_is_async: false,
79+
update_is_async: false
7880
}
7981
};
8082

@@ -190,7 +192,7 @@ export function Fragment(node, context) {
190192
}
191193

192194
if (state.update.length > 0) {
193-
body.push(build_render_statement(state.update));
195+
body.push(build_render_statement(state.update, state.metadata.update_is_async));
194196
}
195197

196198
body.push(...state.after_update);

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

+13-3
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,9 @@ export function RegularElement(node, context) {
409409
b.block([
410410
...child_state.init,
411411
...element_state.init,
412-
child_state.update.length > 0 ? build_render_statement(child_state.update) : b.empty,
412+
child_state.update.length > 0
413+
? build_render_statement(child_state.update, child_state.metadata.update_is_async)
414+
: b.empty,
413415
...child_state.after_update,
414416
...element_state.after_update
415417
])
@@ -418,6 +420,9 @@ export function RegularElement(node, context) {
418420
context.state.init.push(...child_state.init, ...element_state.init);
419421
context.state.update.push(...child_state.update);
420422
context.state.after_update.push(...child_state.after_update, ...element_state.after_update);
423+
424+
context.state.metadata.init_is_async ||= child_state.metadata.init_is_async;
425+
context.state.metadata.update_is_async ||= child_state.metadata.update_is_async;
421426
} else {
422427
context.state.init.push(...element_state.init);
423428
context.state.after_update.push(...element_state.after_update);
@@ -627,9 +632,10 @@ function build_element_attribute_update_assignment(
627632

628633
if (attribute.metadata.expression.has_state) {
629634
if (has_call) {
630-
state.init.push(build_update(update));
635+
state.init.push(build_update(update, attribute.metadata.expression.is_async));
631636
} else {
632637
state.update.push(update);
638+
state.metadata.update_is_async ||= attribute.metadata.expression.is_async;
633639
}
634640
return true;
635641
} else {
@@ -662,12 +668,16 @@ function build_custom_element_attribute_update_assignment(node_id, attribute, co
662668

663669
if (attribute.metadata.expression.has_state) {
664670
if (has_call) {
665-
state.init.push(build_update(update));
671+
state.init.push(build_update(update, attribute.metadata.expression.is_async));
666672
} else {
667673
state.update.push(update);
674+
state.metadata.update_is_async ||= attribute.metadata.expression.is_async;
668675
}
669676
return true;
670677
} else {
678+
if (attribute.metadata.expression.is_async) {
679+
throw new Error('TODO top-level await');
680+
}
671681
state.init.push(update);
672682
return false;
673683
}

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,12 @@ export function SvelteElement(node, context) {
123123
/** @type {Statement[]} */
124124
const inner = inner_context.state.init;
125125
if (inner_context.state.update.length > 0) {
126-
inner.push(build_render_statement(inner_context.state.update));
126+
inner.push(
127+
build_render_statement(
128+
inner_context.state.update,
129+
inner_context.state.metadata.update_is_async
130+
)
131+
);
127132
}
128133
inner.push(...inner_context.state.after_update);
129134
inner.push(

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { build_template_chunk } from './shared/utils.js';
88
* @param {ComponentContext} context
99
*/
1010
export function TitleElement(node, context) {
11-
const { has_state, value } = build_template_chunk(
11+
const { has_state, is_async, value } = build_template_chunk(
1212
/** @type {any} */ (node.fragment.nodes),
1313
context.visit,
1414
context.state
@@ -18,7 +18,12 @@ export function TitleElement(node, context) {
1818

1919
if (has_state) {
2020
context.state.update.push(statement);
21+
context.state.metadata.update_is_async ||= is_async;
2122
} else {
23+
if (is_async) {
24+
throw new Error('TODO top-level await');
25+
}
26+
2227
context.state.init.push(statement);
2328
}
2429
}

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

+16-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export function build_set_attributes(
2929
state
3030
) {
3131
let has_state = false;
32+
let is_async = false;
3233

3334
/** @type {ObjectExpression['properties']} */
3435
const values = [];
@@ -63,6 +64,8 @@ export function build_set_attributes(
6364
}
6465
values.push(b.spread(value));
6566
}
67+
68+
is_async ||= attribute.metadata.expression.is_async;
6669
}
6770

6871
const call = b.call(
@@ -80,6 +83,7 @@ export function build_set_attributes(
8083
context.state.init.push(b.let(attributes_id));
8184
const update = b.stmt(b.assignment('=', attributes_id, call));
8285
context.state.update.push(update);
86+
context.state.metadata.update_is_async ||= is_async;
8387
return true;
8488
}
8589

@@ -104,7 +108,7 @@ export function build_style_directives(
104108
const state = context.state;
105109

106110
for (const directive of style_directives) {
107-
const { has_state, has_call } = directive.metadata.expression;
111+
const { has_state, has_call, is_async } = directive.metadata.expression;
108112

109113
let value =
110114
directive.value === true
@@ -129,10 +133,14 @@ export function build_style_directives(
129133
);
130134

131135
if (!is_attributes_reactive && has_call) {
132-
state.init.push(build_update(update));
136+
state.init.push(build_update(update, is_async));
133137
} else if (is_attributes_reactive || has_state || has_call) {
134138
state.update.push(update);
139+
state.metadata.update_is_async ||= is_async;
135140
} else {
141+
if (is_async) {
142+
throw new Error('TODO top-level await');
143+
}
136144
state.init.push(update);
137145
}
138146
}
@@ -154,7 +162,7 @@ export function build_class_directives(
154162
) {
155163
const state = context.state;
156164
for (const directive of class_directives) {
157-
const { has_state, has_call } = directive.metadata.expression;
165+
const { has_state, has_call, is_async } = directive.metadata.expression;
158166
let value = /** @type {Expression} */ (context.visit(directive.expression));
159167

160168
if (has_call) {
@@ -167,10 +175,14 @@ export function build_class_directives(
167175
const update = b.stmt(b.call('$.toggle_class', element_id, b.literal(directive.name), value));
168176

169177
if (!is_attributes_reactive && has_call) {
170-
state.init.push(build_update(update));
178+
state.init.push(build_update(update, is_async));
171179
} else if (is_attributes_reactive || has_state || has_call) {
172180
state.update.push(update);
181+
state.metadata.update_is_async ||= is_async;
173182
} else {
183+
if (is_async) {
184+
throw new Error('TODO top-level await');
185+
}
174186
state.init.push(update);
175187
}
176188
}

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

+4
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ export function process_children(nodes, initial, is_element, { visit, state }) {
8282
state.init.push(build_update(update, is_async));
8383
} else if (has_state && !within_bound_contenteditable) {
8484
state.update.push(update);
85+
state.metadata.update_is_async ||= is_async;
8586
} else {
87+
if (is_async) {
88+
throw new Error('TODO top-level await');
89+
}
8690
state.init.push(b.stmt(b.assignment('=', b.member(id, 'nodeValue'), value)));
8791
}
8892
}

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,12 @@ export function build_update(statement, is_async) {
102102

103103
/**
104104
* @param {Statement[]} update
105+
* @param {boolean} is_async
105106
*/
106-
export function build_render_statement(update) {
107+
export function build_render_statement(update, is_async) {
107108
return update.length === 1
108-
? build_update(update[0])
109-
: b.stmt(b.call('$.template_effect', b.thunk(b.block(update))));
109+
? build_update(update[0], is_async)
110+
: b.stmt(b.call('$.template_effect', b.thunk(b.block(update), is_async)));
110111
}
111112

112113
/**

0 commit comments

Comments
 (0)