space-data-module-sdk 0.5.18 → 0.5.21

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/README.md CHANGED
@@ -52,6 +52,10 @@ The minimal host surface lives under `src/runtime-host/` and covers three
52
52
  responsibilities:
53
53
 
54
54
  - `createFlatSqlRuntimeStore()` for append-only row handles and row resolution
55
+ - `createFlatBufferStreamIngestor()` for little-endian size-prefixed FlatBuffer
56
+ transport ingest into host-owned row storage without JSON transcoding
57
+ - `createModuleFlatBufferStreamPump()` for feeding those same FlatBuffer stream
58
+ chunks into a resident stateful module instance without JSON envelopes
55
59
  - `createRuntimeRegionStore()` for host-allocated aligned-binary regions and
56
60
  externally backed record-view descriptors
57
61
  - `createModuleRegistry()` for dynamic install/load/unload/invoke
@@ -60,6 +64,9 @@ responsibilities:
60
64
  OrbPro layers entity/view helpers on top of that host instead of inventing a
61
65
  separate durable identity model.
62
66
 
67
+ The canonical FlatBuffer-to-FlatSQL streaming contract is documented in
68
+ [`docs/flatsql-streaming-standard.md`](./docs/flatsql-streaming-standard.md).
69
+
63
70
  ## Module Artifact Model
64
71
 
65
72
  A compliant module built with this SDK is always a valid `.wasm` artifact with:
@@ -189,6 +196,11 @@ the preferred server-side target when the guest needs network-oriented runtime
189
196
  features such as sockets or TLS. Plain `wasi` remains the strict portability
190
197
  baseline; `wasmedge` is the practical higher-capability target.
191
198
 
199
+ If a manifest declares `runtimeTargets: ["browser", "wasmedge"]`, this SDK
200
+ treats that as the explicit "one binary for both" profile. That pair now
201
+ defaults to a shared `single-thread` artifact so the compiled wasm can be loaded
202
+ unchanged by the browser harness and the WasmEdge harness.
203
+
192
204
  ## WasmEdge Pthreads
193
205
 
194
206
  `space-data-module-sdk` is also the source of truth for module thread-model
@@ -197,6 +209,7 @@ selection.
197
209
  - `compileModuleFromSource({ threadModel })` accepts an explicit thread model.
198
210
  - If `threadModel` is omitted, the SDK resolves it from `manifest.runtimeTargets`.
199
211
  - `runtimeTargets: ["wasmedge"]` defaults to `emscripten-pthreads`.
212
+ - `runtimeTargets: ["browser", "wasmedge"]` defaults to `single-thread`.
200
213
  - Other targets currently default to `single-thread`.
201
214
 
202
215
  WasmEdge-targeted pthread builds do not use the embedded `sdn-emception`
@@ -214,11 +227,38 @@ If a runtime cannot interoperate with the guest pthread contract directly,
214
227
  document that as a wrapper requirement instead of changing the guest artifact
215
228
  semantics.
216
229
 
230
+ ## Browser + WasmEdge Isomorphism
231
+
232
+ The supported isomorphic profile and browser edge shims are documented in
233
+ [`docs/browser-wasmedge-isomorphic.md`](./docs/browser-wasmedge-isomorphic.md).
234
+
235
+ The checked-in same-artifact demo lives in
236
+ [`examples/isomorphic-loader`](./examples/isomorphic-loader):
237
+
238
+ - [`build-demo.mjs`](./examples/isomorphic-loader/build-demo.mjs) compiles the
239
+ shared artifact
240
+ - [`browser-demo.html`](./examples/isomorphic-loader/browser-demo.html) and
241
+ [`browser-demo.mjs`](./examples/isomorphic-loader/browser-demo.mjs) load that
242
+ artifact in the browser harness with browser edge shims
243
+ - [`wasmedge-demo.mjs`](./examples/isomorphic-loader/wasmedge-demo.mjs) loads
244
+ that same artifact in WasmEdge
245
+
246
+ Large streamed FlatBuffer ingest should use either the runtime-host transport
247
+ path or the resident-module stream pump, not one giant invoke envelope. See
248
+ [`docs/flatsql-streaming-standard.md`](./docs/flatsql-streaming-standard.md)
249
+ for the recommended browser/WasmEdge/FlatSQL split and the canonical
250
+ direct-binary ingest contract.
251
+
217
252
  ## Testing
218
253
 
