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

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.
@@ -511,12 +511,29 @@ interface BroadcastLeg {
511
511
  readonly mode: 'warn' | 'cascade';
512
512
  }
513
513
 
514
+ /**
515
+ * @category capability
516
+ * Distributed partial-reduce over the kernel Reducer protocol (#8). Each shard
517
+ * folds its own records to a partial STATE; states are merged centrally and
518
+ * finalized once — identical to central `reduceRecords` over the union, but
519
+ * without materializing the union. Used by the scalar `.aggregate().run()` path
520
+ * when every reducer exposes `merge` (else the caller falls back to central).
521
+ */
522
+
523
+ /** One opaque reducer state per spec key. */
524
+ type PartialState = Record<string, unknown>;
525
+
514
526
  /** A source that can fan out records across shards. Satisfied by ShardedQuery. */
515
527
  interface FanoutRecordSource<R> {
516
528
  fanoutRecords(options: FanoutQueryOptions): Promise<{
517
529
  records: R[];
518
530
  skippedVaults: SkippedVault[];
519
531
  }>;
532
+ /** Optional distributed partial-reduce (#8): fold each shard to a state in-callback. */
533
+ fanoutReduce?(spec: AggregateSpec, options: FanoutQueryOptions): Promise<{
534
+ partials: PartialState[];
535
+ skippedVaults: SkippedVault[];
536
+ }>;
520
537
  }
521
538
  /** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */
