@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.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { Vault, SealingKeyProvider, Noydb as Noydb$1 } from '@noy-db/hub';
1
+ import { Vault, SealingKeyProvider, PublicEnvelope, Noydb as Noydb$1 } from '@noy-db/hub';
2
2
  export { CustodyApi, DeedMarker, GrantCustodianOptions, LiberateOptions, LiberateResult, createDeedOwner, isDeedVault, liberateVault, loadDeedMarker } from '@noy-db/hub';
3
3
  import { IndexDef, LiveAggregation, AggregateSpec, AggregateResult, LiveQuery, Vault as Vault$1, Collection, Operator, Noydb, Query, JoinStrategy, ChangeEvent } from '@noy-db/hub/kernel';
4
4
  export { CrossShardJoinError, DataResidencyError, ReservedVaultNameError, ShardProvisioningError, UnknownShardError, VaultTemplateNotFoundError } from '@noy-db/hub/kernel';
5
- import { DecryptedRecord, ExtractionPreview } from '@noy-db/hub/bundle';
5
+ import { DecryptedRecord, ExtractionPreview, WriteNoydbBundleOptions } from '@noy-db/hub/bundle';
6
6
  import { AsXlsxSheetOptions } from '@noy-db/as-xlsx';
7
7
  export { MultiVaultDenormColumn, MultiVaultXlsxEntry, MultiVaultXlsxOptions } from '@noy-db/as-xlsx';
8
8
 
@@ -987,6 +987,107 @@ declare class UnitGraduationError extends Error {
987
987
  constructor(message: string);
988
988
  }
989
989
 
