@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.
- package/README.md +8 -0
- package/dist/{chunk-QOWVNWOC.js → chunk-3ZWCKRHX.js} +27 -25
- package/dist/{chunk-QOWVNWOC.js.map → chunk-3ZWCKRHX.js.map} +1 -1
- package/dist/chunk-6LDQFTYS.js +102 -0
- package/dist/chunk-6LDQFTYS.js.map +1 -0
- package/dist/{chunk-5WGT55R4.js → chunk-AMCG74RZ.js} +195 -24
- package/dist/chunk-AMCG74RZ.js.map +1 -0
- package/dist/{chunk-AOCBDH4T.js → chunk-BVZYTZ5H.js} +76 -103
- package/dist/chunk-BVZYTZ5H.js.map +1 -0
- package/dist/chunk-FQMKGR6L.js +330 -0
- package/dist/chunk-FQMKGR6L.js.map +1 -0
- package/dist/chunk-HXZEYDUR.js +94 -0
- package/dist/chunk-HXZEYDUR.js.map +1 -0
- package/dist/{chunk-IPLKX3L2.js → chunk-IZYUSJC7.js} +16 -14
- package/dist/{chunk-IPLKX3L2.js.map → chunk-IZYUSJC7.js.map} +1 -1
- package/dist/chunk-J22W6HV3.js +107 -0
- package/dist/chunk-J22W6HV3.js.map +1 -0
- package/dist/{chunk-HWPIFSW2.js → chunk-JSCT3CR4.js} +6 -4
- package/dist/{chunk-HWPIFSW2.js.map → chunk-JSCT3CR4.js.map} +1 -1
- package/dist/chunk-JYXEWPH4.js +62 -0
- package/dist/chunk-JYXEWPH4.js.map +1 -0
- package/dist/chunk-LCE3GF5P.js +866 -0
- package/dist/chunk-LCE3GF5P.js.map +1 -0
- package/dist/chunk-MJ2NKQQL.js +119 -0
- package/dist/chunk-MJ2NKQQL.js.map +1 -0
- package/dist/chunk-N6UR7YVY.js +198 -0
- package/dist/chunk-N6UR7YVY.js.map +1 -0
- package/dist/chunk-OHISZPOJ.js +97 -0
- package/dist/chunk-OHISZPOJ.js.map +1 -0
- package/dist/{chunk-5DJTTKX3.js → chunk-PHOUUNK7.js} +74 -111
- package/dist/chunk-PHOUUNK7.js.map +1 -0
- package/dist/{chunk-PY4XCDLR.js → chunk-RB6QPHJ7.js} +8 -6
- package/dist/{chunk-PY4XCDLR.js.map → chunk-RB6QPHJ7.js.map} +1 -1
- package/dist/chunk-SN4YWWYO.js +171 -0
- package/dist/chunk-SN4YWWYO.js.map +1 -0
- package/dist/chunk-SX52TAR4.js +110 -0
- package/dist/chunk-SX52TAR4.js.map +1 -0
- package/dist/{chunk-XOFWRC73.js → chunk-THTWHNU4.js} +319 -24
- package/dist/chunk-THTWHNU4.js.map +1 -0
- package/dist/{chunk-H4RVA4VE.js → chunk-VYPWMZ6H.js} +2 -2
- package/dist/chunk-XGPU467M.js +136 -0
- package/dist/chunk-XGPU467M.js.map +1 -0
- package/dist/{chunk-TDEXAMGO.js → chunk-ZQMEI34O.js} +206 -574
- package/dist/chunk-ZQMEI34O.js.map +1 -0
- package/dist/compat/index.cjs +7656 -0
- package/dist/compat/index.cjs.map +1 -0
- package/dist/compat/index.d.cts +18 -0
- package/dist/compat/index.d.ts +18 -0
- package/dist/compat/index.js +49 -0
- package/dist/compat/index.js.map +1 -0
- package/dist/compat/jotai/index.cjs +2048 -0
- package/dist/compat/jotai/index.cjs.map +1 -0
- package/dist/compat/jotai/index.d.cts +2 -0
- package/dist/compat/jotai/index.d.ts +2 -0
- package/dist/compat/jotai/index.js +9 -0
- package/dist/compat/jotai/index.js.map +1 -0
- package/dist/compat/nanostores/index.cjs +2175 -0
- package/dist/compat/nanostores/index.cjs.map +1 -0
- package/dist/compat/nanostores/index.d.cts +2 -0
- package/dist/compat/nanostores/index.d.ts +2 -0
- package/dist/compat/nanostores/index.js +23 -0
- package/dist/compat/nanostores/index.js.map +1 -0
- package/dist/compat/nestjs/index.cjs +350 -16
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +6 -6
- package/dist/compat/nestjs/index.d.ts +6 -6
- package/dist/compat/nestjs/index.js +10 -9
- package/dist/compat/react/index.cjs +141 -0
- package/dist/compat/react/index.cjs.map +1 -0
- package/dist/compat/react/index.d.cts +2 -0
- package/dist/compat/react/index.d.ts +2 -0
- package/dist/compat/react/index.js +12 -0
- package/dist/compat/react/index.js.map +1 -0
- package/dist/compat/solid/index.cjs +128 -0
- package/dist/compat/solid/index.cjs.map +1 -0
- package/dist/compat/solid/index.d.cts +2 -0
- package/dist/compat/solid/index.d.ts +2 -0
- package/dist/compat/solid/index.js +12 -0
- package/dist/compat/solid/index.js.map +1 -0
- package/dist/compat/svelte/index.cjs +131 -0
- package/dist/compat/svelte/index.cjs.map +1 -0
- package/dist/compat/svelte/index.d.cts +2 -0
- package/dist/compat/svelte/index.d.ts +2 -0
- package/dist/compat/svelte/index.js +12 -0
- package/dist/compat/svelte/index.js.map +1 -0
- package/dist/compat/vue/index.cjs +146 -0
- package/dist/compat/vue/index.cjs.map +1 -0
- package/dist/compat/vue/index.d.cts +3 -0
- package/dist/compat/vue/index.d.ts +3 -0
- package/dist/compat/vue/index.js +12 -0
- package/dist/compat/vue/index.js.map +1 -0
- package/dist/compat/zustand/index.cjs +4931 -0
- package/dist/compat/zustand/index.cjs.map +1 -0
- package/dist/compat/zustand/index.d.cts +5 -0
- package/dist/compat/zustand/index.d.ts +5 -0
- package/dist/compat/zustand/index.js +12 -0
- package/dist/compat/zustand/index.js.map +1 -0
- package/dist/core/index.cjs +53 -4
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +26 -24
- package/dist/demo-shell-26p5fVxn.d.cts +102 -0
- package/dist/demo-shell-DEp-nMTl.d.ts +102 -0
- package/dist/extra/index.cjs +290 -110
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +5 -4
- package/dist/extra/index.d.ts +5 -4
- package/dist/extra/index.js +8 -5
- package/dist/extra/sources.cjs +2486 -0
- package/dist/extra/sources.cjs.map +1 -0
- package/dist/extra/sources.d.cts +465 -0
- package/dist/extra/sources.d.ts +465 -0
- package/dist/extra/sources.js +57 -0
- package/dist/extra/sources.js.map +1 -0
- package/dist/graph/index.cjs +408 -14
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +5 -5
- package/dist/graph/index.d.ts +5 -5
- package/dist/graph/index.js +13 -5
- package/dist/{graph-D-3JIQme.d.cts → graph-6tZ5jEzr.d.cts} +195 -4
- package/dist/{graph-B6NFqv3z.d.ts → graph-DQ69XU0g.d.ts} +195 -4
- package/dist/index-B4MP_8V_.d.cts +37 -0
- package/dist/index-BEfE8H_G.d.cts +121 -0
- package/dist/{index-D7XgsUt7.d.ts → index-BW1z3BN9.d.ts} +169 -127
- package/dist/index-BYOHF0zP.d.ts +34 -0
- package/dist/index-B_IP40nB.d.cts +36 -0
- package/dist/index-Bd_fwmLf.d.cts +45 -0
- package/dist/{index-BysCTzJz.d.ts → index-BeIdBfcb.d.cts} +121 -547
- package/dist/index-BjI6ty9z.d.ts +121 -0
- package/dist/index-Bxb5ZYc9.d.cts +34 -0
- package/dist/{index-BJB7t9gg.d.cts → index-C0ZXMaXO.d.cts} +2 -2
- package/dist/{index-b5BYtczN.d.cts → index-C8mdwMXc.d.cts} +169 -127
- package/dist/index-CDAjUFIv.d.ts +36 -0
- package/dist/index-CPgZ5wRl.d.ts +44 -0
- package/dist/{index-AMWewNDe.d.cts → index-CUwyr1Kk.d.cts} +33 -4
- package/dist/index-CUyrtuOf.d.cts +127 -0
- package/dist/{index-C-TXEa7C.d.ts → index-CY2TljO4.d.ts} +2 -2
- package/dist/index-CmnuOibw.d.ts +37 -0
- package/dist/{index-DiobMNwE.d.ts → index-CuYwdKO-.d.ts} +3 -3
- package/dist/index-DFhjO4Gg.d.cts +44 -0
- package/dist/{index-1z8vRTCt.d.cts → index-DdD5MVDL.d.ts} +121 -547
- package/dist/index-DrISNAOm.d.ts +45 -0
- package/dist/index-QBpffFW-.d.cts +86 -0
- package/dist/{index-J7Kc0oIQ.d.cts → index-_oMEWlDq.d.cts} +3 -3
- package/dist/{index-CYkjxu3s.d.ts → index-eJ6T_qGM.d.ts} +33 -4
- package/dist/index-qldRdbQw.d.ts +86 -0
- package/dist/index-xdGjv0nO.d.ts +127 -0
- package/dist/index.cjs +2334 -195
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1007 -648
- package/dist/index.d.ts +1007 -648
- package/dist/index.js +1204 -1172
- package/dist/index.js.map +1 -1
- package/dist/{meta-CnkLA_43.d.ts → meta-BGqSZ7mt.d.ts} +1 -1
- package/dist/{meta-DWbkoq1s.d.cts → meta-C0-8XW6Q.d.cts} +1 -1
- package/dist/{node-B-f-Lu-k.d.cts → node-C_IBuvX2.d.cts} +26 -1
- package/dist/{node-B-f-Lu-k.d.ts → node-C_IBuvX2.d.ts} +26 -1
- package/dist/{observable-DBnrwcar.d.cts → observable-Crr1jgzx.d.cts} +1 -1
- package/dist/{observable-uP-wy_uK.d.ts → observable-DCk45RH5.d.ts} +1 -1
- package/dist/patterns/demo-shell.cjs +5604 -0
- package/dist/patterns/demo-shell.cjs.map +1 -0
- package/dist/patterns/demo-shell.d.cts +6 -0
- package/dist/patterns/demo-shell.d.ts +6 -0
- package/dist/patterns/demo-shell.js +15 -0
- package/dist/patterns/demo-shell.js.map +1 -0
- package/dist/patterns/reactive-layout/index.cjs +843 -29
- package/dist/patterns/reactive-layout/index.cjs.map +1 -1
- package/dist/patterns/reactive-layout/index.d.cts +6 -5
- package/dist/patterns/reactive-layout/index.d.ts +6 -5
- package/dist/patterns/reactive-layout/index.js +25 -10
- package/dist/reactive-layout-BaOQefHu.d.cts +183 -0
- package/dist/reactive-layout-D9gejYXE.d.ts +183 -0
- package/dist/{storage-BuTdpCI1.d.cts → storage-BMycWEh2.d.ts} +9 -1
- package/dist/{storage-F2X1U1x0.d.ts → storage-DiqWHzVI.d.cts} +9 -1
- package/package.json +32 -2
- package/dist/chunk-5DJTTKX3.js.map +0 -1
- package/dist/chunk-5WGT55R4.js.map +0 -1
- package/dist/chunk-AOCBDH4T.js.map +0 -1
- package/dist/chunk-MW4VAKAO.js +0 -47
- package/dist/chunk-MW4VAKAO.js.map +0 -1
- package/dist/chunk-TDEXAMGO.js.map +0 -1
- package/dist/chunk-XOFWRC73.js.map +0 -1
- /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-
|
|
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-
|
|
187
|
+
} from "./chunk-RB6QPHJ7.js";
|
|
188
|
+
import {
|
|
189
|
+
core_exports
|
|
190
|
+
} from "./chunk-3ZWCKRHX.js";
|
|
165
191
|
import {
|
|
166
|
-
graph_exports
|
|
167
|
-
|
|
192
|
+
graph_exports,
|
|
193
|
+
watchTopologyTree
|
|
194
|
+
} from "./chunk-6LDQFTYS.js";
|
|
168
195
|
import {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
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-
|
|
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
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
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/
|
|
4170
|
-
var
|
|
4171
|
-
__export(
|
|
4172
|
-
|
|
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
|
|
4175
|
-
return
|
|
4176
|
-
}
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
name
|
|
4190
|
-
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
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
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
3635
|
+
/** Snapshot of recorded violations. */
|
|
3636
|
+
all() {
|
|
3637
|
+
return this.violations.retained();
|
|
3638
|
+
}
|
|
3639
|
+
get mode() {
|
|
3640
|
+
return this._mode;
|
|
4325
3641
|
}
|
|
4326
|
-
|
|
4327
|
-
|
|
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
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4404
|
-
|
|
4405
|
-
(
|
|
4406
|
-
const
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
return
|
|
4411
|
-
}
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
(
|
|
4417
|
-
const
|
|
4418
|
-
|
|
4419
|
-
let
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
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(
|
|
6382
|
-
return switchMap(
|
|
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,
|