@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
@@ -996,7 +996,6 @@ var NodeImpl = class {
996
996
  this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
997
997
  return;
998
998
  }
999
- this._cached = value;
1000
999
  this._downInternal(wasDirty ? [[DATA, value]] : [[DIRTY], [DATA, value]]);
1001
1000
  }
1002
1001
  _runFn() {
@@ -1906,7 +1905,7 @@ var RingBuffer = class {
1906
1905
  return result;
1907
1906
  }
1908
1907
  };
1909
- var SPY_ANSI_THEME = {
1908
+ var OBSERVE_ANSI_THEME = {
1910
1909
  data: "\x1B[32m",
1911
1910
  dirty: "\x1B[33m",
1912
1911
  resolved: "\x1B[36m",
@@ -1916,7 +1915,7 @@ var SPY_ANSI_THEME = {
1916
1915
  path: "\x1B[90m",
1917
1916
  reset: "\x1B[0m"
1918
1917
  };
1919
- var SPY_NO_COLOR_THEME = {
1918
+ var OBSERVE_NO_COLOR_THEME = {
1920
1919
  data: "",
1921
1920
  dirty: "",
1922
1921
  resolved: "",
@@ -1936,9 +1935,9 @@ function describeData(value) {
1936
1935
  return "[unserializable]";
1937
1936
  }
1938
1937
  }
1939
- function resolveSpyTheme(theme) {
1940
- if (theme === "none") return SPY_NO_COLOR_THEME;
1941
- if (theme === "ansi" || theme == null) return SPY_ANSI_THEME;
1938
+ function resolveObserveTheme(theme) {
1939
+ if (theme === "none") return OBSERVE_NO_COLOR_THEME;
1940
+ if (theme === "ansi" || theme == null) return OBSERVE_ANSI_THEME;
1942
1941
  return {
1943
1942
  data: theme.data ?? "",
1944
1943
  dirty: theme.dirty ?? "",
@@ -2709,9 +2708,13 @@ var Graph = class _Graph {
2709
2708
  if (actor2 != null && !target.allowsObserve(actor2)) {
2710
2709
  throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
2711
2710
  }
2712
- const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
2713
- if (wantsStructured2 && _Graph.inspectorEnabled) {
2714
- return this._createObserveResult(path, target, resolved);
2711
+ const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full" || resolved.format != null;
2712
+ if (wantsStructured2) {
2713
+ const result = _Graph.inspectorEnabled ? this._createObserveResult(path, target, resolved) : this._createFallbackObserveResult(path, resolved);
2714
+ if (resolved.format != null) {
2715
+ this._attachFormatLogger(result, resolved);
2716
+ }
2717
+ return result;
2715
2718
  }
2716
2719
  return {
2717
2720
  subscribe(sink) {
@@ -2729,9 +2732,13 @@ var Graph = class _Graph {
2729
2732
  }
2730
2733
  const opts = resolveObserveDetail(pathOrOpts);
2731
2734
  const actor = opts.actor;
2732
- const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
2733
- if (wantsStructured && _Graph.inspectorEnabled) {
2734
- return this._createObserveResultForAll(opts);
2735
+ const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full" || opts.format != null;
2736
+ if (wantsStructured) {
2737
+ const result = _Graph.inspectorEnabled ? this._createObserveResultForAll(opts) : this._createFallbackObserveResultForAll(opts);
2738
+ if (opts.format != null) {
2739
+ this._attachFormatLogger(result, opts);
2740
+ }
2741
+ return result;
2735
2742
  }
2736
2743
  return {
2737
2744
  subscribe: (sink) => {
@@ -2775,6 +2782,7 @@ var Graph = class _Graph {
2775
2782
  let lastTriggerDepIndex;
2776
2783
  let lastRunDepValues;
2777
2784
  let detachInspectorHook;
2785
+ let batchSeq = 0;
2778
2786
  if ((causal || derived2) && target instanceof NodeImpl) {
2779
2787
  detachInspectorHook = target._setInspectorHook((event) => {
2780
2788
  if (event.kind === "dep_message") {
@@ -2787,15 +2795,16 @@ var Graph = class _Graph {
2787
2795
  type: "derived",
2788
2796
  path,
2789
2797
  dep_values: [...event.depValues],
2790
- ...timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {}
2798
+ ...timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {}
2791
2799
  });
2792
2800
  }
2793
2801
  });
2794
2802
  }
2795
2803
  const unsub = target.subscribe((msgs) => {
2804
+ batchSeq++;
2796
2805
  for (const m of msgs) {
2797
2806
  const t = m[0];
2798
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
2807
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2799
2808
  const withCausal = causal && lastRunDepValues != null ? (() => {
2800
2809
  const triggerDep = lastTriggerDepIndex != null && lastTriggerDepIndex >= 0 && target instanceof NodeImpl ? target._deps[lastTriggerDepIndex] : void 0;
2801
2810
  const tv = triggerDep?.v;
@@ -2864,11 +2873,15 @@ var Graph = class _Graph {
2864
2873
  Object.assign(merged, extra);
2865
2874
  }
2866
2875
  const resolvedTarget = graph.resolve(basePath);
2867
- return graph._createObserveResult(
2876
+ const expanded = graph._createObserveResult(
2868
2877
  basePath,
2869
2878
  resolvedTarget,
2870
2879
  resolveObserveDetail(merged)
2871
2880
  );
2881
+ if (merged.format != null) {
2882
+ graph._attachFormatLogger(expanded, merged);
2883
+ }
2884
+ return expanded;
2872
2885
  }
2873
2886
  };
2874
2887
  }
@@ -2888,11 +2901,13 @@ var Graph = class _Graph {
2888
2901
  this._collectObserveTargets("", targets);
2889
2902
  targets.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
2890
2903
  const picked = actor == null ? targets : targets.filter(([, nd]) => nd.allowsObserve(actor));
2904
+ let batchSeq = 0;
2891
2905
  const unsubs = picked.map(
2892
2906
  ([path, nd]) => nd.subscribe((msgs) => {
2907
+ batchSeq++;
2893
2908
  for (const m of msgs) {
2894
2909
  const t = m[0];
2895
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
2910
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2896
2911
  if (t === DATA) {
2897
2912
  result.values[path] = m[1];
2898
2913
  result.events.push({ type: "data", path, data: m[1], ...base });
@@ -2948,25 +2963,161 @@ var Graph = class _Graph {
2948
2963
  } else {
2949
2964
  Object.assign(merged, extra);
2950
2965
  }
2951
- return graph._createObserveResultForAll(resolveObserveDetail(merged));
2966
+ const expanded = graph._createObserveResultForAll(resolveObserveDetail(merged));
2967
+ if (merged.format != null) {
2968
+ graph._attachFormatLogger(expanded, merged);
2969
+ }
2970
+ return expanded;
2952
2971
  }
2953
2972
  };
2954
2973
  }
2955
2974
  /**
2956
- * Convenience live debugger over {@link Graph.observe}. Logs protocol events as they flow.
2957
- *
2958
- * Supports one-node (`path`) and graph-wide modes, event filtering, and JSON/pretty rendering.
2959
- * Color themes are built in (`ansi` / `none`) to avoid external dependencies.
2960
- *
2961
- * @param options - Spy configuration.
2962
- * @returns Disposable handle plus a structured observation accumulator.
2975
+ * Fallback ObserveResult for single-node when inspector is disabled but `format` is requested.
2976
+ * Subscribes to raw messages and accumulates events with timeline info.
2977
+ */
2978
+ _createFallbackObserveResult(path, options) {
2979
+ const timeline = options.timeline !== false;
2980
+ const acc = {
2981
+ values: {},
2982
+ dirtyCount: 0,
2983
+ resolvedCount: 0,
2984
+ events: [],
2985
+ completedCleanly: false,
2986
+ errored: false
2987
+ };
2988
+ const target = this.resolve(path);
2989
+ let batchSeq = 0;
2990
+ const unsub = target.subscribe((msgs) => {
2991
+ batchSeq++;
2992
+ for (const m of msgs) {
2993
+ const t = m[0];
2994
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
2995
+ if (t === DATA) {
2996
+ acc.values[path] = m[1];
2997
+ acc.events.push({ type: "data", path, data: m[1], ...base });
2998
+ } else if (t === DIRTY) {
2999
+ acc.dirtyCount++;
3000
+ acc.events.push({ type: "dirty", path, ...base });
3001
+ } else if (t === RESOLVED) {
3002
+ acc.resolvedCount++;
3003
+ acc.events.push({ type: "resolved", path, ...base });
3004
+ } else if (t === COMPLETE) {
3005
+ if (!acc.errored) acc.completedCleanly = true;
3006
+ acc.events.push({ type: "complete", path, ...base });
3007
+ } else if (t === ERROR) {
3008
+ acc.errored = true;
3009
+ acc.events.push({ type: "error", path, data: m[1], ...base });
3010
+ }
3011
+ }
3012
+ });
3013
+ return {
3014
+ get values() {
3015
+ return acc.values;
3016
+ },
3017
+ get dirtyCount() {
3018
+ return acc.dirtyCount;
3019
+ },
3020
+ get resolvedCount() {
3021
+ return acc.resolvedCount;
3022
+ },
3023
+ get events() {
3024
+ return acc.events;
3025
+ },
3026
+ get completedCleanly() {
3027
+ return acc.completedCleanly;
3028
+ },
3029
+ get errored() {
3030
+ return acc.errored;
3031
+ },
3032
+ dispose() {
3033
+ unsub();
3034
+ },
3035
+ expand() {
3036
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
3037
+ }
3038
+ };
3039
+ }
3040
+ /**
3041
+ * Fallback ObserveResult for graph-wide when inspector is disabled but `format` is requested.
3042
+ */
3043
+ _createFallbackObserveResultForAll(options) {
3044
+ const timeline = options.timeline !== false;
3045
+ const actor = options.actor;
3046
+ const acc = {
3047
+ values: {},
3048
+ dirtyCount: 0,
3049
+ resolvedCount: 0,
3050
+ events: [],
3051
+ completedCleanly: false,
3052
+ errored: false
3053
+ };
3054
+ const targets = [];
3055
+ this._collectObserveTargets("", targets);
3056
+ targets.sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
3057
+ const picked = actor == null ? targets : targets.filter(([, nd]) => nd.allowsObserve(actor));
3058
+ let batchSeq = 0;
3059
+ const unsubs = picked.map(
3060
+ ([path, nd]) => nd.subscribe((msgs) => {
3061
+ batchSeq++;
3062
+ for (const m of msgs) {
3063
+ const t = m[0];
3064
+ const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching(), batch_id: batchSeq } : {};
3065
+ if (t === DATA) {
3066
+ acc.values[path] = m[1];
3067
+ acc.events.push({ type: "data", path, data: m[1], ...base });
3068
+ } else if (t === DIRTY) {
3069
+ acc.dirtyCount++;
3070
+ acc.events.push({ type: "dirty", path, ...base });
3071
+ } else if (t === RESOLVED) {
3072
+ acc.resolvedCount++;
3073
+ acc.events.push({ type: "resolved", path, ...base });
3074
+ } else if (t === COMPLETE) {
3075
+ if (!acc.errored) acc.completedCleanly = true;
3076
+ acc.events.push({ type: "complete", path, ...base });
3077
+ } else if (t === ERROR) {
3078
+ acc.errored = true;
3079
+ acc.events.push({ type: "error", path, data: m[1], ...base });
3080
+ }
3081
+ }
3082
+ })
3083
+ );
3084
+ return {
3085
+ get values() {
3086
+ return acc.values;
3087
+ },
3088
+ get dirtyCount() {
3089
+ return acc.dirtyCount;
3090
+ },
3091
+ get resolvedCount() {
3092
+ return acc.resolvedCount;
3093
+ },
3094
+ get events() {
3095
+ return acc.events;
3096
+ },
3097
+ get completedCleanly() {
3098
+ return acc.completedCleanly;
3099
+ },
3100
+ get errored() {
3101
+ return acc.errored;
3102
+ },
3103
+ dispose() {
3104
+ for (const u of unsubs) u();
3105
+ },
3106
+ expand() {
3107
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
3108
+ }
3109
+ };
3110
+ }
3111
+ /**
3112
+ * Attaches a format logger to an ObserveResult, rendering events as they arrive.
3113
+ * Wraps the result's dispose to flush pending events.
2963
3114
  */
2964
- spy(options = {}) {
3115
+ _attachFormatLogger(result, options) {
3116
+ const format = options.format;
3117
+ const logger = options.logger ?? ((line) => console.log(line));
2965
3118
  const include = options.includeTypes ? new Set(options.includeTypes) : null;
2966
3119
  const exclude = options.excludeTypes ? new Set(options.excludeTypes) : null;
2967
- const theme = resolveSpyTheme(options.theme);
2968
- const format = options.format ?? "pretty";
2969
- const logger = options.logger ?? ((line) => console.log(line));
3120
+ const theme = resolveObserveTheme(options.theme);
2970
3121
  const shouldLog = (type) => {
2971
3122
  if (include?.has(type) === false) return false;
2972
3123
  if (exclude?.has(type) === true) return false;
@@ -2991,133 +3142,26 @@ var Graph = class _Graph {
2991
3142
  const batchPart = event.in_batch ? " [batch]" : "";
2992
3143
  return `${pathPart}${color}${event.type.toUpperCase()}${theme.reset}${dataPart}${triggerPart}${batchPart}`;
2993
3144
  };
2994
- if (!_Graph.inspectorEnabled) {
2995
- const timeline = options.timeline ?? true;
2996
- const acc = {
2997
- values: {},
2998
- dirtyCount: 0,
2999
- resolvedCount: 0,
3000
- events: [],
3001
- completedCleanly: false,
3002
- errored: false
3003
- };
3004
- let stop2 = () => {
3005
- };
3006
- const result2 = {
3007
- get values() {
3008
- return acc.values;
3009
- },
3010
- get dirtyCount() {
3011
- return acc.dirtyCount;
3012
- },
3013
- get resolvedCount() {
3014
- return acc.resolvedCount;
3015
- },
3016
- get events() {
3017
- return acc.events;
3018
- },
3019
- get completedCleanly() {
3020
- return acc.completedCleanly;
3021
- },
3022
- get errored() {
3023
- return acc.errored;
3024
- },
3025
- dispose() {
3026
- stop2();
3027
- },
3028
- expand() {
3029
- throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
3030
- }
3031
- };
3032
- const pushEvent = (path, message) => {
3033
- const t = message[0];
3034
- const base = timeline ? { timestamp_ns: monotonicNs(), in_batch: isBatching() } : {};
3035
- let event;
3036
- if (t === DATA) {
3037
- if (path != null) acc.values[path] = message[1];
3038
- event = { type: "data", ...path != null ? { path } : {}, data: message[1], ...base };
3039
- } else if (t === DIRTY) {
3040
- acc.dirtyCount += 1;
3041
- event = { type: "dirty", ...path != null ? { path } : {}, ...base };
3042
- } else if (t === RESOLVED) {
3043
- acc.resolvedCount += 1;
3044
- event = { type: "resolved", ...path != null ? { path } : {}, ...base };
3045
- } else if (t === COMPLETE) {
3046
- if (!acc.errored) acc.completedCleanly = true;
3047
- event = { type: "complete", ...path != null ? { path } : {}, ...base };
3048
- } else if (t === ERROR) {
3049
- acc.errored = true;
3050
- event = {
3051
- type: "error",
3052
- ...path != null ? { path } : {},
3053
- data: message[1],
3054
- ...base
3055
- };
3145
+ let cursor = 0;
3146
+ const flush = () => {
3147
+ const events = result.events;
3148
+ while (cursor < events.length) {
3149
+ const event = events[cursor++];
3150
+ if (shouldLog(event.type)) {
3151
+ logger(renderEvent(event), event);
3056
3152
  }
3057
- if (!event) return;
3058
- acc.events.push(event);
3059
- if (!shouldLog(event.type)) return;
3060
- logger(renderEvent(event), event);
3061
- };
3062
- if (options.path != null) {
3063
- const stream2 = this.observe(options.path, {
3064
- actor: options.actor,
3065
- structured: false
3066
- });
3067
- stop2 = stream2.subscribe((messages) => {
3068
- for (const m of messages) {
3069
- pushEvent(options.path, m);
3070
- }
3071
- });
3072
- } else {
3073
- const stream2 = this.observe({ actor: options.actor, structured: false });
3074
- stop2 = stream2.subscribe((path, messages) => {
3075
- for (const m of messages) {
3076
- pushEvent(path, m);
3077
- }
3078
- });
3079
3153
  }
3080
- return {
3081
- result: result2,
3082
- dispose() {
3083
- result2.dispose();
3084
- }
3085
- };
3086
- }
3087
- const structuredObserveOptions = {
3088
- actor: options.actor,
3089
- structured: true,
3090
- ...options.timeline !== false ? { timeline: true } : {},
3091
- ...options.causal ? { causal: true } : {},
3092
- ...options.derived ? { derived: true } : {}
3093
3154
  };
3094
- const result = options.path != null ? this.observe(options.path, structuredObserveOptions) : this.observe(structuredObserveOptions);
3095
- let cursor = 0;
3096
- const flushNewEvents = () => {
3097
- const nextEvents = result.events.slice(cursor);
3098
- cursor = result.events.length;
3099
- for (const event of nextEvents) {
3100
- if (!shouldLog(event.type)) continue;
3101
- logger(renderEvent(event), event);
3102
- }
3155
+ const origPush = result.events.push;
3156
+ result.events.push = function(...items) {
3157
+ const ret = origPush.apply(this, items);
3158
+ flush();
3159
+ return ret;
3103
3160
  };
3104
- const stream = options.path != null ? this.observe(options.path, { actor: options.actor, structured: false }) : this.observe({ actor: options.actor, structured: false });
3105
- const stop = options.path != null ? stream.subscribe((messages) => {
3106
- if (messages.length > 0) {
3107
- flushNewEvents();
3108
- }
3109
- }) : stream.subscribe((_path, messages) => {
3110
- if (messages.length > 0) {
3111
- flushNewEvents();
3112
- }
3113
- });
3114
- return {
3115
- result,
3116
- dispose() {
3117
- stop();
3118
- flushNewEvents();
3119
- result.dispose();
3120
- }
3161
+ const origDispose = result.dispose.bind(result);
3162
+ result.dispose = () => {
3163
+ origDispose();
3164
+ flush();
3121
3165
  };
3122
3166
  }
3123
3167
  /**
@@ -3512,33 +3556,21 @@ var Graph = class _Graph {
3512
3556
  // ——————————————————————————————————————————————————————————————
3513
3557
  /**
3514
3558
  * When `false`, structured observation options (`causal`, `timeline`),
3515
- * `annotate()`, and `traceLog()` are no-ops. Raw `observe()` always works.
3559
+ * and `trace()` writes are no-ops. Raw `observe()` always works.
3516
3560
  *
3517
3561
  * Default: `true` outside production (`process.env.NODE_ENV !== "production"`).
3518
3562
  */
3519
3563
  static inspectorEnabled = !(typeof process !== "undefined" && process.env?.NODE_ENV === "production");
3520
3564
  _annotations = /* @__PURE__ */ new Map();
3521
3565
  _traceRing = new RingBuffer(1e3);
3522
- /**
3523
- * Attaches a reasoning annotation to a node — captures *why* an AI agent set a value.
3524
- *
3525
- * No-op when {@link Graph.inspectorEnabled} is `false`.
3526
- *
3527
- * @param path - Qualified node path.
3528
- * @param reason - Free-text note stored in the trace ring buffer.
3529
- */
3530
- annotate(path, reason) {
3531
- if (!_Graph.inspectorEnabled) return;
3532
- this.resolve(path);
3533
- this._annotations.set(path, reason);
3534
- this._traceRing.push({ path, reason, timestamp_ns: monotonicNs() });
3535
- }
3536
- /**
3537
- * Returns a chronological log of all reasoning annotations (ring buffer).
3538
- *
3539
- * @returns `[]` when {@link Graph.inspectorEnabled} is `false`.
3540
- */
3541
- traceLog() {
3566
+ trace(path, reason) {
3567
+ if (path != null && reason != null) {
3568
+ if (!_Graph.inspectorEnabled) return;
3569
+ this.resolve(path);
3570
+ this._annotations.set(path, reason);
3571
+ this._traceRing.push({ path, reason, timestamp_ns: monotonicNs() });
3572
+ return;
3573
+ }
3542
3574
  if (!_Graph.inspectorEnabled) return [];
3543
3575
  return this._traceRing.toArray();
3544
3576
  }