@klum-db/lobby 0.2.0-pre.30 → 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.
@@ -1,4 +1,4 @@
1
- import { Vault as Vault$1, IndexDef, Operator, LiveQuery, LiveAggregation, AggregateSpec, AggregateResult, Collection, Noydb, Query, JoinStrategy, ChangeEvent } from '@noy-db/hub/kernel';
1
+ import { Vault as Vault$1, VaultMeta, IndexDef, Operator, LiveQuery, LiveAggregation, AggregateSpec, AggregateResult, RetrieveHit, Collection, Noydb, Query, JoinStrategy, ChangeEvent } from '@noy-db/hub/kernel';
2
2
  import { Vault } from '@noy-db/hub';
3
3
  import { DecryptedRecord } from '@noy-db/hub/bundle';
4
4
 
@@ -154,6 +154,17 @@ declare function mergeCompartment(receiver: Vault, compartmentBytes: Uint8Array,
154
154
  * docs/superpowers/specs/2026-06-07-mvf-vaultgroup-routing-mvp-design.md.
155
155
  */
156
156
 
157
+ /** A federation group's own descriptive metadata (reuses the noy-db VaultMeta shape). */
158
+ type GroupMeta = VaultMeta;
159
+ /** Federation-level metadata: the group's own meta + each member vault's vaultMeta. */
160
+ interface FederationMeta {
161
+ readonly meta: GroupMeta | undefined;
162
+ readonly vaults: ReadonlyArray<{
163
+ readonly vaultId: string;
164
+ readonly partitionKey: string;
165
+ readonly meta: VaultMeta | undefined;
166
+ }>;
167
+ }
157
168
  /**
158
169
  * A schema blueprint for a class of shard vaults. `configure` is
159
170
  * re-applied to every shard handle so all shards are configured
@@ -210,6 +221,8 @@ interface VaultGroupOptions<T> {
210
221
  * Zero cost for shards never opened. Default `false` (use `rolloutSchema`).
211
222
  */
212
223
  readonly cutoverOnOpen?: boolean;
224
+ /** Descriptive group-level metadata (label/description/icon) for UIs. Descriptive-only. */
225
+ readonly meta?: GroupMeta;
213
226
  }
214
227
  /** Result of `VaultGroup.rolloutSchema` (#271 active batch runner). */
