@graphrefly/graphrefly 0.25.0 → 0.27.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 (231) hide show
  1. package/README.md +8 -0
  2. package/dist/ai-CaR_912Q.d.cts +1033 -0
  3. package/dist/ai-WlRltJV7.d.ts +1033 -0
  4. package/dist/audit-ClmqGOCx.d.cts +245 -0
  5. package/dist/audit-DRlSzBu9.d.ts +245 -0
  6. package/dist/{chunk-QOWVNWOC.js → chunk-3ZWCKRHX.js} +27 -25
  7. package/dist/{chunk-QOWVNWOC.js.map → chunk-3ZWCKRHX.js.map} +1 -1
  8. package/dist/chunk-APFNLIRG.js +62 -0
  9. package/dist/chunk-APFNLIRG.js.map +1 -0
  10. package/dist/chunk-AT5LKYNL.js +395 -0
  11. package/dist/chunk-AT5LKYNL.js.map +1 -0
  12. package/dist/{chunk-IAHGTNOZ.js → chunk-BQ6RQQFF.js} +351 -2095
  13. package/dist/chunk-BQ6RQQFF.js.map +1 -0
  14. package/dist/{chunk-L2GLW2U7.js → chunk-BVZYTZ5H.js} +9 -103
  15. package/dist/chunk-BVZYTZ5H.js.map +1 -0
  16. package/dist/{chunk-EVR6UFUV.js → chunk-DST5DKZS.js} +19 -15
  17. package/dist/{chunk-EVR6UFUV.js.map → chunk-DST5DKZS.js.map} +1 -1
  18. package/dist/{chunk-TKE3JGOH.js → chunk-GTE6PWRZ.js} +5 -692
  19. package/dist/chunk-GTE6PWRZ.js.map +1 -0
  20. package/dist/chunk-HXZEYDUR.js +94 -0
  21. package/dist/chunk-HXZEYDUR.js.map +1 -0
  22. package/dist/chunk-J22W6HV3.js +107 -0
  23. package/dist/chunk-J22W6HV3.js.map +1 -0
  24. package/dist/{chunk-PY4XCDLR.js → chunk-J2VBW3DZ.js} +6 -95
  25. package/dist/chunk-J2VBW3DZ.js.map +1 -0
  26. package/dist/{chunk-HWPIFSW2.js → chunk-JSCT3CR4.js} +6 -4
  27. package/dist/{chunk-HWPIFSW2.js.map → chunk-JSCT3CR4.js.map} +1 -1
  28. package/dist/chunk-JWBCY4NC.js +330 -0
  29. package/dist/chunk-JWBCY4NC.js.map +1 -0
  30. package/dist/chunk-K2AUJHVP.js +2251 -0
  31. package/dist/chunk-K2AUJHVP.js.map +1 -0
  32. package/dist/chunk-MJ2NKQQL.js +119 -0
  33. package/dist/chunk-MJ2NKQQL.js.map +1 -0
  34. package/dist/chunk-N6UR7YVY.js +198 -0
  35. package/dist/chunk-N6UR7YVY.js.map +1 -0
  36. package/dist/chunk-NC6S43JJ.js +456 -0
  37. package/dist/chunk-NC6S43JJ.js.map +1 -0
  38. package/dist/chunk-OFVJBJXR.js +98 -0
  39. package/dist/chunk-OFVJBJXR.js.map +1 -0
  40. package/dist/chunk-OHISZPOJ.js +97 -0
  41. package/dist/chunk-OHISZPOJ.js.map +1 -0
  42. package/dist/chunk-OU5CQKNW.js +102 -0
  43. package/dist/chunk-OU5CQKNW.js.map +1 -0
  44. package/dist/{chunk-XOFWRC73.js → chunk-PF7GRZMW.js} +316 -21
  45. package/dist/chunk-PF7GRZMW.js.map +1 -0
  46. package/dist/{chunk-5DJTTKX3.js → chunk-PHOUUNK7.js} +74 -111
  47. package/dist/chunk-PHOUUNK7.js.map +1 -0
  48. package/dist/chunk-RNHBMHKA.js +1665 -0
  49. package/dist/chunk-RNHBMHKA.js.map +1 -0
  50. package/dist/chunk-SX52TAR4.js +110 -0
  51. package/dist/chunk-SX52TAR4.js.map +1 -0
  52. package/dist/{chunk-H4RVA4VE.js → chunk-VYPWMZ6H.js} +2 -2
  53. package/dist/chunk-WBZOVTYK.js +171 -0
  54. package/dist/chunk-WBZOVTYK.js.map +1 -0
  55. package/dist/chunk-WKNUIZOY.js +354 -0
  56. package/dist/chunk-WKNUIZOY.js.map +1 -0
  57. package/dist/chunk-X3VMZYBT.js +713 -0
  58. package/dist/chunk-X3VMZYBT.js.map +1 -0
  59. package/dist/chunk-X5R3GL6H.js +525 -0
  60. package/dist/chunk-X5R3GL6H.js.map +1 -0
  61. package/dist/chunk-XGPU467M.js +136 -0
  62. package/dist/chunk-XGPU467M.js.map +1 -0
  63. package/dist/compat/index.cjs +7656 -0
  64. package/dist/compat/index.cjs.map +1 -0
  65. package/dist/compat/index.d.cts +18 -0
  66. package/dist/compat/index.d.ts +18 -0
  67. package/dist/compat/index.js +50 -0
  68. package/dist/compat/index.js.map +1 -0
  69. package/dist/compat/jotai/index.cjs +2048 -0
  70. package/dist/compat/jotai/index.cjs.map +1 -0
  71. package/dist/compat/jotai/index.d.cts +2 -0
  72. package/dist/compat/jotai/index.d.ts +2 -0
  73. package/dist/compat/jotai/index.js +9 -0
  74. package/dist/compat/jotai/index.js.map +1 -0
  75. package/dist/compat/nanostores/index.cjs +2175 -0
  76. package/dist/compat/nanostores/index.cjs.map +1 -0
  77. package/dist/compat/nanostores/index.d.cts +2 -0
  78. package/dist/compat/nanostores/index.d.ts +2 -0
  79. package/dist/compat/nanostores/index.js +23 -0
  80. package/dist/compat/nanostores/index.js.map +1 -0
  81. package/dist/compat/nestjs/index.cjs +350 -16
  82. package/dist/compat/nestjs/index.cjs.map +1 -1
  83. package/dist/compat/nestjs/index.d.cts +6 -6
  84. package/dist/compat/nestjs/index.d.ts +6 -6
  85. package/dist/compat/nestjs/index.js +11 -9
  86. package/dist/compat/react/index.cjs +141 -0
  87. package/dist/compat/react/index.cjs.map +1 -0
  88. package/dist/compat/react/index.d.cts +2 -0
  89. package/dist/compat/react/index.d.ts +2 -0
  90. package/dist/compat/react/index.js +12 -0
  91. package/dist/compat/react/index.js.map +1 -0
  92. package/dist/compat/solid/index.cjs +128 -0
  93. package/dist/compat/solid/index.cjs.map +1 -0
  94. package/dist/compat/solid/index.d.cts +2 -0
  95. package/dist/compat/solid/index.d.ts +2 -0
  96. package/dist/compat/solid/index.js +12 -0
  97. package/dist/compat/solid/index.js.map +1 -0
  98. package/dist/compat/svelte/index.cjs +131 -0
  99. package/dist/compat/svelte/index.cjs.map +1 -0
  100. package/dist/compat/svelte/index.d.cts +2 -0
  101. package/dist/compat/svelte/index.d.ts +2 -0
  102. package/dist/compat/svelte/index.js +12 -0
  103. package/dist/compat/svelte/index.js.map +1 -0
  104. package/dist/compat/vue/index.cjs +146 -0
  105. package/dist/compat/vue/index.cjs.map +1 -0
  106. package/dist/compat/vue/index.d.cts +3 -0
  107. package/dist/compat/vue/index.d.ts +3 -0
  108. package/dist/compat/vue/index.js +12 -0
  109. package/dist/compat/vue/index.js.map +1 -0
  110. package/dist/compat/zustand/index.cjs +4931 -0
  111. package/dist/compat/zustand/index.cjs.map +1 -0
  112. package/dist/compat/zustand/index.d.cts +5 -0
  113. package/dist/compat/zustand/index.d.ts +5 -0
  114. package/dist/compat/zustand/index.js +12 -0
  115. package/dist/compat/zustand/index.js.map +1 -0
  116. package/dist/composite-C7PcQvcs.d.cts +303 -0
  117. package/dist/composite-aUCvjZVR.d.ts +303 -0
  118. package/dist/core/index.cjs +53 -4
  119. package/dist/core/index.cjs.map +1 -1
  120. package/dist/core/index.d.cts +4 -3
  121. package/dist/core/index.d.ts +4 -3
  122. package/dist/core/index.js +26 -24
  123. package/dist/demo-shell-BDkOptd6.d.ts +102 -0
  124. package/dist/demo-shell-Crid1WdR.d.cts +102 -0
  125. package/dist/extra/index.cjs +222 -110
  126. package/dist/extra/index.cjs.map +1 -1
  127. package/dist/extra/index.d.cts +6 -4
  128. package/dist/extra/index.d.ts +6 -4
  129. package/dist/extra/index.js +72 -65
  130. package/dist/extra/sources.cjs +2486 -0
  131. package/dist/extra/sources.cjs.map +1 -0
  132. package/dist/extra/sources.d.cts +465 -0
  133. package/dist/extra/sources.d.ts +465 -0
  134. package/dist/extra/sources.js +57 -0
  135. package/dist/extra/sources.js.map +1 -0
  136. package/dist/graph/index.cjs +408 -14
  137. package/dist/graph/index.cjs.map +1 -1
  138. package/dist/graph/index.d.cts +5 -5
  139. package/dist/graph/index.d.ts +5 -5
  140. package/dist/graph/index.js +13 -5
  141. package/dist/{graph-D-3JIQme.d.cts → graph-CCwGKLCm.d.ts} +195 -4
  142. package/dist/{graph-B6NFqv3z.d.ts → graph-DNCrvZSn.d.cts} +195 -4
  143. package/dist/index-3lsddbbS.d.ts +86 -0
  144. package/dist/index-B1tloyhO.d.cts +34 -0
  145. package/dist/{index-CYkjxu3s.d.ts → index-B6D3QNSA.d.ts} +33 -4
  146. package/dist/index-B6EhDnjH.d.cts +37 -0
  147. package/dist/index-B9B7_HEY.d.ts +37 -0
  148. package/dist/{index-Ds23Wvou.d.ts → index-BHlKbUwO.d.cts} +131 -883
  149. package/dist/{index-DiobMNwE.d.ts → index-BPVt8kqc.d.ts} +3 -3
  150. package/dist/index-BaSM3aYt.d.ts +195 -0
  151. package/dist/index-BuEoe-Qu.d.ts +121 -0
  152. package/dist/{index-Ch0IpIO0.d.cts → index-BwfLUNw4.d.ts} +131 -883
  153. package/dist/index-ByQxazQJ.d.cts +86 -0
  154. package/dist/index-C0svESO4.d.ts +127 -0
  155. package/dist/{index-OXImXMq6.d.ts → index-C8oil6M6.d.ts} +18 -196
  156. package/dist/{index-DKE1EATr.d.cts → index-CI3DprxP.d.cts} +18 -196
  157. package/dist/{index-AMWewNDe.d.cts → index-CO8uBlUh.d.cts} +33 -4
  158. package/dist/index-CxFrXH4m.d.ts +45 -0
  159. package/dist/index-D8wS_PeY.d.cts +121 -0
  160. package/dist/index-DO_6JN9Z.d.cts +127 -0
  161. package/dist/index-DVGiGFGT.d.cts +195 -0
  162. package/dist/index-DYme44FM.d.cts +44 -0
  163. package/dist/{index-J7Kc0oIQ.d.cts → index-DlLp-2Xn.d.cts} +3 -3
  164. package/dist/index-Dzk2hrlR.d.ts +44 -0
  165. package/dist/index-VHqptjhu.d.cts +45 -0
  166. package/dist/index-VdHQMPy1.d.ts +36 -0
  167. package/dist/index-Xi3u0HCQ.d.cts +36 -0
  168. package/dist/index-wEn0eFe8.d.ts +34 -0
  169. package/dist/index.cjs +1780 -176
  170. package/dist/index.cjs.map +1 -1
  171. package/dist/index.d.cts +784 -2082
  172. package/dist/index.d.ts +784 -2082
  173. package/dist/index.js +955 -4349
  174. package/dist/index.js.map +1 -1
  175. package/dist/memory-C6Z2tGpC.d.cts +139 -0
  176. package/dist/memory-li6FL5RM.d.ts +139 -0
  177. package/dist/messaging-Gt4LPbyA.d.cts +269 -0
  178. package/dist/messaging-XDoYablx.d.ts +269 -0
  179. package/dist/{meta-DWbkoq1s.d.cts → meta-BxCA7rcr.d.cts} +1 -1
  180. package/dist/{meta-CnkLA_43.d.ts → meta-CbznRPYJ.d.ts} +1 -1
  181. package/dist/{node-B-f-Lu-k.d.cts → node-BmerH3kS.d.cts} +26 -1
  182. package/dist/{node-B-f-Lu-k.d.ts → node-BmerH3kS.d.ts} +26 -1
  183. package/dist/{observable-uP-wy_uK.d.ts → observable-BgGUwcqp.d.ts} +1 -1
  184. package/dist/{observable-DBnrwcar.d.cts → observable-DJt_AxzQ.d.cts} +1 -1
  185. package/dist/patterns/ai.cjs +7930 -0
  186. package/dist/patterns/ai.cjs.map +1 -0
  187. package/dist/patterns/ai.d.cts +10 -0
  188. package/dist/patterns/ai.d.ts +10 -0
  189. package/dist/patterns/ai.js +71 -0
  190. package/dist/patterns/ai.js.map +1 -0
  191. package/dist/patterns/audit.cjs +5805 -0
  192. package/dist/patterns/audit.cjs.map +1 -0
  193. package/dist/patterns/audit.d.cts +6 -0
  194. package/dist/patterns/audit.d.ts +6 -0
  195. package/dist/patterns/audit.js +29 -0
  196. package/dist/patterns/audit.js.map +1 -0
  197. package/dist/patterns/demo-shell.cjs +5604 -0
  198. package/dist/patterns/demo-shell.cjs.map +1 -0
  199. package/dist/patterns/demo-shell.d.cts +6 -0
  200. package/dist/patterns/demo-shell.d.ts +6 -0
  201. package/dist/patterns/demo-shell.js +15 -0
  202. package/dist/patterns/demo-shell.js.map +1 -0
  203. package/dist/patterns/memory.cjs +5283 -0
  204. package/dist/patterns/memory.cjs.map +1 -0
  205. package/dist/patterns/memory.d.cts +5 -0
  206. package/dist/patterns/memory.d.ts +5 -0
  207. package/dist/patterns/memory.js +20 -0
  208. package/dist/patterns/memory.js.map +1 -0
  209. package/dist/patterns/reactive-layout/index.cjs +355 -13
  210. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  211. package/dist/patterns/reactive-layout/index.d.cts +6 -5
  212. package/dist/patterns/reactive-layout/index.d.ts +6 -5
  213. package/dist/patterns/reactive-layout/index.js +15 -12
  214. package/dist/reactive-layout-MQP--J3F.d.cts +183 -0
  215. package/dist/reactive-layout-u5Ulnqag.d.ts +183 -0
  216. package/dist/{storage-BuTdpCI1.d.cts → storage-CMjUUuxn.d.ts} +10 -2
  217. package/dist/{storage-F2X1U1x0.d.ts → storage-DdWlZo6U.d.cts} +10 -2
  218. package/dist/sugar-CCOxXK1e.d.ts +201 -0
  219. package/dist/sugar-D02n5JjF.d.cts +201 -0
  220. package/package.json +63 -3
  221. package/dist/chunk-5DJTTKX3.js.map +0 -1
  222. package/dist/chunk-IAHGTNOZ.js.map +0 -1
  223. package/dist/chunk-L2GLW2U7.js.map +0 -1
  224. package/dist/chunk-MW4VAKAO.js +0 -47
  225. package/dist/chunk-MW4VAKAO.js.map +0 -1
  226. package/dist/chunk-PY4XCDLR.js.map +0 -1
  227. package/dist/chunk-TKE3JGOH.js.map +0 -1
  228. package/dist/chunk-XOFWRC73.js.map +0 -1
  229. package/dist/index-BJB7t9gg.d.cts +0 -392
  230. package/dist/index-C-TXEa7C.d.ts +0 -392
  231. /package/dist/{chunk-H4RVA4VE.js.map → chunk-VYPWMZ6H.js.map} +0 -0