990
+ /**
991
+ * Multi-compartment `.noydb` bundle (`NDBM`). A thin outer container
992
+ * that embeds N standard single-vault `.noydb` bundles plus an
993
+ * unencrypted, owner-curated **manifest**. The v1 single-vault format
994
+ * is untouched; each compartment is a complete v1 bundle, produced by
995
+ * `writeNoydbBundle` and read by `readNoydbBundle`.
996
+ *
997
+ * Layout: magic 'NDBM'(4) · version(1) · reserved(1) · manifestLen(4 BE)
998
+ * · manifest JSON · concat(inner v1 bundles, in manifest order).
999
+ *
1000
+ * @packageDocumentation
1001
+ */
1002
+
1003
+ /** Magic bytes 'NDBM' — NOYDB Multi-compartment bundle. */
1004
+ declare const NOYDB_MULTI_BUNDLE_MAGIC: Uint8Array<ArrayBuffer>;
1005
+ /** Fixed prefix: magic(4) + version(1) + reserved(1) + manifestLen(4). */
1006
+ declare const NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10;
1007
+ /** Current multi-bundle layout version. */
1008
+ declare const NOYDB_MULTI_BUNDLE_VERSION = 1;
1009
+ /** One compartment's entry in the pre-decrypt manifest. */
1010
+ interface CompartmentManifest {
1011
+ /** The inner v1 bundle's stable ULID handle. */
1012
+ readonly handle: string;
1013
+ /** Owner-curated classification (e.g. 'shard', 'pool'). Opt-in. */
1014
+ readonly roleTag?: string;
1015
+ /** ISO export timestamp. Always set by the writer; absent for a v1 bundle read as a 1-entry manifest. */
1016
+ readonly exportedAt?: string;
1017
+ /** Compartment (vault) name. Opt-in disclosure. */
1018
+ readonly name?: string;
1019
+ /** Collection names + record counts. Opt-in disclosure. */
1020
+ readonly collections?: readonly {
1021
+ readonly name: string;
1022
+ readonly count: number;
1023
+ }[];
1024
+ /** Inner bundle's owner-curated public envelope, surfaced. Opt-in. */
1025
+ readonly publicEnvelope?: PublicEnvelope;
1026
+ /** Byte length of the inner v1 bundle (drives framing). */
1027
+ readonly innerBytes: number;
1028
+ /** SHA-256 (lowercase hex) of the inner v1 bundle bytes — pre-decrypt integrity. */
1029
+ readonly innerSha256: string;
1030
+ /** Source vault's schema fence version at extract time (FR-8). Opt-in; absent on older bundles. */
1031
+ readonly schemaVersion?: number;
1032
+ }
1033
+ /** The unencrypted manifest of a multi-compartment bundle. */
1034
+ interface MultiBundleManifest {
1035
+ readonly multiFormatVersion: number;
1036
+ /** Opaque ULID for the outer container. */
1037
+ readonly handle: string;
1038
+ readonly compartments: readonly CompartmentManifest[];
1039
+ }
1040
+ /** Assemble the `NDBM` container from a manifest + inner bundle bytes (in manifest order). */
1041
+ declare function encodeMultiBundle(manifest: MultiBundleManifest, inner: readonly Uint8Array[]): Uint8Array;
1042
+ /** Parse the `NDBM` container into its manifest + raw inner bundle byte slices. */
1043
+ declare function decodeMultiBundle(bytes: Uint8Array): {
1044
+ manifest: MultiBundleManifest;
1045
+ inner: Uint8Array[];
1046
+ };
1047
+ /** Per-compartment input to {@link writeMultiVaultBundle}. */
1048
+ interface MultiVaultCompartmentInput {
1049
+ readonly vault: Vault$1;
1050
+ /** Owner-curated classification surfaced in the manifest (e.g. 'shard', 'pool'). */
1051
+ readonly roleTag?: string;
1052
+ /** ISO timestamp for the manifest; defaults to now. */
1053
+ readonly exportedAt?: string;
1054
+ /** Opt-in pre-decrypt disclosure for this compartment. */
1055
+ readonly disclose?: {
1056
+ /** `true` → use `vault.name`; a string → that explicit name. */
1057
+ readonly name?: boolean | string;
1058
+ /** `true` → include collection names + record counts. */
1059
+ readonly collections?: boolean;
1060
+ /** `true` → surface the inner bundle's public envelope into the manifest. */
1061
+ readonly publicEnvelope?: boolean;
1062
+ };
1063
+ /** Options forwarded to `writeNoydbBundle` for this compartment's inner bundle. */
1064
+ readonly bundleOptions?: WriteNoydbBundleOptions;
1065
+ }
1066
+ /** Write N vaults into one `NDBM` multi-compartment bundle. */
1067
+ declare function writeMultiVaultBundle(compartments: readonly MultiVaultCompartmentInput[], opts?: {
1068
+ readonly handle?: string;
1069
+ }): Promise<Uint8Array>;
1070
+ /**
1071
+ * Read the pre-decrypt manifest of a bundle WITHOUT decrypting any
1072
+ * compartment. Accepts a multi-compartment `NDBM` bundle (returns its
1073
+ * N entries) OR a single v1 `NDB1` bundle (returns a 1-entry manifest,
1074
+ * for uniform handling). Throws on anything else.
1075
+ */
1076
+ declare function readNoydbBundleManifest(bytes: Uint8Array): Promise<CompartmentManifest[]>;
1077
+ /**
1078
+ * Extract one compartment's inner v1 `.noydb` bundle bytes, ready to
1079
+ * pass to `readNoydbBundle`. `selector` is a compartment `handle` or a
1080
+ * zero-based index. For a single v1 bundle, the bundle itself is the
1081
+ * only compartment.
1082
+ *
1083
+ * Does NOT verify the manifest `innerSha256` — it returns the raw
1084
+ * slice. Integrity is enforced downstream: `readNoydbBundle` verifies
1085
+ * the inner bundle's own `bodySha256`. Callers wanting an early,
1086
+ * pre-decrypt check can hash the returned bytes against the
1087
+ * compartment's `innerSha256`.
1088
+ */
1089
+ declare function readMultiVaultBundleCompartment(bytes: Uint8Array, selector: string | number): Uint8Array;
1090
+
990
1091
  /**
991
1092
  * @klum-db/lobby interchange — migrate-then-merge (FR-8). Upgrade an incoming
992
1093
  * compartment to the receiver's schema version IN STAGING, then merge.
@@ -1312,4 +1413,4 @@ declare class Lobby {
1312
1413
  }
1313
1414
  declare function createLobby(noydb: Noydb$1): Lobby;
1314
1415
 
1315
- export { type CapturedBlueprint, type CompartmentMeta, CrossVaultAggregation, type CrossVaultClosurePlan, CrossVaultDanglingRefError, type CrossVaultDerivationContext, type CrossVaultDerivationSpec, CrossVaultGroupedAggregation, type GroupedRow as CrossVaultGroupedRow, type CrossVaultLiveAggregation, type CrossVaultLiveQuery, type CrossVaultPreview, type CrossVaultRef, type CrossVaultSeed, type DecryptedMergeOptions, type DeploymentEvent, DockedUnit, type ExportMultiVaultXlsxOptions, type ExtractCrossVaultOptions, type ExtractCrossVaultResult, type FanoutQueryOptions, type FanoutResult, type FieldAuthorityInputs, type FieldAuthorityPolicy, FieldAuthorityPolicyMissingError, type FieldAuthorityRule, FieldLevelDeferredError, type FleetMigrationResult, type GraduateOptions, type GraduationReport, InMemoryUnitDriver, type LiveQueryOptions, Lobby, type MergeCompartmentOptions, type MergeConflict, type MergeReport, type MergeStrategy, type MigrateThenMergeOptions, type MigrateThenMergeReport, type MigrationStatusRow, type MigrationStep, MigrationTransformRequiredError, MinVersionError, type RefreshInsightsResult, type SchemaManifestRow, ShardedCollection, ShardedGroupedQuery, ShardedQuery, type ShardingConfig, type SkippedVault, StateManagementVault, SurfaceCadenceScheduler, type SurfaceConflictPolicy, type SurfaceDefinition, type SurfaceDirection, SurfaceNotFoundError, type SurfaceRow, SurfaceStateError, type SurfaceStatus, type UnitDriver, UnitGraduationError, VaultGroup, type VaultGroupOptions, type VaultRegistryRow, type VaultTemplate, agreeSurface, applySurface, createLobby, describeCrossVaultExtraction, exportSurface, extractCrossVaultPartition, isSurfaceDue, listDueSurfaces, markSynced, mergeCompartment, mergeDecryptedRecords, migrateThenMerge, proposeSurface, resolveFieldAuthority, resolveRecordByFieldAuthority, walkCrossVaultClosure };
1416
+ export { type CapturedBlueprint, type CompartmentManifest, type CompartmentMeta, CrossVaultAggregation, type CrossVaultClosurePlan, CrossVaultDanglingRefError, type CrossVaultDerivationContext, type CrossVaultDerivationSpec, CrossVaultGroupedAggregation, type GroupedRow as CrossVaultGroupedRow, type CrossVaultLiveAggregation, type CrossVaultLiveQuery, type CrossVaultPreview, type CrossVaultRef, type CrossVaultSeed, type DecryptedMergeOptions, type DeploymentEvent, DockedUnit, type ExportMultiVaultXlsxOptions, type ExtractCrossVaultOptions, type ExtractCrossVaultResult, type FanoutQueryOptions, type FanoutResult, type FieldAuthorityInputs, type FieldAuthorityPolicy, FieldAuthorityPolicyMissingError, type FieldAuthorityRule, FieldLevelDeferredError, type FleetMigrationResult, type GraduateOptions, type GraduationReport, InMemoryUnitDriver, type LiveQueryOptions, Lobby, type MergeCompartmentOptions, type MergeConflict, type MergeReport, type MergeStrategy, type MigrateThenMergeOptions, type MigrateThenMergeReport, type MigrationStatusRow, type MigrationStep, MigrationTransformRequiredError, MinVersionError, type MultiBundleManifest, type MultiVaultCompartmentInput, NOYDB_MULTI_BUNDLE_MAGIC, NOYDB_MULTI_BUNDLE_PREFIX_BYTES, NOYDB_MULTI_BUNDLE_VERSION, type RefreshInsightsResult, type SchemaManifestRow, ShardedCollection, ShardedGroupedQuery, ShardedQuery, type ShardingConfig, type SkippedVault, StateManagementVault, SurfaceCadenceScheduler, type SurfaceConflictPolicy, type SurfaceDefinition, type SurfaceDirection, SurfaceNotFoundError, type SurfaceRow, SurfaceStateError, type SurfaceStatus, type UnitDriver, UnitGraduationError, VaultGroup, type VaultGroupOptions, type VaultRegistryRow, type VaultTemplate, agreeSurface, applySurface, createLobby, decodeMultiBundle, describeCrossVaultExtraction, encodeMultiBundle, exportSurface, extractCrossVaultPartition, isSurfaceDue, listDueSurfaces, markSynced, mergeCompartment, mergeDecryptedRecords, migrateThenMerge, proposeSurface, readMultiVaultBundleCompartment, readNoydbBundleManifest, resolveFieldAuthority, resolveRecordByFieldAuthority, walkCrossVaultClosure, writeMultiVaultBundle };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { Vault, SealingKeyProvider, Noydb as Noydb$1 } from '@noy-db/hub';
1
+ import { Vault, SealingKeyProvider, PublicEnvelope, Noydb as Noydb$1 } from '@noy-db/hub';
2
2
  export { CustodyApi, DeedMarker, GrantCustodianOptions, LiberateOptions, LiberateResult, createDeedOwner, isDeedVault, liberateVault, loadDeedMarker } from '@noy-db/hub';
3
3
  import { IndexDef, LiveAggregation, AggregateSpec, AggregateResult, LiveQuery, Vault as Vault$1, Collection, Operator, Noydb, Query, JoinStrategy, ChangeEvent } from '@noy-db/hub/kernel';
4
4
  export { CrossShardJoinError, DataResidencyError, ReservedVaultNameError, ShardProvisioningError, UnknownShardError, VaultTemplateNotFoundError } from '@noy-db/hub/kernel';
5
- import { DecryptedRecord, ExtractionPreview } from '@noy-db/hub/bundle';
5
+ import { DecryptedRecord, ExtractionPreview, WriteNoydbBundleOptions } from '@noy-db/hub/bundle';
6
6
  import { AsXlsxSheetOptions } from '@noy-db/as-xlsx';
7
7
  export { MultiVaultDenormColumn, MultiVaultXlsxEntry, MultiVaultXlsxOptions } from '@noy-db/as-xlsx';
8
8
 
@@ -987,6 +987,107 @@ declare class UnitGraduationError extends Error {
987
987
  constructor(message: string);
988
988
  }
989
989
 
990
+ /**
991
+ * Multi-compartment `.noydb` bundle (`NDBM`). A thin outer container
992
+ * that embeds N standard single-vault `.noydb` bundles plus an
993
+ * unencrypted, owner-curated **manifest**. The v1 single-vault format
994
+ * is untouched; each compartment is a complete v1 bundle, produced by
995
+ * `writeNoydbBundle` and read by `readNoydbBundle`.
996
+ *
997
+ * Layout: magic 'NDBM'(4) · version(1) · reserved(1) · manifestLen(4 BE)
998
+ * · manifest JSON · concat(inner v1 bundles, in manifest order).
999
+ *
1000
+ * @packageDocumentation
1001
+ */
1002
+
1003
+ /** Magic bytes 'NDBM' — NOYDB Multi-compartment bundle. */
1004
+ declare const NOYDB_MULTI_BUNDLE_MAGIC: Uint8Array<ArrayBuffer>;
1005
+ /** Fixed prefix: magic(4) + version(1) + reserved(1) + manifestLen(4). */
1006
+ declare const NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10;
1007
+ /** Current multi-bundle layout version. */
1008
+ declare const NOYDB_MULTI_BUNDLE_VERSION = 1;
1009
+ /** One compartment's entry in the pre-decrypt manifest. */
1010
+ interface CompartmentManifest {
1011
+ /** The inner v1 bundle's stable ULID handle. */
1012
+ readonly handle: string;
1013
+ /** Owner-curated classification (e.g. 'shard', 'pool'). Opt-in. */
1014
+ readonly roleTag?: string;
1015
+ /** ISO export timestamp. Always set by the writer; absent for a v1 bundle read as a 1-entry manifest. */
1016
+ readonly exportedAt?: string;
1017
+ /** Compartment (vault) name. Opt-in disclosure. */
1018
+ readonly name?: string;
1019
+ /** Collection names + record counts. Opt-in disclosure. */
1020
+ readonly collections?: readonly {
1021
+ readonly name: string;
1022
+ readonly count: number;
1023
+ }[];
1024
+ /** Inner bundle's owner-curated public envelope, surfaced. Opt-in. */
1025
+ readonly publicEnvelope?: PublicEnvelope;
1026
+ /** Byte length of the inner v1 bundle (drives framing). */
1027
+ readonly innerBytes: number;
1028
+ /** SHA-256 (lowercase hex) of the inner v1 bundle bytes — pre-decrypt integrity. */
1029
+ readonly innerSha256: string;
1030
+ /** Source vault's schema fence version at extract time (FR-8). Opt-in; absent on older bundles. */
1031
+ readonly schemaVersion?: number;
1032
+ }
1033
+ /** The unencrypted manifest of a multi-compartment bundle. */
1034
+ interface MultiBundleManifest {
1035
+ readonly multiFormatVersion: number;
1036
+ /** Opaque ULID for the outer container. */
1037
+ readonly handle: string;
1038
+ readonly compartments: readonly CompartmentManifest[];
1039
+ }
1040
+ /** Assemble the `NDBM` container from a manifest + inner bundle bytes (in manifest order). */
1041
+ declare function encodeMultiBundle(manifest: MultiBundleManifest, inner: readonly Uint8Array[]): Uint8Array;
1042
+ /** Parse the `NDBM` container into its manifest + raw inner bundle byte slices. */
1043
+ declare function decodeMultiBundle(bytes: Uint8Array): {
1044
+ manifest: MultiBundleManifest;
1045
+ inner: Uint8Array[];
1046
+ };
1047
+ /** Per-compartment input to {@link writeMultiVaultBundle}. */
1048
+ interface MultiVaultCompartmentInput {
1049
+ readonly vault: Vault$1;
1050
+ /** Owner-curated classification surfaced in the manifest (e.g. 'shard', 'pool'). */
1051
+ readonly roleTag?: string;
1052
+ /** ISO timestamp for the manifest; defaults to now. */
1053
+ readonly exportedAt?: string;
1054
+ /** Opt-in pre-decrypt disclosure for this compartment. */
1055
+ readonly disclose?: {
1056
+ /** `true` → use `vault.name`; a string → that explicit name. */
1057
+ readonly name?: boolean | string;
1058
+ /** `true` → include collection names + record counts. */
1059
+ readonly collections?: boolean;
1060
+ /** `true` → surface the inner bundle's public envelope into the manifest. */
1061
+ readonly publicEnvelope?: boolean;
1062
+ };
1063
+ /** Options forwarded to `writeNoydbBundle` for this compartment's inner bundle. */
1064
+ readonly bundleOptions?: WriteNoydbBundleOptions;
1065
+ }
1066
+ /** Write N vaults into one `NDBM` multi-compartment bundle. */
1067
+ declare function writeMultiVaultBundle(compartments: readonly MultiVaultCompartmentInput[], opts?: {
1068
+ readonly handle?: string;
1069
+ }): Promise<Uint8Array>;
1070
+ /**
1071
+ * Read the pre-decrypt manifest of a bundle WITHOUT decrypting any
1072
+ * compartment. Accepts a multi-compartment `NDBM` bundle (returns its
1073
+ * N entries) OR a single v1 `NDB1` bundle (returns a 1-entry manifest,
1074
+ * for uniform handling). Throws on anything else.
1075
+ */
1076
+ declare function readNoydbBundleManifest(bytes: Uint8Array): Promise<CompartmentManifest[]>;
1077
+ /**
1078
+ * Extract one compartment's inner v1 `.noydb` bundle bytes, ready to
1079
+ * pass to `readNoydbBundle`. `selector` is a compartment `handle` or a
1080
+ * zero-based index. For a single v1 bundle, the bundle itself is the
1081
+ * only compartment.
1082
+ *
1083
+ * Does NOT verify the manifest `innerSha256` — it returns the raw
1084
+ * slice. Integrity is enforced downstream: `readNoydbBundle` verifies
1085
+ * the inner bundle's own `bodySha256`. Callers wanting an early,
1086
+ * pre-decrypt check can hash the returned bytes against the
1087
+ * compartment's `innerSha256`.
1088
+ */
1089
+ declare function readMultiVaultBundleCompartment(bytes: Uint8Array, selector: string | number): Uint8Array;
1090
+
990
1091
  /**
991
1092
  * @klum-db/lobby interchange — migrate-then-merge (FR-8). Upgrade an incoming
992
1093
  * compartment to the receiver's schema version IN STAGING, then merge.
@@ -1312,4 +1413,4 @@ declare class Lobby {
1312
1413
  }
1313
1414
  declare function createLobby(noydb: Noydb$1): Lobby;
1314
1415
 
1315
- export { type CapturedBlueprint, type CompartmentMeta, CrossVaultAggregation, type CrossVaultClosurePlan, CrossVaultDanglingRefError, type CrossVaultDerivationContext, type CrossVaultDerivationSpec, CrossVaultGroupedAggregation, type GroupedRow as CrossVaultGroupedRow, type CrossVaultLiveAggregation, type CrossVaultLiveQuery, type CrossVaultPreview, type CrossVaultRef, type CrossVaultSeed, type DecryptedMergeOptions, type DeploymentEvent, DockedUnit, type ExportMultiVaultXlsxOptions, type ExtractCrossVaultOptions, type ExtractCrossVaultResult, type FanoutQueryOptions, type FanoutResult, type FieldAuthorityInputs, type FieldAuthorityPolicy, FieldAuthorityPolicyMissingError, type FieldAuthorityRule, FieldLevelDeferredError, type FleetMigrationResult, type GraduateOptions, type GraduationReport, InMemoryUnitDriver, type LiveQueryOptions, Lobby, type MergeCompartmentOptions, type MergeConflict, type MergeReport, type MergeStrategy, type MigrateThenMergeOptions, type MigrateThenMergeReport, type MigrationStatusRow, type MigrationStep, MigrationTransformRequiredError, MinVersionError, type RefreshInsightsResult, type SchemaManifestRow, ShardedCollection, ShardedGroupedQuery, ShardedQuery, type ShardingConfig, type SkippedVault, StateManagementVault, SurfaceCadenceScheduler, type SurfaceConflictPolicy, type SurfaceDefinition, type SurfaceDirection, SurfaceNotFoundError, type SurfaceRow, SurfaceStateError, type SurfaceStatus, type UnitDriver, UnitGraduationError, VaultGroup, type VaultGroupOptions, type VaultRegistryRow, type VaultTemplate, agreeSurface, applySurface, createLobby, describeCrossVaultExtraction, exportSurface, extractCrossVaultPartition, isSurfaceDue, listDueSurfaces, markSynced, mergeCompartment, mergeDecryptedRecords, migrateThenMerge, proposeSurface, resolveFieldAuthority, resolveRecordByFieldAuthority, walkCrossVaultClosure };
1416
+ export { type CapturedBlueprint, type CompartmentManifest, type CompartmentMeta, CrossVaultAggregation, type CrossVaultClosurePlan, CrossVaultDanglingRefError, type CrossVaultDerivationContext, type CrossVaultDerivationSpec, CrossVaultGroupedAggregation, type GroupedRow as CrossVaultGroupedRow, type CrossVaultLiveAggregation, type CrossVaultLiveQuery, type CrossVaultPreview, type CrossVaultRef, type CrossVaultSeed, type DecryptedMergeOptions, type DeploymentEvent, DockedUnit, type ExportMultiVaultXlsxOptions, type ExtractCrossVaultOptions, type ExtractCrossVaultResult, type FanoutQueryOptions, type FanoutResult, type FieldAuthorityInputs, type FieldAuthorityPolicy, FieldAuthorityPolicyMissingError, type FieldAuthorityRule, FieldLevelDeferredError, type FleetMigrationResult, type GraduateOptions, type GraduationReport, InMemoryUnitDriver, type LiveQueryOptions, Lobby, type MergeCompartmentOptions, type MergeConflict, type MergeReport, type MergeStrategy, type MigrateThenMergeOptions, type MigrateThenMergeReport, type MigrationStatusRow, type MigrationStep, MigrationTransformRequiredError, MinVersionError, type MultiBundleManifest, type MultiVaultCompartmentInput, NOYDB_MULTI_BUNDLE_MAGIC, NOYDB_MULTI_BUNDLE_PREFIX_BYTES, NOYDB_MULTI_BUNDLE_VERSION, type RefreshInsightsResult, type SchemaManifestRow, ShardedCollection, ShardedGroupedQuery, ShardedQuery, type ShardingConfig, type SkippedVault, StateManagementVault, SurfaceCadenceScheduler, type SurfaceConflictPolicy, type SurfaceDefinition, type SurfaceDirection, SurfaceNotFoundError, type SurfaceRow, SurfaceStateError, type SurfaceStatus, type UnitDriver, UnitGraduationError, VaultGroup, type VaultGroupOptions, type VaultRegistryRow, type VaultTemplate, agreeSurface, applySurface, createLobby, decodeMultiBundle, describeCrossVaultExtraction, encodeMultiBundle, exportSurface, extractCrossVaultPartition, isSurfaceDue, listDueSurfaces, markSynced, mergeCompartment, mergeDecryptedRecords, migrateThenMerge, proposeSurface, readMultiVaultBundleCompartment, readNoydbBundleManifest, resolveFieldAuthority, resolveRecordByFieldAuthority, walkCrossVaultClosure, writeMultiVaultBundle };
package/dist/index.js CHANGED
@@ -8,6 +8,188 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
+ // src/bundle/uint32.ts
12
+ function readUint32BE(bytes, offset) {
13
+ return (bytes[offset] << 24 | bytes[offset + 1] << 16 | bytes[offset + 2] << 8 | bytes[offset + 3]) >>> 0;
14
+ }
15
+ function writeUint32BE(bytes, offset, value) {
16
+ bytes[offset] = value >>> 24 & 255;
17
+ bytes[offset + 1] = value >>> 16 & 255;
18
+ bytes[offset + 2] = value >>> 8 & 255;
19
+ bytes[offset + 3] = value & 255;
20
+ }
21
+ var init_uint32 = __esm({
22
+ "src/bundle/uint32.ts"() {
23
+ "use strict";
24
+ }
25
+ });
26
+
27
+ // src/bundle/multi-bundle.ts
28
+ import { sha256Hex, generateULID } from "@noy-db/hub/kernel";
29
+ import {
30
+ writeNoydbBundle,
31
+ readNoydbBundleHeader
32
+ } from "@noy-db/hub/bundle";
33
+ import {
34
+ readNoydbBundlePublicEnvelope,
35
+ hasNoydbBundleMagic
36
+ } from "@noy-db/hub";
37
+ function encodeMultiBundle(manifest, inner) {
38
+ validateManifest(manifest);
39
+ if (manifest.compartments.length !== inner.length) {
40
+ throw new Error(`multi-bundle: manifest has ${manifest.compartments.length} compartments but ${inner.length} inner bundles were provided.`);
41
+ }
42
+ for (let i = 0; i < inner.length; i++) {
43
+ if (manifest.compartments[i].innerBytes !== inner[i].length) {
44
+ throw new Error(`multi-bundle: compartment ${i} declares innerBytes ${manifest.compartments[i].innerBytes} but ${inner[i].length} bytes were provided.`);
45
+ }
46
+ }
47
+ const manifestBytes = new TextEncoder().encode(JSON.stringify(manifest));
48
+ const bodyLen = inner.reduce((n, b) => n + b.length, 0);
49
+ const out = new Uint8Array(NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length + bodyLen);
50
+ out.set(NOYDB_MULTI_BUNDLE_MAGIC, 0);
51
+ out[4] = NOYDB_MULTI_BUNDLE_VERSION;
52
+ out[5] = 0;
53
+ writeUint32BE(out, 6, manifestBytes.length);
54
+ out.set(manifestBytes, NOYDB_MULTI_BUNDLE_PREFIX_BYTES);
55
+ let off = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestBytes.length;
56
+ for (const b of inner) {
57
+ out.set(b, off);
58
+ off += b.length;
59
+ }
60
+ return out;
61
+ }
62
+ function hasMultiMagic(bytes) {
63
+ if (bytes.length < NOYDB_MULTI_BUNDLE_MAGIC.length) return false;
64
+ for (let i = 0; i < NOYDB_MULTI_BUNDLE_MAGIC.length; i++) if (bytes[i] !== NOYDB_MULTI_BUNDLE_MAGIC[i]) return false;
65
+ return true;
66
+ }
67
+ function validateManifest(parsed) {
68
+ if (parsed === null || typeof parsed !== "object") throw new Error("multi-bundle manifest must be a JSON object.");
69
+ const m = parsed;
70
+ if (m["multiFormatVersion"] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`multi-bundle manifest.multiFormatVersion must be ${NOYDB_MULTI_BUNDLE_VERSION}, got ${String(m["multiFormatVersion"])}.`);
71
+ if (typeof m["handle"] !== "string" || m["handle"].length === 0) throw new Error("multi-bundle manifest.handle must be a non-empty string.");
72
+ if (!Array.isArray(m["compartments"])) throw new Error("multi-bundle manifest.compartments must be an array.");
73
+ const seenHandles = /* @__PURE__ */ new Set();
74
+ for (const c of m["compartments"]) {
75
+ if (c === null || typeof c !== "object") throw new Error("multi-bundle compartment must be an object.");
76
+ const e = c;
77
+ if (typeof e["handle"] !== "string" || e["handle"].length === 0) throw new Error("multi-bundle compartment.handle must be a non-empty string.");
78
+ if (seenHandles.has(e["handle"])) {
79
+ throw new Error(`multi-bundle manifest has a duplicate compartment handle "${e["handle"]}".`);
80
+ }
81
+ seenHandles.add(e["handle"]);
82
+ 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.");
83
+ 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.");
84
+ }
85
+ }
86
+ function decodeMultiBundle(bytes) {
87
+ if (!hasMultiMagic(bytes)) throw new Error("not a NOYDB multi-bundle: missing NDBM magic.");
88
+ if (bytes.length < NOYDB_MULTI_BUNDLE_PREFIX_BYTES) throw new Error("multi-bundle truncated: shorter than the fixed prefix.");
89
+ if (bytes[4] !== NOYDB_MULTI_BUNDLE_VERSION) throw new Error(`unsupported multi-bundle version ${String(bytes[4])}.`);
90
+ const manifestLen = readUint32BE(bytes, 6);
91
+ const manifestEnd = NOYDB_MULTI_BUNDLE_PREFIX_BYTES + manifestLen;
92
+ if (manifestEnd > bytes.length) throw new Error("multi-bundle truncated: manifest length overruns the buffer.");
93
+ const manifestJson = new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(NOYDB_MULTI_BUNDLE_PREFIX_BYTES, manifestEnd));
94
+ let parsed;
95
+ try {
96
+ parsed = JSON.parse(manifestJson);
97
+ } catch (err) {
98
+ throw new Error(`multi-bundle manifest is not valid JSON: ${err.message}`);
99
+ }
100
+ validateManifest(parsed);
101
+ const inner = [];
102
+ let off = manifestEnd;
103
+ for (const c of parsed.compartments) {
104
+ const end = off + c.innerBytes;
105
+ if (end > bytes.length) throw new Error(`multi-bundle truncated: compartment "${c.handle}" innerBytes overruns the buffer.`);
106
+ inner.push(bytes.subarray(off, end));
107
+ off = end;
108
+ }
109
+ if (off !== bytes.length) {
110
+ throw new Error(`multi-bundle: ${bytes.length - off} trailing byte(s) after the last compartment \u2014 buffer may be corrupt.`);
111
+ }
112
+ return { manifest: parsed, inner };
113
+ }
114
+ async function writeMultiVaultBundle(compartments, opts = {}) {
115
+ if (compartments.length === 0) throw new Error("writeMultiVaultBundle: at least one compartment is required.");
116
+ const inner = [];
117
+ const entries = [];
118
+ for (const c of compartments) {
119
+ const innerBytes = await writeNoydbBundle(c.vault, c.bundleOptions ?? {});
120
+ const header = readNoydbBundleHeader(innerBytes);
121
+ const entry = {
122
+ handle: header.handle,
123
+ exportedAt: c.exportedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
124
+ innerBytes: innerBytes.length,
125
+ innerSha256: await sha256Hex(innerBytes)
126
+ };
127
+ if (c.roleTag !== void 0) entry.roleTag = c.roleTag;
128
+ if (c.disclose?.name !== void 0 && c.disclose.name !== false) {
129
+ entry.name = c.disclose.name === true ? c.vault.name : c.disclose.name;
130
+ }
131
+ if (c.disclose?.collections === true) {
132
+ const names = await c.vault.collections();
133
+ entry.collections = await Promise.all(
134
+ names.map(async (n) => ({ name: n, count: await c.vault.collection(n).count() }))
135
+ );
136
+ }
137
+ if (c.disclose?.publicEnvelope === true) {
138
+ const env = readNoydbBundlePublicEnvelope(innerBytes);
139
+ if (env !== void 0) entry.publicEnvelope = env;
140
+ }
141
+ const fence = await c.vault.schemaFenceState();
142
+ entry.schemaVersion = fence.currentSchemaVersion;
143
+ inner.push(innerBytes);
144
+ entries.push(entry);
145
+ }
146
+ const manifest = {
147
+ multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,
148
+ handle: opts.handle ?? generateULID(),
149
+ compartments: entries
150
+ };
151
+ return encodeMultiBundle(manifest, inner);
152
+ }
153
+ async function readNoydbBundleManifest(bytes) {
154
+ if (hasMultiMagic(bytes)) return [...decodeMultiBundle(bytes).manifest.compartments];
155
+ if (hasNoydbBundleMagic(bytes)) {
156
+ const header = readNoydbBundleHeader(bytes);
157
+ const env = readNoydbBundlePublicEnvelope(bytes);
158
+ const entry = {
159
+ handle: header.handle,
160
+ innerBytes: bytes.length,
161
+ innerSha256: await sha256Hex(bytes)
162
+ };
163
+ if (env !== void 0) entry.publicEnvelope = env;
164
+ return [entry];
165
+ }
166
+ throw new Error("readNoydbBundleManifest: not a NOYDB bundle (no NDB1 or NDBM magic).");
167
+ }
168
+ function readMultiVaultBundleCompartment(bytes, selector) {
169
+ if (typeof selector === "number" && !Number.isInteger(selector)) {
170
+ throw new Error(`readMultiVaultBundleCompartment: numeric selector must be an integer, got ${selector}.`);
171
+ }
172
+ if (hasNoydbBundleMagic(bytes) && !hasMultiMagic(bytes)) {
173
+ const header = readNoydbBundleHeader(bytes);
174
+ if (selector === 0 || selector === header.handle) return bytes;
175
+ throw new Error(`readMultiVaultBundleCompartment: single v1 bundle has only compartment "${header.handle}".`);
176
+ }
177
+ const { manifest, inner } = decodeMultiBundle(bytes);
178
+ const idx = typeof selector === "number" ? selector : manifest.compartments.findIndex((c) => c.handle === selector);
179
+ if (idx < 0 || idx >= inner.length) throw new Error(`readMultiVaultBundleCompartment: no compartment ${typeof selector === "number" ? `at index ${selector}` : `"${selector}"`}.`);
180
+ return inner[idx];
181
+ }
182
+ var NOYDB_MULTI_BUNDLE_MAGIC, NOYDB_MULTI_BUNDLE_PREFIX_BYTES, NOYDB_MULTI_BUNDLE_VERSION;
183
+ var init_multi_bundle = __esm({
184
+ "src/bundle/multi-bundle.ts"() {
185
+ "use strict";
186
+ init_uint32();
187
+ NOYDB_MULTI_BUNDLE_MAGIC = new Uint8Array([78, 68, 66, 77]);
188
+ NOYDB_MULTI_BUNDLE_PREFIX_BYTES = 10;
189
+ NOYDB_MULTI_BUNDLE_VERSION = 1;
190
+ }
191
+ });
192
+
11
193
  // src/interchange/extract-cross-vault.ts
