1
- import { WebContainer } from '@webcontainer/api' ;
1
+ import { WebContainer , type DirectoryNode , type FileSystemTree } from '@webcontainer/api' ;
2
2
import base64 from 'base64-js' ;
3
3
import AnsiToHtml from 'ansi-to-html' ;
4
4
// @ts -ignore package exports don't have types
5
5
import * as yootils from 'yootils' ;
6
- import { get_depth } from '../../../utils/path' ;
7
- import { escape_html } from '../../../utils/escape' ;
6
+ import { get_depth } from '../../../utils/path.js ' ;
7
+ import { escape_html } from '../../../utils/escape.js ' ;
8
8
import { ready } from '../common/index.js' ;
9
+ import type { Adapter , FileStub , Stub , Warning } from '$lib/tutorial' ;
9
10
10
11
const converter = new AnsiToHtml ( {
11
12
fg : 'var(--sk-text-3)'
12
13
} ) ;
13
14
14
- /** @type { import('@webcontainer/api').WebContainer } Web container singleton */
15
- let vm ;
15
+ /** Web container singleton */
16
+ let vm : WebContainer ;
16
17
17
18
export const state = new ( class WCState {
18
19
progress = $state . raw ( { value : 0 , text : 'initialising' } ) ;
19
- /** @type {string | null } */
20
- base = $state . raw ( null ) ;
21
- /** @type {Error | null } */
22
- error = $state . raw ( null ) ;
23
- /** @type {string[] } */
24
- logs = $state . raw ( [ ] ) ;
25
- /** @type {Record<string, import('$lib/tutorial').Warning[]> } */
26
- warnings = $state . raw ( { } ) ;
20
+ base = $state . raw < string | null > ( null ) ;
21
+ error = $state . raw < Error | null > ( null ) ;
22
+ logs = $state . raw < string [ ] > ( [ ] ) ;
23
+ warnings = $state . raw < Record < string , Warning [ ] > > ( { } ) ;
27
24
} ) ( ) ;
28
25
29
- /**
30
- * @returns {Promise<import('$lib/tutorial').Adapter> }
31
- */
32
- export async function create ( ) {
26
+ export async function create ( ) : Promise < Adapter > {
33
27
state . progress = { value : 0 , text : 'loading files' } ;
34
28
35
29
const q = yootils . queue ( 1 ) ;
36
- /** @type {Map<string, Array<import('$lib/tutorial').FileStub>> } */
37
- const q_per_file = new Map ( ) ;
30
+ const q_per_file = new Map < string , Array < FileStub > > ( ) ;
38
31
39
32
/** Paths and contents of the currently loaded file stubs */
40
33
let current_stubs = stubs_to_map ( [ ] ) ;
@@ -53,14 +46,10 @@ export async function create() {
53
46
}
54
47
} ) ;
55
48
56
- /** @type { Record<string, import('$lib/tutorial').Warning[]> } */
57
- let warnings = { } ;
49
+ let warnings : Record < string , import ( '$lib/tutorial' ) . Warning [ ] > = { } ;
50
+ let timeout : any ;
58
51
59
- /** @type {any } */
60
- let timeout ;
61
-
62
- /** @param {number } msec */
63
- function schedule_to_update_warning ( msec ) {
52
+ function schedule_to_update_warning ( msec : number ) {
64
53
clearTimeout ( timeout ) ;
65
54
timeout = setTimeout ( ( ) => ( state . warnings = { ...warnings } ) , msec ) ;
66
55
}
@@ -72,8 +61,7 @@ export async function create() {
72
61
// clear screen
73
62
state . logs = [ ] ;
74
63
} else if ( chunk ?. startsWith ( 'svelte:warnings:' ) ) {
75
- /** @type {import('$lib/tutorial').Warning } */
76
- const warn = JSON . parse ( chunk . slice ( 16 ) ) ;
64
+ const warn : Warning = JSON . parse ( chunk . slice ( 16 ) ) ;
77
65
const filename = warn . filename . startsWith ( '/' ) ? warn . filename : '/' + warn . filename ;
78
66
const current = warnings [ filename ] ;
79
67
@@ -150,8 +138,7 @@ export async function create() {
150
138
return {
151
139
reset : ( stubs ) => {
152
140
return q . add ( async ( ) => {
153
- /** @type {import('$lib/tutorial').Stub[] } */
154
- const to_write = [ ] ;
141
+ const to_write : Stub [ ] = [ ] ;
155
142
156
143
const force_delete = [ ] ;
157
144
@@ -164,9 +151,7 @@ export async function create() {
164
151
continue ;
165
152
}
166
153
167
- const current = /** @type {import('$lib/tutorial').FileStub } */ (
168
- current_stubs . get ( stub . name )
169
- ) ;
154
+ const current = current_stubs . get ( stub . name ) as FileStub ;
170
155
171
156
if ( current ?. contents !== stub . contents ) {
172
157
to_write . push ( stub ) ;
@@ -235,32 +220,30 @@ export async function create() {
235
220
q_per_file . set ( file . name , ( queue = [ file ] ) ) ;
236
221
237
222
return q . add ( async ( ) => {
238
- /** @type {import('@webcontainer/api').FileSystemTree } */
239
- const root = { } ;
223
+ const root : FileSystemTree = { } ;
240
224
241
225
let tree = root ;
242
226
243
227
const path = file . name . split ( '/' ) . slice ( 1 ) ;
244
- const basename = /** @type { string } */ ( path . pop ( ) ) ;
228
+ const basename = path . pop ( ) ! ;
245
229
246
230
for ( const part of path ) {
247
231
if ( ! tree [ part ] ) {
248
- /** @type {import('@webcontainer/api').FileSystemTree } */
249
- const directory = { } ;
232
+ const directory : FileSystemTree = { } ;
250
233
251
234
tree [ part ] = {
252
235
directory
253
236
} ;
254
237
}
255
238
256
- tree = /** @type { import('@webcontainer/api').DirectoryNode } */ ( tree [ part ] ) . directory ;
239
+ tree = ( tree [ part ] as DirectoryNode ) . directory ;
257
240
}
258
241
259
242
const will_restart = is_config ( file ) ;
260
243
261
244
while ( queue && queue . length > 0 ) {
262
245
// if the file is updated many times rapidly, get the most recently updated one
263
- const file = /** @type { import('$lib/tutorial').FileStub } */ ( queue . pop ( ) ) ;
246
+ const file = queue . pop ( ) ! ;
264
247
queue . length = 0 ;
265
248
266
249
tree [ basename ] = to_file ( file ) ;
@@ -289,17 +272,11 @@ export async function create() {
289
272
} ;
290
273
}
291
274
292
- /**
293
- * @param {import('$lib/tutorial').Stub } file
294
- */
295
- function is_config ( file ) {
275
+ function is_config ( file : Stub ) {
296
276
return file . type === 'file' && is_config_path ( file . name ) ;
297
277
}
298
278
299
- /**
300
- * @param {string } path
301
- */
302
- function is_config_path ( path ) {
279
+ function is_config_path ( path : string ) {
303
280
return [ '/vite.config.js' , '/svelte.config.js' , '/.env' ] . includes ( path ) ;
304
281
}
305
282
@@ -322,13 +299,8 @@ function wait_for_restart_vite() {
322
299
} ) ;
323
300
}
324
301
325
- /**
326
- * @param {import('$lib/tutorial').Stub[] } stubs
327
- * @returns {import('@webcontainer/api').FileSystemTree }
328
- */
329
- function convert_stubs_to_tree ( stubs , depth = 1 ) {
330
- /** @type {import('@webcontainer/api').FileSystemTree } */
331
- const tree = { } ;
302
+ function convert_stubs_to_tree ( stubs : Stub [ ] , depth = 1 ) {
303
+ const tree : FileSystemTree = { } ;
332
304
333
305
for ( const stub of stubs ) {
334
306
if ( get_depth ( stub . name ) === depth ) {
@@ -347,8 +319,7 @@ function convert_stubs_to_tree(stubs, depth = 1) {
347
319
return tree ;
348
320
}
349
321
350
- /** @param {import('$lib/tutorial').FileStub } file */
351
- function to_file ( file ) {
322
+ function to_file ( file : FileStub ) {
352
323
// special case
353
324
if ( file . name === '/src/app.html' || file . name === '/src/error.html' ) {
354
325
const contents = file . contents + '<script type="module" src="/src/__client.js"></script>' ;
@@ -365,11 +336,7 @@ function to_file(file) {
365
336
} ;
366
337
}
367
338
368
- /**
369
- * @param {import('$lib/tutorial').Stub[] } files
370
- * @returns {Map<string, import('$lib/tutorial').Stub> }
371
- */
372
- function stubs_to_map ( files , map = new Map ( ) ) {
339
+ function stubs_to_map ( files : Stub [ ] , map = new Map < string , Stub > ( ) ) {
373
340
for ( const file of files ) {
374
341
map . set ( file . name , file ) ;
375
342
}
0 commit comments