@graphrefly/graphrefly 0.16.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 (75) hide show
  1. package/dist/{chunk-RLVFZDCE.js → chunk-76YPZQTW.js} +3 -9
  2. package/dist/{chunk-RLVFZDCE.js.map → chunk-76YPZQTW.js.map} +1 -1
  3. package/dist/{chunk-VZY2B2LU.js → chunk-BV3TPSBK.js} +1 -2
  4. package/dist/chunk-BV3TPSBK.js.map +1 -0
  5. package/dist/{chunk-YX263TXI.js → chunk-F6ORUNO7.js} +19 -52
  6. package/dist/chunk-F6ORUNO7.js.map +1 -0
  7. package/dist/chunk-FCLROC4Q.js +231 -0
  8. package/dist/chunk-FCLROC4Q.js.map +1 -0
  9. package/dist/{chunk-ITDVOCFO.js → chunk-J7S54G7I.js} +2 -3
  10. package/dist/{chunk-26A4E7J7.js → chunk-KJGUP35I.js} +4 -10
  11. package/dist/chunk-KJGUP35I.js.map +1 -0
  12. package/dist/{chunk-3BLRREFM.js → chunk-LB3RYLSC.js} +207 -174
  13. package/dist/chunk-LB3RYLSC.js.map +1 -0
  14. package/dist/{chunk-LKP7IWRV.js → chunk-TNKODJ6E.js} +3 -7
  15. package/dist/chunk-TNKODJ6E.js.map +1 -0
  16. package/dist/{chunk-RZSQ7P2C.js → chunk-UVWEKTYC.js} +3 -3
  17. package/dist/compat/nestjs/index.cjs +221 -225
  18. package/dist/compat/nestjs/index.cjs.map +1 -1
  19. package/dist/compat/nestjs/index.d.cts +4 -4
  20. package/dist/compat/nestjs/index.d.ts +4 -4
  21. package/dist/compat/nestjs/index.js +7 -13
  22. package/dist/core/index.cjs +0 -84
  23. package/dist/core/index.cjs.map +1 -1
  24. package/dist/core/index.d.cts +2 -2
  25. package/dist/core/index.d.ts +2 -2
  26. package/dist/core/index.js +3 -7
  27. package/dist/extra/index.cjs +17 -54
  28. package/dist/extra/index.cjs.map +1 -1
  29. package/dist/extra/index.d.cts +4 -4
  30. package/dist/extra/index.d.ts +4 -4
  31. package/dist/extra/index.js +3 -9
  32. package/dist/graph/index.cjs +329 -174
  33. package/dist/graph/index.cjs.map +1 -1
  34. package/dist/graph/index.d.cts +3 -3
  35. package/dist/graph/index.d.ts +3 -3
  36. package/dist/graph/index.js +10 -6
  37. package/dist/{graph-fCsaaVIa.d.cts → graph-BYFlyNpX.d.cts} +47 -45
  38. package/dist/{graph-Dc-P9BVm.d.ts → graph-gISB9n3n.d.ts} +47 -45
  39. package/dist/{index-N704txAA.d.ts → index-7WnwgjMu.d.ts} +5 -7
  40. package/dist/{index-DWq0P9T6.d.ts → index-B43mC7uY.d.cts} +5 -7
  41. package/dist/{index-BmoUvOGN.d.ts → index-B80mMeuf.d.ts} +2 -4
  42. package/dist/{index-DlGMf_Qe.d.cts → index-BqOWSFhr.d.cts} +2 -2
  43. package/dist/{index-BBVBYPxr.d.cts → index-CEDaJaYE.d.ts} +5 -7
  44. package/dist/{index-DhXznWyH.d.ts → index-CgKPpiu8.d.ts} +2 -2
  45. package/dist/{index-Db27z6Ki.d.cts → index-Ci_vPaVm.d.cts} +90 -7
  46. package/dist/{index-BR19vQME.d.ts → index-DKaB2x0T.d.ts} +90 -7
  47. package/dist/{index-ClaKZFPl.d.cts → index-D_tUMcpz.d.cts} +5 -7
  48. package/dist/{index-YlOH1Gw6.d.cts → index-EmzYk-TG.d.cts} +2 -4
  49. package/dist/index.cjs +503 -282
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.cts +99 -18
  52. package/dist/index.d.ts +99 -18
  53. package/dist/index.js +170 -63
  54. package/dist/index.js.map +1 -1
  55. package/dist/{meta-BV4pj9ML.d.cts → meta-npl5b97j.d.cts} +1 -53
  56. package/dist/{meta-BV4pj9ML.d.ts → meta-npl5b97j.d.ts} +1 -53
  57. package/dist/observable-DFBCBELR.d.cts +36 -0
  58. package/dist/observable-oAGygKvc.d.ts +36 -0
  59. package/dist/patterns/reactive-layout/index.cjs +204 -172
  60. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  61. package/dist/patterns/reactive-layout/index.d.cts +3 -3
  62. package/dist/patterns/reactive-layout/index.d.ts +3 -3
  63. package/dist/patterns/reactive-layout/index.js +4 -4
  64. package/package.json +1 -1
  65. package/dist/chunk-26A4E7J7.js.map +0 -1
  66. package/dist/chunk-3BLRREFM.js.map +0 -1
  67. package/dist/chunk-LKP7IWRV.js.map +0 -1
  68. package/dist/chunk-SHRJH2DN.js +0 -107
  69. package/dist/chunk-SHRJH2DN.js.map +0 -1
  70. package/dist/chunk-VZY2B2LU.js.map +0 -1
  71. package/dist/chunk-YX263TXI.js.map +0 -1
  72. package/dist/observable-Cz-AWhwR.d.cts +0 -42
  73. package/dist/observable-DCqlwGyl.d.ts +0 -42
  74. /package/dist/{chunk-ITDVOCFO.js.map → chunk-J7S54G7I.js.map} +0 -0
  75. /package/dist/{chunk-RZSQ7P2C.js.map → chunk-UVWEKTYC.js.map} +0 -0
