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