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.
Files changed (67) hide show
  1. package/README.md +16 -23
  2. package/bin/space-data-module.js +5 -3
  3. package/package.json +2 -2
  4. package/schemas/spacedatastandards/PLG.fbs +191 -0
  5. package/src/AGENTS.md +1 -1
  6. package/src/bundle/AGENTS.md +6 -5
  7. package/src/bundle/codec.js +163 -48
  8. package/src/bundle/constants.js +1 -1
  9. package/src/bundle/wasm.js +53 -32
  10. package/src/compiler/compileModule.js +9 -1
  11. package/src/compliance/index.js +4 -0
  12. package/src/compliance/pluginCompliance.js +158 -2
  13. package/src/embeddedManifest.js +25 -5
  14. package/src/generated/orbpro/invoke/plugin-invoke-request.js +2 -2
  15. package/src/generated/orbpro/invoke/plugin-invoke-response.js +2 -2
  16. package/src/generated/orbpro/stream/flat-buffer-type-ref.js +2 -2
  17. package/src/generated/orbpro/stream/typed-arena-buffer.js +2 -2
  18. package/src/generated/spacedatastandards/plg/entry-function.js +86 -0
  19. package/src/generated/spacedatastandards/plg/entry-function.ts +119 -0
  20. package/src/generated/spacedatastandards/plg/index.js +16 -0
  21. package/src/generated/spacedatastandards/plg/index.ts +11 -0
  22. package/src/generated/spacedatastandards/plg/plg.js +657 -0
  23. package/src/generated/spacedatastandards/plg/plg.ts +924 -0
  24. package/src/generated/spacedatastandards/plg/plugin-capability.js +66 -0
  25. package/src/generated/spacedatastandards/plg/plugin-capability.ts +84 -0
  26. package/src/generated/spacedatastandards/plg/plugin-category.js +15 -0
  27. package/src/generated/spacedatastandards/plg/plugin-category.ts +53 -0
  28. package/src/generated/spacedatastandards/plg/plugin-dependency.js +63 -0
  29. package/src/generated/spacedatastandards/plg/plugin-dependency.ts +86 -0
  30. package/src/generated/spacedatastandards/plg/publication-state.js +9 -0
  31. package/src/generated/spacedatastandards/plg/publication-state.ts +23 -0
  32. package/src/generated/spacedatastandards/plg/purchase-tier.js +9 -0
  33. package/src/generated/spacedatastandards/plg/purchase-tier.ts +23 -0
  34. package/src/index.d.ts +1 -1
  35. package/src/invoke/codec.js +1 -1
  36. package/src/manifest/browser.js +7 -0
  37. package/src/manifest/index.js +7 -0
  38. package/src/manifest/legacyToPlg.js +249 -0
  39. package/src/manifest/plgCodec.js +826 -0
  40. package/src/standards/sharedCatalog.js +132 -0
  41. package/src/transport/records.js +34 -3
  42. package/src/vendor/flatbuffers/LICENSE +202 -0
  43. package/src/vendor/flatbuffers/builder.js +534 -0
  44. package/src/vendor/flatbuffers/byte-buffer.js +253 -0
  45. package/src/vendor/flatbuffers/constants.js +4 -0
  46. package/src/vendor/flatbuffers/encoding.js +5 -0
  47. package/src/vendor/flatbuffers/flatbuffers.js +5 -0
  48. package/src/vendor/flatbuffers/utils.js +4 -0
  49. package/schemas/ModuleBundle.fbs +0 -108
  50. package/src/generated/orbpro/module/canonicalization-rule.d.ts +0 -48
  51. package/src/generated/orbpro/module/canonicalization-rule.js +0 -95
  52. package/src/generated/orbpro/module/canonicalization-rule.ts +0 -142
  53. package/src/generated/orbpro/module/module-bundle-entry-role.d.ts +0 -11
  54. package/src/generated/orbpro/module/module-bundle-entry-role.js +0 -14
  55. package/src/generated/orbpro/module/module-bundle-entry-role.ts +0 -15
  56. package/src/generated/orbpro/module/module-bundle-entry.d.ts +0 -97
  57. package/src/generated/orbpro/module/module-bundle-entry.js +0 -219
  58. package/src/generated/orbpro/module/module-bundle-entry.ts +0 -287
  59. package/src/generated/orbpro/module/module-bundle.d.ts +0 -86
  60. package/src/generated/orbpro/module/module-bundle.js +0 -213
  61. package/src/generated/orbpro/module/module-bundle.ts +0 -277
  62. package/src/generated/orbpro/module/module-payload-encoding.d.ts +0 -9
  63. package/src/generated/orbpro/module/module-payload-encoding.js +0 -12
  64. package/src/generated/orbpro/module/module-payload-encoding.ts +0 -13
  65. package/src/generated/orbpro/module.d.ts +0 -5
  66. package/src/generated/orbpro/module.js +0 -7
  67. 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 `sds.bundle` single-file container
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 `sds.bundle` custom-section payloads for:
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 a trailing `REC`
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 does not append arbitrary bytes to the end of the wasm
94
- module. The one-file module container is `sds.bundle`, stored as a standard
95
- wasm custom section. Appended bytes are reserved for SDS publication records
96
- such as `PNM` and `ENC`, wrapped in a trailing `REC` FlatBuffer collection.
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 `sds.bundle` conformance vectors under
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 `sds.bundle`
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
- `sds.bundle` keeps module delivery to one file without changing WebAssembly
396
- loadability for the runtime payload itself. The SDK writes the bundle as a
397
- standard custom section inside the wasm module. When the artifact is signed or
398
- encrypted for publication, SDS appends FlatBuffer publication records after the
399
- wasm bytes in a trailing `REC` container. Loaders must scan from the end,
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
@@ -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
- loadManifestFromFile,
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.7.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": "git+https://github.com/DigitalArsenal/spacedatastandards.org.git#c43c766bf4e8b18af125ed73b993e79c6ce20b24"
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`: `sds.bundle`, wasm custom sections, and vector compatibility.
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
@@ -1,13 +1,14 @@
1
1
  # AGENTS
2
2
 
3
- This directory is the reference implementation for `sds.bundle` and wasm
4
- custom-section packaging.
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
- - `sds.bundle` is the single-file delivery format.
9
- - Put bundle data in a wasm custom section; do not append raw bytes after the
10
- wasm binary.
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
 
@@ -2,13 +2,12 @@ import * as flatbuffers from "flatbuffers/mjs/flatbuffers.js";
2
2
 
3
3
  import {
4
4
  CanonicalizationRuleT,
5
- ModuleBundle,
5
+ MBL,
6
+ MBLT,
6
7
  ModuleBundleEntryRole,
7
8
  ModuleBundleEntryT,
8
- ModuleBundleT,
9
9
  ModulePayloadEncoding,
10
- } from "../generated/orbpro/module.js";
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 normalizeTypeRef(value) {
135
- if (!value) {
143
+ function stringifyTypeRef(value) {
144
+ if (value === undefined || value === null) {
136
145
  return null;
137
146
  }
138
- if (value instanceof FlatBufferTypeRefT) {
147
+ if (typeof value === "string") {
139
148
  return value;
140
149
  }
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
- );
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, SDS_BUNDLE_SECTION_NAME),
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
- normalizeTypeRef(value.typeRef),
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 (!ModuleBundle.bufferHasIdentifier(bb)) {
322
+ if (!MBL.bufferHasIdentifier(bb)) {
191
323
  throw new Error("Module bundle buffer identifier mismatch.");
192
324
  }
193
- return ModuleBundle.getRootAsModuleBundle(bb).unpack();
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
- ModuleBundle.finishModuleBundleBuffer(builder, value.pack(builder));
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
- FlatBufferTypeRefT,
263
- ModuleBundle,
378
+ MBL,
379
+ MBLT,
264
380
  ModuleBundleEntryRole,
265
381
  ModuleBundleEntryT,
266
- ModuleBundleT,
267
382
  ModulePayloadEncoding,
268
383
  };
@@ -1,5 +1,5 @@
1
1
  export const SDS_CUSTOM_SECTION_PREFIX = "sds.";
2
- export const SDS_BUNDLE_SECTION_NAME = "sds.bundle";
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";