@graphrefly/graphrefly 0.24.0 → 0.26.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 (184) hide show
  1. package/README.md +8 -0
  2. package/dist/{chunk-QOWVNWOC.js → chunk-3ZWCKRHX.js} +27 -25
  3. package/dist/{chunk-QOWVNWOC.js.map → chunk-3ZWCKRHX.js.map} +1 -1
  4. package/dist/chunk-6LDQFTYS.js +102 -0
  5. package/dist/chunk-6LDQFTYS.js.map +1 -0
  6. package/dist/{chunk-5WGT55R4.js → chunk-AMCG74RZ.js} +195 -24
  7. package/dist/chunk-AMCG74RZ.js.map +1 -0
  8. package/dist/{chunk-AOCBDH4T.js → chunk-BVZYTZ5H.js} +76 -103
  9. package/dist/chunk-BVZYTZ5H.js.map +1 -0
  10. package/dist/chunk-FQMKGR6L.js +330 -0
  11. package/dist/chunk-FQMKGR6L.js.map +1 -0
  12. package/dist/chunk-HXZEYDUR.js +94 -0
  13. package/dist/chunk-HXZEYDUR.js.map +1 -0
  14. package/dist/{chunk-IPLKX3L2.js → chunk-IZYUSJC7.js} +16 -14
  15. package/dist/{chunk-IPLKX3L2.js.map → chunk-IZYUSJC7.js.map} +1 -1
  16. package/dist/chunk-J22W6HV3.js +107 -0
  17. package/dist/chunk-J22W6HV3.js.map +1 -0
  18. package/dist/{chunk-HWPIFSW2.js → chunk-JSCT3CR4.js} +6 -4
  19. package/dist/{chunk-HWPIFSW2.js.map → chunk-JSCT3CR4.js.map} +1 -1
  20. package/dist/chunk-JYXEWPH4.js +62 -0
  21. package/dist/chunk-JYXEWPH4.js.map +1 -0
  22. package/dist/chunk-LCE3GF5P.js +866 -0
  23. package/dist/chunk-LCE3GF5P.js.map +1 -0
  24. package/dist/chunk-MJ2NKQQL.js +119 -0
  25. package/dist/chunk-MJ2NKQQL.js.map +1 -0
  26. package/dist/chunk-N6UR7YVY.js +198 -0
  27. package/dist/chunk-N6UR7YVY.js.map +1 -0
  28. package/dist/chunk-OHISZPOJ.js +97 -0
  29. package/dist/chunk-OHISZPOJ.js.map +1 -0
  30. package/dist/{chunk-5DJTTKX3.js → chunk-PHOUUNK7.js} +74 -111
  31. package/dist/chunk-PHOUUNK7.js.map +1 -0
  32. package/dist/{chunk-PY4XCDLR.js → chunk-RB6QPHJ7.js} +8 -6
  33. package/dist/{chunk-PY4XCDLR.js.map → chunk-RB6QPHJ7.js.map} +1 -1
  34. package/dist/chunk-SN4YWWYO.js +171 -0
  35. package/dist/chunk-SN4YWWYO.js.map +1 -0
  36. package/dist/chunk-SX52TAR4.js +110 -0
  37. package/dist/chunk-SX52TAR4.js.map +1 -0
  38. package/dist/{chunk-XOFWRC73.js → chunk-THTWHNU4.js} +319 -24
  39. package/dist/chunk-THTWHNU4.js.map +1 -0
  40. package/dist/{chunk-H4RVA4VE.js → chunk-VYPWMZ6H.js} +2 -2
  41. package/dist/chunk-XGPU467M.js +136 -0
  42. package/dist/chunk-XGPU467M.js.map +1 -0
  43. package/dist/{chunk-TDEXAMGO.js → chunk-ZQMEI34O.js} +206 -574
  44. package/dist/chunk-ZQMEI34O.js.map +1 -0
  45. package/dist/compat/index.cjs +7656 -0
  46. package/dist/compat/index.cjs.map +1 -0
  47. package/dist/compat/index.d.cts +18 -0
  48. package/dist/compat/index.d.ts +18 -0
  49. package/dist/compat/index.js +49 -0
  50. package/dist/compat/index.js.map +1 -0
  51. package/dist/compat/jotai/index.cjs +2048 -0
  52. package/dist/compat/jotai/index.cjs.map +1 -0
  53. package/dist/compat/jotai/index.d.cts +2 -0
  54. package/dist/compat/jotai/index.d.ts +2 -0
  55. package/dist/compat/jotai/index.js +9 -0
  56. package/dist/compat/jotai/index.js.map +1 -0
  57. package/dist/compat/nanostores/index.cjs +2175 -0
  58. package/dist/compat/nanostores/index.cjs.map +1 -0
  59. package/dist/compat/nanostores/index.d.cts +2 -0
  60. package/dist/compat/nanostores/index.d.ts +2 -0
  61. package/dist/compat/nanostores/index.js +23 -0
  62. package/dist/compat/nanostores/index.js.map +1 -0
  63. package/dist/compat/nestjs/index.cjs +350 -16
  64. package/dist/compat/nestjs/index.cjs.map +1 -1
  65. package/dist/compat/nestjs/index.d.cts +6 -6
  66. package/dist/compat/nestjs/index.d.ts +6 -6
  67. package/dist/compat/nestjs/index.js +10 -9
  68. package/dist/compat/react/index.cjs +141 -0
  69. package/dist/compat/react/index.cjs.map +1 -0
  70. package/dist/compat/react/index.d.cts +2 -0
  71. package/dist/compat/react/index.d.ts +2 -0
  72. package/dist/compat/react/index.js +12 -0
  73. package/dist/compat/react/index.js.map +1 -0
  74. package/dist/compat/solid/index.cjs +128 -0
  75. package/dist/compat/solid/index.cjs.map +1 -0
  76. package/dist/compat/solid/index.d.cts +2 -0
  77. package/dist/compat/solid/index.d.ts +2 -0
  78. package/dist/compat/solid/index.js +12 -0
  79. package/dist/compat/solid/index.js.map +1 -0
  80. package/dist/compat/svelte/index.cjs +131 -0
  81. package/dist/compat/svelte/index.cjs.map +1 -0
  82. package/dist/compat/svelte/index.d.cts +2 -0
  83. package/dist/compat/svelte/index.d.ts +2 -0
  84. package/dist/compat/svelte/index.js +12 -0
  85. package/dist/compat/svelte/index.js.map +1 -0
  86. package/dist/compat/vue/index.cjs +146 -0
  87. package/dist/compat/vue/index.cjs.map +1 -0
  88. package/dist/compat/vue/index.d.cts +3 -0
  89. package/dist/compat/vue/index.d.ts +3 -0
  90. package/dist/compat/vue/index.js +12 -0
  91. package/dist/compat/vue/index.js.map +1 -0
  92. package/dist/compat/zustand/index.cjs +4931 -0
  93. package/dist/compat/zustand/index.cjs.map +1 -0
  94. package/dist/compat/zustand/index.d.cts +5 -0
  95. package/dist/compat/zustand/index.d.ts +5 -0
  96. package/dist/compat/zustand/index.js +12 -0
  97. package/dist/compat/zustand/index.js.map +1 -0
  98. package/dist/core/index.cjs +53 -4
  99. package/dist/core/index.cjs.map +1 -1
  100. package/dist/core/index.d.cts +3 -3
  101. package/dist/core/index.d.ts +3 -3
  102. package/dist/core/index.js +26 -24
  103. package/dist/demo-shell-26p5fVxn.d.cts +102 -0
  104. package/dist/demo-shell-DEp-nMTl.d.ts +102 -0
  105. package/dist/extra/index.cjs +290 -110
  106. package/dist/extra/index.cjs.map +1 -1
  107. package/dist/extra/index.d.cts +5 -4
  108. package/dist/extra/index.d.ts +5 -4
  109. package/dist/extra/index.js +8 -5
  110. package/dist/extra/sources.cjs +2486 -0
  111. package/dist/extra/sources.cjs.map +1 -0
  112. package/dist/extra/sources.d.cts +465 -0
  113. package/dist/extra/sources.d.ts +465 -0
  114. package/dist/extra/sources.js +57 -0
  115. package/dist/extra/sources.js.map +1 -0
  116. package/dist/graph/index.cjs +408 -14
  117. package/dist/graph/index.cjs.map +1 -1
  118. package/dist/graph/index.d.cts +5 -5
  119. package/dist/graph/index.d.ts +5 -5
  120. package/dist/graph/index.js +13 -5
  121. package/dist/{graph-D-3JIQme.d.cts → graph-6tZ5jEzr.d.cts} +195 -4
  122. package/dist/{graph-B6NFqv3z.d.ts → graph-DQ69XU0g.d.ts} +195 -4
  123. package/dist/index-B4MP_8V_.d.cts +37 -0
  124. package/dist/index-BEfE8H_G.d.cts +121 -0
  125. package/dist/{index-D7XgsUt7.d.ts → index-BW1z3BN9.d.ts} +169 -127
  126. package/dist/index-BYOHF0zP.d.ts +34 -0
  127. package/dist/index-B_IP40nB.d.cts +36 -0
  128. package/dist/index-Bd_fwmLf.d.cts +45 -0
  129. package/dist/{index-BysCTzJz.d.ts → index-BeIdBfcb.d.cts} +121 -547
  130. package/dist/index-BjI6ty9z.d.ts +121 -0
  131. package/dist/index-Bxb5ZYc9.d.cts +34 -0
  132. package/dist/{index-BJB7t9gg.d.cts → index-C0ZXMaXO.d.cts} +2 -2
  133. package/dist/{index-b5BYtczN.d.cts → index-C8mdwMXc.d.cts} +169 -127
  134. package/dist/index-CDAjUFIv.d.ts +36 -0
  135. package/dist/index-CPgZ5wRl.d.ts +44 -0
  136. package/dist/{index-AMWewNDe.d.cts → index-CUwyr1Kk.d.cts} +33 -4
  137. package/dist/index-CUyrtuOf.d.cts +127 -0
  138. package/dist/{index-C-TXEa7C.d.ts → index-CY2TljO4.d.ts} +2 -2
  139. package/dist/index-CmnuOibw.d.ts +37 -0
  140. package/dist/{index-DiobMNwE.d.ts → index-CuYwdKO-.d.ts} +3 -3
  141. package/dist/index-DFhjO4Gg.d.cts +44 -0
  142. package/dist/{index-1z8vRTCt.d.cts → index-DdD5MVDL.d.ts} +121 -547
  143. package/dist/index-DrISNAOm.d.ts +45 -0
  144. package/dist/index-QBpffFW-.d.cts +86 -0
  145. package/dist/{index-J7Kc0oIQ.d.cts → index-_oMEWlDq.d.cts} +3 -3
  146. package/dist/{index-CYkjxu3s.d.ts → index-eJ6T_qGM.d.ts} +33 -4
  147. package/dist/index-qldRdbQw.d.ts +86 -0
  148. package/dist/index-xdGjv0nO.d.ts +127 -0
  149. package/dist/index.cjs +2334 -195
  150. package/dist/index.cjs.map +1 -1
  151. package/dist/index.d.cts +1007 -648
  152. package/dist/index.d.ts +1007 -648
  153. package/dist/index.js +1204 -1172
  154. package/dist/index.js.map +1 -1
  155. package/dist/{meta-CnkLA_43.d.ts → meta-BGqSZ7mt.d.ts} +1 -1
  156. package/dist/{meta-DWbkoq1s.d.cts → meta-C0-8XW6Q.d.cts} +1 -1
  157. package/dist/{node-B-f-Lu-k.d.cts → node-C_IBuvX2.d.cts} +26 -1
  158. package/dist/{node-B-f-Lu-k.d.ts → node-C_IBuvX2.d.ts} +26 -1
  159. package/dist/{observable-DBnrwcar.d.cts → observable-Crr1jgzx.d.cts} +1 -1
  160. package/dist/{observable-uP-wy_uK.d.ts → observable-DCk45RH5.d.ts} +1 -1
  161. package/dist/patterns/demo-shell.cjs +5604 -0
  162. package/dist/patterns/demo-shell.cjs.map +1 -0
  163. package/dist/patterns/demo-shell.d.cts +6 -0
  164. package/dist/patterns/demo-shell.d.ts +6 -0
  165. package/dist/patterns/demo-shell.js +15 -0
  166. package/dist/patterns/demo-shell.js.map +1 -0
  167. package/dist/patterns/reactive-layout/index.cjs +843 -29
  168. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  169. package/dist/patterns/reactive-layout/index.d.cts +6 -5
  170. package/dist/patterns/reactive-layout/index.d.ts +6 -5
  171. package/dist/patterns/reactive-layout/index.js +25 -10
  172. package/dist/reactive-layout-BaOQefHu.d.cts +183 -0
  173. package/dist/reactive-layout-D9gejYXE.d.ts +183 -0
  174. package/dist/{storage-BuTdpCI1.d.cts → storage-BMycWEh2.d.ts} +9 -1
  175. package/dist/{storage-F2X1U1x0.d.ts → storage-DiqWHzVI.d.cts} +9 -1
  176. package/package.json +32 -2
  177. package/dist/chunk-5DJTTKX3.js.map +0 -1
  178. package/dist/chunk-5WGT55R4.js.map +0 -1
  179. package/dist/chunk-AOCBDH4T.js.map +0 -1
  180. package/dist/chunk-MW4VAKAO.js +0 -47
  181. package/dist/chunk-MW4VAKAO.js.map +0 -1
  182. package/dist/chunk-TDEXAMGO.js.map +0 -1
  183. package/dist/chunk-XOFWRC73.js.map +0 -1
  184. /package/dist/{chunk-H4RVA4VE.js.map → chunk-VYPWMZ6H.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,3 +1,32 @@
1
+ import {
2
+ reactive_layout_exports
3
+ } from "./chunk-ZQMEI34O.js";
4
+ import {
5
+ compat_exports,
6
+ signals_exports
7
+ } from "./chunk-SN4YWWYO.js";
8
+ import {
9
+ nanostores_exports
10
+ } from "./chunk-N6UR7YVY.js";
11
+ import {
12
+ cqrs_exports,
13
+ nestjs_exports
14
+ } from "./chunk-IZYUSJC7.js";
15
+ import {
16
+ react_exports
17
+ } from "./chunk-J22W6HV3.js";
18
+ import {
19
+ solid_exports
20
+ } from "./chunk-HXZEYDUR.js";
21
+ import {
22
+ svelte_exports
23
+ } from "./chunk-OHISZPOJ.js";
24
+ import {
25
+ vue_exports
26
+ } from "./chunk-MJ2NKQQL.js";
27
+ import {
28
+ zustand_exports
29
+ } from "./chunk-JYXEWPH4.js";
1
30
  import {
2
31
  CircuitOpenError,
3
32
  NS_PER_MS,
@@ -48,6 +77,7 @@ import {
48
77
  fromCSV,
49
78
  fromClickHouseWatch,
50
79
  fromDrizzle,
80
+ fromFSWatch,
51
81
  fromGitHook,
52
82
  fromHTTP,
53
83
  fromHTTPPoll,
@@ -148,33 +178,29 @@ import {
148
178
  workerBridge,
149
179
  workerSelf,
150
180
  zip
151
- } from "./chunk-5WGT55R4.js";
152
- import {
153
- cqrs_exports,
154
- nestjs_exports
155
- } from "./chunk-IPLKX3L2.js";
156
- import {
157
- core_exports
158
- } from "./chunk-QOWVNWOC.js";
181
+ } from "./chunk-AMCG74RZ.js";
159
182
  import {
160
183
  NativeLogBackend,
161
184
  createWatermarkController,
162
185
  reactiveLog,
163
186
  toObservable
164
- } from "./chunk-PY4XCDLR.js";
187
+ } from "./chunk-RB6QPHJ7.js";
188
+ import {
189
+ core_exports
190
+ } from "./chunk-3ZWCKRHX.js";
165
191
  import {
166
- graph_exports
167
- } from "./chunk-MW4VAKAO.js";
192
+ graph_exports,
193
+ watchTopologyTree
194
+ } from "./chunk-6LDQFTYS.js";
168
195
  import {
169
- analyzeAndMeasure,
170
- computeLineBreaks,
171
- reactive_layout_exports
172
- } from "./chunk-TDEXAMGO.js";
196
+ demo_shell_exports
197
+ } from "./chunk-FQMKGR6L.js";
198
+ import "./chunk-LCE3GF5P.js";
173
199
  import {
174
200
  domainMeta,
175
201
  trackingKey,
176
202
  tryIncrementBounded
177
- } from "./chunk-HWPIFSW2.js";
203
+ } from "./chunk-JSCT3CR4.js";
178
204
  import {
179
205
  cached,
180
206
  empty,
@@ -186,9 +212,9 @@ import {
186
212
  fromAsyncIter,
187
213
  fromCron,
188
214
  fromEvent,
189
- fromFSWatch,
190
215
  fromIter,
191
216
  fromPromise,
217
+ fromRaf,
192
218
  fromTimer,
193
219
  globToRegExp,
194
220
  keepalive,
@@ -203,53 +229,35 @@ import {
203
229
  shareReplay,
204
230
  throwError,
205
231
  toArray
206
- } from "./chunk-AOCBDH4T.js";
232
+ } from "./chunk-BVZYTZ5H.js";
207
233
  import {
208
234
  GRAPH_META_SEGMENT,
209
235
  Graph,
210
236
  OVERHEAD,
211
237
  SIZEOF_SYMBOL,
238
+ SNAPSHOT_VERSION,
212
239
  diffForWAL,
240
+ explainPath,
213
241
  graphProfile,
214
242
  reachable,
215
243
  sizeof
216
- } from "./chunk-XOFWRC73.js";
217
- import {
218
- describeNode,
219
- resolveDescribeFields
220
- } from "./chunk-H4RVA4VE.js";
244
+ } from "./chunk-THTWHNU4.js";
221
245
  import {
222
246
  ResettableTimer
223
247
  } from "./chunk-7TAQJHQV.js";
