@thi.ng/wasm-api 1.1.1 → 1.2.1
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 +7 -1
- package/README.md +40 -16
- package/package.json +7 -2
- package/zig/build.zig +135 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2022-
|
|
3
|
+
- **Last updated**: 2022-12-02T14:13:34Z
|
|
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,12 @@ 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
|
+
## [1.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@1.2.0) (2022-12-01)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- add build script for user projects ([7164f5e](https://github.com/thi-ng/umbrella/commit/7164f5e))
|
|
17
|
+
|
|
12
18
|
## [1.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/wasm-api@1.1.0) (2022-11-28)
|
|
13
19
|
|
|
14
20
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -11,11 +11,12 @@ This project is part of the
|
|
|
11
11
|
|
|
12
12
|
- [About](#about)
|
|
13
13
|
- [Custom API modules](#custom-api-modules)
|
|
14
|
-
- [Building Zig projects with these hybrid API modules](#building-zig-projects-with-these-hybrid-api-modules)
|
|
15
14
|
- [String handling](#string-handling)
|
|
16
15
|
- [Memory allocations](#memory-allocations)
|
|
17
16
|
- [API module auto-initialization](#api-module-auto-initialization)
|
|
18
17
|
- [Object indices & handles](#object-indices--handles)
|
|
18
|
+
- [Using the Zig build system](#using-the-zig-build-system)
|
|
19
|
+
- [Naming & structural conventions](#naming--structural-conventions)
|
|
19
20
|
- [Status](#status)
|
|
20
21
|
- [Support packages](#support-packages)
|
|
21
22
|
- [Installation](#installation)
|
|
@@ -55,13 +56,15 @@ WebGL, WebGPU, WebAudio etc. is being actively worked on.
|
|
|
55
56
|
defining glue code for the TypeScript [core
|
|
56
57
|
API](https://docs.thi.ng/umbrella/wasm-api/interfaces/CoreAPI.html) defined
|
|
57
58
|
by this package
|
|
58
|
-
7.
|
|
59
|
+
7. [Zig build files]() to simplify using hybrid TS/Zig packages with the
|
|
60
|
+
built-in build system
|
|
61
|
+
8. Extensible shared [datatype code generator
|
|
59
62
|
infrastructure](https://github.com/thi-ng/umbrella/tree/develop/packages/wasm-api-bindgen/)
|
|
60
63
|
for (currently) Zig & TypeScript and C11. For TS fully type checked and
|
|
61
64
|
memory-mapped (zero-copy) accessors of WASM-side data are generated. In
|
|
62
65
|
principle, all languages with a WASM target are supported, however currently
|
|
63
66
|
only bindings for these mentioned langs are included.
|
|
64
|
-
|
|
67
|
+
9. [CLI
|
|
65
68
|
frontend/utility](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-bindgen/README.md#cli-generator)
|
|
66
69
|
for the code generator(s)
|
|
67
70
|
|
|
@@ -165,19 +168,6 @@ export fn test_randomVec4() void {
|
|
|
165
168
|
}
|
|
166
169
|
```
|
|
167
170
|
|
|
168
|
-
### Building Zig projects with these hybrid API modules
|
|
169
|
-
|
|
170
|
-
Some example projects (see [list below](#usage-examples)) provide custom
|
|
171
|
-
[`build.zig`](https://github.com/thi-ng/umbrella/blob/develop/examples/zig-canvas/build.zig)
|
|
172
|
-
&
|
|
173
|
-
[`npm.zig`](https://github.com/thi-ng/umbrella/blob/develop/examples/zig-canvas/npm.zig)
|
|
174
|
-
build scripts to easily integrate these hybrid TS/Zig packages into users'
|
|
175
|
-
development processes.
|
|
176
|
-
|
|
177
|
-
To avoid guesswork about the internals of these API modules, all of them are
|
|
178
|
-
using an overall uniform structure, with the main Zig entry point in
|
|
179
|
-
`/zig/lib.zig`...
|
|
180
|
-
|
|
181
171
|
## String handling
|
|
182
172
|
|
|
183
173
|
Most low-level languages deal with strings very differently and alas there's no
|
|
@@ -313,6 +303,40 @@ in the
|
|
|
313
303
|
[@thi.ng/wasm-api-schedule](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api-schedule/)
|
|
314
304
|
packages this is used to manage Zig-side event listeners.
|
|
315
305
|
|
|
306
|
+
## Using the Zig build system
|
|
307
|
+
|
|
308
|
+
This package provides utilities to simplify using hybrid TS/Zig WASM API modules which are distributed as NPM packages. Using these utils, a build file for Zig's built-in build system is as simple as:
|
|
309
|
+
|
|
310
|
+
```zig
|
|
311
|
+
const std = @import("std");
|
|
312
|
+
|
|
313
|
+
pub fn build(b: *std.build.Builder) void {
|
|
314
|
+
@import("node_modules/@thi.ng/wasm-api/zig/build.zig").wasmLib(b, .{
|
|
315
|
+
// Declare extra WASM API packages to use
|
|
316
|
+
// Each package can also declare dependencies to other such packages
|
|
317
|
+
// (wasm-api and wasm-api-bindgen are made available everywhere)
|
|
318
|
+
.packages = &.{
|
|
319
|
+
.{ .id = "wasm-api-dom", .path = "@thi.ng/wasm-api-dom/zig/lib.zig" },
|
|
320
|
+
.{ .id = "wasm-api-schedule", .path = "@thi.ng/wasm-api-schedule/zig/lib.zig" },
|
|
321
|
+
},
|
|
322
|
+
// (optional) build mode override
|
|
323
|
+
// if commented out, we can pass CLI args to choose build mode (default: .Debug)
|
|
324
|
+
.mode = .ReleaseSmall,
|
|
325
|
+
}).install();
|
|
326
|
+
}
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
All bundled example projects (see [list below](#usage-examples)) are being built
|
|
330
|
+
via this script. **Please find more details/options in the commented source
|
|
331
|
+
code:**
|
|
332
|
+
[`/zig/build.zig`](https://github.com/thi-ng/umbrella/blob/develop/packages/wasm-api/zig/build.zig)
|
|
333
|
+
|
|
334
|
+
## Naming & structural conventions
|
|
335
|
+
|
|
336
|
+
To avoid guesswork about the internals of any of the supplied WASM API modules,
|
|
337
|
+
please also consult the information in
|
|
338
|
+
[#368](https://github.com/thi-ng/umbrella/issues/368).
|
|
339
|
+
|
|
316
340
|
## Status
|
|
317
341
|
|
|
318
342
|
**ALPHA** - bleeding edge / work-in-progress
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/wasm-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Generic, modular, extensible API bridge and infrastructure for hybrid JS & WebAssembly projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -55,19 +55,24 @@
|
|
|
55
55
|
"allocator",
|
|
56
56
|
"api",
|
|
57
57
|
"bindings",
|
|
58
|
+
"bigint",
|
|
58
59
|
"browser",
|
|
59
60
|
"c",
|
|
60
61
|
"event",
|
|
62
|
+
"hex",
|
|
61
63
|
"interop",
|
|
62
64
|
"logger",
|
|
63
65
|
"memory",
|
|
64
66
|
"modular",
|
|
67
|
+
"polyglot",
|
|
68
|
+
"shared-memory",
|
|
65
69
|
"string",
|
|
66
70
|
"typedarray",
|
|
67
71
|
"typescript",
|
|
68
72
|
"utf8",
|
|
69
73
|
"wasm",
|
|
70
74
|
"webassembly",
|
|
75
|
+
"zig",
|
|
71
76
|
"ziglang"
|
|
72
77
|
],
|
|
73
78
|
"publishConfig": {
|
|
@@ -110,5 +115,5 @@
|
|
|
110
115
|
"status": "alpha",
|
|
111
116
|
"year": 2022
|
|
112
117
|
},
|
|
113
|
-
"gitHead": "
|
|
118
|
+
"gitHead": "7d1e314f207299ff3c1a782d287ad99120b40b85\n"
|
|
114
119
|
}
|
package/zig/build.zig
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
|
|
3
|
+
/// Definition for a (usually hybrid) Zig package which will be distributed via NPM
|
|
4
|
+
pub const Pkg = struct {
|
|
5
|
+
/// Package ID used for @import
|
|
6
|
+
id: []const u8,
|
|
7
|
+
/// Package sub path (appended to base path)
|
|
8
|
+
path: []const u8,
|
|
9
|
+
/// Package dependencies aka other package IDs.
|
|
10
|
+
/// All of them must already have been registered
|
|
11
|
+
deps: ?[]const []const u8 = null,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
pub const PkgOpts = struct {
|
|
15
|
+
/// Base path to common node_modules directory under which
|
|
16
|
+
/// all to be imported packages are located
|
|
17
|
+
base: []const u8 = "node_modules",
|
|
18
|
+
/// Additional WASM API support packages.
|
|
19
|
+
/// We don't need to specify core wasmapi, only custom/extra ones
|
|
20
|
+
/// `wasm-api` and `wasm-api-bindgen` are also auto-added
|
|
21
|
+
/// as dependency for each of these...
|
|
22
|
+
packages: ?[]const Pkg = null,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/// Dependency graph for WASM API packages
|
|
26
|
+
/// Expands & resolves the more compact/convenient/human friendly format of PkgOpts
|
|
27
|
+
/// into the data structures used by Zig's build system
|
|
28
|
+
/// Provides a `addAllTo()` function to add all declared packages to a build step
|
|
29
|
+
pub const PkgGraph = struct {
|
|
30
|
+
arena: std.heap.ArenaAllocator,
|
|
31
|
+
basePath: []const u8,
|
|
32
|
+
packages: std.StringArrayHashMap(std.build.Pkg),
|
|
33
|
+
|
|
34
|
+
const Self = @This();
|
|
35
|
+
|
|
36
|
+
pub fn init(opts: PkgOpts) Self {
|
|
37
|
+
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
|
38
|
+
var self = Self{
|
|
39
|
+
.arena = arena,
|
|
40
|
+
.basePath = opts.base,
|
|
41
|
+
.packages = std.StringArrayHashMap(std.build.Pkg).init(arena.allocator()),
|
|
42
|
+
};
|
|
43
|
+
const api = "wasm-api";
|
|
44
|
+
self.packages.put(api, .{
|
|
45
|
+
.name = api,
|
|
46
|
+
.source = .{ .path = self.modulePath("@thi.ng/wasm-api/zig/lib.zig") },
|
|
47
|
+
}) catch unreachable;
|
|
48
|
+
const apiTypes = "wasm-api-bindgen";
|
|
49
|
+
self.packages.put(apiTypes, .{
|
|
50
|
+
.name = apiTypes,
|
|
51
|
+
.source = .{ .path = self.modulePath("@thi.ng/wasm-api-bindgen/zig/lib.zig") },
|
|
52
|
+
}) catch unreachable;
|
|
53
|
+
if (opts.packages) |pkgs| {
|
|
54
|
+
for (pkgs) |pkg| {
|
|
55
|
+
self.register(pkg.id, pkg.path, pkg.deps);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return self;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
pub fn deinit(self: *const Self) void {
|
|
62
|
+
self.arena.deinit();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/// Registers a single package and its deps (also injects core wasm-api deps)
|
|
66
|
+
pub fn register(
|
|
67
|
+
self: *Self,
|
|
68
|
+
name: []const u8,
|
|
69
|
+
path: []const u8,
|
|
70
|
+
dependencies: ?[]const []const u8,
|
|
71
|
+
) void {
|
|
72
|
+
var pkg = std.build.Pkg{
|
|
73
|
+
.name = name,
|
|
74
|
+
.source = .{ .path = self.modulePath(path) },
|
|
75
|
+
};
|
|
76
|
+
const num = if (dependencies) |deps| deps.len else 0;
|
|
77
|
+
var dpkgs = self.arena.allocator().alloc(std.build.Pkg, num + 2) catch unreachable;
|
|
78
|
+
dpkgs[0] = if (self.packages.get("wasm-api")) |p| p else unreachable;
|
|
79
|
+
dpkgs[1] = if (self.packages.get("wasm-api-bindgen")) |p| p else unreachable;
|
|
80
|
+
if (dependencies) |deps| {
|
|
81
|
+
var i: usize = 0;
|
|
82
|
+
while (i < deps.len) : (i += 1) {
|
|
83
|
+
if (self.packages.get(deps[i])) |p| {
|
|
84
|
+
dpkgs[i + 1] = p;
|
|
85
|
+
} else @panic("unknown dependency");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
pkg.dependencies = dpkgs;
|
|
89
|
+
self.packages.put(name, pkg) catch unreachable;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/// Adds all registered packages to the given build step
|
|
93
|
+
pub fn addAllTo(self: *const Self, step: *std.build.LibExeObjStep) void {
|
|
94
|
+
for (self.packages.values()) |pkg| step.addPackage(pkg);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
fn modulePath(self: *Self, path: []const u8) []const u8 {
|
|
98
|
+
return std.fs.path.join(self.arena.allocator(), &.{ self.basePath, path }) catch unreachable;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/// Config options
|
|
103
|
+
pub const WasmLibOpts = struct {
|
|
104
|
+
/// Relative path to base directory for WASM API packages
|
|
105
|
+
base: []const u8 = "node_modules",
|
|
106
|
+
/// Relative path to root source file
|
|
107
|
+
root: []const u8 = "zig/main.zig",
|
|
108
|
+
/// Relative path to output directory
|
|
109
|
+
out: []const u8 = "src",
|
|
110
|
+
/// Package definitions for additional WASM API modules
|
|
111
|
+
packages: ?[]const Pkg = null,
|
|
112
|
+
/// Build mode override (else allows config via CLI args)
|
|
113
|
+
mode: ?std.builtin.Mode = null,
|
|
114
|
+
/// Additional WASM target features, e.g. `.simd128` to enable SIMD
|
|
115
|
+
features: ?[]const std.Target.wasm.Feature = null,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/// Creates and returns a build step to build a dynamic WASM library, configured
|
|
119
|
+
/// with given options and package declarations. The given package specs will be inserted
|
|
120
|
+
pub fn wasmLib(b: *std.build.Builder, opts: WasmLibOpts) *std.build.LibExeObjStep {
|
|
121
|
+
const lib = b.addSharedLibrary("main", opts.root, .unversioned);
|
|
122
|
+
lib.setTarget(.{
|
|
123
|
+
.cpu_arch = .wasm32,
|
|
124
|
+
.os_tag = .freestanding,
|
|
125
|
+
.cpu_features_add = if (opts.features) |features| std.Target.wasm.featureSet(features) else std.Target.Cpu.Feature.Set.empty,
|
|
126
|
+
});
|
|
127
|
+
const mode = if (opts.mode) |m| m else b.standardReleaseOptions();
|
|
128
|
+
lib.setBuildMode(mode);
|
|
129
|
+
if (mode == .ReleaseSmall or mode == .ReleaseFast) lib.strip = true;
|
|
130
|
+
const pkgs = PkgGraph.init(.{ .base = opts.base, .packages = opts.packages });
|
|
131
|
+
defer pkgs.deinit();
|
|
132
|
+
pkgs.addAllTo(lib);
|
|
133
|
+
lib.setOutputDir(opts.out);
|
|
134
|
+
return lib;
|
|
135
|
+
}
|