@thi.ng/wasm-api 0.10.0 → 0.12.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.
- package/CHANGELOG.md +77 -1
- package/README.md +248 -170
- package/api.d.ts +98 -14
- package/bin/wasm-api.mjs_ +17 -0
- package/bridge.d.ts +11 -1
- package/bridge.js +15 -10
- package/cli.js +51 -9
- package/codegen/c.d.ts +33 -0
- package/codegen/c.js +100 -0
- package/codegen/c11.d.ts +22 -0
- package/codegen/c11.js +125 -0
- package/codegen/typescript.d.ts +2 -12
- package/codegen/typescript.js +119 -88
- package/codegen/utils.d.ts +53 -4
- package/codegen/utils.js +63 -5
- package/codegen/zig.d.ts +2 -9
- package/codegen/zig.js +74 -29
- package/codegen.d.ts +1 -23
- package/codegen.js +35 -8
- package/include/wasmapi.h +34 -20
- package/include/wasmapi.zig +53 -46
- package/index.d.ts +3 -0
- package/index.js +3 -0
- package/package.json +32 -19
- package/pointer.d.ts +23 -0
- package/pointer.js +27 -0
- package/string.d.ts +96 -0
- package/string.js +145 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- This file is generated - DO NOT EDIT! -->
|
|
2
2
|
|
|
3
|
-
# 
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@thi.ng/wasm-api)
|
|
6
6
|