224
248
  import {
225
- COMPLETE,
226
- COMPLETE_MSG,
227
- COMPLETE_ONLY_BATCH,
228
- DATA,
249
+ resolveDescribeFields
250
+ } from "./chunk-VYPWMZ6H.js";
251
+ import {
252
+ jotai_exports
253
+ } from "./chunk-XGPU467M.js";
254
+ import {
229
255
  DEFAULT_ACTOR,
230
- DIRTY,
231
- DIRTY_MSG,
232
- DIRTY_ONLY_BATCH,
233
256
  ENVELOPE_VERSION,
234
- ERROR,
235
257
  GraphReFlyConfig,
236
258
  GuardDenied,
237
- INVALIDATE,
238
- INVALIDATE_MSG,
239
- INVALIDATE_ONLY_BATCH,
240
259
  JsonCodec,
241
260
  NodeImpl,
242
- PAUSE,
243
- RESOLVED,
244
- RESOLVED_MSG,
245
- RESOLVED_ONLY_BATCH,
246
- RESUME,
247
- START,
248
- START_MSG,
249
- TEARDOWN,
250
- TEARDOWN_MSG,
251
- TEARDOWN_ONLY_BATCH,
252
- __export,
253
261
  accessHintForGuard,
254
262
  advanceVersion,
255
263
  autoTrackNode,
@@ -280,855 +288,61 @@ import {
280
288
  replayWAL,
281
289
  state,
282
290
  wallClockNs
283
- } from "./chunk-5DJTTKX3.js";
284
-
285
- // src/compat/index.ts
286
- var compat_exports = {};
287
- __export(compat_exports, {
288
- jotai: () => jotai_exports,
289
- nanostores: () => nanostores_exports,
290
- nestjs: () => nestjs_exports,
291
- react: () => react_exports,
292
- signals: () => signals_exports,
293
- solid: () => solid_exports,
294
- svelte: () => svelte_exports,
295
- vue: () => vue_exports,
296
- zustand: () => zustand_exports
297
- });
298
-
299
- // src/compat/jotai/index.ts
300
- var jotai_exports = {};
301
- __export(jotai_exports, {
302
- atom: () => atom
303
- });
304
- function atom(initialOrRead, writeOrOptions, options) {
305
- if (typeof initialOrRead === "function") {
306
- const read = initialOrRead;
307
- if (typeof writeOrOptions === "function") {
308
- return createDerivedAtom(read, writeOrOptions, options);
309
- }
310
- return createDerivedAtom(read, void 0, writeOrOptions);
311
- }
312
- return createPrimitiveAtom(initialOrRead, writeOrOptions);
313
- }
314
- function pull(n) {
315
- let val = n.cache;
316
- let err;
317
- const unsub = n.subscribe((msgs) => {
318
- for (const [t, v] of msgs) {
319
- if (t === DATA) val = v;
320
- if (t === ERROR) err = v;
321
- }
322
- });
323
- unsub();
324
- if (err) throw err;
325
- return val;
326
- }
327
- function createPrimitiveAtom(initial, options) {
328
- const n = state(initial, {
329
- ...options,
330
- resubscribable: true,
331
- resetOnTeardown: true
332
- });
333
- return {
334
- get: () => {
335
- if (n.status === "sentinel") {
336
- return pull(n);
337
- }
338
- return n.cache;
339
- },
340
- // Use `n.emit` (not raw `n.down`) so writes go through the framed
341
- // emit pipeline: bundle() auto-prefixes DIRTY (diamond-safe wave
342
- // coordination) and the equals check folds same-value writes to
343
- // RESOLVED (no spurious subscriber fires).
344
- set: (value) => n.emit(value),
345
- update: (fn) => {
346
- const current = n.status === "sentinel" ? pull(n) : n.cache;
347
- n.emit(fn(current));
348
- },
349
- subscribe: (cb) => {
350
- let initial2 = true;
351
- return n.subscribe((msgs) => {
352
- for (const [t, v] of msgs) {
353
- if (t === DATA) {
354
- if (initial2) {
355
- initial2 = false;
356
- continue;
357
- }
358
- cb(v);
359
- }
360
- }
361
- });
362
- },
363
- meta: n.meta,
364
- _node: n
365
- };
366
- }
367
- function createDerivedAtom(read, write, options) {
368
- const n = autoTrackNode(
369
- (track) => read((a) => {
370
- const dn = a._node;
371
- if (dn.status === "sentinel") {
372
- pull(dn);
373
- }
374
- return track(dn);
375
- }),
376
- {
377
- ...options,
378
- resubscribable: true,
379
- resetOnTeardown: true
380
- }
381
- );
382
- const result = {
383
- get: () => {
384
- if (n.status === "sentinel") {
385
- return pull(n);
386
- }
387
- return n.cache;
388
- },
389
- subscribe: (cb) => {
390
- let initial = true;
391
- return n.subscribe((msgs) => {
392
- for (const [t, v] of msgs) {
393
- if (t === DATA) {
394
- if (initial) {
395
- initial = false;
396
- continue;
397
- }
398
- cb(v);
399
- }
400
- }
401
- });
402
- },
403
- meta: n.meta,
404
- _node: n
405
- };
406
- if (write) {
407
- const getFn = (a) => a.get();
408
- const setFn = (a, value) => a.set(value);
409
- const writable = result;
410
- writable.set = (value) => write(getFn, setFn, value);
411
- writable.update = (fn) => {
412
- const current = n.status === "sentinel" ? pull(n) : n.cache;
413
- return write(getFn, setFn, fn(current));
414
- };
415
- return writable;
416
- }
417
- return result;
418
- }
419
-
420
- // src/compat/nanostores/index.ts
421
- var nanostores_exports = {};
422
- __export(nanostores_exports, {
423
- action: () => action,
424
- atom: () => atom2,
425
- computed: () => computed,
426
- getValue: () => getValue,
427
- map: () => map2,
428
- onMount: () => onMount,
429
- onStart: () => onStart,
430
- onStop: () => onStop
431
- });
432
- var START_LISTENERS = /* @__PURE__ */ new WeakMap();
433
- var STOP_LISTENERS = /* @__PURE__ */ new WeakMap();
434
- function trigger(node2, map3) {
435
- const callbacks = map3.get(node2);
436
- if (callbacks) {
437
- for (const cb of callbacks) cb();
438
- }
439
- }
440
- function createStore(node2, extra = {}) {
441
- let listeners = 0;
442
- const store = {
443
- ...extra,
444
- get: () => getVal(node2),
445
- subscribe: (cb) => {
446
- if (listeners === 0) trigger(node2, START_LISTENERS);
447
- listeners++;
448
- const sub = node2.subscribe((msgs) => {
449
- for (const [t, v] of msgs) {
450
- if (t === DATA) cb(v);
451
- }
452
- });
453
- return () => {
454
- sub();
455
- listeners--;
456
- if (listeners === 0) trigger(node2, STOP_LISTENERS);
457
- };
458
- },
459
- listen: (cb) => {
460
- if (listeners === 0) trigger(node2, START_LISTENERS);
461
- listeners++;
462
- let initial = true;
463
- const sub = node2.subscribe((msgs) => {
464
- for (const [t, v] of msgs) {
465
- if (t === DATA) {
466
- if (initial) {
467
- initial = false;
468
- continue;
469
- }
470
- cb(v);
471
- }
472
- }
473
- });
474
- return () => {
475
- sub();
476
- listeners--;
477
- if (listeners === 0) trigger(node2, STOP_LISTENERS);
478
- };
479
- },
480
- _node: node2
481
- };
482
- return store;
483
- }
484
- function pull2(n) {
485
- let val = n.cache;
486
- let err;
487
- const unsub = n.subscribe((msgs) => {
488
- for (const [t, v] of msgs) {
489
- if (t === DATA) val = v;
490
- if (t === ERROR) err = v;
491
- }
492
- });
493
- unsub();
494
- if (err) throw err;
495
- return val;
496
- }
497
- function getVal(n) {
498
- if (n.status === "sentinel") {
499
- return pull2(n);
500
- }
501
- return n.cache;
502
- }
503
- function atom2(initial) {
504
- const n = state(initial, {
505
- resubscribable: true,
506
- resetOnTeardown: true
507
- });
508
- return createStore(n, {
509
- // `n.emit` routes through the framed pipeline: `bundle()` auto-
510
- // prefixes `[DIRTY]` (diamond-safe wave coordination) and the
511
- // node's `equals` (default `Object.is`) folds same-value writes
512
- // into `RESOLVED`. Matches nanostores' documented Object.is
513
- // dedup semantics without any custom check.
514
- set: (value) => n.emit(value)
515
- });
516
- }
517
- function computed(stores, fn) {
518
- const storeArray = Array.isArray(stores) ? stores : [stores];
519
- const depNodes = storeArray.map((s) => s._node);
520
- const n = dynamicNode(
521
- depNodes,
522
- (track) => {
523
- const vals = storeArray.map((s) => {
524
- const node2 = s._node;
525
- if (node2.status === "sentinel") {
526
- pull2(node2);
527
- }
528
- return track(node2);
529
- });
530
- return fn(...vals);
531
- },
532
- {
533
- resubscribable: true,
534
- resetOnTeardown: true,
535
- equals: Object.is
536
- }
537
- );
538
- return createStore(n);
539
- }
540
- function map2(initial) {
541
- const n = state(initial, {
542
- resubscribable: true,
543
- resetOnTeardown: true,
544
- equals: () => false
545
- });
546
- return createStore(n, {
547
- // `map`'s state node is configured with `equals: () => false`
548
- // above, so every `emit` produces DATA (even for same-key same-
549
- // value sets). The `emit` path is still required for diamond
550
- // coordination (`[DIRTY]` auto-prefix via `bundle()`).
551
- set: (value) => n.emit(value),
552
- setKey: (key, value) => {
553
- const current = getVal(n);
554
- n.emit({ ...current, [key]: value });
555
- }
556
- });
557
- }
558
- function getValue(store) {
559
- return store.get();
560
- }
561
- function onStart(store, cb) {
562
- const node2 = store._node;
563
- let callbacks = START_LISTENERS.get(node2);
564
- if (!callbacks) {
565
- callbacks = /* @__PURE__ */ new Set();
566
- START_LISTENERS.set(node2, callbacks);
567
- }
568
- callbacks.add(cb);
569
- }
570
- function onStop(store, cb) {
571
- const node2 = store._node;
572
- let callbacks = STOP_LISTENERS.get(node2);
573
- if (!callbacks) {
574
- callbacks = /* @__PURE__ */ new Set();
575
- STOP_LISTENERS.set(node2, callbacks);
576
- }
577
- callbacks.add(cb);
578
- }
579
- function onMount(store, cb) {
580
- onStart(store, () => {
581
- const stop = cb();
582
- if (typeof stop === "function") onStop(store, stop);
583
- });
584
- }
585
- function action(_store, _name, fn) {
586
- return (...args) => {
587
- let result;
588
- batch(() => {
589
- result = fn(...args);
590
- });
591
- return result;
592
- };
593
- }
594
-
595
- // src/compat/react/index.ts
596
- var react_exports = {};
597
- __export(react_exports, {
598
- useStore: () => useStore,
599
- useSubscribe: () => useSubscribe,
600
- useSubscribeRecord: () => useSubscribeRecord
601
- });
602
- import { useCallback, useMemo, useRef, useSyncExternalStore } from "react";
603
- function useSubscribe(node2) {
604
- return useSyncExternalStore(
605
- (onStoreChange) => {
606
- let disposed = false;
607
- const unsub = node2.subscribe(() => {
608
- if (!disposed) onStoreChange();
609
- });
610
- return () => {
611
- disposed = true;
612
- unsub();
613
- };
614
- },
615
- () => node2.cache,
616
- () => node2.cache
617
- // Server snapshot
618
- );
619
- }
620
- function useStore(node2) {
621
- const value = useSubscribe(node2);
622
- const setter = useCallback(
623
- (v) => {
624
- node2.down([[DIRTY], [DATA, v]]);
625
- },
626
- [node2]
627
- );
628
- return [value, setter];
629
- }
630
- function useSubscribeRecord(keysNode, factory) {
631
- const factoryRef = useRef(factory);
632
- factoryRef.current = factory;
633
- const store = useMemo(() => {
634
- const computeSnap = () => {
635
- const snap = {};
636
- const keys = keysNode.cache ?? [];
637
- for (const key of keys) {
638
- const nodes = factoryRef.current(key);
639
- const values = {};
640
- for (const field of Object.keys(nodes)) {
641
- values[field] = nodes[field].cache;
642
- }
643
- snap[key] = values;
644
- }
645
- return snap;
646
- };
647
- let currentSnapshot = computeSnap();
648
- return {
649
- subscribe: (onStoreChange) => {
650
- let disposed = false;
651
- let entrySubs = [];
652
- const cleanupEntries = () => {
653
- for (const unsub of entrySubs) unsub();
654
- entrySubs = [];
655
- };
656
- const sync = (nextKeys) => {
657
- cleanupEntries();
658
- for (const key of nextKeys) {
659
- const nodes = factoryRef.current(key);
660
- for (const field of Object.keys(nodes)) {
661
- const unsub = nodes[field].subscribe(() => {
662
- currentSnapshot = computeSnap();
663
- if (!disposed) onStoreChange();
664
- });
665
- entrySubs.push(unsub);
666
- }
667
- }
668
- currentSnapshot = computeSnap();
669
- if (!disposed) onStoreChange();
670
- };
671
- const keysUnsub = keysNode.subscribe((msgs) => {
672
- const hasSettled = msgs.some((m) => m[0] === DATA || m[0] === RESOLVED);
673
- if (!disposed && hasSettled) sync(keysNode.cache ?? []);
674
- });
675
- sync(keysNode.cache ?? []);
676
- return () => {
677
- disposed = true;
678
- keysUnsub();
679
- cleanupEntries();
680
- };
681
- },
682
- getSnapshot: () => currentSnapshot
683
- };
684
- }, [keysNode]);
685
- return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
686
- }
687
-
688
- // src/compat/signals/index.ts
689
- var signals_exports = {};
690
- __export(signals_exports, {
691
- Signal: () => Signal
692
- });
693
- var trackingStack = [];
694
- function pull3(n) {
695
- let val = n.cache;
696
- const unsub = n.subscribe((msgs) => {
697
- for (const [t, v] of msgs) {
698
- if (t === DATA) val = v;
699
- }
700
- });
701
- unsub();
702
- return val;
703
- }
704
- var SignalState = class {
705
- /** @internal */
706
- _node;
707
- _equals;
708
- constructor(initial, opts) {
709
- this._equals = opts?.equals ?? Object.is;
710
- this._node = state(initial, {
711
- ...opts,
712
- resubscribable: true,
713
- resetOnTeardown: true
714
- });
715
- }
716
- get() {
717
- const tracker = trackingStack[trackingStack.length - 1];
718
- if (tracker) {
719
- if (this._node.status === "sentinel") {
720
- pull3(this._node);
721
- }
722
- return tracker(this._node);
723
- }
724
- if (this._node.status === "sentinel") {
725
- return pull3(this._node);
726
- }
727
- return this._node.cache;
728
- }
729
- set(value) {
730
- if (this._equals(this.get(), value)) return;
731
- batch(() => {
732
- this._node.down([[DIRTY], [DATA, value]]);
733
- });
734
- }
735
- };
736
- var SignalComputed = class {
737
- /** @internal */
738
- _node;
739
- constructor(computation, opts) {
740
- this._node = autoTrackNode(
741
- (track) => {
742
- trackingStack.push(track);
743
- try {
744
- return computation();
745
- } finally {
746
- trackingStack.pop();
747
- }
748
- },
749
- {
750
- ...opts,
751
- describeKind: "derived",
752
- resubscribable: true,
753
- resetOnTeardown: true
754
- }
755
- );
756
- }
757
- get() {
758
- const tracker = trackingStack[trackingStack.length - 1];
759
- if (tracker) {
760
- if (this._node.status === "sentinel") {
761
- pull3(this._node);
762
- }
763
- return tracker(this._node);
764
- }
765
- if (this._node.status === "sentinel") {
766
- return pull3(this._node);
767
- }
768
- return this._node.cache;
769
- }
770
- };
771
- var Signal = {
772
- State: SignalState,
773
- Computed: SignalComputed,
774
- /**
775
- * Subscribes to changes on a signal.
776
- * Returns an unsubscribe callback.
777
- *
778
- * @example
779
- * ```ts
780
- * const count = new Signal.State(0);
781
- * const unsub = Signal.sub(count, v => console.log(v));
782
- * ```
783
- */
784
- sub: (signal, callback) => {
785
- const handlers = typeof callback === "function" ? { data: callback, error: void 0, complete: void 0 } : callback;
786
- let initial = true;
787
- return signal._node.subscribe((msgs) => {
788
- for (const [t, v] of msgs) {
789
- if (t === DATA) {
790
- if (initial) {
791
- initial = false;
792
- continue;
793
- }
794
- handlers.data?.(v);
795
- }
796
- if (t === ERROR) handlers.error?.(v);
797
- if (t === COMPLETE) handlers.complete?.();
798
- }
799
- });
800
- }
801
- };
802
-
803
- // src/compat/solid/index.ts
804
- var solid_exports = {};
805
- __export(solid_exports, {
806
- useStore: () => useStore2,
807
- useSubscribe: () => useSubscribe2,
808
- useSubscribeRecord: () => useSubscribeRecord2
809
- });
810
- import { createSignal, getOwner, onCleanup } from "solid-js";
811
- function useSubscribe2(node2) {
812
- const [value, setValue] = createSignal(node2.cache, { equals: false });
813
- const unsub = node2.subscribe(() => {
814
- setValue(() => node2.cache);
815
- });
816
- if (getOwner()) {
817
- onCleanup(() => unsub());
818
- } else if (typeof console !== "undefined") {
819
- console.warn(
820
- "[graphrefly-ts] useSubscribe called outside a Solid reactive owner \u2014 subscription will not be auto-disposed."
821
- );
822
- }
823
- return value;
824
- }
825
- function useStore2(node2) {
826
- const value = useSubscribe2(node2);
827
- const setter = (v) => {
828
- node2.down([[DIRTY], [DATA, v]]);
829
- };
830
- return [value, setter];
831
- }
832
- function useSubscribeRecord2(keysNode, factory) {
833
- const [value, setValue] = createSignal({}, { equals: false });
834
- let entrySubs = [];
835
- const cleanupEntries = () => {
836
- for (const unsub of entrySubs) unsub();
837
- entrySubs = [];
838
- };
839
- const buildSnapshot = () => {
840
- const snap = {};
841
- for (const key of keysNode.cache ?? []) {
842
- const nodes = factory(key);
843
- const values = {};
844
- for (const field of Object.keys(nodes)) {
845
- values[field] = nodes[field].cache;
846
- }
847
- snap[key] = values;
848
- }
849
- return snap;
850
- };
851
- const sync = (nextKeys) => {
852
- cleanupEntries();
853
- for (const key of nextKeys) {
854
- const nodes = factory(key);
855
- for (const field of Object.keys(nodes)) {
856
- const unsub = nodes[field].subscribe(() => {
857
- setValue(() => buildSnapshot());
858
- });
859
- entrySubs.push(unsub);
860
- }
861
- }
862
- setValue(() => buildSnapshot());
863
- };
864
- const keysUnsub = keysNode.subscribe((msgs) => {
865
- if (msgs.some((m) => m[0] === DATA || m[0] === RESOLVED)) {
866
- sync(keysNode.cache ?? []);
867
- }
868
- });
869
- sync(keysNode.cache ?? []);
870
- if (getOwner()) {
871
- onCleanup(() => {
872
- keysUnsub();
873
- cleanupEntries();
874
- });
875
- } else if (typeof console !== "undefined") {
876
- console.warn(
877
- "[graphrefly-ts] useSubscribeRecord called outside a Solid reactive owner \u2014 subscription will not be auto-disposed."
878
- );
879
- }
880
- return value;
881
- }
882
-
883
- // src/compat/svelte/index.ts
884
- var svelte_exports = {};
885
- __export(svelte_exports, {
886
- useStore: () => useStore3,
887
- useSubscribe: () => useSubscribe3,
888
- useSubscribeRecord: () => useSubscribeRecord3
889
- });
890
- function useSubscribe3(node2) {
891
- return {
892
- subscribe(run) {
893
- const unsub = node2.subscribe(() => {
894
- run(node2.cache);
895
- });
896
- run(node2.cache);
897
- return unsub;
898
- }
899
- };
900
- }
901
- function useStore3(node2) {
902
- return {
903
- subscribe(run) {
904
- const unsub = node2.subscribe(() => {
905
- run(node2.cache);
906
- });
907
- run(node2.cache);
908
- return unsub;
909
- },
910
- set(value) {
911
- node2.down([[DIRTY], [DATA, value]]);
912
- },
913
- update(updater) {
914
- const next = updater(node2.cache);
915
- node2.down([[DIRTY], [DATA, next]]);
916
- }
917
- };
918
- }
919
- function useSubscribeRecord3(keysNode, factory) {
920
- return {
921
- subscribe(run) {
922
- let entrySubs = [];
923
- const cleanupEntries = () => {
924
- for (const unsub of entrySubs) unsub();
925
- entrySubs = [];
926
- };
927
- const buildSnapshot = () => {
928
- const snap = {};
929
- for (const key of keysNode.cache ?? []) {
930
- const nodes = factory(key);
931
- const values = {};
932
- for (const field of Object.keys(nodes)) {
933
- values[field] = nodes[field].cache;
934
- }
935
- snap[key] = values;
936
- }
937
- return snap;
938
- };
939
- const sync = (nextKeys) => {
940
- cleanupEntries();
941
- for (const key of nextKeys) {
942
- const nodes = factory(key);
943
- for (const field of Object.keys(nodes)) {
944
- const unsub = nodes[field].subscribe(() => {
945
- run(buildSnapshot());
946
- });
947
- entrySubs.push(unsub);
948
- }
949
- }
950
- run(buildSnapshot());
951
- };
952
- const keysUnsub = keysNode.subscribe((msgs) => {
953
- if (msgs.some((m) => m[0] === DATA || m[0] === RESOLVED)) {
954
- sync(keysNode.cache ?? []);
955
- }
956
- });
957
- sync(keysNode.cache ?? []);
958
- return () => {
959
- keysUnsub();
960
- cleanupEntries();
961
- };
962
- }
963
- };
964
- }
965
-
966
- // src/compat/vue/index.ts
967
- var vue_exports = {};
968
- __export(vue_exports, {
969
- useStore: () => useStore4,
970
- useSubscribe: () => useSubscribe4,
971
- useSubscribeRecord: () => useSubscribeRecord4
972
- });
291
+ } from "./chunk-PHOUUNK7.js";
973
292
  import {
974
- computed as computed2,
975
- getCurrentScope,
976
- isRef,
977
- onScopeDispose,
978
- readonly,
979
- shallowRef,
980
- watch
981
- } from "vue";
982
- function useSubscribe4(node2) {
983
- const ref = shallowRef(node2.cache);
984
- const unsub = node2.subscribe(() => {
985
- ref.value = node2.cache;
986
- });
987
- if (getCurrentScope()) {
988
- onScopeDispose(() => unsub());
989
- } else if (typeof console !== "undefined") {
990
- console.warn(
991
- "[graphrefly-ts] useSubscribe called outside a Vue scope \u2014 subscription will not be auto-disposed."
992
- );
993
- }
994
- return readonly(ref);
995
- }
996
- function useStore4(node2) {
997
- const inner = shallowRef(node2.cache);
998
- const unsub = node2.subscribe(() => {
999
- inner.value = node2.cache;
1000
- });
1001
- if (getCurrentScope()) {
1002
- onScopeDispose(() => unsub());
1003
- } else if (typeof console !== "undefined") {
1004
- console.warn(
1005
- "[graphrefly-ts] useStore called outside a Vue scope \u2014 subscription will not be auto-disposed."
1006
- );
1007
- }
1008
- return computed2({
1009
- get: () => inner.value,
1010
- set: (v) => {
1011
- node2.down([[DIRTY], [DATA, v]]);
1012
- }
1013
- });
1014
- }
1015
- function useSubscribeRecord4(keys, factory) {
1016
- const result = shallowRef({});
1017
- const activeSubs = /* @__PURE__ */ new Map();
1018
- function flushResult() {
1019
- const snap = {};
1020
- for (const [key, entry] of activeSubs) {
1021
- snap[key] = { ...entry.values };
1022
- }
1023
- result.value = snap;
1024
- }
1025
- function sync(newKeys) {
1026
- for (const entry of activeSubs.values()) {
1027
- for (const unsub of entry.subs) unsub();
1028
- }
1029
- activeSubs.clear();
1030
- for (const key of newKeys) {
1031
- const nodes = factory(key);
1032
- const fields = Object.keys(nodes);
1033
- const values = {};
1034
- const subs = [];
1035
- for (const field of fields) {
1036
- const node2 = nodes[field];
1037
- values[field] = node2.cache;
1038
- const unsub = node2.subscribe(() => {
1039
- values[field] = node2.cache;
1040
- flushResult();
1041
- });
1042
- subs.push(unsub);
1043
- }
1044
- activeSubs.set(key, { subs, values });
1045
- }
1046
- const snap = {};
1047
- for (const [key, entry] of activeSubs) {
1048
- snap[key] = { ...entry.values };
1049
- }
1050
- result.value = snap;
1051
- }
1052
- const readKeys = () => {
1053
- const current = typeof keys === "function" ? keys() : isRef(keys) ? keys.value : keys;
1054
- return [...current ?? []];
1055
- };
1056
- watch(readKeys, (newKeys) => sync(newKeys ?? []), { immediate: true });
1057
- if (getCurrentScope()) {
1058
- onScopeDispose(() => {
1059
- for (const entry of activeSubs.values()) {
1060
- for (const unsub of entry.subs) unsub();
1061
- }
1062
- activeSubs.clear();
1063
- });
1064
- } else if (typeof console !== "undefined") {
1065
- console.warn(
1066
- "[graphrefly-ts] useSubscribeRecord called outside a Vue scope \u2014 subscription will not be auto-disposed."
1067
- );
1068
- }
1069
- return readonly(result);
1070
- }
1071
-
1072
- // src/compat/zustand/index.ts
1073
- var zustand_exports = {};
1074
- __export(zustand_exports, {
1075
- create: () => create
1076
- });
1077
- var alwaysDiffer = () => false;
1078
- function create(initializer) {
1079
- const g = new Graph("zustand");
1080
- const s = state(void 0, {
1081
- name: "state",
1082
- equals: alwaysDiffer
1083
- });
1084
- g.add("state", s);
1085
- const getState = () => s.cache;
1086
- const setState = (partial, replace) => {
1087
- const prev = s.cache;
1088
- const next = typeof partial === "function" ? partial(prev) : partial;
1089
- s.emit(replace ? next : { ...prev, ...next });
1090
- };
1091
- const api = {
1092
- getState,
1093
- setState,
1094
- getInitialState: () => initialValue,
1095
- subscribe: (listener) => {
1096
- let initial = true;
1097
- let prev = s.cache;
1098
- return s.subscribe((msgs) => {
1099
- for (const [t, v] of msgs) {
1100
- if (t === DATA) {
1101
- if (initial) {
1102
- initial = false;
1103
- continue;
1104
- }
1105
- listener(v, prev);
1106
- prev = v;
1107
- }
1108
- }
1109
- });
1110
- },
1111
- destroy: g.destroy.bind(g)
1112
- };
1113
- const initialValue = initializer(setState, getState, api);
1114
- s.emit(initialValue);
1115
- return Object.assign(g, api);
1116
- }
293
+ COMPLETE,
294
+ COMPLETE_MSG,
295
+ COMPLETE_ONLY_BATCH,
296
+ DATA,
297
+ DIRTY,
298
+ DIRTY_MSG,
299
+ DIRTY_ONLY_BATCH,
300
+ ERROR,
301
+ INVALIDATE,
302
+ INVALIDATE_MSG,
303
+ INVALIDATE_ONLY_BATCH,
304
+ PAUSE,
305
+ RESOLVED,
306
+ RESOLVED_MSG,
307
+ RESOLVED_ONLY_BATCH,
308
+ RESUME,
309
+ START,
310
+ START_MSG,
311
+ TEARDOWN,
312
+ TEARDOWN_MSG,
313
+ TEARDOWN_ONLY_BATCH,
314
+ __export
315
+ } from "./chunk-SX52TAR4.js";
1117
316
 
