1
1
import { APIInterface } from "./APIInterface.mjs" ;
2
- import { readFile } from "fs-extra" ;
3
- import { WASI , File , OpenFile , PreopenDirectory } from "@bjorn3/browser_wasi_shim" ;
2
+ import { WASI , File , OpenFile } from "@bjorn3/browser_wasi_shim" ;
4
3
5
4
// TODO: The Webpack way to get the WASM would be something like:
6
5
//import QueryWasm from "gbz-base/target/wasm32-wasi/release/query.wasm";
@@ -14,24 +13,32 @@ import { WASI, File, OpenFile, PreopenDirectory } from "@bjorn3/browser_wasi_shi
14
13
// fetch the WASM on either Webpack or Jest with its own strategies/by being
15
14
// swapped out.
16
15
17
- // Resolve with the bytes of the WASM query blob, on Jest or Webpack.
16
+ // Resolve with the bytes or Response of the WASM query blob, on Jest or Webpack.
18
17
async function getWasmBytes ( ) {
19
18
let blobBytes = null ;
20
19
21
- if ( ! jest ) {
22
- // Not running on Jest, we should be able to dynamic import a binary asset and get the bytes, and Webpack will handle it.
20
+ if ( ! window [ "jest" ] ) {
21
+ // Not running on Jest, we should be able to dynamic import a binary asset
22
+ // by export name and get the bytes, and Webpack will handle it.
23
23
try {
24
- blobBytes = await import ( "gbz-base/target/wasm32-wasi/release/query.wasm" ) ;
24
+ let blobImport = await import ( "gbz-base/query.wasm" ) ;
25
+ return fetch ( blobImport . default ) ;
25
26
} catch ( e ) {
26
27
console . error ( "Could not dynamically import WASM blob." , e ) ;
27
28
// Leave blobBytes unset to try a fallback method.
28
29
}
29
30
}
30
31
31
32
if ( ! blobBytes ) {
32
- // Either we're on Jest, or the dynamic import didn't work (maybe we're on plain Node?).
33
+ // Either we're on Jest, or the dynamic import didn't work (maybe we're on
34
+ // plain Node?).
35
+ //
33
36
// Try to open the file from the filesystem.
34
- blobBytes = await readFile ( "node_modules/gbz-base/target/wasm32-wasi/release/query.wasm" ) ;
37
+ //
38
+ // Don't actually try and ship the filesystem module in the browser though:
39
+ // see <https://webpack.js.org/api/module-methods/#webpackignore>
40
+ let fs = await import ( /* webpackIgnore: true */ "fs-extra" ) ;
41
+ blobBytes = await fs . readFile ( "node_modules/gbz-base/target/wasm32-wasi/release/query.wasm" ) ;
35
42
}
36
43
37
44
console . log ( "Got blob bytes: " , blobBytes ) ;
@@ -60,7 +67,16 @@ export class GBZBaseAPI extends APIInterface {
60
67
async setUp ( ) {
61
68
if ( this . compiledWasm === undefined ) {
62
69
// Kick off and save exactly one request to get and load the WASM bytes.
63
- this . compiledWasm = WebAssembly . compile ( await getWasmBytes ( ) ) ;
70
+ this . compiledWasm = getWasmBytes ( ) . then ( ( result ) => {
71
+ if ( result instanceof Response ) {
72
+ // If a fetch request was made, compile as it streams in
73
+ return WebAssembly . compileStreaming ( result ) ;
74
+ } else {
75
+ // We have all the bytes, so compile right away.
76
+ // TODO: Put this logic in the function?
77
+ return WebAssembly . compile ( result ) ;
78
+ }
79
+ } ) ;
64
80
}
65
81
66
82
// Wait for the bytes to be available.
@@ -73,10 +89,11 @@ export class GBZBaseAPI extends APIInterface {
73
89
// We need at least one command line argument to be the program name.
74
90
throw new Error ( "Not safe to invoke main() without program name" ) ;
75
91
}
76
-
92
+
93
+ // Make sure this.compiledWasm is set.
94
+ // TODO: Change to an accessor method?
77
95
await this . setUp ( ) ;
78
- let wasm = this . compiledWasm ;
79
-
96
+
80
97
// Define the places to store program input and output
81
98
let stdin = new File ( [ ] ) ;
82
99
let stdout = new File ( [ ] ) ;
@@ -106,6 +123,16 @@ export class GBZBaseAPI extends APIInterface {
106
123
console . log ( "Standard Error:" , new TextDecoder ( ) . decode ( stderr . data ) ) ;
107
124
}
108
125
}
126
+
127
+ // Return true if the WASM setup is working, and false otherwise.
128
+ async available ( ) {
129
+ try {
130
+ await this . callWasm ( [ "query" , "--help" ] ) ;
131
+ return true ;
132
+ } catch {
133
+ return false ;
134
+ }
135
+ }
109
136
110
137
/////////
111
138
// Tube Map API implementation
@@ -128,7 +155,7 @@ export class GBZBaseAPI extends APIInterface {
128
155
} ;
129
156
130
157
for ( let type of this . filesByType ) {
131
- if ( type == "bed" ) {
158
+ if ( type === "bed" ) {
132
159
// Just send all these files in bedFiles.
133
160
response . bedFiles = this . filesByType [ type ] ;
134
161
} else {
0 commit comments