space-data-module-sdk 0.7.0 → 0.8.0
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/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 +22 -23
- package/src/compiler/compileModule.js +9 -1
- package/src/index.d.ts +1 -1
- package/src/transport/records.js +34 -3
- 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.0",
|
|
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.85.0"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"express": "^4.21.2"
|
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";
|
package/src/bundle/wasm.js
CHANGED
|
@@ -7,10 +7,10 @@ import { createDeploymentPlanBundleEntry } from "../deployment/index.js";
|
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_MANIFEST_EXPORT_SYMBOL,
|
|
9
9
|
DEFAULT_MANIFEST_SIZE_SYMBOL,
|
|
10
|
-
SDS_BUNDLE_SECTION_NAME,
|
|
11
10
|
SDS_CUSTOM_SECTION_PREFIX,
|
|
12
11
|
SDS_DEPLOYMENT_ENTRY_ID,
|
|
13
12
|
SDS_DEPLOYMENT_SECTION_NAME,
|
|
13
|
+
SDS_MBL_CONTAINER_NAME,
|
|
14
14
|
} from "./constants.js";
|
|
15
15
|
import {
|
|
16
16
|
decodeModuleBundle,
|
|
@@ -20,7 +20,11 @@ import {
|
|
|
20
20
|
moduleBundleEncodingToName,
|
|
21
21
|
moduleBundleRoleToName,
|
|
22
22
|
} from "./codec.js";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
appendPublicationRecordCollection,
|
|
25
|
+
encodePublicationRecordCollection,
|
|
26
|
+
extractPublicationRecordCollection,
|
|
27
|
+
} from "../transport/records.js";
|
|
24
28
|
|
|
25
29
|
const textDecoder = new TextDecoder();
|
|
26
30
|
const textEncoder = new TextEncoder();
|
|
@@ -392,7 +396,7 @@ export async function createSingleFileBundle(options = {}) {
|
|
|
392
396
|
version: 1,
|
|
393
397
|
strippedCustomSectionPrefix:
|
|
394
398
|
options.customSectionPrefix ?? SDS_CUSTOM_SECTION_PREFIX,
|
|
395
|
-
bundleSectionName: options.bundleSectionName ??
|
|
399
|
+
bundleSectionName: options.bundleSectionName ?? SDS_MBL_CONTAINER_NAME,
|
|
396
400
|
hashAlgorithm: "sha256",
|
|
397
401
|
};
|
|
398
402
|
const canonical = await computeCanonicalModuleHash(wasmBytes, {
|
|
@@ -415,10 +419,14 @@ export async function createSingleFileBundle(options = {}) {
|
|
|
415
419
|
const baseWasmBytes = stripWasmCustomSections(wasmBytes, (section) =>
|
|
416
420
|
section.name.startsWith(canonicalization.strippedCustomSectionPrefix),
|
|
417
421
|
);
|
|
418
|
-
const outputWasmBytes =
|
|
422
|
+
const outputWasmBytes = appendPublicationRecordCollection(
|
|
419
423
|
baseWasmBytes,
|
|
420
|
-
|
|
421
|
-
|
|
424
|
+
encodePublicationRecordCollection({
|
|
425
|
+
version: protectedArtifact?.version,
|
|
426
|
+
mbl: bundle,
|
|
427
|
+
enc: protectedArtifact?.enc,
|
|
428
|
+
pnm: protectedArtifact?.pnm,
|
|
429
|
+
}),
|
|
422
430
|
);
|
|
423
431
|
return {
|
|
424
432
|
bundle,
|
|
@@ -434,25 +442,16 @@ export async function createSingleFileBundle(options = {}) {
|
|
|
434
442
|
|
|
435
443
|
export async function parseSingleFileBundle(bytes, options = {}) {
|
|
436
444
|
const protectedArtifact = extractPublicationRecordCollection(bytes);
|
|
445
|
+
if (!protectedArtifact?.mbl) {
|
|
446
|
+
throw new Error("Missing required REC trailer containing an MBL record.");
|
|
447
|
+
}
|
|
437
448
|
const wasmBytes = normalizeBytes(
|
|
438
|
-
protectedArtifact
|
|
449
|
+
protectedArtifact.payloadBytes,
|
|
439
450
|
"wasm bytes",
|
|
440
451
|
);
|
|
441
452
|
const customSections = listWasmCustomSections(wasmBytes);
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
);
|
|
445
|
-
const bundleSections = customSections.filter(
|
|
446
|
-
(section) => section.name === bundleSectionName,
|
|
447
|
-
);
|
|
448
|
-
if (bundleSections.length === 0) {
|
|
449
|
-
throw new Error(`Missing required custom section "${bundleSectionName}".`);
|
|
450
|
-
}
|
|
451
|
-
if (bundleSections.length > 1) {
|
|
452
|
-
throw new Error(`Expected one "${bundleSectionName}" section, found ${bundleSections.length}.`);
|
|
453
|
-
}
|
|
454
|
-
const bundleBytes = bundleSections[0].dataBytes;
|
|
455
|
-
const bundle = decodeModuleBundle(bundleBytes);
|
|
453
|
+
const bundle = protectedArtifact.mbl;
|
|
454
|
+
const bundleBytes = protectedArtifact.mblBytes ?? encodeModuleBundle(bundle);
|
|
456
455
|
const prefix =
|
|
457
456
|
bundle.canonicalization?.strippedCustomSectionPrefix ??
|
|
458
457
|
SDS_CUSTOM_SECTION_PREFIX;
|
|
@@ -477,8 +476,8 @@ export async function parseSingleFileBundle(bytes, options = {}) {
|
|
|
477
476
|
) ?? null;
|
|
478
477
|
return {
|
|
479
478
|
wasmBytes,
|
|
480
|
-
protectedArtifactBytes: protectedArtifact
|
|
481
|
-
publicationRecords: protectedArtifact
|
|
479
|
+
protectedArtifactBytes: protectedArtifact.protectedBytes,
|
|
480
|
+
publicationRecords: protectedArtifact,
|
|
482
481
|
bundleBytes,
|
|
483
482
|
bundle,
|
|
484
483
|
entries: parsedEntries,
|
|
@@ -894,6 +894,7 @@ export async function protectModuleArtifact(options = {}) {
|
|
|
894
894
|
};
|
|
895
895
|
|
|
896
896
|
let singleFileBundle = null;
|
|
897
|
+
let singleFileBundleRecords = null;
|
|
897
898
|
if (options.singleFileBundle === true) {
|
|
898
899
|
const additionalEntries = [
|
|
899
900
|
...(Array.isArray(options.bundleEntries) ? options.bundleEntries : []),
|
|
@@ -905,9 +906,13 @@ export async function protectModuleArtifact(options = {}) {
|
|
|
905
906
|
authorization: signedAuthorization,
|
|
906
907
|
entries: additionalEntries,
|
|
907
908
|
});
|
|
909
|
+
singleFileBundleRecords = extractPublicationRecordCollection(
|
|
910
|
+
singleFileBundle.wasmBytes,
|
|
911
|
+
);
|
|
908
912
|
}
|
|
909
913
|
|
|
910
|
-
const bundleBytes =
|
|
914
|
+
const bundleBytes = singleFileBundleRecords?.payloadBytes ?? wasmBytes;
|
|
915
|
+
const bundleRecord = singleFileBundleRecords?.mbl ?? null;
|
|
911
916
|
let publicationNotice = null;
|
|
912
917
|
let publicationRecordsBytes = null;
|
|
913
918
|
let protectedArtifactBytes = null;
|
|
@@ -931,6 +936,7 @@ export async function protectModuleArtifact(options = {}) {
|
|
|
931
936
|
signer,
|
|
932
937
|
});
|
|
933
938
|
publicationRecordsBytes = encodePublicationRecordCollection({
|
|
939
|
+
mbl: bundleRecord,
|
|
934
940
|
enc: parsedEncryptedBase.enc,
|
|
935
941
|
pnm: publicationNotice,
|
|
936
942
|
});
|
|
@@ -943,6 +949,7 @@ export async function protectModuleArtifact(options = {}) {
|
|
|
943
949
|
parsedProtectedBlob: {
|
|
944
950
|
payloadBytes: parsedEncryptedBase.payloadBytes,
|
|
945
951
|
recordCollectionBytes: publicationRecordsBytes,
|
|
952
|
+
mbl: bundleRecord,
|
|
946
953
|
enc: parsedEncryptedBase.enc,
|
|
947
954
|
pnm: publicationNotice,
|
|
948
955
|
},
|
|
@@ -959,6 +966,7 @@ export async function protectModuleArtifact(options = {}) {
|
|
|
959
966
|
signer,
|
|
960
967
|
});
|
|
961
968
|
publicationRecordsBytes = encodePublicationRecordCollection({
|
|
969
|
+
mbl: bundleRecord,
|
|
962
970
|
pnm: publicationNotice,
|
|
963
971
|
});
|
|
964
972
|
protectedArtifactBytes = appendPublicationRecordCollection(
|
package/src/index.d.ts
CHANGED
|
@@ -937,7 +937,7 @@ export function validateManifestAgainstStandardsCatalog(
|
|
|
937
937
|
|
|
938
938
|
// --- Bundle ---
|
|
939
939
|
|
|
940
|
-
export const
|
|
940
|
+
export const SDS_MBL_CONTAINER_NAME: string;
|
|
941
941
|
export const DEFAULT_HASH_ALGORITHM: string;
|
|
942
942
|
export const SDS_GUEST_LINK_OBJECT_ENTRY_ID: string;
|
|
943
943
|
export const SDS_GUEST_LINK_METADATA_ENTRY_ID: string;
|