Skip to content

Commit 48751dc

Browse files
authored
webcontainer v1 (sveltejs#220)
1 parent 56d29e0 commit 48751dc

File tree

4 files changed

+45
-53
lines changed

4 files changed

+45
-53
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"type": "module",
3535
"dependencies": {
3636
"@fontsource/roboto-mono": "^4.5.10",
37-
"@webcontainer/api": "^0.0.8",
37+
"@webcontainer/api": "^1.0.2",
3838
"adm-zip": "^0.5.10",
3939
"base64-js": "^1.5.1",
4040
"marked": "^4.2.12",

pnpm-lock.yaml

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app.d.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
/// <reference types="@sveltejs/kit" />
2-
31
// See https://kit.svelte.dev/docs/types#app
42
// for information about these interfaces
5-
declare namespace App {
6-
// interface Locals {}
7-
// interface Platform {}
8-
// interface Session {}
9-
interface Stuff {
10-
index: import('$lib/types').PartStub[];
3+
declare global {
4+
namespace App {
5+
// interface Error {}
6+
// interface Locals {}
7+
// interface PageData {}
8+
// interface Platform {}
119
}
1210
}
11+
12+
export {};

src/lib/client/adapters/webcontainer/index.js

Lines changed: 32 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
import { load } from '@webcontainer/api';
1+
import { WebContainer } from '@webcontainer/api';
22
import base64 from 'base64-js';
33
import { get_depth } from '../../../utils.js';
44
import { ready } from '../common/index.js';
55

66
/** @type {import('@webcontainer/api').WebContainer} Web container singleton */
77
let vm;
88

9+
/** @param {string} label */
10+
function console_stream(label) {
11+
return new WritableStream({
12+
write(chunk) {
13+
console.log(`[${label}] ${chunk}`);
14+
}
15+
});
16+
}
17+
918
/**
1019
* @param {import('$lib/types').Stub[]} stubs
1120
* @param {(progress: number, status: string) => void} callback
@@ -31,15 +40,12 @@ export async function create(stubs, callback) {
3140
/** @type {boolean} Track whether there was an error from vite dev server */
3241
let vite_error = false;
3342

34-
callback(1 / 6, 'loading webcontainer');
35-
const WebContainer = await load();
36-
37-
callback(2 / 6, 'booting webcontainer');
43+
callback(1 / 5, 'booting webcontainer');
3844
vm = await WebContainer.boot();
3945

40-
callback(3 / 6, 'writing virtual files');
46+
callback(2 / 5, 'writing virtual files');
4147
const common = await ready;
42-
await vm.loadFiles({
48+
await vm.mount({
4349
'common.zip': {
4450
file: { contents: new Uint8Array(common.zipped) }
4551
},
@@ -49,24 +55,18 @@ export async function create(stubs, callback) {
4955
...convert_stubs_to_tree(stubs)
5056
});
5157

52-
callback(4 / 6, 'unzipping files');
53-
const unzip = await vm.run(
54-
{
55-
command: 'node',
56-
args: ['unzip.cjs']
57-
},
58-
{
59-
stderr: (data) => console.error(`[unzip] ${data}`)
60-
}
61-
);
62-
const code = await unzip.onExit;
58+
callback(3 / 5, 'unzipping files');
59+
const unzip = await vm.spawn('node', ['unzip.cjs']);
60+
unzip.output.pipeTo(console_stream('unzip'));
61+
const code = await unzip.exit;
62+
6363
if (code !== 0) {
6464
throw new Error('Failed to initialize WebContainer');
6565
}
6666

67-
await vm.run({ command: 'chmod', args: ['a+x', 'node_modules/vite/bin/vite.js'] });
67+
await vm.spawn('chmod', ['a+x', 'node_modules/vite/bin/vite.js']);
6868

69-
callback(5 / 6, 'starting dev server');
69+
callback(4 / 5, 'starting dev server');
7070
const base = await new Promise(async (fulfil, reject) => {
7171
const error_unsub = vm.on('error', (error) => {
7272
error_unsub();
@@ -75,27 +75,21 @@ export async function create(stubs, callback) {
7575

7676
const ready_unsub = vm.on('server-ready', (port, base) => {
7777
ready_unsub();
78-
callback(6 / 6, 'ready');
78+
callback(5 / 5, 'ready');
7979
fulfil(base); // this will be the last thing that happens if everything goes well
8080
});
8181

8282
await run_dev();
8383

8484
async function run_dev() {
85-
const process = await vm.run(
86-
{ command: 'turbo', args: ['run', 'dev'] },
87-
{
88-
stdout: (data) => {
89-
console.log(`[dev] ${data}`);
90-
},
91-
stderr: (data) => {
92-
vite_error = true;
93-
console.error(`[dev] ${data}`);
94-
}
95-
}
96-
);
85+
const process = await vm.spawn('turbo', ['run', 'dev']);
86+
87+
// TODO differentiate between stdout and stderr (sets `vite_error` to `true`)
88+
// https://github.com/stackblitz/webcontainer-core/issues/971
89+
process.output.pipeTo(console_stream('dev'));
90+
9791
// keep restarting dev server (can crash in case of illegal +files for example)
98-
process.onExit.then((code) => {
92+
process.exit.then((code) => {
9993
if (code !== 0) {
10094
setTimeout(() => {
10195
run_dev();
@@ -185,10 +179,10 @@ export async function create(stubs, callback) {
185179
// This will invoke a restart of Vite. Hacky but it works.
186180
// TODO: remove when https://github.com/vitejs/vite/issues/12127 is closed
187181
if (!previous_env && current_stubs.has('/.env')) {
188-
await vm.run({ command: 'touch', args: ['.env']});
182+
await vm.spawn('touch', ['.env']);
189183
}
190184

191-
await vm.loadFiles(convert_stubs_to_tree(to_write));
185+
await vm.mount(convert_stubs_to_tree(to_write));
192186
await promise;
193187
await new Promise((f) => setTimeout(f, 200)); // wait for chokidar
194188

@@ -220,13 +214,13 @@ export async function create(stubs, callback) {
220214
};
221215
}
222216

223-
tree = /** @type {import('@webcontainer/api').DirectoryEntry} */ (tree[part]).directory;
217+
tree = /** @type {import('@webcontainer/api').DirectoryNode} */ (tree[part]).directory;
224218
}
225219

226220
tree[basename] = to_file(stub);
227221
}
228222

229-
await vm.loadFiles(root);
223+
await vm.mount(root);
230224

231225
stubs_to_map(stubs, current_stubs);
232226

@@ -236,8 +230,6 @@ export async function create(stubs, callback) {
236230
},
237231
destroy: async () => {
238232
vm.teardown();
239-
// @ts-ignore
240-
vm = null;
241233
}
242234
};
243235
}

0 commit comments

Comments
 (0)