@klum-db/lobby 0.2.0-pre.26 → 0.2.0-pre.27

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/dist/index.cjs CHANGED
@@ -30,6 +30,182 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // src/bundle/uint32.ts
34
+ function readUint32BE(bytes, offset) {
35
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
36
+ }
37
+ function writeUint32BE(bytes, offset, value) {
38
+ bytes[offset] = value >>> 24 & 255;
39
+ bytes[offset + 1] = value >>> 16 & 255;
40
+ bytes[offset + 2] = value >>> 8 & 255;
41
+ bytes[offset + 3] = value & 255;
42
+ }
43
+ var init_uint32 = __esm({
44
+ "src/bundle/uint32.ts"() {
45
+ "use strict";
46
+ }
47
+ });
48
+
49
+ // src/bundle/multi-bundle.ts
50
+ function encodeMultiBundle(manifest, inner) {
51
+ validateManifest(manifest);
52
+ if (manifest.compartments.length !== inner.length) {
53
+ throw new Error(`multi-bundle: manifest has ${manifest.compartments.length} compartments but ${inner.length} inner bundles were provided.`);
54
+ }
55
+ for (let i = 0; i < inner.length; i++) {
56
+ if (manifest.compartments[i].innerBytes !== inner[i].length) {
57
+ throw new Error(`multi-bundle: compartment ${i} declares innerBytes ${manifest.compartments[i].innerBytes} but ${inner[i].length} bytes were provided.`);
58
+ }
59
+ }
60
+ const manifestBytes = new TextEncoder().encode(JSON.stringify(manifest));
61
+ const bodyLen = inner.reduce((n, b) => n + b.length, 0);
62
+ const out = new Uint8Array(NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length + bodyLen);
63
+ out.set(NOYDB_MULTI_BUNDLE_MAGIC, 0);
64
+ out[4] = NOYDB_MULTI_BUNDLE_VERSION;
65
+ out[5] = 0;
66
+ writeUint32BE(out, 6, manifestBytes.length);
67
+ out.set(manifestBytes, NOYDB_MULTI_BUNDLE_PREFIX_BYTES);
68
+ let off = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length;
69
+ for (const b of inner) {
70
+ out.set(b, off);
71
+ off += b.length;
72
+ }
73
+ return out;
74
+ }
75
+ function hasMultiMagic(bytes) {
76
+ if (bytes.length < NOYDB_MULTI_BUNDLE_MAGIC.length) return false;
77
+ for (let i = 0; i < NOYDB_MULTI_BUNDLE_MAGIC.length; i++) if (bytes[i] !== NOYDB_MULTI_BUNDLE_MAGIC[i]) return false;
78
+ return true;
79
+ }
80
+ function validateManifest(parsed) {
81
+ if (parsed === null || typeof parsed !== "object") throw new Error("multi-bundle manifest must be a JSON object.");
82
+ const m = parsed;
83
+ if (m["multiFormatVersion"] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`multi-bundle manifest.multiFormatVersion must be ${NOYDB_MULTI_BUNDLE_VERSION}, got ${String(m["multiFormatVersion"])}.`);
84
+ if (typeof m["handle"] !== "string" || m["handle"].length === 0) throw new Error("multi-bundle manifest.handle must be a non-empty string.");
85
+ if (!Array.isArray(m["compartments"])) throw new Error("multi-bundle manifest.compartments must be an array.");
86
+ const seenHandles = /* @__PURE__ */ new Set();
87
+ for (const c of m["compartments"]) {
88
+ if (c === null || typeof c !== "object") throw new Error("multi-bundle compartment must be an object.");
89
+ const e = c;
90
+ if (typeof e["handle"] !== "string" || e["handle"].length === 0) throw new Error("multi-bundle compartment.handle must be a non-empty string.");
91
+ if (seenHandles.has(e["handle"])) {
92
+ throw new Error(`multi-bundle manifest has a duplicate compartment handle "${e["handle"]}".`);
93
+ }
94
+ seenHandles.add(e["handle"]);
95
+ if (typeof e["innerBytes"] !== "number" || !Number.isInteger(e["innerBytes"]) || e["innerBytes"] < 0) throw new Error("multi-bundle compartment.innerBytes must be a non-negative integer.");
96
+ if (typeof e["innerSha256"] !== "string" || !/^[0-9a-f]{64}$/.test(e["innerSha256"])) throw new Error("multi-bundle compartment.innerSha256 must be 64-char lowercase hex.");
97
+ }
98
+ }
99
+ function decodeMultiBundle(bytes) {
100
+ if (!hasMultiMagic(bytes)) throw new Error("not a NOYDB multi-bundle: missing NDBM magic.");
101
+ if (bytes.length < NOYDB_MULTI_BUNDLE_PREFIX_BYTES) throw new Error("multi-bundle truncated: shorter than the fixed prefix.");
102
+ if (bytes[4] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`unsupported multi-bundle version ${String(bytes[4])}.`);
103
+ const manifestLen = readUint32BE(bytes, 6);
104
+ const manifestEnd = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestLen;
105
+ if (manifestEnd > bytes.length) throw new Error("multi-bundle truncated: manifest length overruns the buffer.");
106
+ const manifestJson = new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(NOYDB_MULTI_BUNDLE_PREFIX_BYTES, manifestEnd));
107
+ let parsed;
108
+ try {
109
+ parsed = JSON.parse(manifestJson);
110
+ } catch (err) {
111
+ throw new Error(`multi-bundle manifest is not valid JSON: ${err.message}`);
112
+ }
113
+ validateManifest(parsed);
114
+ const inner = [];
115
+ let off = manifestEnd;
116
+ for (const c of parsed.compartments) {
117
+ const end = off + c.innerBytes;
118
+ if (end > bytes.length) throw new Error(`multi-bundle truncated: compartment "${c.handle}" innerBytes overruns the buffer.`);
119
+ inner.push(bytes.subarray(off, end));
120
+ off = end;
121
+ }
122
+ if (off !== bytes.length) {
123
+ throw new Error(`multi-bundle: ${bytes.length - off} trailing byte(s) after the last compartment \u2014 buffer may be corrupt.`);
124
+ }
125
+ return { manifest: parsed, inner };
126
+ }
127
+ async function writeMultiVaultBundle(compartments, opts = {}) {
128
+ if (compartments.length === 0) throw new Error("writeMultiVaultBundle: at least one compartment is required.");
129
+ const inner = [];
130
+ const entries = [];
131
+ for (const c of compartments) {
132
+ const innerBytes = await (0, import_bundle.writeNoydbBundle)(c.vault, c.bundleOptions ?? {});
133
+ const header = (0, import_bundle.readNoydbBundleHeader)(innerBytes);
134
+ const entry = {
135
+ handle: header.handle,
136
+ exportedAt: c.exportedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
137
+ innerBytes: innerBytes.length,
138
+ innerSha256: await (0, import_kernel.sha256Hex)(innerBytes)
139
+ };
140
+ if (c.roleTag !== void 0) entry.roleTag = c.roleTag;
141
+ if (c.disclose?.name !== void 0 && c.disclose.name !== false) {
142
+ entry.name = c.disclose.name === true ? c.vault.name : c.disclose.name;
143
+ }
144
+ if (c.disclose?.collections === true) {
145
+ const names = await c.vault.collections();
146
+ entry.collections = await Promise.all(
147
+ names.map(async (n) => ({ name: n, count: await c.vault.collection(n).count() }))
148
+ );
149
+ }
150
+ if (c.disclose?.publicEnvelope === true) {
151
+ const env = (0, import_hub.readNoydbBundlePublicEnvelope)(innerBytes);
152
+ if (env !== void 0) entry.publicEnvelope = env;
153
+ }
154
+ const fence = await c.vault.schemaFenceState();
155
+ entry.schemaVersion = fence.currentSchemaVersion;
156
+ inner.push(innerBytes);
157
+ entries.push(entry);
158
+ }
159
+ const manifest = {
160
+ multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,
161
+ handle: opts.handle ?? (0, import_kernel.generateULID)(),
162
+ compartments: entries
163
+ };
164
+ return encodeMultiBundle(manifest, inner);
165
+ }
166
+ async function readNoydbBundleManifest(bytes) {
167
+ if (hasMultiMagic(bytes)) return [...decodeMultiBundle(bytes).manifest.compartments];
168
+ if ((0, import_hub.hasNoydbBundleMagic)(bytes)) {
169
+ const header = (0, import_bundle.readNoydbBundleHeader)(bytes);
170
+ const env = (0, import_hub.readNoydbBundlePublicEnvelope)(bytes);
171
+ const entry = {
172
+ handle: header.handle,
173
+ innerBytes: bytes.length,
174
+ innerSha256: await (0, import_kernel.sha256Hex)(bytes)
175
+ };
176
+ if (env !== void 0) entry.publicEnvelope = env;
177
+ return [entry];
178
+ }
179
+ throw new Error("readNoydbBundleManifest: not a NOYDB bundle (no NDB1 or NDBM magic).");
180
+ }
181
+ function readMultiVaultBundleCompartment(bytes, selector) {
182
+ if (typeof selector === "number" && !Number.isInteger(selector)) {
183
+ throw new Error(`readMultiVaultBundleCompartment: numeric selector must be an integer, got ${selector}.`);
184
+ }
185
+ if ((0, import_hub.hasNoydbBundleMagic)(bytes) && !hasMultiMagic(bytes)) {
186
+ const header = (0, import_bundle.readNoydbBundleHeader)(bytes);
187
+ if (selector === 0 || selector === header.handle) return bytes;
188
+ throw new Error(`readMultiVaultBundleCompartment: single v1 bundle has only compartment "${header.handle}".`);
189
+ }
190
+ const { manifest, inner } = decodeMultiBundle(bytes);
191
+ const idx = typeof selector === "number" ? selector : manifest.compartments.findIndex((c) => c.handle === selector);
192
+ if (idx < 0 || idx >= inner.length) throw new Error(`readMultiVaultBundleCompartment: no compartment ${typeof selector === "number" ? `at index ${selector}` : `"${selector}"`}.`);
193
+ return inner[idx];
194
+ }
195
+ var import_kernel, import_bundle, import_hub, NOYDB_MULTI_BUNDLE_MAGIC, NOYDB_MULTI_BUNDLE_PREFIX_BYTES, NOYDB_MULTI_BUNDLE_VERSION;
196
+ var init_multi_bundle = __esm({
197
+ "src/bundle/multi-bundle.ts"() {
198
+ "use strict";
199
+ import_kernel = require("@noy-db/hub/kernel");
200
+ import_bundle = require("@noy-db/hub/bundle");
201
+ import_hub = require("@noy-db/hub");
202
+ init_uint32();
203
+ NOYDB_MULTI_BUNDLE_MAGIC = new Uint8Array([78, 68, 66, 77]);
204
+ NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10;
205
+ NOYDB_MULTI_BUNDLE_VERSION = 1;
206
+ }
207
+ });
208
+
33
209
  // src/interchange/extract-cross-vault.ts
