Skip to content

Commit cd8969a

Browse files
committed
try adding regular awaited variables
1 parent 710d6a6 commit cd8969a

File tree

5 files changed

+76
-21
lines changed

5 files changed

+76
-21
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ export function client_component(analysis, options) {
184184
after_update: /** @type {any} */ (null),
185185
template: /** @type {any} */ (null),
186186
memoizer: /** @type {any} */ (null),
187-
parallelized_derived_chunks: [],
187+
parallelized_chunks: [],
188188
current_parallelized_chunk: null
189189
};
190190

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
VariableDeclaration,
1010
Pattern
1111
} from 'estree';
12-
import type { AST, Namespace, ValidatedCompileOptions } from '#compiler';
12+
import type { AST, Binding, Namespace, ValidatedCompileOptions } from '#compiler';
1313
import type { TransformState } from '../types.js';
1414
import type { ComponentAnalysis } from '../../types.js';
1515
import type { Template } from './transform-template/template.js';
@@ -83,7 +83,8 @@ export interface ComponentClientTransformState extends ClientTransformState {
8383
readonly instance_level_snippets: VariableDeclaration[];
8484
/** Snippets hoisted to the module */
8585
readonly module_level_snippets: VariableDeclaration[];
86-
readonly parallelized_derived_chunks: ParallelizedChunk[];
86+
/** async deriveds and certain awaited variables are chunked so they can be parallelized via `Promise.all` */
87+
readonly parallelized_chunks: ParallelizedChunk[];
8788
current_parallelized_chunk: ParallelizedChunk | null;
8889
}
8990

@@ -95,6 +96,7 @@ export interface ParallelizedChunk {
9596
kind: VariableDeclaration['kind'];
9697
/** index in instance body */
9798
position: number;
99+
bindings: Binding[];
98100
}
99101

