space-data-module-sdk 0.7.0 → 0.8.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/README.md +16 -23
- package/bin/space-data-module.js +5 -3
- package/package.json +2 -2
- package/schemas/spacedatastandards/PLG.fbs +191 -0
- package/src/AGENTS.md +1 -1
- package/src/bundle/AGENTS.md +6 -5
- package/src/bundle/codec.js +163 -48
- package/src/bundle/constants.js +1 -1
- package/src/bundle/wasm.js +53 -32
- package/src/compiler/compileModule.js +9 -1
- package/src/compliance/index.js +4 -0
- package/src/compliance/pluginCompliance.js +158 -2
- package/src/embeddedManifest.js +25 -5
- package/src/generated/orbpro/invoke/plugin-invoke-request.js +2 -2
- package/src/generated/orbpro/invoke/plugin-invoke-response.js +2 -2
- package/src/generated/orbpro/stream/flat-buffer-type-ref.js +2 -2
- package/src/generated/orbpro/stream/typed-arena-buffer.js +2 -2
- package/src/generated/spacedatastandards/plg/entry-function.js +86 -0
- package/src/generated/spacedatastandards/plg/entry-function.ts +119 -0
- package/src/generated/spacedatastandards/plg/index.js +16 -0
- package/src/generated/spacedatastandards/plg/index.ts +11 -0
- package/src/generated/spacedatastandards/plg/plg.js +657 -0
- package/src/generated/spacedatastandards/plg/plg.ts +924 -0
- package/src/generated/spacedatastandards/plg/plugin-capability.js +66 -0
- package/src/generated/spacedatastandards/plg/plugin-capability.ts +84 -0
- package/src/generated/spacedatastandards/plg/plugin-category.js +15 -0
- package/src/generated/spacedatastandards/plg/plugin-category.ts +53 -0
- package/src/generated/spacedatastandards/plg/plugin-dependency.js +63 -0
- package/src/generated/spacedatastandards/plg/plugin-dependency.ts +86 -0
- package/src/generated/spacedatastandards/plg/publication-state.js +9 -0
- package/src/generated/spacedatastandards/plg/publication-state.ts +23 -0
- package/src/generated/spacedatastandards/plg/purchase-tier.js +9 -0
- package/src/generated/spacedatastandards/plg/purchase-tier.ts +23 -0
- package/src/index.d.ts +1 -1
- package/src/invoke/codec.js +1 -1
- package/src/manifest/browser.js +7 -0
- package/src/manifest/index.js +7 -0
- package/src/manifest/legacyToPlg.js +249 -0
- package/src/manifest/plgCodec.js +826 -0
- package/src/standards/sharedCatalog.js +132 -0
- package/src/transport/records.js +34 -3
- package/src/vendor/flatbuffers/LICENSE +202 -0
- package/src/vendor/flatbuffers/builder.js +534 -0
- package/src/vendor/flatbuffers/byte-buffer.js +253 -0
- package/src/vendor/flatbuffers/constants.js +4 -0
- package/src/vendor/flatbuffers/encoding.js +5 -0
- package/src/vendor/flatbuffers/flatbuffers.js +5 -0
- package/src/vendor/flatbuffers/utils.js +4 -0
- package/schemas/ModuleBundle.fbs +0 -108
- package/src/generated/orbpro/module/canonicalization-rule.d.ts +0 -48
- package/src/generated/orbpro/module/canonicalization-rule.js +0 -95
- package/src/generated/orbpro/module/canonicalization-rule.ts +0 -142
- package/src/generated/orbpro/module/module-bundle-entry-role.d.ts +0 -11
- package/src/generated/orbpro/module/module-bundle-entry-role.js +0 -14
- package/src/generated/orbpro/module/module-bundle-entry-role.ts +0 -15
- package/src/generated/orbpro/module/module-bundle-entry.d.ts +0 -97
- package/src/generated/orbpro/module/module-bundle-entry.js +0 -219
- package/src/generated/orbpro/module/module-bundle-entry.ts +0 -287
- package/src/generated/orbpro/module/module-bundle.d.ts +0 -86
- package/src/generated/orbpro/module/module-bundle.js +0 -213
- package/src/generated/orbpro/module/module-bundle.ts +0 -277
- package/src/generated/orbpro/module/module-payload-encoding.d.ts +0 -9
- package/src/generated/orbpro/module/module-payload-encoding.js +0 -12
- package/src/generated/orbpro/module/module-payload-encoding.ts +0 -13
- package/src/generated/orbpro/module.d.ts +0 -5
- package/src/generated/orbpro/module.js +0 -7
- package/src/generated/orbpro/module.ts +0 -9
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ This repository is the source of truth for module-level concerns:
|
|
|
11
11
|
- embedded manifest exports inside `.wasm` modules
|
|
12
12
|
- standards-aware compliance and capability validation
|
|
13
13
|
- module compilation and protection
|
|
14
|
-
- the
|
|
14
|
+
- the REC+MBL single-file container
|
|
15
15
|
- deployment authorization plus SDS publication records (`REC`, `PNM`, `ENC`)
|
|
16
16
|
- the first canonical module hostcall/import ABI surface
|
|
17
17
|
- the canonical runtime-host model for append-only standards rows, host-managed
|
|
@@ -80,20 +80,21 @@ A compliant module built with this SDK is always a valid `.wasm` artifact with:
|
|
|
80
80
|
- `plugin_alloc`
|
|
81
81
|
- `plugin_free`
|
|
82
82
|
- an exported `_start` entry when the artifact supports WASI command mode
|
|
83
|
-
- optional `
|
|
83
|
+
- optional `MBL` bundle metadata carried in one appended SDS `REC` trailer for:
|
|
84
84
|
- manifest bytes
|
|
85
85
|
- resolved deployment plans and input bindings
|
|
86
86
|
- deployment authorization
|
|
87
87
|
- auxiliary FlatBuffer or raw payloads
|
|
88
|
-
- optional appended SDS FlatBuffer publication records in
|
|
89
|
-
container carrying:
|
|
88
|
+
- optional appended SDS FlatBuffer publication records in that same trailing
|
|
89
|
+
`REC` container carrying:
|
|
90
|
+
- `MBL` single-file bundle metadata
|
|
90
91
|
- `PNM` digital-signature/publication metadata
|
|
91
92
|
- `ENC` encrypted-delivery metadata
|
|
92
93
|
|
|
93
|
-
Single-file bundling
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
Single-file bundling appends one SDS `REC` trailer to the end of the wasm
|
|
95
|
+
payload. That trailer carries an `MBL` record for the bundle contents and may
|
|
96
|
+
also carry `PNM` / `ENC` publication metadata when the artifact is signed or
|
|
97
|
+
encrypted.
|
|
97
98
|
|
|
98
99
|
The module contract stays the same whether the artifact is loaded directly,
|
|
99
100
|
wrapped in a deployment envelope, or shipped as one bundled `.wasm` file.
|
|
@@ -171,11 +172,8 @@ This repo currently includes:
|
|
|
171
172
|
|
|
172
173
|
- the JavaScript reference implementation for manifest, compliance, auth,
|
|
173
174
|
transport, bundle handling, and compilation
|
|
174
|
-
- deterministic
|
|
175
|
+
- deterministic REC+MBL conformance vectors under
|
|
175
176
|
[`examples/single-file-bundle/vectors`](./examples/single-file-bundle/vectors)
|
|
176
|
-
- non-JS bundle reference clients in
|
|
177
|
-
[`examples/single-file-bundle/go`](./examples/single-file-bundle/go) and
|
|
178
|
-
[`examples/single-file-bundle/python`](./examples/single-file-bundle/python)
|
|
179
177
|
- reference Node and browser hosts plus the legacy sync `sdn_host` bridge for
|
|
180
178
|
sync-safe guest hostcalls
|
|
181
179
|
|
|
@@ -385,20 +383,18 @@ This repo exposes that deployment surface from
|
|
|
385
383
|
|
|
386
384
|
- validate resolved protocol installations
|
|
387
385
|
- describe input and publication bindings by declared `interfaceId`
|
|
388
|
-
- attach a deployment plan to
|
|
386
|
+
- attach a deployment plan to the bundle `MBL` record
|
|
389
387
|
|
|
390
388
|
The full contract split is documented in
|
|
391
389
|
[`docs/protocol-installation.md`](./docs/protocol-installation.md).
|
|
392
390
|
|
|
393
391
|
## Single-File Bundles
|
|
394
392
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
resolve `PNM` / `ENC`, strip or decrypt as needed, and only then hand the
|
|
401
|
-
remaining raw wasm bytes to a runtime such as WasmEdge.
|
|
393
|
+
REC+MBL keeps module delivery to one file without changing the runtime payload
|
|
394
|
+
itself. The SDK appends one trailing `REC` container after the wasm bytes.
|
|
395
|
+
Loaders must scan from the end, resolve `MBL` / `PNM` / `ENC`, strip or decrypt
|
|
396
|
+
as needed, and only then hand the remaining raw wasm bytes to a runtime such as
|
|
397
|
+
WasmEdge.
|
|
402
398
|
|
|
403
399
|
The reference path lives in
|
|
404
400
|
[`examples/single-file-bundle`](./examples/single-file-bundle):
|
|
@@ -407,8 +403,6 @@ The reference path lives in
|
|
|
407
403
|
bundled module
|
|
408
404
|
- [`generate-vectors.mjs`](./examples/single-file-bundle/generate-vectors.mjs)
|
|
409
405
|
regenerates the checked-in conformance vectors
|
|
410
|
-
- the `go` and `python` directories show non-JS readers against the same
|
|
411
|
-
bundle contract
|
|
412
406
|
|
|
413
407
|
Standard bundle payloads now include the optional `deployment-plan` JSON entry
|
|
414
408
|
for resolved protocol installations and producer input bindings.
|
|
@@ -419,7 +413,6 @@ Digital signature and encrypted-delivery metadata are publication-layer
|
|
|
419
413
|
extensions, not a second module format. The canonical module is still:
|
|
420
414
|
|
|
421
415
|
- valid `.wasm`
|
|
422
|
-
- optionally carrying `sds.bundle` as a wasm custom section
|
|
423
416
|
- optionally carrying one appended SDS `REC` trailer after the wasm bytes
|
|
424
417
|
|
|
425
418
|
That trailing `REC` FlatBuffer is the standards-backed container for
|
package/bin/space-data-module.js
CHANGED
|
@@ -6,13 +6,15 @@ import { readFile, writeFile } from "node:fs/promises";
|
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
8
|
compileModuleFromSource,
|
|
9
|
-
loadComplianceConfig,
|
|
10
9
|
protectModuleArtifact,
|
|
10
|
+
} from "../src/compiler/index.js";
|
|
11
|
+
import {
|
|
12
|
+
loadComplianceConfig,
|
|
13
|
+
loadManifestFromFile,
|
|
11
14
|
resolveManifestFiles,
|
|
12
15
|
validateArtifactWithStandards,
|
|
13
16
|
validateManifestWithStandards,
|
|
14
|
-
|
|
15
|
-
} from "../src/index.js";
|
|
17
|
+
} from "../src/compliance/index.js";
|
|
16
18
|
import { bytesToBase64 } from "../src/utils/encoding.js";
|
|
17
19
|
|
|
18
20
|
async function main(argv) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "space-data-module-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
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",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"flatsql": "^0.4.0",
|
|
73
73
|
"hd-wallet-wasm": "1.6.0",
|
|
74
74
|
"sdn-emception": "1.0.0",
|
|
75
|
-
"spacedatastandards.org": "
|
|
75
|
+
"spacedatastandards.org": "^1.92.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"express": "^4.21.2"
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// Canonical plugin manifest schema.
|
|
2
|
+
//
|
|
3
|
+
// Upstream source: https://github.com/DigitalArsenal/spacedatastandards.org
|
|
4
|
+
// Path: schema/PLG/main.fbs
|
|
5
|
+
// Version: 1.0.6
|
|
6
|
+
// Upstream hash: 2c9ca90ec923b2476832517dee715559c45dd198d3bdd4b5b3dfe0a4d05c4882
|
|
7
|
+
//
|
|
8
|
+
// This is the canonical spacedatastandards.org "PLG" manifest.
|
|
9
|
+
// It is vendored here verbatim so the plugin SDK can depend on a stable copy
|
|
10
|
+
// without adding a network or submodule fetch at build time. Keep this file
|
|
11
|
+
// byte-for-byte identical to the upstream version; if a refresh is needed,
|
|
12
|
+
// re-vendor from the upstream path above rather than hand-editing.
|
|
13
|
+
|
|
14
|
+
// Hash: 2c9ca90ec923b2476832517dee715559c45dd198d3bdd4b5b3dfe0a4d05c4882
|
|
15
|
+
// Version: 1.0.6
|
|
16
|
+
// -----------------------------------END_HEADER
|
|
17
|
+
/// Plugin type category
|
|
18
|
+
enum pluginCategory : byte {
|
|
19
|
+
/// Sensor simulation and analysis
|
|
20
|
+
Sensor,
|
|
21
|
+
/// Orbital propagation algorithms
|
|
22
|
+
Propagator,
|
|
23
|
+
/// Custom rendering/visualization
|
|
24
|
+
Renderer,
|
|
25
|
+
/// Data analysis and processing
|
|
26
|
+
Analysis,
|
|
27
|
+
/// External data source integration
|
|
28
|
+
DataSource,
|
|
29
|
+
/// Electronic warfare simulation
|
|
30
|
+
EW,
|
|
31
|
+
/// Communications modeling
|
|
32
|
+
Comms,
|
|
33
|
+
/// Physics simulation
|
|
34
|
+
Physics,
|
|
35
|
+
/// GLSL shader plugins for custom visualization
|
|
36
|
+
Shader
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// Storefront payment model for the plugin listing
|
|
40
|
+
enum purchaseTier : byte {
|
|
41
|
+
/// No payment required
|
|
42
|
+
Free,
|
|
43
|
+
/// Single one-time purchase
|
|
44
|
+
OneTime,
|
|
45
|
+
/// Recurring subscription purchase
|
|
46
|
+
Subscription
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Publication visibility for the plugin listing
|
|
50
|
+
enum publicationState : byte {
|
|
51
|
+
/// Discoverable in public storefront listings
|
|
52
|
+
Public,
|
|
53
|
+
/// Addressable directly but hidden from public browse surfaces
|
|
54
|
+
Unlisted,
|
|
55
|
+
/// No longer offered for new installs or purchases
|
|
56
|
+
Retired
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// Plugin capability declaration
|
|
60
|
+
table PluginCapability {
|
|
61
|
+
/// Capability name, e.g., "gpu_compute", "wasm_simd"
|
|
62
|
+
NAME: string;
|
|
63
|
+
/// Capability version
|
|
64
|
+
VERSION: string;
|
|
65
|
+
/// Whether this capability is required
|
|
66
|
+
REQUIRED: bool;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/// Plugin dependency on another plugin
|
|
70
|
+
table PluginDependency {
|
|
71
|
+
/// Plugin ID of the dependency
|
|
72
|
+
PLUGIN_ID: string;
|
|
73
|
+
/// Minimum version required (semver)
|
|
74
|
+
MIN_VERSION: string;
|
|
75
|
+
/// Maximum version allowed (optional)
|
|
76
|
+
MAX_VERSION: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// Plugin entry point function definition
|
|
80
|
+
table EntryFunction {
|
|
81
|
+
/// Function name as exported from WASM
|
|
82
|
+
NAME: string (required);
|
|
83
|
+
/// Human-readable description
|
|
84
|
+
DESCRIPTION: string;
|
|
85
|
+
/// Input parameter types (FlatBuffer schema names)
|
|
86
|
+
INPUT_SCHEMAS: [string];
|
|
87
|
+
/// Output type (FlatBuffer schema name)
|
|
88
|
+
OUTPUT_SCHEMA: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// Plugin Manifest - canonical signed storefront and WASM distribution record
|
|
92
|
+
table PLG {
|
|
93
|
+
/// Unique identifier for the plugin
|
|
94
|
+
PLUGIN_ID: string (required);
|
|
95
|
+
/// Human-readable plugin name
|
|
96
|
+
NAME: string (required);
|
|
97
|
+
/// Plugin version (semver format)
|
|
98
|
+
VERSION: string (required);
|
|
99
|
+
/// Detailed description of plugin functionality
|
|
100
|
+
DESCRIPTION: string;
|
|
101
|
+
/// Short marketing summary shown in storefront listings
|
|
102
|
+
TAGLINE: string;
|
|
103
|
+
/// Type/category of the plugin
|
|
104
|
+
PLUGIN_TYPE: pluginCategory;
|
|
105
|
+
/// Human-readable publisher or organization name
|
|
106
|
+
PUBLISHER_NAME: string;
|
|
107
|
+
/// Publisher handle or username
|
|
108
|
+
PUBLISHER_HANDLE: string;
|
|
109
|
+
/// Canonical publisher website
|
|
110
|
+
PUBLISHER_URL: string;
|
|
111
|
+
/// Support or helpdesk URL for this plugin
|
|
112
|
+
SUPPORT_URL: string;
|
|
113
|
+
/// Search and categorization tags for discovery
|
|
114
|
+
TAGS: [string];
|
|
115
|
+
/// Short feature bullets highlighted in storefront listings
|
|
116
|
+
FEATURES: [string];
|
|
117
|
+
/// Screenshot URLs showing the plugin in use
|
|
118
|
+
SCREENSHOT_URLS: [string];
|
|
119
|
+
/// Optional hero/banner image URL for the listing
|
|
120
|
+
BANNER_URL: string;
|
|
121
|
+
|
|
122
|
+
/// ABI version for compatibility checking
|
|
123
|
+
ABI_VERSION: uint32 = 1;
|
|
124
|
+
|
|
125
|
+
/// SHA256 hash of the decrypted WASM binary
|
|
126
|
+
WASM_HASH: [ubyte];
|
|
127
|
+
/// Size of decrypted WASM binary in bytes
|
|
128
|
+
WASM_SIZE: uint64;
|
|
129
|
+
/// IPFS CID of the encrypted WASM binary
|
|
130
|
+
WASM_CID: string;
|
|
131
|
+
/// SHA256 hash of the encrypted delivery artifact bytes
|
|
132
|
+
ENCRYPTED_WASM_HASH: [ubyte];
|
|
133
|
+
/// Size of the encrypted delivery artifact in bytes
|
|
134
|
+
ENCRYPTED_WASM_SIZE: uint64;
|
|
135
|
+
|
|
136
|
+
/// Entry point functions exported by the plugin
|
|
137
|
+
ENTRY_FUNCTIONS: [EntryFunction];
|
|
138
|
+
/// FlatBuffer schemas required by this plugin
|
|
139
|
+
REQUIRED_SCHEMAS: [string];
|
|
140
|
+
/// Other plugins this depends on
|
|
141
|
+
DEPENDENCIES: [PluginDependency];
|
|
142
|
+
/// Capabilities provided by this plugin
|
|
143
|
+
CAPABILITIES: [PluginCapability];
|
|
144
|
+
|
|
145
|
+
/// Peer ID of the plugin provider
|
|
146
|
+
PROVIDER_PEER_ID: string;
|
|
147
|
+
/// IPFS CID of provider's EPM (Entity Profile Message)
|
|
148
|
+
PROVIDER_EPM_CID: string;
|
|
149
|
+
|
|
150
|
+
/// Whether the WASM binary is encrypted
|
|
151
|
+
ENCRYPTED: bool = true;
|
|
152
|
+
/// Canonical required scope for grant issuance
|
|
153
|
+
REQUIRED_SCOPE: string;
|
|
154
|
+
/// Provider-local identifier for the module content key
|
|
155
|
+
KEY_ID: string;
|
|
156
|
+
/// Allowed requester domains for module grants
|
|
157
|
+
ALLOWED_DOMAINS: [string];
|
|
158
|
+
/// Maximum grant timeout allowed for this module publication
|
|
159
|
+
MAX_GRANT_TIMEOUT_MS: uint64;
|
|
160
|
+
/// Minimum permissions required to run
|
|
161
|
+
MIN_PERMISSIONS: [string];
|
|
162
|
+
|
|
163
|
+
/// Unix timestamp when plugin was created
|
|
164
|
+
CREATED_AT: uint64;
|
|
165
|
+
/// Unix timestamp when plugin was last updated
|
|
166
|
+
UPDATED_AT: uint64;
|
|
167
|
+
/// URL to plugin documentation
|
|
168
|
+
DOCUMENTATION_URL: string;
|
|
169
|
+
/// URL to plugin changelog or release notes
|
|
170
|
+
CHANGELOG_URL: string;
|
|
171
|
+
/// URL to plugin icon/logo
|
|
172
|
+
ICON_URL: string;
|
|
173
|
+
/// License identifier (SPDX format)
|
|
174
|
+
LICENSE: string;
|
|
175
|
+
/// Commercial model used for storefront purchase flows
|
|
176
|
+
PAYMENT_MODEL: purchaseTier = Free;
|
|
177
|
+
/// Price in USD cents for one-time purchase or subscription period
|
|
178
|
+
PRICE_USD_CENTS: uint32;
|
|
179
|
+
/// Subscription billing period length in days
|
|
180
|
+
SUBSCRIPTION_PERIOD_DAYS: uint32;
|
|
181
|
+
/// Accepted payment methods, e.g. "stripe", "sol", "usdc"
|
|
182
|
+
ACCEPTED_PAYMENT_METHODS: [string];
|
|
183
|
+
/// Storefront publication state for this manifest version
|
|
184
|
+
LISTING_STATUS: publicationState = Public;
|
|
185
|
+
|
|
186
|
+
/// Ed25519 signature from provider over manifest
|
|
187
|
+
SIGNATURE: [ubyte];
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
root_type PLG;
|
|
191
|
+
file_identifier "$PLG";
|
package/src/AGENTS.md
CHANGED
|
@@ -11,7 +11,7 @@ the SDK source, not a prompt to edit SDK internals by default.
|
|
|
11
11
|
and `src/auth/AGENTS.md` provide narrower rules for those owners.
|
|
12
12
|
- `src/compiler`: compile flow, manifest embedding, runtime targets, toolchains,
|
|
13
13
|
and artifact layout.
|
|
14
|
-
- `src/bundle`:
|
|
14
|
+
- `src/bundle`: REC+MBL single-file packaging, wasm section handling, and vector compatibility.
|
|
15
15
|
- `src/host`: Node host, browser shims, `sdn_host`, WasmEdge runners, and
|
|
16
16
|
isomorphic loaders.
|
|
17
17
|
- `src/runtime-host`: FlatSQL-backed runtime host, row/region identity, and
|
package/src/bundle/AGENTS.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
# AGENTS
|
|
2
2
|
|
|
3
|
-
This directory is the reference implementation for
|
|
4
|
-
|
|
3
|
+
This directory is the reference implementation for REC+MBL single-file module
|
|
4
|
+
packaging and wasm section handling.
|
|
5
5
|
|
|
6
6
|
## What Authors Should Use It For
|
|
7
7
|
|
|
8
|
-
- `
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
- Single-file delivery uses one appended `REC` trailer carrying an `MBL`
|
|
9
|
+
record.
|
|
10
|
+
- Keep the runtime payload canonical `.wasm`; publication/container metadata
|
|
11
|
+
lives in the REC trailer.
|
|
11
12
|
- Use the public bundle helpers and CLI from this repo rather than inventing a
|
|
12
13
|
custom one-file format.
|
|
13
14
|
|
package/src/bundle/codec.js
CHANGED
|
@@ -2,13 +2,12 @@ import * as flatbuffers from "flatbuffers/mjs/flatbuffers.js";
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
CanonicalizationRuleT,
|
|
5
|
-
|
|
5
|
+
MBL,
|
|
6
|
+
MBLT,
|
|
6
7
|
ModuleBundleEntryRole,
|
|
7
8
|
ModuleBundleEntryT,
|
|
8
|
-
ModuleBundleT,
|
|
9
9
|
ModulePayloadEncoding,
|
|
10
|
-
} from "
|
|
11
|
-
import { FlatBufferTypeRefT } from "../generated/orbpro/stream/flat-buffer-type-ref.js";
|
|
10
|
+
} from "spacedatastandards.org/lib/js/MBL/main.js";
|
|
12
11
|
import { canonicalBytes } from "../auth/canonicalize.js";
|
|
13
12
|
import { toUint8Array as toBufferLikeUint8Array } from "../runtime/bufferLike.js";
|
|
14
13
|
import {
|
|
@@ -16,10 +15,11 @@ import {
|
|
|
16
15
|
DEFAULT_MANIFEST_EXPORT_SYMBOL,
|
|
17
16
|
DEFAULT_MANIFEST_SIZE_SYMBOL,
|
|
18
17
|
DEFAULT_MODULE_FORMAT,
|
|
19
|
-
SDS_BUNDLE_SECTION_NAME,
|
|
20
18
|
SDS_CUSTOM_SECTION_PREFIX,
|
|
19
|
+
SDS_MBL_CONTAINER_NAME,
|
|
21
20
|
} from "./constants.js";
|
|
22
21
|
|
|
22
|
+
const textDecoder = new TextDecoder();
|
|
23
23
|
const textEncoder = new TextEncoder();
|
|
24
24
|
|
|
25
25
|
const ROLE_NAME_TO_ENUM = new Map([
|
|
@@ -66,6 +66,15 @@ function normalizeString(value, fallback = null) {
|
|
|
66
66
|
return String(value);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
function firstDefined(...values) {
|
|
70
|
+
for (const value of values) {
|
|
71
|
+
if (value !== undefined) {
|
|
72
|
+
return value;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
|
|
69
78
|
function normalizePayloadWireFormat(value) {
|
|
70
79
|
if (value === 1) {
|
|
71
80
|
return "aligned-binary";
|
|
@@ -131,24 +140,47 @@ function normalizePayloadEncoding(value) {
|
|
|
131
140
|
);
|
|
132
141
|
}
|
|
133
142
|
|
|
134
|
-
function
|
|
135
|
-
if (
|
|
143
|
+
function stringifyTypeRef(value) {
|
|
144
|
+
if (value === undefined || value === null) {
|
|
136
145
|
return null;
|
|
137
146
|
}
|
|
138
|
-
if (value
|
|
147
|
+
if (typeof value === "string") {
|
|
139
148
|
return value;
|
|
140
149
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
const bytes = toBufferLikeUint8Array(value);
|
|
151
|
+
if (bytes) {
|
|
152
|
+
return textDecoder.decode(bytes);
|
|
153
|
+
}
|
|
154
|
+
return textDecoder.decode(canonicalBytes(value));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function parseTypeRef(value) {
|
|
158
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
159
|
+
return {
|
|
160
|
+
...value,
|
|
161
|
+
wireFormat: normalizePayloadWireFormat(value.wireFormat),
|
|
162
|
+
fixedStringLength: normalizeUnsignedInteger(value.fixedStringLength),
|
|
163
|
+
byteLength: normalizeUnsignedInteger(value.byteLength),
|
|
164
|
+
requiredAlignment: normalizeUnsignedInteger(value.requiredAlignment),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const normalized = normalizeString(value);
|
|
168
|
+
if (!normalized) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const parsed = JSON.parse(normalized);
|
|
173
|
+
if (parsed && typeof parsed === "object") {
|
|
174
|
+
return {
|
|
175
|
+
...parsed,
|
|
176
|
+
wireFormat: normalizePayloadWireFormat(parsed.wireFormat),
|
|
177
|
+
fixedStringLength: normalizeUnsignedInteger(parsed.fixedStringLength),
|
|
178
|
+
byteLength: normalizeUnsignedInteger(parsed.byteLength),
|
|
179
|
+
requiredAlignment: normalizeUnsignedInteger(parsed.requiredAlignment),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
} catch {}
|
|
183
|
+
return normalized;
|
|
152
184
|
}
|
|
153
185
|
|
|
154
186
|
function normalizeCanonicalization(value = {}) {
|
|
@@ -161,7 +193,7 @@ function normalizeCanonicalization(value = {}) {
|
|
|
161
193
|
value.strippedCustomSectionPrefix,
|
|
162
194
|
SDS_CUSTOM_SECTION_PREFIX,
|
|
163
195
|
),
|
|
164
|
-
normalizeString(value.bundleSectionName,
|
|
196
|
+
normalizeString(value.bundleSectionName, SDS_MBL_CONTAINER_NAME),
|
|
165
197
|
normalizeString(value.hashAlgorithm, DEFAULT_HASH_ALGORITHM),
|
|
166
198
|
);
|
|
167
199
|
}
|
|
@@ -175,7 +207,7 @@ function normalizeEntry(value = {}) {
|
|
|
175
207
|
normalizeString(value.entryId),
|
|
176
208
|
normalizeRole(value.role),
|
|
177
209
|
normalizeString(value.sectionName),
|
|
178
|
-
|
|
210
|
+
stringifyTypeRef(value.typeRef),
|
|
179
211
|
payloadEncoding,
|
|
180
212
|
normalizeString(value.mediaType),
|
|
181
213
|
Number(value.flags ?? 0),
|
|
@@ -185,38 +217,122 @@ function normalizeEntry(value = {}) {
|
|
|
185
217
|
);
|
|
186
218
|
}
|
|
187
219
|
|
|
220
|
+
function normalizeDecodedEntry(entry = {}) {
|
|
221
|
+
return {
|
|
222
|
+
entryId: firstDefined(entry.entryId, entry.entry_id) ?? null,
|
|
223
|
+
role: entry.role ?? ModuleBundleEntryRole.AUXILIARY,
|
|
224
|
+
sectionName: firstDefined(entry.sectionName, entry.section_name) ?? null,
|
|
225
|
+
typeRef: parseTypeRef(firstDefined(entry.typeRef, entry.type_ref)),
|
|
226
|
+
payloadEncoding:
|
|
227
|
+
firstDefined(entry.payloadEncoding, entry.payload_encoding) ??
|
|
228
|
+
ModulePayloadEncoding.RAW_BYTES,
|
|
229
|
+
mediaType: firstDefined(entry.mediaType, entry.media_type) ?? null,
|
|
230
|
+
flags: Number(entry.flags ?? 0),
|
|
231
|
+
sha256: normalizeByteArray(entry.sha256),
|
|
232
|
+
payload: normalizeByteArray(firstDefined(entry.payload, entry.PAYLOAD)),
|
|
233
|
+
description: entry.description ?? null,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function normalizeDecodedCanonicalization(canonicalization = null) {
|
|
238
|
+
if (!canonicalization || typeof canonicalization !== "object") {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
version: Number(canonicalization.version ?? 1),
|
|
243
|
+
strippedCustomSectionPrefix: normalizeString(
|
|
244
|
+
firstDefined(
|
|
245
|
+
canonicalization.strippedCustomSectionPrefix,
|
|
246
|
+
canonicalization.stripped_custom_section_prefix,
|
|
247
|
+
),
|
|
248
|
+
SDS_CUSTOM_SECTION_PREFIX,
|
|
249
|
+
),
|
|
250
|
+
bundleSectionName: normalizeString(
|
|
251
|
+
firstDefined(
|
|
252
|
+
canonicalization.bundleSectionName,
|
|
253
|
+
canonicalization.bundle_section_name,
|
|
254
|
+
),
|
|
255
|
+
SDS_MBL_CONTAINER_NAME,
|
|
256
|
+
),
|
|
257
|
+
hashAlgorithm: normalizeString(
|
|
258
|
+
firstDefined(
|
|
259
|
+
canonicalization.hashAlgorithm,
|
|
260
|
+
canonicalization.hash_algorithm,
|
|
261
|
+
),
|
|
262
|
+
DEFAULT_HASH_ALGORITHM,
|
|
263
|
+
),
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function normalizeDecodedBundle(bundle = {}) {
|
|
268
|
+
return {
|
|
269
|
+
bundleVersion: Number(
|
|
270
|
+
firstDefined(bundle.bundleVersion, bundle.bundle_version) ?? 1,
|
|
271
|
+
),
|
|
272
|
+
moduleFormat: normalizeString(
|
|
273
|
+
firstDefined(bundle.moduleFormat, bundle.module_format),
|
|
274
|
+
DEFAULT_MODULE_FORMAT,
|
|
275
|
+
),
|
|
276
|
+
canonicalization: normalizeDecodedCanonicalization(bundle.canonicalization),
|
|
277
|
+
canonicalModuleHash: normalizeByteArray(
|
|
278
|
+
firstDefined(bundle.canonicalModuleHash, bundle.canonical_module_hash),
|
|
279
|
+
),
|
|
280
|
+
manifestHash: normalizeByteArray(
|
|
281
|
+
firstDefined(bundle.manifestHash, bundle.manifest_hash),
|
|
282
|
+
),
|
|
283
|
+
manifestExportSymbol: normalizeString(
|
|
284
|
+
firstDefined(bundle.manifestExportSymbol, bundle.manifest_export_symbol),
|
|
285
|
+
DEFAULT_MANIFEST_EXPORT_SYMBOL,
|
|
286
|
+
),
|
|
287
|
+
manifestSizeSymbol: normalizeString(
|
|
288
|
+
firstDefined(bundle.manifestSizeSymbol, bundle.manifest_size_symbol),
|
|
289
|
+
DEFAULT_MANIFEST_SIZE_SYMBOL,
|
|
290
|
+
),
|
|
291
|
+
entries: Array.isArray(bundle.entries)
|
|
292
|
+
? bundle.entries.map(normalizeDecodedEntry)
|
|
293
|
+
: [],
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export function moduleBundleTableFromObject(bundle = {}) {
|
|
298
|
+
return bundle instanceof MBLT
|
|
299
|
+
? bundle
|
|
300
|
+
: new MBLT(
|
|
301
|
+
Number(bundle?.bundleVersion ?? 1),
|
|
302
|
+
normalizeString(bundle?.moduleFormat, DEFAULT_MODULE_FORMAT),
|
|
303
|
+
normalizeCanonicalization(bundle?.canonicalization),
|
|
304
|
+
normalizeByteArray(bundle?.canonicalModuleHash),
|
|
305
|
+
normalizeByteArray(bundle?.manifestHash),
|
|
306
|
+
normalizeString(
|
|
307
|
+
bundle?.manifestExportSymbol,
|
|
308
|
+
DEFAULT_MANIFEST_EXPORT_SYMBOL,
|
|
309
|
+
),
|
|
310
|
+
normalizeString(
|
|
311
|
+
bundle?.manifestSizeSymbol,
|
|
312
|
+
DEFAULT_MANIFEST_SIZE_SYMBOL,
|
|
313
|
+
),
|
|
314
|
+
Array.isArray(bundle?.entries)
|
|
315
|
+
? bundle.entries.map(normalizeEntry)
|
|
316
|
+
: [],
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
188
320
|
export function decodeModuleBundle(data) {
|
|
189
321
|
const bb = toByteBuffer(data);
|
|
190
|
-
if (!
|
|
322
|
+
if (!MBL.bufferHasIdentifier(bb)) {
|
|
191
323
|
throw new Error("Module bundle buffer identifier mismatch.");
|
|
192
324
|
}
|
|
193
|
-
return
|
|
325
|
+
return normalizeDecodedBundle(MBL.getRootAsMBL(bb).unpack());
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export function decodeModuleBundleTable(table) {
|
|
329
|
+
return normalizeDecodedBundle(table?.unpack?.() ?? {});
|
|
194
330
|
}
|
|
195
331
|
|
|
196
332
|
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
|
-
);
|
|
333
|
+
const value = moduleBundleTableFromObject(bundle);
|
|
218
334
|
const builder = new flatbuffers.Builder(1024);
|
|
219
|
-
|
|
335
|
+
MBL.finishMBLBuffer(builder, value.pack(builder));
|
|
220
336
|
return builder.asUint8Array();
|
|
221
337
|
}
|
|
222
338
|
|
|
@@ -259,10 +375,9 @@ export function findModuleBundleEntry(bundle, match) {
|
|
|
259
375
|
|
|
260
376
|
export {
|
|
261
377
|
CanonicalizationRuleT,
|
|
262
|
-
|
|
263
|
-
|
|
378
|
+
MBL,
|
|
379
|
+
MBLT,
|
|
264
380
|
ModuleBundleEntryRole,
|
|
265
381
|
ModuleBundleEntryT,
|
|
266
|
-
ModuleBundleT,
|
|
267
382
|
ModulePayloadEncoding,
|
|
268
383
|
};
|
package/src/bundle/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const SDS_CUSTOM_SECTION_PREFIX = "sds.";
|
|
2
|
-
export const
|
|
2
|
+
export const SDS_MBL_CONTAINER_NAME = "rec.mbl";
|
|
3
3
|
export const DEFAULT_MODULE_FORMAT = "space-data-module";
|
|
4
4
|
export const DEFAULT_HASH_ALGORITHM = "sha256";
|
|
5
5
|
export const DEFAULT_MANIFEST_EXPORT_SYMBOL = "plugin_get_manifest_flatbuffer";
|