@graphrefly/graphrefly 0.11.0 → 0.13.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 (69) hide show
  1. package/dist/{chunk-FMVFRP7L.js → chunk-5RN7NBNG.js} +5 -5
  2. package/dist/{chunk-UG2QZMRN.js → chunk-6B2ZCCNN.js} +40 -39
  3. package/dist/chunk-6B2ZCCNN.js.map +1 -0
  4. package/dist/{chunk-2VHNCFGG.js → chunk-H4UFM6WD.js} +46 -17
  5. package/dist/chunk-H4UFM6WD.js.map +1 -0
  6. package/dist/{chunk-PZCDQD2U.js → chunk-HA6QMDKQ.js} +4 -4
  7. package/dist/{chunk-5WXTWOD7.js → chunk-KNGOJEYP.js} +2 -2
  8. package/dist/{chunk-OHUECHWY.js → chunk-PFMXKG4Y.js} +2 -2
  9. package/dist/{chunk-U5HFZGAQ.js → chunk-QOGWU5K7.js} +3 -3
  10. package/dist/{chunk-3WACHRHV.js → chunk-UPC5OEB5.js} +17 -17
  11. package/dist/chunk-UPC5OEB5.js.map +1 -0
  12. package/dist/{chunk-2OTXEZQO.js → chunk-UQI4GAHD.js} +3 -3
  13. package/dist/compat/nestjs/index.cjs +37 -37
  14. package/dist/compat/nestjs/index.cjs.map +1 -1
  15. package/dist/compat/nestjs/index.d.cts +4 -4
  16. package/dist/compat/nestjs/index.d.ts +4 -4
  17. package/dist/compat/nestjs/index.js +7 -7
  18. package/dist/core/index.cjs +39 -39
  19. package/dist/core/index.cjs.map +1 -1
  20. package/dist/core/index.d.cts +2 -2
  21. package/dist/core/index.d.ts +2 -2
  22. package/dist/core/index.js +5 -5
  23. package/dist/extra/index.cjs +79 -51
  24. package/dist/extra/index.cjs.map +1 -1
  25. package/dist/extra/index.d.cts +4 -4
  26. package/dist/extra/index.d.ts +4 -4
  27. package/dist/extra/index.js +5 -5
  28. package/dist/graph/index.cjs +37 -37
  29. package/dist/graph/index.cjs.map +1 -1
  30. package/dist/graph/index.d.cts +3 -3
  31. package/dist/graph/index.d.ts +3 -3
  32. package/dist/graph/index.js +4 -4
  33. package/dist/{graph-DXT95WZ3.d.ts → graph-BXIK5Dq5.d.ts} +1 -1
  34. package/dist/{graph-BE10ujU9.d.cts → graph-BhADtuFU.d.cts} +1 -1
  35. package/dist/{index-QfbXNW1N.d.cts → index-BNB0KjKe.d.ts} +24 -21
  36. package/dist/{index-C0_7g9sj.d.ts → index-BkToATim.d.ts} +1 -1
  37. package/dist/{index-Bbgvinsi.d.ts → index-CKyYg4IP.d.ts} +17 -13
  38. package/dist/{index-CCvzN5GB.d.cts → index-DANO9Gg7.d.cts} +2 -2
  39. package/dist/{index-DpZozxaJ.d.cts → index-DBhLjWSV.d.cts} +17 -13
  40. package/dist/{index-Dzdm20sx.d.ts → index-DKIyo4Bq.d.cts} +24 -21
  41. package/dist/{index-53cDGX7F.d.ts → index-DSp5R3Xq.d.ts} +3 -3
  42. package/dist/{index-aBZ2RoP0.d.cts → index-Dqemj9q0.d.cts} +3 -3
  43. package/dist/{index-nRulwTr-.d.cts → index-Wa8jXne6.d.cts} +1 -1
  44. package/dist/{index-B10Q0sQB.d.ts → index-fYObbpUw.d.ts} +2 -2
  45. package/dist/index.cjs +283 -71
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.d.cts +85 -15
  48. package/dist/index.d.ts +85 -15
  49. package/dist/index.js +200 -16
  50. package/dist/index.js.map +1 -1
  51. package/dist/{meta-BcuDhtwu.d.cts → meta-CrZUQAJ6.d.cts} +1 -1
  52. package/dist/{meta-BcuDhtwu.d.ts → meta-CrZUQAJ6.d.ts} +1 -1
  53. package/dist/patterns/reactive-layout/index.cjs +50 -50
  54. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  55. package/dist/patterns/reactive-layout/index.d.cts +3 -3
  56. package/dist/patterns/reactive-layout/index.d.ts +3 -3
  57. package/dist/patterns/reactive-layout/index.js +4 -4
  58. package/dist/{reactive-log-OULQssZg.d.cts → reactive-log-ChbpUrY2.d.cts} +2 -2
  59. package/dist/{reactive-log-Cu0VdqkT.d.ts → reactive-log-DV--7BWd.d.ts} +2 -2
  60. package/package.json +1 -1
  61. package/dist/chunk-2VHNCFGG.js.map +0 -1
  62. package/dist/chunk-3WACHRHV.js.map +0 -1
  63. package/dist/chunk-UG2QZMRN.js.map +0 -1
  64. /package/dist/{chunk-FMVFRP7L.js.map → chunk-5RN7NBNG.js.map} +0 -0
  65. /package/dist/{chunk-PZCDQD2U.js.map → chunk-HA6QMDKQ.js.map} +0 -0
  66. /package/dist/{chunk-5WXTWOD7.js.map → chunk-KNGOJEYP.js.map} +0 -0
  67. /package/dist/{chunk-OHUECHWY.js.map → chunk-PFMXKG4Y.js.map} +0 -0
  68. /package/dist/{chunk-U5HFZGAQ.js.map → chunk-QOGWU5K7.js.map} +0 -0
  69. /package/dist/{chunk-2OTXEZQO.js.map → chunk-UQI4GAHD.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -134,10 +134,10 @@ __export(index_exports, {
134
134
  distill: () => distill,
135
135
  distinctUntilChanged: () => distinctUntilChanged,
136
136
  domainTemplates: () => domain_templates_exports,
137
+ downWithBatch: () => downWithBatch,
137
138
  dynamicNode: () => dynamicNode,
138
139
  effect: () => effect,
139
140
  elementAt: () => elementAt,
140
- emitWithBatch: () => emitWithBatch,
141
141
  empty: () => empty,
142
142
  escapeRegexChar: () => escapeRegexChar,
143
143
  exhaustMap: () => exhaustMap,
@@ -182,7 +182,6 @@ __export(index_exports, {
182
182
  fromTimer: () => fromTimer,
183
183
  fromWebSocket: () => fromWebSocket,
184
184
  fromWebhook: () => fromWebhook,
185
- gate: () => gate,
186
185
  globToRegExp: () => globToRegExp,
187
186
  graph: () => graph_exports,
188
187
  graphspec: () => graphspec_exports,
@@ -298,6 +297,7 @@ __export(index_exports, {
298
297
  toWebSocket: () => toWebSocket,
299
298
  tokenBucket: () => tokenBucket,
300
299
  tokenTracker: () => tokenTracker,
300
+ valve: () => valve,
301
301
  verifiable: () => verifiable,
302
302
  version: () => version,
303
303
  vue: () => vue_exports,
@@ -499,12 +499,12 @@ function partitionForBatch(messages) {
499
499
  }
500
500
  return { immediate, deferred, terminal };
501
501
  }
502
- function emitWithBatch(emit, messages, phase = 2, options) {
502
+ function downWithBatch(sink, messages, phase = 2, options) {
503
503
  if (messages.length === 0) {
504
504
  return;
505
505
  }
506
506
  if (options?.strategy === "sequential") {
507
- _emitSequential(emit, messages, phase);
507
+ _downSequential(sink, messages, phase);
508
508
  return;
509
509
  }
510
510
  const queue = phase === 3 ? pendingPhase3 : pendingPhase2;
@@ -512,61 +512,61 @@ function emitWithBatch(emit, messages, phase = 2, options) {
512
512
  const t = messages[0][0];
513
513
  if (t === DATA || t === RESOLVED) {
514
514
  if (isBatching()) {
515
- queue.push(() => emit(messages));
515
+ queue.push(() => sink(messages));
516
516
  } else {
517
- emit(messages);
517
+ sink(messages);
518
518
  }
519
519
  } else if (isTerminalMessage(t)) {
520
520
  if (isBatching()) {
521
- queue.push(() => emit(messages));
521
+ queue.push(() => sink(messages));
522
522
  } else {
523
- emit(messages);
523
+ sink(messages);
524
524
  }
525
525
  } else {
526
- emit(messages);
526
+ sink(messages);
527
527
  }
528
528
  return;
529
529
  }
530
530
  const { immediate, deferred, terminal } = partitionForBatch(messages);
531
531
  if (immediate.length > 0) {
532
- emit(immediate);
532
+ sink(immediate);
533
533
  }
534
534
  if (isBatching()) {
535
535
  if (deferred.length > 0) {
536
- queue.push(() => emit(deferred));
536
+ queue.push(() => sink(deferred));
537
537
  }
538
538
  if (terminal.length > 0) {
539
- queue.push(() => emit(terminal));
539
+ queue.push(() => sink(terminal));
540
540
  }
541
541
  } else {
542
542
  if (deferred.length > 0) {
543
- emit(deferred);
543
+ sink(deferred);
544
544
  }
545
545
  if (terminal.length > 0) {
546
- emit(terminal);
546
+ sink(terminal);
547
547
  }
548
548
  }
549
549
  }
550
- function _emitSequential(emit, messages, phase = 2) {
550
+ function _downSequential(sink, messages, phase = 2) {
551
551
  const dataQueue = phase === 3 ? pendingPhase3 : pendingPhase2;
552
552
  for (const msg of messages) {
553
553
  const tier = messageTier(msg[0]);
554
554
  if (tier === 2) {
555
555
  if (isBatching()) {
556
556
  const m = msg;
557
- dataQueue.push(() => emit([m]));
557
+ dataQueue.push(() => sink([m]));
558
558
  } else {
559
- emit([msg]);
559
+ sink([msg]);
560
560
  }
561
561
  } else if (tier >= 3) {
562
562
  if (isBatching()) {
563
563
  const m = msg;
564
- pendingPhase3.push(() => emit([m]));
564
+ pendingPhase3.push(() => sink([m]));
565
565
  } else {
566
- emit([msg]);
566
+ sink([msg]);
567
567
  }
568
568
  } else {
569
- emit([msg]);
569
+ sink([msg]);
570
570
  }
571
571
  }
572
572
  }
@@ -854,7 +854,7 @@ var NodeImpl = class {
854
854
  _singleDepSinks = /* @__PURE__ */ new WeakSet();
855
855
  _upstreamUnsubs = [];
856
856
  _actions;
857
- _boundEmitToSinks;
857
+ _boundDownToSinks;
858
858
  _inspectorHook;
859
859
  _versioning;
860
860
  _hashFn;
@@ -901,7 +901,7 @@ var NodeImpl = class {
901
901
  },
902
902
  emit(value) {
903
903
  self._manualEmitUsed = true;
904
- self._emitAutoValue(value);
904
+ self._downAutoValue(value);
905
905
  },
906
906
  up(messages) {
907
907
  self._upInternal(messages);
@@ -909,7 +909,7 @@ var NodeImpl = class {
909
909
  };
910
910
  this.down = this.down.bind(this);
911
911
  this.up = this.up.bind(this);
912
- this._boundEmitToSinks = this._emitToSinks.bind(this);
912
+ this._boundDownToSinks = this._downToSinks.bind(this);
913
913
  }
914
914
  get name() {
915
915
  return this._registryName ?? this._optsName;
@@ -1015,12 +1015,12 @@ var NodeImpl = class {
1015
1015
  if (sinkMessages[i][0] !== DIRTY) filtered.push(sinkMessages[i]);
1016
1016
  }
1017
1017
  if (filtered.length > 0) {
1018
- emitWithBatch(this._boundEmitToSinks, filtered);
1018
+ downWithBatch(this._boundDownToSinks, filtered);
1019
1019
  }
1020
1020
  return;
1021
1021
  }
1022
1022
  }
1023
- emitWithBatch(this._boundEmitToSinks, sinkMessages);
1023
+ downWithBatch(this._boundDownToSinks, sinkMessages);
1024
1024
  }
1025
1025
  subscribe(sink, hints) {
1026
1026
  if (hints?.actor != null && this._guard != null) {
@@ -1107,7 +1107,7 @@ var NodeImpl = class {
1107
1107
  this._disconnectUpstream();
1108
1108
  }
1109
1109
  // --- Private methods (prototype, _ prefix) ---
1110
- _emitToSinks(messages) {
1110
+ _downToSinks(messages) {
1111
1111
  if (this._sinks == null) return;
1112
1112
  if (typeof this._sinks === "function") {
1113
1113
  this._sinks(messages);
@@ -1169,7 +1169,7 @@ var NodeImpl = class {
1169
1169
  _canSkipDirty() {
1170
1170
  return this._sinkCount === 1 && this._singleDepSinkCount === 1;
1171
1171
  }
1172
- _emitAutoValue(value) {
1172
+ _downAutoValue(value) {
1173
1173
  const wasDirty = this._status === "dirty";
1174
1174
  let unchanged;
1175
1175
  try {
@@ -1222,7 +1222,7 @@ var NodeImpl = class {
1222
1222
  this._cleanup = out.cleanup;
1223
1223
  if (this._manualEmitUsed) return;
1224
1224
  if ("value" in out) {
1225
- this._emitAutoValue(out.value);
1225
+ this._downAutoValue(out.value);
1226
1226
  }
1227
1227
  return;
1228
1228
  }
@@ -1232,7 +1232,7 @@ var NodeImpl = class {
1232
1232
  }
1233
1233
  if (this._manualEmitUsed) return;
1234
1234
  if (out === void 0) return;
1235
- this._emitAutoValue(out);
1235
+ this._downAutoValue(out);
1236
1236
  } catch (err) {
1237
1237
  const errMsg = err instanceof Error ? err.message : String(err);
1238
1238
  const wrapped = new Error(`Node "${this.name}": fn threw: ${errMsg}`, { cause: err });
@@ -1409,7 +1409,7 @@ var DynamicNodeImpl = class {
1409
1409
  _singleDepSinks = /* @__PURE__ */ new WeakSet();
1410
1410
  // Actions object (for onMessage handler)
1411
1411
  _actions;
1412
- _boundEmitToSinks;
1412
+ _boundDownToSinks;
1413
1413
  // Mutable state
1414
1414
  _cached = NO_VALUE;
1415
1415
  _status = "disconnected";
@@ -1456,7 +1456,7 @@ var DynamicNodeImpl = class {
1456
1456
  self._downInternal(messages);
1457
1457
  },
1458
1458
  emit(value) {
1459
- self._emitAutoValue(value);
1459
+ self._downAutoValue(value);
1460
1460
  },
1461
1461
  up(messages) {
1462
1462
  for (const dep of self._deps) {
@@ -1464,7 +1464,7 @@ var DynamicNodeImpl = class {
1464
1464
  }
1465
1465
  }
1466
1466
  };
1467
- this._boundEmitToSinks = this._emitToSinks.bind(this);
1467
+ this._boundDownToSinks = this._downToSinks.bind(this);
1468
1468
  }
1469
1469
  get name() {
1470
1470
  return this._registryName ?? this._optsName;
@@ -1544,12 +1544,12 @@ var DynamicNodeImpl = class {
1544
1544
  if (sinkMessages[i][0] !== DIRTY) filtered.push(sinkMessages[i]);
1545
1545
  }
1546
1546
  if (filtered.length > 0) {
1547
- emitWithBatch(this._boundEmitToSinks, filtered);
1547
+ downWithBatch(this._boundDownToSinks, filtered);
1548
1548
  }
1549
1549
  return;
1550
1550
  }
1551
1551
  }
1552
- emitWithBatch(this._boundEmitToSinks, sinkMessages);
1552
+ downWithBatch(this._boundDownToSinks, sinkMessages);
1553
1553
  }
1554
1554
  _canSkipDirty() {
1555
1555
  return this._sinkCount === 1 && this._singleDepSinkCount === 1;
@@ -1625,7 +1625,7 @@ var DynamicNodeImpl = class {
1625
1625
  this._disconnect();
1626
1626
  }
1627
1627
  // --- Private methods ---
1628
- _emitToSinks(messages) {
1628
+ _downToSinks(messages) {
1629
1629
  if (this._sinks == null) return;
1630
1630
  if (typeof this._sinks === "function") {
1631
1631
  this._sinks(messages);
@@ -1679,7 +1679,7 @@ var DynamicNodeImpl = class {
1679
1679
  }
1680
1680
  }
1681
1681
  }
1682
- _emitAutoValue(value) {
1682
+ _downAutoValue(value) {
1683
1683
  const wasDirty = this._status === "dirty";
1684
1684
  let unchanged;
1685
1685
  try {
@@ -1739,7 +1739,7 @@ var DynamicNodeImpl = class {
1739
1739
  const result = this._fn(get);
1740
1740
  this._rewire(trackedDeps);
1741
1741
  if (result === void 0) return;
1742
- this._emitAutoValue(result);
1742
+ this._downAutoValue(result);
1743
1743
  } catch (err) {
1744
1744
  this._downInternal([[ERROR, err]]);
1745
1745
  }
@@ -1803,14 +1803,14 @@ var DynamicNodeImpl = class {
1803
1803
  this._dirtyBits.add(index);
1804
1804
  this._settledBits.delete(index);
1805
1805
  if (this._dirtyBits.size === 1) {
1806
- emitWithBatch(this._boundEmitToSinks, [[DIRTY]]);
1806
+ downWithBatch(this._boundDownToSinks, [[DIRTY]]);
1807
1807
  }
1808
1808
  continue;
1809
1809
  }
1810
1810
  if (t === DATA || t === RESOLVED) {
1811
1811
  if (!this._dirtyBits.has(index)) {
1812
1812
  this._dirtyBits.add(index);
1813
- emitWithBatch(this._boundEmitToSinks, [[DIRTY]]);
1813
+ downWithBatch(this._boundDownToSinks, [[DIRTY]]);
1814
1814
  }
1815
1815
  this._settledBits.add(index);
1816
1816
  if (this._allDirtySettled()) {
@@ -5562,9 +5562,9 @@ __export(core_exports, {
5562
5562
  defaultHash: () => defaultHash,
5563
5563
  derived: () => derived,
5564
5564
  describeNode: () => describeNode,
5565
+ downWithBatch: () => downWithBatch,
5565
5566
  dynamicNode: () => dynamicNode,
5566
5567
  effect: () => effect,
5567
- emitWithBatch: () => emitWithBatch,
5568
5568
  isBatching: () => isBatching,
5569
5569
  isKnownMessageType: () => isKnownMessageType,
5570
5570
  isPhase2Message: () => isPhase2Message,
@@ -6948,7 +6948,6 @@ __export(extra_exports, {
6948
6948
  fromTimer: () => fromTimer,
6949
6949
  fromWebSocket: () => fromWebSocket,
6950
6950
  fromWebhook: () => fromWebhook,
6951
- gate: () => gate,
6952
6951
  globToRegExp: () => globToRegExp,
6953
6952
  interval: () => interval,
6954
6953
  last: () => last,
@@ -7027,6 +7026,7 @@ __export(extra_exports, {
7027
7026
  toWebSocket: () => toWebSocket,
7028
7027
  tokenBucket: () => tokenBucket,
7029
7028
  tokenTracker: () => tokenTracker,
7029
+ valve: () => valve,
7030
7030
  verifiable: () => verifiable,
7031
7031
  window: () => window,
7032
7032
  windowCount: () => windowCount,
@@ -11507,30 +11507,58 @@ function throttle(source, ms, opts) {
11507
11507
  );
11508
11508
  }
11509
11509
  function sample(source, notifier, opts) {
11510
+ let lastSourceValue = NO_VALUE;
11511
+ let terminated = false;
11512
+ let sourceCompleted = false;
11510
11513
  return node([source, notifier], () => void 0, {
11511
11514
  ...operatorOpts3(opts),
11512
11515
  completeWhenDepsComplete: false,
11516
+ onResubscribe: opts?.resubscribable === true ? () => {
11517
+ lastSourceValue = NO_VALUE;
11518
+ terminated = false;
11519
+ sourceCompleted = false;
11520
+ } : void 0,
11513
11521
  onMessage(msg, i, a) {
11522
+ if (terminated) return true;
11514
11523
  const t = msg[0];
11515
- if (t === ERROR) {
11524
+ const tier = messageTier(t);
11525
+ if (tier >= 3) {
11526
+ if (t === ERROR) {
11527
+ terminated = true;
11528
+ a.down([msg]);
11529
+ return true;
11530
+ }
11531
+ if (t === COMPLETE) {
11532
+ if (i === 0) {
11533
+ sourceCompleted = true;
11534
+ lastSourceValue = NO_VALUE;
11535
+ return true;
11536
+ }
11537
+ terminated = true;
11538
+ a.down([msg]);
11539
+ return true;
11540
+ }
11516
11541
  a.down([msg]);
11517
11542
  return true;
11518
11543
  }
11519
- if (t === COMPLETE) {
11544
+ if (i === 0) {
11545
+ if (t === DATA) {
11546
+ lastSourceValue = msg[1];
11547
+ return true;
11548
+ }
11549
+ if (t === DIRTY || t === RESOLVED) return true;
11520
11550
  a.down([msg]);
11521
11551
  return true;
11522
11552
  }
11523
- if (i === 1 && t === DATA) {
11524
- a.emit(source.get());
11525
- return true;
11526
- }
11527
- if (i === 1 && t === RESOLVED) {
11528
- return true;
11529
- }
11530
- if (i === 0) {
11553
+ if (t === DATA) {
11554
+ if (lastSourceValue !== NO_VALUE && !sourceCompleted) {
11555
+ a.emit(lastSourceValue);
11556
+ }
11531
11557
  return true;
11532
11558
  }
11533
- return false;
11559
+ if (t === RESOLVED) return true;
11560
+ a.down([msg]);
11561
+ return true;
11534
11562
  }
11535
11563
  });
11536
11564
  }
@@ -11997,7 +12025,7 @@ function rescue(source, recover, opts) {
11997
12025
  }
11998
12026
  });
11999
12027
  }
12000
- function gate(source, control, opts) {
12028
+ function valve(source, control, opts) {
12001
12029
  return node(
12002
12030
  [source, control],
12003
12031
  (_deps, a) => {
@@ -12963,6 +12991,7 @@ __export(ai_exports, {
12963
12991
  knobsAsTools: () => knobsAsTools,
12964
12992
  llmConsolidator: () => llmConsolidator,
12965
12993
  llmExtractor: () => llmExtractor,
12994
+ promptNode: () => promptNode,
12966
12995
  suggestStrategy: () => suggestStrategy,
12967
12996
  systemPromptBuilder: () => systemPromptBuilder,
12968
12997
  toolRegistry: () => toolRegistry,
@@ -13478,6 +13507,75 @@ function fromLLMStream(adapter, messages, opts) {
13478
13507
  }
13479
13508
  };
13480
13509
  }
13510
+ function extractContent(resp) {
13511
+ if (resp != null && typeof resp === "object" && "content" in resp) {
13512
+ return String(resp.content);
13513
+ }
13514
+ if (typeof resp === "string") return resp;
13515
+ return String(resp);
13516
+ }
13517
+ function promptNode(adapter, deps, prompt, opts) {
13518
+ const format = opts?.format ?? "text";
13519
+ const retries = opts?.retries ?? 0;
13520
+ const useCache = opts?.cache ?? false;
13521
+ const cache2 = useCache ? /* @__PURE__ */ new Map() : null;
13522
+ const messagesNode = derived(
13523
+ deps,
13524
+ (values) => {
13525
+ const text = typeof prompt === "string" ? prompt : prompt(...values);
13526
+ const msgs = [];
13527
+ if (opts?.systemPrompt) msgs.push({ role: "system", content: opts.systemPrompt });
13528
+ msgs.push({ role: "user", content: text });
13529
+ return msgs;
13530
+ },
13531
+ {
13532
+ name: opts?.name ? `${opts.name}::messages` : "prompt_node::messages",
13533
+ meta: aiMeta("prompt_node")
13534
+ }
13535
+ );
13536
+ const result = switchMap(messagesNode, (msgs) => {
13537
+ if (!msgs || msgs.length === 0) {
13538
+ return state(null);
13539
+ }
13540
+ const cacheKey = useCache ? JSON.stringify(msgs.map((m) => [m.role, m.content])) : "";
13541
+ if (cache2?.has(cacheKey)) {
13542
+ return state(cache2.get(cacheKey));
13543
+ }
13544
+ async function attempt(remaining) {
13545
+ try {
13546
+ const resp = await new Promise((resolve, reject) => {
13547
+ const input = adapter.invoke(msgs, {
13548
+ model: opts?.model,
13549
+ temperature: opts?.temperature,
13550
+ maxTokens: opts?.maxTokens,
13551
+ systemPrompt: opts?.systemPrompt
13552
+ });
13553
+ if (input && typeof input.then === "function") {
13554
+ input.then(resolve, reject);
13555
+ } else if (input && typeof input.get === "function") {
13556
+ resolve(input.get());
13557
+ } else {
13558
+ resolve(input);
13559
+ }
13560
+ });
13561
+ const content = extractContent(resp);
13562
+ let parsed;
13563
+ if (format === "json") {
13564
+ parsed = JSON.parse(stripFences(content));
13565
+ } else {
13566
+ parsed = content;
13567
+ }
13568
+ cache2?.set(cacheKey, parsed);
13569
+ return parsed;
13570
+ } catch (err) {
13571
+ if (remaining > 0) return attempt(remaining - 1);
13572
+ throw err;
13573
+ }
13574
+ }
13575
+ return attempt(retries);
13576
+ });
13577
+ return result;
13578
+ }
13481
13579
  var ChatStreamGraph = class extends Graph {
13482
13580
  _log;
13483
13581
  _keepaliveSubs = [];
@@ -14819,7 +14917,7 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache2) {
14819
14917
  hyphenWidth = adapter.measureSegment("-", font).width;
14820
14918
  fontCache.set("-", hyphenWidth);
14821
14919
  }
14822
- function emitLine(endSeg = lineEndSeg, endGrapheme = lineEndGrapheme, width = lineW) {
14920
+ function flushLine(endSeg = lineEndSeg, endGrapheme = lineEndGrapheme, width = lineW) {
14823
14921
  let text = "";
14824
14922
  for (let i = lineStartSeg; i < endSeg; i++) {
14825
14923
  const seg = segments[i];
@@ -14882,7 +14980,7 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache2) {
14882
14980
  const seg = segments[i];
14883
14981
  if (seg.kind === "hard-break") {
14884
14982
  if (hasContent) {
14885
- emitLine();
14983
+ flushLine();
14886
14984
  } else {
14887
14985
  lines.push({
14888
14986
  text: "",
@@ -14916,20 +15014,20 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache2) {
14916
15014
  lineW += w;
14917
15015
  lineEndSeg = i + 1;
14918
15016
  lineEndGrapheme = 0;
14919
- emitLine(i + 1, 0, seg.kind === "space" ? lineW - w : lineW);
15017
+ flushLine(i + 1, 0, seg.kind === "space" ? lineW - w : lineW);
14920
15018
  continue;
14921
15019
  }
14922
15020
  if (pendingBreakSeg >= 0) {
14923
- emitLine(pendingBreakSeg, 0, pendingBreakWidth);
15021
+ flushLine(pendingBreakSeg, 0, pendingBreakWidth);
14924
15022
  i--;
14925
15023
  continue;
14926
15024
  }
14927
15025
  if (w > maxWidth && seg.graphemeWidths) {
14928
- emitLine();
15026
+ flushLine();
14929
15027
  appendBreakableSegment(i, 0, seg.graphemeWidths);
14930
15028
  continue;
14931
15029
  }
14932
- emitLine();
15030
+ flushLine();
14933
15031
  i--;
14934
15032
  continue;
14935
15033
  }
@@ -14942,7 +15040,7 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache2) {
14942
15040
  }
14943
15041
  }
14944
15042
  if (hasContent) {
14945
- emitLine();
15043
+ flushLine();
14946
15044
  }
14947
15045
  return { lines, lineCount: lines.length };
14948
15046
  function appendBreakableSegment(segIdx, startG, gWidths) {
@@ -14953,7 +15051,7 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache2) {
14953
15051
  continue;
14954
15052
  }
14955
15053
  if (lineW + gw > maxWidth + 5e-3) {
14956
- emitLine();
15054
+ flushLine();
14957
15055
  startLineAtGrapheme(segIdx, g, gw);
14958
15056
  } else {
14959
15057
  lineW += gw;
@@ -15044,9 +15142,9 @@ function reactiveLayout(opts) {
15044
15142
  const hr = hitRate;
15045
15143
  const len = result.length;
15046
15144
  const el = elapsed;
15047
- emitWithBatch((msgs) => meta["cache-hit-rate"]?.down(msgs), [[DATA, hr]], 3);
15048
- emitWithBatch((msgs) => meta["segment-count"]?.down(msgs), [[DATA, len]], 3);
15049
- emitWithBatch((msgs) => meta["layout-time-ns"]?.down(msgs), [[DATA, el]], 3);
15145
+ downWithBatch((msgs) => meta["cache-hit-rate"]?.down(msgs), [[DATA, hr]], 3);
15146
+ downWithBatch((msgs) => meta["segment-count"]?.down(msgs), [[DATA, len]], 3);
15147
+ downWithBatch((msgs) => meta["layout-time-ns"]?.down(msgs), [[DATA, el]], 3);
15050
15148
  }
15051
15149
  return result;
15052
15150
  },
@@ -17693,7 +17791,7 @@ __export(orchestration_exports, {
17693
17791
  approval: () => approval,
17694
17792
  branch: () => branch,
17695
17793
  forEach: () => forEach2,
17696
- gate: () => gate2,
17794
+ gate: () => gate,
17697
17795
  join: () => join2,
17698
17796
  loop: () => loop,
17699
17797
  onFailure: () => onFailure,
@@ -17701,6 +17799,7 @@ __export(orchestration_exports, {
17701
17799
  sensor: () => sensor,
17702
17800
  subPipeline: () => subPipeline,
17703
17801
  task: () => task,
17802
+ valve: () => valve2,
17704
17803
  wait: () => wait
17705
17804
  });
17706
17805
  function resolveDep(graph, dep) {
@@ -17800,7 +17899,7 @@ function branch(graph, name, source, predicate, opts) {
17800
17899
  registerStep(graph, name, step, src.path ? [src.path] : []);
17801
17900
  return step;
17802
17901
  }
17803
- function gate2(graph, name, source, control, opts) {
17902
+ function valve2(graph, name, source, control, opts) {
17804
17903
  const src = resolveDep(graph, source);
17805
17904
  const ctrl = resolveDep(graph, control);
17806
17905
  const step = node(
@@ -17817,7 +17916,7 @@ function gate2(graph, name, source, control, opts) {
17817
17916
  ...opts,
17818
17917
  name,
17819
17918
  describeKind: "operator",
17820
- meta: baseMeta3("gate", opts?.meta)
17919
+ meta: baseMeta3("valve", opts?.meta)
17821
17920
  }
17822
17921
  );
17823
17922
  registerStep(
@@ -17856,6 +17955,119 @@ function approval(graph, name, source, approver, opts) {
17856
17955
  );
17857
17956
  return step;
17858
17957
  }
17958
+ function gate(graph, name, source, opts) {
17959
+ const maxPending = opts?.maxPending ?? Infinity;
17960
+ if (maxPending < 1 && maxPending !== Infinity) {
17961
+ throw new RangeError("gate: maxPending must be >= 1");
17962
+ }
17963
+ const startOpen = opts?.startOpen ?? false;
17964
+ const src = resolveDep(graph, source);
17965
+ const pendingNode = state([], { name: "pending", equals: () => false });
17966
+ const isOpenNode = state(startOpen, { name: "isOpen" });
17967
+ const countNode = node([pendingNode], ([arr]) => arr.length, {
17968
+ name: "count",
17969
+ describeKind: "derived"
17970
+ });
17971
+ let queue = [];
17972
+ let torn = false;
17973
+ function syncPending() {
17974
+ pendingNode.down([[DATA, [...queue]]]);
17975
+ }
17976
+ function enqueue(value) {
17977
+ queue.push(value);
17978
+ if (queue.length > maxPending) queue.shift();
17979
+ syncPending();
17980
+ }
17981
+ function dequeue(n) {
17982
+ const items = queue.splice(0, n);
17983
+ syncPending();
17984
+ return items;
17985
+ }
17986
+ function guardTorn(method) {
17987
+ if (torn) throw new Error(`gate: ${method}() called after gate was torn down`);
17988
+ }
17989
+ const output = node([src.node], () => void 0, {
17990
+ name,
17991
+ describeKind: "operator",
17992
+ meta: baseMeta3("gate", opts?.meta),
17993
+ onMessage(msg, _depIndex, actions) {
17994
+ if (msg[0] === DATA) {
17995
+ if (isOpenNode.get()) {
17996
+ actions.emit(msg[1]);
17997
+ } else {
17998
+ enqueue(msg[1]);
17999
+ actions.down([[RESOLVED]]);
18000
+ }
18001
+ return true;
18002
+ }
18003
+ if (msg[0] === TEARDOWN) {
18004
+ torn = true;
18005
+ queue = [];
18006
+ syncPending();
18007
+ actions.down([msg]);
18008
+ return true;
18009
+ }
18010
+ if (msg[0] === COMPLETE || msg[0] === ERROR) {
18011
+ torn = true;
18012
+ queue = [];
18013
+ syncPending();
18014
+ actions.down([msg]);
18015
+ return true;
18016
+ }
18017
+ actions.down([msg]);
18018
+ return true;
18019
+ }
18020
+ });
18021
+ const controller = {
18022
+ node: output,
18023
+ pending: pendingNode,
18024
+ count: countNode,
18025
+ isOpen: isOpenNode,
18026
+ approve(count = 1) {
18027
+ guardTorn("approve");
18028
+ const items = dequeue(count);
18029
+ for (const item of items) {
18030
+ if (torn) break;
18031
+ output.down([[DATA, item]]);
18032
+ }
18033
+ },
18034
+ reject(count = 1) {
18035
+ guardTorn("reject");
18036
+ dequeue(count);
18037
+ },
18038
+ modify(fn, count = 1) {
18039
+ guardTorn("modify");
18040
+ const snapshot = [...queue];
18041
+ const items = dequeue(count);
18042
+ for (let i = 0; i < items.length; i++) {
18043
+ if (torn) break;
18044
+ output.down([[DATA, fn(items[i], i, snapshot)]]);
18045
+ }
18046
+ },
18047
+ open() {
18048
+ guardTorn("open");
18049
+ isOpenNode.down([[DATA, true]]);
18050
+ const items = dequeue(queue.length);
18051
+ for (const item of items) {
18052
+ if (torn) break;
18053
+ output.down([[DATA, item]]);
18054
+ }
18055
+ },
18056
+ close() {
18057
+ guardTorn("close");
18058
+ isOpenNode.down([[DATA, false]]);
18059
+ }
18060
+ };
18061
+ countNode.subscribe(() => void 0);
18062
+ registerStep(graph, name, output, src.path ? [src.path] : []);
18063
+ const internal = new Graph(`${name}_state`);
18064
+ internal.add("pending", pendingNode);
18065
+ internal.add("isOpen", isOpenNode);
18066
+ internal.add("count", countNode);
18067
+ internal.connect("pending", "count");
18068
+ graph.mount(`${name}_state`, internal);
18069
+ return controller;
18070
+ }
17859
18071
  function forEach2(graph, name, source, run, opts) {
17860
18072
  const src = resolveDep(graph, source);
17861
18073
  let terminated = false;
@@ -18475,8 +18687,8 @@ function reactiveBlockLayout(opts) {
18475
18687
  const elapsed = monotonicNs() - t0;
18476
18688
  const meta = measuredBlocksNode.meta;
18477
18689
  if (meta) {
18478
- emitWithBatch((msgs) => meta["block-count"]?.down(msgs), [[DATA, result.length]], 3);
18479
- emitWithBatch((msgs) => meta["layout-time-ns"]?.down(msgs), [[DATA, elapsed]], 3);
18690
+ downWithBatch((msgs) => meta["block-count"]?.down(msgs), [[DATA, result.length]], 3);
18691
+ downWithBatch((msgs) => meta["layout-time-ns"]?.down(msgs), [[DATA, elapsed]], 3);
18480
18692
  }
18481
18693
  return result;
18482
18694
  },
@@ -18627,10 +18839,10 @@ var version = "0.0.0";
18627
18839
  distill,
18628
18840
  distinctUntilChanged,
18629
18841
  domainTemplates,
18842
+ downWithBatch,
18630
18843
  dynamicNode,
18631
18844
  effect,
18632
18845
  elementAt,
18633
- emitWithBatch,
18634
18846
  empty,
18635
18847
  escapeRegexChar,
18636
18848
  exhaustMap,
@@ -18675,7 +18887,6 @@ var version = "0.0.0";
18675
18887
  fromTimer,
18676
18888
  fromWebSocket,
18677
18889
  fromWebhook,
18678
- gate,
18679
18890
  globToRegExp,
18680
18891
  graph,
18681
18892
  graphspec,
@@ -18791,6 +19002,7 @@ var version = "0.0.0";
18791
19002
  toWebSocket,
18792
19003
  tokenBucket,
18793
19004
  tokenTracker,
19005
+ valve,
18794
19006
  verifiable,
18795
19007
  version,
18796
19008
  vue,