@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
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import '../node-BmerH3kS.cjs';
|
|
2
|
+
import '../graph-DNCrvZSn.cjs';
|
|
3
|
+
export { C as CollectionEntry, b as CollectionGraph, c as CollectionOptions, d as CollectionPolicy, H as HnswAdapter, e as KnowledgeEdge, K as KnowledgeGraphGraph, L as LightCollectionBundle, f as LightCollectionEntry, g as LightCollectionOptions, R as RankedCollectionEntry, h as VectorBackend, V as VectorIndexBundle, i as VectorIndexOptions, j as VectorRecord, a as VectorSearchResult, k as collection, l as decay, n as knowledgeGraph, o as lightCollection, v as vectorIndex } from '../memory-C6Z2tGpC.cjs';
|
|
4
|
+
import '../meta-BxCA7rcr.cjs';
|
|
5
|
+
import '../storage-DdWlZo6U.cjs';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import '../node-BmerH3kS.js';
|
|
2
|
+
import '../graph-CCwGKLCm.js';
|
|
3
|
+
export { C as CollectionEntry, b as CollectionGraph, c as CollectionOptions, d as CollectionPolicy, H as HnswAdapter, e as KnowledgeEdge, K as KnowledgeGraphGraph, L as LightCollectionBundle, f as LightCollectionEntry, g as LightCollectionOptions, R as RankedCollectionEntry, h as VectorBackend, V as VectorIndexBundle, i as VectorIndexOptions, j as VectorRecord, a as VectorSearchResult, k as collection, l as decay, n as knowledgeGraph, o as lightCollection, v as vectorIndex } from '../memory-li6FL5RM.js';
|
|
4
|
+
import '../meta-CbznRPYJ.js';
|
|
5
|
+
import '../storage-CMjUUuxn.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
collection,
|
|
3
|
+
decay,
|
|
4
|
+
knowledgeGraph,
|
|
5
|
+
lightCollection,
|
|
6
|
+
vectorIndex
|
|
7
|
+
} from "../chunk-AT5LKYNL.js";
|
|
8
|
+
import "../chunk-PF7GRZMW.js";
|
|
9
|
+
import "../chunk-VYPWMZ6H.js";
|
|
10
|
+
import "../chunk-7TAQJHQV.js";
|
|
11
|
+
import "../chunk-PHOUUNK7.js";
|
|
12
|
+
import "../chunk-SX52TAR4.js";
|
|
13
|
+
export {
|
|
14
|
+
collection,
|
|
15
|
+
decay,
|
|
16
|
+
knowledgeGraph,
|
|
17
|
+
lightCollection,
|
|
18
|
+
vectorIndex
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -238,7 +238,7 @@ var CanvasMeasureAdapter = class {
|
|
|
238
238
|
this.currentFont = font;
|
|
239
239
|
}
|
|
240
240
|
let width = ctx.measureText(text).width;
|
|
241
|
-
if (this.emojiCorrection !== 1 &&
|
|
241
|
+
if (this.emojiCorrection !== 1 && new RegExp("\\p{Emoji_Presentation}", "u").test(text)) {
|
|
242
242
|
width *= this.emojiCorrection;
|
|
243
243
|
}
|
|
244
244
|
return { width };
|
|
@@ -1165,6 +1165,12 @@ var NodeImpl = class _NodeImpl {
|
|
|
1165
1165
|
_autoError;
|
|
1166
1166
|
_pausable;
|
|
1167
1167
|
_guard;
|
|
1168
|
+
/**
|
|
1169
|
+
* @internal Additional guards stacked at runtime via {@link NodeImpl._pushGuard}
|
|
1170
|
+
* (e.g. by `policyEnforcer({ mode: "enforce" })`, roadmap §9.2). Effective
|
|
1171
|
+
* write/signal/observe checks AND the original `_guard` with every entry here.
|
|
1172
|
+
*/
|
|
1173
|
+
_extraGuards;
|
|
1168
1174
|
_hashFn;
|
|
1169
1175
|
_versioning;
|
|
1170
1176
|
/**
|
|
@@ -1338,18 +1344,61 @@ var NodeImpl = class _NodeImpl {
|
|
|
1338
1344
|
if (this._inspectorHooks?.size === 0) this._inspectorHooks = void 0;
|
|
1339
1345
|
};
|
|
1340
1346
|
}
|
|
1347
|
+
/**
|
|
1348
|
+
* @internal Push an additional guard onto this node. Effective enforcement
|
|
1349
|
+
* is the AND of `_guard` and every guard pushed via this hook — any one
|
|
1350
|
+
* rejecting throws {@link GuardDenied}. Returns a disposer that removes
|
|
1351
|
+
* the pushed guard. Multiple guards may be stacked simultaneously.
|
|
1352
|
+
*
|
|
1353
|
+
* Used by `policyEnforcer({ mode: "enforce" })` (roadmap §9.2) to overlay
|
|
1354
|
+
* runtime constraint enforcement onto an existing graph without rebuilding
|
|
1355
|
+
* its nodes. Pre-1.0 internal API; not part of the public surface.
|
|
1356
|
+
*
|
|
1357
|
+
* **Identity semantics:** guards are tracked in a `Set`, so pushing the
|
|
1358
|
+
* same `NodeGuard` reference twice is a single registration. Wrap each
|
|
1359
|
+
* push in a unique closure if independent stacking is needed.
|
|
1360
|
+
*
|
|
1361
|
+
* **Iteration order:** insertion-ordered (`Set` semantics). Determinism
|
|
1362
|
+
* follows from single-threaded JS execution; nested re-entry from inside
|
|
1363
|
+
* a guard body (push/pop while iterating) is undefined-but-survivable.
|
|
1364
|
+
*/
|
|
1365
|
+
_pushGuard(guard) {
|
|
1366
|
+
if (this._extraGuards == null) this._extraGuards = /* @__PURE__ */ new Set();
|
|
1367
|
+
this._extraGuards.add(guard);
|
|
1368
|
+
return () => {
|
|
1369
|
+
this._extraGuards?.delete(guard);
|
|
1370
|
+
if (this._extraGuards?.size === 0) this._extraGuards = void 0;
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1341
1373
|
allowsObserve(actor) {
|
|
1342
|
-
if (this._guard == null) return true;
|
|
1343
|
-
|
|
1374
|
+
if (this._guard == null && this._extraGuards == null) return true;
|
|
1375
|
+
const a = normalizeActor(actor);
|
|
1376
|
+
if (this._guard != null && !this._guard(a, "observe")) return false;
|
|
1377
|
+
if (this._extraGuards != null) {
|
|
1378
|
+
for (const eg of this._extraGuards) {
|
|
1379
|
+
if (!eg(a, "observe")) return false;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
return true;
|
|
1344
1383
|
}
|
|
1345
1384
|
// --- Guard helper ---
|
|
1346
1385
|
_checkGuard(options) {
|
|
1347
|
-
if (options?.internal
|
|
1386
|
+
if (options?.internal) return;
|
|
1387
|
+
const hasGuard = this._guard != null || this._extraGuards != null;
|
|
1388
|
+
const hasActor = options?.actor != null;
|
|
1389
|
+
if (!hasGuard && !hasActor) return;
|
|
1348
1390
|
const actor = normalizeActor(options?.actor);
|
|
1349
1391
|
const action = options?.delivery === "signal" ? "signal" : "write";
|
|
1350
|
-
if (!this._guard(actor, action)) {
|
|
1392
|
+
if (this._guard != null && !this._guard(actor, action)) {
|
|
1351
1393
|
throw new GuardDenied({ actor, action, nodeName: this.name });
|
|
1352
1394
|
}
|
|
1395
|
+
if (this._extraGuards != null) {
|
|
1396
|
+
for (const eg of this._extraGuards) {
|
|
1397
|
+
if (!eg(actor, action)) {
|
|
1398
|
+
throw new GuardDenied({ actor, action, nodeName: this.name });
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1353
1402
|
this._lastMutation = { actor, timestamp_ns: wallClockNs() };
|
|
1354
1403
|
}
|
|
1355
1404
|
// --- Public transport ---
|
|
@@ -2281,6 +2330,10 @@ function sentinelGuard(batchData, ctx, allowPartial) {
|
|
|
2281
2330
|
function state(initial, opts) {
|
|
2282
2331
|
return node([], { ...opts, initial });
|
|
2283
2332
|
}
|
|
2333
|
+
function producer(fn, opts) {
|
|
2334
|
+
const wrapped = (_data, actions, ctx) => fn(actions, ctx) ?? void 0;
|
|
2335
|
+
return node(wrapped, { describeKind: "producer", ...opts });
|
|
2336
|
+
}
|
|
2284
2337
|
function derived(deps, fn, opts) {
|
|
2285
2338
|
const allowPartial = opts?.partial ?? false;
|
|
2286
2339
|
const wrapped = (batchData, actions, ctx) => {
|
|
@@ -2483,6 +2536,200 @@ var RingBuffer = class {
|
|
|
2483
2536
|
}
|
|
2484
2537
|
};
|
|
2485
2538
|
|
|
2539
|
+
// src/graph/explain.ts
|
|
2540
|
+
function explainPath(described, from, to, opts = {}) {
|
|
2541
|
+
const fromExists = from in described.nodes;
|
|
2542
|
+
const toExists = to in described.nodes;
|
|
2543
|
+
if (!fromExists) return makeFailure(from, to, "no-such-from");
|
|
2544
|
+
if (!toExists) return makeFailure(from, to, "no-such-to");
|
|
2545
|
+
const maxDepth = opts.maxDepth;
|
|
2546
|
+
if (maxDepth != null && (!Number.isInteger(maxDepth) || maxDepth < 0)) {
|
|
2547
|
+
throw new Error(`explainPath: maxDepth must be an integer >= 0`);
|
|
2548
|
+
}
|
|
2549
|
+
if (from === to) {
|
|
2550
|
+
if (opts.findCycle === true) {
|
|
2551
|
+
const cycle = findShortestCycle(described, from, opts);
|
|
2552
|
+
if (cycle != null) return cycle;
|
|
2553
|
+
}
|
|
2554
|
+
const step = buildStep(from, described.nodes[from], 0, opts);
|
|
2555
|
+
return makeSuccess(from, to, [step]);
|
|
2556
|
+
}
|
|
2557
|
+
if (maxDepth === 0) return makeFailure(from, to, "no-path");
|
|
2558
|
+
const result = bfsShortestPath(described, from, to, maxDepth);
|
|
2559
|
+
if (!result.found) {
|
|
2560
|
+
return makeFailure(from, to, result.truncated ? "max-depth-exceeded" : "no-path");
|
|
2561
|
+
}
|
|
2562
|
+
return makeSuccess(from, to, materializeSteps(described, result.pathOrder, opts));
|
|
2563
|
+
}
|
|
2564
|
+
function bfsShortestPath(described, from, to, maxDepth) {
|
|
2565
|
+
const pred = /* @__PURE__ */ new Map();
|
|
2566
|
+
const queue = [{ path: to, depth: 0 }];
|
|
2567
|
+
const visited = /* @__PURE__ */ new Set([to]);
|
|
2568
|
+
let head = 0;
|
|
2569
|
+
let truncated = false;
|
|
2570
|
+
while (head < queue.length) {
|
|
2571
|
+
const cur = queue[head++];
|
|
2572
|
+
if (cur.path === from) break;
|
|
2573
|
+
if (maxDepth != null && cur.depth >= maxDepth) {
|
|
2574
|
+
const node3 = described.nodes[cur.path];
|
|
2575
|
+
if (node3?.deps && node3.deps.length > 0) truncated = true;
|
|
2576
|
+
continue;
|
|
2577
|
+
}
|
|
2578
|
+
const node2 = described.nodes[cur.path];
|
|
2579
|
+
if (node2 == null) continue;
|
|
2580
|
+
const deps = node2.deps ?? [];
|
|
2581
|
+
const slots = /* @__PURE__ */ new Map();
|
|
2582
|
+
for (let i = 0; i < deps.length; i++) {
|
|
2583
|
+
const dep = deps[i];
|
|
2584
|
+
if (!dep) continue;
|
|
2585
|
+
let arr = slots.get(dep);
|
|
2586
|
+
if (arr == null) {
|
|
2587
|
+
arr = [];
|
|
2588
|
+
slots.set(dep, arr);
|
|
2589
|
+
}
|
|
2590
|
+
arr.push(i);
|
|
2591
|
+
}
|
|
2592
|
+
for (const [dep, indices] of slots) {
|
|
2593
|
+
if (visited.has(dep)) continue;
|
|
2594
|
+
visited.add(dep);
|
|
2595
|
+
pred.set(dep, { from: cur.path, depIndices: indices });
|
|
2596
|
+
queue.push({ path: dep, depth: cur.depth + 1 });
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
if (!pred.has(from)) {
|
|
2600
|
+
return { found: false, pathOrder: [], truncated };
|
|
2601
|
+
}
|
|
2602
|
+
const pathOrder = [{ path: from }];
|
|
2603
|
+
let cursor = from;
|
|
2604
|
+
while (cursor !== to) {
|
|
2605
|
+
const p = pred.get(cursor);
|
|
2606
|
+
if (p == null) return { found: false, pathOrder: [], truncated: false };
|
|
2607
|
+
pathOrder[pathOrder.length - 1].depIndices = p.depIndices;
|
|
2608
|
+
pathOrder.push({ path: p.from });
|
|
2609
|
+
cursor = p.from;
|
|
2610
|
+
}
|
|
2611
|
+
return { found: true, pathOrder, truncated: false };
|
|
2612
|
+
}
|
|
2613
|
+
function findShortestCycle(described, start, opts) {
|
|
2614
|
+
const startNode = described.nodes[start];
|
|
2615
|
+
if (startNode == null) return null;
|
|
2616
|
+
const startDeps = startNode.deps ?? [];
|
|
2617
|
+
const selfSlots = [];
|
|
2618
|
+
for (let i = 0; i < startDeps.length; i++) if (startDeps[i] === start) selfSlots.push(i);
|
|
2619
|
+
if (selfSlots.length > 0) {
|
|
2620
|
+
const step0 = buildStep(start, startNode, 0, opts);
|
|
2621
|
+
step0.dep_index = selfSlots[0];
|
|
2622
|
+
const step1 = buildStep(start, startNode, 1, opts);
|
|
2623
|
+
return makeSuccess(start, start, [step0, step1]);
|
|
2624
|
+
}
|
|
2625
|
+
let best = null;
|
|
2626
|
+
for (let i = 0; i < startDeps.length; i++) {
|
|
2627
|
+
const dep = startDeps[i];
|
|
2628
|
+
if (!dep || dep === start) continue;
|
|
2629
|
+
const sub = bfsShortestPath(described, dep, start, opts.maxDepth);
|
|
2630
|
+
if (!sub.found) continue;
|
|
2631
|
+
if (best == null || sub.pathOrder.length < best.pathOrder.length) {
|
|
2632
|
+
best = sub;
|
|
2633
|
+
best = {
|
|
2634
|
+
found: true,
|
|
2635
|
+
pathOrder: [{ path: start, depIndices: [i] }, ...sub.pathOrder],
|
|
2636
|
+
truncated: false
|
|
2637
|
+
};
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
if (best == null) return null;
|
|
2641
|
+
return makeSuccess(start, start, materializeSteps(described, best.pathOrder, opts));
|
|
2642
|
+
}
|
|
2643
|
+
function materializeSteps(described, pathOrder, opts) {
|
|
2644
|
+
return pathOrder.map((entry, i) => {
|
|
2645
|
+
const node2 = described.nodes[entry.path];
|
|
2646
|
+
const step = buildStep(entry.path, node2, i, opts);
|
|
2647
|
+
if (entry.depIndices != null && entry.depIndices.length > 0) {
|
|
2648
|
+
step.dep_index = entry.depIndices[0];
|
|
2649
|
+
if (entry.depIndices.length > 1) step.dep_indices = [...entry.depIndices];
|
|
2650
|
+
}
|
|
2651
|
+
return step;
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2654
|
+
function buildStep(path, node2, hop, opts) {
|
|
2655
|
+
const step = {
|
|
2656
|
+
path,
|
|
2657
|
+
type: node2.type,
|
|
2658
|
+
hop
|
|
2659
|
+
};
|
|
2660
|
+
if (node2.status !== void 0) step.status = node2.status;
|
|
2661
|
+
if ("value" in node2) step.value = node2.value;
|
|
2662
|
+
if (node2.v != null) step.v = node2.v;
|
|
2663
|
+
const annotation = opts.annotations?.get(path) ?? node2.reason;
|
|
2664
|
+
if (annotation != null) step.reason = annotation;
|
|
2665
|
+
const lastMutation = opts.lastMutations?.get(path) ?? node2.lastMutation;
|
|
2666
|
+
if (lastMutation != null) step.lastMutation = lastMutation;
|
|
2667
|
+
return step;
|
|
2668
|
+
}
|
|
2669
|
+
function makeSuccess(from, to, steps) {
|
|
2670
|
+
return finalize(from, to, true, "ok", steps);
|
|
2671
|
+
}
|
|
2672
|
+
function makeFailure(from, to, reason) {
|
|
2673
|
+
return finalize(from, to, false, reason, []);
|
|
2674
|
+
}
|
|
2675
|
+
function finalize(from, to, found, reason, steps) {
|
|
2676
|
+
const text = renderChain(from, to, found, reason, steps);
|
|
2677
|
+
return {
|
|
2678
|
+
from,
|
|
2679
|
+
to,
|
|
2680
|
+
found,
|
|
2681
|
+
reason,
|
|
2682
|
+
steps,
|
|
2683
|
+
text,
|
|
2684
|
+
toJSON() {
|
|
2685
|
+
return { from, to, found, reason, steps };
|
|
2686
|
+
}
|
|
2687
|
+
};
|
|
2688
|
+
}
|
|
2689
|
+
function renderChain(from, to, found, reason, steps) {
|
|
2690
|
+
if (!found) {
|
|
2691
|
+
switch (reason) {
|
|
2692
|
+
case "no-such-from":
|
|
2693
|
+
return `explainPath: no node named "${from}"`;
|
|
2694
|
+
case "no-such-to":
|
|
2695
|
+
return `explainPath: no node named "${to}"`;
|
|
2696
|
+
case "max-depth-exceeded":
|
|
2697
|
+
return `explainPath: no path from "${from}" to "${to}" within maxDepth`;
|
|
2698
|
+
default:
|
|
2699
|
+
return `explainPath: no path from "${from}" to "${to}"`;
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
const lines = [`Causal path: ${from} \u2192 ${to} (${steps.length} step(s))`];
|
|
2703
|
+
for (const step of steps) {
|
|
2704
|
+
const arrow = step.hop === 0 ? "\xB7" : "\u2193";
|
|
2705
|
+
const head = ` ${arrow} ${step.path} (${step.type}${step.status ? `/${step.status}` : ""})`;
|
|
2706
|
+
lines.push(head);
|
|
2707
|
+
if ("value" in step) {
|
|
2708
|
+
lines.push(` value: ${formatValue(step.value)}`);
|
|
2709
|
+
}
|
|
2710
|
+
if (step.reason != null) {
|
|
2711
|
+
lines.push(` reason: ${step.reason}`);
|
|
2712
|
+
}
|
|
2713
|
+
if (step.lastMutation != null) {
|
|
2714
|
+
const a = step.lastMutation.actor;
|
|
2715
|
+
lines.push(` actor: ${a.type}${a.id ? `:${a.id}` : ""}`);
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
return lines.join("\n");
|
|
2719
|
+
}
|
|
2720
|
+
function formatValue(v) {
|
|
2721
|
+
if (v === void 0) return "<sentinel>";
|
|
2722
|
+
if (v === null) return "null";
|
|
2723
|
+
if (typeof v === "string") return JSON.stringify(v);
|
|
2724
|
+
if (typeof v === "number" || typeof v === "boolean" || typeof v === "bigint") return String(v);
|
|
2725
|
+
try {
|
|
2726
|
+
const s = JSON.stringify(v);
|
|
2727
|
+
return s.length > 80 ? `${s.slice(0, 77)}...` : s;
|
|
2728
|
+
} catch {
|
|
2729
|
+
return String(v);
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2486
2733
|
// src/extra/utils/sizeof.ts
|
|
2487
2734
|
var OVERHEAD = {
|
|
2488
2735
|
object: 56,
|
|
@@ -3116,6 +3363,20 @@ var Graph = class _Graph {
|
|
|
3116
3363
|
_parent = void 0;
|
|
3117
3364
|
_storageDisposers = /* @__PURE__ */ new Set();
|
|
3118
3365
|
_disposers = /* @__PURE__ */ new Set();
|
|
3366
|
+
/**
|
|
3367
|
+
* @internal Lazy `TopologyEvent` producer. Created on first `.topology`
|
|
3368
|
+
* access. Zero cost until something subscribes — producer fn only runs when
|
|
3369
|
+
* the first sink attaches, registering one handler into
|
|
3370
|
+
* {@link Graph._topologyEmitters}.
|
|
3371
|
+
*/
|
|
3372
|
+
_topology;
|
|
3373
|
+
/**
|
|
3374
|
+
* @internal Active emit handlers for the topology producer. Each entry is
|
|
3375
|
+
* the closure registered by the producer fn on activation; cleared on
|
|
3376
|
+
* deactivation. `_emitTopology` broadcasts through every entry (there is at
|
|
3377
|
+
* most one per activation cycle of the producer).
|
|
3378
|
+
*/
|
|
3379
|
+
_topologyEmitters = /* @__PURE__ */ new Set();
|
|
3119
3380
|
/**
|
|
3120
3381
|
* @param name - Non-empty graph id (must not contain `::` and must not
|
|
3121
3382
|
* equal the reserved meta segment `__meta__`).
|
|
@@ -3155,6 +3416,55 @@ var Graph = class _Graph {
|
|
|
3155
3416
|
return out;
|
|
3156
3417
|
}
|
|
3157
3418
|
// ——————————————————————————————————————————————————————————————
|
|
3419
|
+
// Topology companion (structural-change event stream)
|
|
3420
|
+
// ——————————————————————————————————————————————————————————————
|
|
3421
|
+
/**
|
|
3422
|
+
* Reactive stream of structural changes to this graph's own registry
|
|
3423
|
+
* (add / mount / remove). Value mutations live on `observe()`; this
|
|
3424
|
+
* companion only fires when the topology shape changes.
|
|
3425
|
+
*
|
|
3426
|
+
* Lazy: the underlying node is created on first access and activates when
|
|
3427
|
+
* something subscribes. No emission replay — late subscribers do not
|
|
3428
|
+
* receive historical events and should snapshot via {@link Graph.describe}
|
|
3429
|
+
* before listening for incremental changes. Events that fire while the
|
|
3430
|
+
* producer has zero subscribers are dropped (no retention).
|
|
3431
|
+
*
|
|
3432
|
+
* Own-graph only: a parent's `topology` does NOT emit for structural
|
|
3433
|
+
* changes inside a mounted child. Transitive consumers subscribe to each
|
|
3434
|
+
* child's topology separately (recurse through `topology`'s own "added"
|
|
3435
|
+
* events with `nodeKind: "mount"` to discover new children).
|
|
3436
|
+
*
|
|
3437
|
+
* See {@link TopologyEvent} for payload shape.
|
|
3438
|
+
*
|
|
3439
|
+
* @category observability
|
|
3440
|
+
*/
|
|
3441
|
+
get topology() {
|
|
3442
|
+
if (this._topology == null) {
|
|
3443
|
+
this._topology = producer(
|
|
3444
|
+
(actions) => {
|
|
3445
|
+
const handler = (event) => {
|
|
3446
|
+
actions.emit(event);
|
|
3447
|
+
};
|
|
3448
|
+
this._topologyEmitters.add(handler);
|
|
3449
|
+
return () => {
|
|
3450
|
+
this._topologyEmitters.delete(handler);
|
|
3451
|
+
};
|
|
3452
|
+
},
|
|
3453
|
+
{ name: `${this.name}_topology` }
|
|
3454
|
+
);
|
|
3455
|
+
}
|
|
3456
|
+
return this._topology;
|
|
3457
|
+
}
|
|
3458
|
+
/**
|
|
3459
|
+
* @internal Fire a {@link TopologyEvent} to every active subscriber of
|
|
3460
|
+
* `this.topology`. No-op when the topology node has never been accessed or
|
|
3461
|
+
* currently has no sinks — zero cost for graphs nobody observes.
|
|
3462
|
+
*/
|
|
3463
|
+
_emitTopology(event) {
|
|
3464
|
+
if (this._topology == null || this._topologyEmitters.size === 0) return;
|
|
3465
|
+
for (const h of this._topologyEmitters) h(event);
|
|
3466
|
+
}
|
|
3467
|
+
// ——————————————————————————————————————————————————————————————
|
|
3158
3468
|
// Node registry
|
|
3159
3469
|
// ——————————————————————————————————————————————————————————————
|
|
3160
3470
|
/**
|
|
@@ -3184,6 +3494,7 @@ var Graph = class _Graph {
|
|
|
3184
3494
|
}
|
|
3185
3495
|
this._nodes.set(name, node2);
|
|
3186
3496
|
this._nodeToName.set(node2, name);
|
|
3497
|
+
this._emitTopology({ kind: "added", name, nodeKind: "node" });
|
|
3187
3498
|
return node2;
|
|
3188
3499
|
}
|
|
3189
3500
|
/**
|
|
@@ -3224,22 +3535,23 @@ var Graph = class _Graph {
|
|
|
3224
3535
|
assertRegisterableName(name, this.name, "remove");
|
|
3225
3536
|
const child = this._mounts.get(name);
|
|
3226
3537
|
if (child) {
|
|
3227
|
-
const
|
|
3538
|
+
const audit2 = { kind: "mount", nodes: [], mounts: [] };
|
|
3228
3539
|
const targets = [];
|
|
3229
3540
|
child._collectObserveTargets("", targets);
|
|
3230
3541
|
for (const [p, n] of targets) {
|
|
3231
3542
|
if (!p.includes(`${PATH_SEP}${GRAPH_META_SEGMENT}${PATH_SEP}`)) {
|
|
3232
|
-
|
|
3543
|
+
audit2.nodes.push(p);
|
|
3233
3544
|
}
|
|
3234
3545
|
void n;
|
|
3235
3546
|
}
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3547
|
+
audit2.nodes.sort();
|
|
3548
|
+
audit2.mounts.push(name);
|
|
3549
|
+
audit2.mounts.push(...child._collectSubgraphs(`${name}${PATH_SEP}`));
|
|
3239
3550
|
this._mounts.delete(name);
|
|
3240
3551
|
child._parent = void 0;
|
|
3241
3552
|
teardownMountedGraph(child);
|
|
3242
|
-
|
|
3553
|
+
this._emitTopology({ kind: "removed", name, nodeKind: "mount", audit: audit2 });
|
|
3554
|
+
return audit2;
|
|
3243
3555
|
}
|
|
3244
3556
|
const node2 = this._nodes.get(name);
|
|
3245
3557
|
if (!node2) {
|
|
@@ -3248,7 +3560,9 @@ var Graph = class _Graph {
|
|
|
3248
3560
|
this._nodes.delete(name);
|
|
3249
3561
|
this._nodeToName.delete(node2);
|
|
3250
3562
|
node2.down([[TEARDOWN]], { internal: true });
|
|
3251
|
-
|
|
3563
|
+
const audit = { kind: "node", nodes: [name], mounts: [] };
|
|
3564
|
+
this._emitTopology({ kind: "removed", name, nodeKind: "node", audit });
|
|
3565
|
+
return audit;
|
|
3252
3566
|
}
|
|
3253
3567
|
/**
|
|
3254
3568
|
* Bulk remove — invokes {@link Graph.remove} for every local name matching
|
|
@@ -3477,6 +3791,7 @@ var Graph = class _Graph {
|
|
|
3477
3791
|
}
|
|
3478
3792
|
this._mounts.set(name, child);
|
|
3479
3793
|
child._parent = this;
|
|
3794
|
+
this._emitTopology({ kind: "added", name, nodeKind: "mount" });
|
|
3480
3795
|
return child;
|
|
3481
3796
|
}
|
|
3482
3797
|
/**
|
|
@@ -3767,6 +4082,33 @@ var Graph = class _Graph {
|
|
|
3767
4082
|
}
|
|
3768
4083
|
return reachable(this.describe(), from, direction, opts);
|
|
3769
4084
|
}
|
|
4085
|
+
/**
|
|
4086
|
+
* Causal walkback: shortest dep-chain from `from` to `to`, enriched with
|
|
4087
|
+
* each node's value, status, last-mutation actor, and reasoning annotation
|
|
4088
|
+
* from {@link Graph.trace}. Wraps {@link explainPath} (roadmap §9.2).
|
|
4089
|
+
*
|
|
4090
|
+
* @param from - Upstream node (the cause).
|
|
4091
|
+
* @param to - Downstream node (the effect).
|
|
4092
|
+
* @param opts - Optional `maxDepth` and `findCycle`. When `findCycle:true`
|
|
4093
|
+
* and `from === to`, returns the shortest cycle through other nodes
|
|
4094
|
+
* (useful for diagnosing feedback loops, COMPOSITION-GUIDE §7).
|
|
4095
|
+
* Annotations and lastMutations are collected automatically from the
|
|
4096
|
+
* live graph.
|
|
4097
|
+
*/
|
|
4098
|
+
explain(from, to, opts) {
|
|
4099
|
+
const described = this.describe({ detail: "full" });
|
|
4100
|
+
const annotations = new Map(this._annotations);
|
|
4101
|
+
const lastMutations = /* @__PURE__ */ new Map();
|
|
4102
|
+
for (const [path, n] of Object.entries(described.nodes)) {
|
|
4103
|
+
if (n.lastMutation != null) lastMutations.set(path, n.lastMutation);
|
|
4104
|
+
}
|
|
4105
|
+
return explainPath(described, from, to, {
|
|
4106
|
+
...opts?.maxDepth != null ? { maxDepth: opts.maxDepth } : {},
|
|
4107
|
+
...opts?.findCycle === true ? { findCycle: true } : {},
|
|
4108
|
+
annotations,
|
|
4109
|
+
lastMutations
|
|
4110
|
+
});
|
|
4111
|
+
}
|
|
3770
4112
|
/**
|
|
3771
4113
|
* @internal Collect all qualified paths in this graph tree matching a
|
|
3772
4114
|
* glob pattern. Used by scoped autoCheckpoint subscription.
|
|
@@ -4445,7 +4787,7 @@ var Graph = class _Graph {
|
|
|
4445
4787
|
return;
|
|
4446
4788
|
}
|
|
4447
4789
|
const nextSeq = s.seq + 1;
|
|
4448
|
-
const timestamp_ns =
|
|
4790
|
+
const timestamp_ns = wallClockNs();
|
|
4449
4791
|
const isFirst = s.lastSnapshot == null;
|
|
4450
4792
|
const shouldCompact = isFirst || nextSeq % s.compactEvery === 0;
|
|
4451
4793
|
const record = shouldCompact ? {
|