space-data-module-sdk 0.1.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/LICENSE +190 -0
- package/README.md +236 -73
- package/bin/space-data-module.js +24 -0
- package/package.json +16 -4
- package/schemas/ModuleBundle.fbs +108 -0
- package/schemas/PluginInvokeRequest.fbs +18 -0
- package/schemas/PluginInvokeResponse.fbs +30 -0
- package/schemas/PluginManifest.fbs +33 -1
- package/schemas/TypedArenaBuffer.fbs +23 -2
- package/src/bundle/codec.js +268 -0
- package/src/bundle/constants.js +8 -0
- package/src/bundle/index.js +3 -0
- package/src/bundle/wasm.js +447 -0
- package/src/compiler/compileModule.js +353 -37
- 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 +575 -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 +26 -1
- package/src/generated/orbpro/manifest/capability-kind.d.ts.map +1 -1
- package/src/generated/orbpro/manifest/capability-kind.js +25 -0
- package/src/generated/orbpro/manifest/capability-kind.js.map +1 -1
- package/src/generated/orbpro/manifest/capability-kind.ts +25 -0
- 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/module/canonicalization-rule.d.ts +48 -0
- package/src/generated/orbpro/module/canonicalization-rule.js +95 -0
- package/src/generated/orbpro/module/canonicalization-rule.ts +142 -0
- package/src/generated/orbpro/module/module-bundle-entry-role.d.ts +11 -0
- package/src/generated/orbpro/module/module-bundle-entry-role.js +14 -0
- package/src/generated/orbpro/module/module-bundle-entry-role.ts +15 -0
- package/src/generated/orbpro/module/module-bundle-entry.d.ts +97 -0
- package/src/generated/orbpro/module/module-bundle-entry.js +219 -0
- package/src/generated/orbpro/module/module-bundle-entry.ts +287 -0
- package/src/generated/orbpro/module/module-bundle.d.ts +86 -0
- package/src/generated/orbpro/module/module-bundle.js +213 -0
- package/src/generated/orbpro/module/module-bundle.ts +277 -0
- package/src/generated/orbpro/module/module-payload-encoding.d.ts +9 -0
- package/src/generated/orbpro/module/module-payload-encoding.js +12 -0
- package/src/generated/orbpro/module/module-payload-encoding.ts +13 -0
- package/src/generated/orbpro/module.d.ts +5 -0
- package/src/generated/orbpro/module.js +7 -0
- package/src/generated/orbpro/module.ts +9 -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/host/abi.js +282 -0
- package/src/host/cron.js +247 -0
- package/src/host/index.js +3 -0
- package/src/host/nodeHost.js +2165 -0
- package/src/index.d.ts +958 -0
- package/src/index.js +12 -2
- 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 +90 -1
- package/src/runtime/constants.js +29 -0
- package/src/transport/pki.js +0 -5
- package/src/utils/encoding.js +9 -1
- package/src/utils/wasmCrypto.js +49 -1
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "space-data-module-sdk",
|
|
3
|
-
"version": "0.
|
|
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
|
+
"types": "./src/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/DigitalArsenal/space-data-module-sdk.git"
|
|
10
|
+
},
|
|
6
11
|
"bin": {
|
|
7
12
|
"space-data-module": "./bin/space-data-module.js"
|
|
8
13
|
},
|
|
@@ -13,6 +18,8 @@
|
|
|
13
18
|
"./auth": "./src/auth/index.js",
|
|
14
19
|
"./transport": "./src/transport/index.js",
|
|
15
20
|
"./compiler": "./src/compiler/index.js",
|
|
21
|
+
"./bundle": "./src/bundle/index.js",
|
|
22
|
+
"./invoke": "./src/invoke/index.js",
|
|
16
23
|
"./standards": "./src/standards/index.js",
|
|
17
24
|
"./schemas/*": "./schemas/*"
|
|
18
25
|
},
|
|
@@ -24,15 +31,20 @@
|
|
|
24
31
|
"scripts": {
|
|
25
32
|
"test": "node --test",
|
|
26
33
|
"start:lab": "node ./lab/server.js",
|
|
27
|
-
"check:compliance": "node ./bin/space-data-module.js check --repo-root ."
|
|
34
|
+
"check:compliance": "node ./bin/space-data-module.js check --repo-root .",
|
|
35
|
+
"generate:vectors": "node ./examples/single-file-bundle/generate-vectors.mjs",
|
|
36
|
+
"prepublishOnly": "npm test && npm run check:compliance"
|
|
28
37
|
},
|
|
29
38
|
"dependencies": {
|
|
39
|
+
"flatc-wasm": "25.12.19-wasm.43",
|
|
30
40
|
"flatbuffers": "^25.9.23",
|
|
31
|
-
"hd-wallet-wasm": "
|
|
41
|
+
"hd-wallet-wasm": "1.6.0",
|
|
42
|
+
"sdn-emception": "1.0.0",
|
|
32
43
|
"spacedatastandards.org": "23.3.3-0.3.4"
|
|
33
44
|
},
|
|
34
45
|
"devDependencies": {
|
|
35
|
-
"express": "^4.21.2"
|
|
46
|
+
"express": "^4.21.2",
|
|
47
|
+
"flatsql": "^0.4.0"
|
|
36
48
|
},
|
|
37
49
|
"engines": {
|
|
38
50
|
"node": ">=20.0.0"
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Space Data Module SDK - Single-file Module Bundle Schema
|
|
2
|
+
//
|
|
3
|
+
// Draft schema for packaging a loadable WebAssembly module together with
|
|
4
|
+
// SDS-typed metadata inside one `sds.bundle` custom section.
|
|
5
|
+
|
|
6
|
+
include "TypedArenaBuffer.fbs";
|
|
7
|
+
|
|
8
|
+
namespace orbpro.module;
|
|
9
|
+
|
|
10
|
+
/// Logical role for one payload carried in the bundle.
|
|
11
|
+
enum ModuleBundleEntryRole : ubyte {
|
|
12
|
+
MANIFEST = 0,
|
|
13
|
+
AUTHORIZATION = 1,
|
|
14
|
+
SIGNATURE = 2,
|
|
15
|
+
TRANSPORT = 3,
|
|
16
|
+
ATTESTATION = 4,
|
|
17
|
+
AUXILIARY = 5
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/// Serialization format used by an entry payload.
|
|
21
|
+
enum ModulePayloadEncoding : ubyte {
|
|
22
|
+
RAW_BYTES = 0,
|
|
23
|
+
FLATBUFFER = 1,
|
|
24
|
+
JSON_UTF8 = 2,
|
|
25
|
+
CBOR = 3
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/// Canonicalization rule applied before hashing or signature verification.
|
|
29
|
+
table CanonicalizationRule {
|
|
30
|
+
/// Schema version for the canonicalization contract.
|
|
31
|
+
version: uint16 = 1;
|
|
32
|
+
|
|
33
|
+
/// Strip any custom section whose name starts with this prefix before
|
|
34
|
+
/// hashing the module for signature verification.
|
|
35
|
+
stripped_custom_section_prefix: string;
|
|
36
|
+
|
|
37
|
+
/// Name of the required root custom section carrying this bundle.
|
|
38
|
+
bundle_section_name: string;
|
|
39
|
+
|
|
40
|
+
/// Hash function identifier, for example `sha256`.
|
|
41
|
+
hash_algorithm: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// One payload carried inside the bundle.
|
|
45
|
+
table ModuleBundleEntry {
|
|
46
|
+
/// Stable bundle-local identifier.
|
|
47
|
+
entry_id: string (required, key);
|
|
48
|
+
|
|
49
|
+
/// High-level semantic role of the payload.
|
|
50
|
+
role: ModuleBundleEntryRole = AUXILIARY;
|
|
51
|
+
|
|
52
|
+
/// Optional logical section name within the bundle, for example
|
|
53
|
+
/// `sds.authorization`.
|
|
54
|
+
section_name: string;
|
|
55
|
+
|
|
56
|
+
/// SDS/shared-module schema identity when the payload is itself a
|
|
57
|
+
/// FlatBuffer.
|
|
58
|
+
type_ref: orbpro.stream.FlatBufferTypeRef;
|
|
59
|
+
|
|
60
|
+
/// Encoding used for `payload`.
|
|
61
|
+
payload_encoding: ModulePayloadEncoding = RAW_BYTES;
|
|
62
|
+
|
|
63
|
+
/// Optional media type for transitional payloads such as JSON envelopes.
|
|
64
|
+
media_type: string;
|
|
65
|
+
|
|
66
|
+
/// Implementation-defined bit flags for signed/encrypted/compressed state.
|
|
67
|
+
flags: uint32 = 0;
|
|
68
|
+
|
|
69
|
+
/// SHA-256 of the payload bytes.
|
|
70
|
+
sha256: [ubyte];
|
|
71
|
+
|
|
72
|
+
/// Embedded payload bytes. For single-file deployment this should be
|
|
73
|
+
/// populated for every entry.
|
|
74
|
+
payload: [ubyte];
|
|
75
|
+
|
|
76
|
+
/// Human-readable description for tooling and diagnostics.
|
|
77
|
+
description: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/// Metadata stored in the required `sds.bundle` custom section.
|
|
81
|
+
table ModuleBundle {
|
|
82
|
+
/// Bundle schema version.
|
|
83
|
+
bundle_version: uint16 = 1;
|
|
84
|
+
|
|
85
|
+
/// Human-readable package format label.
|
|
86
|
+
module_format: string;
|
|
87
|
+
|
|
88
|
+
/// Canonicalization rule used to compute module hashes.
|
|
89
|
+
canonicalization: CanonicalizationRule;
|
|
90
|
+
|
|
91
|
+
/// SHA-256 of the wasm module after stripping `sds.*` custom sections.
|
|
92
|
+
canonical_module_hash: [ubyte];
|
|
93
|
+
|
|
94
|
+
/// SHA-256 of the canonical plugin manifest bytes.
|
|
95
|
+
manifest_hash: [ubyte];
|
|
96
|
+
|
|
97
|
+
/// Legacy ABI export retained for backward compatibility.
|
|
98
|
+
manifest_export_symbol: string;
|
|
99
|
+
|
|
100
|
+
/// Legacy ABI export retained for backward compatibility.
|
|
101
|
+
manifest_size_symbol: string;
|
|
102
|
+
|
|
103
|
+
/// Payloads embedded in the bundle.
|
|
104
|
+
entries: [ModuleBundleEntry];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
root_type ModuleBundle;
|
|
108
|
+
file_identifier "SMDB";
|
|
@@ -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";
|
|
@@ -33,7 +33,32 @@ enum CapabilityKind : ushort {
|
|
|
33
33
|
STORAGE_QUERY = 7,
|
|
34
34
|
SCENE_ACCESS = 8,
|
|
35
35
|
ENTITY_ACCESS = 9,
|
|
36
|
-
RENDER_HOOKS = 10
|
|
36
|
+
RENDER_HOOKS = 10,
|
|
37
|
+
HTTP = 11,
|
|
38
|
+
FILESYSTEM = 12,
|
|
39
|
+
PIPE = 13,
|
|
40
|
+
NETWORK = 14,
|
|
41
|
+
DATABASE = 15,
|
|
42
|
+
STORAGE_ADAPTER = 16,
|
|
43
|
+
STORAGE_WRITE = 17,
|
|
44
|
+
WALLET_SIGN = 18,
|
|
45
|
+
IPFS = 19,
|
|
46
|
+
TLS = 20,
|
|
47
|
+
MQTT = 21,
|
|
48
|
+
WEBSOCKET = 22,
|
|
49
|
+
TCP = 23,
|
|
50
|
+
UDP = 24,
|
|
51
|
+
PROCESS_EXEC = 25,
|
|
52
|
+
CONTEXT_READ = 26,
|
|
53
|
+
CONTEXT_WRITE = 27,
|
|
54
|
+
CRYPTO_HASH = 28,
|
|
55
|
+
CRYPTO_SIGN = 29,
|
|
56
|
+
CRYPTO_VERIFY = 30,
|
|
57
|
+
CRYPTO_ENCRYPT = 31,
|
|
58
|
+
CRYPTO_DECRYPT = 32,
|
|
59
|
+
CRYPTO_KEY_AGREEMENT = 33,
|
|
60
|
+
CRYPTO_KDF = 34,
|
|
61
|
+
SCHEDULE_CRON = 35
|
|
37
62
|
}
|
|
38
63
|
|
|
39
64
|
/// Drain policy for methods that operate over queued stream frames.
|
|
@@ -43,6 +68,12 @@ enum DrainPolicy : ubyte {
|
|
|
43
68
|
DRAIN_TO_EMPTY = 2
|
|
44
69
|
}
|
|
45
70
|
|
|
71
|
+
/// Canonical module invocation surfaces supported by an artifact.
|
|
72
|
+
enum InvokeSurface : ubyte {
|
|
73
|
+
DIRECT = 0,
|
|
74
|
+
COMMAND = 1
|
|
75
|
+
}
|
|
76
|
+
|
|
46
77
|
/// Accepted schema family for a port.
|
|
47
78
|
table AcceptedTypeSet {
|
|
48
79
|
/// Stable type-set identifier.
|
|
@@ -138,6 +169,7 @@ table PluginManifest {
|
|
|
138
169
|
schemas_used: [orbpro.stream.FlatBufferTypeRef];
|
|
139
170
|
build_artifacts: [BuildArtifact];
|
|
140
171
|
abi_version: uint32 = 1;
|
|
172
|
+
invoke_surfaces: [InvokeSurface];
|
|
141
173
|
}
|
|
142
174
|
|
|
143
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.
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import * as flatbuffers from "flatbuffers";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
CanonicalizationRuleT,
|
|
5
|
+
ModuleBundle,
|
|
6
|
+
ModuleBundleEntryRole,
|
|
7
|
+
ModuleBundleEntryT,
|
|
8
|
+
ModuleBundleT,
|
|
9
|
+
ModulePayloadEncoding,
|
|
10
|
+
} from "../generated/orbpro/module.js";
|
|
11
|
+
import { FlatBufferTypeRefT } from "../generated/orbpro/stream/flat-buffer-type-ref.js";
|
|
12
|
+
import { canonicalBytes } from "../auth/canonicalize.js";
|
|
13
|
+
import { toUint8Array as toBufferLikeUint8Array } from "../runtime/bufferLike.js";
|
|
14
|
+
import {
|
|
15
|
+
DEFAULT_HASH_ALGORITHM,
|
|
16
|
+
DEFAULT_MANIFEST_EXPORT_SYMBOL,
|
|
17
|
+
DEFAULT_MANIFEST_SIZE_SYMBOL,
|
|
18
|
+
DEFAULT_MODULE_FORMAT,
|
|
19
|
+
SDS_BUNDLE_SECTION_NAME,
|
|
20
|
+
SDS_CUSTOM_SECTION_PREFIX,
|
|
21
|
+
} from "./constants.js";
|
|
22
|
+
|
|
23
|
+
const textEncoder = new TextEncoder();
|
|
24
|
+
|
|
25
|
+
const ROLE_NAME_TO_ENUM = new Map([
|
|
26
|
+
["manifest", ModuleBundleEntryRole.MANIFEST],
|
|
27
|
+
["authorization", ModuleBundleEntryRole.AUTHORIZATION],
|
|
28
|
+
["signature", ModuleBundleEntryRole.SIGNATURE],
|
|
29
|
+
["transport", ModuleBundleEntryRole.TRANSPORT],
|
|
30
|
+
["attestation", ModuleBundleEntryRole.ATTESTATION],
|
|
31
|
+
["auxiliary", ModuleBundleEntryRole.AUXILIARY],
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
const ROLE_ENUM_TO_NAME = new Map(
|
|
35
|
+
Array.from(ROLE_NAME_TO_ENUM, ([name, value]) => [value, name]),
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const ENCODING_NAME_TO_ENUM = new Map([
|
|
39
|
+
["raw-bytes", ModulePayloadEncoding.RAW_BYTES],
|
|
40
|
+
["flatbuffer", ModulePayloadEncoding.FLATBUFFER],
|
|
41
|
+
["json-utf8", ModulePayloadEncoding.JSON_UTF8],
|
|
42
|
+
["cbor", ModulePayloadEncoding.CBOR],
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
const ENCODING_ENUM_TO_NAME = new Map(
|
|
46
|
+
Array.from(ENCODING_NAME_TO_ENUM, ([name, value]) => [value, name]),
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
function toByteBuffer(data) {
|
|
50
|
+
if (data instanceof flatbuffers.ByteBuffer) {
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
const bytes = toBufferLikeUint8Array(data);
|
|
54
|
+
if (bytes) {
|
|
55
|
+
return new flatbuffers.ByteBuffer(bytes);
|
|
56
|
+
}
|
|
57
|
+
throw new TypeError(
|
|
58
|
+
"Expected ByteBuffer, Uint8Array, ArrayBufferView, or ArrayBuffer.",
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function normalizeString(value, fallback = null) {
|
|
63
|
+
if (value === undefined || value === null) {
|
|
64
|
+
return fallback;
|
|
65
|
+
}
|
|
66
|
+
return String(value);
|
|
67
|
+
}
|
|
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
|
+
|
|
88
|
+
function normalizeByteArray(value, { encoding = null } = {}) {
|
|
89
|
+
if (value === undefined || value === null) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
if (Array.isArray(value)) {
|
|
93
|
+
return value.map((byte) => Number(byte) & 0xff);
|
|
94
|
+
}
|
|
95
|
+
const bytes = toBufferLikeUint8Array(value);
|
|
96
|
+
if (bytes) {
|
|
97
|
+
return Array.from(bytes);
|
|
98
|
+
}
|
|
99
|
+
if (typeof value === "string") {
|
|
100
|
+
return Array.from(textEncoder.encode(value));
|
|
101
|
+
}
|
|
102
|
+
if (encoding === ModulePayloadEncoding.JSON_UTF8) {
|
|
103
|
+
return Array.from(canonicalBytes(value));
|
|
104
|
+
}
|
|
105
|
+
throw new TypeError(
|
|
106
|
+
"Expected payload bytes, ArrayBufferView, ArrayBuffer, string, or JSON value.",
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function normalizeRole(value) {
|
|
111
|
+
if (typeof value === "number") {
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
const normalized = String(value ?? "auxiliary")
|
|
115
|
+
.trim()
|
|
116
|
+
.toLowerCase()
|
|
117
|
+
.replace(/_/g, "-");
|
|
118
|
+
return ROLE_NAME_TO_ENUM.get(normalized) ?? ModuleBundleEntryRole.AUXILIARY;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function normalizePayloadEncoding(value) {
|
|
122
|
+
if (typeof value === "number") {
|
|
123
|
+
return value;
|
|
124
|
+
}
|
|
125
|
+
const normalized = String(value ?? "raw-bytes")
|
|
126
|
+
.trim()
|
|
127
|
+
.toLowerCase()
|
|
128
|
+
.replace(/_/g, "-");
|
|
129
|
+
return (
|
|
130
|
+
ENCODING_NAME_TO_ENUM.get(normalized) ?? ModulePayloadEncoding.RAW_BYTES
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function normalizeTypeRef(value) {
|
|
135
|
+
if (!value) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
if (value instanceof FlatBufferTypeRefT) {
|
|
139
|
+
return value;
|
|
140
|
+
}
|
|
141
|
+
return new FlatBufferTypeRefT(
|
|
142
|
+
normalizeString(value.schemaName),
|
|
143
|
+
normalizeString(value.fileIdentifier),
|
|
144
|
+
normalizeByteArray(value.schemaHash),
|
|
145
|
+
Boolean(value.acceptsAnyFlatbuffer),
|
|
146
|
+
normalizePayloadWireFormat(value.wireFormat),
|
|
147
|
+
normalizeString(value.rootTypeName),
|
|
148
|
+
normalizeUnsignedInteger(value.fixedStringLength),
|
|
149
|
+
normalizeUnsignedInteger(value.byteLength),
|
|
150
|
+
normalizeUnsignedInteger(value.requiredAlignment),
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function normalizeCanonicalization(value = {}) {
|
|
155
|
+
if (value instanceof CanonicalizationRuleT) {
|
|
156
|
+
return value;
|
|
157
|
+
}
|
|
158
|
+
return new CanonicalizationRuleT(
|
|
159
|
+
Number(value.version ?? 1),
|
|
160
|
+
normalizeString(
|
|
161
|
+
value.strippedCustomSectionPrefix,
|
|
162
|
+
SDS_CUSTOM_SECTION_PREFIX,
|
|
163
|
+
),
|
|
164
|
+
normalizeString(value.bundleSectionName, SDS_BUNDLE_SECTION_NAME),
|
|
165
|
+
normalizeString(value.hashAlgorithm, DEFAULT_HASH_ALGORITHM),
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function normalizeEntry(value = {}) {
|
|
170
|
+
if (value instanceof ModuleBundleEntryT) {
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
const payloadEncoding = normalizePayloadEncoding(value.payloadEncoding);
|
|
174
|
+
return new ModuleBundleEntryT(
|
|
175
|
+
normalizeString(value.entryId),
|
|
176
|
+
normalizeRole(value.role),
|
|
177
|
+
normalizeString(value.sectionName),
|
|
178
|
+
normalizeTypeRef(value.typeRef),
|
|
179
|
+
payloadEncoding,
|
|
180
|
+
normalizeString(value.mediaType),
|
|
181
|
+
Number(value.flags ?? 0),
|
|
182
|
+
normalizeByteArray(value.sha256),
|
|
183
|
+
normalizeByteArray(value.payload, { encoding: payloadEncoding }),
|
|
184
|
+
normalizeString(value.description),
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function decodeModuleBundle(data) {
|
|
189
|
+
const bb = toByteBuffer(data);
|
|
190
|
+
if (!ModuleBundle.bufferHasIdentifier(bb)) {
|
|
191
|
+
throw new Error("Module bundle buffer identifier mismatch.");
|
|
192
|
+
}
|
|
193
|
+
return ModuleBundle.getRootAsModuleBundle(bb).unpack();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function encodeModuleBundle(bundle) {
|
|
197
|
+
const value =
|
|
198
|
+
bundle instanceof ModuleBundleT
|
|
199
|
+
? bundle
|
|
200
|
+
: new ModuleBundleT(
|
|
201
|
+
Number(bundle?.bundleVersion ?? 1),
|
|
202
|
+
normalizeString(bundle?.moduleFormat, DEFAULT_MODULE_FORMAT),
|
|
203
|
+
normalizeCanonicalization(bundle?.canonicalization),
|
|
204
|
+
normalizeByteArray(bundle?.canonicalModuleHash),
|
|
205
|
+
normalizeByteArray(bundle?.manifestHash),
|
|
206
|
+
normalizeString(
|
|
207
|
+
bundle?.manifestExportSymbol,
|
|
208
|
+
DEFAULT_MANIFEST_EXPORT_SYMBOL,
|
|
209
|
+
),
|
|
210
|
+
normalizeString(
|
|
211
|
+
bundle?.manifestSizeSymbol,
|
|
212
|
+
DEFAULT_MANIFEST_SIZE_SYMBOL,
|
|
213
|
+
),
|
|
214
|
+
Array.isArray(bundle?.entries)
|
|
215
|
+
? bundle.entries.map(normalizeEntry)
|
|
216
|
+
: [],
|
|
217
|
+
);
|
|
218
|
+
const builder = new flatbuffers.Builder(1024);
|
|
219
|
+
ModuleBundle.finishModuleBundleBuffer(builder, value.pack(builder));
|
|
220
|
+
return builder.asUint8Array();
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function moduleBundleRoleToName(value) {
|
|
224
|
+
return ROLE_ENUM_TO_NAME.get(value) ?? "auxiliary";
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export function moduleBundleEncodingToName(value) {
|
|
228
|
+
return ENCODING_ENUM_TO_NAME.get(value) ?? "raw-bytes";
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export function decodeModuleBundleEntryPayload(entry) {
|
|
232
|
+
const payloadEncoding = normalizePayloadEncoding(entry?.payloadEncoding);
|
|
233
|
+
const payloadBytes = new Uint8Array(
|
|
234
|
+
normalizeByteArray(entry?.payload, { encoding: payloadEncoding }),
|
|
235
|
+
);
|
|
236
|
+
if (payloadEncoding === ModulePayloadEncoding.JSON_UTF8) {
|
|
237
|
+
return JSON.parse(new TextDecoder().decode(payloadBytes));
|
|
238
|
+
}
|
|
239
|
+
return payloadBytes;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function findModuleBundleEntry(bundle, match) {
|
|
243
|
+
const entries = Array.isArray(bundle?.entries) ? bundle.entries : [];
|
|
244
|
+
if (typeof match === "number") {
|
|
245
|
+
return entries.find((entry) => entry.role === match) ?? null;
|
|
246
|
+
}
|
|
247
|
+
const normalized = String(match ?? "")
|
|
248
|
+
.trim()
|
|
249
|
+
.toLowerCase()
|
|
250
|
+
.replace(/_/g, "-");
|
|
251
|
+
return (
|
|
252
|
+
entries.find((entry) => entry.entryId === match) ??
|
|
253
|
+
entries.find(
|
|
254
|
+
(entry) => moduleBundleRoleToName(normalizeRole(entry.role)) === normalized,
|
|
255
|
+
) ??
|
|
256
|
+
null
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export {
|
|
261
|
+
CanonicalizationRuleT,
|
|
262
|
+
FlatBufferTypeRefT,
|
|
263
|
+
ModuleBundle,
|
|
264
|
+
ModuleBundleEntryRole,
|
|
265
|
+
ModuleBundleEntryT,
|
|
266
|
+
ModuleBundleT,
|
|
267
|
+
ModulePayloadEncoding,
|
|
268
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const SDS_CUSTOM_SECTION_PREFIX = "sds.";
|
|
2
|
+
export const SDS_BUNDLE_SECTION_NAME = "sds.bundle";
|
|
3
|
+
export const DEFAULT_MODULE_FORMAT = "space-data-module";
|
|
4
|
+
export const DEFAULT_HASH_ALGORITHM = "sha256";
|
|
5
|
+
export const DEFAULT_MANIFEST_EXPORT_SYMBOL = "plugin_get_manifest_flatbuffer";
|
|
6
|
+
export const DEFAULT_MANIFEST_SIZE_SYMBOL =
|
|
7
|
+
"plugin_get_manifest_flatbuffer_size";
|
|
8
|
+
|