@@ -0,0 +1,198 @@
1
+ import {
2
+ batch,
3
+ dynamicNode,
4
+ state
5
+ } from "./chunk-PHOUUNK7.js";
6
+ import {
7
+ DATA,
8
+ ERROR,
9
+ __export
10
+ } from "./chunk-SX52TAR4.js";
11
+
12
+ // src/compat/nanostores/index.ts
13
+ var nanostores_exports = {};
14
+ __export(nanostores_exports, {
15
+ action: () => action,
16
+ atom: () => atom,
17
+ computed: () => computed,
18
+ getValue: () => getValue,
19
+ map: () => map,
20
+ onMount: () => onMount,
21
+ onStart: () => onStart,
22
+ onStop: () => onStop
23
+ });
24
+ var START_LISTENERS = /* @__PURE__ */ new WeakMap();
25
+ var STOP_LISTENERS = /* @__PURE__ */ new WeakMap();
26
+ function trigger(node, map2) {
27
+ const callbacks = map2.get(node);
28
+ if (callbacks) {
29
+ for (const cb of callbacks) cb();
30
+ }
31
+ }
32
+ function createStore(node, extra = {}) {
33
+ let listeners = 0;
34
+ const store = {
35
+ ...extra,
36
+ get: () => getVal(node),
37
+ subscribe: (cb) => {
38
+ if (listeners === 0) trigger(node, START_LISTENERS);
39
+ listeners++;
40
+ const sub = node.subscribe((msgs) => {
41
+ for (const [t, v] of msgs) {
42
+ if (t === DATA) cb(v);
43
+ }
44
+ });
45
+ return () => {
46
+ sub();
47
+ listeners--;
48
+ if (listeners === 0) trigger(node, STOP_LISTENERS);
49
+ };
50
+ },
51
+ listen: (cb) => {
52
+ if (listeners === 0) trigger(node, START_LISTENERS);
53
+ listeners++;
54
+ let initial = true;
55
+ const sub = node.subscribe((msgs) => {
56
+ for (const [t, v] of msgs) {
57
+ if (t === DATA) {
58
+ if (initial) {
59
+ initial = false;
60
+ continue;
61
+ }
62
+ cb(v);
63
+ }
64
+ }
65
+ });
66
+ return () => {
67
+ sub();
68
+ listeners--;
69
+ if (listeners === 0) trigger(node, STOP_LISTENERS);
70
+ };
71
+ },
72
+ _node: node
73
+ };
74
+ return store;
75
+ }
76
+ function pull(n) {
77
+ let val = n.cache;
78
+ let err;
79
+ const unsub = n.subscribe((msgs) => {
80
+ for (const [t, v] of msgs) {
81
+ if (t === DATA) val = v;
82
+ if (t === ERROR) err = v;
83
+ }
84
+ });
85
+ unsub();
86
+ if (err) throw err;
87
+ return val;
88
+ }
89
+ function getVal(n) {
90
+ if (n.status === "sentinel") {
91
+ return pull(n);
92
+ }
93
+ return n.cache;
94
+ }
95
+ function atom(initial) {
96
+ const n = state(initial, {
97
+ resubscribable: true,
98
+ resetOnTeardown: true
99
+ });
100
+ return createStore(n, {
101
+ // `n.emit` routes through the framed pipeline: `bundle()` auto-
102
+ // prefixes `[DIRTY]` (diamond-safe wave coordination) and the
103
+ // node's `equals` (default `Object.is`) folds same-value writes
104
+ // into `RESOLVED`. Matches nanostores' documented Object.is
105
+ // dedup semantics without any custom check.
106
+ set: (value) => n.emit(value)
107
+ });
108
+ }
109
+ function computed(stores, fn) {
110
+ const storeArray = Array.isArray(stores) ? stores : [stores];
111
+ const depNodes = storeArray.map((s) => s._node);
112
+ const n = dynamicNode(
113
+ depNodes,
114
+ (track) => {
115
+ const vals = storeArray.map((s) => {
116
+ const node = s._node;
117
+ if (node.status === "sentinel") {
118
+ pull(node);
119
+ }
120
+ return track(node);
121
+ });
122
+ return fn(...vals);
123
+ },
124
+ {
125
+ resubscribable: true,
126
+ resetOnTeardown: true,
127
+ equals: Object.is
128
+ }
129
+ );
130
+ return createStore(n);
131
+ }
132
+ function map(initial) {
133
+ const n = state(initial, {
134
+ resubscribable: true,
135
+ resetOnTeardown: true,
136
+ equals: () => false
137
+ });
138
+ return createStore(n, {
139
+ // `map`'s state node is configured with `equals: () => false`
140
+ // above, so every `emit` produces DATA (even for same-key same-
141
+ // value sets). The `emit` path is still required for diamond
142
+ // coordination (`[DIRTY]` auto-prefix via `bundle()`).
143
+ set: (value) => n.emit(value),
144
+ setKey: (key, value) => {
145
+ const current = getVal(n);
146
+ n.emit({ ...current, [key]: value });
147
+ }
148
+ });
149
+ }
150
+ function getValue(store) {
151
+ return store.get();
152
+ }
153
+ function onStart(store, cb) {
154
+ const node = store._node;
155
+ let callbacks = START_LISTENERS.get(node);
156
+ if (!callbacks) {
157
+ callbacks = /* @__PURE__ */ new Set();
158
+ START_LISTENERS.set(node, callbacks);
159
+ }
160
+ callbacks.add(cb);
161
+ }
162
+ function onStop(store, cb) {
163
+ const node = store._node;
164
+ let callbacks = STOP_LISTENERS.get(node);
165
+ if (!callbacks) {
166
+ callbacks = /* @__PURE__ */ new Set();
167
+ STOP_LISTENERS.set(node, callbacks);
168
+ }
169
+ callbacks.add(cb);
170
+ }
171
+ function onMount(store, cb) {
172
+ onStart(store, () => {
173
+ const stop = cb();
174
+ if (typeof stop === "function") onStop(store, stop);
175
+ });
176
+ }
177
+ function action(_store, _name, fn) {
178
+ return (...args) => {
179
+ let result;
180
+ batch(() => {
181
+ result = fn(...args);
182
+ });
183
+ return result;
184
+ };
185
+ }
186
+
187
+ export {
188
+ atom,
189
+ computed,
190
+ map,
191
+ getValue,
192
+ onStart,
193
+ onStop,
194
+ onMount,
195
+ action,
196
+ nanostores_exports
197
+ };
198
+ //# sourceMappingURL=chunk-N6UR7YVY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/compat/nanostores/index.ts"],"sourcesContent":["import { batch } from \"../../core/batch.js\";\nimport { DATA, ERROR, type Messages } from \"../../core/messages.js\";\nimport type { Node } from \"../../core/node.js\";\nimport { dynamicNode, state, type TrackFn } from \"../../core/sugar.js\";\n\n/**\n * A Nanostores-compatible atom.\n *\n * @category compat\n */\nexport interface NanoAtom<T> {\n\t/** Get current value. */\n\tget(): T;\n\t/** Set a new value (writable atoms only). */\n\tset(value: T): void;\n\t/** Subscribe to value changes. Callback receives the new value.\n\t * Returns unsubscribe function. Called immediately with current value. */\n\tsubscribe(cb: (value: T) => void): () => void;\n\t/** Listen to value changes (no immediate call). Returns unsubscribe. */\n\tlisten(cb: (value: T) => void): () => void;\n\t/** The underlying GraphReFly node. */\n\treadonly _node: Node<T>;\n}\n\n/**\n * A Nanostores-compatible computed store.\n *\n * @category compat\n */\nexport interface NanoComputed<T> {\n\t/** Get current value. */\n\tget(): T;\n\t/** Subscribe to value changes. Called immediately with current value.\n\t * Returns unsubscribe function. */\n\tsubscribe(cb: (value: T) => void): () => void;\n\t/** Listen to value changes (no immediate call). Returns unsubscribe. */\n\tlisten(cb: (value: T) => void): () => void;\n\t/** The underlying GraphReFly node. */\n\treadonly _node: Node<T>;\n}\n\n/**\n * A Nanostores-compatible map.\n *\n * @category compat\n */\nexport interface NanoMap<T extends Record<string, unknown>> extends NanoAtom<T> {\n\t/** Set a single key. */\n\tsetKey<K extends keyof T>(key: K, value: T[K]): void;\n}\n\nconst START_LISTENERS = new WeakMap<Node<any>, Set<() => void>>();\nconst STOP_LISTENERS = new WeakMap<Node<any>, Set<() => void>>();\n\nfunction trigger(node: Node<any>, map: WeakMap<Node<any>, Set<() => void>>) {\n\tconst callbacks = map.get(node);\n\tif (callbacks) {\n\t\tfor (const cb of callbacks) cb();\n\t}\n}\n\nfunction createStore<T>(node: Node<T>, extra: any = {}): any {\n\tlet listeners = 0;\n\tconst store = {\n\t\t...extra,\n\t\tget: () => getVal(node),\n\t\tsubscribe: (cb: (value: T) => void) => {\n\t\t\tif (listeners === 0) trigger(node, START_LISTENERS);\n\t\t\tlisteners++;\n\t\t\t// Push-on-subscribe delivers the initial value via DATA — no explicit cb() needed.\n\t\t\tconst sub = node.subscribe((msgs: Messages) => {\n\t\t\t\tfor (const [t, v] of msgs) {\n\t\t\t\t\tif (t === DATA) cb(v as T);\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tsub();\n\t\t\t\tlisteners--;\n\t\t\t\tif (listeners === 0) trigger(node, STOP_LISTENERS);\n\t\t\t};\n\t\t},\n\t\tlisten: (cb: (value: T) => void) => {\n\t\t\tif (listeners === 0) trigger(node, START_LISTENERS);\n\t\t\tlisteners++;\n\t\t\t// Skip the initial push-on-subscribe DATA — listen() fires on changes only.\n\t\t\tlet initial = true;\n\t\t\tconst sub = node.subscribe((msgs: Messages) => {\n\t\t\t\tfor (const [t, v] of msgs) {\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\tif (initial) {\n\t\t\t\t\t\t\tinitial = false;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcb(v as T);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tsub();\n\t\t\t\tlisteners--;\n\t\t\t\tif (listeners === 0) trigger(node, STOP_LISTENERS);\n\t\t\t};\n\t\t},\n\t\t_node: node,\n\t};\n\treturn store;\n}\n\nfunction pull<T>(n: Node<T>): T {\n\tlet val: T | undefined | null = n.cache;\n\tlet err: any;\n\tconst unsub = n.subscribe((msgs: Messages) => {\n\t\tfor (const [t, v] of msgs) {\n\t\t\tif (t === DATA) val = v as T;\n\t\t\tif (t === ERROR) err = v;\n\t\t}\n\t});\n\tunsub();\n\tif (err) throw err;\n\treturn val as T;\n}\n\nfunction getVal<T>(n: Node<T>): T {\n\tif (n.status === \"sentinel\") {\n\t\treturn pull(n);\n\t}\n\treturn n.cache as T;\n}\n\n/**\n * Creates a nanostores-compatible atom.\n *\n * @param initial - Initial value.\n * @returns `NanoAtom<T>`\n *\n * @category compat\n */\nexport function atom<T>(initial: T): NanoAtom<T> {\n\tconst n = state<T>(initial, {\n\t\tresubscribable: true,\n\t\tresetOnTeardown: true,\n\t});\n\n\treturn createStore(n, {\n\t\t// `n.emit` routes through the framed pipeline: `bundle()` auto-\n\t\t// prefixes `[DIRTY]` (diamond-safe wave coordination) and the\n\t\t// node's `equals` (default `Object.is`) folds same-value writes\n\t\t// into `RESOLVED`. Matches nanostores' documented Object.is\n\t\t// dedup semantics without any custom check.\n\t\tset: (value: T) => n.emit(value),\n\t});\n}\n\n/**\n * Creates a nanostores-compatible computed store.\n *\n * @param stores - One or more atoms/computed stores.\n * @param fn - Compute function.\n * @returns `NanoComputed<T>`\n *\n * @category compat\n */\nexport function computed<T, A>(\n\tstoreA: NanoAtom<A> | NanoComputed<A>,\n\tfn: (a: A) => T,\n): NanoComputed<T>;\nexport function computed<T, A, B>(\n\tstores: [NanoAtom<A> | NanoComputed<A>, NanoAtom<B> | NanoComputed<B>],\n\tfn: (a: A, b: B) => T,\n): NanoComputed<T>;\nexport function computed<T, A, B, C>(\n\tstores: [\n\t\tNanoAtom<A> | NanoComputed<A>,\n\t\tNanoAtom<B> | NanoComputed<B>,\n\t\tNanoAtom<C> | NanoComputed<C>,\n\t],\n\tfn: (a: A, b: B, c: C) => T,\n): NanoComputed<T>;\nexport function computed<T>(stores: any, fn: (...args: any[]) => T): NanoComputed<T> {\n\tconst storeArray: Array<NanoAtom<any> | NanoComputed<any>> = Array.isArray(stores)\n\t\t? stores\n\t\t: [stores];\n\n\tconst depNodes = storeArray.map((s) => s._node);\n\tconst n = dynamicNode(\n\t\tdepNodes,\n\t\t(track: TrackFn) => {\n\t\t\tconst vals = storeArray.map((s) => {\n\t\t\t\tconst node = s._node;\n\t\t\t\tif (node.status === \"sentinel\") {\n\t\t\t\t\tpull(node);\n\t\t\t\t}\n\t\t\t\treturn track(node);\n\t\t\t});\n\t\t\treturn fn(...vals);\n\t\t},\n\t\t{\n\t\t\tresubscribable: true,\n\t\t\tresetOnTeardown: true,\n\t\t\tequals: Object.is as any,\n\t\t},\n\t);\n\n\treturn createStore(n);\n}\n\n/**\n * Creates a nanostores-compatible map.\n *\n * @param initial - Initial object value.\n * @returns `NanoMap<T>`\n *\n * @category compat\n */\nexport function map<T extends Record<string, unknown>>(initial: T): NanoMap<T> {\n\tconst n = state<T>(initial, {\n\t\tresubscribable: true,\n\t\tresetOnTeardown: true,\n\t\tequals: () => false,\n\t});\n\n\treturn createStore(n, {\n\t\t// `map`'s state node is configured with `equals: () => false`\n\t\t// above, so every `emit` produces DATA (even for same-key same-\n\t\t// value sets). The `emit` path is still required for diamond\n\t\t// coordination (`[DIRTY]` auto-prefix via `bundle()`).\n\t\tset: (value: T) => n.emit(value),\n\t\tsetKey: <K extends keyof T>(key: K, value: T[K]) => {\n\t\t\tconst current = getVal(n);\n\t\t\tn.emit({ ...current, [key]: value });\n\t\t},\n\t});\n}\n\n/**\n * Returns the current value of the store.\n *\n * @category compat\n */\nexport function getValue<T>(store: NanoAtom<T> | NanoComputed<T>): T {\n\treturn store.get();\n}\n\n/**\n * Adds a listener for the store start (first listener connected).\n *\n * @category compat\n */\nexport function onStart(store: NanoAtom<any> | NanoComputed<any>, cb: () => void): void {\n\tconst node = store._node;\n\tlet callbacks = START_LISTENERS.get(node);\n\tif (!callbacks) {\n\t\tcallbacks = new Set();\n\t\tSTART_LISTENERS.set(node, callbacks);\n\t}\n\tcallbacks.add(cb);\n}\n\n/**\n * Adds a listener for the store stop (last listener disconnected).\n *\n * @category compat\n */\nexport function onStop(store: NanoAtom<any> | NanoComputed<any>, cb: () => void): void {\n\tconst node = store._node;\n\tlet callbacks = STOP_LISTENERS.get(node);\n\tif (!callbacks) {\n\t\tcallbacks = new Set();\n\t\tSTOP_LISTENERS.set(node, callbacks);\n\t}\n\tcallbacks.add(cb);\n}\n\n/**\n * Adds a listener for the store mount (first listener connected).\n *\n * @returns A cleanup function called when the last listener is removed.\n * @category compat\n */\nexport function onMount(\n\tstore: NanoAtom<any> | NanoComputed<any>,\n\tcb: () => (() => void) | undefined,\n): void {\n\tonStart(store, () => {\n\t\tconst stop = cb();\n\t\tif (typeof stop === \"function\") onStop(store, stop);\n\t});\n}\n\n/**\n * Batches multiple store updates.\n *\n * @category compat\n */\nexport function action<Args extends any[], Return>(\n\t_store: NanoAtom<any> | NanoComputed<any>,\n\t_name: string,\n\tfn: (...args: Args) => Return,\n): (...args: Args) => Return {\n\treturn (...args: Args) => {\n\t\tlet result: any;\n\t\tbatch(() => {\n\t\t\tresult = fn(...args);\n\t\t});\n\t\treturn result as Return;\n\t};\n}\n"],"mappings":"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","names":["map"]}
@@ -0,0 +1,456 @@
1
+ import {
2
+ TopicGraph
3
+ } from "./chunk-X5R3GL6H.js";
4
+ import {
5
+ domainMeta
6
+ } from "./chunk-JSCT3CR4.js";
7
+ import {
8
+ reactiveLog
9
+ } from "./chunk-J2VBW3DZ.js";
10
+ import {
11
+ keepalive
12
+ } from "./chunk-BVZYTZ5H.js";
13
+ import {
14
+ watchTopologyTree
15
+ } from "./chunk-OU5CQKNW.js";
16
+ import {
17
+ Graph
18
+ } from "./chunk-PF7GRZMW.js";
19
+ import {
20
+ NodeImpl,
21
+ defaultHash,
22
+ derived,
23
+ monotonicNs,
24
+ policyFromRules,
25
+ state,
26
+ wallClockNs
27
+ } from "./chunk-PHOUUNK7.js";
28
+ import {
29
+ DATA,
30
+ __export
31
+ } from "./chunk-SX52TAR4.js";
32
+
33
+ // src/patterns/audit.ts
34
+ var audit_exports = {};
35
+ __export(audit_exports, {
36
+ AuditTrailGraph: () => AuditTrailGraph,
37
+ PolicyEnforcerGraph: () => PolicyEnforcerGraph,
38
+ auditTrail: () => auditTrail,
39
+ complianceSnapshot: () => complianceSnapshot,
40
+ policyEnforcer: () => policyEnforcer,
41
+ reactiveExplainPath: () => reactiveExplainPath
42
+ });
43
+ function auditMeta(kind, extra) {
44
+ return domainMeta("audit", kind, extra);
45
+ }
46
+ var DEFAULT_INCLUDE_TYPES = /* @__PURE__ */ new Set([
47
+ "data",
48
+ "error",
49
+ "complete",
50
+ "teardown"
51
+ ]);
52
+ var AuditTrailGraph = class extends Graph {
53
+ entries;
54
+ count;
55
+ _log;
56
+ _target;
57
+ constructor(target, opts) {
58
+ super(opts.name ?? `${target.name}_audit`, opts.graph);
59
+ this._target = target;
60
+ this._log = reactiveLog([], {
61
+ name: "entries",
62
+ ...opts.maxSize != null ? { maxSize: opts.maxSize } : {}
63
+ });
64
+ this.entries = this._log.entries;
65
+ this.add("entries", this.entries);
66
+ this.count = derived(
67
+ [this.entries],
68
+ ([snapshot]) => snapshot.length,
69
+ { name: "count", describeKind: "derived", meta: auditMeta("count") }
70
+ );
71
+ this.add("count", this.count);
72
+ this.addDisposer(keepalive(this.count));
73
+ const includeTypes = opts.includeTypes != null ? new Set(opts.includeTypes) : DEFAULT_INCLUDE_TYPES;
74
+ const filter = opts.filter;
75
+ let seq = 0;
76
+ const handle = target.observe({ timeline: true, structured: true });
77
+ const offEvent = handle.onEvent((event) => {
78
+ if (event.type === "derived") return;
79
+ const type = event.type;
80
+ if (!includeTypes.has(type)) return;
81
+ const path = event.path ?? "";
82
+ const entry = {
83
+ seq: seq++,
84
+ timestamp_ns: event.timestamp_ns ?? monotonicNs(),
85
+ wall_clock_ns: wallClockNs(),
86
+ path,
87
+ type
88
+ };
89
+ const node = path ? safeNode(target, path) : void 0;
90
+ const lastMutation = node?.lastMutation;
91
+ if (lastMutation != null) entry.actor = lastMutation.actor;
92
+ if (type === "data") entry.value = event.data;
93
+ if (type === "error") entry.error = event.data;
94
+ const reason = path ? safeAnnotation(target, path) : void 0;
95
+ if (reason != null) entry.reason = reason;
96
+ if (filter != null && !filter(entry)) return;
97
+ this._log.append(entry);
98
+ });
99
+ this.addDisposer(() => {
100
+ offEvent();
101
+ handle.dispose();
102
+ });
103
+ this.addDisposer(() => this._log.disposeAllViews());
104
+ }
105
+ /** All entries currently in the ring (snapshot). */
106
+ all() {
107
+ return this.entries.cache ?? [];
108
+ }
109
+ /** Entries matching `path`. Order preserved. */
110
+ byNode(path) {
111
+ return this.all().filter((e) => e.path === path);
112
+ }
113
+ /** Entries whose `actor.id` matches. Use `byActorType` for type filtering. */
114
+ byActor(actorId) {
115
+ return this.all().filter((e) => e.actor?.id === actorId);
116
+ }
117
+ /** Entries whose `actor.type` matches (e.g. `"llm"`, `"human"`). */
118
+ byActorType(type) {
119
+ return this.all().filter((e) => e.actor?.type === type);
120
+ }
121
+ /**
122
+ * Entries with `timestamp_ns` in `[start_ns, end_ns)` (end exclusive).
123
+ * Omit `end_ns` to query open-ended.
124
+ */
125
+ byTimeRange(start_ns, end_ns) {
126
+ return this.all().filter((e) => {
127
+ if (e.timestamp_ns < start_ns) return false;
128
+ if (end_ns != null && e.timestamp_ns >= end_ns) return false;
129
+ return true;
130
+ });
131
+ }
132
+ /** Reference to the audited graph (escape hatch for tooling). */
133
+ get target() {
134
+ return this._target;
135
+ }
136
+ };
137
+ function auditTrail(target, opts = {}) {
138
+ return new AuditTrailGraph(target, opts);
139
+ }
140
+ var PolicyEnforcerGraph = class extends Graph {
141
+ policies;
142
+ violations;
143
+ violationCount;
144
+ _target;
145
+ _mode;
146
+ _currentGuard;
147
+ constructor(target, policies, opts) {
148
+ super(opts.name ?? `${target.name}_policy`, opts.graph);
149
+ this._target = target;
150
+ this._mode = opts.mode ?? "audit";
151
+ const policiesNode = isNode(policies) ? policies : state(policies, { name: "policies" });
152
+ this.policies = policiesNode;
153
+ this.add("policies", this.policies);
154
+ this.violations = new TopicGraph("violations", {
155
+ retainedLimit: opts.violationsLimit ?? 1e3
156
+ });
157
+ this.mount("violations", this.violations);
158
+ this.violationCount = derived(
159
+ [this.violations.events],
160
+ ([snapshot]) => snapshot.length,
161
+ {
162
+ name: "violationCount",
163
+ describeKind: "derived",
164
+ meta: auditMeta("policy_violation_count")
165
+ }
166
+ );
167
+ this.add("violationCount", this.violationCount);
168
+ this.addDisposer(keepalive(this.violationCount));
169
+ const initialRules = policiesNode.cache ?? [];
170
+ let latestRules = initialRules;
171
+ this._currentGuard = policyFromRules(latestRules);
172
+ const offPolicies = policiesNode.subscribe((msgs) => {
173
+ for (const m of msgs) {
174
+ if (m[0] === DATA) {
175
+ latestRules = m[1] ?? [];
176
+ this._currentGuard = policyFromRules(latestRules);
177
+ }
178
+ }
179
+ });
180
+ this.addDisposer(offPolicies);
181
+ const paths = opts.paths != null ? [...opts.paths] : collectPaths(target);
182
+ if (this._mode === "enforce") {
183
+ const restorers = /* @__PURE__ */ new Map();
184
+ const wrapAndPush = (path) => {
185
+ if (restorers.has(path)) return;
186
+ const node = safeNode(target, path);
187
+ if (!(node instanceof NodeImpl)) return;
188
+ const pathGuard = (actor, action) => {
189
+ const ok = this._currentGuard(actor, action);
190
+ if (!ok) {
191
+ this._publishViolation(actor, action, path, "blocked");
192
+ }
193
+ return ok;
194
+ };
195
+ restorers.set(path, node._pushGuard(pathGuard));
196
+ };
197
+ for (const path of paths) wrapAndPush(path);
198
+ if (opts.paths == null) {
199
+ const offTopology = watchTopologyTree(target, (event, emitter, prefix) => {
200
+ if (event.kind === "added") {
201
+ if (event.nodeKind === "node") {
202
+ wrapAndPush(`${prefix}${event.name}`);
203
+ } else {
204
+ const child = emitter._mounts.get(event.name);
205
+ if (!(child instanceof Graph)) return;
206
+ const mountPrefix = `${prefix}${event.name}::`;
207
+ const localPaths = collectPaths(child);
208
+ for (const localPath of localPaths) {
209
+ wrapAndPush(
210
+ localPath === "" ? `${prefix}${event.name}` : `${mountPrefix}${localPath}`
211
+ );
212
+ }
213
+ }
214
+ } else if (event.kind === "removed") {
215
+ if (event.nodeKind === "node") {
216
+ const qp = `${prefix}${event.name}`;
217
+ const r = restorers.get(qp);
218
+ if (r != null) {
219
+ r();
220
+ restorers.delete(qp);
221
+ }
222
+ } else {
223
+ const mountQp = `${prefix}${event.name}`;
224
+ const mountPrefix = `${mountQp}::`;
225
+ for (const [p, r] of restorers) {
226
+ if (p === mountQp || p.startsWith(mountPrefix)) {
227
+ r();
228
+ restorers.delete(p);
229
+ }
230
+ }
231
+ }
232
+ }
233
+ });
234
+ this.addDisposer(offTopology);
235
+ } else {
236
+ const offCleanup = target.topology.subscribe((msgs) => {
237
+ for (const m of msgs) {
238
+ if (m[0] !== DATA) continue;
239
+ const event = m[1];
240
+ if (event.kind !== "removed" || event.nodeKind !== "node") continue;
241
+ const r = restorers.get(event.name);
242
+ if (r != null) {
243
+ r();
244
+ restorers.delete(event.name);
245
+ }
246
+ }
247
+ });
248
+ this.addDisposer(offCleanup);
249
+ }
250
+ this.addDisposer(() => {
251
+ for (const r of restorers.values()) r();
252
+ restorers.clear();
253
+ });
254
+ } else {
255
+ const handle = target.observe({ timeline: true, structured: true });
256
+ const off = handle.onEvent((event) => {
257
+ if (event.type !== "data" && event.type !== "error") return;
258
+ const path = event.path ?? "";
259
+ if (!path) return;
260
+ if (opts.paths != null && !opts.paths.includes(path)) return;
261
+ const node = safeNode(target, path);
262
+ const lastMutation = node?.lastMutation;
263
+ if (lastMutation == null) return;
264
+ const action = "write";
265
+ if (this._currentGuard(lastMutation.actor, action)) return;
266
+ this._publishViolation(lastMutation.actor, action, path, "observed");
267
+ });
268
+ this.addDisposer(() => {
269
+ off();
270
+ handle.dispose();
271
+ });
272
+ }
273
+ }
274
+ _publishViolation(actor, action, path, result) {
275
+ this.violations.publish({
276
+ timestamp_ns: monotonicNs(),
277
+ wall_clock_ns: wallClockNs(),
278
+ path,
279
+ actor,
280
+ action,
281
+ mode: this._mode,
282
+ result
283
+ });
284
+ }
285
+ /** Snapshot of recorded violations. */
286
+ all() {
287
+ return this.violations.retained();
288
+ }
289
+ get mode() {
290
+ return this._mode;
291
+ }
292
+ get target() {
293
+ return this._target;
294
+ }
295
+ };
296
+ function policyEnforcer(target, policies, opts = {}) {
297
+ return new PolicyEnforcerGraph(target, policies, opts);
298
+ }
299
+ function reactiveExplainPath(target, from, to, opts) {
300
+ let v = 0;
301
+ const version = state(v, { name: "explain_version" });
302
+ const handle = target.observe({ timeline: true, structured: true });
303
+ const off = handle.onEvent((event) => {
304
+ const t = event.type;
305
+ if (t !== "data" && t !== "error" && t !== "complete" && t !== "teardown") return;
306
+ v += 1;
307
+ version.emit(v);
308
+ });
309
+ const explainOpts = {
310
+ ...opts?.maxDepth != null ? { maxDepth: opts.maxDepth } : {},
311
+ ...opts?.findCycle === true ? { findCycle: true } : {}
312
+ };
313
+ const node = derived([version], () => target.explain(from, to, explainOpts), {
314
+ name: opts?.name ?? "explain",
315
+ describeKind: "derived",
316
+ equals: (a, b) => a.found === b.found && a.reason === b.reason && a.steps.length === b.steps.length && causalStepsEqual(a.steps, b.steps),
317
+ meta: auditMeta("explain_path", { from, to })
318
+ });
319
+ const stopKeepalive = keepalive(node);
320
+ return {
321
+ node,
322
+ dispose() {
323
+ off();
324
+ handle.dispose();
325
+ stopKeepalive();
326
+ }
327
+ };
328
+ }
329
+ function causalStepsEqual(a, b) {
330
+ for (let i = 0; i < a.length; i++) {
331
+ const x = a[i];
332
+ const y = b[i];
333
+ if (x.path !== y.path) return false;
334
+ if (x.type !== y.type) return false;
335
+ if (x.status !== y.status) return false;
336
+ if (x.hop !== y.hop) return false;
337
+ if (x.dep_index !== y.dep_index) return false;
338
+ if (x.reason !== y.reason) return false;
339
+ if (x.value !== y.value) return false;
340
+ if (x.lastMutation !== y.lastMutation) return false;
341
+ const xv = x.v;
342
+ const yv = y.v;
343
+ if (xv !== yv) {
344
+ if (xv == null || yv == null) return false;
345
+ if (xv.id !== yv.id || xv.version !== yv.version) return false;
346
+ }
347
+ }
348
+ return true;
349
+ }
350
+ function complianceSnapshot(target, opts = {}) {
351
+ const result = {
352
+ format_version: 1,
353
+ timestamp_ns: monotonicNs(),
354
+ wall_clock_ns: wallClockNs(),
355
+ graph: target.snapshot()
356
+ };
357
+ if (opts.actor != null) result.actor = opts.actor;
358
+ if (opts.audit != null) {
359
+ const entries = [...opts.audit.all()];
360
+ result.audit = { count: entries.length, entries };
361
+ }
362
+ if (opts.policies != null) {
363
+ const rules = opts.policies.policies.cache ?? [];
364
+ result.policies = {
365
+ mode: opts.policies.mode,
366
+ rules,
367
+ violations: [...opts.policies.all()]
368
+ };
369
+ }
370
+ const fingerprint = computeFingerprint(result);
371
+ return { ...result, fingerprint };
372
+ }
373
+ function isNode(x) {
374
+ return typeof x === "object" && x !== null && "subscribe" in x;
375
+ }
376
+ function safeNode(target, path) {
377
+ try {
378
+ return target.node(path);
379
+ } catch {
380
+ return void 0;
381
+ }
382
+ }
383
+ function safeAnnotation(target, path) {
384
+ try {
385
+ return target.annotation(path);
386
+ } catch {
387
+ return void 0;
388
+ }
389
+ }
390
+ function collectPaths(target) {
391
+ const described = target.describe({ detail: "minimal" });
392
+ return Object.keys(described.nodes);
393
+ }
394
+ function computeFingerprint(value) {
395
+ return defaultHash(JSON.stringify(canonicalize(value)));
396
+ }
397
+ function canonicalize(value) {
398
+ const stack = /* @__PURE__ */ new Set();
399
+ const walk = (v) => {
400
+ if (v === void 0) return { __undefined: true };
401
+ if (v === null) return null;
402
+ const t = typeof v;
403
+ if (t === "bigint") return { __bigint: v.toString() };
404
+ if (t !== "object") return v;
405
+ const obj = v;
406
+ if (stack.has(obj)) return { __circular: true };
407
+ stack.add(obj);
408
+ try {
409
+ if (Array.isArray(obj)) {
410
+ return obj.map(walk);
411
+ }
412
+ if (obj instanceof Date) {
413
+ return { __date: obj.toISOString() };
414
+ }
415
+ if (obj instanceof RegExp) {
416
+ return { __regexp: { source: obj.source, flags: obj.flags } };
417
+ }
418
+ if (obj instanceof Map) {
419
+ const entries = [...obj.entries()].map(([k, mv]) => [
420
+ walk(k),
421
+ walk(mv)
422
+ ]);
423
+ return { __map: entries };
424
+ }
425
+ if (obj instanceof Set) {
426
+ const items = [...obj].map(walk);
427
+ return { __set: items };
428
+ }
429
+ if (ArrayBuffer.isView(obj)) {
430
+ const ta = obj;
431
+ const arr = new Array(ta.length);
432
+ for (let i = 0; i < ta.length; i++) arr[i] = ta[i] ?? 0;
433
+ return { __typed_array: { ctor: obj.constructor.name, data: arr } };
434
+ }
435
+ const out = {};
436
+ for (const k of Object.keys(obj).sort()) {
437
+ out[k] = walk(obj[k]);
438
+ }
439
+ return out;
440
+ } finally {
441
+ stack.delete(obj);
442
+ }
443
+ };
444
+ return walk(value);
445
+ }
446
+
447
+ export {
448
+ AuditTrailGraph,
449
+ auditTrail,
450
+ PolicyEnforcerGraph,
451
+ policyEnforcer,
452
+ reactiveExplainPath,
453
+ complianceSnapshot,
454
+ audit_exports
455
+ };
456
+ //# sourceMappingURL=chunk-NC6S43JJ.js.map