1118
317
  // src/patterns/index.ts
1119
318
  var patterns_exports = {};
1120
319
  __export(patterns_exports, {
320
+ SNAPSHOT_WIRE_VERSION: () => SNAPSHOT_WIRE_VERSION,
321
+ SurfaceError: () => SurfaceError,
322
+ accountability: () => audit_exports,
1121
323
  ai: () => ai_exports,
324
+ asSurfaceError: () => asSurfaceError,
1122
325
  cqrs: () => cqrs_exports,
326
+ createGraph: () => createGraph,
327
+ deleteSnapshot: () => deleteSnapshot,
1123
328
  demoShell: () => demo_shell_exports,
329
+ diffSnapshots: () => diffSnapshots,
1124
330
  domainTemplates: () => domain_templates_exports,
1125
331
  graphspec: () => graphspec_exports,
332
+ guarded: () => guarded_execution_exports,
1126
333
  harness: () => harness_exports,
1127
334
  layout: () => reactive_layout_exports,
335
+ lens: () => lens_exports,
336
+ listSnapshots: () => listSnapshots,
1128
337
  memory: () => memory_exports,
1129
338
  messaging: () => messaging_exports,
1130
339
  orchestration: () => orchestration_exports,
1131
- reduction: () => reduction_exports
340
+ reduction: () => reduction_exports,
341
+ resilientPipeline: () => resilient_pipeline_exports,
342
+ restoreSnapshot: () => restoreSnapshot,
343
+ runReduction: () => runReduction,
344
+ saveSnapshot: () => saveSnapshot,
345
+ surface: () => surface_exports
1132
346
  });
