@thi.ng/wasm-api 0.17.2 → 0.18.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 +21 -1
- package/README.md +35 -11
- package/api.d.ts +20 -4
- package/bridge.d.ts +19 -17
- package/bridge.js +29 -26
- package/package.json +3 -2
- package/zig/{wasmapi.zig → lib.zig} +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-10-
|
|
3
|
+
- **Last updated**: 2022-10-31T23:01:45Z
|
|
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,26 @@ 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.18.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.18.0) (2022-10-31)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- update WasmBridge & child API module specs ([6773494](https://github.com/thi-ng/umbrella/commit/6773494))
|
|
17
|
+
- update IWasmAPI interface to declare import ID & module dependencies
|
|
18
|
+
- update WasmBridge ctor (array instead of object of sub-modules)
|
|
19
|
+
- update WasmBridge.init() to initialize modules in dependency order
|
|
20
|
+
- replace illegalArgs() with assert()
|
|
21
|
+
- add [@thi.ng/arrays](https://github.com/thi-ng/umbrella/tree/main/packages/arrays) as dependency, update pkg
|
|
22
|
+
|
|
23
|
+
### [0.17.3](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.17.3) (2022-10-31)
|
|
24
|
+
|
|
25
|
+
#### ♻️ Refactoring
|
|
26
|
+
|
|
27
|
+
- restructure/rename zig files, update readdme ([c63ca10](https://github.com/thi-ng/umbrella/commit/c63ca10))
|
|
28
|
+
- enforce uniform project structure for all `[@thi.ng/wasm-api-](https://github.com/thi-ng/umbrella/tree/main/packages/wasm-api-)*` packages
|
|
29
|
+
- rename /zig/wasmapi.zig => /zig/lib.zig
|
|
30
|
+
- update readme w/ further info
|
|
31
|
+
|
|
12
32
|
### [0.17.1](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.17.1) (2022-10-30)
|
|
13
33
|
|
|
14
34
|
#### ♻️ Refactoring
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ This project is part of the
|
|
|
17
17
|
- [String handling](#string-handling)
|
|
18
18
|
- [Memory allocations](#memory-allocations)
|
|
19
19
|
- [Custom API modules](#custom-api-modules)
|
|
20
|
+
- [Building Zig projects with these hybrid API modules](#building-zig-projects-with-these-hybrid-api-modules)
|
|
20
21
|
- [Object indices & handles](#object-indices--handles)
|
|
21
22
|
- [Status](#status)
|
|
22
23
|
- [Support packages](#support-packages)
|
|
@@ -450,7 +451,7 @@ The actual allocator is implementation specific and suitable generic mechanisms
|
|
|
450
451
|
are defined for both the included Zig & C bindings. Please see for further
|
|
451
452
|
reference:
|
|
452
453
|
|
|
453
|
-
- [`/zig/
|
|
454
|
+
- [`/zig/lib.zig`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/lib.zig#L64):
|
|
454
455
|
comments about WASM-side allocator handling in Zig
|
|
455
456
|
- [`/include/wasmapi.h`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/include/wasmapi.h#L18):
|
|
456
457
|
comments about WASM-side allocator handling in C/C++
|
|
@@ -504,6 +505,13 @@ following example provides a brief overview:
|
|
|
504
505
|
import { IWasmAPI, WasmBridge } from "@thi.ng/wasm-api";
|
|
505
506
|
|
|
506
507
|
export class CustomAPI implements IWasmAPI {
|
|
508
|
+
// Unique API module identifier to group WASM imports,
|
|
509
|
+
// must match ID used by native code (see further below).
|
|
510
|
+
readonly id = "custom";
|
|
511
|
+
// optionally list IDs of other API modules this module depends on
|
|
512
|
+
// these are used to infer the correct initialization order
|
|
513
|
+
readonly dependencies = [];
|
|
514
|
+
|
|
507
515
|
parent!: WasmBridge;
|
|
508
516
|
|
|
509
517
|
async init(parent: WasmBridge) {
|
|
@@ -537,13 +545,12 @@ export class CustomAPI implements IWasmAPI {
|
|
|
537
545
|
Now we can supply this custom API when creating the main WASM bridge:
|
|
538
546
|
|
|
539
547
|
```ts
|
|
540
|
-
export const bridge = new WasmBridge(
|
|
548
|
+
export const bridge = new WasmBridge([new CustomAPI()]);
|
|
541
549
|
```
|
|
542
550
|
|
|
543
551
|
In Zig (or any other language of your choice) we can then utilize this custom
|
|
544
|
-
API like so (Please also see
|
|
545
|
-
|
|
546
|
-
& other examples in this readme):
|
|
552
|
+
API like so (Please also see [example projects](https://github.com/thi-ng/umbrella/tree/develop/examples/zig-canvas/)
|
|
553
|
+
& other example snippets in this readme):
|
|
547
554
|
|
|
548
555
|
Bindings file / lib:
|
|
549
556
|
|
|
@@ -579,6 +586,19 @@ export fn test_randomVec4() void {
|
|
|
579
586
|
}
|
|
580
587
|
```
|
|
581
588
|
|
|
589
|
+
### Building Zig projects with these hybrid API modules
|
|
590
|
+
|
|
591
|
+
Some example projects (see [list below](#usage-examples)) provide custom
|
|
592
|
+
[`build.zig`](https://github.com/thi-ng/umbrella/blob/develop/examples/zig-canvas/build.zig)
|
|
593
|
+
&
|
|
594
|
+
[`npm.zig`](https://github.com/thi-ng/umbrella/blob/develop/examples/zig-canvas/npm.zig)
|
|
595
|
+
build scripts to easily integrate these hybrid TS/Zig packages into users'
|
|
596
|
+
development processes.
|
|
597
|
+
|
|
598
|
+
To avoid guesswork about the internals of these API modules, all of them are
|
|
599
|
+
using an overall uniform structure, with the main Zig entry point in
|
|
600
|
+
`/zig/lib.zig`...
|
|
601
|
+
|
|
582
602
|
### Object indices & handles
|
|
583
603
|
|
|
584
604
|
Since only numeric values can be exchanged between the WASM module and the JS
|
|
@@ -630,7 +650,9 @@ Since v0.15.0, the supplied Zig core bindings lib also includes a
|
|
|
630
650
|
[`ManagedIndex`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/managed-index.zig)
|
|
631
651
|
for similar dealings on the Zig side of the application. For example, in the
|
|
632
652
|
[@thi.ng/wasm-api-dom](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-dom/)
|
|
633
|
-
|
|
653
|
+
&
|
|
654
|
+
[@thi.ng/wasm-api-timer](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-timer/)
|
|
655
|
+
modules this is used to manage Zig event listeners.
|
|
634
656
|
|
|
635
657
|
## Status
|
|
636
658
|
|
|
@@ -640,7 +662,8 @@ module this is used to manage Zig event listeners.
|
|
|
640
662
|
|
|
641
663
|
## Support packages
|
|
642
664
|
|
|
643
|
-
- [@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
|
|
665
|
+
- [@thi.ng/wasm-api-dom](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-dom) - Browser DOM bridge API for hybrid TypeScript & WASM (Zig) applications
|
|
666
|
+
- [@thi.ng/wasm-api-timer](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-timer) - Delayed & scheduled function execution (via setTimeout() etc.) for hybrid WASM apps
|
|
644
667
|
|
|
645
668
|
## Installation
|
|
646
669
|
|
|
@@ -665,16 +688,17 @@ node --experimental-repl-await
|
|
|
665
688
|
> const wasmApi = await import("@thi.ng/wasm-api");
|
|
666
689
|
```
|
|
667
690
|
|
|
668
|
-
Package sizes (gzipped, pre-treeshake): ESM: 7.
|
|
691
|
+
Package sizes (gzipped, pre-treeshake): ESM: 7.13 KB
|
|
669
692
|
|
|
670
|
-
**IMPORTANT:** The package includes code generators
|
|
671
|
-
|
|
693
|
+
**IMPORTANT:** The package includes multiple language code generators which are
|
|
694
|
+
**not** required for normal use of the API bridge. Hence, the actual package
|
|
672
695
|
size in production will be MUCH smaller than what's stated here!
|
|
673
696
|
|
|
674
697
|
## Dependencies
|
|
675
698
|
|
|
676
699
|
- [@thi.ng/api](https://github.com/thi-ng/umbrella/tree/develop/packages/api)
|
|
677
700
|
- [@thi.ng/args](https://github.com/thi-ng/umbrella/tree/develop/packages/args)
|
|
701
|
+
- [@thi.ng/arrays](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays)
|
|
678
702
|
- [@thi.ng/binary](https://github.com/thi-ng/umbrella/tree/develop/packages/binary)
|
|
679
703
|
- [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks)
|
|
680
704
|
- [@thi.ng/compare](https://github.com/thi-ng/umbrella/tree/develop/packages/compare)
|
|
@@ -757,7 +781,7 @@ folder):
|
|
|
757
781
|
```bash
|
|
758
782
|
# compile WASM binary
|
|
759
783
|
zig build-lib \
|
|
760
|
-
--pkg-begin wasmapi node_modules/@thi.ng/wasm-api/zig/
|
|
784
|
+
--pkg-begin wasmapi node_modules/@thi.ng/wasm-api/zig/lib.zig --pkg-end \
|
|
761
785
|
-target wasm32-freestanding \
|
|
762
786
|
-O ReleaseSmall -dynamic --strip \
|
|
763
787
|
hello.zig
|
package/api.d.ts
CHANGED
|
@@ -13,6 +13,18 @@ export declare type BigIntArray = bigint[] | BigInt64Array | BigUint64Array;
|
|
|
13
13
|
* certain exports declared by WASM module.
|
|
14
14
|
*/
|
|
15
15
|
export interface IWasmAPI<T extends WasmExports = WasmExports> {
|
|
16
|
+
/**
|
|
17
|
+
* The unique ID for grouping the WASM imports of this module. MUST be the
|
|
18
|
+
* same as used by the native side of the module.
|
|
19
|
+
*/
|
|
20
|
+
readonly id: string;
|
|
21
|
+
/**
|
|
22
|
+
* IDs of other WASM API modules which this module depends on. Used to infer
|
|
23
|
+
* correct initialization order. The core module (w/ unique ID: `wasmapi`)
|
|
24
|
+
* is always considered an implicit dependency, will be initialized first
|
|
25
|
+
* and MUST NOT be stated here.
|
|
26
|
+
*/
|
|
27
|
+
readonly dependencies?: string[];
|
|
16
28
|
/**
|
|
17
29
|
* Called by {@link WasmBridge.init} to initialize all child APIs (async)
|
|
18
30
|
* after the WASM module has been instantiated. If the method returns false
|
|
@@ -53,7 +65,7 @@ export interface WasmExports {
|
|
|
53
65
|
* @remarks
|
|
54
66
|
* #### Zig
|
|
55
67
|
*
|
|
56
|
-
* Using the supplied Zig bindings (see `/zig/
|
|
68
|
+
* Using the supplied Zig bindings (see `/zig/lib.zig`), it's the
|
|
57
69
|
* user's responsibility to define a public `WASM_ALLOCATOR` in the root
|
|
58
70
|
* source file to enable allocations, e.g. using the
|
|
59
71
|
* [`std.heap.GeneralPurposeAllocator`](https://ziglang.org/documentation/master/#Choosing-an-Allocator)
|
|
@@ -161,12 +173,12 @@ export interface IWasmMemoryAccess {
|
|
|
161
173
|
}
|
|
162
174
|
/**
|
|
163
175
|
* Core API of WASM imports defined by the {@link WasmBridge}. The same
|
|
164
|
-
* functions are declared as bindings in `/zig/
|
|
176
|
+
* functions are declared as bindings in `/zig/lib.zig`. **Also see this
|
|
165
177
|
* file for documentation of each function...**
|
|
166
178
|
*
|
|
167
179
|
* @remarks
|
|
168
180
|
* Zig API:
|
|
169
|
-
* https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/
|
|
181
|
+
* https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/lib.zig
|
|
170
182
|
*/
|
|
171
183
|
export interface CoreAPI extends WebAssembly.ModuleImports {
|
|
172
184
|
printI8: Fn<number, void>;
|
|
@@ -458,7 +470,11 @@ export interface CodeGenOpts extends CodeGenOptsBase {
|
|
|
458
470
|
*/
|
|
459
471
|
stringType: "slice" | "ptr";
|
|
460
472
|
/**
|
|
461
|
-
* If true (default), forces uppercase enum identifiers
|
|
473
|
+
* If true (default), forces uppercase enum identifiers.
|
|
474
|
+
*
|
|
475
|
+
* @remarks
|
|
476
|
+
* This option is ignored in {@link ZIG} since it's idiomatic for that
|
|
477
|
+
* language to only use lowercase/camelCase enum IDs.
|
|
462
478
|
*
|
|
463
479
|
* @defaultValue true
|
|
464
480
|
*/
|
package/bridge.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import type { Event, INotify, Listener, NumericArray } from "@thi.ng/api";
|
|
2
|
+
import type { Event, INotify, IObjectOf, Listener, NumericArray } from "@thi.ng/api";
|
|
3
3
|
import type { ILogger } from "@thi.ng/logger";
|
|
4
4
|
import { BigIntArray, CoreAPI, IWasmAPI, IWasmMemoryAccess, MemorySlice, WasmExports } from "./api.js";
|
|
5
5
|
export declare const Panic: {
|
|
@@ -36,11 +36,11 @@ export declare const OutOfMemoryError: {
|
|
|
36
36
|
* mechanisms like JS `DataView`...
|
|
37
37
|
*
|
|
38
38
|
* 64bit integers are handled via JS `BigInt` and hence require the host env to
|
|
39
|
-
* support it. No
|
|
39
|
+
* support it. No polyfills are provided.
|
|
40
40
|
*/
|
|
41
41
|
export declare class WasmBridge<T extends WasmExports = WasmExports> implements IWasmMemoryAccess, INotify {
|
|
42
|
-
modules: Record<string, IWasmAPI<T>>;
|
|
43
42
|
logger: ILogger;
|
|
43
|
+
readonly id = "wasmapi";
|
|
44
44
|
i8: Int8Array;
|
|
45
45
|
u8: Uint8Array;
|
|
46
46
|
i16: Int16Array;
|
|
@@ -56,7 +56,8 @@ export declare class WasmBridge<T extends WasmExports = WasmExports> implements
|
|
|
56
56
|
imports: WebAssembly.Imports;
|
|
57
57
|
exports: T;
|
|
58
58
|
api: CoreAPI;
|
|
59
|
-
|
|
59
|
+
modules: IObjectOf<IWasmAPI<T>>;
|
|
60
|
+
constructor(modules?: IWasmAPI<T>[], logger?: ILogger);
|
|
60
61
|
/**
|
|
61
62
|
* Instantiates WASM module from given `src` (and optional provided extra
|
|
62
63
|
* imports), then automatically calls {@link WasmBridge.init} with the
|
|
@@ -72,9 +73,10 @@ export declare class WasmBridge<T extends WasmExports = WasmExports> implements
|
|
|
72
73
|
*/
|
|
73
74
|
instantiate(src: Response | BufferSource | PromiseLike<Response | BufferSource>, imports?: WebAssembly.Imports): Promise<boolean>;
|
|
74
75
|
/**
|
|
75
|
-
* Receives the WASM module's exports, stores
|
|
76
|
-
* then initializes all declared bridge child API modules
|
|
77
|
-
* any of the module
|
|
76
|
+
* Receives the WASM module's combined exports, stores them for future
|
|
77
|
+
* reference and then initializes all declared bridge child API modules in
|
|
78
|
+
* their stated dependency order. Returns false if any of the module
|
|
79
|
+
* initializations failed.
|
|
78
80
|
*
|
|
79
81
|
* @remarks
|
|
80
82
|
* Emits the {@link EVENT_MEMORY_CHANGED} event just before returning (and
|
|
@@ -84,11 +86,11 @@ export declare class WasmBridge<T extends WasmExports = WasmExports> implements
|
|
|
84
86
|
*/
|
|
85
87
|
init(exports: T): Promise<boolean>;
|
|
86
88
|
/**
|
|
87
|
-
* Called automatically during initialization
|
|
88
|
-
* the various typed WASM memory views
|
|
89
|
-
* and the previous buffer becoming
|
|
90
|
-
* the {@link EVENT_MEMORY_CHANGED}
|
|
91
|
-
* views had to be updated.
|
|
89
|
+
* Called automatically during initialization and from other memory
|
|
90
|
+
* accessors. Initializes and/or updates the various typed WASM memory views
|
|
91
|
+
* (e.g. after growing the WASM memory and the previous buffer becoming
|
|
92
|
+
* detached). Unless `notify` is false, the {@link EVENT_MEMORY_CHANGED}
|
|
93
|
+
* event will be emitted if the memory views had to be updated.
|
|
92
94
|
*
|
|
93
95
|
* @param notify
|
|
94
96
|
*/
|
|
@@ -99,16 +101,16 @@ export declare class WasmBridge<T extends WasmExports = WasmExports> implements
|
|
|
99
101
|
* API and any provided bridge API modules.
|
|
100
102
|
*
|
|
101
103
|
* @remarks
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
104
|
+
* Each API module's imports will be in their own WASM import object/table,
|
|
105
|
+
* named using the same key which is defined by the JS side of the module
|
|
106
|
+
* via {@link IWasmAPI.id}. The bridge's core API is named `wasmapi` and is
|
|
107
|
+
* reserved.
|
|
106
108
|
*
|
|
107
109
|
* @example
|
|
108
110
|
* The following creates a bridge with a fictional `custom` API module:
|
|
109
111
|
*
|
|
110
112
|
* ```ts
|
|
111
|
-
* const bridge = new WasmBridge(
|
|
113
|
+
* const bridge = new WasmBridge([new CustomAPI()]);
|
|
112
114
|
*
|
|
113
115
|
* // get combined imports object
|
|
114
116
|
* bridge.getImports();
|
package/bridge.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
2
|
import { INotifyMixin } from "@thi.ng/api/mixins/inotify";
|
|
3
|
+
import { topoSort } from "@thi.ng/arrays/topo-sort";
|
|
4
|
+
import { assert } from "@thi.ng/errors/assert";
|
|
3
5
|
import { defError } from "@thi.ng/errors/deferror";
|
|
4
|
-
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
|
|
5
6
|
import { U16, U32, U64BIG, U8 } from "@thi.ng/hex";
|
|
6
7
|
import { ConsoleLogger } from "@thi.ng/logger/console";
|
|
7
8
|
import { EVENT_MEMORY_CHANGED, } from "./api.js";
|
|
@@ -21,12 +22,12 @@ export const OutOfMemoryError = defError(() => "Out of memory");
|
|
|
21
22
|
* mechanisms like JS `DataView`...
|
|
22
23
|
*
|
|
23
24
|
* 64bit integers are handled via JS `BigInt` and hence require the host env to
|
|
24
|
-
* support it. No
|
|
25
|
+
* support it. No polyfills are provided.
|
|
25
26
|
*/
|
|
26
27
|
let WasmBridge = class WasmBridge {
|
|
27
|
-
constructor(modules =
|
|
28
|
-
this.modules = modules;
|
|
28
|
+
constructor(modules = [], logger = new ConsoleLogger("wasm")) {
|
|
29
29
|
this.logger = logger;
|
|
30
|
+
this.id = "wasmapi";
|
|
30
31
|
this.utf8Decoder = new TextDecoder();
|
|
31
32
|
this.utf8Encoder = new TextEncoder();
|
|
32
33
|
const logN = (x) => this.logger.debug(x);
|
|
@@ -67,6 +68,11 @@ let WasmBridge = class WasmBridge {
|
|
|
67
68
|
timer: () => performance.now(),
|
|
68
69
|
epoch: () => BigInt(Date.now()),
|
|
69
70
|
};
|
|
71
|
+
this.modules = modules.reduce((acc, x) => {
|
|
72
|
+
assert(acc[x.id] === undefined && x.id !== this.id, `duplicate API module ID: ${x.id}`);
|
|
73
|
+
acc[x.id] = x;
|
|
74
|
+
return acc;
|
|
75
|
+
}, {});
|
|
70
76
|
}
|
|
71
77
|
/**
|
|
72
78
|
* Instantiates WASM module from given `src` (and optional provided extra
|
|
@@ -90,9 +96,10 @@ let WasmBridge = class WasmBridge {
|
|
|
90
96
|
return this.init(wasm.instance.exports);
|
|
91
97
|
}
|
|
92
98
|
/**
|
|
93
|
-
* Receives the WASM module's exports, stores
|
|
94
|
-
* then initializes all declared bridge child API modules
|
|
95
|
-
* any of the module
|
|
99
|
+
* Receives the WASM module's combined exports, stores them for future
|
|
100
|
+
* reference and then initializes all declared bridge child API modules in
|
|
101
|
+
* their stated dependency order. Returns false if any of the module
|
|
102
|
+
* initializations failed.
|
|
96
103
|
*
|
|
97
104
|
* @remarks
|
|
98
105
|
* Emits the {@link EVENT_MEMORY_CHANGED} event just before returning (and
|
|
@@ -103,7 +110,8 @@ let WasmBridge = class WasmBridge {
|
|
|
103
110
|
async init(exports) {
|
|
104
111
|
this.exports = exports;
|
|
105
112
|
this.ensureMemory(false);
|
|
106
|
-
for (let id
|
|
113
|
+
for (let id of topoSort(this.modules, (module) => module.dependencies)) {
|
|
114
|
+
assert(!!this.modules[id], `missing API module: ${id}`);
|
|
107
115
|
this.logger.debug(`initializing API module: ${id}`);
|
|
108
116
|
const status = await this.modules[id].init(this);
|
|
109
117
|
if (!status)
|
|
@@ -113,11 +121,11 @@ let WasmBridge = class WasmBridge {
|
|
|
113
121
|
return true;
|
|
114
122
|
}
|
|
115
123
|
/**
|
|
116
|
-
* Called automatically during initialization
|
|
117
|
-
* the various typed WASM memory views
|
|
118
|
-
* and the previous buffer becoming
|
|
119
|
-
* the {@link EVENT_MEMORY_CHANGED}
|
|
120
|
-
* views had to be updated.
|
|
124
|
+
* Called automatically during initialization and from other memory
|
|
125
|
+
* accessors. Initializes and/or updates the various typed WASM memory views
|
|
126
|
+
* (e.g. after growing the WASM memory and the previous buffer becoming
|
|
127
|
+
* detached). Unless `notify` is false, the {@link EVENT_MEMORY_CHANGED}
|
|
128
|
+
* event will be emitted if the memory views had to be updated.
|
|
121
129
|
*
|
|
122
130
|
* @param notify
|
|
123
131
|
*/
|
|
@@ -147,16 +155,16 @@ let WasmBridge = class WasmBridge {
|
|
|
147
155
|
* API and any provided bridge API modules.
|
|
148
156
|
*
|
|
149
157
|
* @remarks
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
158
|
+
* Each API module's imports will be in their own WASM import object/table,
|
|
159
|
+
* named using the same key which is defined by the JS side of the module
|
|
160
|
+
* via {@link IWasmAPI.id}. The bridge's core API is named `wasmapi` and is
|
|
161
|
+
* reserved.
|
|
154
162
|
*
|
|
155
163
|
* @example
|
|
156
164
|
* The following creates a bridge with a fictional `custom` API module:
|
|
157
165
|
*
|
|
158
166
|
* ```ts
|
|
159
|
-
* const bridge = new WasmBridge(
|
|
167
|
+
* const bridge = new WasmBridge([new CustomAPI()]);
|
|
160
168
|
*
|
|
161
169
|
* // get combined imports object
|
|
162
170
|
* bridge.getImports();
|
|
@@ -177,11 +185,8 @@ let WasmBridge = class WasmBridge {
|
|
|
177
185
|
*/
|
|
178
186
|
getImports() {
|
|
179
187
|
if (!this.imports) {
|
|
180
|
-
this.imports = {
|
|
188
|
+
this.imports = { [this.id]: this.api };
|
|
181
189
|
for (let id in this.modules) {
|
|
182
|
-
if (this.imports[id] !== undefined) {
|
|
183
|
-
illegalArgs(`attempt to redeclare API module ${id}`);
|
|
184
|
-
}
|
|
185
190
|
this.imports[id] = this.modules[id].getImports();
|
|
186
191
|
}
|
|
187
192
|
}
|
|
@@ -391,9 +396,7 @@ let WasmBridge = class WasmBridge {
|
|
|
391
396
|
this.ensureMemory();
|
|
392
397
|
maxBytes = Math.min(maxBytes, this.u8.length - addr);
|
|
393
398
|
const len = this.utf8Encoder.encodeInto(str, this.u8.subarray(addr, addr + maxBytes)).written;
|
|
394
|
-
|
|
395
|
-
illegalArgs(`error writing string to 0x${U32(addr)} (max. ${maxBytes} bytes, got at least ${str.length})`);
|
|
396
|
-
}
|
|
399
|
+
assert(len != null && len < maxBytes + (terminate ? 0 : 1), `error writing string to 0x${U32(addr)} (max. ${maxBytes} bytes, got at least ${str.length})`);
|
|
397
400
|
if (terminate) {
|
|
398
401
|
this.u8[addr + len] = 0;
|
|
399
402
|
}
|
|
@@ -402,7 +405,7 @@ let WasmBridge = class WasmBridge {
|
|
|
402
405
|
getElementById(addr, len = 0) {
|
|
403
406
|
const id = this.getString(addr, len);
|
|
404
407
|
const el = document.getElementById(id);
|
|
405
|
-
el
|
|
408
|
+
assert(!!el, `missing DOM element #${id}`);
|
|
406
409
|
return el;
|
|
407
410
|
}
|
|
408
411
|
/** {@inheritDoc @thi.ng/api#INotify.addListener} */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/wasm-api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Generic, modular, extensible API bridge, polyglot glue code and bindings code generators for hybrid JS & WebAssembly projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@thi.ng/api": "^8.4.4",
|
|
40
40
|
"@thi.ng/args": "^2.2.7",
|
|
41
|
+
"@thi.ng/arrays": "^2.4.0",
|
|
41
42
|
"@thi.ng/binary": "^3.3.8",
|
|
42
43
|
"@thi.ng/checks": "^3.3.2",
|
|
43
44
|
"@thi.ng/compare": "^2.1.14",
|
|
@@ -141,5 +142,5 @@
|
|
|
141
142
|
"status": "alpha",
|
|
142
143
|
"year": 2022
|
|
143
144
|
},
|
|
144
|
-
"gitHead": "
|
|
145
|
+
"gitHead": "7eff3051eb395f460421727b8cf5ef79f09faaa9\n"
|
|
145
146
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//!
|
|
1
|
+
//! Zig API for https://thi.ng/wasm-api
|
|
2
2
|
|
|
3
3
|
const std = @import("std");
|
|
4
4
|
const root = @import("root");
|
|
@@ -72,7 +72,7 @@ pub fn panic(msg: []const u8, _: ?*std.builtin.StackTrace, _: ?usize) noreturn {
|
|
|
72
72
|
/// Note: The type for this var is purposefully chosen as an optional,
|
|
73
73
|
/// effectively disabling allocations from the WASM host side if no
|
|
74
74
|
/// `WASM_ALLOCATOR` is set (or set to null).
|
|
75
|
-
pub fn allocator() ?std.mem.Allocator {
|
|
75
|
+
pub inline fn allocator() ?std.mem.Allocator {
|
|
76
76
|
return if (@hasDecl(root, "WASM_ALLOCATOR")) root.WASM_ALLOCATOR else null;
|
|
77
77
|
}
|
|
78
78
|
|