@tybys/wasm-util 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +193 -193
  2. package/dist/tsdoc-metadata.json +1 -1
  3. package/dist/wasm-util.d.ts +12 -6
  4. package/dist/wasm-util.esm-bundler.js +2639 -2607
  5. package/dist/wasm-util.esm.js +2639 -2607
  6. package/dist/wasm-util.esm.min.js +1 -1
  7. package/dist/wasm-util.js +2639 -2606
  8. package/dist/wasm-util.min.js +1 -1
  9. package/lib/cjs/asyncify.js +157 -157
  10. package/lib/cjs/index.js +12 -12
  11. package/lib/cjs/jspi.js +45 -45
  12. package/lib/cjs/load.js +96 -85
  13. package/lib/cjs/memfs.js +2689 -0
  14. package/lib/cjs/memory.js +34 -34
  15. package/lib/cjs/wasi/error.js +102 -102
  16. package/lib/cjs/wasi/fd.js +267 -267
  17. package/lib/cjs/wasi/fs.js +2 -2
  18. package/lib/cjs/wasi/index.js +193 -171
  19. package/lib/cjs/wasi/path.js +173 -173
  20. package/lib/cjs/wasi/preview1.js +1478 -1478
  21. package/lib/cjs/wasi/rights.js +139 -139
  22. package/lib/cjs/wasi/types.js +219 -219
  23. package/lib/cjs/wasi/util.js +121 -121
  24. package/lib/cjs/webassembly.js +12 -12
  25. package/lib/mjs/asyncify.mjs +153 -153
  26. package/lib/mjs/index.mjs +9 -9
  27. package/lib/mjs/jspi.mjs +39 -39
  28. package/lib/mjs/load.mjs +89 -78
  29. package/lib/mjs/memfs.mjs +2688 -0
  30. package/lib/mjs/memory.mjs +28 -28
  31. package/lib/mjs/wasi/error.mjs +97 -97
  32. package/lib/mjs/wasi/fd.mjs +256 -256
  33. package/lib/mjs/wasi/fs.mjs +1 -1
  34. package/lib/mjs/wasi/index.mjs +188 -167
  35. package/lib/mjs/wasi/path.mjs +168 -168
  36. package/lib/mjs/wasi/preview1.mjs +1474 -1474
  37. package/lib/mjs/wasi/rights.mjs +134 -134
  38. package/lib/mjs/wasi/types.mjs +216 -216
  39. package/lib/mjs/wasi/util.mjs +108 -108
  40. package/lib/mjs/webassembly.mjs +9 -9
  41. package/package.json +58 -58