@@ -25,9 +25,11 @@ __export(graph_exports, {
25
25
  JsonCodec: () => JsonCodec,
26
26
  createDagCborCodec: () => createDagCborCodec,
27
27
  createDagCborZstdCodec: () => createDagCborZstdCodec,
28
+ graphProfile: () => graphProfile,
28
29
  negotiateCodec: () => negotiateCodec,
29
30
  reachable: () => reachable,
30
- replayWAL: () => replayWAL
31
+ replayWAL: () => replayWAL,
32
+ sizeof: () => sizeof
31
33
  });
32
34
  module.exports = __toCommonJS(graph_exports);
33
35
 
@@ -787,7 +789,6 @@ var NodeImpl = class {
787
789
  this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
788
790
  return;
789
791
  }
790
- this._cached = value;
791
792
  this._downInternal(wasDirty ? [[DATA, value]] : [[DIRTY], [DATA, value]]);
792
793
  }
793
794
  _runFn() {
@@ -1694,7 +1695,7 @@ var RingBuffer = class {
1694
1695
  return result;
1695
1696
  }
1696
1697
  };
1697
- var SPY_ANSI_THEME = {
1698
+ var OBSERVE_ANSI_THEME = {
1698
1699
  data: "\x1B[32m",
1699
1700
  dirty: "\x1B[33m",
1700
1701
  resolved: "\x1B[36m",
@@ -1704,7 +1705,7 @@ var SPY_ANSI_THEME = {
1704
1705
  path: "\x1B[90m",
1705
1706
  reset: "\x1B[0m"
1706
1707
  };
1707
- var SPY_NO_COLOR_THEME = {
1708
+ var OBSERVE_NO_COLOR_THEME = {
1708
1709
  data: "",
1709
1710
  dirty: "",
1710
1711
  resolved: "",
@@ -1724,9 +1725,9 @@ function describeData(value) {
1724
1725
  return "[unserializable]";
1725
1726
  }
1726
1727
  }
1727
- function resolveSpyTheme(theme) {
1728
- if (theme === "none") return SPY_NO_COLOR_THEME;
1729
- if (theme === "ansi" || theme == null) return SPY_ANSI_THEME;
1728
+ function resolveObserveTheme(theme) {
1729
+ if (theme === "none") return OBSERVE_NO_COLOR_THEME;
1730
+ if (theme === "ansi" || theme == null) return OBSERVE_ANSI_THEME;
1730
1731
  return {
1731
1732
  data: theme.data ?? "",
1732
1733
  dirty: theme.dirty ?? "",
@@ -2497,9 +2498,13 @@ var Graph = class _Graph {
2497
2498
  if (actor2 != null && !target.allowsObserve(actor2)) {
2498
2499
  throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
2499
2500
  }
2500
- const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
2501
- if (wantsStructured2 && _Graph.inspectorEnabled) {
2502
- return this._createObserveResult(path, target, resolved);
2501
+ const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full" || resolved.format != null;
2502
+ if (wantsStructured2) {
2503
+ const result = _Graph.inspectorEnabled ? this._createObserveResult(path, target, resolved) : this._createFallbackObserveResult(path, resolved);
2504
+ if (resolved.format != null) {
2505
+ this._attachFormatLogger(result, resolved);
2506
+ }
2507
+ return result;
2503
2508
  }
2504
2509
  return {
2505
2510
  subscribe(sink) {
@@ -2517,9 +2522,13 @@ var Graph = class _Graph {
2517
2522
  }
2518
2523
  const opts = resolveObserveDetail(pathOrOpts);
2519
2524
  const actor = opts.actor;
2520
- const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
2521
- if (wantsStructured && _Graph.inspectorEnabled) {
2522
- return this._createObserveResultForAll(opts);
2525
+ const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full" || opts.format != null;
2526
+ if (wantsStructured) {
2527
+ const result = _Graph.inspectorEnabled ? this._createObserveResultForAll(opts) : this._createFallbackObserveResultForAll(opts);
2528
+ if (opts.format != null) {
2529
+ this._attachFormatLogger(result, opts);
2530
+ }
2531
+ return result;
2523
2532
  }
2524
2533
  return {
2525
2534
  subscribe: (sink) => {
@@ -2563,6 +2572,7 @@ var Graph = class _Graph {
2563
2572
  let lastTriggerDepIndex;
2564
2573
  let lastRunDepValues;
2565
2574
  let detachInspectorHook;
2575
+ let batchSeq = 0;
2566
2576
  if ((causal || derived) && target instanceof NodeImpl) {
2567
2577
  detachInspectorHook = target._setInspectorHook((event) => {
2568
2578
  if (event.kind === "dep_message") {
@@ -2575,15 +2585,16 @@ var Graph = class _Graph {
2575
2585
  type: "derived",
2576
2586
  path,
2577
2587
  dep_values: [...event.depValues],
2578
- ...timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {}
2588
+ ...timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {}
2579
2589
  });
2580
2590
  }
2581
2591
  });
2582
2592
  }
2583
2593
  const unsub = target.subscribe((msgs) => {
2594
+ batchSeq++;
2584
2595
  for (const m of msgs) {
2585
2596
  const t = m[0];
2586
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
2597
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2587
2598
  const withCausal = causal && lastRunDepValues != null ? (() => {
2588
2599
  const triggerDep = lastTriggerDepIndex != null && lastTriggerDepIndex >= 0 && target instanceof NodeImpl ? target._deps[lastTriggerDepIndex] : void 0;
2589
2600
  const tv = triggerDep?.v;
@@ -2652,11 +2663,15 @@ var Graph = class _Graph {
2652
2663
  Object.assign(merged, extra);
2653
2664
  }
2654
2665
  const resolvedTarget = graph.resolve(basePath);
2655
- return graph._createObserveResult(
2666
+ const expanded = graph._createObserveResult(
2656
2667
  basePath,
2657
2668
  resolvedTarget,
2658
2669
  resolveObserveDetail(merged)
2659
2670
  );
2671
+ if (merged.format != null) {
2672
+ graph._attachFormatLogger(expanded, merged);
2673
+ }
2674
+ return expanded;
2660
2675
  }
2661
2676
  };
2662
2677
  }
@@ -2676,11 +2691,13 @@ var Graph = class _Graph {
2676
2691
  this._collectObserveTargets("", targets);
2677
2692
  targets.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
2678
2693
  const picked = actor == null ? targets : targets.filter(([, nd]) => nd.allowsObserve(actor));
2694
+ let batchSeq = 0;
2679
2695
  const unsubs = picked.map(
2680
2696
  ([path, nd]) => nd.subscribe((msgs) => {
2697
+ batchSeq++;
2681
2698
  for (const m of msgs) {
2682
2699
  const t = m[0];
2683
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
2700
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2684
2701
  if (t === DATA) {
2685
2702
  result.values[path] = m[1];
2686
2703
  result.events.push({ type: "data", path, data: m[1], ...base });
@@ -2736,25 +2753,161 @@ var Graph = class _Graph {
2736
2753
  } else {
2737
2754
  Object.assign(merged, extra);
2738
2755
  }
2739
- return graph._createObserveResultForAll(resolveObserveDetail(merged));
2756
+ const expanded = graph._createObserveResultForAll(resolveObserveDetail(merged));
2757
+ if (merged.format != null) {
2758
+ graph._attachFormatLogger(expanded, merged);
2759
+ }
2760
+ return expanded;
2740
2761
  }
2741
2762
  };
2742
2763
  }
2743
2764
  /**
2744
- * Convenience live debugger over {@link Graph.observe}. Logs protocol events as they flow.
2745
- *
2746
- * Supports one-node (`path`) and graph-wide modes, event filtering, and JSON/pretty rendering.
2747
- * Color themes are built in (`ansi` / `none`) to avoid external dependencies.
2748
- *
2749
- * @param options - Spy configuration.
2750
- * @returns Disposable handle plus a structured observation accumulator.
2765
+ * Fallback ObserveResult for single-node when inspector is disabled but `format` is requested.
2766
+ * Subscribes to raw messages and accumulates events with timeline info.
2751
2767
  */
2752
- spy(options = {}) {
2768
+ _createFallbackObserveResult(path, options) {
2769
+ const timeline = options.timeline !== false;
2770
+ const acc = {
2771
+ values: {},
2772
+ dirtyCount: 0,
2773
+ resolvedCount: 0,
2774
+ events: [],
2775
+ completedCleanly: false,
2776
+ errored: false
2777
+ };
2778
+ const target = this.resolve(path);
2779
+ let batchSeq = 0;
2780
+ const unsub = target.subscribe((msgs) => {
2781
+ batchSeq++;
2782
+ for (const m of msgs) {
2783
+ const t = m[0];
2784
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2785
+ if (t === DATA) {
2786
+ acc.values[path] = m[1];
2787
+ acc.events.push({ type: "data", path, data: m[1], ...base });
2788
+ } else if (t === DIRTY) {
2789
+ acc.dirtyCount++;
2790
+ acc.events.push({ type: "dirty", path, ...base });
2791
+ } else if (t === RESOLVED) {
2792
+ acc.resolvedCount++;
2793
+ acc.events.push({ type: "resolved", path, ...base });
2794
+ } else if (t === COMPLETE) {
2795
+ if (!acc.errored) acc.completedCleanly = true;
2796
+ acc.events.push({ type: "complete", path, ...base });
2797
+ } else if (t === ERROR) {
2798
+ acc.errored = true;
2799
+ acc.events.push({ type: "error", path, data: m[1], ...base });
2800
+ }
2801
+ }
2802
+ });
2803
+ return {
2804
+ get values() {
2805
+ return acc.values;
2806
+ },
2807
+ get dirtyCount() {
2808
+ return acc.dirtyCount;
2809
+ },
2810
+ get resolvedCount() {
2811
+ return acc.resolvedCount;
2812
+ },
2813
+ get events() {
2814
+ return acc.events;
2815
+ },
2816
+ get completedCleanly() {
2817
+ return acc.completedCleanly;
2818
+ },
2819
+ get errored() {
2820
+ return acc.errored;
2821
+ },
2822
+ dispose() {
2823
+ unsub();
2824
+ },
2825
+ expand() {
2826
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
2827
+ }
2828
+ };
2829
+ }
2830
+ /**
2831
+ * Fallback ObserveResult for graph-wide when inspector is disabled but `format` is requested.
2832
+ */
2833
+ _createFallbackObserveResultForAll(options) {
2834
+ const timeline = options.timeline !== false;
2835
+ const actor = options.actor;
2836
+ const acc = {
2837
+ values: {},
2838
+ dirtyCount: 0,
2839
+ resolvedCount: 0,
2840
+ events: [],
2841
+ completedCleanly: false,
2842
+ errored: false
2843
+ };
2844
+ const targets = [];
2845
+ this._collectObserveTargets("", targets);
2846
+ targets.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
2847
+ const picked = actor == null ? targets : targets.filter(([, nd]) => nd.allowsObserve(actor));
2848
+ let batchSeq = 0;
2849
+ const unsubs = picked.map(
2850
+ ([path, nd]) => nd.subscribe((msgs) => {
2851
+ batchSeq++;
2852
+ for (const m of msgs) {
2853
+ const t = m[0];
2854
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2855
+ if (t === DATA) {
2856
+ acc.values[path] = m[1];
2857
+ acc.events.push({ type: "data", path, data: m[1], ...base });
2858
+ } else if (t === DIRTY) {
2859
+ acc.dirtyCount++;
2860
+ acc.events.push({ type: "dirty", path, ...base });
2861
+ } else if (t === RESOLVED) {
2862
+ acc.resolvedCount++;
2863
+ acc.events.push({ type: "resolved", path, ...base });
2864
+ } else if (t === COMPLETE) {
2865
+ if (!acc.errored) acc.completedCleanly = true;
2866
+ acc.events.push({ type: "complete", path, ...base });
2867
+ } else if (t === ERROR) {
2868
+ acc.errored = true;
2869
+ acc.events.push({ type: "error", path, data: m[1], ...base });
2870
+ }
2871
+ }
2872
+ })
2873
+ );
2874
+ return {
2875
+ get values() {
2876
+ return acc.values;
2877
+ },
2878
+ get dirtyCount() {
2879
+ return acc.dirtyCount;
2880
+ },
2881
+ get resolvedCount() {
2882
+ return acc.resolvedCount;
2883
+ },
2884
+ get events() {
2885
+ return acc.events;
2886
+ },
2887
+ get completedCleanly() {
2888
+ return acc.completedCleanly;
2889
+ },
2890
+ get errored() {
2891
+ return acc.errored;
2892
+ },
2893
+ dispose() {
2894
+ for (const u of unsubs) u();
2895
+ },
2896
+ expand() {
2897
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
2898
+ }
2899
+ };
2900
+ }
2901
+ /**
2902
+ * Attaches a format logger to an ObserveResult, rendering events as they arrive.
2903
+ * Wraps the result's dispose to flush pending events.
2904
+ */
2905
+ _attachFormatLogger(result, options) {
2906
+ const format = options.format;
2907
+ const logger = options.logger ?? ((line) => console.log(line));
2753
2908
  const include = options.includeTypes ? new Set(options.includeTypes) : null;
2754
2909
  const exclude = options.excludeTypes ? new Set(options.excludeTypes) : null;
2755
- const theme = resolveSpyTheme(options.theme);
2756
- const format = options.format ?? "pretty";
2757
- const logger = options.logger ?? ((line) => console.log(line));
2910
+ const theme = resolveObserveTheme(options.theme);
2758
2911
  const shouldLog = (type) => {
2759
2912
  if (include?.has(type) === false) return false;
2760
2913
  if (exclude?.has(type) === true) return false;
@@ -2779,133 +2932,26 @@ var Graph = class _Graph {
2779
2932
  const batchPart = event.in_batch ? " [batch]" : "";
2780
2933
  return `${pathPart}${color}${event.type.toUpperCase()}${theme.reset}${dataPart}${triggerPart}${batchPart}`;
2781
2934
  };
2782
- if (!_Graph.inspectorEnabled) {
2783
- const timeline = options.timeline ?? true;
2784
- const acc = {
2785
- values: {},
2786
- dirtyCount: 0,
2787
- resolvedCount: 0,
2788
- events: [],
2789
- completedCleanly: false,
2790
- errored: false
2791
- };
2792
- let stop2 = () => {
2793
- };
2794
- const result2 = {
2795
- get values() {
2796
- return acc.values;
2797
- },
2798
- get dirtyCount() {
2799
- return acc.dirtyCount;
2800
- },
2801
- get resolvedCount() {
2802
- return acc.resolvedCount;
2803
- },
2804
- get events() {
2805
- return acc.events;
2806
- },
2807
- get completedCleanly() {
2808
- return acc.completedCleanly;
2809
- },
2810
- get errored() {
2811
- return acc.errored;
2812
- },
2813
- dispose() {
2814
- stop2();
2815
- },
2816
- expand() {
2817
- throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
2818
- }
2819
- };
2820
- const pushEvent = (path, message) => {
2821
- const t = message[0];
2822
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
2823
- let event;
2824
- if (t === DATA) {
2825
- if (path != null) acc.values[path] = message[1];
2826
- event = { type: "data", ...path != null ? { path } : {}, data: message[1], ...base };
2827
- } else if (t === DIRTY) {
2828
- acc.dirtyCount += 1;
2829
- event = { type: "dirty", ...path != null ? { path } : {}, ...base };
2830
- } else if (t === RESOLVED) {
2831
- acc.resolvedCount += 1;
2832
- event = { type: "resolved", ...path != null ? { path } : {}, ...base };
2833
- } else if (t === COMPLETE) {
2834
- if (!acc.errored) acc.completedCleanly = true;
2835
- event = { type: "complete", ...path != null ? { path } : {}, ...base };
2836
- } else if (t === ERROR) {
2837
- acc.errored = true;
2838
- event = {
2839
- type: "error",
2840
- ...path != null ? { path } : {},
2841
- data: message[1],
2842
- ...base
2843
- };
2935
+ let cursor = 0;
2936
+ const flush = () => {
2937
+ const events = result.events;
2938
+ while (cursor < events.length) {
2939
+ const event = events[cursor++];
2940
+ if (shouldLog(event.type)) {
2941
+ logger(renderEvent(event), event);
2844
2942
  }
2845
- if (!event) return;
2846
- acc.events.push(event);
2847
- if (!shouldLog(event.type)) return;
2848
- logger(renderEvent(event), event);
2849
- };
2850
- if (options.path != null) {
2851
- const stream2 = this.observe(options.path, {
2852
- actor: options.actor,
2853
- structured: false
2854
- });
2855
- stop2 = stream2.subscribe((messages) => {
2856
- for (const m of messages) {
2857
- pushEvent(options.path, m);
2858
- }
2859
- });
2860
- } else {
2861
- const stream2 = this.observe({ actor: options.actor, structured: false });
2862
- stop2 = stream2.subscribe((path, messages) => {
2863
- for (const m of messages) {
2864
- pushEvent(path, m);
2865
- }
2866
- });
2867
2943
  }
2868
- return {
2869
- result: result2,
2870
- dispose() {
2871
- result2.dispose();
2872
- }
2873
- };
2874
- }
2875
- const structuredObserveOptions = {
2876
- actor: options.actor,
2877
- structured: true,
2878
- ...options.timeline !== false ? { timeline: true } : {},
2879
- ...options.causal ? { causal: true } : {},
2880
- ...options.derived ? { derived: true } : {}
2881
2944
  };
2882
- const result = options.path != null ? this.observe(options.path, structuredObserveOptions) : this.observe(structuredObserveOptions);
2883
- let cursor = 0;
2884
- const flushNewEvents = () => {
2885
- const nextEvents = result.events.slice(cursor);
2886
- cursor = result.events.length;
2887
- for (const event of nextEvents) {
2888
- if (!shouldLog(event.type)) continue;
2889
- logger(renderEvent(event), event);
2890
- }
2945
+ const origPush = result.events.push;
2946
+ result.events.push = function(...items) {
2947
+ const ret = origPush.apply(this, items);
2948
+ flush();
2949
+ return ret;
2891
2950
  };
2892
- const stream = options.path != null ? this.observe(options.path, { actor: options.actor, structured: false }) : this.observe({ actor: options.actor, structured: false });
2893
- const stop = options.path != null ? stream.subscribe((messages) => {
2894
- if (messages.length > 0) {
2895
- flushNewEvents();
2896
- }
2897
- }) : stream.subscribe((_path, messages) => {
2898
- if (messages.length > 0) {
2899
- flushNewEvents();
2900
- }
2901
- });
2902
- return {
2903
- result,
2904
- dispose() {
2905
- stop();
2906
- flushNewEvents();
2907
- result.dispose();
2908
- }
2951
+ const origDispose = result.dispose.bind(result);
2952
+ result.dispose = () => {
2953
+ origDispose();
2954
+ flush();
2909
2955
  };
2910
2956
  }
2911
2957
  /**
@@ -3300,33 +3346,21 @@ var Graph = class _Graph {
3300
3346
  // ——————————————————————————————————————————————————————————————
3301
3347
  /**
3302
3348
  * When `false`, structured observation options (`causal`, `timeline`),
3303
- * `annotate()`, and `traceLog()` are no-ops. Raw `observe()` always works.
3349
+ * and `trace()` writes are no-ops. Raw `observe()` always works.
3304
3350
  *
3305
3351
  * Default: `true` outside production (`process.env.NODE_ENV !== "production"`).
3306
3352
  */
3307
3353
  static inspectorEnabled = !(typeof process !== "undefined" && process.env?.NODE_ENV === "production");
3308
3354
  _annotations = /* @__PURE__ */ new Map();
3309
3355
  _traceRing = new RingBuffer(1e3);
3310
- /**
3311
- * Attaches a reasoning annotation to a node — captures *why* an AI agent set a value.
3312
- *
3313
- * No-op when {@link Graph.inspectorEnabled} is `false`.
3314
- *
3315
- * @param path - Qualified node path.
3316
- * @param reason - Free-text note stored in the trace ring buffer.
3317
- */
3318
- annotate(path, reason) {
3319
- if (!_Graph.inspectorEnabled) return;
3320
- this.resolve(path);
3321
- this._annotations.set(path, reason);
3322
- this._traceRing.push({ path, reason, timestamp_ns: monotonicNs() });
3323
- }
3324
- /**
3325
- * Returns a chronological log of all reasoning annotations (ring buffer).
3326
- *
3327
- * @returns `[]` when {@link Graph.inspectorEnabled} is `false`.
3328
- */
3329
- traceLog() {
3356
+ trace(path, reason) {
3357
+ if (path != null && reason != null) {
3358
+ if (!_Graph.inspectorEnabled) return;
3359
+ this.resolve(path);
3360
+ this._annotations.set(path, reason);
3361
+ this._traceRing.push({ path, reason, timestamp_ns: monotonicNs() });
3362
+ return;
3363
+ }
3330
3364
  if (!_Graph.inspectorEnabled) return [];
3331
3365
  return this._traceRing.toArray();
3332
3366
  }
@@ -3454,6 +3488,125 @@ function reachable(described, from, direction, options = {}) {
3454
3488
  }
3455
3489
  return [...out].sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
3456
3490
  }
3491
+
3492
+ // src/graph/sizeof.ts
3493
+ var OVERHEAD = {
3494
+ object: 56,
3495
+ array: 64,
3496
+ string: 40,
3497
+ // header; content added separately
3498
+ number: 8,
3499
+ boolean: 4,
3500
+ null: 0,
3501
+ undefined: 0,
3502
+ symbol: 40,
3503
+ bigint: 16,
3504
+ function: 120,
3505
+ map: 72,
3506
+ set: 72,
3507
+ mapEntry: 40,
3508
+ setEntry: 24
3509
+ };
3510
+ function sizeof(value) {
3511
+ const seen = /* @__PURE__ */ new WeakSet();
3512
+ return _sizeof(value, seen);
3513
+ }
3514
+ function _sizeof(value, seen) {
3515
+ if (value == null) return 0;
3516
+ const t = typeof value;
3517
+ switch (t) {
3518
+ case "number":
3519
+ return OVERHEAD.number;
3520
+ case "boolean":
3521
+ return OVERHEAD.boolean;
3522
+ case "string":
3523
+ return OVERHEAD.string + value.length * 2;
3524
+ // UTF-16
3525
+ case "bigint":
3526
+ return OVERHEAD.bigint;
3527
+ case "symbol":
3528
+ return OVERHEAD.symbol;
3529
+ case "function":
3530
+ if (seen.has(value)) return 0;
3531
+ seen.add(value);
3532
+ return OVERHEAD.function;
3533
+ case "undefined":
3534
+ return 0;
3535
+ }
3536
+ const obj = value;
3537
+ if (seen.has(obj)) return 0;
3538
+ seen.add(obj);
3539
+ if (obj instanceof Map) {
3540
+ let size2 = OVERHEAD.map;
3541
+ for (const [k, v] of obj) {
3542
+ size2 += OVERHEAD.mapEntry + _sizeof(k, seen) + _sizeof(v, seen);
3543
+ }
3544
+ return size2;
3545
+ }
3546
+ if (obj instanceof Set) {
3547
+ let size2 = OVERHEAD.set;
3548
+ for (const v of obj) {
3549
+ size2 += OVERHEAD.setEntry + _sizeof(v, seen);
3550
+ }
3551
+ return size2;
3552
+ }
3553
+ if (Array.isArray(obj)) {
3554
+ let size2 = OVERHEAD.array + obj.length * 8;
3555
+ for (const item of obj) {
3556
+ size2 += _sizeof(item, seen);
3557
+ }
3558
+ return size2;
3559
+ }
3560
+ if (obj instanceof ArrayBuffer) return obj.byteLength;
3561
+ if (ArrayBuffer.isView(obj)) return obj.byteLength;
3562
+ let size = OVERHEAD.object;
3563
+ const keys = Object.keys(obj);
3564
+ for (const key of keys) {
3565
+ size += OVERHEAD.string + key.length * 2;
3566
+ size += _sizeof(obj[key], seen);
3567
+ }
3568
+ return size;
3569
+ }
3570
+
3571
+ // src/graph/profile.ts
3572
+ function graphProfile(graph, opts) {
3573
+ const topN = opts?.topN ?? 10;
3574
+ const desc = graph.describe({ detail: "standard" });
3575
+ const targets = [];
3576
+ if (typeof graph._collectObserveTargets === "function") {
3577
+ graph._collectObserveTargets("", targets);
3578
+ }
3579
+ const pathToNode = /* @__PURE__ */ new Map();
3580
+ for (const [p, n] of targets) {
3581
+ pathToNode.set(p, n);
3582
+ }
3583
+ const profiles = [];
3584
+ for (const [path, nodeDesc] of Object.entries(desc.nodes)) {
3585
+ const nd = pathToNode.get(path);
3586
+ const impl = nd instanceof NodeImpl ? nd : null;
3587
+ const valueSizeBytes = impl ? sizeof(impl.get()) : 0;
3588
+ const subscriberCount = impl ? impl._sinkCount : 0;
3589
+ const depCount = nodeDesc.deps?.length ?? 0;
3590
+ profiles.push({
3591
+ path,
3592
+ type: nodeDesc.type,
3593
+ status: nodeDesc.status ?? "unknown",
3594
+ valueSizeBytes,
3595
+ subscriberCount,
3596
+ depCount
3597
+ });
3598
+ }
3599
+ const totalValueSizeBytes = profiles.reduce((sum, p) => sum + p.valueSizeBytes, 0);
3600
+ const hotspots = [...profiles].sort((a, b) => b.valueSizeBytes - a.valueSizeBytes).slice(0, topN);
3601
+ return {
3602
+ nodeCount: profiles.length,
3603
+ edgeCount: desc.edges.length,
3604
+ subgraphCount: desc.subgraphs.length,
3605
+ nodes: profiles,
3606
+ totalValueSizeBytes,
3607
+ hotspots
3608
+ };
3609
+ }
3457
3610
  // Annotate the CommonJS export names for ESM import in node:
3458
3611
  0 && (module.exports = {
3459
3612
  GRAPH_META_SEGMENT,
@@ -3461,8 +3614,10 @@ function reachable(described, from, direction, options = {}) {
3461
3614
  JsonCodec,
3462
3615
  createDagCborCodec,
3463
3616
  createDagCborZstdCodec,
3617
+ graphProfile,
3464
3618
  negotiateCodec,
3465
3619
  reachable,
3466
- replayWAL
3620
+ replayWAL,
3621
+ sizeof
3467
3622
  });
3468
3623
  //# sourceMappingURL=index.cjs.map