space-data-module-sdk 0.5.14 → 0.5.18

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 (37) hide show
  1. package/README.md +91 -1
  2. package/package.json +8 -4
  3. package/schemas/HostStorageAbi.fbs +53 -0
  4. package/src/bundle/codec.js +1 -1
  5. package/src/compliance/pluginCompliance.js +0 -130
  6. package/src/generated/orbpro/invoke/plugin-invoke-request.js +1 -1
  7. package/src/generated/orbpro/invoke/plugin-invoke-response.js +1 -1
  8. package/src/generated/orbpro/manifest/accepted-type-set.js +1 -1
  9. package/src/generated/orbpro/manifest/build-artifact.js +1 -1
  10. package/src/generated/orbpro/manifest/host-capability.js +1 -1
  11. package/src/generated/orbpro/manifest/method-manifest.js +1 -1
  12. package/src/generated/orbpro/manifest/plugin-manifest.js +1 -1
  13. package/src/generated/orbpro/manifest/port-manifest.js +1 -1
  14. package/src/generated/orbpro/manifest/protocol-spec.js +1 -1
  15. package/src/generated/orbpro/manifest/timer-spec.js +1 -1
  16. package/src/generated/orbpro/module/canonicalization-rule.js +1 -1
  17. package/src/generated/orbpro/module/module-bundle-entry.js +1 -1
  18. package/src/generated/orbpro/module/module-bundle.js +1 -1
  19. package/src/generated/orbpro/stream/flat-buffer-type-ref.js +1 -1
  20. package/src/generated/orbpro/stream/typed-arena-buffer.js +1 -1
  21. package/src/index.d.ts +157 -1
  22. package/src/index.js +1 -0
  23. package/src/invoke/codec.js +10 -8
  24. package/src/manifest/codec.js +1 -1
  25. package/src/runtime-host/flatsqlRuntimeStore.js +217 -0
  26. package/src/runtime-host/index.js +21 -0
  27. package/src/runtime-host/moduleRegistry.js +92 -0
  28. package/src/runtime-host/runtimeRegionStore.js +245 -0
  29. package/src/testing/buildWasmEdgeRunner.js +253 -0
  30. package/src/testing/index.d.ts +311 -0
  31. package/src/testing/index.js +21 -0
  32. package/src/testing/moduleHarness.js +163 -0
  33. package/src/testing/native/wasmedge_emscripten_pthread_runner.c +3111 -0
  34. package/src/testing/processInvoke.js +467 -0
  35. package/src/testing/publicationProtectionDemo.js +271 -0
  36. package/src/testing/streamInvokeCodec.js +175 -0
  37. package/src/transport/records.js +56 -55