package/README.md CHANGED
@@ -1,193 +1,193 @@
1
- # @tybys/wasm-util
2
-
3
- WebAssembly related utils for browser environment
4
-
5
- **The output code is ES2019**
6
-
7
- ## Features
8
-
9
- All example code below need to be bundled by ES module bundlers like `webpack` / `rollup`, or specify import map in browser native ES module runtime.
10
-
11
- ### WASI polyfill for browser
12
-
13
- The API is similar to the `require('wasi').WASI` in Node.js.
14
-
15
- You can use `memfs-browser` to provide filesystem capability.
16
-
17
- - Example: [https://github.com/toyobayashi/wasi-wabt](https://github.com/toyobayashi/wasi-wabt)
18
- - Demo: [https://toyobayashi.github.io/wasi-wabt/](https://toyobayashi.github.io/wasi-wabt/)
19
-
20
- ```js
21
- import { load, WASI } from '@tybys/wasm-util'
22
- import { Volumn, createFsFromVolume } from 'memfs-browser'
23
-
24
- const fs = createFsFromVolume(Volume.from({
25
- '/home/wasi': null
26
- }))
27
-
28
- const wasi = WASI.createSync({
29
- args: ['chrome', 'file.wasm'],
30
- env: {
31
- NODE_ENV: 'development',
32
- WASI_SDK_PATH: '/opt/wasi-sdk'
33
- },
34
- preopens: {
35
- '/': '/'
36
- },
37
- fs,
38
-
39
- // redirect stdout / stderr
40
-
41
- // print (text) { console.log(text) },
42
- // printErr (text) { console.error(text) }
43
- })
44
-
45
- const imports = {
46
- wasi_snapshot_preview1: wasi.wasiImport
47
- }
48
-
49
- const { module, instance } = await load('/path/to/file.wasm', imports)
50
- wasi.start(instance)
51
- // wasi.initialize(instance)
52
- ```
53
-
54
- Implemented syscalls: [wasi_snapshot_preview1](#wasi_snapshot_preview1)
55
-
56
- ### `load` / `loadSync`
57
-
58
- `loadSync` has 4KB wasm size limit in browser.
59
-
60
- ```js
61
- // bundler
62
- import { load, loadSync } from '@tybys/wasm-util'
63
-
64
- const imports = { /* ... */ }
65
-
66
- // using path
67
- const { module, instance } = await load('/path/to/file.wasm', imports)
68
- const { module, instance } = loadSync('/path/to/file.wasm', imports)
69
-
70
- // using URL
71
- const { module, instance } = await load(new URL('./file.wasm', import.meta.url), imports)
72
- const { module, instance } = loadSync(new URL('./file.wasm', import.meta.url), imports)
73
-
74
- // using Uint8Array
75
- const buffer = new Uint8Array([
76
- 0x00, 0x61, 0x73, 0x6d,
77
- 0x01, 0x00, 0x00, 0x00
78
- ])
79
- const { module, instance } = await load(buffer, imports)
80
- const { module, instance } = loadSync(buffer, imports)
81
-
82
- // auto asyncify
83
- const {
84
- module,
85
- instance: asyncifiedInstance
86
- } = await load(buffer, imports, { /* asyncify options */})
87
- asyncifiedInstance.exports.fn() // => return Promise
88
- ```
89
-
90
- ### Extend Memory instance
91
-
92
- ```js
93
- import { Memory, extendMemory } from '@tybys/wasm-util'
94
-
95
- const memory = new WebAssembly.Memory({ initial: 256 })
96
- // const memory = instance.exports.memory
97
-
98
- extendMemory(memory)
99
- console.log(memory instanceof Memory)
100
- console.log(memory instanceof WebAssembly.Memory)
101
- // expose memory view getters like Emscripten
102
- const { HEAPU8, HEAPU32, view } = memory
103
- ```
104
-
105
- ### Asyncify wrap
106
-
107
- Build the C code using `clang`, `wasm-ld` and `wasm-opt`
108
-
109
- ```c
110
- void async_sleep(int ms);
111
-
112
- int main() {
113
- async_sleep(200);
114
- return 0;
115
- }
116
- ```
117
-
118
- ```js
119
- import { Asyncify } from '@tybys/wasm-util'
120
-
121
- const asyncify = new Asyncify()
122
-
123
- const imports = {
124
- env: {
125
- async_sleep: asyncify.wrapImportFunction(function (ms) {
126
- return new Promise((resolve) => {
127
- setTimeout(resolve, ms)
128
- })
129
- })
130
- }
131
- }
132
-
133
- // async_sleep(200)
134
- const bytes = await (await fetch('/asyncfied_by_wasm-opt.wasm')).arrayBuffer()
135
- const { instance } = await WebAssembly.instantiate(bytes, imports)
136
- const asyncifiedInstance = asyncify.init(instance.exports.memory, instance, {
137
- wrapExports: ['_start']
138
- })
139
-
140
- const p = asyncifedInstance._start()
141
- console.log(typeof p.then === 'function')
142
- const now = Date.now()
143
- await p
144
- console.log(Date.now() - now >= 200)
145
- ```
146
-
147
- ### wasi_snapshot_preview1
148
-
149
- - [x] args_get
150
- - [x] args_sizes_get
151
- - [x] environ_get
152
- - [x] environ_sizes_get
153
- - [x] clock_res_get
154
- - [x] clock_time_get
155
- - [ ] ~~fd_advise~~
156
- - [x] fd_allocate
157
- - [x] fd_close
158
- - [x] fd_datasync
159
- - [x] fd_fdstat_get
160
- - [ ] ~~fd_fdstat_set_flags~~
161
- - [x] fd_fdstat_set_rights
162
- - [x] fd_filestat_get
163
- - [x] fd_filestat_set_size
164
- - [x] fd_filestat_set_times
165
- - [x] fd_pread
166
- - [x] fd_prestat_get
167
- - [x] fd_prestat_dir_name
168
- - [x] fd_pwrite
169
- - [x] fd_read
170
- - [x] fd_readdir
171
- - [x] fd_renumber
172
- - [x] fd_seek
173
- - [x] fd_sync
174
- - [x] fd_tell
175
- - [x] fd_write
176
- - [x] path_create_directory
177
- - [x] path_filestat_get
178
- - [x] path_filestat_set_times
179
- - [x] path_link
180
- - [x] path_open
181
- - [x] path_readlink
182
- - [x] path_remove_directory
183
- - [x] path_rename
184
- - [x] path_symlink
185
- - [x] path_unlink_file
186
- - [x] poll_oneoff (timer only)
187
- - [x] proc_exit
188
- - [ ] ~~proc_raise~~
189
- - [x] sched_yield
190
- - [x] random_get
191
- - [ ] ~~sock_recv~~
192
- - [ ] ~~sock_send~~
193
- - [ ] ~~sock_shutdown~~
1
+ # @tybys/wasm-util
2
+
3
+ WebAssembly related utils for browser environment
4
+
5
+ **The output code is ES2019**
6
+
7
+ ## Features
8
+
9
+ All example code below need to be bundled by ES module bundlers like `webpack` / `rollup`, or specify import map in browser native ES module runtime.
10
+
11
+ ### WASI polyfill for browser
12
+
13
+ The API is similar to the `require('wasi').WASI` in Node.js.
14
+
15
+ You can use `memfs-browser` to provide filesystem capability.
16
+
17
+ - Example: [https://github.com/toyobayashi/wasi-wabt](https://github.com/toyobayashi/wasi-wabt)
18
+ - Demo: [https://toyobayashi.github.io/wasi-wabt/](https://toyobayashi.github.io/wasi-wabt/)
19
+
20
+ ```js
21
+ import { load, WASI } from '@tybys/wasm-util'
22
+ import { Volumn, createFsFromVolume } from 'memfs-browser'
23
+
24
+ const fs = createFsFromVolume(Volume.from({
25
+ '/home/wasi': null
26
+ }))
27
+
28
+ const wasi = new WASI({
29
+ args: ['chrome', 'file.wasm'],
30
+ env: {
31
+ NODE_ENV: 'development',
32
+ WASI_SDK_PATH: '/opt/wasi-sdk'
33
+ },
34
+ preopens: {
35
+ '/': '/'
36
+ },
37
+ fs,
38
+
39
+ // redirect stdout / stderr
40
+
41
+ // print (text) { console.log(text) },
42
+ // printErr (text) { console.error(text) }
43
+ })
44
+
45
+ const imports = {
46
+ wasi_snapshot_preview1: wasi.wasiImport
47
+ }
48
+
49
+ const { module, instance } = await load('/path/to/file.wasm', imports)
50
+ wasi.start(instance)
51
+ // wasi.initialize(instance)
52
+ ```
53
+
54
+ Implemented syscalls: [wasi_snapshot_preview1](#wasi_snapshot_preview1)
55
+
56
+ ### `load` / `loadSync`
57
+
58
+ `loadSync` has 4KB wasm size limit in browser.
59
+
60
+ ```js
61
+ // bundler
62
+ import { load, loadSync } from '@tybys/wasm-util'
63
+
64
+ const imports = { /* ... */ }
65
+
66
+ // using path
67
+ const { module, instance } = await load('/path/to/file.wasm', imports)
68
+ const { module, instance } = loadSync('/path/to/file.wasm', imports)
69
+
70
+ // using URL
71
+ const { module, instance } = await load(new URL('./file.wasm', import.meta.url), imports)
72
+ const { module, instance } = loadSync(new URL('./file.wasm', import.meta.url), imports)
73
+
74
+ // using Uint8Array
75
+ const buffer = new Uint8Array([
76
+ 0x00, 0x61, 0x73, 0x6d,
77
+ 0x01, 0x00, 0x00, 0x00
78
+ ])
79
+ const { module, instance } = await load(buffer, imports)
80
+ const { module, instance } = loadSync(buffer, imports)
81
+
82
+ // auto asyncify
83
+ const {
84
+ module,
85
+ instance: asyncifiedInstance
86
+ } = await load(buffer, imports, { /* asyncify options */})
87
+ asyncifiedInstance.exports.fn() // => return Promise
88
+ ```
89
+
90
+ ### Extend Memory instance
91
+
92
+ ```js
93
+ import { Memory, extendMemory } from '@tybys/wasm-util'
94
+
95
+ const memory = new WebAssembly.Memory({ initial: 256 })
96
+ // const memory = instance.exports.memory
97
+
98
+ extendMemory(memory)
99
+ console.log(memory instanceof Memory)
100
+ console.log(memory instanceof WebAssembly.Memory)
101
+ // expose memory view getters like Emscripten
102
+ const { HEAPU8, HEAPU32, view } = memory
103
+ ```
104
+
105
+ ### Asyncify wrap
106
+
107
+ Build the C code using `clang`, `wasm-ld` and `wasm-opt`
108
+
109
+ ```c
110
+ void async_sleep(int ms);
111
+
112
+ int main() {
113
+ async_sleep(200);
114
+ return 0;
115
+ }
116
+ ```
117
+
118
+ ```js
119
+ import { Asyncify } from '@tybys/wasm-util'
120
+
121
+ const asyncify = new Asyncify()
122
+
123
+ const imports = {
124
+ env: {
125
+ async_sleep: asyncify.wrapImportFunction(function (ms) {
126
+ return new Promise((resolve) => {
127
+ setTimeout(resolve, ms)
128
+ })
129
+ })
130
+ }
131
+ }
132
+
133
+ // async_sleep(200)
134
+ const bytes = await (await fetch('/asyncfied_by_wasm-opt.wasm')).arrayBuffer()
135
+ const { instance } = await WebAssembly.instantiate(bytes, imports)
136
+ const asyncifiedInstance = asyncify.init(instance.exports.memory, instance, {
137
+ wrapExports: ['_start']
138
+ })
139
+
140
+ const p = asyncifedInstance._start()
141
+ console.log(typeof p.then === 'function')
142
+ const now = Date.now()
143
+ await p
144
+ console.log(Date.now() - now >= 200)
145
+ ```
146
+
147
+ ### wasi_snapshot_preview1
148
+
149
+ - [x] args_get
150
+ - [x] args_sizes_get
151
+ - [x] environ_get
152
+ - [x] environ_sizes_get
153
+ - [x] clock_res_get
154
+ - [x] clock_time_get
155
+ - [ ] ~~fd_advise~~
156
+ - [x] fd_allocate
157
+ - [x] fd_close
158
+ - [x] fd_datasync
159
+ - [x] fd_fdstat_get
160
+ - [ ] ~~fd_fdstat_set_flags~~
161
+ - [x] fd_fdstat_set_rights
162
+ - [x] fd_filestat_get
163
+ - [x] fd_filestat_set_size
164
+ - [x] fd_filestat_set_times
165
+ - [x] fd_pread
166
+ - [x] fd_prestat_get
167
+ - [x] fd_prestat_dir_name
168
+ - [x] fd_pwrite
169
+ - [x] fd_read
170
+ - [x] fd_readdir
171
+ - [x] fd_renumber
172
+ - [x] fd_seek
173
+ - [x] fd_sync
174
+ - [x] fd_tell
175
+ - [x] fd_write
176
+ - [x] path_create_directory
177
+ - [x] path_filestat_get
178
+ - [x] path_filestat_set_times
179
+ - [x] path_link
180
+ - [x] path_open
181
+ - [x] path_readlink
182
+ - [x] path_remove_directory
183
+ - [x] path_rename
184
+ - [x] path_symlink
185
+ - [x] path_unlink_file
186
+ - [x] poll_oneoff (timer only)
187
+ - [x] proc_exit
188
+ - [ ] ~~proc_raise~~
189
+ - [x] sched_yield
190
+ - [x] random_get
191
+ - [ ] ~~sock_recv~~
192
+ - [ ] ~~sock_send~~
193
+ - [ ] ~~sock_shutdown~~
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.34.4"
8
+ "packageVersion": "7.33.4"
9
9
  }
10
10
  ]
11
11
  }
@@ -32,10 +32,10 @@ export declare type AsyncifyExports<T, U> = T extends Record<string, any> ? {
32
32
  } : T;
33
33
 
34
34
  /** @public */
35
- export declare function asyncifyLoad(asyncify: AsyncifyOptions, urlOrBuffer: string | URL | BufferSource, imports?: WebAssembly.Imports): Promise<WebAssembly.WebAssemblyInstantiatedSource>;
35
+ export declare function asyncifyLoad(asyncify: AsyncifyOptions, urlOrBuffer: string | URL | BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): Promise<WebAssembly.WebAssemblyInstantiatedSource>;
36
36
 
37
37
  /** @public */
38
- export declare function asyncifyLoadSync(asyncify: AsyncifyOptions, buffer: BufferSource, imports?: WebAssembly.Imports): WebAssembly.WebAssemblyInstantiatedSource;
38
+ export declare function asyncifyLoadSync(asyncify: AsyncifyOptions, buffer: BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): WebAssembly.WebAssemblyInstantiatedSource;
39
39
 
40
40
  /** @public */
41
41
  export declare interface AsyncifyOptions {
@@ -76,6 +76,9 @@ export declare type BufferEncodingOption = 'buffer' | {
76
76
  /** @public */
77
77
  export declare type Callable = (...args: any[]) => any;
78
78
 
79
+ /** @public */
80
+ export declare function createAsyncWASI(options?: AsyncWASIOptions): Promise<WASI>;
81
+
79
82
  /** @public */
80
83
  export declare function extendMemory(memory: WebAssembly.Memory): Memory;
81
84
 
@@ -254,6 +257,8 @@ export declare interface IFsPromises {
254
257
  symlink(target: PathLike, path: PathLike, type?: 'dir' | 'file' | 'junction'): Promise<void>;
255
258
  }
256
259
 
260
+ declare const kBindingName: unique symbol;
261
+
257
262
  declare const kExitCode: unique symbol;
258
263
 
259
264
  declare const kInstance: unique symbol;
@@ -263,10 +268,10 @@ declare const kSetMemory: unique symbol;
263
268
  declare const kStarted: unique symbol;
264
269
 
265
270
  /** @public */
266
- export declare function load(urlOrBuffer: string | URL | BufferSource, imports?: WebAssembly.Imports): Promise<WebAssembly.WebAssemblyInstantiatedSource>;
271
+ export declare function load(wasmInput: string | URL | BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): Promise<WebAssembly.WebAssemblyInstantiatedSource>;
267
272
 
268
273
  /** @public */
269
- export declare function loadSync(buffer: BufferSource, imports?: WebAssembly.Imports): WebAssembly.WebAssemblyInstantiatedSource;
274
+ export declare function loadSync(wasmInput: BufferSource | WebAssembly.Module, imports?: WebAssembly.Imports): WebAssembly.WebAssemblyInstantiatedSource;
270
275
 
271
276
  /** @public */
272
277
  export declare interface MakeDirectoryOptions {
@@ -367,16 +372,17 @@ export declare class WASI {
367
372
  private [kStarted];
368
373
  private [kExitCode];
369
374
  private [kInstance];
375
+ private [kBindingName];
370
376
  readonly wasiImport: Record<string, any>;
371
- static createSync(options?: SyncWASIOptions): WASI;
372
- static createAsync(options?: AsyncWASIOptions): Promise<WASI>;
373
377
  constructor(options?: SyncWASIOptions);
374
378
  start(instance: WebAssembly.Instance): number | undefined | Promise<number> | Promise<undefined>;
375
379
  initialize(instance: WebAssembly.Instance): void | Promise<void>;
380
+ getImportObject(): Record<string, Record<string, any>>;
376
381
  }
377
382
 
378
383
  /** @public */
379
384
  export declare interface WASIOptions {
385
+ version?: 'unstable' | 'preview1';
380
386
  args?: string[] | undefined;
381
387
  env?: Record<string, string> | undefined;
382
388
  preopens?: Record<string, string> | undefined;