space-data-module-sdk 0.2.0 → 0.2.5
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 +74 -2
- package/package.json +10 -3
- package/schemas/PluginInvokeRequest.fbs +18 -0
- package/schemas/PluginInvokeResponse.fbs +30 -0
- package/schemas/PluginManifest.fbs +7 -0
- package/schemas/TypedArenaBuffer.fbs +23 -2
- package/src/bundle/codec.js +24 -0
- package/src/compiler/compileModule.js +274 -106
- package/src/compiler/emceptionNode.js +217 -0
- package/src/compiler/flatcSupport.js +66 -0
- package/src/compiler/invokeGlue.js +884 -0
- package/src/compliance/pluginCompliance.js +241 -1
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +51 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.js +131 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-request.ts +173 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +76 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.js +184 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +1 -0
- package/src/generated/orbpro/invoke/plugin-invoke-response.ts +243 -0
- package/src/generated/orbpro/invoke.d.ts +3 -0
- package/src/generated/orbpro/invoke.d.ts.map +1 -0
- package/src/generated/orbpro/invoke.js +5 -0
- package/src/generated/orbpro/invoke.js.map +1 -0
- package/src/generated/orbpro/invoke.ts +6 -0
- package/src/generated/orbpro/manifest/accepted-type-set.d.ts +4 -4
- package/src/generated/orbpro/manifest/accepted-type-set.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/accepted-type-set.js +18 -11
- package/src/generated/orbpro/manifest/accepted-type-set.js.map +1 -1
- package/src/generated/orbpro/manifest/build-artifact.d.ts +1 -1
- package/src/generated/orbpro/manifest/build-artifact.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/build-artifact.js +28 -15
- package/src/generated/orbpro/manifest/build-artifact.js.map +1 -1
- package/src/generated/orbpro/manifest/capability-kind.d.ts +1 -1
- package/src/generated/orbpro/manifest/capability-kind.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/capability-kind.js +1 -1
- package/src/generated/orbpro/manifest/capability-kind.js.map +1 -1
- package/src/generated/orbpro/manifest/drain-policy.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/drain-policy.js.map +1 -1
- package/src/generated/orbpro/manifest/host-capability.d.ts +2 -2
- package/src/generated/orbpro/manifest/host-capability.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/host-capability.js +19 -11
- package/src/generated/orbpro/manifest/host-capability.js.map +1 -1
- package/src/generated/orbpro/manifest/invoke-surface.d.ts +8 -0
- package/src/generated/orbpro/manifest/invoke-surface.d.ts.map +1 -0
- package/src/generated/orbpro/manifest/invoke-surface.js +11 -0
- package/src/generated/orbpro/manifest/invoke-surface.js.map +1 -0
- package/src/generated/orbpro/manifest/invoke-surface.ts +11 -0
- package/src/generated/orbpro/manifest/method-manifest.d.ts +6 -6
- package/src/generated/orbpro/manifest/method-manifest.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/method-manifest.js +33 -16
- package/src/generated/orbpro/manifest/method-manifest.js.map +1 -1
- package/src/generated/orbpro/manifest/plugin-family.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/plugin-family.js.map +1 -1
- package/src/generated/orbpro/manifest/plugin-manifest.d.ts +10 -2
- package/src/generated/orbpro/manifest/plugin-manifest.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/plugin-manifest.js +48 -9
- package/src/generated/orbpro/manifest/plugin-manifest.js.map +1 -1
- package/src/generated/orbpro/manifest/plugin-manifest.ts +322 -491
- package/src/generated/orbpro/manifest/port-manifest.d.ts +4 -4
- package/src/generated/orbpro/manifest/port-manifest.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/port-manifest.js +26 -13
- package/src/generated/orbpro/manifest/port-manifest.js.map +1 -1
- package/src/generated/orbpro/manifest/protocol-spec.d.ts +1 -1
- package/src/generated/orbpro/manifest/protocol-spec.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/protocol-spec.js +28 -15
- package/src/generated/orbpro/manifest/protocol-spec.js.map +1 -1
- package/src/generated/orbpro/manifest/timer-spec.d.ts +1 -1
- package/src/generated/orbpro/manifest/timer-spec.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/timer-spec.js +27 -16
- package/src/generated/orbpro/manifest/timer-spec.js.map +1 -1
- package/src/generated/orbpro/manifest.d.ts +13 -0
- package/src/generated/orbpro/manifest.d.ts.map +1 -0
- package/src/generated/orbpro/manifest.js +1 -0
- package/src/generated/orbpro/manifest.js.map +1 -0
- package/src/generated/orbpro/manifest.ts +16 -0
- package/src/generated/orbpro/stream/buffer-mutability.d.ts.map +1 -1
- package/src/generated/orbpro/stream/buffer-mutability.js.map +1 -1
- package/src/generated/orbpro/stream/buffer-ownership.d.ts.map +1 -1
- package/src/generated/orbpro/stream/buffer-ownership.js.map +1 -1
- package/src/generated/orbpro/stream/flat-buffer-type-ref.d.ts +22 -5
- package/src/generated/orbpro/stream/flat-buffer-type-ref.d.ts.map +1 -1
- package/src/generated/orbpro/stream/flat-buffer-type-ref.js +107 -17
- package/src/generated/orbpro/stream/flat-buffer-type-ref.js.map +1 -1
- package/src/generated/orbpro/stream/flat-buffer-type-ref.ts +126 -2
- package/src/generated/orbpro/stream/payload-wire-format.d.ts +8 -0
- package/src/generated/orbpro/stream/payload-wire-format.d.ts.map +1 -0
- package/src/generated/orbpro/stream/payload-wire-format.js +11 -0
- package/src/generated/orbpro/stream/payload-wire-format.js.map +1 -0
- package/src/generated/orbpro/stream/payload-wire-format.ts +11 -0
- package/src/generated/orbpro/stream/typed-arena-buffer.d.ts +4 -4
- package/src/generated/orbpro/stream/typed-arena-buffer.d.ts.map +1 -1
- package/src/generated/orbpro/stream/typed-arena-buffer.js +42 -24
- package/src/generated/orbpro/stream/typed-arena-buffer.js.map +1 -1
- package/src/index.d.ts +83 -5
- package/src/index.js +3 -0
- package/src/invoke/codec.js +278 -0
- package/src/invoke/index.js +9 -0
- package/src/manifest/codec.js +10 -2
- package/src/manifest/index.js +5 -2
- package/src/manifest/normalize.js +58 -0
- package/src/runtime/constants.js +12 -0
package/README.md
CHANGED
|
@@ -27,6 +27,11 @@ A module built with this SDK is a `.wasm` artifact with:
|
|
|
27
27
|
- exported manifest accessors:
|
|
28
28
|
- `plugin_get_manifest_flatbuffer`
|
|
29
29
|
- `plugin_get_manifest_flatbuffer_size`
|
|
30
|
+
- canonical invoke exports when the artifact supports direct in-memory calls:
|
|
31
|
+
- `plugin_invoke_stream`
|
|
32
|
+
- `plugin_alloc`
|
|
33
|
+
- `plugin_free`
|
|
34
|
+
- an exported `_start` entry when the artifact supports WASI command mode
|
|
30
35
|
- optional `sds.bundle` custom-section payloads for:
|
|
31
36
|
- manifest bytes
|
|
32
37
|
- deployment authorization
|
|
@@ -37,6 +42,45 @@ A module built with this SDK is a `.wasm` artifact with:
|
|
|
37
42
|
The module contract stays the same whether the artifact is loaded directly,
|
|
38
43
|
wrapped in a deployment envelope, or shipped as one bundled `.wasm` file.
|
|
39
44
|
|
|
45
|
+
## Canonical Invoke ABI
|
|
46
|
+
|
|
47
|
+
Modules can now declare one or both canonical invoke surfaces in
|
|
48
|
+
`manifest.invokeSurfaces`:
|
|
49
|
+
|
|
50
|
+
- `direct`: in-memory invocation through `plugin_invoke_stream`
|
|
51
|
+
- `command`: WASI command-mode invocation through `_start`
|
|
52
|
+
|
|
53
|
+
Both surfaces consume and produce the same FlatBuffer envelopes:
|
|
54
|
+
|
|
55
|
+
- `PluginInvokeRequest`
|
|
56
|
+
- `PluginInvokeResponse`
|
|
57
|
+
|
|
58
|
+
Those envelopes route SDS payload frames by `portId` using
|
|
59
|
+
`TypedArenaBuffer.fbs` and a shared payload arena. Command mode reads one
|
|
60
|
+
request from `stdin` and writes one response to `stdout`. Direct mode takes the
|
|
61
|
+
same request bytes from guest memory and returns response bytes in guest
|
|
62
|
+
memory.
|
|
63
|
+
|
|
64
|
+
For simple single-input / single-output methods, command mode also supports a
|
|
65
|
+
degenerate raw shortcut:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
wasmedge module.wasm --method echo < input.fb > output.fb
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
That shortcut is only valid when the method declares exactly one input port and
|
|
72
|
+
at most one output port.
|
|
73
|
+
|
|
74
|
+
Source-built modules can include `space_data_module_invoke.h` and use the
|
|
75
|
+
generated helper functions to read the active invocation inputs and emit SDS
|
|
76
|
+
outputs. The reference invoke examples live in
|
|
77
|
+
[`examples/invoke-echo`](./examples/invoke-echo):
|
|
78
|
+
|
|
79
|
+
- `manifest.direct.json`
|
|
80
|
+
- `manifest.command.json`
|
|
81
|
+
- `manifest.hybrid.json`
|
|
82
|
+
- `module.c`
|
|
83
|
+
|
|
40
84
|
## Runtime Portability
|
|
41
85
|
|
|
42
86
|
The module format is language-neutral. A host can load modules from this SDK
|
|
@@ -135,6 +179,33 @@ The reference path lives in
|
|
|
135
179
|
- the `go` and `python` directories show non-JS readers against the same
|
|
136
180
|
bundle contract
|
|
137
181
|
|
|
182
|
+
## Module Publication
|
|
183
|
+
|
|
184
|
+
Packages that publish SDN modules now use the canonical `sdn-module`
|
|
185
|
+
publication descriptor. That descriptor covers:
|
|
186
|
+
|
|
187
|
+
- standalone module packages
|
|
188
|
+
- attached module artifacts shipped inside another language library
|
|
189
|
+
- discovery of bundled wasm, sidecar signatures, and encrypted transport
|
|
190
|
+
FlatBuffers
|
|
191
|
+
|
|
192
|
+
The full standard is in
|
|
193
|
+
[`docs/module-publication-standard.md`](./docs/module-publication-standard.md),
|
|
194
|
+
with concrete examples under [`examples/publishing`](./examples/publishing).
|
|
195
|
+
|
|
196
|
+
For npm packages, the simplest form is:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"name": "@example/orbit-lib",
|
|
201
|
+
"version": "1.2.3",
|
|
202
|
+
"sdn-module": "./dist/orbit-lib.module.wasm"
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
When signature or transport metadata is published in the same file, it belongs
|
|
207
|
+
inside `sds.bundle`, not as raw bytes after the end of the wasm binary.
|
|
208
|
+
|
|
138
209
|
## Host ABI
|
|
139
210
|
|
|
140
211
|
This repo also defines the module-facing capability vocabulary and the first
|
|
@@ -222,8 +293,9 @@ npm test
|
|
|
222
293
|
npm run check:compliance
|
|
223
294
|
```
|
|
224
295
|
|
|
225
|
-
Node.js `>=20` is required.
|
|
226
|
-
|
|
296
|
+
Node.js `>=20` is required. The compiler uses `sdn-emception` and `flatc-wasm`
|
|
297
|
+
by default, with a system Emscripten fallback only if the embedded toolchain
|
|
298
|
+
cannot load.
|
|
227
299
|
|
|
228
300
|
## License
|
|
229
301
|
|
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "space-data-module-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
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",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/DigitalArsenal/space-data-module-sdk.git"
|
|
10
|
+
},
|
|
7
11
|
"bin": {
|
|
8
12
|
"space-data-module": "./bin/space-data-module.js"
|
|
9
13
|
},
|
|
@@ -15,6 +19,7 @@
|
|
|
15
19
|
"./transport": "./src/transport/index.js",
|
|
16
20
|
"./compiler": "./src/compiler/index.js",
|
|
17
21
|
"./bundle": "./src/bundle/index.js",
|
|
22
|
+
"./invoke": "./src/invoke/index.js",
|
|
18
23
|
"./standards": "./src/standards/index.js",
|
|
19
24
|
"./schemas/*": "./schemas/*"
|
|
20
25
|
},
|
|
@@ -31,13 +36,15 @@
|
|
|
31
36
|
"prepublishOnly": "npm test && npm run check:compliance"
|
|
32
37
|
},
|
|
33
38
|
"dependencies": {
|
|
34
|
-
"
|
|
39
|
+
"flatc-wasm": "25.12.19-wasm.43",
|
|
35
40
|
"flatbuffers": "^25.9.23",
|
|
36
41
|
"hd-wallet-wasm": "1.6.0",
|
|
42
|
+
"sdn-emception": "1.0.0",
|
|
37
43
|
"spacedatastandards.org": "23.3.3-0.3.4"
|
|
38
44
|
},
|
|
39
45
|
"devDependencies": {
|
|
40
|
-
"express": "^4.21.2"
|
|
46
|
+
"express": "^4.21.2",
|
|
47
|
+
"flatsql": "^0.4.0"
|
|
41
48
|
},
|
|
42
49
|
"engines": {
|
|
43
50
|
"node": ">=20.0.0"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
include "TypedArenaBuffer.fbs";
|
|
2
|
+
|
|
3
|
+
namespace orbpro.invoke;
|
|
4
|
+
|
|
5
|
+
/// Canonical invoke envelope consumed by direct ABI and command-mode execution.
|
|
6
|
+
table PluginInvokeRequest {
|
|
7
|
+
/// Stable method identifier from PluginManifest.methods.
|
|
8
|
+
method_id: string (required);
|
|
9
|
+
|
|
10
|
+
/// Input frames for the invocation, routed by TypedArenaBuffer.port_id.
|
|
11
|
+
input_frames: [orbpro.stream.TypedArenaBuffer];
|
|
12
|
+
|
|
13
|
+
/// Arena backing all input frame payload bytes.
|
|
14
|
+
payload_arena: [ubyte];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
root_type PluginInvokeRequest;
|
|
18
|
+
file_identifier "PINQ";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
include "TypedArenaBuffer.fbs";
|
|
2
|
+
|
|
3
|
+
namespace orbpro.invoke;
|
|
4
|
+
|
|
5
|
+
/// Canonical invoke result emitted by direct ABI and command-mode execution.
|
|
6
|
+
table PluginInvokeResponse {
|
|
7
|
+
/// Method-specific status code. Zero conventionally indicates success.
|
|
8
|
+
status_code: int = 0;
|
|
9
|
+
|
|
10
|
+
/// True when the method yielded before fully draining queued work.
|
|
11
|
+
yielded: bool = false;
|
|
12
|
+
|
|
13
|
+
/// Remaining backlog, if known.
|
|
14
|
+
backlog_remaining: uint32 = 0;
|
|
15
|
+
|
|
16
|
+
/// Output frames produced by the invocation, routed by port_id.
|
|
17
|
+
output_frames: [orbpro.stream.TypedArenaBuffer];
|
|
18
|
+
|
|
19
|
+
/// Arena backing all output frame payload bytes.
|
|
20
|
+
payload_arena: [ubyte];
|
|
21
|
+
|
|
22
|
+
/// Stable machine-readable error code when invocation fails.
|
|
23
|
+
error_code: string;
|
|
24
|
+
|
|
25
|
+
/// Human-readable error message when invocation fails.
|
|
26
|
+
error_message: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
root_type PluginInvokeResponse;
|
|
30
|
+
file_identifier "PINS";
|
|
@@ -68,6 +68,12 @@ enum DrainPolicy : ubyte {
|
|
|
68
68
|
DRAIN_TO_EMPTY = 2
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
+
/// Canonical module invocation surfaces supported by an artifact.
|
|
72
|
+
enum InvokeSurface : ubyte {
|
|
73
|
+
DIRECT = 0,
|
|
74
|
+
COMMAND = 1
|
|
75
|
+
}
|
|
76
|
+
|
|
71
77
|
/// Accepted schema family for a port.
|
|
72
78
|
table AcceptedTypeSet {
|
|
73
79
|
/// Stable type-set identifier.
|
|
@@ -163,6 +169,7 @@ table PluginManifest {
|
|
|
163
169
|
schemas_used: [orbpro.stream.FlatBufferTypeRef];
|
|
164
170
|
build_artifacts: [BuildArtifact];
|
|
165
171
|
abi_version: uint32 = 1;
|
|
172
|
+
invoke_surfaces: [InvokeSurface];
|
|
166
173
|
}
|
|
167
174
|
|
|
168
175
|
root_type PluginManifest;
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
// OrbPro Plugin SDK - Typed Arena Buffer Schema
|
|
2
2
|
//
|
|
3
|
-
// Canonical descriptor for schema-tagged
|
|
3
|
+
// Canonical descriptor for schema-tagged payload frames moving through
|
|
4
4
|
// arena-backed plugin streams.
|
|
5
5
|
|
|
6
6
|
namespace orbpro.stream;
|
|
7
7
|
|
|
8
|
-
///
|
|
8
|
+
/// Logical payload wire format for a stream frame or accepted port type.
|
|
9
|
+
enum PayloadWireFormat : ubyte {
|
|
10
|
+
Flatbuffer = 0,
|
|
11
|
+
AlignedBinary = 1
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/// Payload schema identity for a stream frame or accepted port type.
|
|
9
15
|
table FlatBufferTypeRef {
|
|
10
16
|
/// Logical schema name, for example `OMM.fbs`.
|
|
11
17
|
schema_name: string;
|
|
@@ -18,6 +24,21 @@ table FlatBufferTypeRef {
|
|
|
18
24
|
|
|
19
25
|
/// True when this port/type set accepts any FlatBuffer frame.
|
|
20
26
|
accepts_any_flatbuffer: bool = false;
|
|
27
|
+
|
|
28
|
+
/// Payload wire format. Defaults to regular FlatBuffer framing.
|
|
29
|
+
wire_format: PayloadWireFormat = Flatbuffer;
|
|
30
|
+
|
|
31
|
+
/// Root or layout type name for aligned-binary payloads.
|
|
32
|
+
root_type_name: string;
|
|
33
|
+
|
|
34
|
+
/// Fixed string length for aligned-binary schemas when required.
|
|
35
|
+
fixed_string_length: uint16 = 0;
|
|
36
|
+
|
|
37
|
+
/// Fixed byte length for aligned-binary payloads.
|
|
38
|
+
byte_length: uint32 = 0;
|
|
39
|
+
|
|
40
|
+
/// Required byte alignment for aligned-binary payloads.
|
|
41
|
+
required_alignment: uint16 = 0;
|
|
21
42
|
}
|
|
22
43
|
|
|
23
44
|
/// Ownership mode for an arena-backed frame.
|
package/src/bundle/codec.js
CHANGED
|
@@ -66,6 +66,25 @@ function normalizeString(value, fallback = null) {
|
|
|
66
66
|
return String(value);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function normalizePayloadWireFormat(value) {
|
|
70
|
+
if (value === 1) {
|
|
71
|
+
return "aligned-binary";
|
|
72
|
+
}
|
|
73
|
+
const normalized = String(value ?? "")
|
|
74
|
+
.trim()
|
|
75
|
+
.toLowerCase()
|
|
76
|
+
.replace(/_/g, "-");
|
|
77
|
+
return normalized === "aligned-binary" ? "aligned-binary" : "flatbuffer";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function normalizeUnsignedInteger(value, fallback = 0) {
|
|
81
|
+
const normalized = Number(value ?? fallback);
|
|
82
|
+
if (!Number.isFinite(normalized)) {
|
|
83
|
+
return fallback;
|
|
84
|
+
}
|
|
85
|
+
return Math.max(0, Math.trunc(normalized));
|
|
86
|
+
}
|
|
87
|
+
|
|
69
88
|
function normalizeByteArray(value, { encoding = null } = {}) {
|
|
70
89
|
if (value === undefined || value === null) {
|
|
71
90
|
return [];
|
|
@@ -124,6 +143,11 @@ function normalizeTypeRef(value) {
|
|
|
124
143
|
normalizeString(value.fileIdentifier),
|
|
125
144
|
normalizeByteArray(value.schemaHash),
|
|
126
145
|
Boolean(value.acceptsAnyFlatbuffer),
|
|
146
|
+
normalizePayloadWireFormat(value.wireFormat),
|
|
147
|
+
normalizeString(value.rootTypeName),
|
|
148
|
+
normalizeUnsignedInteger(value.fixedStringLength),
|
|
149
|
+
normalizeUnsignedInteger(value.byteLength),
|
|
150
|
+
normalizeUnsignedInteger(value.requiredAlignment),
|
|
127
151
|
);
|
|
128
152
|
}
|
|
129
153
|
|