@klum-db/lobby 0.2.0-pre.31 → 0.2.0-pre.32

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,7 +1,7 @@
1
1
  import { Vault, SealingKeyProvider, PublicEnvelope, Noydb } from '@noy-db/hub';
2
2
  export { CustodyApi, DeedMarker, GrantCustodianOptions, LiberateOptions, LiberateResult, createDeedOwner, isDeedVault, liberateVault, loadDeedMarker } from '@noy-db/hub';
3
- import { a as VaultTemplate, S as StateManagementVault, V as VaultGroup, b as SkippedVault, M as MergeCompartmentOptions, c as MergeReport, d as SurfaceDirection, e as SurfaceConflictPolicy, f as SurfaceRow, g as VaultGroupOptions } from './vault-group-DqEyXbN1.cjs';
4
- export { C as CapturedBlueprint, h as CrossVaultAggregation, i as CrossVaultDerivationContext, j as CrossVaultDerivationSpec, k as CrossVaultGroupedAggregation, G as CrossVaultGroupedRow, l as CrossVaultLiveAggregation, m as CrossVaultLiveQuery, D as DecryptedMergeOptions, n as DeploymentEvent, F as FanoutQueryOptions, o as FanoutResult, p as FieldAuthorityInputs, q as FieldAuthorityPolicy, r as FieldAuthorityPolicyMissingError, s as FieldAuthorityRule, t as FieldLevelDeferredError, L as LiveQueryOptions, u as MergeConflict, v as MergeStrategy, w as MigrationStatusRow, R as RefreshInsightsResult, x as SchemaManifestRow, y as SchemaRolloutResult, z as ShardedCollection, A as ShardedGroupedQuery, B as ShardedQuery, E as ShardingConfig, H as SurfaceStatus, I as VaultRegistryRow, J as mergeCompartment, K as mergeDecryptedRecords, N as resolveFieldAuthority, O as resolveRecordByFieldAuthority } from './vault-group-DqEyXbN1.cjs';
3
+ import { a as VaultTemplate, S as StateManagementVault, V as VaultGroup, b as SkippedVault, M as MergeCompartmentOptions, c as MergeReport, d as SurfaceDirection, e as SurfaceConflictPolicy, f as SurfaceRow, g as VaultGroupOptions } from './vault-group-BchRCDm5.cjs';
4
+ export { C as CapturedBlueprint, h as CrossVaultAggregation, i as CrossVaultDerivationContext, j as CrossVaultDerivationSpec, k as CrossVaultGroupedAggregation, G as CrossVaultGroupedRow, l as CrossVaultLiveAggregation, m as CrossVaultLiveQuery, D as DecryptedMergeOptions, n as DeploymentEvent, F as FanoutQueryOptions, o as FanoutResult, p as FederatedRetrieveHit, q as FederatedRetrieveOptions, r as FederatedRetrieveResult, s as FederationMeta, t as FieldAuthorityInputs, u as FieldAuthorityPolicy, v as FieldAuthorityPolicyMissingError, w as FieldAuthorityRule, x as FieldLevelDeferredError, y as GroupMeta, L as LiveQueryOptions, z as MergeConflict, A as MergeStrategy, B as MigrationStatusRow, R as RefreshInsightsResult, E as SchemaManifestRow, H as SchemaRolloutResult, I as ShardedCollection, J as ShardedGroupedQuery, K as ShardedQuery, N as ShardingConfig, O as SurfaceStatus, P as VaultRegistryRow, Q as mergeCompartment, T as mergeDecryptedRecords, U as resolveFieldAuthority, W as resolveRecordByFieldAuthority } from './vault-group-BchRCDm5.cjs';
5
5
  import { AsXlsxSheetOptions } from '@noy-db/as-xlsx';
6
6
  export { MultiVaultDenormColumn, MultiVaultXlsxEntry, MultiVaultXlsxOptions } from '@noy-db/as-xlsx';
7
7
  import { ExtractionPreview, WriteNoydbBundleOptions } from '@noy-db/hub/bundle';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Vault, SealingKeyProvider, PublicEnvelope, Noydb } from '@noy-db/hub';