215
228
  interface SchemaRolloutResult {
@@ -241,6 +254,32 @@ interface FanoutResult<R> {
241
254
  readonly results: R[];
242
255
  readonly skippedVaults: SkippedVault[];
243
256
  }
257
+ /** Options for cross-vault federated retrieval (#26). Extends the fan-out base. */
258
+ interface FederatedRetrieveOptions extends FanoutQueryOptions {
259
+ readonly mode?: 'lexical' | 'semantic' | 'hybrid';
260
+ readonly limit?: number;
261
+ readonly minScore?: number;
262
+ readonly fields?: readonly string[];
263
+ readonly match?: 'any' | 'all';
264
+ readonly prefix?: boolean;
265
+ readonly snippetWindow?: number;
266
+ readonly includeRecord?: boolean;
267
+ /** Payload filter applied per-vault (retrieve ∩ where), rebuilt into each shard's `within`. */
268
+ readonly where?: ReadonlyArray<readonly [field: string, op: Operator, value: unknown]>;
269
+ /** RRF constant; default 60. */
270
+ readonly rrfK?: number;
271
+ /** Re-throw a per-shard retrieve() failure instead of skipping it. */
272
+ readonly failFast?: boolean;
273
+ }
274
+ /** A fused hit carrying the originating shard (provenance). */
275
+ interface FederatedRetrieveHit<R> extends RetrieveHit<R> {
276
+ readonly vault: string;
277
+ }
278
+ /** Result of `ShardedCollection.retrieve()`. */
279
+ interface FederatedRetrieveResult<R> {
280
+ readonly hits: FederatedRetrieveHit<R>[];
281
+ readonly skippedVaults: SkippedVault[];
282
+ }
244
283
  /** A single captured where-clause, replayed inside each shard. */
245
284
  interface WhereClause {
246
285
  readonly field: string;
@@ -511,12 +550,29 @@ interface BroadcastLeg {
511
550
  readonly mode: 'warn' | 'cascade';
512
551
  }
513
552
 
553
+ /**
554
+ * @category capability
555
+ * Distributed partial-reduce over the kernel Reducer protocol (#8). Each shard
556
+ * folds its own records to a partial STATE; states are merged centrally and
557
+ * finalized once — identical to central `reduceRecords` over the union, but
558
+ * without materializing the union. Used by the scalar `.aggregate().run()` path
559
+ * when every reducer exposes `merge` (else the caller falls back to central).
560
+ */
561
+
562
+ /** One opaque reducer state per spec key. */
563
+ type PartialState = Record<string, unknown>;
564
+
514
565
  /** A source that can fan out records across shards. Satisfied by ShardedQuery. */
515
566
  interface FanoutRecordSource<R> {
516
567
  fanoutRecords(options: FanoutQueryOptions): Promise<{
517
568
  records: R[];
518
569
  skippedVaults: SkippedVault[];
519
570
  }>;
571
+ /** Optional distributed partial-reduce (#8): fold each shard to a state in-callback. */
572
+ fanoutReduce?(spec: AggregateSpec, options: FanoutQueryOptions): Promise<{
573
+ partials: PartialState[];
574
+ skippedVaults: SkippedVault[];
575
+ }>;
520
576
  }
521
577
  /** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */
522
578
  interface LiveBinding {
@@ -524,8 +580,12 @@ interface LiveBinding {
524
580
  isRelevant: (e: ChangeEvent) => boolean;
525
581
  }
526
582
  /**
527
- * One-shot cross-vault aggregate. Concatenates all shard records and runs a
528
- * single central reduce, ensuring correct avg/mean values.
583
+ * One-shot cross-vault aggregate. When every reducer in the spec exposes the
584
+ * `merge` seam, `run()` uses **distributed partial-reduce** each shard folds
585
+ * its own records to a partial state, merged centrally and finalized once (no
586
+ * union materialized). A spec with any merge-less reducer falls back to
587
+ * central-reduce. The result is identical either way. `.live()` and grouped
588
+ * aggregates remain central-reduce.
529
589
  */
530
590
  declare class CrossVaultAggregation<R, Spec extends AggregateSpec> {
531
591
  private readonly src;
@@ -569,13 +629,15 @@ declare class VaultGroup<T> {
569
629
  /** @internal */ readonly sharding: ShardingConfig<T>;
570
630
  /** @internal */ readonly template: VaultTemplate;
571
631
  /** @internal — lazy cutover-on-open (#271). */ readonly cutoverOnOpen: boolean;
632
+ /** @internal — group-level descriptive metadata (#27). */ readonly meta?: GroupMeta | undefined;
572
633
  constructor(
573
634
  /** @internal */ db: Noydb,
574
635
  /** @internal */ name: string,
575
636
  /** @internal */ registry: Collection<VaultRegistryRow>,
576
637
  /** @internal */ sharding: ShardingConfig<T>,
577
638
  /** @internal */ template: VaultTemplate,
578
- /** @internal — lazy cutover-on-open (#271). */ cutoverOnOpen?: boolean);
639
+ /** @internal — lazy cutover-on-open (#271). */ cutoverOnOpen?: boolean,
640
+ /** @internal — group-level descriptive metadata (#27). */ meta?: GroupMeta | undefined);
579
641
  /** @internal — set when the group is managed (no explicit registry). */
580
642
  private stateVault;
581
643
  /** @internal */
@@ -598,6 +660,14 @@ declare class VaultGroup<T> {
598
660
  * `liveBinding().isRelevant` already applies to the reactive path.
599
661
  */
600
662
  allRows(): Promise<VaultRegistryRow[]>;
663
+ /**
664
+ * Federation-level descriptive metadata (#27): this group's `meta` plus each
665
+ * member vault's `vaultMeta` (read via `getMeta()`). Best-effort per shard — a
666
+ * shard that fails to open yields `meta: undefined` for that entry, never
667
+ * throwing. Member meta is transient per-open (noy-db sets it at `openVault`,
668
+ * does not persist it); this surfaces whatever each vault was opened with.
669
+ */
670
+ federationMeta(): Promise<FederationMeta>;
601
671
  /**
602
672
  * Open an existing shard and apply the template. When `cutoverOnOpen` is set
603
673
  * (#271) and the shard's registry version is behind the template, its cutover
@@ -627,9 +697,11 @@ declare class VaultGroup<T> {
627
697
  shard(partitionKey: string): Promise<Vault$1>;
628
698
  /** A sharded view over one logical collection across all shards. */
629
699
  collection<R = T>(collectionName: string): ShardedCollection<T, R>;
630
- /** @internal — eligible (openable-candidate) rows + drift/divergence skips. */
700
+ /** @internal — eligible (openable-candidate) rows + drift/divergence/unreachable skips. */
631
701
  resolveEligible(options?: {
632
702
  minVersion?: number;
703
+ only?: readonly string[];
704
+ failFast?: boolean;
633
705
  }): Promise<{
634
706
  eligible: VaultRegistryRow[];
635
707
  skipped: SkippedVault[];
@@ -671,11 +743,24 @@ declare class VaultGroup<T> {
671
743
  * Insight Vault keyed by partition key. Shards behind `minVersion`,
672
744
  * unprovisioned, or whose read errors are reported in `skippedVaults` and
673
745
  * are not written (a stale summary is never left behind for a failed shard).
746
+ * A shard whose backend is unreachable (provisioning probe or read throws) is
747
+ * **skipped** (`reason: 'error'`) and the pass continues for the others — its
748
+ * prior summary is left intact. Pass `failFast: true` for the legacy
749
+ * all-or-nothing throw. Reconcile a lagging shard later with
750
+ * `refreshInsights({ only: [pk] })` or `refreshDerivation(pk)`.
674
751
  */
675
752
  refreshInsights(options?: {
676
753
  minVersion?: number;
677
754
  concurrency?: number;
755
+ only?: readonly string[];
756
+ failFast?: boolean;
678
757
  }): Promise<RefreshInsightsResult>;
758
+ /**
759
+ * Reconcile one shard's Insight summaries after its backend was unreachable.
760
+ * Equivalent to `refreshInsights({ only: [partitionKey] })` — runs every
761
+ * registered derivation (autoPush or not) for just this shard.
762
+ */
763
+ refreshDerivation(partitionKey: string): Promise<RefreshInsightsResult>;
679
764
  /** @internal — re-derive + push every autoPush derivation's summary for one shard. */
680
765
  private _recomputeShardInsights;
681
766
  /**
@@ -721,6 +806,15 @@ declare class ShardedCollection<T, R = T> {
721
806
  put(id: string, record: T): Promise<void>;
722
807
  /** Begin a cross-shard fan-out query. */
723
808
  query(): ShardedQuery<T, R>;
809
+ /**
810
+ * Cross-vault federated retrieval (#26): scatter-gather across all eligible
811
+ * shards — each shard runs its own trusted-tier `retrieve()`, then results are
812
+ * RRF-fused by rank only (no cross-vault statistics cross the DEK boundary).
813
+ * Every hit carries its originating `vault`. An unreachable, schema-drifted, or
814
+ * un-indexed shard is skipped (`skippedVaults`); pass `failFast` to re-throw
815
+ * the first per-shard error instead.
816
+ */
817
+ retrieve(query: string, opts?: FederatedRetrieveOptions): Promise<FederatedRetrieveResult<R>>;
724
818
  }
725
819
  declare class ShardedQuery<T, R = T> {
726
820
  private readonly group;
@@ -739,6 +833,16 @@ declare class ShardedQuery<T, R = T> {
739
833
  records: R[];
740
834
  skippedVaults: SkippedVault[];
741
835
  }>;
836
+ /**
837
+ * @internal — distributed partial-reduce (#8). Fan out across eligible shards,
838
+ * but fold each shard's where-filtered records to a partial reducer STATE
839
+ * inside the per-shard callback (never returning the rows). Only the scalar
840
+ * `.aggregate()` path calls this, and that path rejects join legs upstream.
841
+ */
842
+ fanoutReduce(spec: AggregateSpec, options?: FanoutQueryOptions): Promise<{
843
+ partials: PartialState[];
844
+ skippedVaults: SkippedVault[];
845
+ }>;
742
846
  /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
743
847
  toArray(options?: FanoutQueryOptions): Promise<FanoutResult<R>>;
744
848
  /** @internal — build the change-subscription + relevance binding for this query's group+collection. */
@@ -760,4 +864,4 @@ declare class ShardedGroupedQuery<T, R, F extends string> {
760
864
  aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultGroupedAggregation<R, F, Spec>;
761
865
  }
762
866
 
763
- export { ShardedGroupedQuery as A, ShardedQuery as B, type CapturedBlueprint as C, type DecryptedMergeOptions as D, type ShardingConfig as E, type FanoutQueryOptions as F, type GroupedRow as G, type SurfaceStatus as H, type VaultRegistryRow as I, mergeCompartment as J, mergeDecryptedRecords as K, type LiveQueryOptions as L, type MergeCompartmentOptions as M, resolveFieldAuthority as N, resolveRecordByFieldAuthority as O, type RefreshInsightsResult as R, StateManagementVault as S, VaultGroup as V, type VaultTemplate as a, type SkippedVault as b, type MergeReport as c, type SurfaceDirection as d, type SurfaceConflictPolicy as e, type SurfaceRow as f, type VaultGroupOptions as g, CrossVaultAggregation as h, type CrossVaultDerivationContext as i, type CrossVaultDerivationSpec as j, CrossVaultGroupedAggregation as k, type CrossVaultLiveAggregation as l, type CrossVaultLiveQuery as m, type DeploymentEvent as n, type FanoutResult as o, type FieldAuthorityInputs as p, type FieldAuthorityPolicy as q, FieldAuthorityPolicyMissingError as r, type FieldAuthorityRule as s, FieldLevelDeferredError as t, type MergeConflict as u, type MergeStrategy as v, type MigrationStatusRow as w, type SchemaManifestRow as x, type SchemaRolloutResult as y, ShardedCollection as z };
867
+ export { type MergeStrategy as A, type MigrationStatusRow as B, type CapturedBlueprint as C, type DecryptedMergeOptions as D, type SchemaManifestRow as E, type FanoutQueryOptions as F, type GroupedRow as G, type SchemaRolloutResult as H, ShardedCollection as I, ShardedGroupedQuery as J, ShardedQuery as K, type LiveQueryOptions as L, type MergeCompartmentOptions as M, type ShardingConfig as N, type SurfaceStatus as O, type VaultRegistryRow as P, mergeCompartment as Q, type RefreshInsightsResult as R, StateManagementVault as S, mergeDecryptedRecords as T, resolveFieldAuthority as U, VaultGroup as V, resolveRecordByFieldAuthority as W, type VaultTemplate as a, type SkippedVault as b, type MergeReport as c, type SurfaceDirection as d, type SurfaceConflictPolicy as e, type SurfaceRow as f, type VaultGroupOptions as g, CrossVaultAggregation as h, type CrossVaultDerivationContext as i, type CrossVaultDerivationSpec as j, CrossVaultGroupedAggregation as k, type CrossVaultLiveAggregation as l, type CrossVaultLiveQuery as m, type DeploymentEvent as n, type FanoutResult as o, type FederatedRetrieveHit as p, type FederatedRetrieveOptions as q, type FederatedRetrieveResult as r, type FederationMeta as s, type FieldAuthorityInputs as t, type FieldAuthorityPolicy as u, FieldAuthorityPolicyMissingError as v, type FieldAuthorityRule as w, FieldLevelDeferredError as x, type GroupMeta as y, type MergeConflict as z };
@@ -1,4 +1,4 @@
1
- import { Vault as Vault$1, IndexDef, Operator, LiveQuery, LiveAggregation, AggregateSpec, AggregateResult, Collection, Noydb, Query, JoinStrategy, ChangeEvent } from '@noy-db/hub/kernel';
1
+ import { Vault as Vault$1, VaultMeta, IndexDef, Operator, LiveQuery, LiveAggregation, AggregateSpec, AggregateResult, RetrieveHit, Collection, Noydb, Query, JoinStrategy, ChangeEvent } from '@noy-db/hub/kernel';
2
2
  import { Vault } from '@noy-db/hub';
3
3
  import { DecryptedRecord } from '@noy-db/hub/bundle';
4
4
 
@@ -154,6 +154,17 @@ declare function mergeCompartment(receiver: Vault, compartmentBytes: Uint8Array,
154
154
  * docs/superpowers/specs/2026-06-07-mvf-vaultgroup-routing-mvp-design.md.
155
155
  */
156
156
 
157
+ /** A federation group's own descriptive metadata (reuses the noy-db VaultMeta shape). */
158
+ type GroupMeta = VaultMeta;
159
+ /** Federation-level metadata: the group's own meta + each member vault's vaultMeta. */
160
+ interface FederationMeta {
161
+ readonly meta: GroupMeta | undefined;
162
+ readonly vaults: ReadonlyArray<{
163
+ readonly vaultId: string;
164
+ readonly partitionKey: string;
165
+ readonly meta: VaultMeta | undefined;
166
+ }>;
167
+ }
157
168
  /**
158
169
  * A schema blueprint for a class of shard vaults. `configure` is
159
170
  * re-applied to every shard handle so all shards are configured
@@ -210,6 +221,8 @@ interface VaultGroupOptions<T> {
210
221
  * Zero cost for shards never opened. Default `false` (use `rolloutSchema`).
211
222
  */
212
223
  readonly cutoverOnOpen?: boolean;
224
+ /** Descriptive group-level metadata (label/description/icon) for UIs. Descriptive-only. */
225
+ readonly meta?: GroupMeta;
213
226
  }
214
227
  /** Result of `VaultGroup.rolloutSchema` (#271 active batch runner). */
215
228
  interface SchemaRolloutResult {
@@ -241,6 +254,32 @@ interface FanoutResult<R> {
241
254
  readonly results: R[];
242
255
  readonly skippedVaults: SkippedVault[];
243
256
  }
257
+ /** Options for cross-vault federated retrieval (#26). Extends the fan-out base. */
258
+ interface FederatedRetrieveOptions extends FanoutQueryOptions {
259
+ readonly mode?: 'lexical' | 'semantic' | 'hybrid';
260
+ readonly limit?: number;
261
+ readonly minScore?: number;
262
+ readonly fields?: readonly string[];
263
+ readonly match?: 'any' | 'all';
264
+ readonly prefix?: boolean;
265
+ readonly snippetWindow?: number;
266
+ readonly includeRecord?: boolean;
267
+ /** Payload filter applied per-vault (retrieve ∩ where), rebuilt into each shard's `within`. */
268
+ readonly where?: ReadonlyArray<readonly [field: string, op: Operator, value: unknown]>;
269
+ /** RRF constant; default 60. */
270
+ readonly rrfK?: number;
271
+ /** Re-throw a per-shard retrieve() failure instead of skipping it. */
272
+ readonly failFast?: boolean;
273
+ }
274
+ /** A fused hit carrying the originating shard (provenance). */
275
+ interface FederatedRetrieveHit<R> extends RetrieveHit<R> {
276
+ readonly vault: string;
277
+ }
278
+ /** Result of `ShardedCollection.retrieve()`. */
279
+ interface FederatedRetrieveResult<R> {
280
+ readonly hits: FederatedRetrieveHit<R>[];
281
+ readonly skippedVaults: SkippedVault[];
282
+ }
244
283
  /** A single captured where-clause, replayed inside each shard. */
245
284
  interface WhereClause {
246
285
  readonly field: string;
@@ -511,12 +550,29 @@ interface BroadcastLeg {
511
550
  readonly mode: 'warn' | 'cascade';
512
551
  }
513
552
 
553
+ /**
554
+ * @category capability
555
+ * Distributed partial-reduce over the kernel Reducer protocol (#8). Each shard
556
+ * folds its own records to a partial STATE; states are merged centrally and
557
+ * finalized once — identical to central `reduceRecords` over the union, but
558
+ * without materializing the union. Used by the scalar `.aggregate().run()` path
559
+ * when every reducer exposes `merge` (else the caller falls back to central).
560
+ */
561
+
562
+ /** One opaque reducer state per spec key. */
563
+ type PartialState = Record<string, unknown>;
564
+
514
565
  /** A source that can fan out records across shards. Satisfied by ShardedQuery. */
515
566
  interface FanoutRecordSource<R> {
516
567
  fanoutRecords(options: FanoutQueryOptions): Promise<{
517
568
  records: R[];
518
569
  skippedVaults: SkippedVault[];
519
570
  }>;
571
+ /** Optional distributed partial-reduce (#8): fold each shard to a state in-callback. */
572
+ fanoutReduce?(spec: AggregateSpec, options: FanoutQueryOptions): Promise<{
573
+ partials: PartialState[];
574
+ skippedVaults: SkippedVault[];
575
+ }>;
520
576
  }
521
577
  /** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */
522
578
  interface LiveBinding {
@@ -524,8 +580,12 @@ interface LiveBinding {
524
580
  isRelevant: (e: ChangeEvent) => boolean;
525
581
  }
526
582
  /**
527
- * One-shot cross-vault aggregate. Concatenates all shard records and runs a
528
- * single central reduce, ensuring correct avg/mean values.
583
+ * One-shot cross-vault aggregate. When every reducer in the spec exposes the
584
+ * `merge` seam, `run()` uses **distributed partial-reduce** each shard folds
585
+ * its own records to a partial state, merged centrally and finalized once (no
586
+ * union materialized). A spec with any merge-less reducer falls back to
587
+ * central-reduce. The result is identical either way. `.live()` and grouped
588
+ * aggregates remain central-reduce.
529
589
  */
530
590
  declare class CrossVaultAggregation<R, Spec extends AggregateSpec> {
531
591
  private readonly src;
@@ -569,13 +629,15 @@ declare class VaultGroup<T> {
569
629
  /** @internal */ readonly sharding: ShardingConfig<T>;
570
630
  /** @internal */ readonly template: VaultTemplate;
571
631
  /** @internal — lazy cutover-on-open (#271). */ readonly cutoverOnOpen: boolean;
632
+ /** @internal — group-level descriptive metadata (#27). */ readonly meta?: GroupMeta | undefined;
572
633
  constructor(
573
634
  /** @internal */ db: Noydb,
574
635
  /** @internal */ name: string,
575
636
  /** @internal */ registry: Collection<VaultRegistryRow>,
576
637
  /** @internal */ sharding: ShardingConfig<T>,
577
638
  /** @internal */ template: VaultTemplate,
578
- /** @internal — lazy cutover-on-open (#271). */ cutoverOnOpen?: boolean);
639
+ /** @internal — lazy cutover-on-open (#271). */ cutoverOnOpen?: boolean,
640
+ /** @internal — group-level descriptive metadata (#27). */ meta?: GroupMeta | undefined);
579
641
  /** @internal — set when the group is managed (no explicit registry). */
580
642
  private stateVault;
581
643
  /** @internal */
@@ -598,6 +660,14 @@ declare class VaultGroup<T> {
598
660
  * `liveBinding().isRelevant` already applies to the reactive path.
599
661
  */
600
662
  allRows(): Promise<VaultRegistryRow[]>;
663
+ /**
664
+ * Federation-level descriptive metadata (#27): this group's `meta` plus each
665
+ * member vault's `vaultMeta` (read via `getMeta()`). Best-effort per shard — a
666
+ * shard that fails to open yields `meta: undefined` for that entry, never
667
+ * throwing. Member meta is transient per-open (noy-db sets it at `openVault`,
668
+ * does not persist it); this surfaces whatever each vault was opened with.
669
+ */
670
+ federationMeta(): Promise<FederationMeta>;
601
671
  /**
602
672
  * Open an existing shard and apply the template. When `cutoverOnOpen` is set
603
673
  * (#271) and the shard's registry version is behind the template, its cutover
@@ -627,9 +697,11 @@ declare class VaultGroup<T> {
627
697
  shard(partitionKey: string): Promise<Vault$1>;
628
698
  /** A sharded view over one logical collection across all shards. */
629
699
  collection<R = T>(collectionName: string): ShardedCollection<T, R>;
630
- /** @internal — eligible (openable-candidate) rows + drift/divergence skips. */
700
+ /** @internal — eligible (openable-candidate) rows + drift/divergence/unreachable skips. */
631
701
  resolveEligible(options?: {
632
702
  minVersion?: number;
703
+ only?: readonly string[];
704
+ failFast?: boolean;
633
705
  }): Promise<{
634
706
  eligible: VaultRegistryRow[];
635
707
  skipped: SkippedVault[];
@@ -671,11 +743,24 @@ declare class VaultGroup<T> {
671
743
  * Insight Vault keyed by partition key. Shards behind `minVersion`,
672
744
  * unprovisioned, or whose read errors are reported in `skippedVaults` and
673
745
  * are not written (a stale summary is never left behind for a failed shard).
746
+ * A shard whose backend is unreachable (provisioning probe or read throws) is
747
+ * **skipped** (`reason: 'error'`) and the pass continues for the others — its
748
+ * prior summary is left intact. Pass `failFast: true` for the legacy
749
+ * all-or-nothing throw. Reconcile a lagging shard later with
750
+ * `refreshInsights({ only: [pk] })` or `refreshDerivation(pk)`.
674
751
  */
675
752
  refreshInsights(options?: {
676
753
  minVersion?: number;
677
754
  concurrency?: number;
755
+ only?: readonly string[];
756
+ failFast?: boolean;
678
757
  }): Promise<RefreshInsightsResult>;
758
+ /**
759
+ * Reconcile one shard's Insight summaries after its backend was unreachable.
760
+ * Equivalent to `refreshInsights({ only: [partitionKey] })` — runs every
761
+ * registered derivation (autoPush or not) for just this shard.
762
+ */
763
+ refreshDerivation(partitionKey: string): Promise<RefreshInsightsResult>;
679
764
  /** @internal — re-derive + push every autoPush derivation's summary for one shard. */
680
765
  private _recomputeShardInsights;
681
766
  /**
@@ -721,6 +806,15 @@ declare class ShardedCollection<T, R = T> {
721
806
  put(id: string, record: T): Promise<void>;
722
807
  /** Begin a cross-shard fan-out query. */
723
808
  query(): ShardedQuery<T, R>;
809
+ /**
810
+ * Cross-vault federated retrieval (#26): scatter-gather across all eligible
811
+ * shards — each shard runs its own trusted-tier `retrieve()`, then results are
812
+ * RRF-fused by rank only (no cross-vault statistics cross the DEK boundary).
813
+ * Every hit carries its originating `vault`. An unreachable, schema-drifted, or
814
+ * un-indexed shard is skipped (`skippedVaults`); pass `failFast` to re-throw
815
+ * the first per-shard error instead.
816
+ */
817
+ retrieve(query: string, opts?: FederatedRetrieveOptions): Promise<FederatedRetrieveResult<R>>;
724
818
  }
725
819
  declare class ShardedQuery<T, R = T> {
726
820
  private readonly group;
@@ -739,6 +833,16 @@ declare class ShardedQuery<T, R = T> {
739
833
  records: R[];
740
834
  skippedVaults: SkippedVault[];
741
835
  }>;
836
+ /**
837
+ * @internal — distributed partial-reduce (#8). Fan out across eligible shards,
838
+ * but fold each shard's where-filtered records to a partial reducer STATE
839
+ * inside the per-shard callback (never returning the rows). Only the scalar
840
+ * `.aggregate()` path calls this, and that path rejects join legs upstream.
841
+ */
842
+ fanoutReduce(spec: AggregateSpec, options?: FanoutQueryOptions): Promise<{
843
+ partials: PartialState[];
844
+ skippedVaults: SkippedVault[];
845
+ }>;
742
846
  /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
743
847
  toArray(options?: FanoutQueryOptions): Promise<FanoutResult<R>>;
744
848
  /** @internal — build the change-subscription + relevance binding for this query's group+collection. */
@@ -760,4 +864,4 @@ declare class ShardedGroupedQuery<T, R, F extends string> {
760
864
  aggregate<Spec extends AggregateSpec>(spec: Spec): CrossVaultGroupedAggregation<R, F, Spec>;
761
865
  }
762
866
 
763
- export { ShardedGroupedQuery as A, ShardedQuery as B, type CapturedBlueprint as C, type DecryptedMergeOptions as D, type ShardingConfig as E, type FanoutQueryOptions as F, type GroupedRow as G, type SurfaceStatus as H, type VaultRegistryRow as I, mergeCompartment as J, mergeDecryptedRecords as K, type LiveQueryOptions as L, type MergeCompartmentOptions as M, resolveFieldAuthority as N, resolveRecordByFieldAuthority as O, type RefreshInsightsResult as R, StateManagementVault as S, VaultGroup as V, type VaultTemplate as a, type SkippedVault as b, type MergeReport as c, type SurfaceDirection as d, type SurfaceConflictPolicy as e, type SurfaceRow as f, type VaultGroupOptions as g, CrossVaultAggregation as h, type CrossVaultDerivationContext as i, type CrossVaultDerivationSpec as j, CrossVaultGroupedAggregation as k, type CrossVaultLiveAggregation as l, type CrossVaultLiveQuery as m, type DeploymentEvent as n, type FanoutResult as o, type FieldAuthorityInputs as p, type FieldAuthorityPolicy as q, FieldAuthorityPolicyMissingError as r, type FieldAuthorityRule as s, FieldLevelDeferredError as t, type MergeConflict as u, type MergeStrategy as v, type MigrationStatusRow as w, type SchemaManifestRow as x, type SchemaRolloutResult as y, ShardedCollection as z };
867
+ export { type MergeStrategy as A, type MigrationStatusRow as B, type CapturedBlueprint as C, type DecryptedMergeOptions as D, type SchemaManifestRow as E, type FanoutQueryOptions as F, type GroupedRow as G, type SchemaRolloutResult as H, ShardedCollection as I, ShardedGroupedQuery as J, ShardedQuery as K, type LiveQueryOptions as L, type MergeCompartmentOptions as M, type ShardingConfig as N, type SurfaceStatus as O, type VaultRegistryRow as P, mergeCompartment as Q, type RefreshInsightsResult as R, StateManagementVault as S, mergeDecryptedRecords as T, resolveFieldAuthority as U, VaultGroup as V, resolveRecordByFieldAuthority as W, type VaultTemplate as a, type SkippedVault as b, type MergeReport as c, type SurfaceDirection as d, type SurfaceConflictPolicy as e, type SurfaceRow as f, type VaultGroupOptions as g, CrossVaultAggregation as h, type CrossVaultDerivationContext as i, type CrossVaultDerivationSpec as j, CrossVaultGroupedAggregation as k, type CrossVaultLiveAggregation as l, type CrossVaultLiveQuery as m, type DeploymentEvent as n, type FanoutResult as o, type FederatedRetrieveHit as p, type FederatedRetrieveOptions as q, type FederatedRetrieveResult as r, type FederationMeta as s, type FieldAuthorityInputs as t, type FieldAuthorityPolicy as u, FieldAuthorityPolicyMissingError as v, type FieldAuthorityRule as w, FieldLevelDeferredError as x, type GroupMeta as y, type MergeConflict as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klum-db/lobby",
3
- "version": "0.2.0-pre.30",
3
+ "version": "0.2.0-pre.32",
4
4
  "description": "klum-db Lobby — orchestrates a group of sovereign noy-db vaults (federation, interchange, custody). The outward framework to noy-db's inward vault.",
5
5
  "license": "MIT",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
@@ -41,10 +41,10 @@
41
41
  "node": ">=18.0.0"
42
42
  },
43
43
  "peerDependencies": {
44
- "@noy-db/as-xlsx": "^0.2.0-pre.26",
45
- "@noy-db/hub": "^0.2.0-pre.26",
46
- "@noy-db/in-devtools": "^0.2.0-pre.26",
47
- "@noy-db/to-meter": "^0.2.0-pre.26"
44
+ "@noy-db/as-xlsx": "^0.2.0-pre.29",
45
+ "@noy-db/hub": "^0.2.0-pre.29",
46
+ "@noy-db/in-devtools": "^0.2.0-pre.29",
47
+ "@noy-db/to-meter": "^0.2.0-pre.29"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "@noy-db/in-devtools": {
@@ -56,12 +56,12 @@
56
56
  },
57
57
  "devDependencies": {
58
58
  "@eslint/js": "^9.18.0",
59
- "@noy-db/as-xlsx": "0.2.0-pre.26",
60
- "@noy-db/as-zip": "0.2.0-pre.26",
61
- "@noy-db/hub": "0.2.0-pre.26",
62
- "@noy-db/in-devtools": "0.2.0-pre.26",
63
- "@noy-db/to-memory": "0.2.0-pre.26",
64
- "@noy-db/to-meter": "0.2.0-pre.26",
59
+ "@noy-db/as-xlsx": "0.2.0-pre.30",
60
+ "@noy-db/as-zip": "0.2.0-pre.30",
61
+ "@noy-db/hub": "0.2.0-pre.30",
62
+ "@noy-db/in-devtools": "0.2.0-pre.30",
63
+ "@noy-db/to-memory": "0.2.0-pre.30",
64
+ "@noy-db/to-meter": "0.2.0-pre.30",
65
65
  "@types/node": "^22.0.0",
66
66
  "eslint": "^9.18.0",
67
67
  "tsup": "^8.4.0",