219
254
  This repo now exposes a manifest-driven harness generator from
220
255
  `space-data-module-sdk/testing` and two complementary integration suites:
221
256
 
257
+ - browser/isomorphic helpers:
258
+ - `createBrowserModuleHarness(...)`
259
+ - `detectArtifactProfile(...)`
260
+ - `loadModule(...)`
261
+
222
262
  - shared process-level helpers for command-surface runtimes:
223
263
  - `createPluginInvokeProcessClient(...)`
224
264
  - `resolveWasmEdgePluginLaunchPlan(...)`
@@ -233,10 +273,23 @@ This repo now exposes a manifest-driven harness generator from
233
273
  - `npm run test:host-surfaces`
234
274
  - authoritative Node-host coverage for HTTP, TCP, UDP, TLS, WebSocket, MQTT,
235
275
  process execution, timers, filesystem, and the sync `sdn_host` ABI
276
+ - `npm run test:stream-ingest`
277
+ - correctness coverage for chunked size-prefixed FlatBuffer ingest into the
278
+ runtime-host row store
279
+ - `npm run test:module-stream`
280
+ - correctness coverage for chunked FlatBuffer streaming into a resident
281
+ direct-surface module instance
282
+ - `npm run benchmark:stream-1gib`
283
+ - env-gated local stress benchmark for 1 GiB total FlatBuffer transport ingest
284
+ - `npm run benchmark:module-stream-1gib`
285
+ - env-gated local stress benchmark for 1 GiB total chunked module stream-pump
286
+ ingest
236
287
 
237
288
  The detailed edge cases and the current WASI-vs-host portability boundary are
238
289
  documented in
239
- [`docs/testing-harness.md`](./docs/testing-harness.md).
290
+ [`docs/testing-harness.md`](./docs/testing-harness.md). The canonical
291
+ FlatBuffer-to-FlatSQL ingest contract is documented in
292
+ [`docs/flatsql-streaming-standard.md`](./docs/flatsql-streaming-standard.md).
240
293
 
241
294
  ## Install
242
295
 
@@ -410,6 +463,22 @@ For npm packages, the simplest form is:
410
463
  }
411
464
  ```
412
465
 
466
+ For module repos themselves, the canonical compiled artifact should live at:
467
+
468
+ ```text
469
+ dist/isomorphic/module.wasm
470
+ ```
471
+
472
+ If the repo also ships a direct browser adapter, publish it under:
473
+
474
+ ```text
475
+ dist/browser/module.js
476
+ dist/browser/module.wasm
477
+ ```
478
+
479
+ That keeps the shared browser/WasmEdge artifact path stable across repos while
480
+ leaving the browser-specific adapter optional.
481
+
413
482
  When publication metadata is published in the same file, it belongs in an
414
483
  appended SDS `REC` trailer. Loaders scan from the end of the protected blob,
415
484
  resolve `PNM` / `ENC`, strip or decrypt as needed, and only then instantiate
@@ -465,16 +534,16 @@ Manifests can also declare coarse runtime targets for planning and compliance:
465
534
 
466
535
  ```bash
467
536
  # Validate a manifest + wasm pair
468
- npx space-data-module check --manifest ./manifest.json --wasm ./dist/module.wasm
537
+ npx space-data-module check --manifest ./manifest.json --wasm ./dist/isomorphic/module.wasm
469
538
 
470
539
  # Compile C/C++ source and embed the manifest
471
- npx space-data-module compile --manifest ./manifest.json --source ./src/module.c --out ./dist/module.wasm
540
+ npx space-data-module compile --manifest ./manifest.json --source ./src/module.c --out ./dist/isomorphic/module.wasm
472
541
 
473
542
  # Sign and encrypt a deployment payload
474
- npx space-data-module protect --manifest ./manifest.json --wasm ./dist/module.wasm --json
543
+ npx space-data-module protect --manifest ./manifest.json --wasm ./dist/isomorphic/module.wasm --json
475
544
 
476
545
  # Emit a single-file bundled wasm
477
- npx space-data-module protect --manifest ./manifest.json --wasm ./dist/module.wasm --single-file-bundle --out ./dist/module.bundle.wasm
546
+ npx space-data-module protect --manifest ./manifest.json --wasm ./dist/isomorphic/module.wasm --single-file-bundle --out ./dist/module.bundle.wasm
478
547
  ```
479
548
 
480
549
  ## Module Lab
@@ -507,8 +576,11 @@ npm run check:compliance
507
576
  ```
