@graphrefly/graphrefly 0.5.0 → 0.7.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 +30 -14
- package/dist/{chunk-5X3LAO3B.js → chunk-3EVXOI5C.js} +50 -5
- package/dist/chunk-3EVXOI5C.js.map +1 -0
- package/dist/chunk-47YJEZUJ.js +106 -0
- package/dist/chunk-47YJEZUJ.js.map +1 -0
- package/dist/{chunk-6W5SGIGB.js → chunk-BLCXEMAD.js} +129 -25
- package/dist/chunk-BLCXEMAD.js.map +1 -0
- package/dist/{chunk-QW7H3ICI.js → chunk-FGLZ5QID.js} +4 -4
- package/dist/{chunk-CP6MNKAA.js → chunk-ISGMZ2T3.js} +10 -4
- package/dist/{chunk-CP6MNKAA.js.map → chunk-ISGMZ2T3.js.map} +1 -1
- package/dist/{chunk-HP7OKEOE.js → chunk-L4J2K2RT.js} +3 -3
- package/dist/chunk-L4J2K2RT.js.map +1 -0
- package/dist/{chunk-ZERWUCGK.js → chunk-ONLYF6GA.js} +866 -206
- package/dist/chunk-ONLYF6GA.js.map +1 -0
- package/dist/{chunk-Z4Y4FMQN.js → chunk-OSR3G3DP.js} +7 -7
- package/dist/{chunk-KWXPDASV.js → chunk-PEBORXRA.js} +2 -2
- package/dist/chunk-WZ2Z2CRV.js +32 -0
- package/dist/chunk-WZ2Z2CRV.js.map +1 -0
- package/dist/compat/nestjs/index.cjs +226 -41
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +4 -4
- package/dist/compat/nestjs/index.d.ts +4 -4
- package/dist/compat/nestjs/index.js +8 -7
- package/dist/core/index.cjs +134 -20
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +10 -4
- package/dist/extra/index.cjs +939 -209
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +4 -4
- package/dist/extra/index.d.ts +4 -4
- package/dist/extra/index.js +26 -3
- package/dist/graph/index.cjs +226 -41
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +3 -3
- package/dist/graph/index.d.ts +3 -3
- package/dist/graph/index.js +4 -4
- package/dist/{graph-CL_ZDAj9.d.cts → graph-B3BoJjcb.d.cts} +58 -7
- package/dist/{graph-D18qmsNm.d.ts → graph-CmiUuhaN.d.ts} +58 -7
- package/dist/{index-B7eOdgEx.d.ts → index-Bf2X1YSI.d.ts} +3 -3
- package/dist/{index-BvhgZRHK.d.cts → index-Bl7hJcc3.d.cts} +4 -2
- package/dist/{index-Bvy_6CaN.d.ts → index-BrgtEG-C.d.ts} +47 -4
- package/dist/{index-D_geH2Bm.d.cts → index-BsuKSs4L.d.cts} +3 -3
- package/dist/{index-BtK55IE2.d.ts → index-CsUq2rrK.d.ts} +4 -2
- package/dist/{index-C3BMRmmp.d.cts → index-D0cx-Yht.d.cts} +3 -3
- package/dist/{index-Cz8og7-L.d.cts → index-D1hgSTzr.d.cts} +488 -60
- package/dist/{index-C5mqLhMX.d.cts → index-D8NIq6om.d.cts} +47 -4
- package/dist/{index-CP_QvbWu.d.ts → index-DFFNKYig.d.ts} +3 -3
- package/dist/{index-C3LRU4jB.d.ts → index-Pm68AYPh.d.ts} +488 -60
- package/dist/index.cjs +3005 -1776
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +112 -14
- package/dist/index.d.ts +112 -14
- package/dist/index.js +396 -27
- package/dist/index.js.map +1 -1
- package/dist/{meta-BsF6Sag9.d.cts → meta-BJEU8fYz.d.cts} +31 -4
- package/dist/{meta-BsF6Sag9.d.ts → meta-BJEU8fYz.d.ts} +31 -4
- package/dist/patterns/reactive-layout/index.cjs +226 -41
- package/dist/patterns/reactive-layout/index.cjs.map +1 -1
- package/dist/patterns/reactive-layout/index.d.cts +3 -3
- package/dist/patterns/reactive-layout/index.d.ts +3 -3
- package/dist/patterns/reactive-layout/index.js +4 -4
- package/dist/{reactive-log-BfvfNWQh.d.cts → reactive-log-CAXzJ7hw.d.cts} +2 -2
- package/dist/{reactive-log-ohLmTXoZ.d.ts → reactive-log-DwNhOe0g.d.ts} +2 -2
- package/package.json +29 -18
- package/dist/chunk-5X3LAO3B.js.map +0 -1
- package/dist/chunk-6W5SGIGB.js.map +0 -1
- package/dist/chunk-HP7OKEOE.js.map +0 -1
- package/dist/chunk-O3PI7W45.js +0 -68
- package/dist/chunk-O3PI7W45.js.map +0 -1
- package/dist/chunk-ZERWUCGK.js.map +0 -1
- /package/dist/{chunk-QW7H3ICI.js.map → chunk-FGLZ5QID.js.map} +0 -0
- /package/dist/{chunk-Z4Y4FMQN.js.map → chunk-OSR3G3DP.js.map} +0 -0
- /package/dist/{chunk-KWXPDASV.js.map → chunk-PEBORXRA.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Graph
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BLCXEMAD.js";
|
|
4
4
|
import {
|
|
5
5
|
DATA,
|
|
6
6
|
INVALIDATE,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
emitWithBatch,
|
|
11
11
|
monotonicNs,
|
|
12
12
|
state
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-3EVXOI5C.js";
|
|
14
14
|
|
|
15
15
|
// src/patterns/reactive-layout/index.ts
|
|
16
16
|
var reactive_layout_exports = {};
|
|
@@ -1077,16 +1077,16 @@ function reactiveBlockLayout(opts) {
|
|
|
1077
1077
|
}
|
|
1078
1078
|
|
|
1079
1079
|
export {
|
|
1080
|
+
analyzeAndMeasure,
|
|
1081
|
+
computeLineBreaks,
|
|
1082
|
+
computeCharPositions,
|
|
1083
|
+
reactiveLayout,
|
|
1080
1084
|
CliMeasureAdapter,
|
|
1081
1085
|
PrecomputedAdapter,
|
|
1082
1086
|
CanvasMeasureAdapter,
|
|
1083
1087
|
NodeCanvasMeasureAdapter,
|
|
1084
1088
|
SvgBoundsAdapter,
|
|
1085
1089
|
ImageSizeAdapter,
|
|
1086
|
-
analyzeAndMeasure,
|
|
1087
|
-
computeLineBreaks,
|
|
1088
|
-
computeCharPositions,
|
|
1089
|
-
reactiveLayout,
|
|
1090
1090
|
measureBlock,
|
|
1091
1091
|
measureBlocks,
|
|
1092
1092
|
computeBlockFlow,
|
|
@@ -1094,4 +1094,4 @@ export {
|
|
|
1094
1094
|
reactiveBlockLayout,
|
|
1095
1095
|
reactive_layout_exports
|
|
1096
1096
|
};
|
|
1097
|
-
//# sourceMappingURL=chunk-
|
|
1097
|
+
//# sourceMappingURL=chunk-OSR3G3DP.js.map
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
producer,
|
|
12
12
|
state,
|
|
13
13
|
wallClockNs
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-3EVXOI5C.js";
|
|
15
15
|
|
|
16
16
|
// src/extra/observable.ts
|
|
17
17
|
import { Observable } from "rxjs";
|
|
@@ -778,4 +778,4 @@ export {
|
|
|
778
778
|
reactiveLog,
|
|
779
779
|
logSlice
|
|
780
780
|
};
|
|
781
|
-
//# sourceMappingURL=chunk-
|
|
781
|
+
//# sourceMappingURL=chunk-PEBORXRA.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/core/timer.ts
|
|
2
|
+
var ResettableTimer = class {
|
|
3
|
+
_timer;
|
|
4
|
+
_gen = 0;
|
|
5
|
+
/** Schedule callback after delayMs. Cancels any pending timer. */
|
|
6
|
+
start(delayMs, callback) {
|
|
7
|
+
this.cancel();
|
|
8
|
+
this._gen += 1;
|
|
9
|
+
const gen = this._gen;
|
|
10
|
+
this._timer = setTimeout(() => {
|
|
11
|
+
this._timer = void 0;
|
|
12
|
+
if (gen !== this._gen) return;
|
|
13
|
+
callback();
|
|
14
|
+
}, delayMs);
|
|
15
|
+
}
|
|
16
|
+
/** Cancel the pending timer (if any). */
|
|
17
|
+
cancel() {
|
|
18
|
+
if (this._timer !== void 0) {
|
|
19
|
+
clearTimeout(this._timer);
|
|
20
|
+
this._timer = void 0;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Whether a timer is currently pending. */
|
|
24
|
+
get pending() {
|
|
25
|
+
return this._timer !== void 0;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
ResettableTimer
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=chunk-WZ2Z2CRV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/timer.ts"],"sourcesContent":["/**\n * Creates a resettable deadline timer for internal timeout, retry, and rate-limiting use.\n *\n * @remarks **Centralised primitive:** wraps `setTimeout`/`clearTimeout` with a generation guard\n * so that stale callbacks never fire after `cancel()` or a new `start()`.\n *\n * @remarks **Spec §5.10 exception:** resilience operators (`timeout`, `retry`, `rateLimiter`)\n * need raw timers — `fromTimer` creates a new Node per reset, which is too heavy here.\n *\n * @example\n * ```ts\n * import { ResettableTimer } from \"@graphrefly/graphrefly-ts\";\n *\n * const timer = new ResettableTimer();\n * timer.start(1000, () => console.log(\"fired\"));\n * timer.cancel(); // cancels before firing\n * timer.start(500, () => console.log(\"new deadline\"));\n * console.log(timer.pending); // true\n * ```\n *\n * @category core\n */\nexport class ResettableTimer {\n\tprivate _timer: ReturnType<typeof setTimeout> | undefined;\n\tprivate _gen = 0;\n\n\t/** Schedule callback after delayMs. Cancels any pending timer. */\n\tstart(delayMs: number, callback: () => void): void {\n\t\tthis.cancel();\n\t\tthis._gen += 1;\n\t\tconst gen = this._gen;\n\t\tthis._timer = setTimeout(() => {\n\t\t\tthis._timer = undefined;\n\t\t\tif (gen !== this._gen) return;\n\t\t\tcallback();\n\t\t}, delayMs);\n\t}\n\n\t/** Cancel the pending timer (if any). */\n\tcancel(): void {\n\t\tif (this._timer !== undefined) {\n\t\t\tclearTimeout(this._timer);\n\t\t\tthis._timer = undefined;\n\t\t}\n\t}\n\n\t/** Whether a timer is currently pending. */\n\tget pending(): boolean {\n\t\treturn this._timer !== undefined;\n\t}\n}\n"],"mappings":";AAsBO,IAAM,kBAAN,MAAsB;AAAA,EACpB;AAAA,EACA,OAAO;AAAA;AAAA,EAGf,MAAM,SAAiB,UAA4B;AAClD,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,UAAM,MAAM,KAAK;AACjB,SAAK,SAAS,WAAW,MAAM;AAC9B,WAAK,SAAS;AACd,UAAI,QAAQ,KAAK,KAAM;AACvB,eAAS;AAAA,IACV,GAAG,OAAO;AAAA,EACX;AAAA;AAAA,EAGA,SAAe;AACd,QAAI,KAAK,WAAW,QAAW;AAC9B,mBAAa,KAAK,MAAM;AACxB,WAAK,SAAS;AAAA,IACf;AAAA,EACD;AAAA;AAAA,EAGA,IAAI,UAAmB;AACtB,WAAO,KAAK,WAAW;AAAA,EACxB;AACD;","names":[]}
|
|
@@ -447,10 +447,14 @@ function partitionForBatch(messages) {
|
|
|
447
447
|
}
|
|
448
448
|
return { immediate, deferred, terminal };
|
|
449
449
|
}
|
|
450
|
-
function emitWithBatch(emit, messages, phase = 2) {
|
|
450
|
+
function emitWithBatch(emit, messages, phase = 2, options) {
|
|
451
451
|
if (messages.length === 0) {
|
|
452
452
|
return;
|
|
453
453
|
}
|
|
454
|
+
if (options?.strategy === "sequential") {
|
|
455
|
+
_emitSequential(emit, messages, phase);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
454
458
|
const queue = phase === 3 ? pendingPhase3 : pendingPhase2;
|
|
455
459
|
if (messages.length === 1) {
|
|
456
460
|
const t = messages[0][0];
|
|
@@ -491,6 +495,29 @@ function emitWithBatch(emit, messages, phase = 2) {
|
|
|
491
495
|
}
|
|
492
496
|
}
|
|
493
497
|
}
|
|
498
|
+
function _emitSequential(emit, messages, phase = 2) {
|
|
499
|
+
const dataQueue = phase === 3 ? pendingPhase3 : pendingPhase2;
|
|
500
|
+
for (const msg of messages) {
|
|
501
|
+
const tier = messageTier(msg[0]);
|
|
502
|
+
if (tier === 2) {
|
|
503
|
+
if (isBatching()) {
|
|
504
|
+
const m = msg;
|
|
505
|
+
dataQueue.push(() => emit([m]));
|
|
506
|
+
} else {
|
|
507
|
+
emit([msg]);
|
|
508
|
+
}
|
|
509
|
+
} else if (tier >= 3) {
|
|
510
|
+
if (isBatching()) {
|
|
511
|
+
const m = msg;
|
|
512
|
+
pendingPhase3.push(() => emit([m]));
|
|
513
|
+
} else {
|
|
514
|
+
emit([msg]);
|
|
515
|
+
}
|
|
516
|
+
} else {
|
|
517
|
+
emit([msg]);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
494
521
|
|
|
495
522
|
// src/core/guard.ts
|
|
496
523
|
var GuardDenied = class extends Error {
|
|
@@ -721,6 +748,7 @@ var NodeImpl = class {
|
|
|
721
748
|
_producerStarted = false;
|
|
722
749
|
_connecting = false;
|
|
723
750
|
_manualEmitUsed = false;
|
|
751
|
+
_hasEmittedData = false;
|
|
724
752
|
_sinkCount = 0;
|
|
725
753
|
_singleDepSinkCount = 0;
|
|
726
754
|
// --- Object/collection state ---
|
|
@@ -1007,6 +1035,7 @@ var NodeImpl = class {
|
|
|
1007
1035
|
this._cleanup = void 0;
|
|
1008
1036
|
cleanupFn?.();
|
|
1009
1037
|
this._cached = void 0;
|
|
1038
|
+
this._hasEmittedData = false;
|
|
1010
1039
|
this._lastDepValues = void 0;
|
|
1011
1040
|
}
|
|
1012
1041
|
this._status = statusAfterMessage(this._status, m);
|
|
@@ -1016,6 +1045,7 @@ var NodeImpl = class {
|
|
|
1016
1045
|
if (t === TEARDOWN) {
|
|
1017
1046
|
if (this._opts.resetOnTeardown) {
|
|
1018
1047
|
this._cached = void 0;
|
|
1048
|
+
this._hasEmittedData = false;
|
|
1019
1049
|
}
|
|
1020
1050
|
const teardownCleanup = this._cleanup;
|
|
1021
1051
|
this._cleanup = void 0;
|
|
@@ -1046,7 +1076,16 @@ var NodeImpl = class {
|
|
|
1046
1076
|
}
|
|
1047
1077
|
_emitAutoValue(value) {
|
|
1048
1078
|
const wasDirty = this._status === "dirty";
|
|
1049
|
-
|
|
1079
|
+
let unchanged;
|
|
1080
|
+
try {
|
|
1081
|
+
unchanged = this._hasEmittedData && this._equals(this._cached, value);
|
|
1082
|
+
} catch (eqErr) {
|
|
1083
|
+
const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
|
|
1084
|
+
const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
|
|
1085
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1086
|
+
return;
|
|
1087
|
+
}
|
|
1088
|
+
this._hasEmittedData = true;
|
|
1050
1089
|
if (unchanged) {
|
|
1051
1090
|
this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
|
|
1052
1091
|
return;
|
|
@@ -1093,7 +1132,9 @@ var NodeImpl = class {
|
|
|
1093
1132
|
if (out === void 0) return;
|
|
1094
1133
|
this._emitAutoValue(out);
|
|
1095
1134
|
} catch (err) {
|
|
1096
|
-
|
|
1135
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1136
|
+
const wrapped = new Error(`Node "${this.name}": fn threw: ${errMsg}`, { cause: err });
|
|
1137
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1097
1138
|
}
|
|
1098
1139
|
}
|
|
1099
1140
|
_onDepDirty(index) {
|
|
@@ -1128,7 +1169,11 @@ var NodeImpl = class {
|
|
|
1128
1169
|
try {
|
|
1129
1170
|
if (this._onMessage(msg, index, this._actions)) continue;
|
|
1130
1171
|
} catch (err) {
|
|
1131
|
-
|
|
1172
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1173
|
+
const wrapped = new Error(`Node "${this.name}": onMessage threw: ${errMsg}`, {
|
|
1174
|
+
cause: err
|
|
1175
|
+
});
|
|
1176
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1132
1177
|
return;
|
|
1133
1178
|
}
|
|
1134
1179
|
}
|
|
@@ -2527,6 +2572,19 @@ var DynamicNodeImpl = class {
|
|
|
2527
2572
|
};
|
|
2528
2573
|
|
|
2529
2574
|
// src/core/meta.ts
|
|
2575
|
+
function resolveDescribeFields(detail, fields) {
|
|
2576
|
+
if (fields != null && fields.length > 0) return new Set(fields);
|
|
2577
|
+
switch (detail) {
|
|
2578
|
+
case "standard":
|
|
2579
|
+
return /* @__PURE__ */ new Set(["type", "status", "value", "deps", "meta", "v"]);
|
|
2580
|
+
case "full":
|
|
2581
|
+
return null;
|
|
2582
|
+
// null = include everything
|
|
2583
|
+
case "minimal":
|
|
2584
|
+
default:
|
|
2585
|
+
return /* @__PURE__ */ new Set(["type", "deps"]);
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2530
2588
|
function inferDescribeType(n) {
|
|
2531
2589
|
if (n._describeKind != null) return n._describeKind;
|
|
2532
2590
|
if (!n._hasDeps) return n._fn != null ? "producer" : "state";
|
|
@@ -2544,12 +2602,10 @@ function metaSnapshot(node2) {
|
|
|
2544
2602
|
}
|
|
2545
2603
|
return out;
|
|
2546
2604
|
}
|
|
2547
|
-
function describeNode(node2) {
|
|
2548
|
-
const
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2551
|
-
meta.access = accessHintForGuard(guard);
|
|
2552
|
-
}
|
|
2605
|
+
function describeNode(node2, includeFields) {
|
|
2606
|
+
const all = includeFields == null;
|
|
2607
|
+
const metaKeys = !all && includeFields != null ? [...includeFields].filter((f) => f.startsWith("meta.")).map((f) => f.slice(5)) : null;
|
|
2608
|
+
const wantsMeta = all || includeFields.has("meta") || metaKeys != null && metaKeys.length > 0;
|
|
2553
2609
|
let type = "state";
|
|
2554
2610
|
let deps = [];
|
|
2555
2611
|
if (node2 instanceof NodeImpl) {
|
|
@@ -2559,20 +2615,36 @@ function describeNode(node2) {
|
|
|
2559
2615
|
type = node2._describeKind ?? "derived";
|
|
2560
2616
|
deps = [];
|
|
2561
2617
|
}
|
|
2562
|
-
const out = {
|
|
2563
|
-
|
|
2564
|
-
status
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2618
|
+
const out = { type, deps };
|
|
2619
|
+
if (all || includeFields.has("status")) {
|
|
2620
|
+
out.status = node2.status;
|
|
2621
|
+
}
|
|
2622
|
+
const guard = node2 instanceof NodeImpl && node2._guard || node2 instanceof DynamicNodeImpl && node2._guard || void 0;
|
|
2623
|
+
if (wantsMeta) {
|
|
2624
|
+
const rawMeta = { ...metaSnapshot(node2) };
|
|
2625
|
+
if (guard != null && rawMeta.access === void 0) {
|
|
2626
|
+
rawMeta.access = accessHintForGuard(guard);
|
|
2627
|
+
}
|
|
2628
|
+
if (metaKeys != null && metaKeys.length > 0 && !includeFields.has("meta")) {
|
|
2629
|
+
const filtered = {};
|
|
2630
|
+
for (const k of metaKeys) {
|
|
2631
|
+
if (k in rawMeta) filtered[k] = rawMeta[k];
|
|
2632
|
+
}
|
|
2633
|
+
out.meta = filtered;
|
|
2634
|
+
} else {
|
|
2635
|
+
out.meta = rawMeta;
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2568
2638
|
if (node2.name != null) {
|
|
2569
2639
|
out.name = node2.name;
|
|
2570
2640
|
}
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2641
|
+
if (all || includeFields.has("value")) {
|
|
2642
|
+
try {
|
|
2643
|
+
out.value = node2.get();
|
|
2644
|
+
} catch {
|
|
2645
|
+
}
|
|
2574
2646
|
}
|
|
2575
|
-
if (node2.v != null) {
|
|
2647
|
+
if ((all || includeFields.has("v")) && node2.v != null) {
|
|
2576
2648
|
const vInfo = { id: node2.v.id, version: node2.v.version };
|
|
2577
2649
|
if ("cid" in node2.v) {
|
|
2578
2650
|
vInfo.cid = node2.v.cid;
|
|
@@ -2580,6 +2652,16 @@ function describeNode(node2) {
|
|
|
2580
2652
|
}
|
|
2581
2653
|
out.v = vInfo;
|
|
2582
2654
|
}
|
|
2655
|
+
if (all || includeFields.has("guard")) {
|
|
2656
|
+
if (guard != null) {
|
|
2657
|
+
out.guard = accessHintForGuard(guard);
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
if (all || includeFields.has("lastMutation")) {
|
|
2661
|
+
if (node2.lastMutation != null) {
|
|
2662
|
+
out.lastMutation = node2.lastMutation;
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2583
2665
|
return out;
|
|
2584
2666
|
}
|
|
2585
2667
|
|
|
@@ -2769,6 +2851,23 @@ function resolveSpyTheme(theme) {
|
|
|
2769
2851
|
reset: theme.reset ?? ""
|
|
2770
2852
|
};
|
|
2771
2853
|
}
|
|
2854
|
+
function resolveObserveDetail(opts) {
|
|
2855
|
+
if (opts == null) return {};
|
|
2856
|
+
const detail = opts.detail;
|
|
2857
|
+
if (detail === "full") {
|
|
2858
|
+
return {
|
|
2859
|
+
...opts,
|
|
2860
|
+
structured: opts.structured ?? true,
|
|
2861
|
+
timeline: opts.timeline ?? true,
|
|
2862
|
+
causal: opts.causal ?? true,
|
|
2863
|
+
derived: opts.derived ?? true
|
|
2864
|
+
};
|
|
2865
|
+
}
|
|
2866
|
+
if (detail === "minimal") {
|
|
2867
|
+
return { ...opts, structured: opts.structured ?? true };
|
|
2868
|
+
}
|
|
2869
|
+
return opts;
|
|
2870
|
+
}
|
|
2772
2871
|
function assertLocalName(name, graphName, label) {
|
|
2773
2872
|
if (name === "") {
|
|
2774
2873
|
throw new Error(`Graph "${graphName}": ${label} name must be non-empty`);
|
|
@@ -2966,6 +3065,22 @@ var Graph = class _Graph {
|
|
|
2966
3065
|
if (this._defaultVersioningLevel != null) {
|
|
2967
3066
|
node2._applyVersioning(this._defaultVersioningLevel);
|
|
2968
3067
|
}
|
|
3068
|
+
if (node2._deps.length > 0) {
|
|
3069
|
+
for (const dep of node2._deps) {
|
|
3070
|
+
for (const [depName, depNode] of this._nodes) {
|
|
3071
|
+
if (depNode === dep) {
|
|
3072
|
+
this._edges.add(edgeKey(depName, name));
|
|
3073
|
+
break;
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
for (const [otherName, otherNode] of this._nodes) {
|
|
3079
|
+
if (otherName === name) continue;
|
|
3080
|
+
if (otherNode instanceof NodeImpl && otherNode._deps.includes(node2)) {
|
|
3081
|
+
this._edges.add(edgeKey(name, otherName));
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
2969
3084
|
}
|
|
2970
3085
|
}
|
|
2971
3086
|
/**
|
|
@@ -3352,6 +3467,9 @@ var Graph = class _Graph {
|
|
|
3352
3467
|
describe(options) {
|
|
3353
3468
|
const actor = options?.actor;
|
|
3354
3469
|
const filter = options?.filter;
|
|
3470
|
+
const includeFields = resolveDescribeFields(options?.detail, options?.fields);
|
|
3471
|
+
const isSpec = options?.format === "spec";
|
|
3472
|
+
const effectiveFields = isSpec ? resolveDescribeFields("minimal") : includeFields;
|
|
3355
3473
|
const targets = [];
|
|
3356
3474
|
this._collectObserveTargets("", targets);
|
|
3357
3475
|
const nodeToPath = /* @__PURE__ */ new Map();
|
|
@@ -3361,7 +3479,7 @@ var Graph = class _Graph {
|
|
|
3361
3479
|
const nodes = {};
|
|
3362
3480
|
for (const [p, n] of targets) {
|
|
3363
3481
|
if (actor != null && !n.allowsObserve(actor)) continue;
|
|
3364
|
-
const raw = describeNode(n);
|
|
3482
|
+
const raw = describeNode(n, effectiveFields);
|
|
3365
3483
|
const deps = n instanceof NodeImpl ? n._deps.map((d) => nodeToPath.get(d) ?? d.name ?? "") : [];
|
|
3366
3484
|
const { name: _name, ...rest } = raw;
|
|
3367
3485
|
const entry = { ...rest, deps };
|
|
@@ -3382,7 +3500,7 @@ var Graph = class _Graph {
|
|
|
3382
3500
|
continue;
|
|
3383
3501
|
}
|
|
3384
3502
|
if (normalizedKey === "metaHas") {
|
|
3385
|
-
if (!Object.hasOwn(entry.meta, String(fv))) {
|
|
3503
|
+
if (!Object.hasOwn(entry.meta ?? {}, String(fv))) {
|
|
3386
3504
|
match = false;
|
|
3387
3505
|
break;
|
|
3388
3506
|
}
|
|
@@ -3415,11 +3533,24 @@ var Graph = class _Graph {
|
|
|
3415
3533
|
const prefix = `${sg}${PATH_SEP}`;
|
|
3416
3534
|
return [...nodeKeys].some((k) => k === sg || k.startsWith(prefix));
|
|
3417
3535
|
}) : allSubgraphs;
|
|
3536
|
+
const graph = this;
|
|
3537
|
+
const baseOpts = options;
|
|
3418
3538
|
return {
|
|
3419
3539
|
name: this.name,
|
|
3420
3540
|
nodes,
|
|
3421
3541
|
edges,
|
|
3422
|
-
subgraphs
|
|
3542
|
+
subgraphs,
|
|
3543
|
+
expand(detailOrFields) {
|
|
3544
|
+
const merged = { ...baseOpts, format: void 0 };
|
|
3545
|
+
if (Array.isArray(detailOrFields)) {
|
|
3546
|
+
merged.fields = detailOrFields;
|
|
3547
|
+
merged.detail = void 0;
|
|
3548
|
+
} else {
|
|
3549
|
+
merged.detail = detailOrFields;
|
|
3550
|
+
merged.fields = void 0;
|
|
3551
|
+
}
|
|
3552
|
+
return graph.describe(merged);
|
|
3553
|
+
}
|
|
3423
3554
|
};
|
|
3424
3555
|
}
|
|
3425
3556
|
_collectSubgraphs(prefix) {
|
|
@@ -3472,14 +3603,15 @@ var Graph = class _Graph {
|
|
|
3472
3603
|
observe(pathOrOpts, options) {
|
|
3473
3604
|
if (typeof pathOrOpts === "string") {
|
|
3474
3605
|
const path = pathOrOpts;
|
|
3475
|
-
const
|
|
3606
|
+
const resolved = resolveObserveDetail(options);
|
|
3607
|
+
const actor2 = resolved.actor;
|
|
3476
3608
|
const target = this.resolve(path);
|
|
3477
3609
|
if (actor2 != null && !target.allowsObserve(actor2)) {
|
|
3478
3610
|
throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
|
|
3479
3611
|
}
|
|
3480
|
-
const wantsStructured2 =
|
|
3612
|
+
const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
|
|
3481
3613
|
if (wantsStructured2 && _Graph.inspectorEnabled) {
|
|
3482
|
-
return this._createObserveResult(path, target,
|
|
3614
|
+
return this._createObserveResult(path, target, resolved);
|
|
3483
3615
|
}
|
|
3484
3616
|
return {
|
|
3485
3617
|
subscribe(sink) {
|
|
@@ -3495,11 +3627,11 @@ var Graph = class _Graph {
|
|
|
3495
3627
|
}
|
|
3496
3628
|
};
|
|
3497
3629
|
}
|
|
3498
|
-
const opts = pathOrOpts;
|
|
3499
|
-
const actor = opts
|
|
3500
|
-
const wantsStructured = opts
|
|
3630
|
+
const opts = resolveObserveDetail(pathOrOpts);
|
|
3631
|
+
const actor = opts.actor;
|
|
3632
|
+
const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
|
|
3501
3633
|
if (wantsStructured && _Graph.inspectorEnabled) {
|
|
3502
|
-
return this._createObserveResultForAll(opts
|
|
3634
|
+
return this._createObserveResultForAll(opts);
|
|
3503
3635
|
}
|
|
3504
3636
|
return {
|
|
3505
3637
|
subscribe: (sink) => {
|
|
@@ -3531,6 +3663,7 @@ var Graph = class _Graph {
|
|
|
3531
3663
|
const timeline = options.timeline === true;
|
|
3532
3664
|
const causal = options.causal === true;
|
|
3533
3665
|
const derived2 = options.derived === true;
|
|
3666
|
+
const minimal = options.detail === "minimal";
|
|
3534
3667
|
const result = {
|
|
3535
3668
|
values: {},
|
|
3536
3669
|
dirtyCount: 0,
|
|
@@ -3576,6 +3709,11 @@ var Graph = class _Graph {
|
|
|
3576
3709
|
if (t === DATA) {
|
|
3577
3710
|
result.values[path] = m[1];
|
|
3578
3711
|
result.events.push({ type: "data", path, data: m[1], ...base, ...withCausal });
|
|
3712
|
+
} else if (minimal) {
|
|
3713
|
+
if (t === DIRTY) result.dirtyCount++;
|
|
3714
|
+
else if (t === RESOLVED) result.resolvedCount++;
|
|
3715
|
+
else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
|
|
3716
|
+
else if (t === ERROR) result.errored = true;
|
|
3579
3717
|
} else if (t === DIRTY) {
|
|
3580
3718
|
result.dirtyCount++;
|
|
3581
3719
|
result.events.push({ type: "dirty", path, ...base });
|
|
@@ -3591,6 +3729,8 @@ var Graph = class _Graph {
|
|
|
3591
3729
|
}
|
|
3592
3730
|
}
|
|
3593
3731
|
});
|
|
3732
|
+
const graph = this;
|
|
3733
|
+
const basePath = path;
|
|
3594
3734
|
return {
|
|
3595
3735
|
get values() {
|
|
3596
3736
|
return result.values;
|
|
@@ -3613,11 +3753,28 @@ var Graph = class _Graph {
|
|
|
3613
3753
|
dispose() {
|
|
3614
3754
|
unsub();
|
|
3615
3755
|
detachInspectorHook?.();
|
|
3756
|
+
},
|
|
3757
|
+
expand(extra) {
|
|
3758
|
+
unsub();
|
|
3759
|
+
detachInspectorHook?.();
|
|
3760
|
+
const merged = { ...options };
|
|
3761
|
+
if (typeof extra === "string") {
|
|
3762
|
+
merged.detail = extra;
|
|
3763
|
+
} else {
|
|
3764
|
+
Object.assign(merged, extra);
|
|
3765
|
+
}
|
|
3766
|
+
const resolvedTarget = graph.resolve(basePath);
|
|
3767
|
+
return graph._createObserveResult(
|
|
3768
|
+
basePath,
|
|
3769
|
+
resolvedTarget,
|
|
3770
|
+
resolveObserveDetail(merged)
|
|
3771
|
+
);
|
|
3616
3772
|
}
|
|
3617
3773
|
};
|
|
3618
3774
|
}
|
|
3619
3775
|
_createObserveResultForAll(options) {
|
|
3620
3776
|
const timeline = options.timeline === true;
|
|
3777
|
+
const minimal = options.detail === "minimal";
|
|
3621
3778
|
const result = {
|
|
3622
3779
|
values: {},
|
|
3623
3780
|
dirtyCount: 0,
|
|
@@ -3639,6 +3796,11 @@ var Graph = class _Graph {
|
|
|
3639
3796
|
if (t === DATA) {
|
|
3640
3797
|
result.values[path] = m[1];
|
|
3641
3798
|
result.events.push({ type: "data", path, data: m[1], ...base });
|
|
3799
|
+
} else if (minimal) {
|
|
3800
|
+
if (t === DIRTY) result.dirtyCount++;
|
|
3801
|
+
else if (t === RESOLVED) result.resolvedCount++;
|
|
3802
|
+
else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
|
|
3803
|
+
else if (t === ERROR) result.errored = true;
|
|
3642
3804
|
} else if (t === DIRTY) {
|
|
3643
3805
|
result.dirtyCount++;
|
|
3644
3806
|
result.events.push({ type: "dirty", path, ...base });
|
|
@@ -3655,6 +3817,7 @@ var Graph = class _Graph {
|
|
|
3655
3817
|
}
|
|
3656
3818
|
})
|
|
3657
3819
|
);
|
|
3820
|
+
const graph = this;
|
|
3658
3821
|
return {
|
|
3659
3822
|
get values() {
|
|
3660
3823
|
return result.values;
|
|
@@ -3676,6 +3839,16 @@ var Graph = class _Graph {
|
|
|
3676
3839
|
},
|
|
3677
3840
|
dispose() {
|
|
3678
3841
|
for (const u of unsubs) u();
|
|
3842
|
+
},
|
|
3843
|
+
expand(extra) {
|
|
3844
|
+
for (const u of unsubs) u();
|
|
3845
|
+
const merged = { ...options };
|
|
3846
|
+
if (typeof extra === "string") {
|
|
3847
|
+
merged.detail = extra;
|
|
3848
|
+
} else {
|
|
3849
|
+
Object.assign(merged, extra);
|
|
3850
|
+
}
|
|
3851
|
+
return graph._createObserveResultForAll(resolveObserveDetail(merged));
|
|
3679
3852
|
}
|
|
3680
3853
|
};
|
|
3681
3854
|
}
|
|
@@ -3751,6 +3924,9 @@ var Graph = class _Graph {
|
|
|
3751
3924
|
},
|
|
3752
3925
|
dispose() {
|
|
3753
3926
|
stop2();
|
|
3927
|
+
},
|
|
3928
|
+
expand() {
|
|
3929
|
+
throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
|
|
3754
3930
|
}
|
|
3755
3931
|
};
|
|
3756
3932
|
const pushEvent = (path, message) => {
|
|
@@ -3851,16 +4027,16 @@ var Graph = class _Graph {
|
|
|
3851
4027
|
* @returns Rendered graph text.
|
|
3852
4028
|
*/
|
|
3853
4029
|
dumpGraph(options = {}) {
|
|
3854
|
-
const described = this.describe({
|
|
4030
|
+
const { expand: _, ...described } = this.describe({
|
|
3855
4031
|
actor: options.actor,
|
|
3856
|
-
filter: options.filter
|
|
4032
|
+
filter: options.filter,
|
|
4033
|
+
detail: "standard"
|
|
3857
4034
|
});
|
|
3858
4035
|
const includeEdges = options.includeEdges ?? true;
|
|
3859
4036
|
const includeSubgraphs = options.includeSubgraphs ?? true;
|
|
3860
4037
|
if (options.format === "json") {
|
|
3861
4038
|
const payload = {
|
|
3862
|
-
|
|
3863
|
-
nodes: described.nodes,
|
|
4039
|
+
...described,
|
|
3864
4040
|
edges: includeEdges ? described.edges : [],
|
|
3865
4041
|
subgraphs: includeSubgraphs ? described.subgraphs : []
|
|
3866
4042
|
};
|
|
@@ -3930,10 +4106,11 @@ var Graph = class _Graph {
|
|
|
3930
4106
|
* @returns Persistable snapshot with sorted keys.
|
|
3931
4107
|
*/
|
|
3932
4108
|
snapshot() {
|
|
3933
|
-
const d = this.describe();
|
|
4109
|
+
const { expand: _, ...d } = this.describe({ detail: "full" });
|
|
3934
4110
|
const sortedNodes = {};
|
|
3935
4111
|
for (const key of Object.keys(d.nodes).sort()) {
|
|
3936
|
-
|
|
4112
|
+
const { lastMutation: _lm, guard: _g, ...node2 } = d.nodes[key];
|
|
4113
|
+
sortedNodes[key] = node2;
|
|
3937
4114
|
}
|
|
3938
4115
|
const sortedSubgraphs = [...d.subgraphs].sort();
|
|
3939
4116
|
return { ...d, version: 1, nodes: sortedNodes, subgraphs: sortedSubgraphs };
|
|
@@ -4087,16 +4264,22 @@ var Graph = class _Graph {
|
|
|
4087
4264
|
if (!pending) return;
|
|
4088
4265
|
pending = false;
|
|
4089
4266
|
try {
|
|
4090
|
-
const
|
|
4267
|
+
const { expand: _expand, ...raw } = this.describe({ detail: "full" });
|
|
4268
|
+
const cleanNodes = {};
|
|
4269
|
+
for (const [p, n] of Object.entries(raw.nodes)) {
|
|
4270
|
+
const { lastMutation: _lm, guard: _g, ...node2 } = n;
|
|
4271
|
+
cleanNodes[p] = node2;
|
|
4272
|
+
}
|
|
4273
|
+
const described = { ...raw, nodes: cleanNodes };
|
|
4091
4274
|
const snapshot = { ...described, version: SNAPSHOT_VERSION };
|
|
4092
4275
|
seq += 1;
|
|
4093
4276
|
const shouldCompact = lastDescribe == null || seq % compactEvery === 0;
|
|
4094
4277
|
if (shouldCompact) {
|
|
4095
|
-
adapter.save({ mode: "full", snapshot, seq });
|
|
4278
|
+
adapter.save(this.name, { mode: "full", snapshot, seq });
|
|
4096
4279
|
} else {
|
|
4097
4280
|
const previous = lastDescribe;
|
|
4098
4281
|
if (previous == null) return;
|
|
4099
|
-
adapter.save({
|
|
4282
|
+
adapter.save(this.name, {
|
|
4100
4283
|
mode: "diff",
|
|
4101
4284
|
diff: _Graph.diff(previous, described),
|
|
4102
4285
|
snapshot,
|
|
@@ -4117,8 +4300,10 @@ var Graph = class _Graph {
|
|
|
4117
4300
|
const triggeredByTier = messages.some((m) => messageTier(m[0]) >= 2);
|
|
4118
4301
|
if (!triggeredByTier) return;
|
|
4119
4302
|
if (options.filter) {
|
|
4120
|
-
const
|
|
4121
|
-
if (
|
|
4303
|
+
const nd = this.resolve(path);
|
|
4304
|
+
if (nd == null) return;
|
|
4305
|
+
const described = describeNode(nd, resolveDescribeFields("standard"));
|
|
4306
|
+
if (!options.filter(path, described)) return;
|
|
4122
4307
|
}
|
|
4123
4308
|
schedule();
|
|
4124
4309
|
});
|