@@ -0,0 +1,271 @@
1
+ import * as flatbuffers from "flatbuffers";
2
+
3
+ import { createRecipientKeypairHex, protectModuleArtifact } from "../compiler/compileModule.js";
4
+ import { extractPublicationRecordCollection } from "../transport/records.js";
5
+ import { REC } from "spacedatastandards.org/lib/js/REC/REC.js";
6
+ import { Record } from "spacedatastandards.org/lib/js/REC/Record.js";
7
+ import { PNM } from "spacedatastandards.org/lib/js/PNM/main.js";
8
+ import { ENC } from "spacedatastandards.org/lib/js/ENC/main.js";
9
+
10
+ const MINIMAL_WASM_BYTES = Uint8Array.of(
11
+ 0x00,
12
+ 0x61,
13
+ 0x73,
14
+ 0x6d,
15
+ 0x01,
16
+ 0x00,
17
+ 0x00,
18
+ 0x00,
19
+ );
20
+
21
+ export function createPublicationProtectionDemoManifest() {
22
+ return {
23
+ pluginId: "com.digitalarsenal.examples.publication-protection-demo",
24
+ name: "Publication Protection Demo",
25
+ version: "0.1.0",
26
+ pluginFamily: "propagator",
27
+ capabilities: ["clock", "crypto_sign", "crypto_encrypt"],
28
+ externalInterfaces: [],
29
+ methods: [
30
+ {
31
+ methodId: "propagate",
32
+ displayName: "Propagate",
33
+ inputPorts: [
34
+ {
35
+ portId: "request",
36
+ acceptedTypeSets: [
37
+ {
38
+ setId: "omm-request",
39
+ allowedTypes: [
40
+ {
41
+ schemaName: "OMM.fbs",
42
+ fileIdentifier: "$OMM",
43
+ },
44
+ ],
45
+ },
46
+ ],
47
+ minStreams: 1,
48
+ maxStreams: 1,
49
+ required: true,
50
+ },
51
+ ],
52
+ outputPorts: [
53
+ {
54
+ portId: "state",
55
+ acceptedTypeSets: [
56
+ {
57
+ setId: "state-vector",
58
+ allowedTypes: [
59
+ {
60
+ schemaName: "StateVector.fbs",
61
+ fileIdentifier: "STVC",
62
+ },
63
+ {
64
+ schemaName: "StateVector.fbs",
65
+ fileIdentifier: "STVC",
66
+ wireFormat: "aligned-binary",
67
+ rootTypeName: "StateVector",
68
+ byteLength: 72,
69
+ requiredAlignment: 8,
70
+ },
71
+ ],
72
+ },
73
+ ],
74
+ minStreams: 1,
75
+ maxStreams: 1,
76
+ required: true,
77
+ },
78
+ ],
79
+ maxBatch: 32,
80
+ drainPolicy: "drain-to-empty",
81
+ },
82
+ ],
83
+ schemasUsed: [
84
+ {
85
+ schemaName: "OMM.fbs",
86
+ fileIdentifier: "$OMM",
87
+ },
88
+ {
89
+ schemaName: "StateVector.fbs",
90
+ fileIdentifier: "STVC",
91
+ },
92
+ {
93
+ schemaName: "StateVector.fbs",
94
+ fileIdentifier: "STVC",
95
+ wireFormat: "aligned-binary",
96
+ rootTypeName: "StateVector",
97
+ byteLength: 72,
98
+ requiredAlignment: 8,
99
+ },
100
+ ],
101
+ };
102
+ }
103
+
104
+ function summarizeAlignedBinaryContract(manifest = {}) {
105
+ const summaries = [];
106
+ for (const method of Array.isArray(manifest.methods) ? manifest.methods : []) {
107
+ const ports = [
108
+ ...(Array.isArray(method.inputPorts) ? method.inputPorts : []),
109
+ ...(Array.isArray(method.outputPorts) ? method.outputPorts : []),
110
+ ];
111
+ for (const port of ports) {
112
+ for (const typeSet of Array.isArray(port.acceptedTypeSets)
113
+ ? port.acceptedTypeSets
114
+ : []) {
115
+ const allowedTypes = Array.isArray(typeSet.allowedTypes)
116
+ ? typeSet.allowedTypes
117
+ : [];
118
+ for (const allowedType of allowedTypes) {
119
+ if (allowedType?.wireFormat !== "aligned-binary") {
120
+ continue;
121
+ }
122
+ const hasFlatbufferFallback = allowedTypes.some(
123
+ (candidate) =>
124
+ (candidate?.wireFormat ?? "flatbuffer") === "flatbuffer" &&
125
+ candidate?.schemaName === allowedType.schemaName &&
126
+ candidate?.fileIdentifier === allowedType.fileIdentifier,
127
+ );
128
+ summaries.push({
129
+ methodId: method.methodId ?? null,
130
+ portId: port.portId ?? null,
131
+ setId: typeSet.setId ?? null,
132
+ schemaName: allowedType.schemaName ?? null,
133
+ fileIdentifier: allowedType.fileIdentifier ?? null,
134
+ rootTypeName: allowedType.rootTypeName ?? null,
135
+ byteLength: allowedType.byteLength ?? null,
136
+ requiredAlignment: allowedType.requiredAlignment ?? null,
137
+ hasFlatbufferFallback,
138
+ });
139
+ }
140
+ }
141
+ }
142
+ }
143
+ return summaries;
144
+ }
145
+
146
+ function parseStandardsRec(recordCollectionBytes) {
147
+ const recBuffer = new flatbuffers.ByteBuffer(recordCollectionBytes);
148
+ const rec = REC.getRootAsREC(recBuffer);
149
+ const records = [];
150
+ for (let index = 0; index < rec.recordsLength(); index += 1) {
151
+ const record = rec.RECORDS(index, new Record());
152
+ if (!record) {
153
+ continue;
154
+ }
155
+ const standard = record.standard() ?? null;
156
+ if (standard === "PNM") {
157
+ const pnm = record.value(new PNM());
158
+ records.push({
159
+ standard,
160
+ fileIdentifier: "$PNM",
161
+ fileName: pnm?.FILE_NAME() ?? null,
162
+ fileId: pnm?.FILE_ID() ?? null,
163
+ cid: pnm?.CID() ?? null,
164
+ hasSignature: Boolean(pnm?.SIGNATURE()),
165
+ });
166
+ continue;
167
+ }
168
+ if (standard === "ENC") {
169
+ const enc = record.value(new ENC());
170
+ records.push({
171
+ standard,
172
+ fileIdentifier: "$ENC",
173
+ context: enc?.CONTEXT() ?? null,
174
+ rootType: enc?.ROOT_TYPE() ?? null,
175
+ nonceLength: enc?.nonceStartLength() ?? 0,
176
+ ephemeralPublicKeyLength: enc?.ephemeralPublicKeyLength() ?? 0,
177
+ });
178
+ continue;
179
+ }
180
+ records.push({
181
+ standard,
182
+ fileIdentifier: null,
183
+ });
184
+ }
185
+ return {
186
+ fileIdentifier: "$REC",
187
+ version: rec.version() ?? null,
188
+ recordCount: records.length,
189
+ recordStandards: records.map((record) => record.standard),
190
+ usesStandardsFlatbuffers: REC.bufferHasIdentifier(
191
+ new flatbuffers.ByteBuffer(recordCollectionBytes),
192
+ ),
193
+ records,
194
+ };
195
+ }
196
+
197
+ function summarizeProtectedArtifact(protectedArtifact) {
198
+ const parsed = extractPublicationRecordCollection(
199
+ protectedArtifact.protectedArtifactBytes,
200
+ );
201
+ if (!parsed) {
202
+ throw new Error("Protected artifact is missing the REC publication trailer.");
203
+ }
204
+ const trailer = parseStandardsRec(parsed.recordCollectionBytes);
205
+ return {
206
+ artifactId: protectedArtifact.payload.artifactId,
207
+ encrypted: protectedArtifact.encrypted,
208
+ trailer,
209
+ recordStandards: trailer.recordStandards,
210
+ pnm: parsed.pnm
211
+ ? {
212
+ fileName: parsed.pnm.fileName ?? null,
213
+ fileId: parsed.pnm.fileId ?? null,
214
+ cid: parsed.pnm.cid ?? null,
215
+ hasSignature: Boolean(parsed.pnm.signature),
216
+ signatureType: parsed.pnm.signatureType ?? null,
217
+ publishTimestamp: parsed.pnm.publishTimestamp ?? null,
218
+ }
219
+ : null,
220
+ enc: parsed.enc
221
+ ? {
222
+ context: parsed.enc.context ?? null,
223
+ rootType: parsed.enc.rootType ?? null,
224
+ keyExchange: parsed.enc.keyExchange ?? null,
225
+ symmetric: parsed.enc.symmetric ?? null,
226
+ keyDerivation: parsed.enc.keyDerivation ?? null,
227
+ nonceLength: parsed.enc.nonceStart?.length ?? 0,
228
+ ephemeralPublicKeyLength: parsed.enc.ephemeralPublicKey?.length ?? 0,
229
+ }
230
+ : null,
231
+ envelope: protectedArtifact.encryptedEnvelope
232
+ ? {
233
+ scheme: protectedArtifact.encryptedEnvelope.scheme ?? null,
234
+ hasEncRecord: Boolean(
235
+ protectedArtifact.encryptedEnvelope.encRecordBase64,
236
+ ),
237
+ hasPnmRecord: Boolean(
238
+ protectedArtifact.encryptedEnvelope.pnmRecordBase64,
239
+ ),
240
+ }
241
+ : null,
242
+ };
243
+ }
244
+
245
+ export async function createPublicationProtectionDemoSummary(options = {}) {
246
+ const manifest = options.manifest ?? createPublicationProtectionDemoManifest();
247
+ const wasmBytes =
248
+ options.wasmBytes instanceof Uint8Array
249
+ ? options.wasmBytes
250
+ : MINIMAL_WASM_BYTES;
251
+ const recipient = options.recipient ?? (await createRecipientKeypairHex());
252
+ const signedOnly = await protectModuleArtifact({
253
+ manifest,
254
+ wasmBytes,
255
+ mnemonic: options.mnemonic ?? null,
256
+ });
257
+ const encryptedDelivery = await protectModuleArtifact({
258
+ manifest,
259
+ wasmBytes,
260
+ mnemonic: options.mnemonic ?? null,
261
+ recipientPublicKeyHex: recipient.publicKeyHex,
262
+ });
263
+
264
+ return {
265
+ manifest,
266
+ recTrailer: parseStandardsRec(signedOnly.publicationRecordsBytes),
267
+ alignedBinaryContract: summarizeAlignedBinaryContract(manifest),
268
+ signedOnly: summarizeProtectedArtifact(signedOnly),
269
+ encryptedDelivery: summarizeProtectedArtifact(encryptedDelivery),
270
+ };
271
+ }
@@ -0,0 +1,175 @@
1
+ import * as flatbuffers from "flatbuffers/mjs/flatbuffers.js";
2
+
3
+ import { DrainPolicy } from "../generated/orbpro/manifest/drain-policy.js";
4
+ import { TypedArenaBuffer } from "../generated/orbpro/stream/typed-arena-buffer.js";
5
+
6
+ function toByteBuffer(data) {
7
+ if (data instanceof flatbuffers.ByteBuffer) {
8
+ return data;
9
+ }
10
+ return new flatbuffers.ByteBuffer(data);
11
+ }
12
+
13
+ class StreamInvokeRequest {
14
+ constructor() {
15
+ this.bb = null;
16
+ this.bb_pos = 0;
17
+ }
18
+
19
+ __init(i, bb) {
20
+ this.bb_pos = i;
21
+ this.bb = bb;
22
+ return this;
23
+ }
24
+
25
+ static getRootAsStreamInvokeRequest(bb, obj) {
26
+ return (obj || new StreamInvokeRequest()).__init(
27
+ bb.readInt32(bb.position()) + bb.position(),
28
+ bb,
29
+ );
30
+ }
31
+
32
+ static startStreamInvokeRequest(builder) {
33
+ builder.startObject(4);
34
+ }
35
+
36
+ static addMethodId(builder, methodIdOffset) {
37
+ builder.addFieldOffset(0, methodIdOffset, 0);
38
+ }
39
+
40
+ static addInputs(builder, inputsOffset) {
41
+ builder.addFieldOffset(1, inputsOffset, 0);
42
+ }
43
+
44
+ static createInputsVector(builder, data) {
45
+ builder.startVector(4, data.length, 4);
46
+ for (let i = data.length - 1; i >= 0; i -= 1) {
47
+ builder.addOffset(data[i]);
48
+ }
49
+ return builder.endVector();
50
+ }
51
+
52
+ static addOutputStreamCap(builder, outputStreamCap) {
53
+ builder.addFieldInt32(2, outputStreamCap, 0);
54
+ }
55
+
56
+ static addDrainPolicy(builder, drainPolicy) {
57
+ builder.addFieldInt8(3, drainPolicy, DrainPolicy.DRAIN_UNTIL_YIELD);
58
+ }
59
+
60
+ static endStreamInvokeRequest(builder) {
61
+ const offset = builder.endObject();
62
+ builder.requiredField(offset, 4);
63
+ return offset;
64
+ }
65
+ }
66
+
67
+ class StreamInvokeRequestT {
68
+ constructor(
69
+ methodId = null,
70
+ inputs = [],
71
+ outputStreamCap = 0,
72
+ drainPolicy = DrainPolicy.DRAIN_UNTIL_YIELD,
73
+ ) {
74
+ this.methodId = methodId;
75
+ this.inputs = inputs;
76
+ this.outputStreamCap = outputStreamCap;
77
+ this.drainPolicy = drainPolicy;
78
+ }
79
+
80
+ pack(builder) {
81
+ const methodId =
82
+ this.methodId !== null ? builder.createString(this.methodId) : 0;
83
+ const inputs = StreamInvokeRequest.createInputsVector(
84
+ builder,
85
+ builder.createObjectOffsetList(this.inputs),
86
+ );
87
+ StreamInvokeRequest.startStreamInvokeRequest(builder);
88
+ StreamInvokeRequest.addMethodId(builder, methodId);
89
+ StreamInvokeRequest.addInputs(builder, inputs);
90
+ StreamInvokeRequest.addOutputStreamCap(builder, this.outputStreamCap);
91
+ StreamInvokeRequest.addDrainPolicy(builder, this.drainPolicy);
92
+ return StreamInvokeRequest.endStreamInvokeRequest(builder);
93
+ }
94
+ }
95
+
96
+ class StreamInvokeResponse {
97
+ constructor() {
98
+ this.bb = null;
99
+ this.bb_pos = 0;
100
+ }
101
+
102
+ __init(i, bb) {
103
+ this.bb_pos = i;
104
+ this.bb = bb;
105
+ return this;
106
+ }
107
+
108
+ static getRootAsStreamInvokeResponse(bb, obj) {
109
+ return (obj || new StreamInvokeResponse()).__init(
110
+ bb.readInt32(bb.position()) + bb.position(),
111
+ bb,
112
+ );
113
+ }
114
+
115
+ outputs(index, obj) {
116
+ const offset = this.bb.__offset(this.bb_pos, 4);
117
+ return offset
118
+ ? (obj || new TypedArenaBuffer()).__init(
119
+ this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4),
120
+ this.bb,
121
+ )
122
+ : null;
123
+ }
124
+
125
+ outputsLength() {
126
+ const offset = this.bb.__offset(this.bb_pos, 4);
127
+ return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
128
+ }
129
+
130
+ backlogRemaining() {
131
+ const offset = this.bb.__offset(this.bb_pos, 6);
132
+ return offset ? this.bb.readUint32(this.bb_pos + offset) : 0;
133
+ }
134
+
135
+ yielded() {
136
+ const offset = this.bb.__offset(this.bb_pos, 8);
137
+ return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false;
138
+ }
139
+
140
+ errorCode() {
141
+ const offset = this.bb.__offset(this.bb_pos, 10);
142
+ return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
143
+ }
144
+
145
+ errorMessage(optionalEncoding) {
146
+ const offset = this.bb.__offset(this.bb_pos, 12);
147
+ return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
148
+ }
149
+
150
+ unpack() {
151
+ return {
152
+ outputs: this.bb.createObjList(this.outputs.bind(this), this.outputsLength()),
153
+ backlogRemaining: this.backlogRemaining(),
154
+ yielded: this.yielded(),
155
+ errorCode: this.errorCode(),
156
+ errorMessage: this.errorMessage(),
157
+ };
158
+ }
159
+ }
160
+
161
+ export function encodeStreamInvokeRequest(request) {
162
+ const normalized =
163
+ request instanceof StreamInvokeRequestT
164
+ ? request
165
+ : Object.assign(new StreamInvokeRequestT(), request);
166
+ const builder = new flatbuffers.Builder(1024);
167
+ builder.finish(normalized.pack(builder));
168
+ return builder.asUint8Array();
169
+ }
170
+
171
+ export function decodeStreamInvokeResponse(data) {
172
+ return StreamInvokeResponse.getRootAsStreamInvokeResponse(
173
+ toByteBuffer(data),
174
+ ).unpack();
175
+ }
@@ -1,6 +1,12 @@
1
- import * as flatbuffers from "flatbuffers";
1
+ import * as flatbuffers from "flatbuffers/mjs/flatbuffers.js";
2
2
 
