@thi.ng/wasm-api
Advanced tools
Comparing version 0.3.1 to 0.4.0
@@ -51,3 +51,3 @@ import type { Fn, Fn2 } from "@thi.ng/api"; | ||
*/ | ||
export interface CoreAPI { | ||
export interface CoreAPI extends WebAssembly.ModuleImports { | ||
printI8: Fn<number, void>; | ||
@@ -54,0 +54,0 @@ printU8: Fn<number, void>; |
@@ -35,4 +35,5 @@ import type { NumericArray } from "@thi.ng/api"; | ||
utf8Encoder: TextEncoder; | ||
imports: WebAssembly.Imports; | ||
exports: T; | ||
core: CoreAPI; | ||
exports: T; | ||
constructor(modules?: Record<string, IWasmAPI<T>>, logger?: ILogger); | ||
@@ -67,5 +68,28 @@ /** | ||
* @remarks | ||
* Since all declared imports will be merged into a single flat namespace, | ||
* it's recommended to use per-module naming prefixes to avoid clashes. If | ||
* there're any naming clashes, this function will throw an error. | ||
* Since v0.4.0 each API module's imports will be in their own WASM import | ||
* table, named using the same key which was assigned to the module when | ||
* creating the WASM bridge. | ||
* | ||
* @example | ||
* The following creates a bridge with a fictional `custom` API module: | ||
* | ||
* ```ts | ||
* const bridge = new WasmBridge({ custom: new CustomAPI() }); | ||
* | ||
* // get combined imports object | ||
* bridge.getImports(); | ||
* { | ||
* // imports defined by the core API of the bridge itself | ||
* core: { ... }, | ||
* // imports defined by the CustomAPI module | ||
* custom: { ... } | ||
* } | ||
* ``` | ||
* | ||
* Any related API bindings on the WASM (Zig) side then also need to refer | ||
* to these custom import sections (also see `/zig/core.zig`): | ||
* | ||
* ```zig | ||
* pub export "custom" fn foo(x: u32) void; | ||
* ``` | ||
*/ | ||
@@ -72,0 +96,0 @@ getImports(): WebAssembly.Imports; |
@@ -73,10 +73,6 @@ import { illegalArgs } from "@thi.ng/errors/illegal-arguments"; | ||
const $src = await src; | ||
const $imports = { ...imports, ...this.getImports() }; | ||
let wasm; | ||
if ($src instanceof Response) { | ||
wasm = await WebAssembly.instantiateStreaming($src, $imports); | ||
} | ||
else { | ||
wasm = await WebAssembly.instantiate($src, $imports); | ||
} | ||
const $imports = { ...this.getImports(), ...imports }; | ||
const wasm = await ($src instanceof Response | ||
? WebAssembly.instantiateStreaming($src, $imports) | ||
: WebAssembly.instantiate($src, $imports)); | ||
return this.init(wasm.instance.exports); | ||
@@ -118,19 +114,40 @@ } | ||
* @remarks | ||
* Since all declared imports will be merged into a single flat namespace, | ||
* it's recommended to use per-module naming prefixes to avoid clashes. If | ||
* there're any naming clashes, this function will throw an error. | ||
* Since v0.4.0 each API module's imports will be in their own WASM import | ||
* table, named using the same key which was assigned to the module when | ||
* creating the WASM bridge. | ||
* | ||
* @example | ||
* The following creates a bridge with a fictional `custom` API module: | ||
* | ||
* ```ts | ||
* const bridge = new WasmBridge({ custom: new CustomAPI() }); | ||
* | ||
* // get combined imports object | ||
* bridge.getImports(); | ||
* { | ||
* // imports defined by the core API of the bridge itself | ||
* core: { ... }, | ||
* // imports defined by the CustomAPI module | ||
* custom: { ... } | ||
* } | ||
* ``` | ||
* | ||
* Any related API bindings on the WASM (Zig) side then also need to refer | ||
* to these custom import sections (also see `/zig/core.zig`): | ||
* | ||
* ```zig | ||
* pub export "custom" fn foo(x: u32) void; | ||
* ``` | ||
*/ | ||
getImports() { | ||
const env = { ...this.core }; | ||
for (let id in this.modules) { | ||
const imports = this.modules[id].getImports(); | ||
// check for naming clashes | ||
for (let k in imports) { | ||
if (env[k] !== undefined) { | ||
illegalArgs(`attempt to redeclare import: ${k} by API module ${id}`); | ||
if (!this.imports) { | ||
this.imports = { core: this.core }; | ||
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(); | ||
} | ||
Object.assign(env, imports); | ||
} | ||
return { env }; | ||
return this.imports; | ||
} | ||
@@ -137,0 +154,0 @@ getI8(addr) { |
# Change Log | ||
- **Last updated**: 2022-08-04T21:21:08Z | ||
- **Last updated**: 2022-08-07T15:28:01Z | ||
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub) | ||
@@ -12,2 +12,11 @@ | ||
## [0.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.4.0) (2022-08-07) | ||
#### 🚀 Features | ||
- use named import objects ([4965f20](https://github.com/thi-ng/umbrella/commit/4965f20)) | ||
- switch to name import objects to avoid merging into flat namespace | ||
- update externs in core.zig | ||
- update docstrings | ||
## [0.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@0.3.0) (2022-08-04) | ||
@@ -14,0 +23,0 @@ |
{ | ||
"name": "@thi.ng/wasm-api", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "Modular, extensible API bridge and generic glue code between JS & WebAssembly", | ||
@@ -95,3 +95,3 @@ "type": "module", | ||
}, | ||
"gitHead": "01b7a47077d88c2aefe77650ce3340040bae00ee\n" | ||
"gitHead": "0eeb5054111cea51f4714b013dda8700ade3cd54\n" | ||
} |
@@ -60,4 +60,4 @@ <!-- This file is generated - DO NOT EDIT! --> | ||
* Returns object of functions to import as externals into | ||
* the WASM module. These imports are merged with the bridge's | ||
* core API and hence should use naming prefixes... | ||
* the WASM module. These imports are merged into a larger | ||
* imports object alongside the bridge's core API... | ||
*/ | ||
@@ -69,3 +69,3 @@ getImports(): WebAssembly.Imports { | ||
*/ | ||
custom_randomVec2: (addr: number) => { | ||
randomVec2: (addr: number) => { | ||
this.parent.f32.set( | ||
@@ -88,3 +88,4 @@ [Math.random(), Math.random()], | ||
In Zig (or any other language of your choice) we can then utilize this custom | ||
API like so (Please also see example further below in this readme): | ||
API like so (Please also see /test/index.ts` & the example further below in this | ||
readme): | ||
@@ -96,3 +97,5 @@ ```zig | ||
/// JS external to fill vec2 w/ random values | ||
extern fn custom_randomVec2(addr: usize) void; | ||
/// Note: Each API module uses a separate import object to avoid naming clashes | ||
/// Here we declare an external binding belonging to the "custom" import group | ||
extern "custom" fn randomVec2(addr: usize) void; | ||
@@ -106,3 +109,3 @@ export fn test_randomVec2() void { | ||
// populate foo with random numbers | ||
custom_randomVec2(@ptrToInt(&foo)); | ||
randomVec2(@ptrToInt(&foo)); | ||
@@ -190,3 +193,3 @@ // print result | ||
Package sizes (gzipped, pre-treeshake): ESM: 1.63 KB | ||
Package sizes (gzipped, pre-treeshake): ESM: 1.61 KB | ||
@@ -221,2 +224,3 @@ ## Dependencies | ||
// this also initializes any bindings & bridge child APIs (if any) | ||
// (also accepts a fetch() `Response` as input) | ||
await bridge.instantiate(readFileSync("hello.wasm")); | ||
@@ -263,3 +267,3 @@ | ||
(type $none_=>_none (func)) | ||
(import "env" "_printStr" (func $fimport$0 (param i32 i32))) | ||
(import "core" "_printStr" (func $fimport$0 (param i32 i32))) | ||
(global $global$0 (mut i32) (i32.const 65536)) | ||
@@ -266,0 +270,0 @@ (memory $0 2) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
689
293
58732
18