100102
export type Context = import('zimmerframe').Context<AST.SvelteNode, ClientTransformState>;

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ export function is_state_source(binding, analysis) {
3333
* @param {Expression} expression
3434
* @param {Scope} scope
3535
* @param {Analysis | ComponentAnalysis} analysis
36+
* @param {Binding[]} bindings bindings currently being parallelized (and cannot be accessed)
3637
* @returns {boolean}
3738
*/
38-
export function can_be_parallelized(expression, scope, analysis) {
39+
export function can_be_parallelized(expression, scope, analysis, bindings) {
3940
let has_closures = false;
4041
/** @type {Set<string>} */
4142
const references = new Set();
@@ -70,6 +71,10 @@ export function can_be_parallelized(expression, scope, analysis) {
7071
return false;
7172
}
7273

74+
if (bindings.includes(binding)) {
75+
return false;
76+
}
77+
7378
if (binding.kind === 'derived') {
7479
const init = /** @type {CallExpression} */ (binding.initial);
7580
if (analysis.async_deriveds.has(init)) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ export function Program(node, context) {
141141
const body = [];
142142
for (let i = 0; i < node.body.length; i++) {
143143
const transformed = /** @type {Program['body'][number]} */ (context.visit(node.body[i]));
144-
const chunk = context.state.parallelized_derived_chunks?.at(-1);
144+
const chunk = context.state.parallelized_chunks?.at(-1);
145145
body.push(transformed);
146146
if (chunk && chunk.position === i) {
147147
if (chunk.declarators.length === 1) {

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

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,52 @@ export function VariableDeclaration(node, context) {
4545

4646
continue;
4747
}
48+
if (
49+
init.type === 'AwaitExpression' &&
50+
context.state.analysis.instance?.scope === context.state.scope
51+
) {
52+
const parallelize = can_be_parallelized(
53+
init.argument,
54+
context.state.scope,
55+
context.state.analysis,
56+
context.state.current_parallelized_chunk?.bindings ?? []
57+
);
58+
if (parallelize) {
59+
const bindings = context.state.scope.get_bindings(declarator);
60+
const visited = /** @type {VariableDeclarator} */ (
61+
context.visit({
62+
...declarator,
63+
init: init.argument
64+
})
65+
);
66+
const declarators = [
67+
{
68+
id: visited.id,
69+
init: /** @type {Expression} */ (visited.init)
70+
}
71+
];
72+
if (
73+
context.state.current_parallelized_chunk &&
74+
context.state.current_parallelized_chunk.kind === node.kind
75+
) {
76+
context.state.current_parallelized_chunk.declarators.push(...declarators);
77+
context.state.current_parallelized_chunk.bindings.push(...bindings);
78+
context.state.current_parallelized_chunk.position = /** @type {Program} */ (
79+
context.path.at(-1)
80+
).body.indexOf(node);
81+
} else {
82+
const chunk = {
83+
kind: node.kind,
84+
declarators,
85+
position: /** @type {Program} */ (context.path.at(-1)).body.indexOf(node),
86+
bindings
87+
};
88+
context.state.current_parallelized_chunk = chunk;
89+
context.state.parallelized_chunks.push(chunk);
90+
}
91+
continue;
92+
}
93+
}
4894
declarations.push(/** @type {VariableDeclarator} */ (context.visit(declarator)));
4995
continue;
5096
}
@@ -215,11 +261,18 @@ export function VariableDeclaration(node, context) {
215261
// TODO make it work without this
216262
declarator.id.type === 'Identifier'
217263
) {
218-
parallelize = can_be_parallelized(value, context.state.scope, context.state.analysis);
264+
parallelize = can_be_parallelized(
265+
value,
266+
context.state.scope,
267+
context.state.analysis,
268+
context.state.current_parallelized_chunk?.bindings ?? []
269+
);
219270
}
220271

221272
/** @type {VariableDeclarator[]} */
222273
const derived_declarators = [];
274+
/** @type {Binding[]} */
275+
const bindings = [];
223276

224277
if (declarator.id.type === 'Identifier') {
225278
let expression = /** @type {Expression} */ (
@@ -239,15 +292,13 @@ export function VariableDeclaration(node, context) {
239292

240293
if (!parallelize) call = b.call(b.await(b.call('$.save', call)));
241294
if (dev) call = b.call('$.tag', call, b.literal(declarator.id.name));
242-
295+
bindings.push(/** @type {Binding} */ (context.state.scope.get(declarator.id.name)));
243296
derived_declarators.push(b.declarator(declarator.id, call));
244297
} else {
245298
if (rune === '$derived') expression = b.thunk(expression);
246299

247300
let call = b.call('$.derived', expression);
248301
if (dev) call = b.call('$.tag', call, b.literal(declarator.id.name));
249-
250-
derived_declarators.push(b.declarator(declarator.id, call));
251302
}
252303
} else {
253304
const init = /** @type {CallExpression} */ (declarator.init);
@@ -273,17 +324,13 @@ export function VariableDeclaration(node, context) {
273324
b.thunk(expression, true),
274325
location ? b.literal(location) : undefined
275326
);
276-
if (!parallelize) {
277-
call = b.call(b.await(b.call('$.save', call)));
278-
}
327+
call = b.call(b.await(b.call('$.save', call)));
279328
}
280329

281330
if (dev) {
282331
const label = `[$derived ${declarator.id.type === 'ArrayPattern' ? 'iterable' : 'object'}]`;
283332
call = b.call('$.tag', call, b.literal(label));
284333
}
285-
286-
derived_declarators.push(b.declarator(id, call));
287334
}
288335

289336
const { inserts, paths } = extract_paths(declarator.id, rhs);
@@ -299,8 +346,6 @@ export function VariableDeclaration(node, context) {
299346
const label = `[$derived ${declarator.id.type === 'ArrayPattern' ? 'iterable' : 'object'}]`;
300347
call = b.call('$.tag', call, b.literal(label));
301348
}
302-
303-
derived_declarators.push(b.declarator(id, call));
304349
}
305350

306351
for (const path of paths) {
@@ -327,19 +372,22 @@ export function VariableDeclaration(node, context) {
327372
}));
328373
if (
329374
context.state.current_parallelized_chunk &&
330-
context.state.current_parallelized_chunk.kind === node.kind &&
331-
context.state.current_parallelized_chunk.position ===
332-
/** @type {Program} */ (context.path.at(-1)).body.indexOf(node)
375+
context.state.current_parallelized_chunk.kind === node.kind
333376
) {
334377
context.state.current_parallelized_chunk.declarators.push(...declarators);
378+
context.state.current_parallelized_chunk.bindings.push(...bindings);
379+
context.state.current_parallelized_chunk.position = /** @type {Program} */ (
380+
context.path.at(-1)
381+
).body.indexOf(node);
335382
} else {
336383
const chunk = {
337384
kind: node.kind,
338385
declarators,
339-
position: /** @type {Program} */ (context.path.at(-1)).body.indexOf(node)
386+
position: /** @type {Program} */ (context.path.at(-1)).body.indexOf(node),
387+
bindings
340388
};
341389
context.state.current_parallelized_chunk = chunk;
342-
context.state.parallelized_derived_chunks.push(chunk);
390+
context.state.parallelized_chunks.push(chunk);
343391
}
344392
}
345393

0 commit comments

Comments
 (0)