|
|
@@ -10,17 +10,19 @@ This project is part of the
|
|
|
10
10
|
[@thi.ng/umbrella](https://github.com/thi-ng/umbrella/) monorepo.
|
|
11
11
|
|
|
12
12
|
- [About](#about)
|
|
13
|
-
- [Custom API modules](#custom-api-modules)
|
|
14
13
|
- [Data bindings & code generators](#data-bindings--code-generators)
|
|
15
14
|
- [CLI generator](#cli-generator)
|
|
16
15
|
- [Data type definitions](#data-type-definitions)
|
|
17
16
|
- [Example usage](#example-usage)
|
|
18
17
|
- [String handling](#string-handling)
|
|
19
18
|
- [Memory allocations](#memory-allocations)
|
|
19
|
+
- [Custom API modules](#custom-api-modules)
|
|
20
20
|
- [Object indices & handles](#object-indices--handles)
|
|
21
|
-
|
|
21
|
+
- [Status](#status)
|
|
22
|
+
- [Support packages](#support-packages)
|
|
22
23
|
- [Installation](#installation)
|
|
23
24
|
- [Dependencies](#dependencies)
|
|
25
|
+
- [Usage examples](#usage-examples)
|
|
24
26
|
- [API](#api)
|
|
25
27
|
- [Basic usage example](#basic-usage-example)
|
|
26
28
|
- [Zig version](#zig-version)
|
|
@@ -30,7 +32,7 @@ This project is part of the
|
|
|
30
32
|
|
|
31
33
|
## About
|
|
32
34
|
|
|
33
|
-
Generic, modular, extensible API bridge, glue code and bindings code
|
|
35
|
+
Generic, modular, extensible API bridge, polyglot glue code and bindings code generators for hybrid JS & WebAssembly projects.
|
|
34
36
|
|
|
35
37
|
This package provides a the following:
|
|
36
38
|
|
|
@@ -38,117 +40,37 @@ This package provides a the following:
|
|
|
38
40
|
[`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
|
|
39
41
|
class as interop basis and much reduced boilerplate for hybrid JS/WebAssembly
|
|
40
42
|
applications.
|
|
41
|
-
2. A minimal core API for
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
manipulation,
|
|
43
|
+
2. A minimal core API for debug output, string/pointer/typedarray accessors for
|
|
44
|
+
8/16/32/64 bit (u)ints and 32/64 bit floats, memory allocation (optional).
|
|
45
|
+
Additionally, a number of support modules for [DOM
|
|
46
|
+
manipulation](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-dom/),
|
|
47
|
+
WebGL, WebGPU, WebAudio etc. is being actively worked on.
|
|
45
48
|
3. [Include files for C11/C++ and
|
|
46
49
|
Zig](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api/include),
|
|
47
|
-
defining WASM imports of the JS [core
|
|
50
|
+
defining WASM imports of the extern JS [core
|
|
48
51
|
API](https://docs.thi.ng/umbrella/wasm-api/interfaces/CoreAPI.html) defined
|
|
49
52
|
by this package
|
|
50
|
-
4. Extensible shared datatype code generators for (currently)
|
|
51
|
-
[Zig](https://ziglang.org)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
bindings for these
|
|
53
|
+
4. Extensible shared datatype code generators for (currently) C11, TypeScript &
|
|
54
|
+
[Zig](https://ziglang.org). The latter also generates fully type checked
|
|
55
|
+
memory-mapped (zero-copy) accessors of WASM-side data. In general, all
|
|
56
|
+
languages with a WebAssembly target are supported, however currently only
|
|
57
|
+
bindings for these mentioned langs are included.
|
|
55
58
|
5. [CLI frontend/utility](#cli-generator) to invoke the code generator(s)
|
|
56
59
|
|
|
57
|
-
### Custom API modules
|
|
58
|
-
|
|
59
|
-
The
|
|
60
|
-
[`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html) is
|
|
61
|
-
extensible via custom defined API modules. Such API extensions will consist of a
|
|
62
|
-
collection of JS/TS functions & variables, their related counterparts (import
|
|
63
|
-
definitions) for the WASM target and (optionally) some shared data types
|
|
64
|
-
([bindings for which _can_ be generated by this package
|
|
65
|
-
too](#data-bindings--code-generators)).
|
|
66
|
-
|
|
67
|
-
On the JS side, custom API modules can be easily integrated via the [`IWasmAPI`
|
|
68
|
-
interface](https://docs.thi.ng/umbrella/wasm-api/interfaces/IWasmAPI.html). The
|
|
69
|
-
following example provides a brief overview:
|
|
70
|
-
|
|
71
|
-
```ts
|
|
72
|
-
import { IWasmAPI, WasmBridge } from "@thi.ng/wasm-api";
|
|
73
|
-
|
|
74
|
-
export class CustomAPI implements IWasmAPI {
|
|
75
|
-
parent!: WasmBridge;
|
|
76
|
-
|
|
77
|
-
async init(parent: WasmBridge) {
|
|
78
|
-
this.parent = parent;
|
|
79
|
-
this.parent.logger.debug("initializing custom API");
|
|
80
|
-
|
|
81
|
-
// any other tasks you might need to do...
|
|
82
|
-
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Returns object of functions to import as externals into
|
|
88
|
-
* the WASM module. These imports are merged into a larger
|
|
89
|
-
* imports object alongside the bridge's core API...
|
|
90
|
-
*/
|
|
91
|
-
getImports(): WebAssembly.Imports {
|
|
92
|
-
return {
|
|
93
|
-
/**
|
|
94
|
-
* Writes 2 random float32 numbers to given address
|
|
95
|
-
*/
|
|
96
|
-
randomVec2: (addr: number) => {
|
|
97
|
-
this.parent.f32.set(
|
|
98
|
-
[Math.random(), Math.random()],
|
|
99
|
-
addr >> 2
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
Now we can supply this custom API when creating the main WASM bridge:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
export const bridge = new WasmBridge({ custom: new CustomAPI() });
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
In Zig (or any other language of your choice) we can then utilize this custom
|
|
114
|
-
API like so (Please also see /test/index.ts` & the example further below in this
|
|
115
|
-
readme):
|
|
116
|
-
|
|
117
|
-
```zig
|
|
118
|
-
// Import JS core API
|
|
119
|
-
const js = @import("wasmapi");
|
|
120
|
-
|
|
121
|
-
/// JS external to fill vec2 w/ random values
|
|
122
|
-
/// Note: Each API module uses a separate import object to avoid naming clashes
|
|
123
|
-
/// Here we declare an external binding belonging to the "custom" import group
|
|
124
|
-
extern "custom" fn randomVec2(addr: usize) void;
|
|
125
|
-
|
|
126
|
-
export fn test_randomVec2() void {
|
|
127
|
-
var foo = [2]f32{ 0, 0 };
|
|
128
|
-
|
|
129
|
-
// print original
|
|
130
|
-
js.printF32Array(foo[0..]);
|
|
131
|
-
|
|
132
|
-
// populate foo with random numbers
|
|
133
|
-
randomVec2(@ptrToInt(&foo));
|
|
134
|
-
|
|
135
|
-
// print result
|
|
136
|
-
js.printF32Array(foo[0..]);
|
|
137
|
-
}
|
|
138
|
-
```
|
|
139
|
-
|
|
140
60
|
### Data bindings & code generators
|
|
141
61
|
|
|
142
62
|
The package provides an extensible codegeneration framework to simplify the
|
|
143
63
|
bilateral design & exchange of data structures shared between the WASM & JS host
|
|
144
64
|
env. Currently, code generators for TypeScript & Zig are supplied (more are
|
|
145
|
-
planned). A CLI wrapper is
|
|
65
|
+
planned). A CLI wrapper is available too. See the
|
|
66
|
+
[@thi.ng/wasm-api-dom](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-dom/)
|
|
67
|
+
support package for a more thorough realworld example...
|
|
146
68
|
|
|
147
69
|
#### CLI generator
|
|
148
70
|
|
|
149
71
|
The package includes a [small CLI
|
|
150
72
|
wrapper](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/src/cli.ts)
|
|
151
|
-
to invoke the
|
|
73
|
+
to invoke the code generator(s) from JSON type definitions and to write the
|
|
152
74
|
generated source code(s) to different files:
|
|
153
75
|
|
|
154
76
|
```text
|
|
@@ -156,7 +78,7 @@ $ npx @thi.ng/wasm-api
|
|
|
156
78
|
|
|
157
79
|
█ █ █ │
|
|
158
80
|
██ █ │
|
|
159
|
-
█ █ █ █ █ █ █ █ │ @thi.ng/wasm-api 0.
|
|
81
|
+
█ █ █ █ █ █ █ █ │ @thi.ng/wasm-api 0.12.0
|
|
160
82
|
█ █ █ █ █ █ █ █ █ │ Multi-language data bindings code generator
|
|
161
83
|
█ │
|
|
162
84
|
█ █ │
|
|
@@ -171,18 +93,21 @@ Flags:
|
|
|
171
93
|
|
|
172
94
|
Main:
|
|
173
95
|
|
|
96
|
+
-a FILE, --analytics FILE output file path for raw codegen analytics
|
|
174
97
|
-c FILE, --config FILE JSON config file with codegen options
|
|
175
|
-
-l ID[,..], --lang ID[,..] [multiple] target language: "ts", "zig" (default: ["ts","zig"])
|
|
98
|
+
-l ID[,..], --lang ID[,..] [multiple] target language: "c11", "ts", "zig" (default: ["ts","zig"])
|
|
176
99
|
-o FILE, --out FILE [multiple] output file path
|
|
100
|
+
-s TYPE, --string TYPE Force string type implementation: "slice", "ptr"
|
|
177
101
|
```
|
|
178
102
|
|
|
179
|
-
By default, the CLI generates sources for
|
|
180
|
-
|
|
181
|
-
|
|
103
|
+
By default, the CLI generates sources for TypeScript and Zig (in this order!).
|
|
104
|
+
Order is important, since the output file paths must be given in the same order
|
|
105
|
+
as the target languages. It's recommended to be more explicit with this. An
|
|
182
106
|
example invocation looks like:
|
|
183
107
|
|
|
184
108
|
```bash
|
|
185
|
-
wasm-api
|
|
109
|
+
wasm-api \
|
|
110
|
+
--config codegen-opts.json \
|
|
186
111
|
--lang ts -o src/generated.ts \
|
|
187
112
|
--lang zig -o src.zig/generated.zig \
|
|
188
113
|
typedefs.json
|
|
@@ -190,20 +115,34 @@ wasm-api --config codegen-opts.json \
|
|
|
190
115
|
|
|
191
116
|
The structure of the config file is as follows (all optional):
|
|
192
117
|
|
|
193
|
-
```
|
|
118
|
+
```json
|
|
194
119
|
{
|
|
195
|
-
global: { ... },
|
|
196
|
-
|
|
197
|
-
|
|
120
|
+
"global": { ... },
|
|
121
|
+
"c11": { ... },
|
|
122
|
+
"ts": { ... },
|
|
123
|
+
"zig": { ... },
|
|
198
124
|
}
|
|
199
125
|
```
|
|
200
126
|
|
|
201
127
|
More details about possible
|
|
202
128
|
[`global`](https://docs.thi.ng/umbrella/wasm-api/interfaces/CodeGenOpts.html),
|
|
129
|
+
[`c`](https://docs.thi.ng/umbrella/wasm-api/interfaces/C11Opts.html) and
|
|
203
130
|
[`ts`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TSOpts.html) and
|
|
204
131
|
[`zig`](https://docs.thi.ng/umbrella/wasm-api/interfaces/ZigOpts.html) config
|
|
205
132
|
options & values.
|
|
206
133
|
|
|
134
|
+
All code generators have support for custom code prologues & epilogues which can
|
|
135
|
+
be specified via the above options. These config options exist for both non-CLI
|
|
136
|
+
& CLI usage. For the latter, these custom code sections can also be loaded from
|
|
137
|
+
external files by specifying their file paths using `@` as prefix, e.g.
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"ts": { "pre": "@tpl/prelude.ts" },
|
|
142
|
+
"zig": { "pre": "@tpl/prelude.zig", "post": "@tpl/epilogue.zig" },
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
207
146
|
#### Data type definitions
|
|
208
147
|
|
|
209
148
|
Currently, the code generator supports structs and enums. See API docs for
|
|
@@ -262,42 +201,59 @@ codes:
|
|
|
262
201
|
<details><summary>generated.ts (generated TypeScript source)</summary>
|
|
263
202
|
|
|
264
203
|
```ts
|
|
265
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* Generated by @thi.ng/wasm-api at 2022-10-03T15:32:12.339Z - DO NOT EDIT!
|
|
206
|
+
*/
|
|
266
207
|
|
|
267
|
-
|
|
208
|
+
// @ts-ignore possibly includes unused imports
|
|
209
|
+
import { Pointer, WasmStringSlice, WasmTypeBase, WasmTypeConstructor } from "@thi.ng/wasm-api";
|
|
268
210
|
|
|
269
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
* Example struct
|
|
213
|
+
*/
|
|
270
214
|
export interface Foo extends WasmTypeBase {
|
|
271
215
|
color: Float32Array;
|
|
272
216
|
bars: Bar[];
|
|
273
|
-
/**
|
|
217
|
+
/**
|
|
218
|
+
* Unique ID
|
|
219
|
+
*/
|
|
274
220
|
id: number;
|
|
275
221
|
}
|
|
276
222
|
|
|
277
223
|
export const $Foo: WasmTypeConstructor<Foo> = (mem) => ({
|
|
278
|
-
get align() {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
224
|
+
get align() {
|
|
225
|
+
return 16;
|
|
226
|
+
},
|
|
227
|
+
get size() {
|
|
228
|
+
return 48;
|
|
229
|
+
},
|
|
230
|
+
instance: (base) => {
|
|
231
|
+
return {
|
|
232
|
+
get __base() {
|
|
233
|
+
return base;
|
|
234
|
+
},
|
|
235
|
+
get __bytes() {
|
|
236
|
+
return mem.u8.subarray(base, base + 48);
|
|
237
|
+
},
|
|
238
|
+
get color(): Float32Array {
|
|
239
|
+
const addr = base >>> 2;
|
|
240
|
+
return mem.f32.subarray(addr, addr + 4);
|
|
241
|
+
},
|
|
242
|
+
get bars(): Bar[] {
|
|
243
|
+
const addr = (base + 16);
|
|
244
|
+
const inst = $Bar(mem);
|
|
245
|
+
const slice: Bar[] = [];
|
|
246
|
+
for(let i = 0; i < 3; i++) slice.push(inst.instance(addr + i * 24));
|
|
247
|
+
return slice;
|
|
248
|
+
},
|
|
249
|
+
get id(): number {
|
|
250
|
+
return mem.u8[(base + 40)];
|
|
251
|
+
},
|
|
252
|
+
set id(x: number) {
|
|
253
|
+
mem.u8[(base + 40)] = x;
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
}
|
|
301
257
|
});
|
|
302
258
|
|
|
303
259
|
export interface Bar extends WasmTypeBase {
|
|
@@ -306,24 +262,34 @@ export interface Bar extends WasmTypeBase {
|
|
|
306
262
|
}
|
|
307
263
|
|
|
308
264
|
export const $Bar: WasmTypeConstructor<Bar> = (mem) => ({
|
|
309
|
-
get align() {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
265
|
+
get align() {
|
|
266
|
+
return 4;
|
|
267
|
+
},
|
|
268
|
+
get size() {
|
|
269
|
+
return 8;
|
|
270
|
+
},
|
|
271
|
+
instance: (base) => {
|
|
272
|
+
return {
|
|
273
|
+
get __base() {
|
|
274
|
+
return base;
|
|
275
|
+
},
|
|
276
|
+
get __bytes() {
|
|
277
|
+
return mem.u8.subarray(base, base + 8);
|
|
278
|
+
},
|
|
279
|
+
get kind(): Kind {
|
|
280
|
+
return mem.u16[base >>> 1];
|
|
281
|
+
},
|
|
282
|
+
set kind(x: Kind) {
|
|
283
|
+
mem.u16[base >>> 1] = x;
|
|
284
|
+
},
|
|
285
|
+
get flags(): number {
|
|
286
|
+
return mem.u32[(base + 4) >>> 2];
|
|
287
|
+
},
|
|
288
|
+
set flags(x: number) {
|
|
289
|
+
mem.u32[(base + 4) >>> 2] = x;
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|
|
327
293
|
});
|
|
328
294
|
|
|
329
295
|
export enum Kind {
|
|
@@ -337,7 +303,9 @@ export enum Kind {
|
|
|
337
303
|
<details><summary>generated.zig (generated Zig source)</summary>
|
|
338
304
|
|
|
339
305
|
```zig
|
|
340
|
-
//! Generated by @thi.ng/wasm-api at 2022-
|
|
306
|
+
//! Generated by @thi.ng/wasm-api at 2022-10-03T15:32:12.341Z - DO NOT EDIT!
|
|
307
|
+
|
|
308
|
+
const std = @import("std");
|
|
341
309
|
|
|
342
310
|
/// Example struct
|
|
343
311
|
pub const Foo = struct {
|
|
@@ -353,9 +321,9 @@ pub const Bar = struct {
|
|
|
353
321
|
};
|
|
354
322
|
|
|
355
323
|
pub const Kind = enum(u16) {
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
324
|
+
UNKNOWN,
|
|
325
|
+
GOOD = 100,
|
|
326
|
+
BEST = 1000,
|
|
359
327
|
};
|
|
360
328
|
```
|
|
361
329
|
</details>
|
|
@@ -439,7 +407,9 @@ reference:
|
|
|
439
407
|
Note: The provided Zig mechanism supports the idiomatic (Zig) pattern of working
|
|
440
408
|
with multiple allocators in different parts of the application and supports
|
|
441
409
|
dynamic assignments/swapping of the exposed allocator. See comments in source
|
|
442
|
-
file
|
|
410
|
+
file and
|
|
411
|
+
[tests](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api/test)
|
|
412
|
+
for more details...
|
|
443
413
|
|
|
444
414
|
```ts
|
|
445
415
|
try {
|
|
@@ -461,6 +431,95 @@ try {
|
|
|
461
431
|
}
|
|
462
432
|
```
|
|
463
433
|
|
|
434
|
+
### Custom API modules
|
|
435
|
+
|
|
436
|
+
The
|
|
437
|
+
[`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
|
|
438
|
+
can be extented via custom defined API modules. Such API extensions will consist
|
|
439
|
+
of a collection of JS/TS functions & variables, their related counterparts
|
|
440
|
+
(import definitions) for the WASM target and (optionally) some shared data types
|
|
441
|
+
([bindings for which _can_ be generated by this package
|
|
442
|
+
too](#data-bindings--code-generators)).
|
|
443
|
+
|
|
444
|
+
On the JS side, custom API modules can be easily integrated via the [`IWasmAPI`
|
|
445
|
+
interface](https://docs.thi.ng/umbrella/wasm-api/interfaces/IWasmAPI.html). The
|
|
446
|
+
following example provides a brief overview:
|
|
447
|
+
|
|
448
|
+
```ts
|
|
449
|
+
import { IWasmAPI, WasmBridge } from "@thi.ng/wasm-api";
|
|
450
|
+
|
|
451
|
+
export class CustomAPI implements IWasmAPI {
|
|
452
|
+
parent!: WasmBridge;
|
|
453
|
+
|
|
454
|
+
async init(parent: WasmBridge) {
|
|
455
|
+
this.parent = parent;
|
|
456
|
+
this.parent.logger.debug("initializing custom API");
|
|
457
|
+
|
|
458
|
+
// any other tasks you might need to do...
|
|
459
|
+
|
|
460
|
+
return true;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Returns object of functions to import as externals into the
|
|
465
|
+
* WASM module during instantiation. These imports are merged
|
|
466
|
+
* into a larger imports object alongside the bridge's core API...
|
|
467
|
+
*/
|
|
468
|
+
getImports(): WebAssembly.Imports {
|
|
469
|
+
return {
|
|
470
|
+
/**
|
|
471
|
+
* Writes `num` random float32 numbers from given address
|
|
472
|
+
*/
|
|
473
|
+
fillRandom: (addr: number, num: number) => {
|
|
474
|
+
addr >>>= 2;
|
|
475
|
+
while(num-- > 0) this.parent.f32[addr++] = Math.random();
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Now we can supply this custom API when creating the main WASM bridge:
|
|
483
|
+
|
|
484
|
+
```ts
|
|
485
|
+
export const bridge = new WasmBridge({ custom: new CustomAPI() });
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
In Zig (or any other language of your choice) we can then utilize this custom
|
|
489
|
+
API like so (Please also see
|
|
490
|
+
[tests](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api/test)
|
|
491
|
+
& other examples in this readme):
|
|
492
|
+
|
|
493
|
+
```zig
|
|
494
|
+
//! custom.zig - extern definitions of custom JS API
|
|
495
|
+
|
|
496
|
+
/// JS external to fill a slice w/ random values
|
|
497
|
+
/// Note: Each API module uses a separate import object to avoid naming clashes
|
|
498
|
+
/// Here we declare an external binding belonging to the "custom" import group
|
|
499
|
+
///
|
|
500
|
+
/// The bridge core API uses "wasmapi" as reserved import group name
|
|
501
|
+
extern "custom" fn fillRandom(addr: usize, num: usize) void;
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
```zig
|
|
505
|
+
// Import JS core API
|
|
506
|
+
const js = @import("wasmapi");
|
|
507
|
+
const custom = @import("custom.zig");
|
|
508
|
+
|
|
509
|
+
export fn test_randomVec4() void {
|
|
510
|
+
var foo = [4]f32{ 1, 2, 3, 4 };
|
|
511
|
+
|
|
512
|
+
// print original
|
|
513
|
+
js.printF32Array(foo[0..]);
|
|
514
|
+
|
|
515
|
+
// populate foo with random numbers
|
|
516
|
+
custom.fillRandom(@ptrToInt(&foo), foo.len);
|
|
517
|
+
|
|
518
|
+
// print result
|
|
519
|
+
js.printF32Array(foo[0..]);
|
|
520
|
+
}
|
|
521
|
+
```
|
|
522
|
+
|
|
464
523
|
### Object indices & handles
|
|
465
524
|
|
|
466
525
|
Since only numeric values can be exchanged between the WASM module and the JS
|
|
@@ -508,12 +567,16 @@ canvases.delete(0);
|
|
|
508
567
|
// true
|
|
509
568
|
```
|
|
510
569
|
|
|
511
|
-
|
|
570
|
+
## Status
|
|
512
571
|
|
|
513
572
|
**ALPHA** - bleeding edge / work-in-progress
|
|
514
573
|
|
|
515
574
|
[Search or submit any issues for this package](https://github.com/thi-ng/umbrella/issues?q=%5Bwasm-api%5D+in%3Atitle)
|
|
516
575
|
|
|
576
|
+
## Support packages
|
|
577
|
+
|
|
578
|
+
- [@thi.ng/wasm-api-dom](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-dom) - Browser DOM bridge API for hybrid TypeScript & Zig applications
|
|
579
|
+
|
|
517
580
|
## Installation
|
|
518
581
|
|
|
519
582
|
```bash
|
|
@@ -537,11 +600,11 @@ node --experimental-repl-await
|
|
|
537
600
|
> const wasmApi = await import("@thi.ng/wasm-api");
|
|
538
601
|
```
|
|
539
602
|
|
|
540
|
-
Package sizes (gzipped, pre-treeshake): ESM:
|
|
603
|
+
Package sizes (gzipped, pre-treeshake): ESM: 6.29 KB
|
|
541
604
|
|
|
542
|
-
**IMPORTANT:** The package includes
|
|
543
|
-
|
|
544
|
-
in production will be MUCH smaller!
|
|
605
|
+
**IMPORTANT:** The package includes code generators for various languages which
|
|
606
|
+
are **not** required for just using the API bridge. Hence, the usual package
|
|
607
|
+
size in production will be MUCH smaller than what's stated here!
|
|
545
608
|
|
|
546
609
|
## Dependencies
|
|
547
610
|
|
|
@@ -556,6 +619,20 @@ in production will be MUCH smaller!
|
|
|
556
619
|
- [@thi.ng/hex](https://github.com/thi-ng/umbrella/tree/develop/packages/hex)
|
|
557
620
|
- [@thi.ng/idgen](https://github.com/thi-ng/umbrella/tree/develop/packages/idgen)
|
|
558
621
|
- [@thi.ng/logger](https://github.com/thi-ng/umbrella/tree/develop/packages/logger)
|
|
622
|
+
- [@thi.ng/paths](https://github.com/thi-ng/umbrella/tree/develop/packages/paths)
|
|
623
|
+
- [@thi.ng/strings](https://github.com/thi-ng/umbrella/tree/develop/packages/strings)
|
|
624
|
+
|
|
625
|
+
## Usage examples
|
|
626
|
+
|
|
627
|
+
Several demos in this repo's
|
|
628
|
+
[/examples](https://github.com/thi-ng/umbrella/tree/develop/examples)
|
|
629
|
+
directory are using this package.
|
|
630
|
+
|
|
631
|
+
A selection:
|
|
632
|
+
|
|
633
|
+
| Screenshot | Description | Live demo | Source |
|
|
634
|
+
|:------------------------------------------------------------------------------------------------------------------|:--------------------------------------------|:-------------------------------------------------|:------------------------------------------------------------------------------|
|
|
635
|
+
| <img src="https://raw.githubusercontent.com/thi-ng/umbrella/develop/assets/examples/zig-canvas.png" width="240"/> | Zig-based DOM creation & canvas drawing app | [Demo](https://demo.thi.ng/umbrella/zig-canvas/) | [Source](https://github.com/thi-ng/umbrella/tree/develop/examples/zig-canvas) |
|
|
559
636
|
|
|
560
637
|
## API
|
|
561
638
|
|
|
@@ -631,16 +708,16 @@ The resulting WASM:
|
|
|
631
708
|
(type $none_=>_none (func))
|
|
632
709
|
(type $i32_=>_i32 (func (param i32) (result i32)))
|
|
633
710
|
(import "wasmapi" "_printStr" (func $fimport$0 (param i32 i32)))
|
|
634
|
-
(global $global$0 (mut i32) (i32.const
|
|
635
|
-
(memory $0
|
|
636
|
-
(data (i32.const
|
|
711
|
+
(global $global$0 (mut i32) (i32.const 1048576))
|
|
712
|
+
(memory $0 17)
|
|
713
|
+
(data (i32.const 1048576) "hello world!\00")
|
|
637
714
|
(export "memory" (memory $0))
|
|
638
715
|
(export "start" (func $0))
|
|
639
716
|
(export "_wasm_allocate" (func $1))
|
|
640
717
|
(export "_wasm_free" (func $2))
|
|
641
718
|
(func $0
|
|
642
719
|
(call $fimport$0
|
|
643
|
-
(i32.const
|
|
720
|
+
(i32.const 1048576)
|
|
644
721
|
(i32.const 12)
|
|
645
722
|
)
|
|
646
723
|
)
|
|
@@ -667,7 +744,7 @@ void WASM_KEEP start() {
|
|
|
667
744
|
Building the WASM module:
|
|
668
745
|
|
|
669
746
|
```bash
|
|
670
|
-
emcc -Os -Inode_modules/@thi.ng/wasm-api/include
|
|
747
|
+
emcc -Os -Inode_modules/@thi.ng/wasm-api/include \
|
|
671
748
|
-sERROR_ON_UNDEFINED_SYMBOLS=0 --no-entry \
|
|
672
749
|
-o hello.wasm hello.c
|
|
673
750
|
```
|
|
@@ -680,6 +757,7 @@ Resulting WASM:
|
|
|
680
757
|
(type $none_=>_none (func))
|
|
681
758
|
(type $i32_=>_i32 (func (param i32) (result i32)))
|
|
682
759
|
(type $none_=>_i32 (func (result i32)))
|
|
760
|
+
(type $i32_i32_=>_none (func (param i32 i32)))
|
|
683
761
|
(import "wasmapi" "_printStr0" (func $fimport$0 (param i32)))
|
|
684
762
|
(global $global$0 (mut i32) (i32.const 5243936))
|
|
685
763
|
(memory $0 256 256)
|
|
@@ -702,7 +780,7 @@ Resulting WASM:
|
|
|
702
780
|
(func $1 (param $0 i32) (result i32)
|
|
703
781
|
(i32.const 0)
|
|
704
782
|
)
|
|
705
|
-
(func $2 (param $0 i32)
|
|
783
|
+
(func $2 (param $0 i32) (param $1 i32)
|
|
706
784
|
(nop)
|
|
707
785
|
)
|
|
708
786
|
(func $3
|