@graphrefly/graphrefly 0.25.0 → 0.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/ai-CaR_912Q.d.cts +1033 -0
- package/dist/ai-WlRltJV7.d.ts +1033 -0
- package/dist/audit-ClmqGOCx.d.cts +245 -0
- package/dist/audit-DRlSzBu9.d.ts +245 -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-APFNLIRG.js +62 -0
- package/dist/chunk-APFNLIRG.js.map +1 -0
- package/dist/chunk-AT5LKYNL.js +395 -0
- package/dist/chunk-AT5LKYNL.js.map +1 -0
- package/dist/{chunk-IAHGTNOZ.js → chunk-BQ6RQQFF.js} +351 -2095
- package/dist/chunk-BQ6RQQFF.js.map +1 -0
- package/dist/{chunk-L2GLW2U7.js → chunk-BVZYTZ5H.js} +9 -103
- package/dist/chunk-BVZYTZ5H.js.map +1 -0
- package/dist/{chunk-EVR6UFUV.js → chunk-DST5DKZS.js} +19 -15
- package/dist/{chunk-EVR6UFUV.js.map → chunk-DST5DKZS.js.map} +1 -1
- package/dist/{chunk-TKE3JGOH.js → chunk-GTE6PWRZ.js} +5 -692
- package/dist/chunk-GTE6PWRZ.js.map +1 -0
- package/dist/chunk-HXZEYDUR.js +94 -0
- package/dist/chunk-HXZEYDUR.js.map +1 -0
- package/dist/chunk-J22W6HV3.js +107 -0
- package/dist/chunk-J22W6HV3.js.map +1 -0
- package/dist/{chunk-PY4XCDLR.js → chunk-J2VBW3DZ.js} +6 -95
- package/dist/chunk-J2VBW3DZ.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-JWBCY4NC.js +330 -0
- package/dist/chunk-JWBCY4NC.js.map +1 -0
- package/dist/chunk-K2AUJHVP.js +2251 -0
- package/dist/chunk-K2AUJHVP.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-NC6S43JJ.js +456 -0
- package/dist/chunk-NC6S43JJ.js.map +1 -0
- package/dist/chunk-OFVJBJXR.js +98 -0
- package/dist/chunk-OFVJBJXR.js.map +1 -0
- package/dist/chunk-OHISZPOJ.js +97 -0
- package/dist/chunk-OHISZPOJ.js.map +1 -0
- package/dist/chunk-OU5CQKNW.js +102 -0
- package/dist/chunk-OU5CQKNW.js.map +1 -0
- package/dist/{chunk-XOFWRC73.js → chunk-PF7GRZMW.js} +316 -21
- package/dist/chunk-PF7GRZMW.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-RNHBMHKA.js +1665 -0
- package/dist/chunk-RNHBMHKA.js.map +1 -0
- package/dist/chunk-SX52TAR4.js +110 -0
- package/dist/chunk-SX52TAR4.js.map +1 -0
- package/dist/{chunk-H4RVA4VE.js → chunk-VYPWMZ6H.js} +2 -2
- package/dist/chunk-WBZOVTYK.js +171 -0
- package/dist/chunk-WBZOVTYK.js.map +1 -0
- package/dist/chunk-WKNUIZOY.js +354 -0
- package/dist/chunk-WKNUIZOY.js.map +1 -0
- package/dist/chunk-X3VMZYBT.js +713 -0
- package/dist/chunk-X3VMZYBT.js.map +1 -0
- package/dist/chunk-X5R3GL6H.js +525 -0
- package/dist/chunk-X5R3GL6H.js.map +1 -0
- package/dist/chunk-XGPU467M.js +136 -0
- package/dist/chunk-XGPU467M.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 +50 -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 +11 -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/composite-C7PcQvcs.d.cts +303 -0
- package/dist/composite-aUCvjZVR.d.ts +303 -0
- package/dist/core/index.cjs +53 -4
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +4 -3
- package/dist/core/index.d.ts +4 -3
- package/dist/core/index.js +26 -24
- package/dist/demo-shell-BDkOptd6.d.ts +102 -0
- package/dist/demo-shell-Crid1WdR.d.cts +102 -0
- package/dist/extra/index.cjs +222 -110
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +6 -4
- package/dist/extra/index.d.ts +6 -4
- package/dist/extra/index.js +72 -65
- 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-CCwGKLCm.d.ts} +195 -4
- package/dist/{graph-B6NFqv3z.d.ts → graph-DNCrvZSn.d.cts} +195 -4
- package/dist/index-3lsddbbS.d.ts +86 -0
- package/dist/index-B1tloyhO.d.cts +34 -0
- package/dist/{index-CYkjxu3s.d.ts → index-B6D3QNSA.d.ts} +33 -4
- package/dist/index-B6EhDnjH.d.cts +37 -0
- package/dist/index-B9B7_HEY.d.ts +37 -0
- package/dist/{index-Ds23Wvou.d.ts → index-BHlKbUwO.d.cts} +131 -883
- package/dist/{index-DiobMNwE.d.ts → index-BPVt8kqc.d.ts} +3 -3
- package/dist/index-BaSM3aYt.d.ts +195 -0
- package/dist/index-BuEoe-Qu.d.ts +121 -0
- package/dist/{index-Ch0IpIO0.d.cts → index-BwfLUNw4.d.ts} +131 -883
- package/dist/index-ByQxazQJ.d.cts +86 -0
- package/dist/index-C0svESO4.d.ts +127 -0
- package/dist/{index-OXImXMq6.d.ts → index-C8oil6M6.d.ts} +18 -196
- package/dist/{index-DKE1EATr.d.cts → index-CI3DprxP.d.cts} +18 -196
- package/dist/{index-AMWewNDe.d.cts → index-CO8uBlUh.d.cts} +33 -4
- package/dist/index-CxFrXH4m.d.ts +45 -0
- package/dist/index-D8wS_PeY.d.cts +121 -0
- package/dist/index-DO_6JN9Z.d.cts +127 -0
- package/dist/index-DVGiGFGT.d.cts +195 -0
- package/dist/index-DYme44FM.d.cts +44 -0
- package/dist/{index-J7Kc0oIQ.d.cts → index-DlLp-2Xn.d.cts} +3 -3
- package/dist/index-Dzk2hrlR.d.ts +44 -0
- package/dist/index-VHqptjhu.d.cts +45 -0
- package/dist/index-VdHQMPy1.d.ts +36 -0
- package/dist/index-Xi3u0HCQ.d.cts +36 -0
- package/dist/index-wEn0eFe8.d.ts +34 -0
- package/dist/index.cjs +1780 -176
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +784 -2082
- package/dist/index.d.ts +784 -2082
- package/dist/index.js +955 -4349
- package/dist/index.js.map +1 -1
- package/dist/memory-C6Z2tGpC.d.cts +139 -0
- package/dist/memory-li6FL5RM.d.ts +139 -0
- package/dist/messaging-Gt4LPbyA.d.cts +269 -0
- package/dist/messaging-XDoYablx.d.ts +269 -0
- package/dist/{meta-DWbkoq1s.d.cts → meta-BxCA7rcr.d.cts} +1 -1
- package/dist/{meta-CnkLA_43.d.ts → meta-CbznRPYJ.d.ts} +1 -1
- package/dist/{node-B-f-Lu-k.d.cts → node-BmerH3kS.d.cts} +26 -1
- package/dist/{node-B-f-Lu-k.d.ts → node-BmerH3kS.d.ts} +26 -1
- package/dist/{observable-uP-wy_uK.d.ts → observable-BgGUwcqp.d.ts} +1 -1
- package/dist/{observable-DBnrwcar.d.cts → observable-DJt_AxzQ.d.cts} +1 -1
- package/dist/patterns/ai.cjs +7930 -0
- package/dist/patterns/ai.cjs.map +1 -0
- package/dist/patterns/ai.d.cts +10 -0
- package/dist/patterns/ai.d.ts +10 -0
- package/dist/patterns/ai.js +71 -0
- package/dist/patterns/ai.js.map +1 -0
- package/dist/patterns/audit.cjs +5805 -0
- package/dist/patterns/audit.cjs.map +1 -0
- package/dist/patterns/audit.d.cts +6 -0
- package/dist/patterns/audit.d.ts +6 -0
- package/dist/patterns/audit.js +29 -0
- package/dist/patterns/audit.js.map +1 -0
- 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/memory.cjs +5283 -0
- package/dist/patterns/memory.cjs.map +1 -0
- package/dist/patterns/memory.d.cts +5 -0
- package/dist/patterns/memory.d.ts +5 -0
- package/dist/patterns/memory.js +20 -0
- package/dist/patterns/memory.js.map +1 -0
- package/dist/patterns/reactive-layout/index.cjs +355 -13
- 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 +15 -12
- package/dist/reactive-layout-MQP--J3F.d.cts +183 -0
- package/dist/reactive-layout-u5Ulnqag.d.ts +183 -0
- package/dist/{storage-BuTdpCI1.d.cts → storage-CMjUUuxn.d.ts} +10 -2
- package/dist/{storage-F2X1U1x0.d.ts → storage-DdWlZo6U.d.cts} +10 -2
- package/dist/sugar-CCOxXK1e.d.ts +201 -0
- package/dist/sugar-D02n5JjF.d.cts +201 -0
- package/package.json +63 -3
- package/dist/chunk-5DJTTKX3.js.map +0 -1
- package/dist/chunk-IAHGTNOZ.js.map +0 -1
- package/dist/chunk-L2GLW2U7.js.map +0 -1
- package/dist/chunk-MW4VAKAO.js +0 -47
- package/dist/chunk-MW4VAKAO.js.map +0 -1
- package/dist/chunk-PY4XCDLR.js.map +0 -1
- package/dist/chunk-TKE3JGOH.js.map +0 -1
- package/dist/chunk-XOFWRC73.js.map +0 -1
- package/dist/index-BJB7t9gg.d.cts +0 -392
- package/dist/index-C-TXEa7C.d.ts +0 -392
- /package/dist/{chunk-H4RVA4VE.js.map → chunk-VYPWMZ6H.js.map} +0 -0
|
@@ -1,31 +1,229 @@
|
|
|
1
1
|
import {
|
|
2
2
|
describeNode,
|
|
3
3
|
resolveDescribeFields
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-VYPWMZ6H.js";
|
|
5
5
|
import {
|
|
6
6
|
ResettableTimer,
|
|
7
7
|
RingBuffer
|
|
8
8
|
} from "./chunk-7TAQJHQV.js";
|
|
9
9
|
import {
|
|
10
|
-
COMPLETE,
|
|
11
|
-
DATA,
|
|
12
|
-
DIRTY,
|
|
13
|
-
ERROR,
|
|
14
10
|
GuardDenied,
|
|
15
|
-
INVALIDATE,
|
|
16
11
|
NodeImpl,
|
|
17
|
-
PAUSE,
|
|
18
|
-
RESOLVED,
|
|
19
|
-
RESUME,
|
|
20
|
-
TEARDOWN,
|
|
21
12
|
batch,
|
|
22
13
|
decodeEnvelope,
|
|
23
14
|
defaultConfig,
|
|
24
15
|
encodeEnvelope,
|
|
25
16
|
isBatching,
|
|
26
17
|
monotonicNs,
|
|
27
|
-
|
|
28
|
-
|
|
18
|
+
producer,
|
|
19
|
+
state,
|
|
20
|
+
wallClockNs
|
|
21
|
+
} from "./chunk-PHOUUNK7.js";
|
|
22
|
+
import {
|
|
23
|
+
COMPLETE,
|
|
24
|
+
DATA,
|
|
25
|
+
DIRTY,
|
|
26
|
+
ERROR,
|
|
27
|
+
INVALIDATE,
|
|
28
|
+
PAUSE,
|
|
29
|
+
RESOLVED,
|
|
30
|
+
RESUME,
|
|
31
|
+
TEARDOWN
|
|
32
|
+
} from "./chunk-SX52TAR4.js";
|
|
33
|
+
|
|
34
|
+
// src/graph/explain.ts
|
|
35
|
+
function explainPath(described, from, to, opts = {}) {
|
|
36
|
+
const fromExists = from in described.nodes;
|
|
37
|
+
const toExists = to in described.nodes;
|
|
38
|
+
if (!fromExists) return makeFailure(from, to, "no-such-from");
|
|
39
|
+
if (!toExists) return makeFailure(from, to, "no-such-to");
|
|
40
|
+
const maxDepth = opts.maxDepth;
|
|
41
|
+
if (maxDepth != null && (!Number.isInteger(maxDepth) || maxDepth < 0)) {
|
|
42
|
+
throw new Error(`explainPath: maxDepth must be an integer >= 0`);
|
|
43
|
+
}
|
|
44
|
+
if (from === to) {
|
|
45
|
+
if (opts.findCycle === true) {
|
|
46
|
+
const cycle = findShortestCycle(described, from, opts);
|
|
47
|
+
if (cycle != null) return cycle;
|
|
48
|
+
}
|
|
49
|
+
const step = buildStep(from, described.nodes[from], 0, opts);
|
|
50
|
+
return makeSuccess(from, to, [step]);
|
|
51
|
+
}
|
|
52
|
+
if (maxDepth === 0) return makeFailure(from, to, "no-path");
|
|
53
|
+
const result = bfsShortestPath(described, from, to, maxDepth);
|
|
54
|
+
if (!result.found) {
|
|
55
|
+
return makeFailure(from, to, result.truncated ? "max-depth-exceeded" : "no-path");
|
|
56
|
+
}
|
|
57
|
+
return makeSuccess(from, to, materializeSteps(described, result.pathOrder, opts));
|
|
58
|
+
}
|
|
59
|
+
function bfsShortestPath(described, from, to, maxDepth) {
|
|
60
|
+
const pred = /* @__PURE__ */ new Map();
|
|
61
|
+
const queue = [{ path: to, depth: 0 }];
|
|
62
|
+
const visited = /* @__PURE__ */ new Set([to]);
|
|
63
|
+
let head = 0;
|
|
64
|
+
let truncated = false;
|
|
65
|
+
while (head < queue.length) {
|
|
66
|
+
const cur = queue[head++];
|
|
67
|
+
if (cur.path === from) break;
|
|
68
|
+
if (maxDepth != null && cur.depth >= maxDepth) {
|
|
69
|
+
const node2 = described.nodes[cur.path];
|
|
70
|
+
if (node2?.deps && node2.deps.length > 0) truncated = true;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const node = described.nodes[cur.path];
|
|
74
|
+
if (node == null) continue;
|
|
75
|
+
const deps = node.deps ?? [];
|
|
76
|
+
const slots = /* @__PURE__ */ new Map();
|
|
77
|
+
for (let i = 0; i < deps.length; i++) {
|
|
78
|
+
const dep = deps[i];
|
|
79
|
+
if (!dep) continue;
|
|
80
|
+
let arr = slots.get(dep);
|
|
81
|
+
if (arr == null) {
|
|
82
|
+
arr = [];
|
|
83
|
+
slots.set(dep, arr);
|
|
84
|
+
}
|
|
85
|
+
arr.push(i);
|
|
86
|
+
}
|
|
87
|
+
for (const [dep, indices] of slots) {
|
|
88
|
+
if (visited.has(dep)) continue;
|
|
89
|
+
visited.add(dep);
|
|
90
|
+
pred.set(dep, { from: cur.path, depIndices: indices });
|
|
91
|
+
queue.push({ path: dep, depth: cur.depth + 1 });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (!pred.has(from)) {
|
|
95
|
+
return { found: false, pathOrder: [], truncated };
|
|
96
|
+
}
|
|
97
|
+
const pathOrder = [{ path: from }];
|
|
98
|
+
let cursor = from;
|
|
99
|
+
while (cursor !== to) {
|
|
100
|
+
const p = pred.get(cursor);
|
|
101
|
+
if (p == null) return { found: false, pathOrder: [], truncated: false };
|
|
102
|
+
pathOrder[pathOrder.length - 1].depIndices = p.depIndices;
|
|
103
|
+
pathOrder.push({ path: p.from });
|
|
104
|
+
cursor = p.from;
|
|
105
|
+
}
|
|
106
|
+
return { found: true, pathOrder, truncated: false };
|
|
107
|
+
}
|
|
108
|
+
function findShortestCycle(described, start, opts) {
|
|
109
|
+
const startNode = described.nodes[start];
|
|
110
|
+
if (startNode == null) return null;
|
|
111
|
+
const startDeps = startNode.deps ?? [];
|
|
112
|
+
const selfSlots = [];
|
|
113
|
+
for (let i = 0; i < startDeps.length; i++) if (startDeps[i] === start) selfSlots.push(i);
|
|
114
|
+
if (selfSlots.length > 0) {
|
|
115
|
+
const step0 = buildStep(start, startNode, 0, opts);
|
|
116
|
+
step0.dep_index = selfSlots[0];
|
|
117
|
+
const step1 = buildStep(start, startNode, 1, opts);
|
|
118
|
+
return makeSuccess(start, start, [step0, step1]);
|
|
119
|
+
}
|
|
120
|
+
let best = null;
|
|
121
|
+
for (let i = 0; i < startDeps.length; i++) {
|
|
122
|
+
const dep = startDeps[i];
|
|
123
|
+
if (!dep || dep === start) continue;
|
|
124
|
+
const sub = bfsShortestPath(described, dep, start, opts.maxDepth);
|
|
125
|
+
if (!sub.found) continue;
|
|
126
|
+
if (best == null || sub.pathOrder.length < best.pathOrder.length) {
|
|
127
|
+
best = sub;
|
|
128
|
+
best = {
|
|
129
|
+
found: true,
|
|
130
|
+
pathOrder: [{ path: start, depIndices: [i] }, ...sub.pathOrder],
|
|
131
|
+
truncated: false
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (best == null) return null;
|
|
136
|
+
return makeSuccess(start, start, materializeSteps(described, best.pathOrder, opts));
|
|
137
|
+
}
|
|
138
|
+
function materializeSteps(described, pathOrder, opts) {
|
|
139
|
+
return pathOrder.map((entry, i) => {
|
|
140
|
+
const node = described.nodes[entry.path];
|
|
141
|
+
const step = buildStep(entry.path, node, i, opts);
|
|
142
|
+
if (entry.depIndices != null && entry.depIndices.length > 0) {
|
|
143
|
+
step.dep_index = entry.depIndices[0];
|
|
144
|
+
if (entry.depIndices.length > 1) step.dep_indices = [...entry.depIndices];
|
|
145
|
+
}
|
|
146
|
+
return step;
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function buildStep(path, node, hop, opts) {
|
|
150
|
+
const step = {
|
|
151
|
+
path,
|
|
152
|
+
type: node.type,
|
|
153
|
+
hop
|
|
154
|
+
};
|
|
155
|
+
if (node.status !== void 0) step.status = node.status;
|
|
156
|
+
if ("value" in node) step.value = node.value;
|
|
157
|
+
if (node.v != null) step.v = node.v;
|
|
158
|
+
const annotation = opts.annotations?.get(path) ?? node.reason;
|
|
159
|
+
if (annotation != null) step.reason = annotation;
|
|
160
|
+
const lastMutation = opts.lastMutations?.get(path) ?? node.lastMutation;
|
|
161
|
+
if (lastMutation != null) step.lastMutation = lastMutation;
|
|
162
|
+
return step;
|
|
163
|
+
}
|
|
164
|
+
function makeSuccess(from, to, steps) {
|
|
165
|
+
return finalize(from, to, true, "ok", steps);
|
|
166
|
+
}
|
|
167
|
+
function makeFailure(from, to, reason) {
|
|
168
|
+
return finalize(from, to, false, reason, []);
|
|
169
|
+
}
|
|
170
|
+
function finalize(from, to, found, reason, steps) {
|
|
171
|
+
const text = renderChain(from, to, found, reason, steps);
|
|
172
|
+
return {
|
|
173
|
+
from,
|
|
174
|
+
to,
|
|
175
|
+
found,
|
|
176
|
+
reason,
|
|
177
|
+
steps,
|
|
178
|
+
text,
|
|
179
|
+
toJSON() {
|
|
180
|
+
return { from, to, found, reason, steps };
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function renderChain(from, to, found, reason, steps) {
|
|
185
|
+
if (!found) {
|
|
186
|
+
switch (reason) {
|
|
187
|
+
case "no-such-from":
|
|
188
|
+
return `explainPath: no node named "${from}"`;
|
|
189
|
+
case "no-such-to":
|
|
190
|
+
return `explainPath: no node named "${to}"`;
|
|
191
|
+
case "max-depth-exceeded":
|
|
192
|
+
return `explainPath: no path from "${from}" to "${to}" within maxDepth`;
|
|
193
|
+
default:
|
|
194
|
+
return `explainPath: no path from "${from}" to "${to}"`;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const lines = [`Causal path: ${from} \u2192 ${to} (${steps.length} step(s))`];
|
|
198
|
+
for (const step of steps) {
|
|
199
|
+
const arrow = step.hop === 0 ? "\xB7" : "\u2193";
|
|
200
|
+
const head = ` ${arrow} ${step.path} (${step.type}${step.status ? `/${step.status}` : ""})`;
|
|
201
|
+
lines.push(head);
|
|
202
|
+
if ("value" in step) {
|
|
203
|
+
lines.push(` value: ${formatValue(step.value)}`);
|
|
204
|
+
}
|
|
205
|
+
if (step.reason != null) {
|
|
206
|
+
lines.push(` reason: ${step.reason}`);
|
|
207
|
+
}
|
|
208
|
+
if (step.lastMutation != null) {
|
|
209
|
+
const a = step.lastMutation.actor;
|
|
210
|
+
lines.push(` actor: ${a.type}${a.id ? `:${a.id}` : ""}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return lines.join("\n");
|
|
214
|
+
}
|
|
215
|
+
function formatValue(v) {
|
|
216
|
+
if (v === void 0) return "<sentinel>";
|
|
217
|
+
if (v === null) return "null";
|
|
218
|
+
if (typeof v === "string") return JSON.stringify(v);
|
|
219
|
+
if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") return String(v);
|
|
220
|
+
try {
|
|
221
|
+
const s = JSON.stringify(v);
|
|
222
|
+
return s.length > 80 ? `${s.slice(0, 77)}...` : s;
|
|
223
|
+
} catch {
|
|
224
|
+
return String(v);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
29
227
|
|
|
30
228
|
// src/extra/utils/sizeof.ts
|
|
31
229
|
var OVERHEAD = {
|
|
@@ -660,6 +858,20 @@ var Graph = class _Graph {
|
|
|
660
858
|
_parent = void 0;
|
|
661
859
|
_storageDisposers = /* @__PURE__ */ new Set();
|
|
662
860
|
_disposers = /* @__PURE__ */ new Set();
|
|
861
|
+
/**
|
|
862
|
+
* @internal Lazy `TopologyEvent` producer. Created on first `.topology`
|
|
863
|
+
* access. Zero cost until something subscribes — producer fn only runs when
|
|
864
|
+
* the first sink attaches, registering one handler into
|
|
865
|
+
* {@link Graph._topologyEmitters}.
|
|
866
|
+
*/
|
|
867
|
+
_topology;
|
|
868
|
+
/**
|
|
869
|
+
* @internal Active emit handlers for the topology producer. Each entry is
|
|
870
|
+
* the closure registered by the producer fn on activation; cleared on
|
|
871
|
+
* deactivation. `_emitTopology` broadcasts through every entry (there is at
|
|
872
|
+
* most one per activation cycle of the producer).
|
|
873
|
+
*/
|
|
874
|
+
_topologyEmitters = /* @__PURE__ */ new Set();
|
|
663
875
|
/**
|
|
664
876
|
* @param name - Non-empty graph id (must not contain `::` and must not
|
|
665
877
|
* equal the reserved meta segment `__meta__`).
|
|
@@ -699,6 +911,55 @@ var Graph = class _Graph {
|
|
|
699
911
|
return out;
|
|
700
912
|
}
|
|
701
913
|
// ——————————————————————————————————————————————————————————————
|
|
914
|
+
// Topology companion (structural-change event stream)
|
|
915
|
+
// ——————————————————————————————————————————————————————————————
|
|
916
|
+
/**
|
|
917
|
+
* Reactive stream of structural changes to this graph's own registry
|
|
918
|
+
* (add / mount / remove). Value mutations live on `observe()`; this
|
|
919
|
+
* companion only fires when the topology shape changes.
|
|
920
|
+
*
|
|
921
|
+
* Lazy: the underlying node is created on first access and activates when
|
|
922
|
+
* something subscribes. No emission replay — late subscribers do not
|
|
923
|
+
* receive historical events and should snapshot via {@link Graph.describe}
|
|
924
|
+
* before listening for incremental changes. Events that fire while the
|
|
925
|
+
* producer has zero subscribers are dropped (no retention).
|
|
926
|
+
*
|
|
927
|
+
* Own-graph only: a parent's `topology` does NOT emit for structural
|
|
928
|
+
* changes inside a mounted child. Transitive consumers subscribe to each
|
|
929
|
+
* child's topology separately (recurse through `topology`'s own "added"
|
|
930
|
+
* events with `nodeKind: "mount"` to discover new children).
|
|
931
|
+
*
|
|
932
|
+
* See {@link TopologyEvent} for payload shape.
|
|
933
|
+
*
|
|
934
|
+
* @category observability
|
|
935
|
+
*/
|
|
936
|
+
get topology() {
|
|
937
|
+
if (this._topology == null) {
|
|
938
|
+
this._topology = producer(
|
|
939
|
+
(actions) => {
|
|
940
|
+
const handler = (event) => {
|
|
941
|
+
actions.emit(event);
|
|
942
|
+
};
|
|
943
|
+
this._topologyEmitters.add(handler);
|
|
944
|
+
return () => {
|
|
945
|
+
this._topologyEmitters.delete(handler);
|
|
946
|
+
};
|
|
947
|
+
},
|
|
948
|
+
{ name: `${this.name}_topology` }
|
|
949
|
+
);
|
|
950
|
+
}
|
|
951
|
+
return this._topology;
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* @internal Fire a {@link TopologyEvent} to every active subscriber of
|
|
955
|
+
* `this.topology`. No-op when the topology node has never been accessed or
|
|
956
|
+
* currently has no sinks — zero cost for graphs nobody observes.
|
|
957
|
+
*/
|
|
958
|
+
_emitTopology(event) {
|
|
959
|
+
if (this._topology == null || this._topologyEmitters.size === 0) return;
|
|
960
|
+
for (const h of this._topologyEmitters) h(event);
|
|
961
|
+
}
|
|
962
|
+
// ——————————————————————————————————————————————————————————————
|
|
702
963
|
// Node registry
|
|
703
964
|
// ——————————————————————————————————————————————————————————————
|
|
704
965
|
/**
|
|
@@ -728,6 +989,7 @@ var Graph = class _Graph {
|
|
|
728
989
|
}
|
|
729
990
|
this._nodes.set(name, node);
|
|
730
991
|
this._nodeToName.set(node, name);
|
|
992
|
+
this._emitTopology({ kind: "added", name, nodeKind: "node" });
|
|
731
993
|
return node;
|
|
732
994
|
}
|
|
733
995
|
/**
|
|
@@ -768,22 +1030,23 @@ var Graph = class _Graph {
|
|
|
768
1030
|
assertRegisterableName(name, this.name, "remove");
|
|
769
1031
|
const child = this._mounts.get(name);
|
|
770
1032
|
if (child) {
|
|
771
|
-
const
|
|
1033
|
+
const audit2 = { kind: "mount", nodes: [], mounts: [] };
|
|
772
1034
|
const targets = [];
|
|
773
1035
|
child._collectObserveTargets("", targets);
|
|
774
1036
|
for (const [p, n] of targets) {
|
|
775
1037
|
if (!p.includes(`${PATH_SEP}${GRAPH_META_SEGMENT}${PATH_SEP}`)) {
|
|
776
|
-
|
|
1038
|
+
audit2.nodes.push(p);
|
|
777
1039
|
}
|
|
778
1040
|
void n;
|
|
779
1041
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
1042
|
+
audit2.nodes.sort();
|
|
1043
|
+
audit2.mounts.push(name);
|
|
1044
|
+
audit2.mounts.push(...child._collectSubgraphs(`${name}${PATH_SEP}`));
|
|
783
1045
|
this._mounts.delete(name);
|
|
784
1046
|
child._parent = void 0;
|
|
785
1047
|
teardownMountedGraph(child);
|
|
786
|
-
|
|
1048
|
+
this._emitTopology({ kind: "removed", name, nodeKind: "mount", audit: audit2 });
|
|
1049
|
+
return audit2;
|
|
787
1050
|
}
|
|
788
1051
|
const node = this._nodes.get(name);
|
|
789
1052
|
if (!node) {
|
|
@@ -792,7 +1055,9 @@ var Graph = class _Graph {
|
|
|
792
1055
|
this._nodes.delete(name);
|
|
793
1056
|
this._nodeToName.delete(node);
|
|
794
1057
|
node.down([[TEARDOWN]], { internal: true });
|
|
795
|
-
|
|
1058
|
+
const audit = { kind: "node", nodes: [name], mounts: [] };
|
|
1059
|
+
this._emitTopology({ kind: "removed", name, nodeKind: "node", audit });
|
|
1060
|
+
return audit;
|
|
796
1061
|
}
|
|
797
1062
|
/**
|
|
798
1063
|
* Bulk remove — invokes {@link Graph.remove} for every local name matching
|
|
@@ -1021,6 +1286,7 @@ var Graph = class _Graph {
|
|
|
1021
1286
|
}
|
|
1022
1287
|
this._mounts.set(name, child);
|
|
1023
1288
|
child._parent = this;
|
|
1289
|
+
this._emitTopology({ kind: "added", name, nodeKind: "mount" });
|
|
1024
1290
|
return child;
|
|
1025
1291
|
}
|
|
1026
1292
|
/**
|
|
@@ -1311,6 +1577,33 @@ var Graph = class _Graph {
|
|
|
1311
1577
|
}
|
|
1312
1578
|
return reachable(this.describe(), from, direction, opts);
|
|
1313
1579
|
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Causal walkback: shortest dep-chain from `from` to `to`, enriched with
|
|
1582
|
+
* each node's value, status, last-mutation actor, and reasoning annotation
|
|
1583
|
+
* from {@link Graph.trace}. Wraps {@link explainPath} (roadmap §9.2).
|
|
1584
|
+
*
|
|
1585
|
+
* @param from - Upstream node (the cause).
|
|
1586
|
+
* @param to - Downstream node (the effect).
|
|
1587
|
+
* @param opts - Optional `maxDepth` and `findCycle`. When `findCycle:true`
|
|
1588
|
+
* and `from === to`, returns the shortest cycle through other nodes
|
|
1589
|
+
* (useful for diagnosing feedback loops, COMPOSITION-GUIDE §7).
|
|
1590
|
+
* Annotations and lastMutations are collected automatically from the
|
|
1591
|
+
* live graph.
|
|
1592
|
+
*/
|
|
1593
|
+
explain(from, to, opts) {
|
|
1594
|
+
const described = this.describe({ detail: "full" });
|
|
1595
|
+
const annotations = new Map(this._annotations);
|
|
1596
|
+
const lastMutations = /* @__PURE__ */ new Map();
|
|
1597
|
+
for (const [path, n] of Object.entries(described.nodes)) {
|
|
1598
|
+
if (n.lastMutation != null) lastMutations.set(path, n.lastMutation);
|
|
1599
|
+
}
|
|
1600
|
+
return explainPath(described, from, to, {
|
|
1601
|
+
...opts?.maxDepth != null ? { maxDepth: opts.maxDepth } : {},
|
|
1602
|
+
...opts?.findCycle === true ? { findCycle: true } : {},
|
|
1603
|
+
annotations,
|
|
1604
|
+
lastMutations
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1314
1607
|
/**
|
|
1315
1608
|
* @internal Collect all qualified paths in this graph tree matching a
|
|
1316
1609
|
* glob pattern. Used by scoped autoCheckpoint subscription.
|
|
@@ -1989,7 +2282,7 @@ var Graph = class _Graph {
|
|
|
1989
2282
|
return;
|
|
1990
2283
|
}
|
|
1991
2284
|
const nextSeq = s.seq + 1;
|
|
1992
|
-
const timestamp_ns =
|
|
2285
|
+
const timestamp_ns = wallClockNs();
|
|
1993
2286
|
const isFirst = s.lastSnapshot == null;
|
|
1994
2287
|
const shouldCompact = isFirst || nextSeq % s.compactEvery === 0;
|
|
1995
2288
|
const record = shouldCompact ? {
|
|
@@ -2405,13 +2698,15 @@ function reachable(described, from, direction, options = {}) {
|
|
|
2405
2698
|
}
|
|
2406
2699
|
|
|
2407
2700
|
export {
|
|
2701
|
+
explainPath,
|
|
2408
2702
|
OVERHEAD,
|
|
2409
2703
|
SIZEOF_SYMBOL,
|
|
2410
2704
|
sizeof,
|
|
2411
2705
|
graphProfile,
|
|
2412
2706
|
GRAPH_META_SEGMENT,
|
|
2707
|
+
SNAPSHOT_VERSION,
|
|
2413
2708
|
Graph,
|
|
2414
2709
|
diffForWAL,
|
|
2415
2710
|
reachable
|
|
2416
2711
|
};
|
|
2417
|
-
//# sourceMappingURL=chunk-
|
|
2712
|
+
//# sourceMappingURL=chunk-PF7GRZMW.js.map
|