1133
347
 
1134
348
  // src/patterns/ai.ts
@@ -4166,308 +3380,418 @@ async function suggestStrategy(graph, problem, adapter, opts) {
4166
3380
  };
4167
3381
  }
4168
3382
 
4169
- // src/patterns/demo-shell.ts
4170
- var demo_shell_exports = {};
4171
- __export(demo_shell_exports, {
4172
- demoShell: () => demoShell
3383
+ // src/patterns/audit.ts
3384
+ var audit_exports = {};
3385
+ __export(audit_exports, {
3386
+ AuditTrailGraph: () => AuditTrailGraph,
3387
+ PolicyEnforcerGraph: () => PolicyEnforcerGraph,
3388
+ auditTrail: () => auditTrail,
3389
+ complianceSnapshot: () => complianceSnapshot,
3390
+ policyEnforcer: () => policyEnforcer,
3391
+ reactiveExplainPath: () => reactiveExplainPath
4173
3392
  });
4174
- function clamp01(v) {
4175
- return Math.max(0, Math.min(1, v));
4176
- }
4177
- function demoShell(opts) {
4178
- const mainRatioInit = clamp01(opts?.mainRatio ?? 0.65);
4179
- const sideSplitInit = clamp01(opts?.sideSplit ?? 0.5);
4180
- const viewportInit = Math.max(0, opts?.viewportWidth ?? 1280);
4181
- const registry = opts?.nodeRegistry ?? /* @__PURE__ */ new Map();
4182
- const adapter = opts?.adapter ?? null;
4183
- const layoutFont = opts?.layoutFont ?? "14px monospace";
4184
- const onHighlight = opts?.onHighlight;
4185
- const g = new Graph("demo-shell");
4186
- const paneMainRatio = state(mainRatioInit, { name: "pane/main-ratio" });
4187
- const paneSideSplit = state(sideSplitInit, { name: "pane/side-split" });
4188
- const paneFullscreen = state(null, {
4189
- name: "pane/fullscreen"
4190
- });
4191
- const viewportWidth = state(viewportInit, { name: "viewport/width" });
4192
- g.add("pane/main-ratio", paneMainRatio);
4193
- g.add("pane/side-split", paneSideSplit);
4194
- g.add("pane/fullscreen", paneFullscreen);
4195
- g.add("viewport/width", viewportWidth);
4196
- const paneMainWidth = derived(
4197
- [paneMainRatio, viewportWidth, paneFullscreen],
4198
- ([ratio, vw, fs]) => {
4199
- const r = ratio;
4200
- const w = vw;
4201
- const fullscreen = fs;
4202
- if (fullscreen === "main") return w;
4203
- if (fullscreen === "graph" || fullscreen === "code") return 0;
4204
- return Math.round(w * r);
4205
- },
4206
- { name: "pane/main-width" }
4207
- );
4208
- const paneSideWidth = derived(
4209
- [paneMainWidth, viewportWidth, paneFullscreen],
4210
- ([main, vw, fs]) => {
4211
- const fullscreen = fs;
4212
- const w = vw;
4213
- if (fullscreen === "main") return 0;
4214
- if (fullscreen === "graph" || fullscreen === "code") return w;
4215
- return w - main;
4216
- },
4217
- { name: "pane/side-width" }
4218
- );
4219
- const paneGraphHeight = derived(
4220
- [paneSideSplit, paneFullscreen],
4221
- ([split, fs]) => {
4222
- const fullscreen = fs;
4223
- if (fullscreen === "graph") return 1;
4224
- if (fullscreen === "code") return 0;
4225
- if (fullscreen === "main") return 0;
4226
- return clamp01(split);
4227
- },
4228
- { name: "pane/graph-height-ratio" }
4229
- );
4230
- const paneCodeHeight = derived(
4231
- [paneGraphHeight, paneFullscreen],
4232
- ([graphH, fs]) => {
4233
- const fullscreen = fs;
4234
- if (fullscreen === "code") return 1;
4235
- if (fullscreen === "graph" || fullscreen === "main") return 0;
4236
- return 1 - graphH;
4237
- },
4238
- { name: "pane/code-height-ratio" }
4239
- );
4240
- g.add("pane/main-width", paneMainWidth);
4241
- g.add("pane/side-width", paneSideWidth);
4242
- g.add("pane/graph-height-ratio", paneGraphHeight);
4243
- g.add("pane/code-height-ratio", paneCodeHeight);
4244
- const demoGraphRef = state(null, {
4245
- name: "demo/graph-ref"
4246
- });
4247
- const demoGraphTick = state(0, { name: "demo/graph-tick" });
4248
- g.add("demo/graph-ref", demoGraphRef);
4249
- g.add("demo/graph-tick", demoGraphTick);
4250
- const graphMermaid = derived(
4251
- [demoGraphRef, demoGraphTick],
4252
- ([ref, _tick]) => {
4253
- const demo = ref;
4254
- if (!demo) return "";
4255
- return demo.describe({ format: "mermaid" });
4256
- },
4257
- { name: "graph/mermaid" }
4258
- );
4259
- const graphDescribe = derived(
4260
- [demoGraphRef, demoGraphTick],
4261
- ([ref, _tick]) => {
4262
- const demo = ref;
4263
- if (!demo) return null;
4264
- const { expand: _, ...snapshot } = demo.describe({ detail: "standard" });
4265
- return snapshot;
4266
- },
4267
- { name: "graph/describe" }
4268
- );
4269
- g.add("graph/mermaid", graphMermaid);
4270
- g.add("graph/describe", graphDescribe);
4271
- const hoverTarget = state(null, { name: "hover/target" });
4272
- g.add("hover/target", hoverTarget);
4273
- const highlightCodeScroll = derived(
4274
- [hoverTarget],
4275
- ([target]) => {
4276
- const t = target;
4277
- if (!t) return null;
4278
- const entry = registry.get(t.id);
4279
- return entry ? entry.codeLine : null;
4280
- },
4281
- { name: "highlight/code-scroll" }
4282
- );
4283
- const highlightVisual = derived(
4284
- [hoverTarget],
4285
- ([target]) => {
4286
- const t = target;
4287
- if (!t) return null;
4288
- const entry = registry.get(t.id);
4289
- return entry ? entry.visualSelector : null;
4290
- },
4291
- { name: "highlight/visual" }
4292
- );
4293
- const highlightGraph = derived(
4294
- [hoverTarget],
4295
- ([target]) => {
4296
- const t = target;
4297
- if (!t) return null;
4298
- return t.id;
4299
- },
4300
- { name: "highlight/graph" }
4301
- );
4302
- g.add("highlight/code-scroll", highlightCodeScroll);
4303
- g.add("highlight/visual", highlightVisual);
4304
- g.add("highlight/graph", highlightGraph);
4305
- if (onHighlight?.codeScroll) {
4306
- const cb = onHighlight.codeScroll;
4307
- const applyCodeScroll = effect([highlightCodeScroll], ([line]) => {
4308
- cb(line);
3393
+ function auditMeta(kind, extra) {
3394
+ return domainMeta("audit", kind, extra);
3395
+ }
3396
+ var DEFAULT_INCLUDE_TYPES = /* @__PURE__ */ new Set([
3397
+ "data",
3398
+ "error",
3399
+ "complete",
3400
+ "teardown"
3401
+ ]);
3402
+ var AuditTrailGraph = class extends Graph {
3403
+ entries;
3404
+ count;
3405
+ _log;
3406
+ _target;
3407
+ constructor(target, opts) {
3408
+ super(opts.name ?? `${target.name}_audit`, opts.graph);
3409
+ this._target = target;
3410
+ this._log = reactiveLog([], {
3411
+ name: "entries",
3412
+ ...opts.maxSize != null ? { maxSize: opts.maxSize } : {}
4309
3413
  });
4310
- g.add("highlight/apply-code-scroll", applyCodeScroll);
3414
+ this.entries = this._log.entries;
3415
+ this.add("entries", this.entries);
3416
+ this.count = derived(
3417
+ [this.entries],
3418
+ ([snapshot]) => snapshot.length,
3419
+ { name: "count", describeKind: "derived", meta: auditMeta("count") }
3420
+ );
3421
+ this.add("count", this.count);
3422
+ this.addDisposer(keepalive(this.count));
3423
+ const includeTypes = opts.includeTypes != null ? new Set(opts.includeTypes) : DEFAULT_INCLUDE_TYPES;
3424
+ const filter2 = opts.filter;
3425
+ let seq = 0;
3426
+ const handle = target.observe({ timeline: true, structured: true });
3427
+ const offEvent = handle.onEvent((event) => {
3428
+ if (event.type === "derived") return;
3429
+ const type = event.type;
3430
+ if (!includeTypes.has(type)) return;
3431
+ const path = event.path ?? "";
3432
+ const entry = {
3433
+ seq: seq++,
3434
+ timestamp_ns: event.timestamp_ns ?? monotonicNs(),
3435
+ wall_clock_ns: wallClockNs(),
3436
+ path,
3437
+ type
3438
+ };
3439
+ const node2 = path ? safeNode(target, path) : void 0;
3440
+ const lastMutation = node2?.lastMutation;
3441
+ if (lastMutation != null) entry.actor = lastMutation.actor;
3442
+ if (type === "data") entry.value = event.data;
3443
+ if (type === "error") entry.error = event.data;
3444
+ const reason = path ? safeAnnotation(target, path) : void 0;
3445
+ if (reason != null) entry.reason = reason;
3446
+ if (filter2 != null && !filter2(entry)) return;
3447
+ this._log.append(entry);
3448
+ });
3449
+ this.addDisposer(() => {
3450
+ offEvent();
3451
+ handle.dispose();
3452
+ });
3453
+ this.addDisposer(() => this._log.disposeAllViews());
3454
+ }
3455
+ /** All entries currently in the ring (snapshot). */
3456
+ all() {
3457
+ return this.entries.cache ?? [];
3458
+ }
3459
+ /** Entries matching `path`. Order preserved. */
3460
+ byNode(path) {
3461
+ return this.all().filter((e) => e.path === path);
3462
+ }
3463
+ /** Entries whose `actor.id` matches. Use `byActorType` for type filtering. */
3464
+ byActor(actorId) {
3465
+ return this.all().filter((e) => e.actor?.id === actorId);
3466
+ }
3467
+ /** Entries whose `actor.type` matches (e.g. `"llm"`, `"human"`). */
3468
+ byActorType(type) {
3469
+ return this.all().filter((e) => e.actor?.type === type);
3470
+ }
3471
+ /**
3472
+ * Entries with `timestamp_ns` in `[start_ns, end_ns)` (end exclusive).
3473
+ * Omit `end_ns` to query open-ended.
3474
+ */
3475
+ byTimeRange(start_ns, end_ns) {
3476
+ return this.all().filter((e) => {
3477
+ if (e.timestamp_ns < start_ns) return false;
3478
+ if (end_ns != null && e.timestamp_ns >= end_ns) return false;
3479
+ return true;
3480
+ });
3481
+ }
3482
+ /** Reference to the audited graph (escape hatch for tooling). */
3483
+ get target() {
3484
+ return this._target;
3485
+ }
3486
+ };
3487
+ function auditTrail(target, opts = {}) {
3488
+ return new AuditTrailGraph(target, opts);
3489
+ }
3490
+ var PolicyEnforcerGraph = class extends Graph {
3491
+ policies;
3492
+ violations;
3493
+ violationCount;
3494
+ _target;
3495
+ _mode;
3496
+ _currentGuard;
3497
+ constructor(target, policies, opts) {
3498
+ super(opts.name ?? `${target.name}_policy`, opts.graph);
3499
+ this._target = target;
3500
+ this._mode = opts.mode ?? "audit";
3501
+ const policiesNode = isNode(policies) ? policies : state(policies, { name: "policies" });
3502
+ this.policies = policiesNode;
3503
+ this.add("policies", this.policies);
3504
+ this.violations = new TopicGraph("violations", {
3505
+ retainedLimit: opts.violationsLimit ?? 1e3
3506
+ });
3507
+ this.mount("violations", this.violations);
3508
+ this.violationCount = derived(
3509
+ [this.violations.events],
3510
+ ([snapshot]) => snapshot.length,
3511
+ {
3512
+ name: "violationCount",
3513
+ describeKind: "derived",
3514
+ meta: auditMeta("policy_violation_count")
3515
+ }
3516
+ );
3517
+ this.add("violationCount", this.violationCount);
3518
+ this.addDisposer(keepalive(this.violationCount));
3519
+ const initialRules = policiesNode.cache ?? [];
3520
+ let latestRules = initialRules;
3521
+ this._currentGuard = policyFromRules(latestRules);
3522
+ const offPolicies = policiesNode.subscribe((msgs) => {
3523
+ for (const m of msgs) {
3524
+ if (m[0] === DATA) {
3525
+ latestRules = m[1] ?? [];
3526
+ this._currentGuard = policyFromRules(latestRules);
3527
+ }
3528
+ }
3529
+ });
3530
+ this.addDisposer(offPolicies);
3531
+ const paths = opts.paths != null ? [...opts.paths] : collectPaths(target);
3532
+ if (this._mode === "enforce") {
3533
+ const restorers = /* @__PURE__ */ new Map();
3534
+ const wrapAndPush = (path) => {
3535
+ if (restorers.has(path)) return;
3536
+ const node2 = safeNode(target, path);
3537
+ if (!(node2 instanceof NodeImpl)) return;
3538
+ const pathGuard = (actor, action) => {
3539
+ const ok = this._currentGuard(actor, action);
3540
+ if (!ok) {
3541
+ this._publishViolation(actor, action, path, "blocked");
3542
+ }
3543
+ return ok;
3544
+ };
3545
+ restorers.set(path, node2._pushGuard(pathGuard));
3546
+ };
3547
+ for (const path of paths) wrapAndPush(path);
3548
+ if (opts.paths == null) {
3549
+ const offTopology = watchTopologyTree(target, (event, emitter, prefix) => {
3550
+ if (event.kind === "added") {
3551
+ if (event.nodeKind === "node") {
3552
+ wrapAndPush(`${prefix}${event.name}`);
3553
+ } else {
3554
+ const child = emitter._mounts.get(event.name);
3555
+ if (!(child instanceof Graph)) return;
3556
+ const mountPrefix = `${prefix}${event.name}::`;
3557
+ const localPaths = collectPaths(child);
3558
+ for (const localPath of localPaths) {
3559
+ wrapAndPush(
3560
+ localPath === "" ? `${prefix}${event.name}` : `${mountPrefix}${localPath}`
3561
+ );
3562
+ }
3563
+ }
3564
+ } else if (event.kind === "removed") {
3565
+ if (event.nodeKind === "node") {
3566
+ const qp = `${prefix}${event.name}`;
3567
+ const r = restorers.get(qp);
3568
+ if (r != null) {
3569
+ r();
3570
+ restorers.delete(qp);
3571
+ }
3572
+ } else {
3573
+ const mountQp = `${prefix}${event.name}`;
3574
+ const mountPrefix = `${mountQp}::`;
3575
+ for (const [p, r] of restorers) {
3576
+ if (p === mountQp || p.startsWith(mountPrefix)) {
3577
+ r();
3578
+ restorers.delete(p);
3579
+ }
3580
+ }
3581
+ }
3582
+ }
3583
+ });
3584
+ this.addDisposer(offTopology);
3585
+ } else {
3586
+ const offCleanup = target.topology.subscribe((msgs) => {
3587
+ for (const m of msgs) {
3588
+ if (m[0] !== DATA) continue;
3589
+ const event = m[1];
3590
+ if (event.kind !== "removed" || event.nodeKind !== "node") continue;
3591
+ const r = restorers.get(event.name);
3592
+ if (r != null) {
3593
+ r();
3594
+ restorers.delete(event.name);
3595
+ }
3596
+ }
3597
+ });
3598
+ this.addDisposer(offCleanup);
3599
+ }
3600
+ this.addDisposer(() => {
3601
+ for (const r of restorers.values()) r();
3602
+ restorers.clear();
3603
+ });
3604
+ } else {
3605
+ const handle = target.observe({ timeline: true, structured: true });
3606
+ const off = handle.onEvent((event) => {
3607
+ if (event.type !== "data" && event.type !== "error") return;
3608
+ const path = event.path ?? "";
3609
+ if (!path) return;
3610
+ if (opts.paths != null && !opts.paths.includes(path)) return;
3611
+ const node2 = safeNode(target, path);
3612
+ const lastMutation = node2?.lastMutation;
3613
+ if (lastMutation == null) return;
3614
+ const action = "write";
3615
+ if (this._currentGuard(lastMutation.actor, action)) return;
3616
+ this._publishViolation(lastMutation.actor, action, path, "observed");
3617
+ });
3618
+ this.addDisposer(() => {
3619
+ off();
3620
+ handle.dispose();
3621
+ });
3622
+ }
4311
3623
  }
4312
- if (onHighlight?.visual) {
4313
- const cb = onHighlight.visual;
4314
- const applyVisual = effect([highlightVisual], ([selector]) => {
4315
- cb(selector);
3624
+ _publishViolation(actor, action, path, result) {
3625
+ this.violations.publish({
3626
+ timestamp_ns: monotonicNs(),
3627
+ wall_clock_ns: wallClockNs(),
3628
+ path,
3629
+ actor,
3630
+ action,
3631
+ mode: this._mode,
3632
+ result
4316
3633
  });
4317
- g.add("highlight/apply-visual", applyVisual);
4318
3634
  }
4319
- if (onHighlight?.graph) {
4320
- const cb = onHighlight.graph;
4321
- const applyGraph = effect([highlightGraph], ([nodeId]) => {
4322
- cb(nodeId);
4323
- });
4324
- g.add("highlight/apply-graph", applyGraph);
3635
+ /** Snapshot of recorded violations. */
3636
+ all() {
3637
+ return this.violations.retained();
3638
+ }
3639
+ get mode() {
3640
+ return this._mode;
4325
3641
  }
4326
- const inspectSelected = state(null, {
4327
- name: "inspect/selected-node"
3642
+ get target() {
3643
+ return this._target;
3644
+ }
3645
+ };
3646
+ function policyEnforcer(target, policies, opts = {}) {
3647
+ return new PolicyEnforcerGraph(target, policies, opts);
3648
+ }
3649
+ function reactiveExplainPath(target, from, to, opts) {
3650
+ let v = 0;
3651
+ const version2 = state(v, { name: "explain_version" });
3652
+ const handle = target.observe({ timeline: true, structured: true });
3653
+ const off = handle.onEvent((event) => {
3654
+ const t = event.type;
3655
+ if (t !== "data" && t !== "error" && t !== "complete" && t !== "teardown") return;
3656
+ v += 1;
3657
+ version2.emit(v);
4328
3658
  });
4329
- g.add("inspect/selected-node", inspectSelected);
4330
- const standardFields = resolveDescribeFields("standard");
4331
- const inspectNodeDetail = derived(
4332
- [inspectSelected, demoGraphRef, demoGraphTick],
4333
- ([path, ref, _tick]) => {
4334
- const demo = ref;
4335
- const p = path;
4336
- if (!demo || !p) return null;
4337
- try {
4338
- const nd = demo.resolve(p);
4339
- const nodeDesc = describeNode(nd, standardFields);
4340
- return { path: p, ...nodeDesc, value: nd.cache };
4341
- } catch {
4342
- return null;
3659
+ const explainOpts = {
3660
+ ...opts?.maxDepth != null ? { maxDepth: opts.maxDepth } : {},
3661
+ ...opts?.findCycle === true ? { findCycle: true } : {}
3662
+ };
3663
+ const node2 = derived([version2], () => target.explain(from, to, explainOpts), {
3664
+ name: opts?.name ?? "explain",
3665
+ describeKind: "derived",
3666
+ equals: (a, b) => a.found === b.found && a.reason === b.reason && a.steps.length === b.steps.length && causalStepsEqual(a.steps, b.steps),
3667
+ meta: auditMeta("explain_path", { from, to })
3668
+ });
3669
+ const stopKeepalive = keepalive(node2);
3670
+ return {
3671
+ node: node2,
3672
+ dispose() {
3673
+ off();
3674
+ handle.dispose();
3675
+ stopKeepalive();
3676
+ }
3677
+ };
3678
+ }
3679
+ function causalStepsEqual(a, b) {
3680
+ for (let i = 0; i < a.length; i++) {
3681
+ const x = a[i];
3682
+ const y = b[i];
3683
+ if (x.path !== y.path) return false;
3684
+ if (x.type !== y.type) return false;
3685
+ if (x.status !== y.status) return false;
3686
+ if (x.hop !== y.hop) return false;
3687
+ if (x.dep_index !== y.dep_index) return false;
3688
+ if (x.reason !== y.reason) return false;
3689
+ if (x.value !== y.value) return false;
3690
+ if (x.lastMutation !== y.lastMutation) return false;
3691
+ const xv = x.v;
3692
+ const yv = y.v;
3693
+ if (xv !== yv) {
3694
+ if (xv == null || yv == null) return false;
3695
+ if (xv.id !== yv.id || xv.version !== yv.version) return false;
3696
+ }
3697
+ }
3698
+ return true;
3699
+ }
3700
+ function complianceSnapshot(target, opts = {}) {
3701
+ const result = {
3702
+ format_version: 1,
3703
+ timestamp_ns: monotonicNs(),
3704
+ wall_clock_ns: wallClockNs(),
3705
+ graph: target.snapshot()
3706
+ };
3707
+ if (opts.actor != null) result.actor = opts.actor;
3708
+ if (opts.audit != null) {
3709
+ const entries = [...opts.audit.all()];
3710
+ result.audit = { count: entries.length, entries };
3711
+ }
3712
+ if (opts.policies != null) {
3713
+ const rules = opts.policies.policies.cache ?? [];
3714
+ result.policies = {
3715
+ mode: opts.policies.mode,
3716
+ rules,
3717
+ violations: [...opts.policies.all()]
3718
+ };
3719
+ }
3720
+ const fingerprint = computeFingerprint(result);
3721
+ return { ...result, fingerprint };
3722
+ }
3723
+ function isNode(x) {
3724
+ return typeof x === "object" && x !== null && "subscribe" in x;
3725
+ }
3726
+ function safeNode(target, path) {
3727
+ try {
3728
+ return target.node(path);
3729
+ } catch {
3730
+ return void 0;
3731
+ }
3732
+ }
3733
+ function safeAnnotation(target, path) {
3734
+ try {
3735
+ return target.annotation(path);
3736
+ } catch {
3737
+ return void 0;
3738
+ }
3739
+ }
3740
+ function collectPaths(target) {
3741
+ const described = target.describe({ detail: "minimal" });
3742
+ return Object.keys(described.nodes);
3743
+ }
3744
+ function computeFingerprint(value) {
3745
+ return defaultHash(JSON.stringify(canonicalize(value)));
3746
+ }
3747
+ function canonicalize(value) {
3748
+ const stack = /* @__PURE__ */ new Set();
3749
+ const walk = (v) => {
3750
+ if (v === void 0) return { __undefined: true };
3751
+ if (v === null) return null;
3752
+ const t = typeof v;
3753
+ if (t === "bigint") return { __bigint: v.toString() };
3754
+ if (t !== "object") return v;
3755
+ const obj = v;
3756
+ if (stack.has(obj)) return { __circular: true };
3757
+ stack.add(obj);
3758
+ try {
3759
+ if (Array.isArray(obj)) {
3760
+ return obj.map(walk);
4343
3761
  }
4344
- },
4345
- { name: "inspect/node-detail" }
4346
- );
4347
- const inspectTraceLog = derived(
4348
- [demoGraphRef, demoGraphTick],
4349
- ([ref, _tick]) => {
4350
- const demo = ref;
4351
- if (!demo) return [];
4352
- return demo.trace();
4353
- },
4354
- { name: "inspect/trace-log" }
4355
- );
4356
- g.add("inspect/node-detail", inspectNodeDetail);
4357
- g.add("inspect/trace-log", inspectTraceLog);
4358
- const metaDebug = state(false, { name: "meta/debug" });
4359
- g.add("meta/debug", metaDebug);
4360
- const metaShellMermaid = derived(
4361
- [metaDebug, demoGraphTick],
4362
- ([debug, _tick]) => {
4363
- if (!debug) return "";
4364
- return g.describe({ format: "mermaid" });
4365
- },
4366
- { name: "meta/shell-mermaid" }
4367
- );
4368
- g.add("meta/shell-mermaid", metaShellMermaid);
4369
- const codeTextNode = state("", { name: "layout/code-text" });
4370
- g.add("layout/code-text", codeTextNode);
4371
- if (adapter) {
4372
- const measureCache = /* @__PURE__ */ new Map();
4373
- const graphLabels = derived(
4374
- [graphDescribe],
4375
- ([desc]) => {
4376
- const d = desc;
4377
- if (!d) return /* @__PURE__ */ new Map();
4378
- const result = /* @__PURE__ */ new Map();
4379
- for (const [name] of Object.entries(d.nodes)) {
4380
- const segments = analyzeAndMeasure(name, layoutFont, adapter, measureCache);
4381
- const lb = computeLineBreaks(segments, Infinity, adapter, layoutFont, measureCache);
4382
- const width = lb.lines.reduce((max, l) => Math.max(max, l.width), 0);
4383
- const height = lb.lineCount * 20;
4384
- result.set(name, { width, height });
4385
- }
4386
- return result;
4387
- },
4388
- {
4389
- name: "layout/graph-labels",
4390
- equals: (a, b) => {
4391
- if (a === b) return true;
4392
- const ma = a;
4393
- const mb = b;
4394
- if (ma.size !== mb.size) return false;
4395
- for (const [k, v] of ma) {
4396
- const bv = mb.get(k);
4397
- if (!bv || bv.width !== v.width || bv.height !== v.height) return false;
4398
- }
4399
- return true;
4400
- }
3762
+ if (obj instanceof Date) {
3763
+ return { __date: obj.toISOString() };
4401
3764
  }
4402
- );
4403
- const codeLines = derived(
4404
- [codeTextNode, paneSideWidth],
4405
- ([text, sideW]) => {
4406
- const t = text;
4407
- if (!t) return { lineCount: 0, lines: [] };
4408
- const segments = analyzeAndMeasure(t, layoutFont, adapter, measureCache);
4409
- const maxW = sideW - 40;
4410
- return computeLineBreaks(segments, Math.max(100, maxW), adapter, layoutFont, measureCache);
4411
- },
4412
- { name: "layout/code-lines" }
4413
- );
4414
- const sideWidthHint = derived(
4415
- [graphLabels],
4416
- ([labels]) => {
4417
- const m = labels;
4418
- if (m.size === 0) return 200;
4419
- let maxW = 0;
4420
- for (const { width } of m.values()) {
4421
- if (width > maxW) maxW = width;
4422
- }
4423
- return Math.max(200, Math.round(maxW + 80));
4424
- },
4425
- { name: "layout/side-width-hint" }
4426
- );
4427
- g.add("layout/graph-labels", graphLabels);
4428
- g.add("layout/code-lines", codeLines);
4429
- g.add("layout/side-width-hint", sideWidthHint);
4430
- }
4431
- let tickCounter = 0;
4432
- return {
4433
- graph: g,
4434
- setMainRatio(ratio) {
4435
- g.set("pane/main-ratio", clamp01(ratio));
4436
- },
4437
- setSideSplit(ratio) {
4438
- g.set("pane/side-split", clamp01(ratio));
4439
- },
4440
- setFullscreen(pane) {
4441
- g.set("pane/fullscreen", pane);
4442
- },
4443
- setViewportWidth(width) {
4444
- g.set("viewport/width", Math.max(0, width));
4445
- },
4446
- setHoverTarget(target) {
4447
- g.set("hover/target", target);
4448
- },
4449
- setDemoGraph(demo) {
4450
- g.set("demo/graph-ref", demo);
4451
- },
4452
- bumpGraphTick() {
4453
- g.set("demo/graph-tick", ++tickCounter);
4454
- },
4455
- selectNode(path) {
4456
- g.set("inspect/selected-node", path);
4457
- },
4458
- setMetaDebug(on) {
4459
- g.set("meta/debug", on);
4460
- },
4461
- setCodeText(text) {
4462
- g.set("layout/code-text", text);
4463
- },
4464
- batch(fn) {
4465
- batch(fn);
4466
- },
4467
- destroy() {
4468
- g.destroy();
3765
+ if (obj instanceof RegExp) {
3766
+ return { __regexp: { source: obj.source, flags: obj.flags } };
3767
+ }
3768
+ if (obj instanceof Map) {
3769
+ const entries = [...obj.entries()].map(([k, mv]) => [
3770
+ walk(k),
3771
+ walk(mv)
3772
+ ]);
3773
+ return { __map: entries };
3774
+ }
3775
+ if (obj instanceof Set) {
3776
+ const items = [...obj].map(walk);
3777
+ return { __set: items };
3778
+ }
3779
+ if (ArrayBuffer.isView(obj)) {
3780
+ const ta = obj;
3781
+ const arr = new Array(ta.length);
3782
+ for (let i = 0; i < ta.length; i++) arr[i] = ta[i] ?? 0;
3783
+ return { __typed_array: { ctor: obj.constructor.name, data: arr } };
3784
+ }
3785
+ const out = {};
3786
+ for (const k of Object.keys(obj).sort()) {
3787
+ out[k] = walk(obj[k]);
3788
+ }
3789
+ return out;
3790
+ } finally {
3791
+ stack.delete(obj);
4469
3792
  }
4470
3793
  };
3794
+ return walk(value);
4471
3795
  }
4472
3796
 
4473
3797
  // src/patterns/domain-templates.ts
@@ -6300,6 +5624,65 @@ ${validation.errors.join("\n")}`);
6300
5624
  return parsed;
6301
5625
  }
6302
5626
 
5627
+ // src/patterns/guarded-execution.ts
5628
+ var guarded_execution_exports = {};
5629
+ __export(guarded_execution_exports, {
5630
+ GuardedExecutionGraph: () => GuardedExecutionGraph,
5631
+ guardedExecution: () => guardedExecution
5632
+ });
5633
+ var GuardedExecutionGraph = class extends Graph {
5634
+ enforcer;
5635
+ violations;
5636
+ _target;
5637
+ _defaultActor;
5638
+ constructor(target, opts) {
5639
+ super(opts.name ?? `${target.name}_guarded`, opts.graph);
5640
+ this._target = target;
5641
+ this._defaultActor = opts.actor;
5642
+ const enforcerOpts = {
5643
+ mode: opts.mode ?? "enforce",
5644
+ name: "enforcer"
5645
+ };
5646
+ if (opts.violationsLimit != null) enforcerOpts.violationsLimit = opts.violationsLimit;
5647
+ this.enforcer = policyEnforcer(target, opts.policies, enforcerOpts);
5648
+ this.violations = this.enforcer.violations;
5649
+ this.mount("enforcer", this.enforcer);
5650
+ }
5651
+ /**
5652
+ * Describe the **target** graph scoped to the configured actor. Returns
5653
+ * only nodes the actor is permitted to see (via the target's node guards
5654
+ * filtering `describe()` via `actor`).
5655
+ *
5656
+ * Pass `{actor}` in opts to override the configured actor for this call.
5657
+ * Pass any standard {@link GraphDescribeOptions} fields (`detail`,
5658
+ * `fields`, `filter`) — they apply to the target's describe.
5659
+ *
5660
+ * **Mode interaction:**
5661
+ * - In `mode: "enforce"` (default), the enforcer stacks a policy-derived
5662
+ * guard on every target node. `scopedDescribe({actor})` then filters by
5663
+ * the AND of per-node guards AND the stacked policy guard.
5664
+ * - In `mode: "audit"`, NO guards are stacked — `scopedDescribe` filters
5665
+ * purely by the target's pre-existing per-node guards. If a target has
5666
+ * no node-level guards, the policy rules you pass have no effect on
5667
+ * visibility (they only populate the `violations` topic on writes).
5668
+ */
5669
+ scopedDescribe(opts) {
5670
+ const actor = opts?.actor ?? this._defaultActor;
5671
+ const describeOpts = {
5672
+ ...opts,
5673
+ ...actor != null ? { actor } : {}
5674
+ };
5675
+ return this._target.describe(describeOpts);
5676
+ }
5677
+ /** The wrapped graph (escape hatch for tooling). */
5678
+ get target() {
5679
+ return this._target;
5680
+ }
5681
+ };
5682
+ function guardedExecution(target, opts) {
5683
+ return new GuardedExecutionGraph(target, opts);
5684
+ }
5685
+
6303
5686
  // src/patterns/harness/index.ts
6304
5687
  var harness_exports = {};
6305
5688
  __export(harness_exports, {
@@ -6378,8 +5761,8 @@ function evalIntakeBridge(evalSource2, intakeTopic, opts) {
6378
5761
  { name: opts?.name ?? "eval-intake-bridge" }
6379
5762
  );
6380
5763
  }
6381
- function evalSource(trigger2, runner) {
6382
- return switchMap(trigger2, () => fromAny(runner()));
5764
+ function evalSource(trigger, runner) {
5765
+ return switchMap(trigger, () => fromAny(runner()));
6383
5766
  }
6384
5767
  function beforeAfterCompare(before, after) {
6385
5768
  return derived(
@@ -6981,6 +6364,636 @@ function truncate(s, max) {
6981
6364
  return s.length > max ? `${s.slice(0, max - 1)}\u2026` : s;
6982
6365
  }
6983
6366
 
6367
+ // src/patterns/lens.ts
6368
+ var lens_exports = {};
6369
+ __export(lens_exports, {
6370
+ LensGraph: () => LensGraph,
6371
+ graphLens: () => graphLens,
6372
+ watchTopologyTree: () => watchTopologyTree
6373
+ });
6374
+ function lensMeta(kind) {
6375
+ return domainMeta("lens", kind);
6376
+ }
6377
+ function computeTopologyStats(described) {
6378
+ const paths = Object.keys(described.nodes);
6379
+ const depsByPath = /* @__PURE__ */ new Map();
6380
+ const dependents = /* @__PURE__ */ new Map();
6381
+ for (const path of paths) {
6382
+ const deps = described.nodes[path]?.deps ?? [];
6383
+ depsByPath.set(path, deps);
6384
+ for (const dep of deps) {
6385
+ if (!dependents.has(dep)) dependents.set(dep, /* @__PURE__ */ new Set());
6386
+ dependents.get(dep).add(path);
6387
+ }
6388
+ }
6389
+ const sources = [];
6390
+ const sinks = [];
6391
+ for (const path of paths) {
6392
+ if ((depsByPath.get(path) ?? []).length === 0) sources.push(path);
6393
+ if (!dependents.has(path)) sinks.push(path);
6394
+ }
6395
+ sources.sort();
6396
+ sinks.sort();
6397
+ const edgeCount = described.edges.length;
6398
+ const WHITE = 0;
6399
+ const GRAY = 1;
6400
+ const BLACK = 2;
6401
+ const color = /* @__PURE__ */ new Map();
6402
+ for (const p of paths) color.set(p, WHITE);
6403
+ let hasCycles = false;
6404
+ const longestFrom = /* @__PURE__ */ new Map();
6405
+ const dfs = (path) => {
6406
+ const c = color.get(path) ?? WHITE;
6407
+ if (c === GRAY) {
6408
+ hasCycles = true;
6409
+ return 0;
6410
+ }
6411
+ if (c === BLACK) return longestFrom.get(path) ?? 0;
6412
+ color.set(path, GRAY);
6413
+ let best = 0;
6414
+ const kids = dependents.get(path);
6415
+ if (kids != null) {
6416
+ for (const k of kids) {
6417
+ const childLongest = dfs(k);
6418
+ if (childLongest + 1 > best) best = childLongest + 1;
6419
+ }
6420
+ }
6421
+ color.set(path, BLACK);
6422
+ longestFrom.set(path, best);
6423
+ return best;
6424
+ };
6425
+ let depth = 0;
6426
+ for (const src of sources) {
6427
+ const d = dfs(src);
6428
+ if (d > depth) depth = d;
6429
+ }
6430
+ for (const p of paths) {
6431
+ if (color.get(p) === WHITE) dfs(p);
6432
+ }
6433
+ return {
6434
+ nodeCount: paths.length,
6435
+ edgeCount,
6436
+ subgraphCount: described.subgraphs.length,
6437
+ sources,
6438
+ sinks,
6439
+ depth,
6440
+ hasCycles
6441
+ };
6442
+ }
6443
+ function computeHealthReport(described) {
6444
+ const problems = [];
6445
+ for (const [path, desc] of Object.entries(described.nodes)) {
6446
+ if (desc.status !== "errored") continue;
6447
+ const entry = { path, status: "errored" };
6448
+ const upstream = reachable(described, path, "upstream", {});
6449
+ for (const p of upstream) {
6450
+ if (p === path) continue;
6451
+ if (described.nodes[p]?.status === "errored") {
6452
+ entry.upstreamCause = p;
6453
+ break;
6454
+ }
6455
+ }
6456
+ problems.push(entry);
6457
+ }
6458
+ problems.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
6459
+ return { ok: problems.length === 0, problems };
6460
+ }
6461
+ function topologyStatsEqual(a, b) {
6462
+ return a.nodeCount === b.nodeCount && a.edgeCount === b.edgeCount && a.subgraphCount === b.subgraphCount && a.depth === b.depth && a.hasCycles === b.hasCycles && stringArrayEqual(a.sources, b.sources) && stringArrayEqual(a.sinks, b.sinks);
6463
+ }
6464
+ function healthReportEqual(a, b) {
6465
+ if (a.ok !== b.ok) return false;
6466
+ if (a.problems.length !== b.problems.length) return false;
6467
+ for (let i = 0; i < a.problems.length; i++) {
6468
+ const x = a.problems[i];
6469
+ const y = b.problems[i];
6470
+ if (x.path !== y.path) return false;
6471
+ if (x.status !== y.status) return false;
6472
+ if (x.upstreamCause !== y.upstreamCause) return false;
6473
+ }
6474
+ return true;
6475
+ }
6476
+ function stringArrayEqual(a, b) {
6477
+ if (a.length !== b.length) return false;
6478
+ for (let i = 0; i < a.length; i++) {
6479
+ if (a[i] !== b[i]) return false;
6480
+ }
6481
+ return true;
6482
+ }
6483
+ var LensGraph = class extends Graph {
6484
+ /**
6485
+ * Aggregate structural stats — `nodeCount`, `edgeCount`, `sources`,
6486
+ * `sinks`, `depth`, `hasCycles`, `subgraphCount`. Recomputes on every
6487
+ * structural change via {@link watchTopologyTree} (transitive).
6488
+ *
6489
+ * Named `stats` (not `topology`) because `Graph.topology` already names
6490
+ * the raw `TopologyEvent` stream on every graph including `LensGraph`;
6491
+ * giving the lens its own `topology` accessor with an incompatible
6492
+ * `Node<TopologyStats>` type would break Liskov substitutability.
6493
+ */
6494
+ stats;
6495
+ health;
6496
+ /**
6497
+ * Per-path flow tracker — a live {@link ReactiveMapBundle} keyed by
6498
+ * qualified path. Use `.get(path)` / `.has(path)` / `.size` for O(1)
6499
+ * sync queries; subscribe to `.entries` for a reactive snapshot of the
6500
+ * whole map. Lazy — the snapshot is materialized only while `.entries`
6501
+ * has subscribers.
6502
+ *
6503
+ * Shape intentionally differs from `stats` / `health` (which are plain
6504
+ * `Node<Report>`) because `flow` is a keyed collection, not a single
6505
+ * aggregate value. The map shape exposes cheaper queries than any
6506
+ * snapshot-based design.
6507
+ */
6508
+ flow;
6509
+ _target;
6510
+ constructor(target, opts = {}) {
6511
+ super(opts.name ?? `${target.name}_lens`, opts.graph);
6512
+ this._target = target;
6513
+ let statsVersion = 0;
6514
+ let healthVersion = 0;
6515
+ const statsTick = state(0, { name: "stats_tick" });
6516
+ const healthTick = state(0, { name: "health_tick" });
6517
+ this.add("stats_tick", statsTick);
6518
+ this.add("health_tick", healthTick);
6519
+ const mapOpts = { name: "flow" };
6520
+ if (opts.maxFlowPaths != null) mapOpts.maxSize = opts.maxFlowPaths;
6521
+ this.flow = reactiveMap(mapOpts);
6522
+ this.add("flow", this.flow.entries);
6523
+ const pathFilter = opts.pathFilter;
6524
+ const offTopology = watchTopologyTree(target, (event, _emitter, prefix) => {
6525
+ statsVersion += 1;
6526
+ statsTick.emit(statsVersion);
6527
+ healthVersion += 1;
6528
+ healthTick.emit(healthVersion);
6529
+ if (event.kind === "removed") {
6530
+ if (event.nodeKind === "node") {
6531
+ const qp = `${prefix}${event.name}`;
6532
+ this.flow.delete(qp);
6533
+ } else {
6534
+ const mountPrefix = `${prefix}${event.name}::`;
6535
+ const keysToDelete = [];
6536
+ for (const relativePath of event.audit.nodes) {
6537
+ const qualified = relativePath === "" ? `${prefix}${event.name}` : `${mountPrefix}${relativePath}`;
6538
+ keysToDelete.push(qualified);
6539
+ }
6540
+ if (keysToDelete.length > 0) this.flow.deleteMany(keysToDelete);
6541
+ }
6542
+ }
6543
+ });
6544
+ this.addDisposer(offTopology);
6545
+ const observeHandle = target.observe({ timeline: true, structured: true });
6546
+ const offObserve = observeHandle.onEvent((event) => {
6547
+ const t = event.type;
6548
+ if (t === "error" || t === "complete" || t === "data" || t === "teardown") {
6549
+ healthVersion += 1;
6550
+ healthTick.emit(healthVersion);
6551
+ }
6552
+ if (t === "data") {
6553
+ const path = event.path ?? "";
6554
+ if (!path) return;
6555
+ if (pathFilter != null && !pathFilter(path)) return;
6556
+ const existing = this.flow.get(path);
6557
+ const count = existing != null ? existing.count + 1 : 1;
6558
+ this.flow.set(path, { path, count, lastUpdate_ns: monotonicNs() });
6559
+ }
6560
+ });
6561
+ this.addDisposer(() => {
6562
+ offObserve();
6563
+ observeHandle.dispose();
6564
+ });
6565
+ this.stats = derived(
6566
+ [statsTick],
6567
+ () => computeTopologyStats(target.describe({ detail: "minimal" })),
6568
+ {
6569
+ name: "stats",
6570
+ describeKind: "derived",
6571
+ equals: topologyStatsEqual,
6572
+ meta: lensMeta("stats")
6573
+ }
6574
+ );
6575
+ this.add("stats", this.stats);
6576
+ this.addDisposer(keepalive(this.stats));
6577
+ this.health = derived(
6578
+ [healthTick],
6579
+ () => computeHealthReport(target.describe({ detail: "standard" })),
6580
+ {
6581
+ name: "health",
6582
+ describeKind: "derived",
6583
+ equals: healthReportEqual,
6584
+ meta: lensMeta("health")
6585
+ }
6586
+ );
6587
+ this.add("health", this.health);
6588
+ this.addDisposer(keepalive(this.health));
6589
+ }
6590
+ /**
6591
+ * Live causal chain from `from` to `to`. Recomputes whenever the target
6592
+ * mutates. Disposed automatically when the lens is destroyed.
6593
+ *
6594
+ * **Lifetime note:** every call to `why()` registers a lens-owned disposer
6595
+ * that runs on `lens.destroy()`. The returned `dispose` function releases
6596
+ * the internal subscription but does NOT remove the lens-owned disposer —
6597
+ * so heavy calling (e.g. per render frame) accumulates no-op disposers
6598
+ * until lens teardown. Cache the returned handle for long-lived queries.
6599
+ *
6600
+ * @param from - Qualified path of the upstream endpoint.
6601
+ * @param to - Qualified path of the downstream endpoint.
6602
+ * @param opts - See {@link reactiveExplainPath}.
6603
+ */
6604
+ why(from, to, opts) {
6605
+ const handle = reactiveExplainPath(this._target, from, to, opts);
6606
+ this.addDisposer(handle.dispose);
6607
+ return handle;
6608
+ }
6609
+ /** Reference to the lensed graph. */
6610
+ get target() {
6611
+ return this._target;
6612
+ }
6613
+ };
6614
+ function graphLens(target, opts) {
6615
+ return new LensGraph(target, opts);
6616
+ }
6617
+
6618
+ // src/patterns/resilient-pipeline.ts
6619
+ var resilient_pipeline_exports = {};
6620
+ __export(resilient_pipeline_exports, {
6621
+ NS_PER_MS: () => NS_PER_MS,
6622
+ NS_PER_SEC: () => NS_PER_SEC,
6623
+ resilientPipeline: () => resilientPipeline
6624
+ });
6625
+ function resilientPipeline(source, opts = {}) {
6626
+ let current = source;
6627
+ if (opts.rateLimit != null) {
6628
+ current = rateLimiter(current, opts.rateLimit);
6629
+ }
6630
+ if (opts.budget != null && opts.budget.length > 0) {
6631
+ current = budgetGate(current, opts.budget);
6632
+ }
6633
+ let breakerState;
6634
+ if (opts.breaker != null) {
6635
+ const breaker = circuitBreaker(opts.breaker);
6636
+ const onOpen = opts.breakerOnOpen ?? "skip";
6637
+ const wrapped = withBreaker(breaker, { onOpen })(current);
6638
+ current = wrapped.node;
6639
+ breakerState = wrapped.breakerState;
6640
+ }
6641
+ if (opts.timeoutMs != null) {
6642
+ if (opts.timeoutMs <= 0) throw new RangeError("timeoutMs must be > 0");
6643
+ if (opts.timeoutMs > 9e6) {
6644
+ throw new RangeError(
6645
+ "timeoutMs must be <= 9_000_000 (\u22482.5h) to stay within safe ns arithmetic"
6646
+ );
6647
+ }
6648
+ current = timeout(current, opts.timeoutMs * NS_PER_MS);
6649
+ }
6650
+ if (opts.retry != null) {
6651
+ current = retry(current, opts.retry);
6652
+ }
6653
+ if (opts.fallback !== void 0) {
6654
+ current = fallback(current, opts.fallback);
6655
+ }
6656
+ const withStatusBundle = withStatus(current, { initialStatus: opts.initialStatus ?? "pending" });
6657
+ return {
6658
+ node: withStatusBundle.node,
6659
+ status: withStatusBundle.status,
6660
+ error: withStatusBundle.error,
6661
+ breakerState
6662
+ };
6663
+ }
6664
+
6665
+ // src/patterns/surface/index.ts
6666
+ var surface_exports = {};
6667
+ __export(surface_exports, {
6668
+ SNAPSHOT_WIRE_VERSION: () => SNAPSHOT_WIRE_VERSION,
6669
+ SurfaceError: () => SurfaceError,
6670
+ asSurfaceError: () => asSurfaceError,
6671
+ createGraph: () => createGraph,
6672
+ deleteSnapshot: () => deleteSnapshot,
6673
+ diffSnapshots: () => diffSnapshots,
6674
+ listSnapshots: () => listSnapshots,
6675
+ restoreSnapshot: () => restoreSnapshot,
6676
+ runReduction: () => runReduction,
6677
+ saveSnapshot: () => saveSnapshot
6678
+ });
6679
+
6680
+ // src/patterns/surface/errors.ts
6681
+ var SurfaceError = class extends Error {
6682
+ code;
6683
+ details;
6684
+ constructor(code, message, details) {
6685
+ super(message);
6686
+ this.name = "SurfaceError";
6687
+ this.code = code;
6688
+ if (details !== void 0) this.details = details;
6689
+ }
6690
+ /**
6691
+ * JSON-safe payload for wire serialization. Defensively validates
6692
+ * `details` — if it can't be round-tripped through `JSON.stringify`
6693
+ * (cyclic refs, `BigInt`, `Error` instance not pre-toJSON'd), the
6694
+ * payload falls back to `{code, message}` only rather than crashing
6695
+ * the MCP/CLI wrapper when it serializes this error onto the wire.
6696
+ */
6697
+ toJSON() {
6698
+ const out = { code: this.code, message: this.message };
6699
+ if (this.details !== void 0) {
6700
+ const safe = safeDetails(this.details);
6701
+ if (safe !== void 0) out.details = safe;
6702
+ }
6703
+ return out;
6704
+ }
6705
+ };
6706
+ function safeDetails(details) {
6707
+ try {
6708
+ return JSON.parse(JSON.stringify(details));
6709
+ } catch {
6710
+ return void 0;
6711
+ }
6712
+ }
6713
+ function asSurfaceError(err, fallbackCode = "internal-error") {
6714
+ if (err instanceof SurfaceError) return err;
6715
+ const message = err instanceof Error ? err.message : String(err);
6716
+ return new SurfaceError(fallbackCode, message);
6717
+ }
6718
+
6719
+ // src/patterns/surface/create.ts
6720
+ function createGraph(spec, opts) {
6721
+ const structural = validateSpec(spec);
6722
+ if (!structural.valid) {
6723
+ throw new SurfaceError(
6724
+ "invalid-spec",
6725
+ `GraphSpec validation failed:
6726
+ ${structural.errors.join("\n")}`,
6727
+ { errors: structural.errors }
6728
+ );
6729
+ }
6730
+ const catalog = opts?.catalog ?? {};
6731
+ const catalogValidation = validateSpecAgainstCatalog(spec, catalog);
6732
+ if (!catalogValidation.valid) {
6733
+ throw new SurfaceError(
6734
+ "catalog-error",
6735
+ `Catalog validation failed:
6736
+ ${catalogValidation.errors.join("\n")}`,
6737
+ { errors: catalogValidation.errors }
6738
+ );
6739
+ }
6740
+ try {
6741
+ return compileSpec(spec, opts);
6742
+ } catch (err) {
6743
+ const message = err instanceof Error ? err.message : String(err);
6744
+ throw new SurfaceError("catalog-error", message);
6745
+ }
6746
+ }
6747
+
6748
+ // src/patterns/surface/reduce.ts
6749
+ var DEFAULT_TIMEOUT_MS2 = 3e4;
6750
+ async function runReduction(spec, input, opts) {
6751
+ const inputPath = opts?.inputPath ?? "input";
6752
+ const outputPath = opts?.outputPath ?? "output";
6753
+ const timeoutMs = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
6754
+ const graph = createGraph(spec, { catalog: opts?.catalog });
6755
+ let outputNode;
6756
+ try {
6757
+ outputNode = graph.resolve(outputPath);
6758
+ } catch {
6759
+ graph.destroy();
6760
+ throw new SurfaceError(
6761
+ "node-not-found",
6762
+ `reduce: output path "${outputPath}" is not registered`,
6763
+ { path: outputPath }
6764
+ );
6765
+ }
6766
+ try {
6767
+ graph.resolve(inputPath);
6768
+ } catch {
6769
+ graph.destroy();
6770
+ throw new SurfaceError(
6771
+ "node-not-found",
6772
+ `reduce: input path "${inputPath}" is not registered`,
6773
+ { path: inputPath }
6774
+ );
6775
+ }
6776
+ try {
6777
+ return await new Promise((resolve, reject) => {
6778
+ let primed = false;
6779
+ let settled = false;
6780
+ let timer;
6781
+ let unsub;
6782
+ let shouldUnsub = false;
6783
+ const finish = (action) => {
6784
+ if (settled) return;
6785
+ settled = true;
6786
+ if (timer !== void 0) clearTimeout(timer);
6787
+ if (unsub !== void 0) {
6788
+ unsub();
6789
+ unsub = void 0;
6790
+ } else {
6791
+ shouldUnsub = true;
6792
+ }
6793
+ action();
6794
+ };
6795
+ unsub = outputNode.subscribe((msgs) => {
6796
+ for (const m of msgs) {
6797
+ if (settled) return;
6798
+ if (!primed) continue;
6799
+ if (m[0] === DATA) {
6800
+ finish(() => resolve(m[1]));
6801
+ return;
6802
+ }
6803
+ if (m[0] === RESOLVED) {
6804
+ const cached2 = outputNode.cache;
6805
+ finish(() => resolve(cached2));
6806
+ return;
6807
+ }
6808
+ if (m[0] === ERROR) {
6809
+ const payload = m[1];
6810
+ const message = payload instanceof Error ? payload.message : String(payload);
6811
+ const cause = payload instanceof Error ? payload : void 0;
6812
+ finish(
6813
+ () => reject(
6814
+ new SurfaceError(
6815
+ "internal-error",
6816
+ `reduce: output emitted ERROR: ${message}`,
6817
+ cause != null ? { cause } : void 0
6818
+ )
6819
+ )
6820
+ );
6821
+ return;
6822
+ }
6823
+ if (m[0] === COMPLETE) {
6824
+ finish(
6825
+ () => reject(
6826
+ new SurfaceError(
6827
+ "internal-error",
6828
+ `reduce: output COMPLETEd without a post-push DATA`
6829
+ )
6830
+ )
6831
+ );
6832
+ return;
6833
+ }
6834
+ }
6835
+ });
6836
+ if (shouldUnsub) {
6837
+ unsub?.();
6838
+ unsub = void 0;
6839
+ }
6840
+ primed = true;
6841
+ try {
6842
+ graph.set(inputPath, input);
6843
+ } catch (err) {
6844
+ const message = err instanceof Error ? err.message : String(err);
6845
+ const cause = err instanceof Error ? err : void 0;
6846
+ finish(
6847
+ () => reject(
6848
+ new SurfaceError(
6849
+ "internal-error",
6850
+ `reduce: failed to set input on "${inputPath}": ${message}`,
6851
+ cause != null ? { path: inputPath, cause } : { path: inputPath }
6852
+ )
6853
+ )
6854
+ );
6855
+ return;
6856
+ }
6857
+ if (!settled && Number.isFinite(timeoutMs) && timeoutMs > 0) {
6858
+ timer = setTimeout(() => {
6859
+ finish(
6860
+ () => reject(
6861
+ new SurfaceError(
6862
+ "reduce-timeout",
6863
+ `reduce: no output emitted within ${timeoutMs}ms`,
6864
+ { timeoutMs, outputPath }
6865
+ )
6866
+ )
6867
+ );
6868
+ }, timeoutMs);
6869
+ timer.unref?.();
6870
+ }
6871
+ });
6872
+ } finally {
6873
+ graph.destroy();
6874
+ }
6875
+ }
6876
+
6877
+ // src/patterns/surface/snapshot.ts
6878
+ var SNAPSHOT_WIRE_VERSION = SNAPSHOT_VERSION;
6879
+ function unwrapCheckpoint(raw, snapshotId) {
6880
+ if (raw == null || typeof raw !== "object") {
6881
+ throw new SurfaceError("snapshot-not-found", `snapshot "${snapshotId}" not found in tier`, {
6882
+ snapshotId
6883
+ });
6884
+ }
6885
+ const record = raw;
6886
+ if ("mode" in record) {
6887
+ if (record.mode === "full" && "snapshot" in record) {
6888
+ return record.snapshot;
6889
+ }
6890
+ if (record.mode === "diff") {
6891
+ throw new SurfaceError(
6892
+ "restore-failed",
6893
+ `snapshot "${snapshotId}" is a diff record; restore the baseline and replay WAL instead`,
6894
+ { snapshotId, mode: "diff" }
6895
+ );
6896
+ }
6897
+ throw new SurfaceError(
6898
+ "restore-failed",
6899
+ `snapshot "${snapshotId}" has unknown mode "${String(record.mode)}"`,
6900
+ { snapshotId, mode: String(record.mode) }
6901
+ );
6902
+ }
6903
+ if ("nodes" in record && "edges" in record && "subgraphs" in record && "name" in record) {
6904
+ return record;
6905
+ }
6906
+ throw new SurfaceError(
6907
+ "restore-failed",
6908
+ `snapshot "${snapshotId}" payload is not a GraphCheckpointRecord or GraphPersistSnapshot`,
6909
+ { snapshotId }
6910
+ );
6911
+ }
6912
+ async function saveSnapshot(graph, snapshotId, tier) {
6913
+ let snapshot;
6914
+ try {
6915
+ snapshot = graph.snapshot();
6916
+ } catch (err) {
6917
+ const message = err instanceof Error ? err.message : String(err);
6918
+ throw new SurfaceError(
6919
+ "snapshot-failed",
6920
+ `snapshot "${snapshotId}" serialization failed: ${message}`,
6921
+ { snapshotId }
6922
+ );
6923
+ }
6924
+ const record = {
6925
+ mode: "full",
6926
+ seq: 0,
6927
+ timestamp_ns: wallClockNs(),
6928
+ format_version: SNAPSHOT_WIRE_VERSION,
6929
+ snapshot
6930
+ };
6931
+ try {
6932
+ await tier.save(snapshotId, record);
6933
+ } catch (err) {
6934
+ const message = err instanceof Error ? err.message : String(err);
6935
+ throw new SurfaceError("snapshot-failed", `snapshot "${snapshotId}" save failed: ${message}`, {
6936
+ snapshotId
6937
+ });
6938
+ }
6939
+ return { snapshotId, timestamp_ns: record.timestamp_ns };
6940
+ }
6941
+ async function restoreSnapshot(snapshotId, tier, opts) {
6942
+ const raw = await tier.load(snapshotId);
6943
+ const snapshot = unwrapCheckpoint(raw, snapshotId);
6944
+ try {
6945
+ return Graph.fromSnapshot(
6946
+ snapshot,
6947
+ opts?.factories ? { factories: opts.factories } : void 0
6948
+ );
6949
+ } catch (err) {
6950
+ const message = err instanceof Error ? err.message : String(err);
6951
+ throw new SurfaceError(
6952
+ "restore-failed",
6953
+ `snapshot "${snapshotId}" restore failed: ${message}`,
6954
+ {
6955
+ snapshotId
6956
+ }
6957
+ );
6958
+ }
6959
+ }
6960
+ async function diffSnapshots(snapshotIdA, snapshotIdB, tier) {
6961
+ const [rawA, rawB] = await Promise.all([tier.load(snapshotIdA), tier.load(snapshotIdB)]);
6962
+ const snapshotA = unwrapCheckpoint(rawA, snapshotIdA);
6963
+ const snapshotB = unwrapCheckpoint(rawB, snapshotIdB);
6964
+ return Graph.diff(snapshotA, snapshotB);
6965
+ }
6966
+ async function listSnapshots(tier) {
6967
+ if (typeof tier.list !== "function") {
6968
+ throw new SurfaceError(
6969
+ "tier-no-list",
6970
+ "StorageTier does not implement list(); wrap the tier with an enumerator or use a different backend"
6971
+ );
6972
+ }
6973
+ return tier.list();
6974
+ }
6975
+ async function deleteSnapshot(snapshotId, tier) {
6976
+ if (typeof tier.clear !== "function") {
6977
+ throw new SurfaceError(
6978
+ "snapshot-failed",
6979
+ `StorageTier is append-only (no clear()); cannot delete "${snapshotId}"`,
6980
+ { snapshotId }
6981
+ );
6982
+ }
6983
+ try {
6984
+ await tier.clear(snapshotId);
6985
+ } catch (err) {
6986
+ const message = err instanceof Error ? err.message : String(err);
6987
+ throw new SurfaceError(
6988
+ "snapshot-failed",
6989
+ `snapshot "${snapshotId}" delete failed: ${message}`,
6990
+ {
6991
+ snapshotId
6992
+ }
6993
+ );
6994
+ }
6995
+ }
6996
+
6984
6997
  // src/index.ts
6985
6998
  var version = "0.0.0";
6986
6999
  export {
@@ -7020,15 +7033,20 @@ export {
7020
7033
  ResettableTimer,
7021
7034
  OVERHEAD as SIZEOF_OVERHEAD,
7022
7035
  SIZEOF_SYMBOL,
7036
+ SNAPSHOT_VERSION,
7037
+ SNAPSHOT_WIRE_VERSION,
7023
7038
  START,
7024
7039
  START_MSG,
7040
+ SurfaceError,
7025
7041
  TEARDOWN,
7026
7042
  TEARDOWN_MSG,
7027
7043
  TEARDOWN_ONLY_BATCH,
7028
7044
  TimeoutError,
7029
7045
  accessHintForGuard,
7046
+ audit_exports as accountability,
7030
7047
  advanceVersion,
7031
7048
  ai_exports as ai,
7049
+ asSurfaceError,
7032
7050
  audit,
7033
7051
  autoTrackNode,
7034
7052
  batch,
@@ -7052,6 +7070,7 @@ export {
7052
7070
  cqrs_exports as cqrs,
7053
7071
  createDagCborCodec,
7054
7072
  createDagCborZstdCodec,
7073
+ createGraph,
7055
7074
  createTransport,
7056
7075
  createVersioning,
7057
7076
  createWatermarkController,
@@ -7063,11 +7082,13 @@ export {
7063
7082
  defaultConfig,
7064
7083
  defaultHash,
7065
7084
  delay,
7085
+ deleteSnapshot,
7066
7086
  demo_shell_exports as demoShell,
7067
7087
  derived,
7068
7088
  deserializeError,
7069
7089
  dictStorage,
7070
7090
  diffForWAL,
7091
+ diffSnapshots,
7071
7092
  distill,
7072
7093
  distinctUntilChanged,
7073
7094
  domain_templates_exports as domainTemplates,
@@ -7079,6 +7100,7 @@ export {
7079
7100
  encodeEnvelope,
7080
7101
  escapeRegexChar,
7081
7102
  exhaustMap,
7103
+ explainPath,
7082
7104
  exponential,
7083
7105
  externalBundle,
7084
7106
  externalProducer,
@@ -7119,6 +7141,7 @@ export {
7119
7141
  fromPromise,
7120
7142
  fromPulsar,
7121
7143
  fromRabbitMQ,
7144
+ fromRaf,
7122
7145
  fromRedisStream,
7123
7146
  fromSSE,
7124
7147
  fromSqlite,
@@ -7133,6 +7156,7 @@ export {
7133
7156
  graph_exports as graph,
7134
7157
  graphProfile,
7135
7158
  graphspec_exports as graphspec,
7159
+ guarded_execution_exports as guarded,
7136
7160
  harness_exports as harness,
7137
7161
  indexedDbStorage,
7138
7162
  interval,
@@ -7142,7 +7166,9 @@ export {
7142
7166
  keepalive,
7143
7167
  last,
7144
7168
  reactive_layout_exports as layout,
7169
+ lens_exports as lens,
7145
7170
  linear,
7171
+ listSnapshots,
7146
7172
  lru,
7147
7173
  map,
7148
7174
  matchesAnyPattern,
@@ -7192,11 +7218,15 @@ export {
7192
7218
  replay,
7193
7219
  replayWAL,
7194
7220
  rescue,
7221
+ resilient_pipeline_exports as resilientPipeline,
7195
7222
  resolveBackoffPreset,
7196
7223
  resolveDescribeFields,
7224
+ restoreSnapshot,
7197
7225
  retry,
7198
7226
  retrySource,
7227
+ runReduction,
7199
7228
  sample,
7229
+ saveSnapshot,
7200
7230
  scan,
7201
7231
  serializeError,
7202
7232
  share,
@@ -7208,6 +7238,7 @@ export {
7208
7238
  solid_exports as solid,
7209
7239
  sqliteStorage,
7210
7240
  state,
7241
+ surface_exports as surface,
7211
7242
  svelte_exports as svelte,
7212
7243
  switchMap,
7213
7244
  take,
@@ -7245,6 +7276,7 @@ export {
7245
7276
  version,
7246
7277
  vue_exports as vue,
7247
7278
  wallClockNs,
7279
+ watchTopologyTree,
7248
7280
  window,
7249
7281
  windowCount,
7250
7282
  windowTime,