@graphrefly/graphrefly 0.17.0 → 0.18.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 (71) hide show
  1. package/dist/{chunk-2PORF4RP.js → chunk-76YPZQTW.js} +2 -8
  2. package/dist/{chunk-2PORF4RP.js.map → chunk-76YPZQTW.js.map} +1 -1
  3. package/dist/{chunk-646OG3PO.js → chunk-F6ORUNO7.js} +18 -51
  4. package/dist/chunk-F6ORUNO7.js.map +1 -0
  5. package/dist/{chunk-EBNKJULL.js → chunk-FCLROC4Q.js} +2 -2
  6. package/dist/chunk-FCLROC4Q.js.map +1 -0
  7. package/dist/{chunk-F2ULI3Q3.js → chunk-J7S54G7I.js} +1 -2
  8. package/dist/{chunk-XJ6EMQ22.js → chunk-KJGUP35I.js} +3 -9
  9. package/dist/chunk-KJGUP35I.js.map +1 -0
  10. package/dist/{chunk-IHJHBADD.js → chunk-LB3RYLSC.js} +206 -173
  11. package/dist/chunk-LB3RYLSC.js.map +1 -0
  12. package/dist/{chunk-R6OHUUYB.js → chunk-TNKODJ6E.js} +2 -6
  13. package/dist/chunk-TNKODJ6E.js.map +1 -0
  14. package/dist/{chunk-YXROQFXZ.js → chunk-UVWEKTYC.js} +2 -2
  15. package/dist/compat/nestjs/index.cjs +221 -224
  16. package/dist/compat/nestjs/index.cjs.map +1 -1
  17. package/dist/compat/nestjs/index.d.cts +4 -4
  18. package/dist/compat/nestjs/index.d.ts +4 -4
  19. package/dist/compat/nestjs/index.js +6 -12
  20. package/dist/core/index.cjs +0 -83
  21. package/dist/core/index.cjs.map +1 -1
  22. package/dist/core/index.d.cts +2 -2
  23. package/dist/core/index.d.ts +2 -2
  24. package/dist/core/index.js +2 -6
  25. package/dist/extra/index.cjs +17 -53
  26. package/dist/extra/index.cjs.map +1 -1
  27. package/dist/extra/index.d.cts +4 -4
  28. package/dist/extra/index.d.ts +4 -4
  29. package/dist/extra/index.js +2 -8
  30. package/dist/graph/index.cjs +204 -171
  31. package/dist/graph/index.cjs.map +1 -1
  32. package/dist/graph/index.d.cts +3 -3
  33. package/dist/graph/index.d.ts +3 -3
  34. package/dist/graph/index.js +3 -3
  35. package/dist/{graph-Dc-P9BVm.d.ts → graph-BYFlyNpX.d.cts} +47 -45
  36. package/dist/{graph-fCsaaVIa.d.cts → graph-gISB9n3n.d.ts} +47 -45
  37. package/dist/{index-N704txAA.d.ts → index-7WnwgjMu.d.ts} +5 -7
  38. package/dist/{index-DWq0P9T6.d.ts → index-B43mC7uY.d.cts} +5 -7
  39. package/dist/{index-BmoUvOGN.d.ts → index-B80mMeuf.d.ts} +2 -4
  40. package/dist/{index-DlGMf_Qe.d.cts → index-BqOWSFhr.d.cts} +2 -2
  41. package/dist/{index-BBVBYPxr.d.cts → index-CEDaJaYE.d.ts} +5 -7
  42. package/dist/{index-DhXznWyH.d.ts → index-CgKPpiu8.d.ts} +2 -2
  43. package/dist/{index-D7y9Q8W4.d.ts → index-Ci_vPaVm.d.cts} +4 -6
  44. package/dist/{index-4OIX-q0C.d.cts → index-DKaB2x0T.d.ts} +4 -6
  45. package/dist/{index-ClaKZFPl.d.cts → index-D_tUMcpz.d.cts} +5 -7
  46. package/dist/{index-YlOH1Gw6.d.cts → index-EmzYk-TG.d.cts} +2 -4
  47. package/dist/index.cjs +312 -239
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +51 -13
  50. package/dist/index.d.ts +51 -13
  51. package/dist/index.js +103 -24
  52. package/dist/index.js.map +1 -1
  53. package/dist/{meta-BV4pj9ML.d.cts → meta-npl5b97j.d.cts} +1 -53
  54. package/dist/{meta-BV4pj9ML.d.ts → meta-npl5b97j.d.ts} +1 -53
  55. package/dist/observable-DFBCBELR.d.cts +36 -0
  56. package/dist/observable-oAGygKvc.d.ts +36 -0
  57. package/dist/patterns/reactive-layout/index.cjs +204 -171
  58. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  59. package/dist/patterns/reactive-layout/index.d.cts +3 -3
  60. package/dist/patterns/reactive-layout/index.d.ts +3 -3
  61. package/dist/patterns/reactive-layout/index.js +3 -3
  62. package/package.json +1 -1
  63. package/dist/chunk-646OG3PO.js.map +0 -1
  64. package/dist/chunk-EBNKJULL.js.map +0 -1
  65. package/dist/chunk-IHJHBADD.js.map +0 -1
  66. package/dist/chunk-R6OHUUYB.js.map +0 -1
  67. package/dist/chunk-XJ6EMQ22.js.map +0 -1
  68. package/dist/observable-Cz-AWhwR.d.cts +0 -42
  69. package/dist/observable-DCqlwGyl.d.ts +0 -42
  70. /package/dist/{chunk-F2ULI3Q3.js.map → chunk-J7S54G7I.js.map} +0 -0
  71. /package/dist/{chunk-YXROQFXZ.js.map → chunk-UVWEKTYC.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -129,7 +129,6 @@ __export(index_exports, {
129
129
  delay: () => delay,
130
130
  demoShell: () => demo_shell_exports,
131
131
  derived: () => derived,
132
- describeNode: () => describeNode,
133
132
  deserializeError: () => deserializeError,
134
133
  distill: () => distill,
135
134
  distinctUntilChanged: () => distinctUntilChanged,
@@ -208,7 +207,6 @@ __export(index_exports, {
208
207
  mergeMap: () => mergeMap,
209
208
  messageTier: () => messageTier,
210
209
  messaging: () => messaging_exports,
211
- metaSnapshot: () => metaSnapshot,
212
210
  monotonicNs: () => monotonicNs,
213
211
  nameToSignal: () => nameToSignal,
214
212
  nanostores: () => nanostores_exports,
@@ -217,8 +215,6 @@ __export(index_exports, {
217
215
  never: () => never,
218
216
  node: () => node,
219
217
  normalizeActor: () => normalizeActor,
220
- observeGraph$: () => observeGraph$,
221
- observeNode$: () => observeNode$,
222
218
  of: () => of,
223
219
  orchestration: () => orchestration_exports,
224
220
  pairwise: () => pairwise,
@@ -285,7 +281,6 @@ __export(index_exports, {
285
281
  toFile: () => toFile,
286
282
  toKafka: () => toKafka,
287
283
  toLoki: () => toLoki,
288
- toMessages$: () => toMessages$,
289
284
  toMongo: () => toMongo,
290
285
  toNATS: () => toNATS,
291
286
  toObservable: () => toObservable,
@@ -2166,58 +2161,35 @@ __export(nestjs_exports, {
2166
2161
  getActor: () => getActor,
2167
2162
  getGraphToken: () => getGraphToken,
2168
2163
  getNodeToken: () => getNodeToken,
2169
- observeGraph$: () => observeGraph$,
2170
- observeNode$: () => observeNode$,
2171
2164
  observeSSE: () => observeSSE,
2172
2165
  observeSubscription: () => observeSubscription,
2173
- toMessages$: () => toMessages$,
2174
2166
  toObservable: () => toObservable
2175
2167
  });
2176
2168
 
2177
2169
  // src/extra/observable.ts
2178
2170
  var import_rxjs = require("rxjs");
2179
- function toObservable(node2) {
2180
- return new import_rxjs.Observable((subscriber) => {
2181
- const unsub = node2.subscribe((msgs) => {
2182
- for (const m of msgs) {
2171
+ function toObservable(node2, options) {
2172
+ if (options?.raw) {
2173
+ return new import_rxjs.Observable((subscriber) => {
2174
+ const unsub = node2.subscribe((msgs) => {
2183
2175
  if (subscriber.closed) return;
2184
- if (m[0] === DATA) {
2185
- subscriber.next(m[1]);
2186
- } else if (m[0] === ERROR) {
2187
- subscriber.error(m[1]);
2188
- return;
2189
- } else if (m[0] === COMPLETE) {
2190
- subscriber.complete();
2191
- return;
2176
+ subscriber.next(msgs);
2177
+ for (const m of msgs) {
2178
+ if (m[0] === ERROR) {
2179
+ subscriber.error(m[1]);
2180
+ return;
2181
+ }
2182
+ if (m[0] === COMPLETE) {
2183
+ subscriber.complete();
2184
+ return;
2185
+ }
2192
2186
  }
2193
- }
2187
+ });
2188
+ return unsub;
2194
2189
  });
2195
- return unsub;
2196
- });
2197
- }
2198
- function toMessages$(node2) {
2190
+ }
2199
2191
  return new import_rxjs.Observable((subscriber) => {
2200
2192
  const unsub = node2.subscribe((msgs) => {
2201
- if (subscriber.closed) return;
2202
- subscriber.next(msgs);
2203
- for (const m of msgs) {
2204
- if (m[0] === ERROR) {
2205
- subscriber.error(m[1]);
2206
- return;
2207
- }
2208
- if (m[0] === COMPLETE) {
2209
- subscriber.complete();
2210
- return;
2211
- }
2212
- }
2213
- });
2214
- return unsub;
2215
- });
2216
- }
2217
- function observeNode$(graph, path, options) {
2218
- return new import_rxjs.Observable((subscriber) => {
2219
- const handle = graph.observe(path, options);
2220
- const unsub = handle.subscribe((msgs) => {
2221
2193
  for (const m of msgs) {
2222
2194
  if (subscriber.closed) return;
2223
2195
  if (m[0] === DATA) {
@@ -2234,16 +2206,6 @@ function observeNode$(graph, path, options) {
2234
2206
  return unsub;
2235
2207
  });
2236
2208
  }
2237
- function observeGraph$(graph, options) {
2238
- return new import_rxjs.Observable((subscriber) => {
2239
- const handle = graph.observe(options);
2240
- const unsub = handle.subscribe((nodePath, messages) => {
2241
- if (subscriber.closed) return;
2242
- subscriber.next({ path: nodePath, messages });
2243
- });
2244
- return unsub;
2245
- });
2246
- }
2247
2209
 
2248
2210
  // src/compat/nestjs/decorators.ts
2249
2211
  var import_common = require("@nestjs/common");
@@ -3790,7 +3752,7 @@ var RingBuffer = class {
3790
3752
  return result;
3791
3753
  }
3792
3754
  };
3793
- var SPY_ANSI_THEME = {
3755
+ var OBSERVE_ANSI_THEME = {
3794
3756
  data: "\x1B[32m",
3795
3757
  dirty: "\x1B[33m",
3796
3758
  resolved: "\x1B[36m",
@@ -3800,7 +3762,7 @@ var SPY_ANSI_THEME = {
3800
3762
  path: "\x1B[90m",
3801
3763
  reset: "\x1B[0m"
3802
3764
  };
3803
- var SPY_NO_COLOR_THEME = {
3765
+ var OBSERVE_NO_COLOR_THEME = {
3804
3766
  data: "",
3805
3767
  dirty: "",
3806
3768
  resolved: "",
@@ -3820,9 +3782,9 @@ function describeData(value) {
3820
3782
  return "[unserializable]";
3821
3783
  }
3822
3784
  }
3823
- function resolveSpyTheme(theme) {
3824
- if (theme === "none") return SPY_NO_COLOR_THEME;
3825
- if (theme === "ansi" || theme == null) return SPY_ANSI_THEME;
3785
+ function resolveObserveTheme(theme) {
3786
+ if (theme === "none") return OBSERVE_NO_COLOR_THEME;
3787
+ if (theme === "ansi" || theme == null) return OBSERVE_ANSI_THEME;
3826
3788
  return {
3827
3789
  data: theme.data ?? "",
3828
3790
  dirty: theme.dirty ?? "",
@@ -4593,9 +4555,13 @@ var Graph = class _Graph {
4593
4555
  if (actor2 != null && !target.allowsObserve(actor2)) {
4594
4556
  throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
4595
4557
  }
4596
- const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
4597
- if (wantsStructured2 && _Graph.inspectorEnabled) {
4598
- return this._createObserveResult(path, target, resolved);
4558
+ const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full" || resolved.format != null;
4559
+ if (wantsStructured2) {
4560
+ const result = _Graph.inspectorEnabled ? this._createObserveResult(path, target, resolved) : this._createFallbackObserveResult(path, resolved);
4561
+ if (resolved.format != null) {
4562
+ this._attachFormatLogger(result, resolved);
4563
+ }
4564
+ return result;
4599
4565
  }
4600
4566
  return {
4601
4567
  subscribe(sink) {
@@ -4613,9 +4579,13 @@ var Graph = class _Graph {
4613
4579
  }
4614
4580
  const opts = resolveObserveDetail(pathOrOpts);
4615
4581
  const actor = opts.actor;
4616
- const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
4617
- if (wantsStructured && _Graph.inspectorEnabled) {
4618
- return this._createObserveResultForAll(opts);
4582
+ const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full" || opts.format != null;
4583
+ if (wantsStructured) {
4584
+ const result = _Graph.inspectorEnabled ? this._createObserveResultForAll(opts) : this._createFallbackObserveResultForAll(opts);
4585
+ if (opts.format != null) {
4586
+ this._attachFormatLogger(result, opts);
4587
+ }
4588
+ return result;
4619
4589
  }
4620
4590
  return {
4621
4591
  subscribe: (sink) => {
@@ -4659,6 +4629,7 @@ var Graph = class _Graph {
4659
4629
  let lastTriggerDepIndex;
4660
4630
  let lastRunDepValues;
4661
4631
  let detachInspectorHook;
4632
+ let batchSeq = 0;
4662
4633
  if ((causal || derived2) && target instanceof NodeImpl) {
4663
4634
  detachInspectorHook = target._setInspectorHook((event) => {
4664
4635
  if (event.kind === "dep_message") {
@@ -4671,15 +4642,16 @@ var Graph = class _Graph {
4671
4642
  type: "derived",
4672
4643
  path,
4673
4644
  dep_values: [...event.depValues],
4674
- ...timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {}
4645
+ ...timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {}
4675
4646
  });
4676
4647
  }
4677
4648
  });
4678
4649
  }
4679
4650
  const unsub = target.subscribe((msgs) => {
4651
+ batchSeq++;
4680
4652
  for (const m of msgs) {
4681
4653
  const t = m[0];
4682
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
4654
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
4683
4655
  const withCausal = causal && lastRunDepValues != null ? (() => {
4684
4656
  const triggerDep = lastTriggerDepIndex != null && lastTriggerDepIndex >= 0 && target instanceof NodeImpl ? target._deps[lastTriggerDepIndex] : void 0;
4685
4657
  const tv = triggerDep?.v;
@@ -4748,11 +4720,15 @@ var Graph = class _Graph {
4748
4720
  Object.assign(merged, extra);
4749
4721
  }
4750
4722
  const resolvedTarget = graph.resolve(basePath);
4751
- return graph._createObserveResult(
4723
+ const expanded = graph._createObserveResult(
4752
4724
  basePath,
4753
4725
  resolvedTarget,
4754
4726
  resolveObserveDetail(merged)
4755
4727
  );
4728
+ if (merged.format != null) {
4729
+ graph._attachFormatLogger(expanded, merged);
4730
+ }
4731
+ return expanded;
4756
4732
  }
4757
4733
  };
4758
4734
  }
@@ -4772,11 +4748,13 @@ var Graph = class _Graph {
4772
4748
  this._collectObserveTargets("", targets);
4773
4749
  targets.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
4774
4750
  const picked = actor == null ? targets : targets.filter(([, nd]) => nd.allowsObserve(actor));
4751
+ let batchSeq = 0;
4775
4752
  const unsubs = picked.map(
4776
4753
  ([path, nd]) => nd.subscribe((msgs) => {
4754
+ batchSeq++;
4777
4755
  for (const m of msgs) {
4778
4756
  const t = m[0];
4779
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
4757
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
4780
4758
  if (t === DATA) {
4781
4759
  result.values[path] = m[1];
4782
4760
  result.events.push({ type: "data", path, data: m[1], ...base });
@@ -4832,25 +4810,161 @@ var Graph = class _Graph {
4832
4810
  } else {
4833
4811
  Object.assign(merged, extra);
4834
4812
  }
4835
- return graph._createObserveResultForAll(resolveObserveDetail(merged));
4813
+ const expanded = graph._createObserveResultForAll(resolveObserveDetail(merged));
4814
+ if (merged.format != null) {
4815
+ graph._attachFormatLogger(expanded, merged);
4816
+ }
4817
+ return expanded;
4836
4818
  }
4837
4819
  };
4838
4820
  }
4839
4821
  /**
4840
- * Convenience live debugger over {@link Graph.observe}. Logs protocol events as they flow.
4841
- *
4842
- * Supports one-node (`path`) and graph-wide modes, event filtering, and JSON/pretty rendering.
4843
- * Color themes are built in (`ansi` / `none`) to avoid external dependencies.
4844
- *
4845
- * @param options - Spy configuration.
4846
- * @returns Disposable handle plus a structured observation accumulator.
4822
+ * Fallback ObserveResult for single-node when inspector is disabled but `format` is requested.
4823
+ * Subscribes to raw messages and accumulates events with timeline info.
4824
+ */
4825
+ _createFallbackObserveResult(path, options) {
4826
+ const timeline = options.timeline !== false;
4827
+ const acc = {
4828
+ values: {},
4829
+ dirtyCount: 0,
4830
+ resolvedCount: 0,
4831
+ events: [],
4832
+ completedCleanly: false,
4833
+ errored: false
4834
+ };
4835
+ const target = this.resolve(path);
4836
+ let batchSeq = 0;
4837
+ const unsub = target.subscribe((msgs) => {
4838
+ batchSeq++;
4839
+ for (const m of msgs) {
4840
+ const t = m[0];
4841
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
4842
+ if (t === DATA) {
4843
+ acc.values[path] = m[1];
4844
+ acc.events.push({ type: "data", path, data: m[1], ...base });
4845
+ } else if (t === DIRTY) {
4846
+ acc.dirtyCount++;
4847
+ acc.events.push({ type: "dirty", path, ...base });
4848
+ } else if (t === RESOLVED) {
4849
+ acc.resolvedCount++;
4850
+ acc.events.push({ type: "resolved", path, ...base });
4851
+ } else if (t === COMPLETE) {
4852
+ if (!acc.errored) acc.completedCleanly = true;
4853
+ acc.events.push({ type: "complete", path, ...base });
4854
+ } else if (t === ERROR) {
4855
+ acc.errored = true;
4856
+ acc.events.push({ type: "error", path, data: m[1], ...base });
4857
+ }
4858
+ }
4859
+ });
4860
+ return {
4861
+ get values() {
4862
+ return acc.values;
4863
+ },
4864
+ get dirtyCount() {
4865
+ return acc.dirtyCount;
4866
+ },
4867
+ get resolvedCount() {
4868
+ return acc.resolvedCount;
4869
+ },
4870
+ get events() {
4871
+ return acc.events;
4872
+ },
4873
+ get completedCleanly() {
4874
+ return acc.completedCleanly;
4875
+ },
4876
+ get errored() {
4877
+ return acc.errored;
4878
+ },
4879
+ dispose() {
4880
+ unsub();
4881
+ },
4882
+ expand() {
4883
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
4884
+ }
4885
+ };
4886
+ }
4887
+ /**
4888
+ * Fallback ObserveResult for graph-wide when inspector is disabled but `format` is requested.
4889
+ */
4890
+ _createFallbackObserveResultForAll(options) {
4891
+ const timeline = options.timeline !== false;
4892
+ const actor = options.actor;
4893
+ const acc = {
4894
+ values: {},
4895
+ dirtyCount: 0,
4896
+ resolvedCount: 0,
4897
+ events: [],
4898
+ completedCleanly: false,
4899
+ errored: false
4900
+ };
4901
+ const targets = [];
4902
+ this._collectObserveTargets("", targets);
4903
+ targets.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
4904
+ const picked = actor == null ? targets : targets.filter(([, nd]) => nd.allowsObserve(actor));
4905
+ let batchSeq = 0;
4906
+ const unsubs = picked.map(
4907
+ ([path, nd]) => nd.subscribe((msgs) => {
4908
+ batchSeq++;
4909
+ for (const m of msgs) {
4910
+ const t = m[0];
4911
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
4912
+ if (t === DATA) {
4913
+ acc.values[path] = m[1];
4914
+ acc.events.push({ type: "data", path, data: m[1], ...base });
4915
+ } else if (t === DIRTY) {
4916
+ acc.dirtyCount++;
4917
+ acc.events.push({ type: "dirty", path, ...base });
4918
+ } else if (t === RESOLVED) {
4919
+ acc.resolvedCount++;
4920
+ acc.events.push({ type: "resolved", path, ...base });
4921
+ } else if (t === COMPLETE) {
4922
+ if (!acc.errored) acc.completedCleanly = true;
4923
+ acc.events.push({ type: "complete", path, ...base });
4924
+ } else if (t === ERROR) {
4925
+ acc.errored = true;
4926
+ acc.events.push({ type: "error", path, data: m[1], ...base });
4927
+ }
4928
+ }
4929
+ })
4930
+ );
4931
+ return {
4932
+ get values() {
4933
+ return acc.values;
4934
+ },
4935
+ get dirtyCount() {
4936
+ return acc.dirtyCount;
4937
+ },
4938
+ get resolvedCount() {
4939
+ return acc.resolvedCount;
4940
+ },
4941
+ get events() {
4942
+ return acc.events;
4943
+ },
4944
+ get completedCleanly() {
4945
+ return acc.completedCleanly;
4946
+ },
4947
+ get errored() {
4948
+ return acc.errored;
4949
+ },
4950
+ dispose() {
4951
+ for (const u of unsubs) u();
4952
+ },
4953
+ expand() {
4954
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
4955
+ }
4956
+ };
4957
+ }
4958
+ /**
4959
+ * Attaches a format logger to an ObserveResult, rendering events as they arrive.
4960
+ * Wraps the result's dispose to flush pending events.
4847
4961
  */
4848
- spy(options = {}) {
4962
+ _attachFormatLogger(result, options) {
4963
+ const format = options.format;
4964
+ const logger = options.logger ?? ((line) => console.log(line));
4849
4965
  const include = options.includeTypes ? new Set(options.includeTypes) : null;
4850
4966
  const exclude = options.excludeTypes ? new Set(options.excludeTypes) : null;
4851
- const theme = resolveSpyTheme(options.theme);
4852
- const format = options.format ?? "pretty";
4853
- const logger = options.logger ?? ((line) => console.log(line));
4967
+ const theme = resolveObserveTheme(options.theme);
4854
4968
  const shouldLog = (type) => {
4855
4969
  if (include?.has(type) === false) return false;
4856
4970
  if (exclude?.has(type) === true) return false;
@@ -4875,133 +4989,26 @@ var Graph = class _Graph {
4875
4989
  const batchPart = event.in_batch ? " [batch]" : "";
4876
4990
  return `${pathPart}${color}${event.type.toUpperCase()}${theme.reset}${dataPart}${triggerPart}${batchPart}`;
4877
4991
  };
4878
- if (!_Graph.inspectorEnabled) {
4879
- const timeline = options.timeline ?? true;
4880
- const acc = {
4881
- values: {},
4882
- dirtyCount: 0,
4883
- resolvedCount: 0,
4884
- events: [],
4885
- completedCleanly: false,
4886
- errored: false
4887
- };
4888
- let stop2 = () => {
4889
- };
4890
- const result2 = {
4891
- get values() {
4892
- return acc.values;
4893
- },
4894
- get dirtyCount() {
4895
- return acc.dirtyCount;
4896
- },
4897
- get resolvedCount() {
4898
- return acc.resolvedCount;
4899
- },
4900
- get events() {
4901
- return acc.events;
4902
- },
4903
- get completedCleanly() {
4904
- return acc.completedCleanly;
4905
- },
4906
- get errored() {
4907
- return acc.errored;
4908
- },
4909
- dispose() {
4910
- stop2();
4911
- },
4912
- expand() {
4913
- throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
4914
- }
4915
- };
4916
- const pushEvent = (path, message) => {
4917
- const t = message[0];
4918
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
4919
- let event;
4920
- if (t === DATA) {
4921
- if (path != null) acc.values[path] = message[1];
4922
- event = { type: "data", ...path != null ? { path } : {}, data: message[1], ...base };
4923
- } else if (t === DIRTY) {
4924
- acc.dirtyCount += 1;
4925
- event = { type: "dirty", ...path != null ? { path } : {}, ...base };
4926
- } else if (t === RESOLVED) {
4927
- acc.resolvedCount += 1;
4928
- event = { type: "resolved", ...path != null ? { path } : {}, ...base };
4929
- } else if (t === COMPLETE) {
4930
- if (!acc.errored) acc.completedCleanly = true;
4931
- event = { type: "complete", ...path != null ? { path } : {}, ...base };
4932
- } else if (t === ERROR) {
4933
- acc.errored = true;
4934
- event = {
4935
- type: "error",
4936
- ...path != null ? { path } : {},
4937
- data: message[1],
4938
- ...base
4939
- };
4992
+ let cursor = 0;
4993
+ const flush = () => {
4994
+ const events = result.events;
4995
+ while (cursor < events.length) {
4996
+ const event = events[cursor++];
4997
+ if (shouldLog(event.type)) {
4998
+ logger(renderEvent(event), event);
4940
4999
  }
4941
- if (!event) return;
4942
- acc.events.push(event);
4943
- if (!shouldLog(event.type)) return;
4944
- logger(renderEvent(event), event);
4945
- };
4946
- if (options.path != null) {
4947
- const stream2 = this.observe(options.path, {
4948
- actor: options.actor,
4949
- structured: false
4950
- });
4951
- stop2 = stream2.subscribe((messages) => {
4952
- for (const m of messages) {
4953
- pushEvent(options.path, m);
4954
- }
4955
- });
4956
- } else {
4957
- const stream2 = this.observe({ actor: options.actor, structured: false });
4958
- stop2 = stream2.subscribe((path, messages) => {
4959
- for (const m of messages) {
4960
- pushEvent(path, m);
4961
- }
4962
- });
4963
5000
  }
4964
- return {
4965
- result: result2,
4966
- dispose() {
4967
- result2.dispose();
4968
- }
4969
- };
4970
- }
4971
- const structuredObserveOptions = {
4972
- actor: options.actor,
4973
- structured: true,
4974
- ...options.timeline !== false ? { timeline: true } : {},
4975
- ...options.causal ? { causal: true } : {},
4976
- ...options.derived ? { derived: true } : {}
4977
5001
  };
4978
- const result = options.path != null ? this.observe(options.path, structuredObserveOptions) : this.observe(structuredObserveOptions);
4979
- let cursor = 0;
4980
- const flushNewEvents = () => {
4981
- const nextEvents = result.events.slice(cursor);
4982
- cursor = result.events.length;
4983
- for (const event of nextEvents) {
4984
- if (!shouldLog(event.type)) continue;
4985
- logger(renderEvent(event), event);
4986
- }
5002
+ const origPush = result.events.push;
5003
+ result.events.push = function(...items) {
5004
+ const ret = origPush.apply(this, items);
5005
+ flush();
5006
+ return ret;
4987
5007
  };
4988
- const stream = options.path != null ? this.observe(options.path, { actor: options.actor, structured: false }) : this.observe({ actor: options.actor, structured: false });
4989
- const stop = options.path != null ? stream.subscribe((messages) => {
4990
- if (messages.length > 0) {
4991
- flushNewEvents();
4992
- }
4993
- }) : stream.subscribe((_path, messages) => {
4994
- if (messages.length > 0) {
4995
- flushNewEvents();
4996
- }
4997
- });
4998
- return {
4999
- result,
5000
- dispose() {
5001
- stop();
5002
- flushNewEvents();
5003
- result.dispose();
5004
- }
5008
+ const origDispose = result.dispose.bind(result);
5009
+ result.dispose = () => {
5010
+ origDispose();
5011
+ flush();
5005
5012
  };
5006
5013
  }
5007
5014
  /**
@@ -5396,33 +5403,21 @@ var Graph = class _Graph {
5396
5403
  // ——————————————————————————————————————————————————————————————
5397
5404
  /**
5398
5405
  * When `false`, structured observation options (`causal`, `timeline`),
5399
- * `annotate()`, and `traceLog()` are no-ops. Raw `observe()` always works.
5406
+ * and `trace()` writes are no-ops. Raw `observe()` always works.
5400
5407
  *
5401
5408
  * Default: `true` outside production (`process.env.NODE_ENV !== "production"`).
5402
5409
  */
5403
5410
  static inspectorEnabled = !(typeof process !== "undefined" && process.env?.NODE_ENV === "production");
5404
5411
  _annotations = /* @__PURE__ */ new Map();
5405
5412
  _traceRing = new RingBuffer(1e3);
5406
- /**
5407
- * Attaches a reasoning annotation to a node — captures *why* an AI agent set a value.
5408
- *
5409
- * No-op when {@link Graph.inspectorEnabled} is `false`.
5410
- *
5411
- * @param path - Qualified node path.
5412
- * @param reason - Free-text note stored in the trace ring buffer.
5413
- */
5414
- annotate(path, reason) {
5415
- if (!_Graph.inspectorEnabled) return;
5416
- this.resolve(path);
5417
- this._annotations.set(path, reason);
5418
- this._traceRing.push({ path, reason, timestamp_ns: monotonicNs() });
5419
- }
5420
- /**
5421
- * Returns a chronological log of all reasoning annotations (ring buffer).
5422
- *
5423
- * @returns `[]` when {@link Graph.inspectorEnabled} is `false`.
5424
- */
5425
- traceLog() {
5413
+ trace(path, reason) {
5414
+ if (path != null && reason != null) {
5415
+ if (!_Graph.inspectorEnabled) return;
5416
+ this.resolve(path);
5417
+ this._annotations.set(path, reason);
5418
+ this._traceRing.push({ path, reason, timestamp_ns: monotonicNs() });
5419
+ return;
5420
+ }
5426
5421
  if (!_Graph.inspectorEnabled) return [];
5427
5422
  return this._traceRing.toArray();
5428
5423
  }
@@ -5585,7 +5580,6 @@ __export(core_exports, {
5585
5580
  createVersioning: () => createVersioning,
5586
5581
  defaultHash: () => defaultHash,
5587
5582
  derived: () => derived,
5588
- describeNode: () => describeNode,
5589
5583
  downWithBatch: () => downWithBatch,
5590
5584
  dynamicNode: () => dynamicNode,
5591
5585
  effect: () => effect,
@@ -5596,7 +5590,6 @@ __export(core_exports, {
5596
5590
  isV1: () => isV1,
5597
5591
  knownMessageTypes: () => knownMessageTypes,
5598
5592
  messageTier: () => messageTier,
5599
- metaSnapshot: () => metaSnapshot,
5600
5593
  monotonicNs: () => monotonicNs,
5601
5594
  node: () => node,
5602
5595
  normalizeActor: () => normalizeActor,
@@ -7079,8 +7072,6 @@ __export(extra_exports, {
7079
7072
  mergeMap: () => mergeMap,
7080
7073
  nameToSignal: () => nameToSignal,
7081
7074
  never: () => never,
7082
- observeGraph$: () => observeGraph$,
7083
- observeNode$: () => observeNode$,
7084
7075
  of: () => of,
7085
7076
  pairwise: () => pairwise,
7086
7077
  parseCron: () => parseCron,
@@ -7129,7 +7120,6 @@ __export(extra_exports, {
7129
7120
  toFile: () => toFile,
7130
7121
  toKafka: () => toKafka,
7131
7122
  toLoki: () => toLoki,
7132
- toMessages$: () => toMessages$,
7133
7123
  toMongo: () => toMongo,
7134
7124
  toNATS: () => toNATS,
7135
7125
  toObservable: () => toObservable,
@@ -15520,7 +15510,7 @@ function demoShell(opts) {
15520
15510
  ([ref, _tick]) => {
15521
15511
  const demo = ref;
15522
15512
  if (!demo) return [];
15523
- return demo.traceLog();
15513
+ return demo.trace();
15524
15514
  },
15525
15515
  { name: "inspect/trace-log" }
15526
15516
  );
@@ -17471,6 +17461,7 @@ __export(harness_exports, {
17471
17461
  evalIntakeBridge: () => evalIntakeBridge,
17472
17462
  harnessLoop: () => harnessLoop,
17473
17463
  harnessProfile: () => harnessProfile,
17464
+ harnessTrace: () => harnessTrace,
17474
17465
  priorityScore: () => priorityScore,
17475
17466
  strategyKey: () => strategyKey,
17476
17467
  strategyModel: () => strategyModel
@@ -18687,7 +18678,7 @@ function harnessLoop(name, opts) {
18687
18678
  });
18688
18679
  const itemRetries = item._retries ?? 0;
18689
18680
  if (errClass === "self-correctable" && itemRetries < maxRetries && (totalRetries.get() ?? 0) < maxTotalRetries) {
18690
- totalRetries.down([[DATA, (totalRetries.get() ?? 0) + 1]]);
18681
+ totalRetries.down([[DIRTY], [DATA, (totalRetries.get() ?? 0) + 1]]);
18691
18682
  const key = trackingKey(item);
18692
18683
  const retryItem = {
18693
18684
  ...item,
@@ -18702,7 +18693,7 @@ function harnessLoop(name, opts) {
18702
18693
  const key = trackingKey(item);
18703
18694
  const itemReingestions = item._reingestions ?? 0;
18704
18695
  if (itemReingestions < maxReingestions && (totalReingestions.get() ?? 0) < maxTotalReingestions) {
18705
- totalReingestions.down([[DATA, (totalReingestions.get() ?? 0) + 1]]);
18696
+ totalReingestions.down([[DIRTY], [DATA, (totalReingestions.get() ?? 0) + 1]]);
18706
18697
  intake.publish({
18707
18698
  source: "eval",
18708
18699
  summary: `Verification failed for: ${key}`,
@@ -18731,6 +18722,10 @@ function harnessLoop(name, opts) {
18731
18722
  harness.addDisposer(routerUnsub);
18732
18723
  harness.addDisposer(fastRetryUnsub);
18733
18724
  harness.addDisposer(strategy.dispose);
18725
+ harness.add("triage", triageNode);
18726
+ harness.add("execute", executeNode);
18727
+ harness.add("verify", verifyNode);
18728
+ harness.add("strategy", strategy.node);
18734
18729
  harness.mount("intake", intake);
18735
18730
  for (const [route, topic2] of queueTopics) {
18736
18731
  harness.mount(`queue/${route}`, topic2);
@@ -18757,6 +18752,89 @@ function harnessProfile(harness, opts) {
18757
18752
  };
18758
18753
  }
18759
18754
 
18755
+ // src/patterns/harness/trace.ts
18756
+ var STAGE_LABELS = {
18757
+ "intake::latest": "INTAKE",
18758
+ triage: "TRIAGE",
18759
+ execute: "EXECUTE",
18760
+ "verify-results::latest": "VERIFY",
18761
+ strategy: "STRATEGY"
18762
+ };
18763
+ for (const route of QUEUE_NAMES) {
18764
+ STAGE_LABELS[`queue/${route}::latest`] = "QUEUE";
18765
+ }
18766
+ function harnessTrace(harness, opts) {
18767
+ const logger = opts?.logger ?? console.log;
18768
+ const startNs = monotonicNs();
18769
+ const observations = [];
18770
+ function elapsed() {
18771
+ const deltaNs = monotonicNs() - startNs;
18772
+ const secs = deltaNs / 1e9;
18773
+ return secs.toFixed(3);
18774
+ }
18775
+ for (const [path, stage] of Object.entries(STAGE_LABELS)) {
18776
+ try {
18777
+ const obs = harness.observe(path, {
18778
+ format: "json",
18779
+ logger: (_line, event) => {
18780
+ if (event.type === "data") {
18781
+ const dataStr = event.data !== void 0 ? ` ${summarize(event.data)}` : "";
18782
+ logger(`[${elapsed()}s] ${stage.padEnd(9)} \u2190${dataStr}`);
18783
+ } else if (event.type === "error") {
18784
+ const errStr = event.data !== void 0 ? ` ${summarize(event.data)}` : "";
18785
+ logger(`[${elapsed()}s] ${stage.padEnd(9)} \u2717${errStr}`);
18786
+ } else if (event.type === "complete") {
18787
+ logger(`[${elapsed()}s] ${stage.padEnd(9)} \u25A0 complete`);
18788
+ }
18789
+ },
18790
+ includeTypes: ["data", "error", "complete"]
18791
+ });
18792
+ observations.push(obs);
18793
+ } catch {
18794
+ }
18795
+ }
18796
+ for (const [gatedRoute] of harness.gates) {
18797
+ const gatePath = `gates::${gatedRoute}/gate`;
18798
+ try {
18799
+ const obs = harness.observe(gatePath, {
18800
+ format: "json",
18801
+ logger: (_line, event) => {
18802
+ if (event.type === "data") {
18803
+ const dataStr = event.data !== void 0 ? ` ${summarize(event.data)}` : "";
18804
+ logger(`[${elapsed()}s] GATE \u25B6${dataStr}`);
18805
+ } else if (event.type === "error") {
18806
+ logger(`[${elapsed()}s] GATE \u2717 ${summarize(event.data)}`);
18807
+ }
18808
+ },
18809
+ includeTypes: ["data", "error", "complete"]
18810
+ });
18811
+ observations.push(obs);
18812
+ } catch {
18813
+ }
18814
+ }
18815
+ return {
18816
+ dispose() {
18817
+ for (const obs of observations) obs.dispose();
18818
+ observations.length = 0;
18819
+ }
18820
+ };
18821
+ }
18822
+ function summarize(value) {
18823
+ if (value == null) return "null";
18824
+ if (typeof value === "string") return truncate(value, 80);
18825
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
18826
+ if (typeof value === "bigint") return String(value);
18827
+ try {
18828
+ const json = JSON.stringify(value);
18829
+ return truncate(json, 120);
18830
+ } catch {
18831
+ return String(value);
18832
+ }
18833
+ }
18834
+ function truncate(s, max) {
18835
+ return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
18836
+ }
18837
+
18760
18838
  // src/patterns/reactive-layout/index.ts
18761
18839
  var reactive_layout_exports = {};
18762
18840
  __export(reactive_layout_exports, {
@@ -19315,7 +19393,6 @@ var version = "0.0.0";
19315
19393
  delay,
19316
19394
  demoShell,
19317
19395
  derived,
19318
- describeNode,
19319
19396
  deserializeError,
19320
19397
  distill,
19321
19398
  distinctUntilChanged,
@@ -19394,7 +19471,6 @@ var version = "0.0.0";
19394
19471
  mergeMap,
19395
19472
  messageTier,
19396
19473
  messaging,
19397
- metaSnapshot,
19398
19474
  monotonicNs,
19399
19475
  nameToSignal,
19400
19476
  nanostores,
@@ -19403,8 +19479,6 @@ var version = "0.0.0";
19403
19479
  never,
19404
19480
  node,
19405
19481
  normalizeActor,
19406
- observeGraph$,
19407
- observeNode$,
19408
19482
  of,
19409
19483
  orchestration,
19410
19484
  pairwise,
@@ -19471,7 +19545,6 @@ var version = "0.0.0";
19471
19545
  toFile,
19472
19546
  toKafka,
19473
19547
  toLoki,
19474
- toMessages$,
19475
19548
  toMongo,
19476
19549
  toNATS,
19477
19550
  toObservable,