2
2
  export { CustodyApi, DeedMarker, GrantCustodianOptions, LiberateOptions, LiberateResult, createDeedOwner, isDeedVault, liberateVault, loadDeedMarker } from '@noy-db/hub';
3
- import { a as VaultTemplate, S as StateManagementVault, V as VaultGroup, b as SkippedVault, M as MergeCompartmentOptions, c as MergeReport, d as SurfaceDirection, e as SurfaceConflictPolicy, f as SurfaceRow, g as VaultGroupOptions } from './vault-group-DqEyXbN1.js';
4
- export { C as CapturedBlueprint, h as CrossVaultAggregation, i as CrossVaultDerivationContext, j as CrossVaultDerivationSpec, k as CrossVaultGroupedAggregation, G as CrossVaultGroupedRow, l as CrossVaultLiveAggregation, m as CrossVaultLiveQuery, D as DecryptedMergeOptions, n as DeploymentEvent, F as FanoutQueryOptions, o as FanoutResult, p as FieldAuthorityInputs, q as FieldAuthorityPolicy, r as FieldAuthorityPolicyMissingError, s as FieldAuthorityRule, t as FieldLevelDeferredError, L as LiveQueryOptions, u as MergeConflict, v as MergeStrategy, w as MigrationStatusRow, R as RefreshInsightsResult, x as SchemaManifestRow, y as SchemaRolloutResult, z as ShardedCollection, A as ShardedGroupedQuery, B as ShardedQuery, E as ShardingConfig, H as SurfaceStatus, I as VaultRegistryRow, J as mergeCompartment, K as mergeDecryptedRecords, N as resolveFieldAuthority, O as resolveRecordByFieldAuthority } from './vault-group-DqEyXbN1.js';
3
+ import { a as VaultTemplate, S as StateManagementVault, V as VaultGroup, b as SkippedVault, M as MergeCompartmentOptions, c as MergeReport, d as SurfaceDirection, e as SurfaceConflictPolicy, f as SurfaceRow, g as VaultGroupOptions } from './vault-group-BchRCDm5.js';
4
+ export { C as CapturedBlueprint, h as CrossVaultAggregation, i as CrossVaultDerivationContext, j as CrossVaultDerivationSpec, k as CrossVaultGroupedAggregation, G as CrossVaultGroupedRow, l as CrossVaultLiveAggregation, m as CrossVaultLiveQuery, D as DecryptedMergeOptions, n as DeploymentEvent, F as FanoutQueryOptions, o as FanoutResult, p as FederatedRetrieveHit, q as FederatedRetrieveOptions, r as FederatedRetrieveResult, s as FederationMeta, t as FieldAuthorityInputs, u as FieldAuthorityPolicy, v as FieldAuthorityPolicyMissingError, w as FieldAuthorityRule, x as FieldLevelDeferredError, y as GroupMeta, L as LiveQueryOptions, z as MergeConflict, A as MergeStrategy, B as MigrationStatusRow, R as RefreshInsightsResult, E as SchemaManifestRow, H as SchemaRolloutResult, I as ShardedCollection, J as ShardedGroupedQuery, K as ShardedQuery, N as ShardingConfig, O as SurfaceStatus, P as VaultRegistryRow, Q as mergeCompartment, T as mergeDecryptedRecords, U as resolveFieldAuthority, W as resolveRecordByFieldAuthority } from './vault-group-BchRCDm5.js';
5
5
  import { AsXlsxSheetOptions } from '@noy-db/as-xlsx';
6
6
  export { MultiVaultDenormColumn, MultiVaultXlsxEntry, MultiVaultXlsxOptions } from '@noy-db/as-xlsx';
7
7
  import { ExtractionPreview, WriteNoydbBundleOptions } from '@noy-db/hub/bundle';
package/dist/index.js CHANGED
@@ -1402,6 +1402,73 @@ var init_aggregate_across = __esm({
1402
1402
  }
1403
1403
  });
1404
1404
 