508
577
 
509
578
  Node.js `>=20` is required. The compiler uses `sdn-emception` and `flatc-wasm`
510
- by default for the embedded toolchain path. WasmEdge pthread builds require a
511
- system Emscripten toolchain on `PATH`.
579
+ by default for the embedded toolchain path. For multi-repo module builds, use a
580
+ repo-local `deps/emsdk` checkout by default instead of Homebrew or any other
581
+ machine-global Emscripten install. Treat `PATH` Emscripten as an explicit escape
582
+ hatch, not the default. WasmEdge pthread builds still require a system
583
+ Emscripten toolchain on `PATH`.
512
584
 
513
585
  If another repo needs the same compiler runtime, the package also exposes a
514
586
  shared emception session at `space-data-module-sdk/compiler/emception` with
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "space-data-module-sdk",
3
- "version": "0.5.18",
3
+ "version": "0.5.21",
4
4
  "description": "Module SDK for building, validating, signing, and deploying WebAssembly modules on the Space Data Network.",
5
5
  "type": "module",
6
6
  "types": "./src/index.d.ts",
@@ -35,6 +35,11 @@
35
35
  "types": "./src/index.d.ts",
36
36
  "default": "./src/runtime-host/index.js"
37
37
  },
38
+ "./host/browser": "./src/host/browserHost.js",
39
+ "./host/browser-edge-shims": "./src/host/browserEdgeShims.js",
40
+ "./host/wasi-shim": "./src/host/wasiShim.js",
41
+ "./host/isomorphic": "./src/host/isomorphicLoader.js",
42
+ "./testing/browser": "./src/testing/browserModuleHarness.js",
38
43
  "./testing": "./src/testing/index.js",
39
44
  "./standards": "./src/standards/index.js",
40
45
  "./schemas/*": "./schemas/*"
@@ -48,6 +53,10 @@
48
53
  "test": "node --test",
49
54
  "test:host-surfaces": "node --test test/node-host.test.js test/host-abi.test.js",
50
55
  "test:runtime-matrix": "SPACE_DATA_MODULE_SDK_ENABLE_RUNTIME_MATRIX=1 node --test test/runtime-matrix.test.js",
56
+ "test:stream-ingest": "node --test test/runtime-host-stream-ingest.test.js",
57
+ "test:module-stream": "node --test test/module-flatbuffer-stream-pump.test.js",
58
+ "benchmark:stream-1gib": "SPACE_DATA_MODULE_SDK_ENABLE_1GB_STREAM_TEST=1 node --test test/runtime-host-stream-ingest.test.js",
59
+ "benchmark:module-stream-1gib": "SPACE_DATA_MODULE_SDK_ENABLE_1GB_MODULE_STREAM_TEST=1 node --test test/module-flatbuffer-stream-pump.test.js",
51
60
  "start:lab": "node ./lab/server.js",
52
61
  "check:compliance": "node ./bin/space-data-module.js check --repo-root .",
53
62
  "generate:vectors": "node ./examples/single-file-bundle/generate-vectors.mjs",
