@graphrefly/graphrefly 0.7.0 → 0.9.0

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.
Files changed (66) hide show
  1. package/dist/{chunk-L4J2K2RT.js → chunk-A2AJJOSJ.js} +3 -3
  2. package/dist/{chunk-ISGMZ2T3.js → chunk-E7OH6ZAZ.js} +3 -3
  3. package/dist/{chunk-47YJEZUJ.js → chunk-LR2CLSEF.js} +2 -2
  4. package/dist/{chunk-3EVXOI5C.js → chunk-QTZSBQGJ.js} +35 -21
  5. package/dist/chunk-QTZSBQGJ.js.map +1 -0
  6. package/dist/{chunk-ONLYF6GA.js → chunk-TZLX4KIT.js} +3 -3
  7. package/dist/{chunk-FGLZ5QID.js → chunk-UCW3VWMN.js} +4 -4
  8. package/dist/{chunk-BLCXEMAD.js → chunk-WYI7YW54.js} +16 -8
  9. package/dist/chunk-WYI7YW54.js.map +1 -0
  10. package/dist/{chunk-OSR3G3DP.js → chunk-XCZPGOVP.js} +3 -3
  11. package/dist/{chunk-PEBORXRA.js → chunk-YWTP2XRJ.js} +2 -2
  12. package/dist/compat/nestjs/index.cjs +47 -25
  13. package/dist/compat/nestjs/index.cjs.map +1 -1
  14. package/dist/compat/nestjs/index.d.cts +3 -3
  15. package/dist/compat/nestjs/index.d.ts +3 -3
  16. package/dist/compat/nestjs/index.js +7 -7
  17. package/dist/core/index.cjs +34 -20
  18. package/dist/core/index.cjs.map +1 -1
  19. package/dist/core/index.d.cts +1 -1
  20. package/dist/core/index.d.ts +1 -1
  21. package/dist/core/index.js +3 -3
  22. package/dist/extra/index.cjs +34 -20
  23. package/dist/extra/index.cjs.map +1 -1
  24. package/dist/extra/index.d.cts +3 -3
  25. package/dist/extra/index.d.ts +3 -3
  26. package/dist/extra/index.js +3 -3
  27. package/dist/graph/index.cjs +47 -25
  28. package/dist/graph/index.cjs.map +1 -1
  29. package/dist/graph/index.d.cts +2 -2
  30. package/dist/graph/index.d.ts +2 -2
  31. package/dist/graph/index.js +4 -4
  32. package/dist/{graph-B3BoJjcb.d.cts → graph-DqTICAY2.d.cts} +11 -5
  33. package/dist/{graph-CmiUuhaN.d.ts → graph-X9uwnD_z.d.ts} +11 -5
  34. package/dist/{index-D0cx-Yht.d.cts → index-3U0WxdD-.d.cts} +1 -1
  35. package/dist/{index-D1hgSTzr.d.cts → index-BP1t_38S.d.cts} +2 -2
  36. package/dist/{index-CsUq2rrK.d.ts → index-BPCeYDS4.d.ts} +1 -1
  37. package/dist/{index-BrgtEG-C.d.ts → index-BVG5pjin.d.ts} +3 -1
  38. package/dist/{index-D8NIq6om.d.cts → index-BYEgosAX.d.cts} +3 -1
  39. package/dist/{index-BsuKSs4L.d.cts → index-BYa2YMat.d.cts} +2 -2
  40. package/dist/{index-DFFNKYig.d.ts → index-DLO8wnYU.d.ts} +2 -2
  41. package/dist/{index-Bf2X1YSI.d.ts → index-DMv1Etbi.d.ts} +1 -1
  42. package/dist/{index-Bl7hJcc3.d.cts → index-DbwgQ4Cw.d.cts} +1 -1
  43. package/dist/{index-Pm68AYPh.d.ts → index-a5gHmH5b.d.ts} +2 -2
  44. package/dist/index.cjs +322 -26
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +200 -25
  47. package/dist/index.d.ts +200 -25
  48. package/dist/index.js +291 -18
  49. package/dist/index.js.map +1 -1
  50. package/dist/patterns/reactive-layout/index.cjs +47 -25
  51. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  52. package/dist/patterns/reactive-layout/index.d.cts +2 -2
  53. package/dist/patterns/reactive-layout/index.d.ts +2 -2
  54. package/dist/patterns/reactive-layout/index.js +4 -4
  55. package/dist/{reactive-log-CAXzJ7hw.d.cts → reactive-log-BfX6bOSZ.d.cts} +1 -1
  56. package/dist/{reactive-log-DwNhOe0g.d.ts → reactive-log-RhgIog2Z.d.ts} +1 -1
  57. package/package.json +1 -1
  58. package/dist/chunk-3EVXOI5C.js.map +0 -1
  59. package/dist/chunk-BLCXEMAD.js.map +0 -1
  60. /package/dist/{chunk-L4J2K2RT.js.map → chunk-A2AJJOSJ.js.map} +0 -0
  61. /package/dist/{chunk-ISGMZ2T3.js.map → chunk-E7OH6ZAZ.js.map} +0 -0
  62. /package/dist/{chunk-47YJEZUJ.js.map → chunk-LR2CLSEF.js.map} +0 -0
  63. /package/dist/{chunk-ONLYF6GA.js.map → chunk-TZLX4KIT.js.map} +0 -0
  64. /package/dist/{chunk-FGLZ5QID.js.map → chunk-UCW3VWMN.js.map} +0 -0
  65. /package/dist/{chunk-OSR3G3DP.js.map → chunk-XCZPGOVP.js.map} +0 -0
  66. /package/dist/{chunk-PEBORXRA.js.map → chunk-YWTP2XRJ.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -237,6 +237,7 @@ __export(index_exports, {
237
237
  reactiveLog: () => reactiveLog,
238
238
  reactiveMap: () => reactiveMap,
239
239
  reduce: () => reduce,
240
+ reduction: () => reduction_exports,
240
241
  repeat: () => repeat,
241
242
  replay: () => replay,
242
243
  replayWAL: () => replayWAL,
@@ -726,6 +727,7 @@ function isV1(info) {
726
727
  }
727
728
 
728
729
  // src/core/node.ts
730
+ var NO_VALUE = /* @__PURE__ */ Symbol.for("graphrefly/NO_VALUE");
729
731
  function createIntBitSet() {
730
732
  let bits = 0;
731
733
  return {
@@ -826,7 +828,6 @@ var NodeImpl = class {
826
828
  _producerStarted = false;
827
829
  _connecting = false;
828
830
  _manualEmitUsed = false;
829
- _hasEmittedData = false;
830
831
  _sinkCount = 0;
831
832
  _singleDepSinkCount = 0;
832
833
  // --- Object/collection state ---
@@ -856,10 +857,10 @@ var NodeImpl = class {
856
857
  this._hasDeps = deps.length > 0;
857
858
  this._autoComplete = opts.completeWhenDepsComplete ?? true;
858
859
  this._isSingleDep = deps.length === 1 && fn != null;
859
- this._cached = opts.initial;
860
+ this._cached = "initial" in opts ? opts.initial : NO_VALUE;
860
861
  this._status = this._hasDeps ? "disconnected" : "settled";
861
862
  this._hashFn = opts.versioningHash ?? defaultHash;
862
- this._versioning = opts.versioning != null ? createVersioning(opts.versioning, this._cached, {
863
+ this._versioning = opts.versioning != null ? createVersioning(opts.versioning, this._cached === NO_VALUE ? void 0 : this._cached, {
863
864
  id: opts.versioningId,
864
865
  hash: this._hashFn
865
866
  }) : void 0;
@@ -943,10 +944,14 @@ var NodeImpl = class {
943
944
  _applyVersioning(level, opts) {
944
945
  if (this._versioning != null) return;
945
946
  this._hashFn = opts?.hash ?? this._hashFn;
946
- this._versioning = createVersioning(level, this._cached, {
947
- id: opts?.id,
948
- hash: this._hashFn
949
- });
947
+ this._versioning = createVersioning(
948
+ level,
949
+ this._cached === NO_VALUE ? void 0 : this._cached,
950
+ {
951
+ id: opts?.id,
952
+ hash: this._hashFn
953
+ }
954
+ );
950
955
  }
951
956
  hasGuard() {
952
957
  return this._guard != null;
@@ -956,7 +961,7 @@ var NodeImpl = class {
956
961
  return this._guard(normalizeActor(actor), "observe");
957
962
  }
958
963
  get() {
959
- return this._cached;
964
+ return this._cached === NO_VALUE ? void 0 : this._cached;
960
965
  }
961
966
  down(messages, options) {
962
967
  if (messages.length === 0) return;
@@ -1013,6 +1018,7 @@ var NodeImpl = class {
1013
1018
  }
1014
1019
  if (this._terminal && this._opts.resubscribable) {
1015
1020
  this._terminal = false;
1021
+ this._cached = NO_VALUE;
1016
1022
  this._status = this._hasDeps ? "disconnected" : "settled";
1017
1023
  this._opts.onResubscribe?.();
1018
1024
  }
@@ -1112,8 +1118,7 @@ var NodeImpl = class {
1112
1118
  const cleanupFn = this._cleanup;
1113
1119
  this._cleanup = void 0;
1114
1120
  cleanupFn?.();
1115
- this._cached = void 0;
1116
- this._hasEmittedData = false;
1121
+ this._cached = NO_VALUE;
1117
1122
  this._lastDepValues = void 0;
1118
1123
  }
1119
1124
  this._status = statusAfterMessage(this._status, m);
@@ -1122,8 +1127,7 @@ var NodeImpl = class {
1122
1127
  }
1123
1128
  if (t === TEARDOWN) {
1124
1129
  if (this._opts.resetOnTeardown) {
1125
- this._cached = void 0;
1126
- this._hasEmittedData = false;
1130
+ this._cached = NO_VALUE;
1127
1131
  }
1128
1132
  const teardownCleanup = this._cleanup;
1129
1133
  this._cleanup = void 0;
@@ -1156,14 +1160,13 @@ var NodeImpl = class {
1156
1160
  const wasDirty = this._status === "dirty";
1157
1161
  let unchanged;
1158
1162
  try {
1159
- unchanged = this._hasEmittedData && this._equals(this._cached, value);
1163
+ unchanged = this._cached !== NO_VALUE && this._equals(this._cached, value);
1160
1164
  } catch (eqErr) {
1161
1165
  const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
1162
1166
  const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
1163
1167
  this._downInternal([[ERROR, wrapped]]);
1164
1168
  return;
1165
1169
  }
1166
- this._hasEmittedData = true;
1167
1170
  if (unchanged) {
1168
1171
  this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
1169
1172
  return;
@@ -1387,7 +1390,7 @@ var DynamicNodeImpl = class {
1387
1390
  _actions;
1388
1391
  _boundEmitToSinks;
1389
1392
  // Mutable state
1390
- _cached;
1393
+ _cached = NO_VALUE;
1391
1394
  _status = "disconnected";
1392
1395
  _terminal = false;
1393
1396
  _connected = false;
@@ -1481,7 +1484,7 @@ var DynamicNodeImpl = class {
1481
1484
  return this._guard(normalizeActor(actor), "observe");
1482
1485
  }
1483
1486
  get() {
1484
- return this._cached;
1487
+ return this._cached === NO_VALUE ? void 0 : this._cached;
1485
1488
  }
1486
1489
  down(messages, options) {
1487
1490
  if (messages.length === 0) return;
@@ -1539,6 +1542,7 @@ var DynamicNodeImpl = class {
1539
1542
  }
1540
1543
  if (this._terminal && this._resubscribable) {
1541
1544
  this._terminal = false;
1545
+ this._cached = NO_VALUE;
1542
1546
  this._status = "disconnected";
1543
1547
  this._onResubscribe?.();
1544
1548
  }
@@ -1616,10 +1620,13 @@ var DynamicNodeImpl = class {
1616
1620
  const t = m[0];
1617
1621
  if (t === DATA) this._cached = m[1];
1618
1622
  if (t === INVALIDATE) {
1619
- this._cached = void 0;
1623
+ this._cached = NO_VALUE;
1624
+ this._status = "dirty";
1620
1625
  }
1621
- if (t === DATA || t === RESOLVED) {
1626
+ if (t === DATA) {
1622
1627
  this._status = "settled";
1628
+ } else if (t === RESOLVED) {
1629
+ this._status = "resolved";
1623
1630
  } else if (t === DIRTY) {
1624
1631
  this._status = "dirty";
1625
1632
  } else if (t === COMPLETE) {
@@ -1630,7 +1637,7 @@ var DynamicNodeImpl = class {
1630
1637
  this._terminal = true;
1631
1638
  }
1632
1639
  if (t === TEARDOWN) {
1633
- if (this._resetOnTeardown) this._cached = void 0;
1640
+ if (this._resetOnTeardown) this._cached = NO_VALUE;
1634
1641
  try {
1635
1642
  this._propagateToMeta(t);
1636
1643
  } finally {
@@ -1653,7 +1660,15 @@ var DynamicNodeImpl = class {
1653
1660
  }
1654
1661
  _emitAutoValue(value) {
1655
1662
  const wasDirty = this._status === "dirty";
1656
- const unchanged = this._equals(this._cached, value);
1663
+ let unchanged;
1664
+ try {
1665
+ unchanged = this._cached !== NO_VALUE && this._equals(this._cached, value);
1666
+ } catch (eqErr) {
1667
+ const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
1668
+ const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
1669
+ this._downInternal([[ERROR, wrapped]]);
1670
+ return;
1671
+ }
1657
1672
  if (unchanged) {
1658
1673
  this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
1659
1674
  return;
@@ -5174,20 +5189,28 @@ var Graph = class _Graph {
5174
5189
  return g;
5175
5190
  }
5176
5191
  /**
5177
- * Plain snapshot with **recursively sorted object keys** for deterministic serialization (§3.8).
5192
+ * Plain snapshot object with **recursively sorted object keys** for deterministic serialization (§3.8).
5178
5193
  *
5179
5194
  * @remarks
5180
- * ECMAScript `JSON.stringify(graph)` invokes this method; it must return a plain object, not an
5181
- * already-stringified JSON string (otherwise the graph would be double-encoded).
5182
5195
  * For a single UTF-8 string with a trailing newline (convenient for git), use {@link Graph.toJSONString}.
5183
5196
  *
5184
5197
  * @returns Same object as {@link Graph.snapshot}.
5185
5198
  */
5186
- toJSON() {
5199
+ toObject() {
5187
5200
  return this.snapshot();
5188
5201
  }
5189
5202
  /**
5190
- * Deterministic JSON **text**: `JSON.stringify` of {@link Graph.toJSON} plus a trailing newline (§3.8).
5203
+ * ECMAScript `JSON.stringify` hook — delegates to {@link Graph.toObject}.
5204
+ *
5205
+ * @remarks
5206
+ * Must return a plain object (not a string) so `JSON.stringify(graph)` works correctly
5207
+ * without double-encoding.
5208
+ */
5209
+ toJSON() {
5210
+ return this.toObject();
5211
+ }
5212
+ /**
5213
+ * Deterministic JSON **text**: `JSON.stringify` of {@link Graph.toObject} plus a trailing newline (§3.8).
5191
5214
  *
5192
5215
  * @returns Stable string suitable for diffs.
5193
5216
  */
@@ -12842,7 +12865,8 @@ __export(patterns_exports, {
12842
12865
  layout: () => reactive_layout_exports,
12843
12866
  memory: () => memory_exports,
12844
12867
  messaging: () => messaging_exports,
12845
- orchestration: () => orchestration_exports
12868
+ orchestration: () => orchestration_exports,
12869
+ reduction: () => reduction_exports
12846
12870
  });
12847
12871
 
12848
12872
  // src/patterns/ai.ts
@@ -16662,6 +16686,277 @@ function reactiveBlockLayout(opts) {
16662
16686
  };
16663
16687
  }
16664
16688
 
16689
+ // src/patterns/reduction.ts
16690
+ var reduction_exports = {};
16691
+ __export(reduction_exports, {
16692
+ budgetGate: () => budgetGate,
16693
+ feedback: () => feedback,
16694
+ funnel: () => funnel,
16695
+ scorer: () => scorer,
16696
+ stratify: () => stratify
16697
+ });
16698
+ function baseMeta2(kind, meta) {
16699
+ return {
16700
+ reduction: true,
16701
+ reduction_type: kind,
16702
+ ...meta ?? {}
16703
+ };
16704
+ }
16705
+ function stratify(name, source, rules, opts) {
16706
+ const g = new Graph(name, opts);
16707
+ g.add("source", source);
16708
+ const rulesNode = state(rules, {
16709
+ meta: baseMeta2("stratify_rules")
16710
+ });
16711
+ g.add("rules", rulesNode);
16712
+ for (const rule of rules) {
16713
+ _addBranch(g, source, rulesNode, rule);
16714
+ }
16715
+ return g;
16716
+ }
16717
+ function _addBranch(graph, source, rulesNode, rule) {
16718
+ const branchName = `branch/${rule.name}`;
16719
+ let pendingDirty = false;
16720
+ const filterNode = node([source, rulesNode], () => void 0, {
16721
+ describeKind: "operator",
16722
+ meta: baseMeta2("stratify_branch", { branch: rule.name }),
16723
+ onMessage(msg, depIndex, actions) {
16724
+ if (depIndex !== 0) return false;
16725
+ const t = msg[0];
16726
+ if (t === DATA) {
16727
+ const value = msg[1];
16728
+ const currentRules = rulesNode.get();
16729
+ const currentRule = currentRules.find((r) => r.name === rule.name);
16730
+ if (currentRule && currentRule.classify(value)) {
16731
+ pendingDirty = false;
16732
+ actions.emit(value);
16733
+ } else {
16734
+ if (pendingDirty) {
16735
+ pendingDirty = false;
16736
+ actions.down([[DIRTY], [RESOLVED]]);
16737
+ }
16738
+ }
16739
+ return true;
16740
+ }
16741
+ if (t === DIRTY) {
16742
+ pendingDirty = true;
16743
+ return true;
16744
+ }
16745
+ if (t === RESOLVED) {
16746
+ if (pendingDirty) {
16747
+ pendingDirty = false;
16748
+ actions.down([[DIRTY], [RESOLVED]]);
16749
+ } else {
16750
+ actions.down([[RESOLVED]]);
16751
+ }
16752
+ return true;
16753
+ }
16754
+ if (t === COMPLETE || t === ERROR) {
16755
+ pendingDirty = false;
16756
+ actions.down([msg]);
16757
+ return true;
16758
+ }
16759
+ return false;
16760
+ }
16761
+ });
16762
+ graph.add(branchName, filterNode);
16763
+ graph.connect("source", branchName);
16764
+ if (rule.ops) {
16765
+ const transformed = rule.ops(filterNode);
16766
+ const transformedName = `branch/${rule.name}/out`;
16767
+ graph.add(transformedName, transformed);
16768
+ graph.connect(branchName, transformedName);
16769
+ }
16770
+ }
16771
+ function funnel(name, sources, stages, opts) {
16772
+ if (sources.length === 0) throw new RangeError("funnel requires at least one source");
16773
+ if (stages.length === 0) throw new RangeError("funnel requires at least one stage");
16774
+ const g = new Graph(name, opts);
16775
+ const merged = sources.length === 1 ? sources[0] : merge(...sources);
16776
+ g.add("merged", merged);
16777
+ let prevOutputPath = "merged";
16778
+ for (let i = 0; i < stages.length; i++) {
16779
+ const stage = stages[i];
16780
+ const sub = new Graph(stage.name);
16781
+ stage.build(sub);
16782
+ try {
16783
+ sub.resolve("input");
16784
+ } catch {
16785
+ throw new Error(`funnel stage "${stage.name}" must define an "input" node`);
16786
+ }
16787
+ try {
16788
+ sub.resolve("output");
16789
+ } catch {
16790
+ throw new Error(`funnel stage "${stage.name}" must define an "output" node`);
16791
+ }
16792
+ g.mount(stage.name, sub);
16793
+ const prevNode = g.resolve(prevOutputPath);
16794
+ const stageInputPath = `${stage.name}::input`;
16795
+ const stageInput = g.resolve(stageInputPath);
16796
+ prevNode.subscribe((msgs) => {
16797
+ for (const msg of msgs) {
16798
+ const t = msg[0];
16799
+ if (t === DATA) {
16800
+ stageInput.down([[DATA, msg[1]]]);
16801
+ } else if (t === DIRTY) {
16802
+ stageInput.down([[DIRTY]]);
16803
+ } else if (t === RESOLVED) {
16804
+ stageInput.down([[RESOLVED]]);
16805
+ } else if (t === COMPLETE || t === ERROR) {
16806
+ stageInput.down([msg]);
16807
+ }
16808
+ }
16809
+ });
16810
+ prevOutputPath = `${stage.name}::output`;
16811
+ }
16812
+ return g;
16813
+ }
16814
+ function feedback(graph, condition, reentry, opts) {
16815
+ const maxIter = opts?.maxIterations ?? 10;
16816
+ const counterName = `__feedback_${condition}`;
16817
+ const counter = state(0, {
16818
+ meta: baseMeta2("feedback_counter", { maxIterations: maxIter })
16819
+ });
16820
+ graph.add(counterName, counter);
16821
+ const condNode = graph.resolve(condition);
16822
+ const reentryNode = graph.resolve(reentry);
16823
+ condNode.subscribe((msgs) => {
16824
+ for (const msg of msgs) {
16825
+ if (msg[0] === DATA) {
16826
+ const currentCount = counter.get();
16827
+ if (currentCount >= maxIter) continue;
16828
+ const condValue = msg[1];
16829
+ if (condValue == null) continue;
16830
+ counter.down([[DATA, currentCount + 1]]);
16831
+ reentryNode.down([[DATA, condValue]]);
16832
+ }
16833
+ }
16834
+ });
16835
+ return graph;
16836
+ }
16837
+ function budgetGate(source, constraints, opts) {
16838
+ if (constraints.length === 0) throw new RangeError("budgetGate requires at least one constraint");
16839
+ const constraintNodes = constraints.map((c) => c.node);
16840
+ const allDeps = [source, ...constraintNodes];
16841
+ let buffer2 = [];
16842
+ let paused = false;
16843
+ const lockId = /* @__PURE__ */ Symbol("budget-gate");
16844
+ function checkBudget() {
16845
+ return constraints.every((c) => c.check(c.node.get()));
16846
+ }
16847
+ function flushBuffer(actions) {
16848
+ while (buffer2.length > 0 && checkBudget()) {
16849
+ const item = buffer2.shift();
16850
+ actions.emit(item);
16851
+ }
16852
+ }
16853
+ return node(allDeps, () => void 0, {
16854
+ ...opts,
16855
+ describeKind: "operator",
16856
+ meta: baseMeta2("budget_gate", opts?.meta),
16857
+ onMessage(msg, depIndex, actions) {
16858
+ const t = msg[0];
16859
+ if (depIndex === 0) {
16860
+ if (t === DATA) {
16861
+ if (checkBudget() && buffer2.length === 0) {
16862
+ actions.emit(msg[1]);
16863
+ } else {
16864
+ buffer2.push(msg[1]);
16865
+ if (!paused) {
16866
+ paused = true;
16867
+ actions.up([[PAUSE, lockId]]);
16868
+ }
16869
+ }
16870
+ return true;
16871
+ }
16872
+ if (t === DIRTY) {
16873
+ actions.down([[DIRTY]]);
16874
+ return true;
16875
+ }
16876
+ if (t === RESOLVED) {
16877
+ if (buffer2.length === 0) {
16878
+ actions.down([[RESOLVED]]);
16879
+ }
16880
+ return true;
16881
+ }
16882
+ if (t === COMPLETE || t === ERROR) {
16883
+ for (const item of buffer2) {
16884
+ actions.emit(item);
16885
+ }
16886
+ buffer2 = [];
16887
+ if (paused) {
16888
+ paused = false;
16889
+ actions.up([[RESUME, lockId]]);
16890
+ }
16891
+ actions.down([msg]);
16892
+ return true;
16893
+ }
16894
+ return false;
16895
+ }
16896
+ if (t === DATA || t === RESOLVED) {
16897
+ if (checkBudget() && buffer2.length > 0) {
16898
+ flushBuffer(actions);
16899
+ if (buffer2.length === 0 && paused) {
16900
+ paused = false;
16901
+ actions.up([[RESUME, lockId]]);
16902
+ }
16903
+ } else if (!checkBudget() && !paused && buffer2.length > 0) {
16904
+ paused = true;
16905
+ actions.up([[PAUSE, lockId]]);
16906
+ }
16907
+ return true;
16908
+ }
16909
+ if (t === DIRTY) {
16910
+ return true;
16911
+ }
16912
+ if (t === ERROR) {
16913
+ actions.down([msg]);
16914
+ return true;
16915
+ }
16916
+ if (t === COMPLETE) {
16917
+ return true;
16918
+ }
16919
+ return false;
16920
+ }
16921
+ });
16922
+ }
16923
+ function scorer(sources, weights, opts) {
16924
+ if (sources.length === 0) throw new RangeError("scorer requires at least one source");
16925
+ if (sources.length !== weights.length) {
16926
+ throw new RangeError("scorer requires the same number of sources and weights");
16927
+ }
16928
+ const allDeps = [...sources, ...weights];
16929
+ const n = sources.length;
16930
+ const scoreFns = opts?.scoreFns;
16931
+ return derived(
16932
+ allDeps,
16933
+ (vals) => {
16934
+ const signals = vals.slice(0, n);
16935
+ const weightValues = vals.slice(n);
16936
+ const breakdown = [];
16937
+ let totalScore = 0;
16938
+ for (let i = 0; i < n; i++) {
16939
+ const sig = signals[i] ?? 0;
16940
+ const wt = weightValues[i] ?? 0;
16941
+ const rawScore = scoreFns?.[i] ? scoreFns[i](sig) : sig;
16942
+ const weighted = rawScore * wt;
16943
+ breakdown.push(weighted);
16944
+ totalScore += weighted;
16945
+ }
16946
+ return {
16947
+ value: signals,
16948
+ score: totalScore,
16949
+ breakdown
16950
+ };
16951
+ },
16952
+ {
16953
+ ...opts,
16954
+ describeKind: "derived",
16955
+ meta: baseMeta2("scorer", opts?.meta)
16956
+ }
16957
+ );
16958
+ }
16959
+
16665
16960
  // src/index.ts
16666
16961
  var version = "0.0.0";
16667
16962
  // Annotate the CommonJS export names for ESM import in node:
@@ -16838,6 +17133,7 @@ var version = "0.0.0";
16838
17133
  reactiveLog,
16839
17134
  reactiveMap,
16840
17135
  reduce,
17136
+ reduction,
16841
17137
  repeat,
16842
17138
  replay,
16843
17139
  replayWAL,