1405
+ // src/federation/retrieve-across.ts
1406
+ import { fuseRetrieval } from "@noy-db/hub/kernel";
1407
+ async function retrieveAcross(group, collectionName, query, opts = {}) {
1408
+ const { eligible, skipped } = await group.resolveEligible({
1409
+ ...opts.minVersion !== void 0 ? { minVersion: opts.minVersion } : {},
1410
+ ...opts.failFast !== void 0 ? { failFast: opts.failFast } : {}
1411
+ });
1412
+ const across = await group.db.queryAcross(
1413
+ eligible.map((r) => r.vaultId),
1414
+ async (vault) => {
1415
+ group.template.configure(vault);
1416
+ const coll = vault.collection(collectionName);
1417
+ let within;
1418
+ if (opts.where?.length) {
1419
+ let q = coll.query();
1420
+ for (const [f, op, v] of opts.where) q = q.where(f, op, v);
1421
+ within = q;
1422
+ }
1423
+ return coll.retrieve(query, {
1424
+ ...opts.mode ? { mode: opts.mode } : {},
1425
+ ...opts.limit !== void 0 ? { limit: opts.limit } : {},
1426
+ ...opts.minScore !== void 0 ? { minScore: opts.minScore } : {},
1427
+ ...opts.fields ? { fields: opts.fields } : {},
1428
+ ...opts.match ? { match: opts.match } : {},
1429
+ ...opts.prefix ? { prefix: opts.prefix } : {},
1430
+ ...opts.snippetWindow !== void 0 ? { snippetWindow: opts.snippetWindow } : {},
1431
+ ...opts.includeRecord ? { includeRecord: true } : {},
1432
+ ...within ? { within } : {}
1433
+ });
1434
+ },
1435
+ { concurrency: opts.concurrency ?? 1, create: false }
1436
+ );
1437
+ const skippedVaults = [...skipped];
1438
+ const perVault = [];
1439
+ for (const r of across) {
1440
+ if (r.error) {
1441
+ if (opts.failFast) throw r.error;
1442
+ skippedVaults.push({ vaultId: r.vault, reason: classifyShardSkip(r.error), error: r.error });
1443
+ } else {
1444
+ perVault.push({ vault: r.vault, hits: r.result });
1445
+ }
1446
+ }
1447
+ const lists = perVault.map((pv) => {
1448
+ if (pv.vault.includes(SEP)) {
1449
+ throw new Error(`retrieveAcross: vault id "${pv.vault}" contains the reserved NUL separator`);
1450
+ }
1451
+ return pv.hits.map((h) => ({ ...h, id: pv.vault + SEP + h.id }));
1452
+ });
1453
+ const fused = fuseRetrieval(lists, {
1454
+ ...opts.limit !== void 0 ? { limit: opts.limit } : {},
1455
+ ...opts.rrfK !== void 0 ? { k: opts.rrfK } : {}
1456
+ });
1457
+ const hits = fused.map((h) => {
1458
+ const i = h.id.indexOf(SEP);
1459
+ return { ...h, vault: h.id.slice(0, i), id: h.id.slice(i + 1) };
1460
+ });
1461
+ return { hits, skippedVaults };
1462
+ }
1463
+ var SEP;
1464
+ var init_retrieve_across = __esm({
1465
+ "src/federation/retrieve-across.ts"() {
1466
+ "use strict";
1467
+ init_classify_skip();
1468
+ SEP = "\0";
1469
+ }
1470
+ });
1471
+
1405
1472
  // src/federation/vault-group.ts
1406
1473
  var vault_group_exports = {};
