@thi.ng/wasm-api 0.6.0 → 0.9.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2022-08-15T15:40:55Z
3
+ - **Last updated**: 2022-08-23T10:37:04Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,42 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [0.9.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.9.0) (2022-08-23)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add debug() core API function ([ca01978](https://github.com/thi-ng/umbrella/commit/ca01978))
17
+
18
+ #### 🩹 Bug fixes
19
+
20
+ - update setString() return value ([116dd0b](https://github.com/thi-ng/umbrella/commit/116dd0b))
21
+ - always only return num bytes written w/o sentinel
22
+
23
+ ## [0.8.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.8.0) (2022-08-16)
24
+
25
+ #### 🚀 Features
26
+
27
+ - add preliminary string handling support ([3da4efe](https://github.com/thi-ng/umbrella/commit/3da4efe))
28
+ - update/rename IWasmMemoryAccess (add string getter/setter)
29
+ - update StructField.type (add `string`)
30
+ - add CodeGenOpts.stringType option
31
+ - update codegen fns
32
+ - update TS & Zig codegen impls
33
+
34
+ ## [0.7.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.7.0) (2022-08-15)
35
+
36
+ #### 🚀 Features
37
+
38
+ - add CLI wrapper for codegens ([683a560](https://github.com/thi-ng/umbrella/commit/683a560))
39
+ - update TSOpts & TS codegen ([4f6bbbf](https://github.com/thi-ng/umbrella/commit/4f6bbbf))
40
+ - add `uppercaseEnum` option to force UC enum IDs
41
+ - update helper predicates ([65b23d4](https://github.com/thi-ng/umbrella/commit/65b23d4))
42
+
43
+ #### 🩹 Bug fixes
44
+
45
+ - allow signed ints for enum tags ([78d0822](https://github.com/thi-ng/umbrella/commit/78d0822))
46
+ - correct TS __mapArray codegen ([289b137](https://github.com/thi-ng/umbrella/commit/289b137))
47
+
12
48
  ## [0.6.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.6.0) (2022-08-15)
13
49
 
14
50
  #### 🚀 Features
package/README.md CHANGED
@@ -11,11 +11,13 @@ This project is part of the
11
11
 
12
12
  - [About](#about)
13
13
  - [Custom API modules](#custom-api-modules)
14
- - [Object indices & handles](#object-indices--handles)
15
14
  - [Data bindings & code generators](#data-bindings--code-generators)
15
+ - [CLI generator](#cli-generator)
16
16
  - [Data type definitions](#data-type-definitions)
17
- - [Code generation](#code-generation)
18
17
  - [Example usage](#example-usage)
18
+ - [String handling](#string-handling)
19
+ - [Memory allocations](#memory-allocations)
20
+ - [Object indices & handles](#object-indices--handles)
19
21
  - [Status](#status)
20
22
  - [Installation](#installation)
21
23
  - [Dependencies](#dependencies)
@@ -36,23 +38,31 @@ This package provides a the following:
36
38
  [`WasmBridge`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html)
37
39
  class as interop basis and much reduced boilerplate for hybrid JS/WebAssembly
38
40
  applications.
39
- 2. A minimal core API for debug output, string, pointer, typed array accessors
40
- (8/16/32/64 bit (u)ints, 32/64 bit floats). In the future we aim to also supply
41
- support modules for DOM manipulation, WebGL, WebGPU, WebAudio etc.
42
- 3. Extensible shared datatype code generators for (currently)
43
- [Zig](https://ziglang.org) & TypeScript. The latter also generates fully type
44
- checked memory-mapped accessors of WASM-side data. In general, all languages
45
- with a WebAssembly target are supported, however currently only bindings for
46
- these few langs are included.
47
- 4. Include files for C11 and Zig, defining imports for the JS core API defined
41
+ 2. A minimal core API for memory allocation (can be disabled), debug output,
42
+ string/pointer/typedarray accessors for 8/16/32/64 bit (u)ints and 32/64 bit
43
+ floats. In the future we aim to also supply support modules for DOM
44
+ manipulation, WebGL, WebGPU, WebAudio etc.
45
+ 3. [Include files for C11/C++ and
46
+ Zig](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api/include),
47
+ defining WASM imports of the JS [core
48
+ API](https://docs.thi.ng/umbrella/wasm-api/interfaces/CoreAPI.html) defined
48
49
  by this package
50
+ 4. Extensible shared datatype code generators for (currently)
51
+ [Zig](https://ziglang.org) & TypeScript. The latter also generates fully type
52
+ checked memory-mapped (zero-copy) accessors of WASM-side data. In general,
53
+ all languages with a WebAssembly target are supported, however currently only
54
+ bindings for these few langs are included.
55
+ 5. [CLI frontend/utility](#cli-generator) to invoke the code generator(s)
49
56
 
50
57
  ### Custom API modules
51
58
 
52
- The WasmBridge is extensible via custom defined API modules. Such API extensions
53
- will consist of a collection of JS/TS functions & variables, their related
54
- counterparts (import definitions) for the WASM target and (optionally) some
55
- shared data types (bindings for which _can_ be generated by this package too).
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)).
56
66
 
57
67
  On the JS side, custom API modules can be easily integrated via the [`IWasmAPI`
58
68
  interface](https://docs.thi.ng/umbrella/wasm-api/interfaces/IWasmAPI.html). The
@@ -127,6 +137,314 @@ export fn test_randomVec2() void {
127
137
  }
128
138
  ```
129
139
 
140
+ ### Data bindings & code generators
141
+
142
+ The package provides an extensible codegeneration framework to simplify the
143
+ bilateral design & exchange of data structures shared between the WASM & JS host
144
+ env. Currently, code generators for TypeScript & Zig are supplied (more are
145
+ planned). A CLI wrapper is worked on too.
146
+
147
+ #### CLI generator
148
+
149
+ The package includes a [small CLI
150
+ wrapper](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/src/cli.ts)
151
+ to invoke the codegenerator(s) from JSON type definitions and to write the
152
+ generated source code(s) to different files:
153
+
154
+ ```text
155
+ $ npx @thi.ng/wasm-api
156
+
157
+ █ █ █ │
158
+ ██ █ │
159
+ █ █ █ █ █ █ █ █ │ @thi.ng/wasm-api 0.6.0
160
+ █ █ █ █ █ █ █ █ █ │ Multi-language data bindings code generator
161
+ █ │
162
+ █ █ │
163
+
164
+ usage: wasm-api [OPTS] JSON-INPUT-FILE(S) ...
165
+ wasm-api --help
166
+
167
+ Flags:
168
+
169
+ -d, --debug enable debug output
170
+ --dry-run enable dry run (don't overwrite files)
171
+
172
+ Main:
173
+
174
+ -c FILE, --config FILE JSON config file with codegen options
175
+ -l ID[,..], --lang ID[,..] [multiple] target language: "ts", "zig" (default: ["ts","zig"])
176
+ -o FILE, --out FILE [multiple] output file path
177
+ ```
178
+
179
+ By default, the CLI generates sources for both TypeScript and Zig (in this
180
+ order!). Order is important, since the output file paths must be given in the
181
+ same order as the target languages. It's recommended to be more explicit. An
182
+ example invocation looks like:
183
+
184
+ ```bash
185
+ wasm-api --config codegen-opts.json \
186
+ --lang ts -o src/generated.ts \
187
+ --lang zig -o src.zig/generated.zig \
188
+ typedefs.json
189
+ ```
190
+
191
+ The structure of the config file is as follows (all optional):
192
+
193
+ ```text
194
+ {
195
+ global: { ... },
196
+ ts: { ... },
197
+ zig: { ... },
198
+ }
199
+ ```
200
+
201
+ More details about possible
202
+ [`global`](https://docs.thi.ng/umbrella/wasm-api/interfaces/CodeGenOpts.html),
203
+ [`ts`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TSOpts.html) and
204
+ [`zig`](https://docs.thi.ng/umbrella/wasm-api/interfaces/ZigOpts.html) config
205
+ options & values.
206
+
207
+ #### Data type definitions
208
+
209
+ Currently, the code generator supports structs and enums. See API docs for
210
+ further details:
211
+
212
+ - [`Enum`](https://docs.thi.ng/umbrella/wasm-api/interfaces/Enum.html)
213
+ - [`EnumValue`](https://docs.thi.ng/umbrella/wasm-api/interfaces/EnumValue.html)
214
+ - [`Struct`](https://docs.thi.ng/umbrella/wasm-api/interfaces/Struct.html)
215
+ - [`StructField`](https://docs.thi.ng/umbrella/wasm-api/interfaces/StructField.html)
216
+ - [`TopLevelType`](https://docs.thi.ng/umbrella/wasm-api/interfaces/TopLevelType.html)
217
+
218
+ #### Example usage
219
+
220
+ Below is an example file with JSON type definitions and the resulting source
221
+ codes:
222
+
223
+ **⬇︎ CLICK TO EXPAND EACH CODE BLOCK ⬇︎**
224
+
225
+ <details><summary>types.json (Type definitions)</summary>
226
+
227
+ ```json
228
+ [
229
+ {
230
+ "name": "Foo",
231
+ "type": "struct",
232
+ "doc": "Example struct",
233
+ "auto": true,
234
+ "fields": [
235
+ { "name": "id", "type": "u8", "doc": "Unique ID" },
236
+ { "name": "bars", "type": "Bar", "tag": "array", "len": 3 },
237
+ { "name": "color", "type": "f32", "tag": "vec", "len": 4 }
238
+ ]
239
+ },
240
+ {
241
+ "name": "Bar",
242
+ "type": "struct",
243
+ "fields": [
244
+ { "name": "kind", "type": "Kind" },
245
+ { "name": "flags", "type": "u32" }
246
+ ]
247
+ },
248
+ {
249
+ "name": "Kind",
250
+ "type": "enum",
251
+ "tag": "u16",
252
+ "values": [
253
+ "unknown",
254
+ { "name": "good", "value": 100 },
255
+ { "name": "best", "value": 1000 }
256
+ ]
257
+ }
258
+ ]
259
+ ```
260
+ </details>
261
+
262
+ <details><summary>generated.ts (generated TypeScript source)</summary>
263
+
264
+ ```ts
265
+ /** Generated by @thi.ng/wasm-api at 2022-08-15T22:32:21.189Z - DO NOT EDIT! */
266
+
267
+ import type { WasmTypeBase, WasmTypeConstructor } from "@thi.ng/wasm-api";
268
+
269
+ /** Example struct */
270
+ export interface Foo extends WasmTypeBase {
271
+ color: Float32Array;
272
+ bars: Bar[];
273
+ /** Unique ID */
274
+ id: number;
275
+ }
276
+
277
+ export const $Foo: WasmTypeConstructor<Foo> = (mem) => ({
278
+ get align() { return 16; },
279
+ get size() { return 48; },
280
+ instance: (base) => ({
281
+ get __base() { return base; },
282
+ get __bytes() { return mem.u8.subarray(base, base + 48); },
283
+ get color(): Float32Array {
284
+ const addr = base >>> 2;
285
+ return mem.f32.subarray(addr, addr + 4);
286
+ },
287
+ get bars(): Bar[] {
288
+ const addr = (base + 16);
289
+ const inst = $Bar(mem);
290
+ const slice: Bar[] = [];
291
+ for(let i = 0; i < 3; i++) slice.push(inst.instance(addr + i * 24));
292
+ return slice;
293
+ },
294
+ get id(): number {
295
+ return mem.u8[(base + 40)];
296
+ },
297
+ set id(x: number) {
298
+ mem.u8[(base + 40)] = x;
299
+ },
300
+ })
301
+ });
302
+
303
+ export interface Bar extends WasmTypeBase {
304
+ kind: Kind;
305
+ flags: number;
306
+ }
307
+
308
+ export const $Bar: WasmTypeConstructor<Bar> = (mem) => ({
309
+ get align() { return 4; },
310
+ get size() { return 8; },
311
+ instance: (base) => ({
312
+ get __base() { return base; },
313
+ get __bytes() { return mem.u8.subarray(base, base + 8); },
314
+ get kind(): Kind {
315
+ return mem.u16[base >>> 1];
316
+ },
317
+ set kind(x: Kind) {
318
+ mem.u16[base >>> 1] = x;
319
+ },
320
+ get flags(): number {
321
+ return mem.u32[(base + 4) >>> 2];
322
+ },
323
+ set flags(x: number) {
324
+ mem.u32[(base + 4) >>> 2] = x;
325
+ },
326
+ })
327
+ });
328
+
329
+ export enum Kind {
330
+ UNKNOWN,
331
+ GOOD = 100,
332
+ BEST = 1000,
333
+ }
334
+ ```
335
+ </details>
336
+
337
+ <details><summary>generated.zig (generated Zig source)</summary>
338
+
339
+ ```zig
340
+ //! Generated by @thi.ng/wasm-api at 2022-08-15T22:32:21.191Z - DO NOT EDIT!
341
+
342
+ /// Example struct
343
+ pub const Foo = struct {
344
+ color: @Vector(4, f32),
345
+ bars: [3]Bar,
346
+ /// Unique ID
347
+ id: u8,
348
+ };
349
+
350
+ pub const Bar = struct {
351
+ kind: Kind,
352
+ flags: u32,
353
+ };
354
+
355
+ pub const Kind = enum(u16) {
356
+ unknown,
357
+ good = 100,
358
+ best = 1000,
359
+ };
360
+ ```
361
+ </details>
362
+
363
+ On the TypeScript/JS side, the memory-mapped wrappers (e.g. `$Foo` and `$Bar`)
364
+ can be used in combination with the `WasmBridge` to obtain fully typed views
365
+ (according to the generated types) of the underlying WASM memory. Basic usage is
366
+ like:
367
+
368
+ ```ts
369
+ import { WasmBridge } from "@thi.ng/wasm-api";
370
+ import { $Foo, Kind } from "./generated.ts";
371
+
372
+ const bridge = new WasmBridge();
373
+ // bridge initialization omitted here (see other examples below)
374
+ // ...
375
+
376
+ // Create an instance using the bridge's memory views
377
+ // and mapping a `Foo` struct from given address
378
+ // (e.g. obtained from an exported WASM function/value)
379
+ const foo = $Foo(bridge).instance(0x10000);
380
+
381
+ // then use like normal JS object
382
+ foo.color
383
+ // Float32Array(4) [0.1, 0.2, 0.3, 0.4]
384
+
385
+ // this even applies to arrays using other types
386
+ foo.bars[2].kind = Kind.BEST;
387
+
388
+ // IMPORTANT: any modifications like this are directly
389
+ // applied to the underlying WASM memory...
390
+ ```
391
+
392
+ **IMPORTANT:** Struct field setters are currently only supported for single
393
+ values, incl. enums, strings, structs. The latter 2 will always be copied by
394
+ value (mem copy). Arrays or slices of strings do not currently provide write
395
+ access...
396
+
397
+ ### String handling
398
+
399
+ Most low-level languages deal with strings very differently and alas there's no
400
+ general standard. Some have UTF-8/16 support, others don't. In some languages
401
+ (incl. C & Zig), strings are stored as zero terminated, in others they aren't...
402
+ It's outside the scope of this package to provide an allround out-of-the-box
403
+ solution. The `WasmBridge` provides read & write accessors to obtain JS strings
404
+ from UTF-8 encoded WASM memory. See
405
+ [`getString()`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html#getString)
406
+ and
407
+ [`setString()`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html#setString)
408
+ for details.
409
+
410
+ The code generators too provide a global `stringType` option to
411
+ interpret the `string` type of a struct field in different ways:
412
+
413
+ - `slice` (default): Considers strings as Zig-style slices (i.e. pointer + length)
414
+ - `ptr`: Considers strings as C-style raw `*char` pointer (without any length)
415
+
416
+ Note: If setting this global option to `ptr`, it also has to be repeated for the
417
+ TypeScript code generator explicitly.
418
+
419
+ ### Memory allocations
420
+
421
+ The `WasmBridge` includes support for malloc/free-style allocations (within the
422
+ linear WASM memory), _unless_ these are explicitly disabled on the WASM side. Please see for further reference:
423
+
424
+ - [`/include/wasmapi.zig`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/include/wasmapi.zig#L6) - comments about WASM-side allocator handling
425
+ - [`WasmBridge.allocate()`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html#allocate) - allocating memory from JS side
426
+ - [`WasmBridge.free()`](https://docs.thi.ng/umbrella/wasm-api/classes/WasmBridge.html#free) - freeing previously allocated memory
427
+
428
+ ```ts
429
+ try {
430
+ // allocate 1KB of memory for passing a string to WASM side
431
+ const addr = bridge.allocate(256);
432
+
433
+ // write string to reserved memory
434
+ // max. 256 bytes written, zero terminated
435
+ const num = bridge.setString("hello WASM world!", addr, 256, true);
436
+
437
+ // call WASM function doing something w/ the string
438
+ bridge.exports.doSomethingWithString(addr, num);
439
+
440
+ // cleanup
441
+ bridge.free(addr, 256);
442
+ } catch(e) {
443
+ // allocation error
444
+ // ...
445
+ }
446
+ ```
447
+
130
448
  ### Object indices & handles
131
449
 
132
450
  Since only numeric values can be exchanged between the WASM module and the JS
@@ -174,29 +492,6 @@ canvases.delete(0);
174
492
  // true
175
493
  ```
176
494
 
177
- ### Data bindings & code generators
178
-
179
- The package provides an extensible codegeneration framework to simplify the
180
- bilateral design & exchange of data structures shared between the WASM & JS host
181
- env. Currently, code generators for TypeScript & Zig are supplied (more are
182
- planned). A CLI wrapper is worked on too.
183
-
184
- #### Data type definitions
185
-
186
- TODO
187
-
188
- ##### Struct
189
-
190
- ##### Enum
191
-
192
- #### Code generation
193
-
194
- TODO
195
-
196
- #### Example usage
197
-
198
- TODO
199
-
200
495
  ### Status
201
496
 
202
497
  **ALPHA** - bleeding edge / work-in-progress
@@ -226,7 +521,7 @@ node --experimental-repl-await
226
521
  > const wasmApi = await import("@thi.ng/wasm-api");
227
522
  ```
228
523
 
229
- Package sizes (gzipped, pre-treeshake): ESM: 3.98 KB
524
+ Package sizes (gzipped, pre-treeshake): ESM: 4.34 KB
230
525
 
231
526
  **IMPORTANT:** The package includes various code generators and supporting
232
527
  functions which are NOT required during runtime. Hence the actual package size
@@ -235,11 +530,13 @@ in production will be MUCH smaller!
235
530
  ## Dependencies
236
531
 
237
532
  - [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
533
+ - [@thi.ng/args](https://github.com/thi-ng/umbrella/tree/develop/packages/args)
238
534
  - [@thi.ng/binary](https://github.com/thi-ng/umbrella/tree/develop/packages/binary)
239
535
  - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
240
536
  - [@thi.ng/compare](https://github.com/thi-ng/umbrella/tree/develop/packages/compare)
241
537
  - [@thi.ng/defmulti](https://github.com/thi-ng/umbrella/tree/develop/packages/defmulti)
242
538
  - [@thi.ng/errors](https://github.com/thi-ng/umbrella/tree/develop/packages/errors)
539
+ - [@thi.ng/file-io](https://github.com/thi-ng/umbrella/tree/develop/packages/file-io)
243
540
  - [@thi.ng/hex](https://github.com/thi-ng/umbrella/tree/develop/packages/hex)
244
541
  - [@thi.ng/idgen](https://github.com/thi-ng/umbrella/tree/develop/packages/idgen)
245
542
  - [@thi.ng/logger](https://github.com/thi-ng/umbrella/tree/develop/packages/logger)
package/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { FloatType, Fn, Fn2 } from "@thi.ng/api";
1
+ import type { BigType, FloatType, Fn, Fn2 } from "@thi.ng/api";
2
2
  import type { WasmBridge } from "./bridge.js";
3
3
  export declare const PKG_NAME = "@thi.ng/wasm-api";
4
4
  export declare type BigIntArray = bigint[] | BigInt64Array | BigUint64Array;
@@ -66,7 +66,7 @@ export interface WasmExports {
66
66
  */
67
67
  _wasm_free(addr: number, numBytes: number): void;
68
68
  }
69
- export interface WasmMemViews {
69
+ export interface IWasmMemoryAccess {
70
70
  i8: Int8Array;
71
71
  u8: Uint8Array;
72
72
  i16: Int16Array;
@@ -77,6 +77,31 @@ export interface WasmMemViews {
77
77
  u64: BigUint64Array;
78
78
  f32: Float32Array;
79
79
  f64: Float64Array;
80
+ /**
81
+ * Reads UTF-8 encoded string from given address and optional byte length.
82
+ * The default length is 0, which will be interpreted as a zero-terminated
83
+ * string. Returns string.
84
+ *
85
+ * @param addr
86
+ * @param len
87
+ */
88
+ getString(addr: number, len?: number): string;
89
+ /**
90
+ * Encodes given string as UTF-8 and writes it to WASM memory starting at
91
+ * `addr`. By default the string will be zero-terminated and only `maxBytes`
92
+ * will be written. Returns the number of bytes written.
93
+ *
94
+ * @remarks
95
+ * An error will be thrown if the encoded string doesn't fully fit into the
96
+ * designated memory region (also note that there might need to be space for
97
+ * the additional sentinel/termination byte).
98
+ *
99
+ * @param str
100
+ * @param addr
101
+ * @param maxBytes
102
+ * @param terminate
103
+ */
104
+ setString(str: string, addr: number, maxBytes: number, terminate?: boolean): number;
80
105
  }
81
106
  /**
82
107
  * Core API of WASM imports defined by the {@link WasmBridge}. The same
@@ -110,6 +135,7 @@ export interface CoreAPI extends WebAssembly.ModuleImports {
110
135
  _printF64Array: (addr: number, len: number) => void;
111
136
  _printStr0: (addr: number) => void;
112
137
  _printStr: (addr: number, len: number) => void;
138
+ debug: () => void;
113
139
  }
114
140
  export interface WasmTypeBase {
115
141
  /**
@@ -126,11 +152,12 @@ export interface WasmType<T> {
126
152
  readonly size: number;
127
153
  instance: Fn<number, T>;
128
154
  }
129
- export declare type WasmTypeConstructor<T> = Fn<WasmMemViews, WasmType<T>>;
155
+ export declare type WasmTypeConstructor<T> = Fn<IWasmMemoryAccess, WasmType<T>>;
130
156
  export declare type WasmInt = "i8" | "i16" | "i32" | "i64";
131
157
  export declare type WasmUint = "u8" | "u16" | "u32" | "u64";
132
158
  export declare type WasmFloat = FloatType;
133
159
  export declare type WasmPrim = WasmInt | WasmUint | WasmFloat;
160
+ export declare type WasmPrim32 = Exclude<WasmPrim, BigType>;
134
161
  export declare type TypeColl = Record<string, TopLevelType>;
135
162
  export interface TypeInfo {
136
163
  /**
@@ -153,16 +180,30 @@ export interface TypeInfo {
153
180
  __align?: number;
154
181
  }
155
182
  export interface TopLevelType extends TypeInfo {
183
+ /**
184
+ * Type name
185
+ */
156
186
  name: string;
187
+ /**
188
+ * Optional (multi-line) docstring for this type
189
+ */
157
190
  doc?: string;
191
+ /**
192
+ * Type / kind
193
+ */
158
194
  type: "struct" | "enum";
159
195
  }
160
196
  export interface Struct extends TopLevelType {
161
197
  type: "struct";
198
+ /**
199
+ * List of struct fields (might be re-ordered if {@link Struct.auto} is
200
+ * enabled).
201
+ */
162
202
  fields: StructField[];
163
203
  /**
164
204
  * If true, struct fields will be re-ordered in descending order based on
165
- * their {@link TypeInfo.__align} size.
205
+ * their {@link TypeInfo.__align} size. This might result in overall smaller
206
+ * structs due to minimizing inter-field padding.
166
207
  *
167
208
  * @defaultValue false
168
209
  */
@@ -178,43 +219,70 @@ export interface StructField extends TypeInfo {
178
219
  */
179
220
  doc?: string;
180
221
  /**
181
- * Field type tag/qualifier (note: `slice` & `vec` are only supported by
182
- * Zig & TS)
222
+ * Field type tag/qualifier (note: `slice` & `vec` are only supported by Zig
223
+ * & TS).
224
+ *
225
+ * @remarks
226
+ * - Array & vector fields are statically sized (using
227
+ * {@link StructField.len})
228
+ * - Pointers are emitted as single-value pointers (where this distinction
229
+ * exist), i.e. even if they're pointing to multiple values, there's no
230
+ * explicit length encoded/available
231
+ * - Zig slices are essentially a pointer w/ associated length
232
+ * - Zig vectors will be processed using SIMD (if enabled in WASM target)
233
+ * and therefore will have stricter (larger) alignment requirements.
183
234
  *
184
235
  * @defaultValue "scalar"
185
236
  */
186
237
  tag?: "scalar" | "array" | "ptr" | "slice" | "vec";
187
238
  /**
188
- * Field base type. If not a {@link WasmPrim} or `opaque`, the value is
189
- * interpreted as another type name in the {@link TypeColl}.
239
+ * Field base type. If not a {@link WasmPrim}, `string` or `opaque`, the
240
+ * value is interpreted as another type name in the {@link TypeColl}.
241
+ *
242
+ * @remarks
243
+ * Please see {@link CodeGenOpts.stringType} and consult package readme for
244
+ * further details re: string handling.
190
245
  *
191
246
  * TODO `opaque` currently unsupported.
192
247
  */
193
- type: WasmPrim | "opaque" | string;
248
+ type: WasmPrim | "string" | "opaque" | string;
194
249
  /**
195
- * TODO currently unsupported!
250
+ * TODO currently unsupported & ignored!
196
251
  */
197
252
  sentinel?: number;
198
253
  /**
199
- * Array or vector length
254
+ * Array or vector length (see {@link StructField.tag})
200
255
  */
201
256
  len?: number;
202
257
  /**
203
- * TODO currently unsupported!
258
+ * TODO currently unsupported & ignored!
204
259
  */
205
260
  default?: any;
206
261
  }
207
262
  export interface Enum extends TopLevelType {
208
263
  type: "enum";
209
264
  /**
210
- * No u64 support, due to Typescript not supporting bigint enum values
265
+ * No i64/u64 support, due to Typescript not supporting bigint enum values
266
+ */
267
+ tag: Exclude<WasmPrim32, FloatType>;
268
+ /**
269
+ * List of possible values/IDs. Use {@link EnumValue}s for more detailed
270
+ * config.
211
271
  */
212
- tag: Exclude<WasmUint, "u64">;
213
272
  values: (string | EnumValue)[];
214
273
  }
215
274
  export interface EnumValue {
275
+ /**
276
+ * Enum value name/ID
277
+ */
216
278
  name: string;
279
+ /**
280
+ * Optional associated numeric value
281
+ */
217
282
  value?: number;
283
+ /**
284
+ * Optional docstring for this value
285
+ */
218
286
  doc?: string;
219
287
  }
220
288
  export interface ICodeGen {
@@ -226,8 +294,17 @@ export interface ICodeGen {
226
294
  * Optional source code to be appended after any generated type defs.
227
295
  */
228
296
  post?: string;
297
+ /**
298
+ * Docstring codegen
299
+ */
229
300
  doc: (doc: string, indent: string, acc: string[], topLevel?: boolean) => void;
301
+ /**
302
+ * Codegen for enum types.
303
+ */
230
304
  enum: (type: Enum, types: TypeColl, acc: string[]) => void;
305
+ /**
306
+ * Codegen for struct types.
307
+ */
231
308
  struct: (type: Struct, types: TypeColl, acc: string[]) => void;
232
309
  }
233
310
  /**
package/bin/wasm-api ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # https://stackoverflow.com/a/246128/294515
4
+ SOURCE="${BASH_SOURCE[0]}"
5
+ while [ -h "$SOURCE" ]; do
6
+ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
7
+ SOURCE="$(readlink "$SOURCE")"
8
+ [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
9
+ done
10
+ DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
11
+
12
+ /usr/bin/env node "$DIR/../cli.js" "$DIR" "$@"