Skip to content

Commit e8157a9

Browse files
authored
feat: make it possible to await bundling, retrieve ASTs (#1392)
Useful for use cases like v0 which wants to await the bundle then retrieve the resulting ASTs for further analysis
1 parent 036348a commit e8157a9

File tree

3 files changed

+52
-15
lines changed

3 files changed

+52
-15
lines changed

packages/repl/src/lib/Bundler.svelte.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,22 @@ export default class Bundler {
5656
});
5757

5858
uid += 1;
59+
60+
return new Promise<void>((resolve) => {
61+
const destroy = $effect.root(() => {
62+
let first = true;
63+
$effect.pre(() => {
64+
this.result;
65+
if (first) {
66+
first = false;
67+
} else {
68+
destroy();
69+
// This isn't necessarily the result of this bundle call, as it could be
70+
// superseeded by another call to `bundle` before the result is set.
71+
resolve();
72+
}
73+
});
74+
});
75+
});
5976
}
6077
}

packages/repl/src/lib/Repl.svelte

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,16 @@
5252
text: true
5353
};
5454
55-
const workspace = new Workspace([dummy], {
55+
const workspace: Workspace = new Workspace([dummy], {
5656
initial: 'App.svelte',
5757
svelte_version: svelteVersion,
5858
onupdate() {
5959
rebundle();
6060
onchange?.();
6161
},
6262
onreset() {
63-
rebundle();
63+
// Return promise so we can await it in the workspace
64+
return rebundle();
6465
}
6566
});
6667
@@ -74,28 +75,39 @@
7475
};
7576
}
7677
77-
// TODO get rid
78+
// Our own playground / v0 need this
7879
export async function set(data: {
7980
files: File[];
8081
tailwind?: boolean;
8182
aliases?: Record<string, string>;
8283
}) {
83-
workspace.reset(
84+
// Await promise so that users (v0 in this case) can know when the bundling is done
85+
await workspace.reset(
8486
data.files,
8587
{ tailwind: data.tailwind ?? false, aliases: data.aliases },
8688
'App.svelte'
8789
);
8890
}
8991
92+
// v0 needs this
93+
export function get_asts() {
94+
return Object.fromEntries(
95+
Object.entries(workspace.compiled).map(([name, compiled]) => [
96+
name,
97+
compiled.result?.ast ?? null
98+
])
99+
);
100+
}
101+
90102
// TODO get rid
91103
export function markSaved() {
92104
workspace.mark_saved();
93105
}
94106
95107
const toggleable: ReplContext['toggleable'] = writable(false);
96108
97-
async function rebundle() {
98-
bundler!.bundle(workspace.files as File[], {
109+
function rebundle() {
110+
return bundler!.bundle(workspace.files as File[], {
99111
tailwind: workspace.tailwind,
100112
fragments: workspace.compiler_options.fragments,
101113
aliases: workspace.aliases

packages/repl/src/lib/Workspace.svelte.ts

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export class Workspace {
126126
};
127127

128128
#onupdate: (file: File) => void;
129-
#onreset: (items: Item[]) => void;
129+
#onreset: (items: Item[]) => void | Promise<void>;
130130

131131
// CodeMirror stuff
132132
states = new Map<string, EditorState>();
@@ -199,7 +199,7 @@ export class Workspace {
199199
initial?: string;
200200
readonly?: boolean;
201201
onupdate?: (file: File) => void;
202-
onreset?: (items: Item[]) => void;
202+
onreset?: (items: Item[]) => void | Promise<void>;
203203
} = {}
204204
) {
205205
this.#svelte_version = svelte_version;
@@ -414,8 +414,12 @@ export class Workspace {
414414
this.#tailwind = options.tailwind;
415415
this.#aliases = options.aliases;
416416

417-
this.#onreset(new_files);
418-
this.#reset_diagnostics();
417+
const bundle = this.#onreset(new_files);
418+
const diagnostics = this.#reset_diagnostics();
419+
420+
return Promise.all([bundle, diagnostics])
421+
.then(() => {})
422+
.catch(() => {});
419423
}
420424

421425
select(name: string) {
@@ -663,22 +667,26 @@ export class Workspace {
663667
files = [this.current, ...this.#files.slice(0, i), ...this.#files.slice(i + 1)];
664668
}
665669

666-
for (const file of files) {
667-
if (file.type !== 'file') continue;
668-
if (!is_svelte_file(file)) continue;
670+
const done = files.map((file) => {
671+
if (file.type !== 'file') return;
672+
if (!is_svelte_file(file)) return;
669673

670674
seen.push(file.name);
671675

672-
compile_file(file, this.#svelte_version, this.compiler_options).then((compiled) => {
676+
return compile_file(file, this.#svelte_version, this.compiler_options).then((compiled) => {
673677
this.compiled[file.name] = compiled;
674678
});
675-
}
679+
});
676680

677681
for (const key of keys) {
678682
if (!seen.includes(key)) {
679683
delete this.compiled[key];
680684
}
681685
}
686+
687+
return Promise.all(done)
688+
.then(() => {})
689+
.catch(() => {});
682690
}
683691

684692
#select(file: File) {

0 commit comments

Comments
 (0)