34
210
  var extract_cross_vault_exports = {};
35
211
  __export(extract_cross_vault_exports, {
@@ -95,7 +271,7 @@ async function walkCrossVaultClosure(openVault, opts) {
95
271
  for (const vaultName of batch) {
96
272
  const seeds = perVaultSeeds.get(vaultName);
97
273
  const v = await openVault(vaultName);
98
- const { closure } = await (0, import_bundle.walkClosure)(v, {
274
+ const { closure } = await (0, import_bundle2.walkClosure)(v, {
99
275
  seeds,
100
276
  ...opts.maxDepth !== void 0 ? { maxDepth: opts.maxDepth } : {}
101
277
  });
@@ -147,20 +323,20 @@ async function extractCrossVaultPartition(openVault, opts) {
147
323
  const sealIds = {};
148
324
  for (const [vaultName, seeds] of plan.perVaultSeeds) {
149
325
  const v = await openVault(vaultName);
150
- const { bundleBytes, transferKey, sealId } = await (0, import_bundle.extractPartition)(v, {
326
+ const { bundleBytes, transferKey, sealId } = await (0, import_bundle2.extractPartition)(v, {
151
327
  seeds,
152
328
  ...opts.maxDepth !== void 0 ? { maxDepth: opts.maxDepth } : {},
153
329
  carrySchemas: opts.carrySchemas ?? true,
154
330
  carryLedger: opts.carryLedger ?? false,
155
331
  ...opts.compression !== void 0 ? { compression: opts.compression } : {}
156
332
  });
157
- const header = (0, import_bundle.readNoydbBundleHeader)(bundleBytes);
333
+ const header = (0, import_bundle2.readNoydbBundleHeader)(bundleBytes);
158
334
  const meta = opts.compartmentMeta?.[vaultName];
159
335
  const entry = {
160
336
  handle: header.handle,
161
337
  exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
162
338
  innerBytes: bundleBytes.length,
163
- innerSha256: await (0, import_kernel.sha256Hex)(bundleBytes)
339
+ innerSha256: await (0, import_kernel2.sha256Hex)(bundleBytes)
164
340
  };
165
341
  if (meta?.roleTag !== void 0) entry.roleTag = meta.roleTag;
166
342
  if (meta?.disclose?.name !== void 0 && meta.disclose.name !== false) {
@@ -178,18 +354,18 @@ async function extractCrossVaultPartition(openVault, opts) {
178
354
  sealIds[vaultName] = sealId;
179
355
  }
180
356
  const manifest = {
181
- multiFormatVersion: import_bundle.NOYDB_MULTI_BUNDLE_VERSION,
182
- handle: (0, import_bundle.generateULID)(),
357
+ multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,
358
+ handle: (0, import_kernel2.generateULID)(),
183
359
  compartments
184
360
  };
185
- return { bundle: (0, import_bundle.encodeMultiBundle)(manifest, inner), transferKeys, sealIds };
361
+ return { bundle: encodeMultiBundle(manifest, inner), transferKeys, sealIds };
186
362
  }
187
363
  async function describeCrossVaultExtraction(openVault, opts) {
188
364
  const plan = await walkCrossVaultClosure(openVault, opts);
189
365
  const compartments = [];
190
366
  for (const [vaultName, seeds] of plan.perVaultSeeds) {
191
367
  const v = await openVault(vaultName);
192
- const preview = await (0, import_bundle.describeExtraction)(v, {
368
+ const preview = await (0, import_bundle2.describeExtraction)(v, {
193
369
  seeds,
194
370
  ...opts.maxDepth !== void 0 ? { maxDepth: opts.maxDepth } : {}
195
371
  });
@@ -197,12 +373,13 @@ async function describeCrossVaultExtraction(openVault, opts) {
197
373
  }
198
374
  return { compartments, dangling: plan.dangling };
199
375
  }
200
- var import_bundle, import_kernel, CrossVaultDanglingRefError;
376
+ var import_bundle2, import_kernel2, CrossVaultDanglingRefError;
201
377
  var init_extract_cross_vault = __esm({
202
378
  "src/interchange/extract-cross-vault.ts"() {
203
379
  "use strict";
204
- import_bundle = require("@noy-db/hub/bundle");
205
- import_kernel = require("@noy-db/hub/kernel");
380
+ import_bundle2 = require("@noy-db/hub/bundle");
381
+ import_kernel2 = require("@noy-db/hub/kernel");
382
+ init_multi_bundle();
206
383
  CrossVaultDanglingRefError = class extends Error {
207
384
  constructor(dangling) {
208
385
  super(
@@ -287,7 +464,7 @@ async function mergeDecryptedRecords(receiver, decrypted, opts) {
287
464
  incomingSource.set(coll, srcMap);
288
465
  incomingSourceTs.set(coll, stsMap);
289
466
  }
290
- const diff = await (0, import_hub.diffVault)(receiver, candidate);
467
+ const diff = await (0, import_hub2.diffVault)(receiver, candidate);
291
468
  const byCollection = {};
292
469
  const conflicts = [];
293
470
  const writes = [];
@@ -403,15 +580,15 @@ async function mergeDecryptedRecords(receiver, decrypted, opts) {
403
580
  };
404
581
  }
405
582
  async function mergeCompartment(receiver, compartmentBytes, opts) {
406
- const incoming = await (0, import_bundle2.decryptExtractedPartition)(compartmentBytes, opts.transferKey);
583
+ const incoming = await (0, import_bundle3.decryptExtractedPartition)(compartmentBytes, opts.transferKey);
407
584
  return mergeDecryptedRecords(receiver, incoming, opts);
408
585
  }
409
- var import_hub, import_bundle2, FieldLevelDeferredError;
586
+ var import_hub2, import_bundle3, FieldLevelDeferredError;
410
587
  var init_merge_compartment = __esm({
411
588
  "src/interchange/merge-compartment.ts"() {
412
589
  "use strict";
413
- import_hub = require("@noy-db/hub");
414
- import_bundle2 = require("@noy-db/hub/bundle");
590
+ import_hub2 = require("@noy-db/hub");
591
+ import_bundle3 = require("@noy-db/hub/bundle");
415
592
  init_field_authority();
416
593
  FieldLevelDeferredError = class extends Error {
417
594
  constructor(collection) {
@@ -507,7 +684,7 @@ async function graduate(noydb, docked, opts) {
507
684
  await mergeDecryptedRecords(vault, staged, { strategy: "take-incoming", reason: "dock:graduate" });
508
685
  let deedSealed = false;
509
686
  if (opts.deed) {
510
- await (0, import_hub2.createDeedOwner)(noydb._store, opts.vaultName, opts.deed.ownerId, opts.deed.sealingProvider);
687
+ await (0, import_hub3.createDeedOwner)(noydb._store, opts.vaultName, opts.deed.ownerId, opts.deed.sealingProvider);
511
688
  deedSealed = true;
512
689
  }
513
690
  if (opts.stateVault) {
@@ -527,11 +704,11 @@ async function graduate(noydb, docked, opts) {
527
704
  event: { type: "unit-graduated", unitId: docked.unitId, vault: opts.vaultName }
528
705
  };
529
706
  }
530
- var import_hub2, UnitGraduationError, ISO_EPOCH;
707
+ var import_hub3, UnitGraduationError, ISO_EPOCH;
531
708
  var init_graduate = __esm({
532
709
  "src/dock/graduate.ts"() {
533
710
  "use strict";
534
- import_hub2 = require("@noy-db/hub");
711
+ import_hub3 = require("@noy-db/hub");
535
712
  init_merge_compartment();
536
713
  init_stage_records();
537
714
  UnitGraduationError = class extends Error {
@@ -561,7 +738,7 @@ __export(surface_exports, {
561
738
  async function proposeSurface(smv, def, proposedBy, now) {
562
739
  const row = {
563
740
  ...def,
564
- id: def.id ?? (0, import_kernel2.generateULID)(),
741
+ id: def.id ?? (0, import_kernel3.generateULID)(),
565
742
  status: "proposed",
566
743
  proposedBy,
567
744
  createdAt: now
@@ -582,7 +759,7 @@ async function exportSurface(source, surface) {
582
759
  throw new SurfaceStateError(surface.id, surface.status, "agreed");
583
760
  }
584
761
  const seeds = Object.fromEntries(surface.collections.map((c) => [c, () => true]));
585
- const { bundleBytes, transferKey } = await (0, import_bundle4.extractPartition)(source, {
762
+ const { bundleBytes, transferKey } = await (0, import_bundle5.extractPartition)(source, {
586
763
  seeds,
587
764
  maxDepth: 0,
588
765
  ...surface.fields ? { fieldProjection: surface.fields } : {},
@@ -620,12 +797,12 @@ async function markSynced(smv, id, now) {
620
797
  nextSyncDueAt: now + cadenceMs
621
798
  });
622
799
  }
623
- var import_kernel2, import_bundle4, SurfaceNotFoundError, SurfaceStateError, SurfaceCadenceScheduler;
800
+ var import_kernel3, import_bundle5, SurfaceNotFoundError, SurfaceStateError, SurfaceCadenceScheduler;
624
801
  var init_surface = __esm({
625
802
  "src/interchange/surface.ts"() {
626
803
  "use strict";
627
- import_kernel2 = require("@noy-db/hub/kernel");
628
- import_bundle4 = require("@noy-db/hub/bundle");
804
+ import_kernel3 = require("@noy-db/hub/kernel");
805
+ import_bundle5 = require("@noy-db/hub/bundle");
629
806
  init_merge_compartment();
630
807
  SurfaceNotFoundError = class extends Error {
631
808
  name = "SurfaceNotFoundError";
@@ -730,38 +907,38 @@ function canonical(value) {
730
907
  return `{${keys.map((k) => `${JSON.stringify(k)}:${canonical(obj[k])}`).join(",")}}`;
731
908
  }
732
909
  async function fingerprintBlueprint(bp) {
733
- return (0, import_kernel3.sha256Hex)(new TextEncoder().encode(canonical(bp)));
910
+ return (0, import_kernel4.sha256Hex)(new TextEncoder().encode(canonical(bp)));
734
911
  }
735
- var import_kernel3;
912
+ var import_kernel4;
736
913
  var init_schema_manifest = __esm({
737
914
  "src/federation/schema-manifest.ts"() {
738
915
  "use strict";
739
- import_kernel3 = require("@noy-db/hub/kernel");
916
+ import_kernel4 = require("@noy-db/hub/kernel");
740
917
  }
741
918
  });
742
919
 
743
920
  // src/federation/constants.ts
744
- var import_hub3;
921
+ var import_hub4;
745
922
  var init_constants = __esm({
746
923
  "src/federation/constants.ts"() {
747
924
  "use strict";
748
- import_hub3 = require("@noy-db/hub");
925
+ import_hub4 = require("@noy-db/hub");
749
926
  }
750
927
  });
751
928
 
752
929
  // src/federation/state-vault.ts
753
930
  var state_vault_exports = {};
754
931
  __export(state_vault_exports, {
755
- STATE_VAULT_NAME: () => import_hub3.STATE_VAULT_NAME,
932
+ STATE_VAULT_NAME: () => import_hub4.STATE_VAULT_NAME,
756
933
  StateManagementVault: () => StateManagementVault
757
934
  });
758
- var import_kernel4, REGISTRY, MANIFEST, EVENTS, MIGRATION_STATUS, SURFACES, StateManagementVault;
935
+ var import_kernel5, REGISTRY, MANIFEST, EVENTS, MIGRATION_STATUS, SURFACES, StateManagementVault;
759
936
  var init_state_vault = __esm({
760
937
  "src/federation/state-vault.ts"() {
761
938
  "use strict";
762
939
  init_schema_manifest();
763
940
  init_constants();
764
- import_kernel4 = require("@noy-db/hub/kernel");
941
+ import_kernel5 = require("@noy-db/hub/kernel");
765
942
  init_constants();
766
943
  REGISTRY = "vaultRegistry";
767
944
  MANIFEST = "schemaManifest";
@@ -791,7 +968,7 @@ var init_state_vault = __esm({
791
968
  #surfaces;
792
969
  /** Idempotently open the reserved state vault and bind the control-plane collections. */
793
970
  static async open(db) {
794
- const vault = await db.openVault(import_hub3.STATE_VAULT_NAME);
971
+ const vault = await db.openVault(import_hub4.STATE_VAULT_NAME);
795
972
  return new _StateManagementVault(
796
973
  vault.collection(REGISTRY),
797
974
  vault.collection(MANIFEST),
@@ -851,7 +1028,7 @@ var init_state_vault = __esm({
851
1028
  */
852
1029
  async appendEvent(event) {
853
1030
  const ts = event.ts ?? Date.now();
854
- const id = (0, import_kernel4.generateULID)();
1031
+ const id = (0, import_kernel5.generateULID)();
855
1032
  await this.#events.put(id, { ...event, id, ts });
856
1033
  }
857
1034
  /**
@@ -893,13 +1070,13 @@ var init_state_vault = __esm({
893
1070
 
894
1071
  // src/federation/classify-skip.ts
895
1072
  function classifyShardSkip(err) {
896
- return err instanceof import_kernel5.NoAccessError ? "no-grant" : "error";
1073
+ return err instanceof import_kernel6.NoAccessError ? "no-grant" : "error";
897
1074
  }
898
- var import_kernel5;
1075
+ var import_kernel6;
899
1076
  var init_classify_skip = __esm({
900
1077
  "src/federation/classify-skip.ts"() {
901
1078
  "use strict";
902
- import_kernel5 = require("@noy-db/hub/kernel");
1079
+ import_kernel6 = require("@noy-db/hub/kernel");
903
1080
  }
904
1081
  });
905
1082
 
@@ -924,7 +1101,7 @@ async function applyBroadcastLegs(rows, legs) {
924
1101
  for (const leg of legs) {
925
1102
  const map = /* @__PURE__ */ new Map();
926
1103
  for (const rec of await leg.from.list()) {
927
- const k = coerceKey((0, import_kernel6.readPath)(rec, leg.on));
1104
+ const k = coerceKey((0, import_kernel7.readPath)(rec, leg.on));
928
1105
  if (k !== null && !map.has(k)) map.set(k, rec);
929
1106
  }
930
1107
  indexes.push({ leg, map });
@@ -932,7 +1109,7 @@ async function applyBroadcastLegs(rows, legs) {
932
1109
  return rows.map((row) => {
933
1110
  const out = { ...row };
934
1111
  for (const { leg, map } of indexes) {
935
- const key = coerceKey((0, import_kernel6.readPath)(row, leg.field));
1112
+ const key = coerceKey((0, import_kernel7.readPath)(row, leg.field));
936
1113
  const match = key === null ? null : map.get(key) ?? null;
937
1114
  if (match === null && leg.mode === "warn") {
938
1115
  warnOnceBroadcastMiss(leg.field, leg.as, key ?? "<null>");
@@ -942,11 +1119,11 @@ async function applyBroadcastLegs(rows, legs) {
942
1119
  return out;
943
1120
  });
944
1121
  }
945
- var import_kernel6, warnedBroadcastKeys;
1122
+ var import_kernel7, warnedBroadcastKeys;
946
1123
  var init_cross_shard_join = __esm({
947
1124
  "src/federation/cross-shard-join.ts"() {
948
1125
  "use strict";
949
- import_kernel6 = require("@noy-db/hub/kernel");
1126
+ import_kernel7 = require("@noy-db/hub/kernel");
950
1127
  warnedBroadcastKeys = /* @__PURE__ */ new Set();
951
1128
  }
952
1129
  });
@@ -1092,12 +1269,12 @@ var init_insight_auto_push = __esm({
1092
1269
  });
1093
1270
 
1094
1271
  // src/federation/aggregate-across.ts
1095
- var import_kernel7, import_kernel8, CrossVaultAggregation, CrossVaultGroupedAggregation;
1272
+ var import_kernel8, import_kernel9, CrossVaultAggregation, CrossVaultGroupedAggregation;
1096
1273
  var init_aggregate_across = __esm({
1097
1274
  "src/federation/aggregate-across.ts"() {
1098
1275
  "use strict";
1099
- import_kernel7 = require("@noy-db/hub/kernel");
1100
1276
  import_kernel8 = require("@noy-db/hub/kernel");
1277
+ import_kernel9 = require("@noy-db/hub/kernel");
1101
1278
  init_cross_vault_live();
1102
1279
  CrossVaultAggregation = class {
1103
1280
  constructor(src, spec, bind) {
@@ -1110,7 +1287,7 @@ var init_aggregate_across = __esm({
1110
1287
  bind;
1111
1288
  async run(options = {}) {
1112
1289
  const { records, skippedVaults } = await this.src.fanoutRecords(options);
1113
- return { result: (0, import_kernel7.reduceRecords)(records, this.spec), skippedVaults };
1290
+ return { result: (0, import_kernel8.reduceRecords)(records, this.spec), skippedVaults };
1114
1291
  }
1115
1292
  live(options = {}) {
1116
1293
  if (!this.bind) throw new Error("CrossVaultAggregation: live() requires a LiveBinding \u2014 use ShardedQuery.aggregate()");
@@ -1121,7 +1298,7 @@ var init_aggregate_across = __esm({
1121
1298
  isRelevant: this.bind.isRelevant,
1122
1299
  compute: async () => {
1123
1300
  const { records, skippedVaults } = await src.fanoutRecords(options);
1124
- return { value: (0, import_kernel7.reduceRecords)(records, spec), skipped: skippedVaults };
1301
+ return { value: (0, import_kernel8.reduceRecords)(records, spec), skipped: skippedVaults };
1125
1302
  },
1126
1303
  initialSnapshot: { value: void 0, skipped: [] },
1127
1304
  ...options.debounceMs !== void 0 ? { debounceMs: options.debounceMs } : {}
@@ -1156,7 +1333,7 @@ var init_aggregate_across = __esm({
1156
1333
  async run(options = {}) {
1157
1334
  const { records, skippedVaults } = await this.src.fanoutRecords(options);
1158
1335
  return {
1159
- results: (0, import_kernel8.groupAndReduce)(records, this.field, this.spec),
1336
+ results: (0, import_kernel9.groupAndReduce)(records, this.field, this.spec),
1160
1337
  skippedVaults
1161
1338
  };
1162
1339
  }
@@ -1171,7 +1348,7 @@ var init_aggregate_across = __esm({
1171
1348
  compute: async () => {
1172
1349
  const { records, skippedVaults } = await src.fanoutRecords(options);
1173
1350
  return {
1174
- records: (0, import_kernel8.groupAndReduce)(records, field, spec),
1351
+ records: (0, import_kernel9.groupAndReduce)(records, field, spec),
1175
1352
  skipped: skippedVaults
1176
1353
  };
1177
1354
  },
@@ -1207,28 +1384,28 @@ __export(vault_group_exports, {
1207
1384
  });
1208
1385
  function assertSafePartitionKey(partitionKey) {
1209
1386
  if (partitionKey.length === 0) {
1210
- throw new import_kernel9.ValidationError("partitionKey must be a non-empty string");
1387
+ throw new import_kernel10.ValidationError("partitionKey must be a non-empty string");
1211
1388
  }
1212
- if (partitionKey === import_hub3.STATE_VAULT_NAME) {
1213
- throw new import_kernel9.ReservedVaultNameError(partitionKey);
1389
+ if (partitionKey === import_hub4.STATE_VAULT_NAME) {
1390
+ throw new import_kernel10.ReservedVaultNameError(partitionKey);
1214
1391
  }
1215
1392
  if (!SAFE_PARTITION_KEY.test(partitionKey)) {
1216
- throw new import_kernel9.ValidationError(
1393
+ throw new import_kernel10.ValidationError(
1217
1394
  `partitionKey "${partitionKey}" contains characters outside [A-Za-z0-9._-]. Map your records to a store-safe key in sharding.keyOf.`
1218
1395
  );
1219
1396
  }
1220
1397
  if (partitionKey.includes(SHARD_SEPARATOR)) {
1221
- throw new import_kernel9.ValidationError(
1398
+ throw new import_kernel10.ValidationError(
1222
1399
  `partitionKey "${partitionKey}" must not contain "--" \u2014 it is reserved as the shard vault-id separator and would risk shard-id collisions.`
1223
1400
  );
1224
1401
  }
1225
1402
  }
1226
- var import_kernel9, SHARD_SEPARATOR, SAFE_PARTITION_KEY, VaultGroup, ShardedCollection, ShardedQuery, ShardedGroupedQuery;
1403
+ var import_kernel10, SHARD_SEPARATOR, SAFE_PARTITION_KEY, VaultGroup, ShardedCollection, ShardedQuery, ShardedGroupedQuery;
1227
1404
  var init_vault_group = __esm({
1228
1405
  "src/federation/vault-group.ts"() {
1229
1406
  "use strict";
1230
1407
  init_state_vault();
1231
- import_kernel9 = require("@noy-db/hub/kernel");
1408
+ import_kernel10 = require("@noy-db/hub/kernel");
1232
1409
  init_constants();
1233
1410
  init_classify_skip();
1234
1411
  init_cross_shard_join();
@@ -1246,7 +1423,7 @@ var init_vault_group = __esm({
1246
1423
  this.template = template;
1247
1424
  this.migrateOnOpen = migrateOnOpen;
1248
1425
  if (name.includes(SHARD_SEPARATOR)) {
1249
- throw new import_kernel9.ValidationError(
1426
+ throw new import_kernel10.ValidationError(
1250
1427
  `VaultGroup name "${name}" must not contain "--" (reserved shard vault-id separator).`
1251
1428
  );
1252
1429
  }
@@ -1326,11 +1503,11 @@ var init_vault_group = __esm({
1326
1503
  const vaultId = this.shardVaultId(partitionKey);
1327
1504
  const row = await this.registry.get(this.registryId(partitionKey));
1328
1505
  const provisioned = await this.db._shardVaultProvisioned(vaultId);
1329
- if (row && !provisioned) throw new import_kernel9.ShardProvisioningError(vaultId, partitionKey);
1506
+ if (row && !provisioned) throw new import_kernel10.ShardProvisioningError(vaultId, partitionKey);
1330
1507
  if (row && provisioned) return this.openShard(partitionKey);
1331
1508
  if (region !== void 0) {
1332
1509
  const backendRegion = this.db._resolveBackend(vaultId).capabilities?.region;
1333
- if (backendRegion !== region) throw new import_kernel9.DataResidencyError(vaultId, region, backendRegion);
1510
+ if (backendRegion !== region) throw new import_kernel10.DataResidencyError(vaultId, region, backendRegion);
1334
1511
  }
1335
1512
  const vault = await this.db.openVault(vaultId);
1336
1513
  this.template.configure(vault);
@@ -1364,9 +1541,9 @@ var init_vault_group = __esm({
1364
1541
  async shard(partitionKey) {
1365
1542
  const vaultId = this.shardVaultId(partitionKey);
1366
1543
  const row = await this.registry.get(this.registryId(partitionKey));
1367
- if (!row) throw new import_kernel9.UnknownShardError(partitionKey, this.name);
1544
+ if (!row) throw new import_kernel10.UnknownShardError(partitionKey, this.name);
1368
1545
  const provisioned = await this.db._shardVaultProvisioned(vaultId);
1369
- if (!provisioned) throw new import_kernel9.ShardProvisioningError(vaultId, partitionKey);
1546
+ if (!provisioned) throw new import_kernel10.ShardProvisioningError(vaultId, partitionKey);
1370
1547
  return this.openShard(partitionKey);
1371
1548
  }
1372
1549
  /** A sharded view over one logical collection across all shards. */
@@ -1387,7 +1564,7 @@ var init_vault_group = __esm({
1387
1564
  const eligible = [];
1388
1565
  versionOk.forEach((row, i) => {
1389
1566
  if (provisioned[i]) eligible.push(row);
1390
- else skipped.push({ vaultId: row.vaultId, reason: "error", error: new import_kernel9.ShardProvisioningError(row.vaultId, row.partitionKey) });
1567
+ else skipped.push({ vaultId: row.vaultId, reason: "error", error: new import_kernel10.ShardProvisioningError(row.vaultId, row.partitionKey) });
1391
1568
  });
1392
1569
  return { eligible, skipped };
1393
1570
  }
@@ -1424,7 +1601,7 @@ var init_vault_group = __esm({
1424
1601
  withCrossVaultDerivation(spec) {
1425
1602
  const target = spec.target.vault;
1426
1603
  if (target === this.name || target.startsWith(`${this.name}${SHARD_SEPARATOR}`)) {
1427
- throw new import_kernel9.ValidationError(
1604
+ throw new import_kernel10.ValidationError(
1428
1605
  `withCrossVaultDerivation: target.vault "${target}" is the "${this.name}" group itself or one of its shards \u2014 an Insight summary must target a SEPARATE analytics vault, never write back into client-shard data (it would breach the per-shard DEK boundary). Use a distinct vault name.`
1429
1606
  );
1430
1607
  }
@@ -1529,7 +1706,7 @@ var init_vault_group = __esm({
1529
1706
  async migrateShard(partitionKey) {
1530
1707
  const vaultId = this.shardVaultId(partitionKey);
1531
1708
  const row = await this.registry.get(this.registryId(partitionKey));
1532
- if (!row) throw new import_kernel9.UnknownShardError(partitionKey, this.name);
1709
+ if (!row) throw new import_kernel10.UnknownShardError(partitionKey, this.name);
1533
1710
  const target = this.template.version;
1534
1711
  const sv = await this.ensureStateVault();
1535
1712
  const base = { vaultId, group: this.name, currentVersion: row.schemaVersion, targetVersion: target };
@@ -1612,7 +1789,7 @@ var init_vault_group = __esm({
1612
1789
  let vault;
1613
1790
  if (!row) {
1614
1791
  if (this.group.sharding.autoCreate === false) {
1615
- throw new import_kernel9.UnknownShardError(key, this.group.name);
1792
+ throw new import_kernel10.UnknownShardError(key, this.group.name);
1616
1793
  }
1617
1794
  vault = await this.group.createShard(key, this.group.sharding.regionOf?.(record));
1618
1795
  } else {
@@ -1684,7 +1861,7 @@ var init_vault_group = __esm({
1684
1861
  this.group.template.configure(probe);
1685
1862
  for (const leg of this.coPartitionedLegs) {
1686
1863
  if (!probe.resolveRef(this.collectionName, leg.field)) {
1687
- throw new import_kernel9.CrossShardJoinError(
1864
+ throw new import_kernel10.CrossShardJoinError(
1688
1865
  `crossShardJoin("${leg.field}"): no ref() declared for "${leg.field}" on collection "${this.collectionName}" in template "${this.group.sharding.vaultTemplate}". Add refs: { ${leg.field}: ref('<target>') } to the template's collection options.`
1689
1866
  );
1690
1867
  }
@@ -1741,7 +1918,7 @@ var init_vault_group = __esm({
1741
1918
  /** @internal — joined queries don't support reactive/aggregate surfaces in v1. */
1742
1919
  assertNoJoinLegs(surface) {
1743
1920
  if (this.coPartitionedLegs.length || this.broadcastLegs.length) {
1744
- throw new import_kernel9.CrossShardJoinError(
1921
+ throw new import_kernel10.CrossShardJoinError(
1745
1922
  `${surface}() is not supported on a ShardedQuery with crossShardJoin/broadcastJoin legs in v1. Use toArray() for joined cross-shard queries.`
1746
1923
  );
1747
1924
  }
@@ -1807,10 +1984,10 @@ var init_vault_group = __esm({
1807
1984
  // src/index.ts
1808
1985
  var index_exports = {};
1809
1986
  __export(index_exports, {
1810
- CrossShardJoinError: () => import_kernel11.CrossShardJoinError,
1987
+ CrossShardJoinError: () => import_kernel12.CrossShardJoinError,
1811
1988
  CrossVaultDanglingRefError: () => CrossVaultDanglingRefError,
1812
- CustodyApi: () => import_hub5.CustodyApi,
1813
- DataResidencyError: () => import_kernel11.DataResidencyError,
1989
+ CustodyApi: () => import_hub6.CustodyApi,
1990
+ DataResidencyError: () => import_kernel12.DataResidencyError,
1814
1991
  DockedUnit: () => DockedUnit,
1815
1992
  FieldAuthorityPolicyMissingError: () => FieldAuthorityPolicyMissingError,
1816
1993
  FieldLevelDeferredError: () => FieldLevelDeferredError,
@@ -1818,38 +1995,46 @@ __export(index_exports, {
1818
1995
  Lobby: () => Lobby,
1819
1996
  MigrationTransformRequiredError: () => MigrationTransformRequiredError,
1820
1997
  MinVersionError: () => MinVersionError,
1821
- ReservedVaultNameError: () => import_kernel11.ReservedVaultNameError,
1822
- ShardProvisioningError: () => import_kernel11.ShardProvisioningError,
1998
+ NOYDB_MULTI_BUNDLE_MAGIC: () => NOYDB_MULTI_BUNDLE_MAGIC,
1999
+ NOYDB_MULTI_BUNDLE_PREFIX_BYTES: () => NOYDB_MULTI_BUNDLE_PREFIX_BYTES,
2000
+ NOYDB_MULTI_BUNDLE_VERSION: () => NOYDB_MULTI_BUNDLE_VERSION,
2001
+ ReservedVaultNameError: () => import_kernel12.ReservedVaultNameError,
2002
+ ShardProvisioningError: () => import_kernel12.ShardProvisioningError,
1823
2003
  SurfaceCadenceScheduler: () => SurfaceCadenceScheduler,
1824
2004
  SurfaceNotFoundError: () => SurfaceNotFoundError,
1825
2005
  SurfaceStateError: () => SurfaceStateError,
1826
2006
  UnitGraduationError: () => UnitGraduationError,
1827
- UnknownShardError: () => import_kernel11.UnknownShardError,
1828
- VaultTemplateNotFoundError: () => import_kernel11.VaultTemplateNotFoundError,
2007
+ UnknownShardError: () => import_kernel12.UnknownShardError,
2008
+ VaultTemplateNotFoundError: () => import_kernel12.VaultTemplateNotFoundError,
1829
2009
  agreeSurface: () => agreeSurface,
1830
2010
  applySurface: () => applySurface,
1831
- createDeedOwner: () => import_hub5.createDeedOwner,
2011
+ createDeedOwner: () => import_hub6.createDeedOwner,
1832
2012
  createLobby: () => createLobby,
2013
+ decodeMultiBundle: () => decodeMultiBundle,
1833
2014
  describeCrossVaultExtraction: () => describeCrossVaultExtraction,
2015
+ encodeMultiBundle: () => encodeMultiBundle,
1834
2016
  exportSurface: () => exportSurface,
1835
2017
  extractCrossVaultPartition: () => extractCrossVaultPartition,
1836
- isDeedVault: () => import_hub5.isDeedVault,
2018
+ isDeedVault: () => import_hub6.isDeedVault,
1837
2019
  isSurfaceDue: () => isSurfaceDue,
1838
- liberateVault: () => import_hub5.liberateVault,
2020
+ liberateVault: () => import_hub6.liberateVault,
1839
2021
  listDueSurfaces: () => listDueSurfaces,
1840
- loadDeedMarker: () => import_hub5.loadDeedMarker,
2022
+ loadDeedMarker: () => import_hub6.loadDeedMarker,
1841
2023
  markSynced: () => markSynced,
1842
2024
  mergeCompartment: () => mergeCompartment,
1843
2025
  mergeDecryptedRecords: () => mergeDecryptedRecords,
1844
2026
  migrateThenMerge: () => migrateThenMerge,
1845
2027
  proposeSurface: () => proposeSurface,
2028
+ readMultiVaultBundleCompartment: () => readMultiVaultBundleCompartment,
2029
+ readNoydbBundleManifest: () => readNoydbBundleManifest,
1846
2030
  resolveFieldAuthority: () => resolveFieldAuthority,
1847
2031
  resolveRecordByFieldAuthority: () => resolveRecordByFieldAuthority,
1848
- walkCrossVaultClosure: () => walkCrossVaultClosure
2032
+ walkCrossVaultClosure: () => walkCrossVaultClosure,
2033
+ writeMultiVaultBundle: () => writeMultiVaultBundle
1849
2034
  });
1850
2035
  module.exports = __toCommonJS(index_exports);
1851
- var import_kernel10 = require("@noy-db/hub/kernel");
1852
- var import_hub4 = require("@noy-db/hub");
2036
+ var import_kernel11 = require("@noy-db/hub/kernel");
2037
+ var import_hub5 = require("@noy-db/hub");
1853
2038
 
1854
2039
  // src/dock/docked-unit.ts
1855
2040
  var DockedUnit = class {
@@ -1869,12 +2054,13 @@ var DockedUnit = class {
1869
2054
  };
1870
2055
 
1871
2056
  // src/index.ts
1872
- var import_kernel11 = require("@noy-db/hub/kernel");
2057
+ var import_kernel12 = require("@noy-db/hub/kernel");
2058
+ init_multi_bundle();
1873
2059
  init_extract_cross_vault();
1874
2060
  init_merge_compartment();
1875
2061
 
1876
2062
  // src/interchange/migrate-then-merge.ts
1877
- var import_bundle3 = require("@noy-db/hub/bundle");
2063
+ var import_bundle4 = require("@noy-db/hub/bundle");
1878
2064
  init_merge_compartment();
1879
2065
  init_stage_records();
1880
2066
  init_stage_records();
@@ -1899,7 +2085,7 @@ async function migrateThenMerge(receiver, compartmentBytes, opts) {
1899
2085
  );
1900
2086
  }
1901
2087
  if (fromVersion > toVersion) throw new MinVersionError(fromVersion, toVersion);
1902
- const incoming = await (0, import_bundle3.decryptExtractedPartition)(compartmentBytes, opts.transferKey);
2088
+ const incoming = await (0, import_bundle4.decryptExtractedPartition)(compartmentBytes, opts.transferKey);
1903
2089
  const transformsByCollection = {};
1904
2090
  const migrationByCollection = {};
1905
2091
  for (const [coll, recs] of Object.entries(incoming)) {
@@ -1922,7 +2108,7 @@ async function migrateThenMerge(receiver, compartmentBytes, opts) {
1922
2108
 
1923
2109
  // src/index.ts
1924
2110
  init_field_authority();
1925
- var import_hub5 = require("@noy-db/hub");
2111
+ var import_hub6 = require("@noy-db/hub");
1926
2112
 
1927
2113
  // src/dock/unit-driver.ts
1928
2114
  var InMemoryUnitDriver = class {
@@ -1956,10 +2142,10 @@ var Lobby = class {
1956
2142
  }
1957
2143
  async openVaultGroup(name, opts) {
1958
2144
  const db = this.noydb;
1959
- if (db.isClosed) throw new import_kernel10.ValidationError("Instance is closed");
1960
- if (name === import_hub4.STATE_VAULT_NAME) throw new import_kernel10.ReservedVaultNameError(name);
2145
+ if (db.isClosed) throw new import_kernel11.ValidationError("Instance is closed");
2146
+ if (name === import_hub5.STATE_VAULT_NAME) throw new import_kernel11.ReservedVaultNameError(name);
1961
2147
  const template = this.vaultTemplates.get(opts.sharding.vaultTemplate);
1962
- if (!template) throw new import_kernel10.VaultTemplateNotFoundError(opts.sharding.vaultTemplate);
2148
+ if (!template) throw new import_kernel11.VaultTemplateNotFoundError(opts.sharding.vaultTemplate);
1963
2149
  const { VaultGroup: VaultGroup2 } = await Promise.resolve().then(() => (init_vault_group(), vault_group_exports));
1964
2150
  const { StateManagementVault: StateManagementVault2 } = await Promise.resolve().then(() => (init_state_vault(), state_vault_exports));
1965
2151
  const stateVault = opts.registry ? void 0 : await StateManagementVault2.open(db);
@@ -1978,7 +2164,7 @@ var Lobby = class {
1978
2164
  }
1979
2165
  async openStateManagementVault() {
1980
2166
  const db = this.noydb;
1981
- if (db.isClosed) throw new import_kernel10.ValidationError("Instance is closed");
2167
+ if (db.isClosed) throw new import_kernel11.ValidationError("Instance is closed");
1982
2168
  const { StateManagementVault: StateManagementVault2 } = await Promise.resolve().then(() => (init_state_vault(), state_vault_exports));
1983
2169
  return StateManagementVault2.open(db);
1984
2170
  }
@@ -2077,6 +2263,9 @@ function createLobby(noydb) {
2077
2263
  Lobby,
2078
2264
  MigrationTransformRequiredError,
2079
2265
  MinVersionError,
2266
+ NOYDB_MULTI_BUNDLE_MAGIC,
2267
+ NOYDB_MULTI_BUNDLE_PREFIX_BYTES,
2268
+ NOYDB_MULTI_BUNDLE_VERSION,
2080
2269
  ReservedVaultNameError,
2081
2270
  ShardProvisioningError,
2082
2271
  SurfaceCadenceScheduler,
@@ -2089,7 +2278,9 @@ function createLobby(noydb) {
2089
2278
  applySurface,
2090
2279
  createDeedOwner,
2091
2280
  createLobby,
2281
+ decodeMultiBundle,
2092
2282
  describeCrossVaultExtraction,
2283
+ encodeMultiBundle,
2093
2284
  exportSurface,
2094
2285
  extractCrossVaultPartition,
2095
2286
  isDeedVault,
@@ -2102,8 +2293,11 @@ function createLobby(noydb) {
2102
2293
  mergeDecryptedRecords,
2103
2294
  migrateThenMerge,
2104
2295
  proposeSurface,
2296
+ readMultiVaultBundleCompartment,
2297
+ readNoydbBundleManifest,
2105
2298
  resolveFieldAuthority,
2106
2299
  resolveRecordByFieldAuthority,
2107
- walkCrossVaultClosure
2300
+ walkCrossVaultClosure,
2301
+ writeMultiVaultBundle
2108
2302
  });
2109
2303
  //# sourceMappingURL=index.cjs.map