1407
1474
  __export(vault_group_exports, {
@@ -1440,17 +1507,19 @@ var init_vault_group = __esm({
1440
1507
  init_cross_vault_live();
1441
1508
  init_insight_auto_push();
1442
1509
  init_aggregate_across();
1510
+ init_retrieve_across();
1443
1511
  init_partial_reduce();
1444
1512
  SHARD_SEPARATOR = "--";
1445
1513
  SAFE_PARTITION_KEY = /^[A-Za-z0-9._-]+$/;
1446
1514
  VaultGroup = class {
1447
- constructor(db, name, registry, sharding, template, cutoverOnOpen = false) {
1515
+ constructor(db, name, registry, sharding, template, cutoverOnOpen = false, meta) {
1448
1516
  this.db = db;
1449
1517
  this.name = name;
1450
1518
  this.registry = registry;
1451
1519
  this.sharding = sharding;
1452
1520
  this.template = template;
1453
1521
  this.cutoverOnOpen = cutoverOnOpen;
1522
+ this.meta = meta;
1454
1523
  if (name.includes(SHARD_SEPARATOR)) {
1455
1524
  throw new ValidationError(
1456
1525
  `VaultGroup name "${name}" must not contain "--" (reserved shard vault-id separator).`
@@ -1463,6 +1532,7 @@ var init_vault_group = __esm({
1463
1532
  sharding;
1464
1533
  template;
1465
1534
  cutoverOnOpen;
1535
+ meta;
1466
1536
  /** @internal — set when the group is managed (no explicit registry). */
1467
1537
  stateVault;
1468
1538
  /** @internal */
@@ -1496,6 +1566,30 @@ var init_vault_group = __esm({
1496
1566
  const rows = this.registry.query().toArray();
1497
1567
  return rows.filter((r) => r.group === this.name);
1498
1568
  }
1569
+ /**
1570
+ * Federation-level descriptive metadata (#27): this group's `meta` plus each
1571
+ * member vault's `vaultMeta` (read via `getMeta()`). Best-effort per shard — a
1572
+ * shard that fails to open yields `meta: undefined` for that entry, never
1573
+ * throwing. Member meta is transient per-open (noy-db sets it at `openVault`,
1574
+ * does not persist it); this surfaces whatever each vault was opened with.
1575
+ */
1576
+ async federationMeta() {
1577
+ const rows = await this.allRows();
1578
+ const vaults = await Promise.all(
1579
+ rows.map(async (row) => {
1580
+ let meta;
1581
+ try {
1582
+ const vault = await this.db.openVault(row.vaultId);
1583
+ this.template.configure(vault);
1584
+ meta = vault.getMeta();
1585
+ } catch {
1586
+ meta = void 0;
1587
+ }
1588
+ return { vaultId: row.vaultId, partitionKey: row.partitionKey, meta };
1589
+ })
1590
+ );
1591
+ return { meta: this.meta, vaults };
1592
+ }
1499
1593
  /**
1500
1594
  * Open an existing shard and apply the template. When `cutoverOnOpen` is set
1501
1595
  * (#271) and the shard's registry version is behind the template, its cutover
@@ -1857,6 +1951,17 @@ var init_vault_group = __esm({
1857
1951
  query() {
1858
1952
  return new ShardedQuery(this.group, this.collectionName, []);
1859
1953
  }
1954
+ /**
1955
+ * Cross-vault federated retrieval (#26): scatter-gather across all eligible
1956
+ * shards — each shard runs its own trusted-tier `retrieve()`, then results are
1957
+ * RRF-fused by rank only (no cross-vault statistics cross the DEK boundary).
1958
+ * Every hit carries its originating `vault`. An unreachable, schema-drifted, or
1959
+ * un-indexed shard is skipped (`skippedVaults`); pass `failFast` to re-throw
1960
+ * the first per-shard error instead.
1961
+ */
1962
+ async retrieve(query, opts = {}) {
1963
+ return retrieveAcross(this.group, this.collectionName, query, opts);
1964
+ }
1860
1965
  };
1861
1966
  ShardedQuery = class _ShardedQuery {
1862
1967
  constructor(group, collectionName, clauses, coPartitionedLegs = [], broadcastLegs = []) {
@@ -2252,7 +2357,7 @@ var Lobby = class {
2252
2357
  const { StateManagementVault: StateManagementVault2 } = await Promise.resolve().then(() => (init_state_vault(), state_vault_exports));
2253
2358
  const stateVault = opts.registry ? void 0 : await StateManagementVault2.open(db);
2254
2359
  const registry = opts.registry ?? stateVault.registry;
2255
- const group = new VaultGroup2(db, name, registry, opts.sharding, template, opts.cutoverOnOpen ?? false);
2360
+ const group = new VaultGroup2(db, name, registry, opts.sharding, template, opts.cutoverOnOpen ?? false, opts.meta);
2256
2361
  if (stateVault) {
2257
2362
  group._attachStateVault(stateVault);
2258
2363
  await stateVault.recordManifest(opts.sharding.vaultTemplate, template);