3
- import { ENC, ENCT, KDF, KeyExchange, SymmetricAlgo } from "spacedatastandards.org/lib/js/ENC/main.js";
3
+ import {
4
+ ENC,
5
+ ENCT,
6
+ KDF,
7
+ KeyExchange,
8
+ SymmetricAlgo,
9
+ } from "spacedatastandards.org/lib/js/ENC/main.js";
4
10
  import { PNM, PNMT } from "spacedatastandards.org/lib/js/PNM/main.js";
5
11
  import { REC, RECT } from "spacedatastandards.org/lib/js/REC/REC.js";
6
12
  import { Record, RecordT } from "spacedatastandards.org/lib/js/REC/Record.js";
@@ -75,6 +81,16 @@ function readUint16LE(buffer, offset, label) {
75
81
  return buffer[offset] | (buffer[offset + 1] << 8);
76
82
  }
77
83
 
84
+ function getRecordValueType(recordTable) {
85
+ if (typeof recordTable.valueType === "function") {
86
+ return recordTable.valueType();
87
+ }
88
+ if (typeof recordTable.value_type === "function") {
89
+ return recordTable.value_type();
90
+ }
91
+ throw new TypeError("REC record table does not expose a value type accessor.");
92
+ }
93
+
78
94
  function readUint32LE(buffer, offset, label) {
79
95
  assertBounds(buffer, offset, 4, label);
80
96
  return (
@@ -277,7 +293,27 @@ function validateEncTable(table, buffer, label) {
277
293
  maxLength: 32,
278
294
  });
279
295
  assertOptionalStringField(buffer, tableMeta, 22, `${label} root type`);
280
- const record = normalizeEncTable(table.unpack());
296
+ const timestamp = table.TIMESTAMP();
297
+ const record = {
298
+ version: Number(table.VERSION()),
299
+ keyExchange:
300
+ KEY_EXCHANGE_NAME_BY_VALUE[table.KEY_EXCHANGE()] ??
301
+ String(table.KEY_EXCHANGE()),
302
+ symmetric:
303
+ SYMMETRIC_ALGO_NAME_BY_VALUE[table.SYMMETRIC()] ??
304
+ String(table.SYMMETRIC()),
305
+ keyDerivation:
306
+ KDF_NAME_BY_VALUE[table.KEY_DERIVATION()] ??
307
+ String(table.KEY_DERIVATION()),
308
+ ephemeralPublicKey: normalizeByteField(table.ephemeralPublicKeyArray()),
309
+ nonceStart: normalizeByteField(table.nonceStartArray()),
310
+ recipientKeyId: normalizeByteField(table.recipientKeyIdArray()),
311
+ context: normalizeStringField(table.CONTEXT()),
312
+ schemaHash: normalizeByteField(table.schemaHashArray()),
313
+ rootType: normalizeStringField(table.ROOT_TYPE()),
314
+ timestamp:
315
+ timestamp === undefined || timestamp === null ? 0 : Number(timestamp),
316
+ };
281
317
  if (!record.ephemeralPublicKey?.length) {
282
318
  throw new Error(`${label} is missing the ephemeral public key.`);
283
319
  }
@@ -316,7 +352,17 @@ function validatePnmTable(table, buffer, label) {
316
352
  assertOptionalStringField(buffer, tableMeta, 16, `${label} timestamp signature`);
317
353
  assertOptionalStringField(buffer, tableMeta, 18, `${label} signature type`);
318
354
  assertOptionalStringField(buffer, tableMeta, 20, `${label} timestamp signature type`);
319
- const record = normalizePnmTable(table.unpack());
355
+ const record = {
356
+ multiformatAddress: normalizeStringField(table.MULTIFORMAT_ADDRESS()),
357
+ publishTimestamp: normalizeStringField(table.PUBLISH_TIMESTAMP()),
358
+ cid: normalizeStringField(table.CID()),
359
+ fileName: normalizeStringField(table.FILE_NAME()),
360
+ fileId: normalizeStringField(table.FILE_ID()),
361
+ signature: normalizeStringField(table.SIGNATURE()),
362
+ timestampSignature: normalizeStringField(table.TIMESTAMP_SIGNATURE()),
363
+ signatureType: normalizeStringField(table.SIGNATURE_TYPE()),
364
+ timestampSignatureType: normalizeStringField(table.TIMESTAMP_SIGNATURE_TYPE()),
365
+ };
320
366
  if (
321
367
  !record.multiformatAddress &&
322
368
  !record.publishTimestamp &&
@@ -426,48 +472,6 @@ function pnmTableFromObject(record = {}) {
426
472
  );
427
473
  }
428
474
 
429
- function normalizeEncTable(table) {
430
- if (!table) {
431
- return null;
432
- }
433
- return {
434
- version: Number(table.VERSION ?? 1),
435
- keyExchange:
436
- KEY_EXCHANGE_NAME_BY_VALUE[table.KEY_EXCHANGE] ?? String(table.KEY_EXCHANGE),
437
- symmetric:
438
- SYMMETRIC_ALGO_NAME_BY_VALUE[table.SYMMETRIC] ?? String(table.SYMMETRIC),
439
- keyDerivation:
440
- KDF_NAME_BY_VALUE[table.KEY_DERIVATION] ?? String(table.KEY_DERIVATION),
441
- ephemeralPublicKey: normalizeByteField(table.EPHEMERAL_PUBLIC_KEY),
442
- nonceStart: normalizeByteField(table.NONCE_START),
443
- recipientKeyId: normalizeByteField(table.RECIPIENT_KEY_ID),
444
- context: normalizeStringField(table.CONTEXT),
445
- schemaHash: normalizeByteField(table.SCHEMA_HASH),
446
- rootType: normalizeStringField(table.ROOT_TYPE),
447
- timestamp:
448
- table.TIMESTAMP === undefined || table.TIMESTAMP === null
449
- ? 0
450
- : Number(table.TIMESTAMP),
451
- };
452
- }
453
-
454
- function normalizePnmTable(table) {
455
- if (!table) {
456
- return null;
457
- }
458
- return {
459
- multiformatAddress: normalizeStringField(table.MULTIFORMAT_ADDRESS),
460
- publishTimestamp: normalizeStringField(table.PUBLISH_TIMESTAMP),
461
- cid: normalizeStringField(table.CID),
462
- fileName: normalizeStringField(table.FILE_NAME),
463
- fileId: normalizeStringField(table.FILE_ID),
464
- signature: normalizeStringField(table.SIGNATURE),
465
- timestampSignature: normalizeStringField(table.TIMESTAMP_SIGNATURE),
466
- signatureType: normalizeStringField(table.SIGNATURE_TYPE),
467
- timestampSignatureType: normalizeStringField(table.TIMESTAMP_SIGNATURE_TYPE),
468
- };
469
- }
470
-
471
475
  function readFooterLength(bytes) {
472
476
  const view = toUint8Array(bytes);
473
477
  if (view.length < TRAILER_FOOTER_LENGTH) {
@@ -601,7 +605,6 @@ export function decodePublicationRecordCollection(bytes) {
601
605
  if (recordTables.length === 0) {
602
606
  throw new Error("REC trailer does not contain any records.");
603
607
  }
604
- const collection = collectionTable.unpack();
605
608
  const records = [];
606
609
  let enc = null;
607
610
  let pnm = null;
@@ -622,10 +625,9 @@ export function decodePublicationRecordCollection(bytes) {
622
625
  8,
623
626
  `REC trailer record ${index} standard`,
624
627
  );
625
- const unpackedRecord = collection.RECORDS[index];
626
- const recordType = recordTable.value_type();
628
+ const recordType = getRecordValueType(recordTable);
627
629
  const standard =
628
- normalizeStringField(unpackedRecord?.standard) ??
630
+ normalizeStringField(recordTable.standard()) ??
629
631
  STANDARD_BY_RECORD_TYPE[recordType] ??
630
632
  null;
631
633
  const expectedStandard =
@@ -644,10 +646,7 @@ export function decodePublicationRecordCollection(bytes) {
644
646
  if (!valueMeta) {
645
647
  throw new Error(`REC trailer record ${index} is missing a value.`);
646
648
  }
647
- let value =
648
- standard === "ENC" || standard === "PNM"
649
- ? null
650
- : unpackedRecord?.value ?? null;
649
+ let value = null;
651
650
  if (standard === "ENC") {
652
651
  const encTable = recordTable.value(new ENC());
653
652
  if (!encTable) {
@@ -684,7 +683,9 @@ export function decodePublicationRecordCollection(bytes) {
684
683
  });
685
684
  }
686
685
  return {
687
- version: normalizeStringField(collection.version) ?? DEFAULT_RECORD_COLLECTION_VERSION,
686
+ version:
687
+ normalizeStringField(collectionTable.version()) ??
688
+ DEFAULT_RECORD_COLLECTION_VERSION,
688
689
  records,
689
690
  enc,
690
691
  pnm,