12
194
  var extract_cross_vault_exports = {};
13
195
  __export(extract_cross_vault_exports, {
@@ -19,13 +201,10 @@ __export(extract_cross_vault_exports, {
19
201
  import {
20
202
  walkClosure,
21
203
  extractPartition,
22
- encodeMultiBundle,
23
- readNoydbBundleHeader,
24
- NOYDB_MULTI_BUNDLE_VERSION,
25
- generateULID,
204
+ readNoydbBundleHeader as readNoydbBundleHeader2,
26
205
  describeExtraction
27
206
  } from "@noy-db/hub/bundle";
28
- import { sha256Hex } from "@noy-db/hub/kernel";
207
+ import { sha256Hex as sha256Hex2, generateULID as generateULID2 } from "@noy-db/hub/kernel";
29
208
  function asIdArray(v) {
30
209
  if (v === null || v === void 0) return [];
31
210
  if (Array.isArray(v)) return v.filter((x) => typeof x === "string" || typeof x === "number").map(String);
@@ -142,13 +321,13 @@ async function extractCrossVaultPartition(openVault, opts) {
142
321
  carryLedger: opts.carryLedger ?? false,
143
322
  ...opts.compression !== void 0 ? { compression: opts.compression } : {}
144
323
  });
145
- const header = readNoydbBundleHeader(bundleBytes);
324
+ const header = readNoydbBundleHeader2(bundleBytes);
146
325
  const meta = opts.compartmentMeta?.[vaultName];
147
326
  const entry = {
148
327
  handle: header.handle,
149
328
  exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
150
329
  innerBytes: bundleBytes.length,
151
- innerSha256: await sha256Hex(bundleBytes)
330
+ innerSha256: await sha256Hex2(bundleBytes)
152
331
  };
153
332
  if (meta?.roleTag !== void 0) entry.roleTag = meta.roleTag;
154
333
  if (meta?.disclose?.name !== void 0 && meta.disclose.name !== false) {
@@ -167,7 +346,7 @@ async function extractCrossVaultPartition(openVault, opts) {
167
346
  }
168
347
  const manifest = {
169
348
  multiFormatVersion: NOYDB_MULTI_BUNDLE_VERSION,
170
- handle: generateULID(),
349
+ handle: generateULID2(),
171
350
  compartments
172
351
  };
173
352
  return { bundle: encodeMultiBundle(manifest, inner), transferKeys, sealIds };
@@ -189,6 +368,7 @@ var CrossVaultDanglingRefError;
189
368
  var init_extract_cross_vault = __esm({
190
369
  "src/interchange/extract-cross-vault.ts"() {
191
370
  "use strict";
371
+ init_multi_bundle();
192
372
  CrossVaultDanglingRefError = class extends Error {
193
373
  constructor(dangling) {
194
374
  super(
@@ -544,12 +724,12 @@ __export(surface_exports, {
544
724
  markSynced: () => markSynced,
545
725
  proposeSurface: () => proposeSurface
546
726
  });
547
- import { generateULID as generateULID2 } from "@noy-db/hub/kernel";
727
+ import { generateULID as generateULID3 } from "@noy-db/hub/kernel";
548
728
  import { extractPartition as extractPartition2 } from "@noy-db/hub/bundle";
549
729
  async function proposeSurface(smv, def, proposedBy, now) {
550
730
  const row = {
551
731
  ...def,
552
- id: def.id ?? generateULID2(),
732
+ id: def.id ?? generateULID3(),
553
733
  status: "proposed",
554
734
  proposedBy,
555
735
  createdAt: now
@@ -666,7 +846,7 @@ var init_surface = __esm({
666
846
  });
667
847
 
668
848
  // src/federation/schema-manifest.ts
669
- import { sha256Hex as sha256Hex2 } from "@noy-db/hub/kernel";
849
+ import { sha256Hex as sha256Hex3 } from "@noy-db/hub/kernel";
670
850
  function captureBlueprint(configure) {
671
851
  const recorded = [];
672
852
  const collectionStub = new Proxy(
@@ -717,7 +897,7 @@ function canonical(value) {
717
897
  return `{${keys.map((k) => `${JSON.stringify(k)}:${canonical(obj[k])}`).join(",")}}`;
718
898
  }
719
899
  async function fingerprintBlueprint(bp) {
720
- return sha256Hex2(new TextEncoder().encode(canonical(bp)));
900
+ return sha256Hex3(new TextEncoder().encode(canonical(bp)));
721
901
  }
722
902
  var init_schema_manifest = __esm({
723
903
  "src/federation/schema-manifest.ts"() {
@@ -739,7 +919,7 @@ __export(state_vault_exports, {
739
919
  STATE_VAULT_NAME: () => STATE_VAULT_NAME,
740
920
  StateManagementVault: () => StateManagementVault
741
921
  });
742
- import { generateULID as generateULID3 } from "@noy-db/hub/kernel";
922
+ import { generateULID as generateULID4 } from "@noy-db/hub/kernel";
743
923
  var REGISTRY, MANIFEST, EVENTS, MIGRATION_STATUS, SURFACES, StateManagementVault;
744
924
  var init_state_vault = __esm({
745
925
  "src/federation/state-vault.ts"() {
@@ -835,7 +1015,7 @@ var init_state_vault = __esm({
835
1015
  */
836
1016
  async appendEvent(event) {
837
1017
  const ts = event.ts ?? Date.now();
838
- const id = generateULID3();
1018
+ const id = generateULID4();
839
1019
  await this.#events.put(id, { ...event, id, ts });
840
1020
  }
841
1021
  /**
@@ -1809,6 +1989,7 @@ var DockedUnit = class {
1809
1989
  };
1810
1990
 
1811
1991
  // src/index.ts
1992
+ init_multi_bundle();
1812
1993
  init_extract_cross_vault();
1813
1994
  init_merge_compartment();
1814
1995
  import {
@@ -2023,6 +2204,9 @@ export {
2023
2204
  Lobby,
2024
2205
  MigrationTransformRequiredError,
2025
2206
  MinVersionError,
2207
+ NOYDB_MULTI_BUNDLE_MAGIC,
2208
+ NOYDB_MULTI_BUNDLE_PREFIX_BYTES,
2209
+ NOYDB_MULTI_BUNDLE_VERSION,
2026
2210
  ReservedVaultNameError3 as ReservedVaultNameError,
2027
2211
  ShardProvisioningError2 as ShardProvisioningError,
2028
2212
  SurfaceCadenceScheduler,
@@ -2035,7 +2219,9 @@ export {
2035
2219
  applySurface,
2036
2220
  createDeedOwner2 as createDeedOwner,
2037
2221
  createLobby,
2222
+ decodeMultiBundle,
2038
2223
  describeCrossVaultExtraction,
2224
+ encodeMultiBundle,
2039
2225
  exportSurface,
2040
2226
  extractCrossVaultPartition,
2041
2227
  isDeedVault,
@@ -2048,8 +2234,11 @@ export {
2048
2234
  mergeDecryptedRecords,
2049
2235
  migrateThenMerge,
2050
2236
  proposeSurface,
2237
+ readMultiVaultBundleCompartment,
2238
+ readNoydbBundleManifest,
2051
2239
  resolveFieldAuthority,
2052
2240
  resolveRecordByFieldAuthority,
2053
- walkCrossVaultClosure
2241
+ walkCrossVaultClosure,
2242
+ writeMultiVaultBundle
2054
2243
  };
2055
2244
  //# sourceMappingURL=index.js.map