package/src/AGENTS.md ADDED
@@ -0,0 +1,33 @@
1
+ # AGENTS
2
+
3
+ Apply the root `AGENTS.md` first. This file routes source edits to the correct
4
+ subsystem.
5
+
6
+ ## Source Routing
7
+
8
+ - `src/manifest`, `src/compliance`, `src/standards`: manifest shape, type refs,
9
+ standards validation, and compliance warnings/errors.
10
+ - `src/manifest/AGENTS.md`, `src/compliance/AGENTS.md`, `src/bundle/AGENTS.md`,
11
+ and `src/auth/AGENTS.md` provide narrower rules for those owners.
12
+ - `src/compiler`: compile flow, manifest embedding, runtime targets, toolchains,
13
+ and artifact layout.
14
+ - `src/bundle`: `sds.bundle`, wasm custom sections, and vector compatibility.
15
+ - `src/host`: Node host, browser shims, `sdn_host`, WasmEdge runners, and
16
+ isomorphic loaders.
17
+ - `src/runtime-host`: FlatSQL-backed runtime host, row/region identity, and
18
+ binary stream ingest.
19
+ - `src/testing`: harnesses, browser module loading, process invoke clients, and
20
+ module-owned FlatBuffer stream pumps.
21
+ - `src/auth`, `src/transport`, `src/deployment`: signing, encryption, REC/PNM/
22
+ ENC records, deployment plans, and publication protection.
23
+ - `src/generated`: generated code. Do not hand-edit unless regeneration is part
24
+ of the task and you update the generation path or fixtures as needed.
25
+
26
+ ## Working Rules
27
+
28
+ - Keep module contracts portable unless the task is explicitly runtime-specific.
29
+ - Prefer changes in the smallest subsystem that owns the behavior.
30
+ - If a change crosses compiler, host, and docs, update each owner explicitly
31
+ rather than hiding policy in one layer.
32
+ - Add or update tests near the owning subsystem and then wire them into the
33
+ repo-level verification set in `test/AGENTS.md`.
@@ -0,0 +1,25 @@
1
+ # AGENTS
2
+
3
+ You are in `src/auth`, which owns deployment authorization, signing helpers,
4
+ and related record handling used by module distribution.
5
+
6
+ ## Rules
7
+
8
+ - Keep signing and authorization flows deterministic and explicit.
9
+ - Do not invent app-local signature records when a repo-level contract belongs
10
+ here.
11
+ - When auth changes affect transport or deployment plans, update the related
12
+ surfaces together rather than splitting incompatible changes across repos.
13
+
14
+ ## Related Surfaces
15
+
16
+ - `src/transport`
17
+ - `src/deployment`
18
+ - `test/transport-records.test.js`
19
+ - `test/deployment-plan.test.js`
20
+
21
+ ## Check Before You Finish
22
+
23
+ - `npm test`
24
+ - `npm run check:compliance`
25
+ - `node --test test/transport-records.test.js test/deployment-plan.test.js`
package/src/browser.js CHANGED
@@ -6,3 +6,11 @@ export * from "./capabilities.js";
6
6
  export * from "./deployment/index.js";
7
7
  export * from "./invoke/index.js";
8
8
  export * from "./runtime/index.js";
