1
+ import fetch from './fetch.js' ;
1
2
import { Exit , Environment , directoryFromTree , directoryIntoTree } from './wasi-virt.js' ;
2
3
import { lineBuffered } from './util.js' ;
3
4
4
5
export { Exit } from './wasi-virt.js' ;
5
6
6
- export class BaseApplication {
7
+ async function fetchObject ( obj , fetchFn ) {
8
+ // Mutate the object being fetched, to avoid re-fetches within the same session.
9
+ // Do this in parallel to avoid head-of-line blocking.
10
+ const promises = [ ] ;
11
+ for ( const [ key , value ] of Object . entries ( obj ) ) {
12
+ if ( typeof value === "string" || value instanceof Uint8Array ) {
13
+ promises . push ( Promise . resolve ( [ key , value ] ) ) ;
14
+ } else if ( value instanceof URL ) {
15
+ promises . push ( fetchFn ( value ) . then ( ( fetched ) => [ key , fetched ] ) ) ;
16
+ } else {
17
+ promises . push ( fetchObject ( value , fetchFn ) . then ( ( fetched ) => [ key , fetched ] ) ) ;
18
+ }
19
+ }
20
+ for ( const [ key , value ] of await Promise . all ( promises ) )
21
+ obj [ key ] = value ;
22
+ return obj ;
23
+ }
24
+
25
+ function fetchWebAssembly ( url ) {
26
+ return fetch ( url ) . then ( WebAssembly . compileStreaming ) ;
27
+ }
28
+
29
+ function fetchUint8Array ( url ) {
30
+ return fetch ( url ) . then ( ( resp ) => resp . arrayBuffer ( ) ) . then ( ( buf ) => new Uint8Array ( buf ) ) ;
31
+ }
32
+
33
+ function fetchResources ( { modules, filesystem } ) {
34
+ return Promise . all ( [
35
+ fetchObject ( modules , fetchWebAssembly ) ,
36
+ fetchObject ( filesystem , fetchUint8Array )
37
+ ] ) . then ( ( [ modules , filesystem ] ) => {
38
+ return { modules, filesystem } ;
39
+ } ) ;
40
+ }
41
+
42
+ export class Application {
7
43
constructor ( resourceFileURL , instantiate , argv0 ) {
8
44
this . resourceFileURL = resourceFileURL ;
9
45
this . resources = null ;
@@ -14,10 +50,10 @@ export class BaseApplication {
14
50
// The `printLine` option is deprecated and not documented but still accepted for compatibility.
15
51
async run ( args = null , files = { } , { stdout, stderr, decodeASCII = true , printLine } = { } ) {
16
52
if ( this . resources === null )
17
- this . resources = await this . _fetchResources ( ) ;
53
+ this . resources = await import ( this . resourceFileURL ) . then ( fetchResources ) ;
18
54
19
55
if ( args === null )
20
- return ; // only fetch resources
56
+ return ; // prefetch resources, but do not run
21
57
22
58
const environment = new Environment ( ) ;
23
59
environment . args = [ this . argv0 ] . concat ( args ) ;
@@ -51,39 +87,4 @@ export class BaseApplication {
51
87
return files ;
52
88
}
53
89
}
54
-
55
- async _fetchResources ( ) {
56
- // Async import, to allow inlining some of the resources within resource file.
57
- const { modules, filesystem } = await import ( this . resourceFileURL ) ;
58
- return {
59
- modules : await this . _fetchObject ( modules , this . _fetchWebAssembly ) ,
60
- filesystem : await this . _fetchObject ( filesystem , this . _fetchUint8Array ) ,
61
- } ;
62
- }
63
-
64
- async _fetchObject ( obj , fetchFn ) {
65
- // Mutate the object being fetched, to avoid re-fetches within the same session.
66
- // Do this in parallel to avoid head-of-line blocking.
67
- const promises = [ ] ;
68
- for ( const [ key , value ] of Object . entries ( obj ) ) {
69
- if ( value instanceof URL ) {
70
- promises . push ( fetchFn ( value ) . then ( ( fetched ) => [ key , fetched ] ) ) ;
71
- } else if ( typeof value === "string" || value instanceof Uint8Array ) {
72
- promises . push ( Promise . resolve ( [ key , value ] ) ) ;
73
- } else {
74
- promises . push ( this . _fetchObject ( value , fetchFn ) . then ( ( fetched ) => [ key , fetched ] ) ) ;
75
- }
76
- }
77
- for ( const [ key , value ] of await Promise . all ( promises ) )
78
- obj [ key ] = value ;
79
- return obj ;
80
- }
81
-
82
- async _fetchUint8Array ( _url ) {
83
- throw 'not implemented' ;
84
- }
85
-
86
- async _fetchWebAssembly ( _url ) {
87
- throw 'not implemented' ;
88
- }
89
90
}
0 commit comments