522
539
  interface LiveBinding {
@@ -524,8 +541,12 @@ interface LiveBinding {
524
541
  isRelevant: (e: ChangeEvent) => boolean;
525
542
  }
526
543
  /**
527
- * One-shot cross-vault aggregate. Concatenates all shard records and runs a
528
- * single central reduce, ensuring correct avg/mean values.
544
+ * One-shot cross-vault aggregate. When every reducer in the spec exposes the
545
+ * `merge` seam, `run()` uses **distributed partial-reduce** each shard folds
546
+ * its own records to a partial state, merged centrally and finalized once (no
547
+ * union materialized). A spec with any merge-less reducer falls back to
548
+ * central-reduce. The result is identical either way. `.live()` and grouped
549
+ * aggregates remain central-reduce.
529
550
  */
530
551
  declare class CrossVaultAggregation<R, Spec extends AggregateSpec> {
531
552
  private readonly src;
@@ -627,9 +648,11 @@ declare class VaultGroup<T> {
627
648
  shard(partitionKey: string): Promise<Vault$1>;
628
649
  /** A sharded view over one logical collection across all shards. */
629
650
  collection<R = T>(collectionName: string): ShardedCollection<T, R>;
630
- /** @internal — eligible (openable-candidate) rows + drift/divergence skips. */
651
+ /** @internal — eligible (openable-candidate) rows + drift/divergence/unreachable skips. */
631
652
  resolveEligible(options?: {
632
653
  minVersion?: number;
654
+ only?: readonly string[];
655
+ failFast?: boolean;
633
656
  }): Promise<{
634
657
  eligible: VaultRegistryRow[];
635
658
  skipped: SkippedVault[];
@@ -671,11 +694,24 @@ declare class VaultGroup<T> {
671
694
  * Insight Vault keyed by partition key. Shards behind `minVersion`,
672
695
  * unprovisioned, or whose read errors are reported in `skippedVaults` and
673
696
  * are not written (a stale summary is never left behind for a failed shard).
697
+ * A shard whose backend is unreachable (provisioning probe or read throws) is
698
+ * **skipped** (`reason: 'error'`) and the pass continues for the others — its
699
+ * prior summary is left intact. Pass `failFast: true` for the legacy
700
+ * all-or-nothing throw. Reconcile a lagging shard later with
701
+ * `refreshInsights({ only: [pk] })` or `refreshDerivation(pk)`.
674
702
  */
675
703
  refreshInsights(options?: {
676
704
  minVersion?: number;
677
705
  concurrency?: number;
706
+ only?: readonly string[];
707
+ failFast?: boolean;
678
708
  }): Promise<RefreshInsightsResult>;
709
+ /**
710
+ * Reconcile one shard's Insight summaries after its backend was unreachable.
711
+ * Equivalent to `refreshInsights({ only: [partitionKey] })` — runs every
712
+ * registered derivation (autoPush or not) for just this shard.
713
+ */
714
+ refreshDerivation(partitionKey: string): Promise<RefreshInsightsResult>;
679
715
  /** @internal — re-derive + push every autoPush derivation's summary for one shard. */
680
716
  private _recomputeShardInsights;
681
717
  /**
@@ -739,6 +775,16 @@ declare class ShardedQuery<T, R = T> {
739
775
  records: R[];
740
776
  skippedVaults: SkippedVault[];
741
777
  }>;
778
+ /**
779
+ * @internal — distributed partial-reduce (#8). Fan out across eligible shards,
780
+ * but fold each shard's where-filtered records to a partial reducer STATE
781
+ * inside the per-shard callback (never returning the rows). Only the scalar
782
+ * `.aggregate()` path calls this, and that path rejects join legs upstream.
783
+ */
784
+ fanoutReduce(spec: AggregateSpec, options?: FanoutQueryOptions): Promise<{
785
+ partials: PartialState[];
786
+ skippedVaults: SkippedVault[];
787
+ }>;
742
788
  /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
743
789
  toArray(options?: FanoutQueryOptions): Promise<FanoutResult<R>>;
744
790
  /** @internal — build the change-subscription + relevance binding for this query's group+collection. */
@@ -511,12 +511,29 @@ interface BroadcastLeg {
511
511
  readonly mode: 'warn' | 'cascade';
512
512
  }
513
513
 
514
+ /**
515
+ * @category capability
516
+ * Distributed partial-reduce over the kernel Reducer protocol (#8). Each shard
517
+ * folds its own records to a partial STATE; states are merged centrally and
518
+ * finalized once — identical to central `reduceRecords` over the union, but
519
+ * without materializing the union. Used by the scalar `.aggregate().run()` path
520
+ * when every reducer exposes `merge` (else the caller falls back to central).
521
+ */
522
+
523
+ /** One opaque reducer state per spec key. */
524
+ type PartialState = Record<string, unknown>;
525
+
514
526
  /** A source that can fan out records across shards. Satisfied by ShardedQuery. */
515
527
  interface FanoutRecordSource<R> {
516
528
  fanoutRecords(options: FanoutQueryOptions): Promise<{
517
529
  records: R[];
518
530
  skippedVaults: SkippedVault[];
519
531
  }>;
532
+ /** Optional distributed partial-reduce (#8): fold each shard to a state in-callback. */
533
+ fanoutReduce?(spec: AggregateSpec, options: FanoutQueryOptions): Promise<{
534
+ partials: PartialState[];
535
+ skippedVaults: SkippedVault[];
536
+ }>;
520
537
  }
521
538
  /** Live-binding hooks (change subscription + relevance) threaded from ShardedQuery. */
522
539
  interface LiveBinding {
@@ -524,8 +541,12 @@ interface LiveBinding {
524
541
  isRelevant: (e: ChangeEvent) => boolean;
525
542
  }
526
543
  /**
527
- * One-shot cross-vault aggregate. Concatenates all shard records and runs a
528
- * single central reduce, ensuring correct avg/mean values.
544
+ * One-shot cross-vault aggregate. When every reducer in the spec exposes the
545
+ * `merge` seam, `run()` uses **distributed partial-reduce** each shard folds
546
+ * its own records to a partial state, merged centrally and finalized once (no
547
+ * union materialized). A spec with any merge-less reducer falls back to
548
+ * central-reduce. The result is identical either way. `.live()` and grouped
549
+ * aggregates remain central-reduce.
529
550
  */
530
551
  declare class CrossVaultAggregation<R, Spec extends AggregateSpec> {
531
552
  private readonly src;
@@ -627,9 +648,11 @@ declare class VaultGroup<T> {
627
648
  shard(partitionKey: string): Promise<Vault$1>;
628
649
  /** A sharded view over one logical collection across all shards. */
629
650
  collection<R = T>(collectionName: string): ShardedCollection<T, R>;
630
- /** @internal — eligible (openable-candidate) rows + drift/divergence skips. */
651
+ /** @internal — eligible (openable-candidate) rows + drift/divergence/unreachable skips. */
631
652
  resolveEligible(options?: {
632
653
  minVersion?: number;
654
+ only?: readonly string[];
655
+ failFast?: boolean;
633
656
  }): Promise<{
634
657
  eligible: VaultRegistryRow[];
635
658
  skipped: SkippedVault[];
@@ -671,11 +694,24 @@ declare class VaultGroup<T> {
671
694
  * Insight Vault keyed by partition key. Shards behind `minVersion`,
672
695
  * unprovisioned, or whose read errors are reported in `skippedVaults` and
673
696
  * are not written (a stale summary is never left behind for a failed shard).
697
+ * A shard whose backend is unreachable (provisioning probe or read throws) is
698
+ * **skipped** (`reason: 'error'`) and the pass continues for the others — its
699
+ * prior summary is left intact. Pass `failFast: true` for the legacy
700
+ * all-or-nothing throw. Reconcile a lagging shard later with
701
+ * `refreshInsights({ only: [pk] })` or `refreshDerivation(pk)`.
674
702
  */
675
703
  refreshInsights(options?: {
676
704
  minVersion?: number;
677
705
  concurrency?: number;
706
+ only?: readonly string[];
707
+ failFast?: boolean;
678
708
  }): Promise<RefreshInsightsResult>;
709
+ /**
710
+ * Reconcile one shard's Insight summaries after its backend was unreachable.
711
+ * Equivalent to `refreshInsights({ only: [partitionKey] })` — runs every
712
+ * registered derivation (autoPush or not) for just this shard.
713
+ */
714
+ refreshDerivation(partitionKey: string): Promise<RefreshInsightsResult>;
679
715
  /** @internal — re-derive + push every autoPush derivation's summary for one shard. */
680
716
  private _recomputeShardInsights;
681
717
  /**
@@ -739,6 +775,16 @@ declare class ShardedQuery<T, R = T> {
739
775
  records: R[];
740
776
  skippedVaults: SkippedVault[];
741
777
  }>;
778
+ /**
779
+ * @internal — distributed partial-reduce (#8). Fan out across eligible shards,
780
+ * but fold each shard's where-filtered records to a partial reducer STATE
781
+ * inside the per-shard callback (never returning the rows). Only the scalar
782
+ * `.aggregate()` path calls this, and that path rejects join legs upstream.
783
+ */
784
+ fanoutReduce(spec: AggregateSpec, options?: FanoutQueryOptions): Promise<{
785
+ partials: PartialState[];
786
+ skippedVaults: SkippedVault[];
787
+ }>;
742
788
  /** Fan out across eligible shards, merge, then apply any broadcast dimension legs. */
743
789
  toArray(options?: FanoutQueryOptions): Promise<FanoutResult<R>>;
744
790
  /** @internal — build the change-subscription + relevance binding for this query's group+collection. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@klum-db/lobby",
3
- "version": "0.2.0-pre.29",
3
+ "version": "0.2.0-pre.31",
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>",
@@ -46,6 +46,14 @@
46
46
  "@noy-db/in-devtools": "^0.2.0-pre.26",
47
47
  "@noy-db/to-meter": "^0.2.0-pre.26"
48
48
  },
49
+ "peerDependenciesMeta": {
50
+ "@noy-db/in-devtools": {
51
+ "optional": true
52
+ },
53
+ "@noy-db/to-meter": {
54
+ "optional": true
55
+ }
56
+ },
49
57
  "devDependencies": {
50
58
  "@eslint/js": "^9.18.0",
51
59
  "@noy-db/as-xlsx": "0.2.0-pre.26",