9
+ export * from "./runtime-host/index.js";
10
+ export * from "./host/browserHost.js";
11
+ export * from "./host/browserEdgeShims.js";
12
+ export * from "./host/wasiShim.js";
13
+ export * from "./host/abi.js";
14
+ export * from "./host/isomorphicLoader.js";
15
+ export { createBrowserModuleHarness, detectArtifactProfile } from "./testing/browserModuleHarness.js";
16
+ export { createModuleFlatBufferStreamPump } from "./testing/moduleFlatbufferStreamPump.js";
@@ -0,0 +1,21 @@
1
+ # AGENTS
2
+
3
+ You are in `src/bundle`, which owns `sds.bundle` and the wasm custom-section
4
+ packaging rules.
5
+
6
+ ## Rules
7
+
8
+ - `sds.bundle` is the single-file delivery format.
9
+ - Put bundle data in a wasm custom section; do not append raw bytes after the
10
+ wasm binary.
11
+ - Keep parser, encoder, CLI behavior, vectors, and cross-language fixtures in
12
+ sync.
13
+ - If the bundle contract changes, regenerate vectors and update the bundle docs
14
+ and demos in the same change.
15
+
16
+ ## Check Before You Finish
17
+
18
+ - `npm test`
19
+ - `npm run check:compliance`
20
+ - `node --test test/module-bundle.test.js test/module-bundle-vectors.test.js test/module-bundle-cli.test.js test/module-bundle-go.test.js test/module-bundle-python.test.js`
21
+ - `npm run generate:vectors` when vectors or the contract changed
@@ -0,0 +1,35 @@
1
+ # AGENTS
2
+
3
+ Apply the root and `src/AGENTS.md` files first.
4
+
5
+ ## Area Ownership
6
+
7
+ This directory owns source-to-wasm compile behavior, manifest embedding, runtime
8
+ target inference, toolchain integration, and canonical artifact layout.
9
+
10
+ ## Compiler Rules
11
+
12
+ - Preserve the canonical manifest accessor exports and validate them together
13
+ with compiled wasm.
14
+ - For shared browser/WasmEdge modules, emit the standalone artifact at
15
+ `dist/isomorphic/module.wasm`.
16
+ - Optional browser adapters belong under `dist/browser/`.
17
+ - Do not make browser/WasmEdge shared artifacts depend on pthread-style `env.*`
18
+ imports.
19
+ - Prefer repo-local Emscripten or `sdn-emception`. Do not assume Homebrew
20
+ toolchains.
21
+ - If you change runtime-target inference, keep the browser/WasmEdge shared path
22
+ on the standalone profile unless the docs and tests are updated deliberately.
23
+
24
+ ## Key Files
25
+
26
+ - `compileModule.js`
27
+ - `compileModuleFromSource.js`
28
+ - `emception*.js`
29
+ - `invokeGlue.js`
30
+
31
+ ## Verification
32
+
33
+ - `node --test test/module-sdk.test.js test/compliance.test.js`
34
+ - `node --test test/browser-harness.test.js test/isomorphic-loader.test.js`
35
+ - `node --test test/compiler-emception-subpath-export.test.js`
@@ -142,6 +142,9 @@ function resolveThreadModel({ manifest, threadModel } = {}) {
142
142
  .map((target) => String(target ?? "").trim().toLowerCase())
143
143
  .filter(Boolean)
144
144
  : [];
145
+ if (runtimeTargets.includes(RuntimeTarget.BROWSER)) {
146
+ return ModuleThreadModel.SINGLE_THREAD;
147
+ }
145
148
  if (runtimeTargets.includes(RuntimeTarget.WASMEDGE)) {
146
149
  return ModuleThreadModel.EMSCRIPTEN_PTHREADS;
147
150
  }
@@ -0,0 +1,18 @@
1
+ # AGENTS
2
+
3
+ You are in `src/compliance`, which defines what counts as a compliant module or
4
+ artifact.
5
+
6
+ ## Rules
7
+
8
+ - Treat this directory as policy, not convenience code.
9
+ - When tightening validation, update tests and error messages together so the
10
+ failure mode is actionable.
11
+ - When relaxing validation, make sure the compiler, docs, and examples still
12
+ describe the broader contract accurately.
13
+
14
+ ## Check Before You Finish
15
+
16
+ - `npm test`
17
+ - `npm run check:compliance`
18
+ - `node --test test/module-sdk.test.js test/compliance.test.js`
@@ -30,7 +30,6 @@ const ExternalInterfaceKindSet = new Set(Object.values(ExternalInterfaceKind));
30
30
  const ProtocolRoleSet = new Set(Object.values(ProtocolRole));
31
31
  const ProtocolTransportKindSet = new Set(Object.values(ProtocolTransportKind));
32
32
  const BrowserIncompatibleCapabilitySet = new Set([
33
- "filesystem",
34
33
  "pipe",
35
34
  "network",
36
35
  "tcp",
@@ -0,0 +1,39 @@
1
+ # AGENTS
2
+
3
+ Apply the root and `src/AGENTS.md` files first.
4
+
5
+ ## Area Ownership
6
+
7
+ This directory owns the Node reference host, browser host, browser edge shims,
8
+ WASI shims, the sync `sdn_host` ABI bridge, WasmEdge launch planning, and the
9
+ isomorphic loader path.
10
+
11
+ ## Host Rules
12
+
13
+ - Shared browser/WasmEdge artifacts must stay within standalone WASI plus the
14
+ optional `sdn_host` bridge. Raw WasmEdge-native extension imports are not
15
+ browser-isomorphic.
16
+ - Browser shims are host-side replacements, not a promise that the guest can
17
+ import WasmEdge-native sockets, TLS, or filesystem extensions directly.
18
+ - Keep the sync guest-host ABI narrow and deliberate. Avoid adding new hostcalls
19
+ unless the Node host, browser path, docs, and tests all agree on semantics.
20
+ - Scope host capabilities tightly: filesystem roots, network allowlists, TLS,
21
+ exec, timers, and crypto should stay explicit.
22
+
23
+ ## Key Files
24
+
25
+ - `abi.js`
26
+ - `browserEdgeShims.js`
27
+ - `browserHost.js`
28
+ - `isomorphicLoader.js`
29
+ - `nodeHost.js`
30
+ - `wasiShim.js`
31
+
32
+ ## Verification
33
+
34
+ - `node --test test/node-host.test.js test/host-abi.test.js`
35
+ - `node --test test/browser-harness.test.js test/isomorphic-loader.test.js`
36
+ - `node --test test/process-invoke.test.js`
37
+ - `node --test test/wasmedge-runner-build.test.js`
38
+ - `node --test test/wasmedge-runner-runtime.test.js` when WasmEdge behavior is
39
+ part of the change