@thi.ng/wasm-api
Advanced tools
Comparing version 0.17.3 to 0.18.0
12
api.d.ts
@@ -17,2 +17,14 @@ import type { BigType, FloatType, Fn, Fn2, IDeref, ILength, IObjectOf, NumOrString } from "@thi.ng/api"; | ||
/** | ||
* The unique ID for grouping the WASM imports of this module. MUST be the | ||
* same as used by the native side of the module. | ||
*/ | ||
readonly id: string; | ||
/** | ||
* IDs of other WASM API modules which this module depends on. Used to infer | ||
* correct initialization order. The core module (w/ unique ID: `wasmapi`) | ||
* is always considered an implicit dependency, will be initialized first | ||
* and MUST NOT be stated here. | ||
*/ | ||
readonly dependencies?: string[]; | ||
/** | ||
* Called by {@link WasmBridge.init} to initialize all child APIs (async) | ||
@@ -19,0 +31,0 @@ * after the WASM module has been instantiated. If the method returns false |
/// <reference types="node" /> | ||
import type { Event, INotify, Listener, NumericArray } from "@thi.ng/api"; | ||
import type { Event, INotify, IObjectOf, Listener, NumericArray } from "@thi.ng/api"; | ||
import type { ILogger } from "@thi.ng/logger"; | ||
@@ -39,7 +39,7 @@ import { BigIntArray, CoreAPI, IWasmAPI, IWasmMemoryAccess, MemorySlice, WasmExports } from "./api.js"; | ||
* 64bit integers are handled via JS `BigInt` and hence require the host env to | ||
* support it. No polyfill is provided. | ||
* support it. No polyfills are provided. | ||
*/ | ||
export declare class WasmBridge<T extends WasmExports = WasmExports> implements IWasmMemoryAccess, INotify { | ||
modules: Record<string, IWasmAPI<T>>; | ||
logger: ILogger; | ||
readonly id = "wasmapi"; | ||
i8: Int8Array; | ||
@@ -60,3 +60,4 @@ u8: Uint8Array; | ||
api: CoreAPI; | ||
constructor(modules?: Record<string, IWasmAPI<T>>, logger?: ILogger); | ||
modules: IObjectOf<IWasmAPI<T>>; | ||
constructor(modules?: IWasmAPI<T>[], logger?: ILogger); | ||
/** | ||
@@ -77,5 +78,6 @@ * Instantiates WASM module from given `src` (and optional provided extra | ||
/** | ||
* Receives the WASM module's exports, stores the for future reference and | ||
* then initializes all declared bridge child API modules. Returns false if | ||
* any of the module initializations failed. | ||
* Receives the WASM module's combined exports, stores them for future | ||
* reference and then initializes all declared bridge child API modules in | ||
* their stated dependency order. Returns false if any of the module | ||
* initializations failed. | ||
* | ||
@@ -90,7 +92,7 @@ * @remarks | ||
/** | ||
* Called automatically during initialization. Initializes and/or updates | ||
* the various typed WASM memory views (e.g. after growing the WASM memory | ||
* and the previous buffer becoming detached). Unless `notify` is false, | ||
* the {@link EVENT_MEMORY_CHANGED} event will be emitted if the memory | ||
* views had to be updated. | ||
* Called automatically during initialization and from other memory | ||
* accessors. Initializes and/or updates the various typed WASM memory views | ||
* (e.g. after growing the WASM memory and the previous buffer becoming | ||
* detached). Unless `notify` is false, the {@link EVENT_MEMORY_CHANGED} | ||
* event will be emitted if the memory views had to be updated. | ||
* | ||
@@ -106,6 +108,6 @@ * @param notify | ||
* @remarks | ||
* Since v0.4.0 each API module's imports will be in their own WASM import | ||
* object, named using the same key which was assigned to the module when | ||
* creating the WASM bridge. The bridge's core API will be named `core` and | ||
* is reserved. | ||
* Each API module's imports will be in their own WASM import object/table, | ||
* named using the same key which is defined by the JS side of the module | ||
* via {@link IWasmAPI.id}. The bridge's core API is named `wasmapi` and is | ||
* reserved. | ||
* | ||
@@ -116,3 +118,3 @@ * @example | ||
* ```ts | ||
* const bridge = new WasmBridge({ custom: new CustomAPI() }); | ||
* const bridge = new WasmBridge([new CustomAPI()]); | ||
* | ||
@@ -119,0 +121,0 @@ * // get combined imports object |
import { __decorate } from "tslib"; | ||
import { INotifyMixin } from "@thi.ng/api/mixins/inotify"; | ||
import { topoSort } from "@thi.ng/arrays/topo-sort"; | ||
import { assert } from "@thi.ng/errors/assert"; | ||
import { defError } from "@thi.ng/errors/deferror"; | ||
import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; | ||
import { U16, U32, U64BIG, U8 } from "@thi.ng/hex"; | ||
@@ -24,8 +25,8 @@ import { ConsoleLogger } from "@thi.ng/logger/console"; | ||
* 64bit integers are handled via JS `BigInt` and hence require the host env to | ||
* support it. No polyfill is provided. | ||
* support it. No polyfills are provided. | ||
*/ | ||
let WasmBridge = class WasmBridge { | ||
constructor(modules = {}, logger = new ConsoleLogger("wasm")) { | ||
this.modules = modules; | ||
constructor(modules = [], logger = new ConsoleLogger("wasm")) { | ||
this.logger = logger; | ||
this.id = "wasmapi"; | ||
this.utf8Decoder = new TextDecoder(); | ||
@@ -71,2 +72,7 @@ this.utf8Encoder = new TextEncoder(); | ||
}; | ||
this.modules = modules.reduce((acc, x) => { | ||
assert(acc[x.id] === undefined && x.id !== this.id, `duplicate API module ID: ${x.id}`); | ||
acc[x.id] = x; | ||
return acc; | ||
}, {}); | ||
} | ||
@@ -95,5 +101,6 @@ /** | ||
/** | ||
* Receives the WASM module's exports, stores the for future reference and | ||
* then initializes all declared bridge child API modules. Returns false if | ||
* any of the module initializations failed. | ||
* Receives the WASM module's combined exports, stores them for future | ||
* reference and then initializes all declared bridge child API modules in | ||
* their stated dependency order. Returns false if any of the module | ||
* initializations failed. | ||
* | ||
@@ -109,3 +116,4 @@ * @remarks | ||
this.ensureMemory(false); | ||
for (let id in this.modules) { | ||
for (let id of topoSort(this.modules, (module) => module.dependencies)) { | ||
assert(!!this.modules[id], `missing API module: ${id}`); | ||
this.logger.debug(`initializing API module: ${id}`); | ||
@@ -120,7 +128,7 @@ const status = await this.modules[id].init(this); | ||
/** | ||
* Called automatically during initialization. Initializes and/or updates | ||
* the various typed WASM memory views (e.g. after growing the WASM memory | ||
* and the previous buffer becoming detached). Unless `notify` is false, | ||
* the {@link EVENT_MEMORY_CHANGED} event will be emitted if the memory | ||
* views had to be updated. | ||
* Called automatically during initialization and from other memory | ||
* accessors. Initializes and/or updates the various typed WASM memory views | ||
* (e.g. after growing the WASM memory and the previous buffer becoming | ||
* detached). Unless `notify` is false, the {@link EVENT_MEMORY_CHANGED} | ||
* event will be emitted if the memory views had to be updated. | ||
* | ||
@@ -155,6 +163,6 @@ * @param notify | ||
* @remarks | ||
* Since v0.4.0 each API module's imports will be in their own WASM import | ||
* object, named using the same key which was assigned to the module when | ||
* creating the WASM bridge. The bridge's core API will be named `core` and | ||
* is reserved. | ||
* Each API module's imports will be in their own WASM import object/table, | ||
* named using the same key which is defined by the JS side of the module | ||
* via {@link IWasmAPI.id}. The bridge's core API is named `wasmapi` and is | ||
* reserved. | ||
* | ||
@@ -165,3 +173,3 @@ * @example | ||
* ```ts | ||
* const bridge = new WasmBridge({ custom: new CustomAPI() }); | ||
* const bridge = new WasmBridge([new CustomAPI()]); | ||
* | ||
@@ -187,7 +195,4 @@ * // get combined imports object | ||
if (!this.imports) { | ||
this.imports = { wasmapi: this.api }; | ||
this.imports = { [this.id]: this.api }; | ||
for (let id in this.modules) { | ||
if (this.imports[id] !== undefined) { | ||
illegalArgs(`attempt to redeclare API module ${id}`); | ||
} | ||
this.imports[id] = this.modules[id].getImports(); | ||
@@ -402,5 +407,3 @@ } | ||
const len = this.utf8Encoder.encodeInto(str, this.u8.subarray(addr, addr + maxBytes)).written; | ||
if (len == null || len >= maxBytes + (terminate ? 0 : 1)) { | ||
illegalArgs(`error writing string to 0x${U32(addr)} (max. ${maxBytes} bytes, got at least ${str.length})`); | ||
} | ||
assert(len != null && len < maxBytes + (terminate ? 0 : 1), `error writing string to 0x${U32(addr)} (max. ${maxBytes} bytes, got at least ${str.length})`); | ||
if (terminate) { | ||
@@ -414,3 +417,3 @@ this.u8[addr + len] = 0; | ||
const el = document.getElementById(id); | ||
el == null && illegalArgs(`missing DOM element #${id}`); | ||
assert(!!el, `missing DOM element #${id}`); | ||
return el; | ||
@@ -417,0 +420,0 @@ } |
# Change Log | ||
- **Last updated**: 2022-10-31T09:19:33Z | ||
- **Last updated**: 2022-10-31T23:01:45Z | ||
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub) | ||
@@ -12,2 +12,13 @@ | ||
## [0.18.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.18.0) (2022-10-31) | ||
#### 🚀 Features | ||
- update WasmBridge & child API module specs ([6773494](https://github.com/thi-ng/umbrella/commit/6773494)) | ||
- update IWasmAPI interface to declare import ID & module dependencies | ||
- update WasmBridge ctor (array instead of object of sub-modules) | ||
- update WasmBridge.init() to initialize modules in dependency order | ||
- replace illegalArgs() with assert() | ||
- add [@thi.ng/arrays](https://github.com/thi-ng/umbrella/tree/main/packages/arrays) as dependency, update pkg | ||
### [0.17.3](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.17.3) (2022-10-31) | ||
@@ -14,0 +25,0 @@ |
{ | ||
"name": "@thi.ng/wasm-api", | ||
"version": "0.17.3", | ||
"version": "0.18.0", | ||
"description": "Generic, modular, extensible API bridge, polyglot glue code and bindings code generators for hybrid JS & WebAssembly projects", | ||
@@ -41,2 +41,3 @@ "type": "module", | ||
"@thi.ng/args": "^2.2.7", | ||
"@thi.ng/arrays": "^2.4.0", | ||
"@thi.ng/binary": "^3.3.8", | ||
@@ -145,3 +146,3 @@ "@thi.ng/checks": "^3.3.2", | ||
}, | ||
"gitHead": "7c5c0cb37ff88c2fa5dd77dd78bf3a5ceb5c62c6\n" | ||
"gitHead": "7eff3051eb395f460421727b8cf5ef79f09faaa9\n" | ||
} |
@@ -508,2 +508,9 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
export class CustomAPI implements IWasmAPI { | ||
// Unique API module identifier to group WASM imports, | ||
// must match ID used by native code (see further below). | ||
readonly id = "custom"; | ||
// optionally list IDs of other API modules this module depends on | ||
// these are used to infer the correct initialization order | ||
readonly dependencies = []; | ||
parent!: WasmBridge; | ||
@@ -542,3 +549,3 @@ | ||
```ts | ||
export const bridge = new WasmBridge({ custom: new CustomAPI() }); | ||
export const bridge = new WasmBridge([new CustomAPI()]); | ||
``` | ||
@@ -686,3 +693,3 @@ | ||
Package sizes (gzipped, pre-treeshake): ESM: 7.06 KB | ||
Package sizes (gzipped, pre-treeshake): ESM: 7.13 KB | ||
@@ -697,2 +704,3 @@ **IMPORTANT:** The package includes multiple language code generators which are | ||
- [@thi.ng/args](https://github.com/thi-ng/umbrella/tree/develop/packages/args) | ||
- [@thi.ng/arrays](https://github.com/thi-ng/umbrella/tree/develop/packages/arrays) | ||
- [@thi.ng/binary](https://github.com/thi-ng/umbrella/tree/develop/packages/binary) | ||
@@ -699,0 +707,0 @@ - [@thi.ng/checks](https://github.com/thi-ng/umbrella/tree/develop/packages/checks) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
188952
3096
927
14
+ Added@thi.ng/arrays@^2.4.0
+ Added@thi.ng/arrays@2.10.7(transitive)
+ Added@thi.ng/equiv@2.1.70(transitive)
+ Added@thi.ng/random@4.1.5(transitive)