@graphrefly/graphrefly 0.6.0 → 0.8.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-HP7OKEOE.js → chunk-A2AJJOSJ.js} +3 -3
- package/dist/chunk-A2AJJOSJ.js.map +1 -0
- package/dist/{chunk-CP6MNKAA.js → chunk-E7OH6ZAZ.js} +10 -4
- package/dist/{chunk-CP6MNKAA.js.map → chunk-E7OH6ZAZ.js.map} +1 -1
- package/dist/chunk-LR2CLSEF.js +106 -0
- package/dist/chunk-LR2CLSEF.js.map +1 -0
- package/dist/{chunk-5X3LAO3B.js → chunk-QTZSBQGJ.js} +79 -20
- package/dist/chunk-QTZSBQGJ.js.map +1 -0
- package/dist/{chunk-V3UACY6A.js → chunk-TZLX4KIT.js} +790 -203
- package/dist/chunk-TZLX4KIT.js.map +1 -0
- package/dist/{chunk-QW7H3ICI.js → chunk-UCW3VWMN.js} +4 -4
- package/dist/{chunk-6W5SGIGB.js → chunk-WYI7YW54.js} +142 -30
- package/dist/chunk-WYI7YW54.js.map +1 -0
- package/dist/chunk-WZ2Z2CRV.js +32 -0
- package/dist/chunk-WZ2Z2CRV.js.map +1 -0
- package/dist/{chunk-Z4Y4FMQN.js → chunk-XCZPGOVP.js} +7 -7
- package/dist/{chunk-KWXPDASV.js → chunk-YWTP2XRJ.js} +2 -2
- package/dist/compat/nestjs/index.cjs +268 -61
- 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 +163 -35
- 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 +892 -221
- 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 +22 -3
- package/dist/graph/index.cjs +268 -61
- 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-DqTICAY2.d.cts} +69 -12
- package/dist/{graph-D18qmsNm.d.ts → graph-X9uwnD_z.d.ts} +69 -12
- package/dist/{index-C3BMRmmp.d.cts → index-3U0WxdD-.d.cts} +3 -3
- package/dist/{index-Bk_idZm1.d.cts → index-BP1t_38S.d.cts} +406 -61
- package/dist/{index-BtK55IE2.d.ts → index-BPCeYDS4.d.ts} +4 -2
- package/dist/{index-Bvy_6CaN.d.ts → index-BVG5pjin.d.ts} +50 -5
- package/dist/{index-C5mqLhMX.d.cts → index-BYEgosAX.d.cts} +50 -5
- package/dist/{index-D_geH2Bm.d.cts → index-BYa2YMat.d.cts} +3 -3
- package/dist/{index-CP_QvbWu.d.ts → index-DLO8wnYU.d.ts} +3 -3
- package/dist/{index-B7eOdgEx.d.ts → index-DMv1Etbi.d.ts} +3 -3
- package/dist/{index-BvhgZRHK.d.cts → index-DbwgQ4Cw.d.cts} +4 -2
- package/dist/{index-B2jmzVxL.d.ts → index-a5gHmH5b.d.ts} +406 -61
- package/dist/index.cjs +2966 -1790
- 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 +385 -20
- 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 +268 -61
- 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-BfX6bOSZ.d.cts} +2 -2
- package/dist/{reactive-log-ohLmTXoZ.d.ts → reactive-log-RhgIog2Z.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-V3UACY6A.js.map +0 -1
- /package/dist/{chunk-QW7H3ICI.js.map → chunk-UCW3VWMN.js.map} +0 -0
- /package/dist/{chunk-Z4Y4FMQN.js.map → chunk-XCZPGOVP.js.map} +0 -0
- /package/dist/{chunk-KWXPDASV.js.map → chunk-YWTP2XRJ.js.map} +0 -0
|
@@ -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 {
|
|
@@ -621,6 +648,7 @@ function advanceVersion(info, newValue, hashFn) {
|
|
|
621
648
|
}
|
|
622
649
|
|
|
623
650
|
// src/core/node.ts
|
|
651
|
+
var NO_VALUE = /* @__PURE__ */ Symbol.for("graphrefly/NO_VALUE");
|
|
624
652
|
function createIntBitSet() {
|
|
625
653
|
let bits = 0;
|
|
626
654
|
return {
|
|
@@ -750,10 +778,10 @@ var NodeImpl = class {
|
|
|
750
778
|
this._hasDeps = deps.length > 0;
|
|
751
779
|
this._autoComplete = opts.completeWhenDepsComplete ?? true;
|
|
752
780
|
this._isSingleDep = deps.length === 1 && fn != null;
|
|
753
|
-
this._cached = opts.initial;
|
|
781
|
+
this._cached = "initial" in opts ? opts.initial : NO_VALUE;
|
|
754
782
|
this._status = this._hasDeps ? "disconnected" : "settled";
|
|
755
783
|
this._hashFn = opts.versioningHash ?? defaultHash;
|
|
756
|
-
this._versioning = opts.versioning != null ? createVersioning(opts.versioning, this._cached, {
|
|
784
|
+
this._versioning = opts.versioning != null ? createVersioning(opts.versioning, this._cached === NO_VALUE ? void 0 : this._cached, {
|
|
757
785
|
id: opts.versioningId,
|
|
758
786
|
hash: this._hashFn
|
|
759
787
|
}) : void 0;
|
|
@@ -837,10 +865,14 @@ var NodeImpl = class {
|
|
|
837
865
|
_applyVersioning(level, opts) {
|
|
838
866
|
if (this._versioning != null) return;
|
|
839
867
|
this._hashFn = opts?.hash ?? this._hashFn;
|
|
840
|
-
this._versioning = createVersioning(
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
868
|
+
this._versioning = createVersioning(
|
|
869
|
+
level,
|
|
870
|
+
this._cached === NO_VALUE ? void 0 : this._cached,
|
|
871
|
+
{
|
|
872
|
+
id: opts?.id,
|
|
873
|
+
hash: this._hashFn
|
|
874
|
+
}
|
|
875
|
+
);
|
|
844
876
|
}
|
|
845
877
|
hasGuard() {
|
|
846
878
|
return this._guard != null;
|
|
@@ -850,7 +882,7 @@ var NodeImpl = class {
|
|
|
850
882
|
return this._guard(normalizeActor(actor), "observe");
|
|
851
883
|
}
|
|
852
884
|
get() {
|
|
853
|
-
return this._cached;
|
|
885
|
+
return this._cached === NO_VALUE ? void 0 : this._cached;
|
|
854
886
|
}
|
|
855
887
|
down(messages, options) {
|
|
856
888
|
if (messages.length === 0) return;
|
|
@@ -907,6 +939,7 @@ var NodeImpl = class {
|
|
|
907
939
|
}
|
|
908
940
|
if (this._terminal && this._opts.resubscribable) {
|
|
909
941
|
this._terminal = false;
|
|
942
|
+
this._cached = NO_VALUE;
|
|
910
943
|
this._status = this._hasDeps ? "disconnected" : "settled";
|
|
911
944
|
this._opts.onResubscribe?.();
|
|
912
945
|
}
|
|
@@ -1006,7 +1039,7 @@ var NodeImpl = class {
|
|
|
1006
1039
|
const cleanupFn = this._cleanup;
|
|
1007
1040
|
this._cleanup = void 0;
|
|
1008
1041
|
cleanupFn?.();
|
|
1009
|
-
this._cached =
|
|
1042
|
+
this._cached = NO_VALUE;
|
|
1010
1043
|
this._lastDepValues = void 0;
|
|
1011
1044
|
}
|
|
1012
1045
|
this._status = statusAfterMessage(this._status, m);
|
|
@@ -1015,7 +1048,7 @@ var NodeImpl = class {
|
|
|
1015
1048
|
}
|
|
1016
1049
|
if (t === TEARDOWN) {
|
|
1017
1050
|
if (this._opts.resetOnTeardown) {
|
|
1018
|
-
this._cached =
|
|
1051
|
+
this._cached = NO_VALUE;
|
|
1019
1052
|
}
|
|
1020
1053
|
const teardownCleanup = this._cleanup;
|
|
1021
1054
|
this._cleanup = void 0;
|
|
@@ -1046,7 +1079,15 @@ var NodeImpl = class {
|
|
|
1046
1079
|
}
|
|
1047
1080
|
_emitAutoValue(value) {
|
|
1048
1081
|
const wasDirty = this._status === "dirty";
|
|
1049
|
-
|
|
1082
|
+
let unchanged;
|
|
1083
|
+
try {
|
|
1084
|
+
unchanged = this._cached !== NO_VALUE && this._equals(this._cached, value);
|
|
1085
|
+
} catch (eqErr) {
|
|
1086
|
+
const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
|
|
1087
|
+
const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
|
|
1088
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1050
1091
|
if (unchanged) {
|
|
1051
1092
|
this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
|
|
1052
1093
|
return;
|
|
@@ -1093,7 +1134,9 @@ var NodeImpl = class {
|
|
|
1093
1134
|
if (out === void 0) return;
|
|
1094
1135
|
this._emitAutoValue(out);
|
|
1095
1136
|
} catch (err) {
|
|
1096
|
-
|
|
1137
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1138
|
+
const wrapped = new Error(`Node "${this.name}": fn threw: ${errMsg}`, { cause: err });
|
|
1139
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1097
1140
|
}
|
|
1098
1141
|
}
|
|
1099
1142
|
_onDepDirty(index) {
|
|
@@ -1128,7 +1171,11 @@ var NodeImpl = class {
|
|
|
1128
1171
|
try {
|
|
1129
1172
|
if (this._onMessage(msg, index, this._actions)) continue;
|
|
1130
1173
|
} catch (err) {
|
|
1131
|
-
|
|
1174
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1175
|
+
const wrapped = new Error(`Node "${this.name}": onMessage threw: ${errMsg}`, {
|
|
1176
|
+
cause: err
|
|
1177
|
+
});
|
|
1178
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1132
1179
|
return;
|
|
1133
1180
|
}
|
|
1134
1181
|
}
|
|
@@ -2095,7 +2142,7 @@ var DynamicNodeImpl = class {
|
|
|
2095
2142
|
_actions;
|
|
2096
2143
|
_boundEmitToSinks;
|
|
2097
2144
|
// Mutable state
|
|
2098
|
-
_cached;
|
|
2145
|
+
_cached = NO_VALUE;
|
|
2099
2146
|
_status = "disconnected";
|
|
2100
2147
|
_terminal = false;
|
|
2101
2148
|
_connected = false;
|
|
@@ -2189,7 +2236,7 @@ var DynamicNodeImpl = class {
|
|
|
2189
2236
|
return this._guard(normalizeActor(actor), "observe");
|
|
2190
2237
|
}
|
|
2191
2238
|
get() {
|
|
2192
|
-
return this._cached;
|
|
2239
|
+
return this._cached === NO_VALUE ? void 0 : this._cached;
|
|
2193
2240
|
}
|
|
2194
2241
|
down(messages, options) {
|
|
2195
2242
|
if (messages.length === 0) return;
|
|
@@ -2247,6 +2294,7 @@ var DynamicNodeImpl = class {
|
|
|
2247
2294
|
}
|
|
2248
2295
|
if (this._terminal && this._resubscribable) {
|
|
2249
2296
|
this._terminal = false;
|
|
2297
|
+
this._cached = NO_VALUE;
|
|
2250
2298
|
this._status = "disconnected";
|
|
2251
2299
|
this._onResubscribe?.();
|
|
2252
2300
|
}
|
|
@@ -2324,10 +2372,13 @@ var DynamicNodeImpl = class {
|
|
|
2324
2372
|
const t = m[0];
|
|
2325
2373
|
if (t === DATA) this._cached = m[1];
|
|
2326
2374
|
if (t === INVALIDATE) {
|
|
2327
|
-
this._cached =
|
|
2375
|
+
this._cached = NO_VALUE;
|
|
2376
|
+
this._status = "dirty";
|
|
2328
2377
|
}
|
|
2329
|
-
if (t === DATA
|
|
2378
|
+
if (t === DATA) {
|
|
2330
2379
|
this._status = "settled";
|
|
2380
|
+
} else if (t === RESOLVED) {
|
|
2381
|
+
this._status = "resolved";
|
|
2331
2382
|
} else if (t === DIRTY) {
|
|
2332
2383
|
this._status = "dirty";
|
|
2333
2384
|
} else if (t === COMPLETE) {
|
|
@@ -2338,7 +2389,7 @@ var DynamicNodeImpl = class {
|
|
|
2338
2389
|
this._terminal = true;
|
|
2339
2390
|
}
|
|
2340
2391
|
if (t === TEARDOWN) {
|
|
2341
|
-
if (this._resetOnTeardown) this._cached =
|
|
2392
|
+
if (this._resetOnTeardown) this._cached = NO_VALUE;
|
|
2342
2393
|
try {
|
|
2343
2394
|
this._propagateToMeta(t);
|
|
2344
2395
|
} finally {
|
|
@@ -2361,7 +2412,15 @@ var DynamicNodeImpl = class {
|
|
|
2361
2412
|
}
|
|
2362
2413
|
_emitAutoValue(value) {
|
|
2363
2414
|
const wasDirty = this._status === "dirty";
|
|
2364
|
-
|
|
2415
|
+
let unchanged;
|
|
2416
|
+
try {
|
|
2417
|
+
unchanged = this._cached !== NO_VALUE && this._equals(this._cached, value);
|
|
2418
|
+
} catch (eqErr) {
|
|
2419
|
+
const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
|
|
2420
|
+
const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
|
|
2421
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2365
2424
|
if (unchanged) {
|
|
2366
2425
|
this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
|
|
2367
2426
|
return;
|
|
@@ -2527,6 +2586,19 @@ var DynamicNodeImpl = class {
|
|
|
2527
2586
|
};
|
|
2528
2587
|
|
|
2529
2588
|
// src/core/meta.ts
|
|
2589
|
+
function resolveDescribeFields(detail, fields) {
|
|
2590
|
+
if (fields != null && fields.length > 0) return new Set(fields);
|
|
2591
|
+
switch (detail) {
|
|
2592
|
+
case "standard":
|
|
2593
|
+
return /* @__PURE__ */ new Set(["type", "status", "value", "deps", "meta", "v"]);
|
|
2594
|
+
case "full":
|
|
2595
|
+
return null;
|
|
2596
|
+
// null = include everything
|
|
2597
|
+
case "minimal":
|
|
2598
|
+
default:
|
|
2599
|
+
return /* @__PURE__ */ new Set(["type", "deps"]);
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2530
2602
|
function inferDescribeType(n) {
|
|
2531
2603
|
if (n._describeKind != null) return n._describeKind;
|
|
2532
2604
|
if (!n._hasDeps) return n._fn != null ? "producer" : "state";
|
|
@@ -2544,12 +2616,10 @@ function metaSnapshot(node2) {
|
|
|
2544
2616
|
}
|
|
2545
2617
|
return out;
|
|
2546
2618
|
}
|
|
2547
|
-
function describeNode(node2) {
|
|
2548
|
-
const
|
|
2549
|
-
const
|
|
2550
|
-
|
|
2551
|
-
meta.access = accessHintForGuard(guard);
|
|
2552
|
-
}
|
|
2619
|
+
function describeNode(node2, includeFields) {
|
|
2620
|
+
const all = includeFields == null;
|
|
2621
|
+
const metaKeys = !all && includeFields != null ? [...includeFields].filter((f) => f.startsWith("meta.")).map((f) => f.slice(5)) : null;
|
|
2622
|
+
const wantsMeta = all || includeFields.has("meta") || metaKeys != null && metaKeys.length > 0;
|
|
2553
2623
|
let type = "state";
|
|
2554
2624
|
let deps = [];
|
|
2555
2625
|
if (node2 instanceof NodeImpl) {
|
|
@@ -2559,20 +2629,36 @@ function describeNode(node2) {
|
|
|
2559
2629
|
type = node2._describeKind ?? "derived";
|
|
2560
2630
|
deps = [];
|
|
2561
2631
|
}
|
|
2562
|
-
const out = {
|
|
2563
|
-
|
|
2564
|
-
status
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2632
|
+
const out = { type, deps };
|
|
2633
|
+
if (all || includeFields.has("status")) {
|
|
2634
|
+
out.status = node2.status;
|
|
2635
|
+
}
|
|
2636
|
+
const guard = node2 instanceof NodeImpl && node2._guard || node2 instanceof DynamicNodeImpl && node2._guard || void 0;
|
|
2637
|
+
if (wantsMeta) {
|
|
2638
|
+
const rawMeta = { ...metaSnapshot(node2) };
|
|
2639
|
+
if (guard != null && rawMeta.access === void 0) {
|
|
2640
|
+
rawMeta.access = accessHintForGuard(guard);
|
|
2641
|
+
}
|
|
2642
|
+
if (metaKeys != null && metaKeys.length > 0 && !includeFields.has("meta")) {
|
|
2643
|
+
const filtered = {};
|
|
2644
|
+
for (const k of metaKeys) {
|
|
2645
|
+
if (k in rawMeta) filtered[k] = rawMeta[k];
|
|
2646
|
+
}
|
|
2647
|
+
out.meta = filtered;
|
|
2648
|
+
} else {
|
|
2649
|
+
out.meta = rawMeta;
|
|
2650
|
+
}
|
|
2651
|
+
}
|
|
2568
2652
|
if (node2.name != null) {
|
|
2569
2653
|
out.name = node2.name;
|
|
2570
2654
|
}
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2655
|
+
if (all || includeFields.has("value")) {
|
|
2656
|
+
try {
|
|
2657
|
+
out.value = node2.get();
|
|
2658
|
+
} catch {
|
|
2659
|
+
}
|
|
2574
2660
|
}
|
|
2575
|
-
if (node2.v != null) {
|
|
2661
|
+
if ((all || includeFields.has("v")) && node2.v != null) {
|
|
2576
2662
|
const vInfo = { id: node2.v.id, version: node2.v.version };
|
|
2577
2663
|
if ("cid" in node2.v) {
|
|
2578
2664
|
vInfo.cid = node2.v.cid;
|
|
@@ -2580,6 +2666,16 @@ function describeNode(node2) {
|
|
|
2580
2666
|
}
|
|
2581
2667
|
out.v = vInfo;
|
|
2582
2668
|
}
|
|
2669
|
+
if (all || includeFields.has("guard")) {
|
|
2670
|
+
if (guard != null) {
|
|
2671
|
+
out.guard = accessHintForGuard(guard);
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
if (all || includeFields.has("lastMutation")) {
|
|
2675
|
+
if (node2.lastMutation != null) {
|
|
2676
|
+
out.lastMutation = node2.lastMutation;
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2583
2679
|
return out;
|
|
2584
2680
|
}
|
|
2585
2681
|
|
|
@@ -2769,6 +2865,23 @@ function resolveSpyTheme(theme) {
|
|
|
2769
2865
|
reset: theme.reset ?? ""
|
|
2770
2866
|
};
|
|
2771
2867
|
}
|
|
2868
|
+
function resolveObserveDetail(opts) {
|
|
2869
|
+
if (opts == null) return {};
|
|
2870
|
+
const detail = opts.detail;
|
|
2871
|
+
if (detail === "full") {
|
|
2872
|
+
return {
|
|
2873
|
+
...opts,
|
|
2874
|
+
structured: opts.structured ?? true,
|
|
2875
|
+
timeline: opts.timeline ?? true,
|
|
2876
|
+
causal: opts.causal ?? true,
|
|
2877
|
+
derived: opts.derived ?? true
|
|
2878
|
+
};
|
|
2879
|
+
}
|
|
2880
|
+
if (detail === "minimal") {
|
|
2881
|
+
return { ...opts, structured: opts.structured ?? true };
|
|
2882
|
+
}
|
|
2883
|
+
return opts;
|
|
2884
|
+
}
|
|
2772
2885
|
function assertLocalName(name, graphName, label) {
|
|
2773
2886
|
if (name === "") {
|
|
2774
2887
|
throw new Error(`Graph "${graphName}": ${label} name must be non-empty`);
|
|
@@ -2966,6 +3079,22 @@ var Graph = class _Graph {
|
|
|
2966
3079
|
if (this._defaultVersioningLevel != null) {
|
|
2967
3080
|
node2._applyVersioning(this._defaultVersioningLevel);
|
|
2968
3081
|
}
|
|
3082
|
+
if (node2._deps.length > 0) {
|
|
3083
|
+
for (const dep of node2._deps) {
|
|
3084
|
+
for (const [depName, depNode] of this._nodes) {
|
|
3085
|
+
if (depNode === dep) {
|
|
3086
|
+
this._edges.add(edgeKey(depName, name));
|
|
3087
|
+
break;
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
}
|
|
3091
|
+
}
|
|
3092
|
+
for (const [otherName, otherNode] of this._nodes) {
|
|
3093
|
+
if (otherName === name) continue;
|
|
3094
|
+
if (otherNode instanceof NodeImpl && otherNode._deps.includes(node2)) {
|
|
3095
|
+
this._edges.add(edgeKey(name, otherName));
|
|
3096
|
+
}
|
|
3097
|
+
}
|
|
2969
3098
|
}
|
|
2970
3099
|
}
|
|
2971
3100
|
/**
|
|
@@ -3352,6 +3481,9 @@ var Graph = class _Graph {
|
|
|
3352
3481
|
describe(options) {
|
|
3353
3482
|
const actor = options?.actor;
|
|
3354
3483
|
const filter = options?.filter;
|
|
3484
|
+
const includeFields = resolveDescribeFields(options?.detail, options?.fields);
|
|
3485
|
+
const isSpec = options?.format === "spec";
|
|
3486
|
+
const effectiveFields = isSpec ? resolveDescribeFields("minimal") : includeFields;
|
|
3355
3487
|
const targets = [];
|
|
3356
3488
|
this._collectObserveTargets("", targets);
|
|
3357
3489
|
const nodeToPath = /* @__PURE__ */ new Map();
|
|
@@ -3361,7 +3493,7 @@ var Graph = class _Graph {
|
|
|
3361
3493
|
const nodes = {};
|
|
3362
3494
|
for (const [p, n] of targets) {
|
|
3363
3495
|
if (actor != null && !n.allowsObserve(actor)) continue;
|
|
3364
|
-
const raw = describeNode(n);
|
|
3496
|
+
const raw = describeNode(n, effectiveFields);
|
|
3365
3497
|
const deps = n instanceof NodeImpl ? n._deps.map((d) => nodeToPath.get(d) ?? d.name ?? "") : [];
|
|
3366
3498
|
const { name: _name, ...rest } = raw;
|
|
3367
3499
|
const entry = { ...rest, deps };
|
|
@@ -3382,7 +3514,7 @@ var Graph = class _Graph {
|
|
|
3382
3514
|
continue;
|
|
3383
3515
|
}
|
|
3384
3516
|
if (normalizedKey === "metaHas") {
|
|
3385
|
-
if (!Object.hasOwn(entry.meta, String(fv))) {
|
|
3517
|
+
if (!Object.hasOwn(entry.meta ?? {}, String(fv))) {
|
|
3386
3518
|
match = false;
|
|
3387
3519
|
break;
|
|
3388
3520
|
}
|
|
@@ -3415,11 +3547,24 @@ var Graph = class _Graph {
|
|
|
3415
3547
|
const prefix = `${sg}${PATH_SEP}`;
|
|
3416
3548
|
return [...nodeKeys].some((k) => k === sg || k.startsWith(prefix));
|
|
3417
3549
|
}) : allSubgraphs;
|
|
3550
|
+
const graph = this;
|
|
3551
|
+
const baseOpts = options;
|
|
3418
3552
|
return {
|
|
3419
3553
|
name: this.name,
|
|
3420
3554
|
nodes,
|
|
3421
3555
|
edges,
|
|
3422
|
-
subgraphs
|
|
3556
|
+
subgraphs,
|
|
3557
|
+
expand(detailOrFields) {
|
|
3558
|
+
const merged = { ...baseOpts, format: void 0 };
|
|
3559
|
+
if (Array.isArray(detailOrFields)) {
|
|
3560
|
+
merged.fields = detailOrFields;
|
|
3561
|
+
merged.detail = void 0;
|
|
3562
|
+
} else {
|
|
3563
|
+
merged.detail = detailOrFields;
|
|
3564
|
+
merged.fields = void 0;
|
|
3565
|
+
}
|
|
3566
|
+
return graph.describe(merged);
|
|
3567
|
+
}
|
|
3423
3568
|
};
|
|
3424
3569
|
}
|
|
3425
3570
|
_collectSubgraphs(prefix) {
|
|
@@ -3472,14 +3617,15 @@ var Graph = class _Graph {
|
|
|
3472
3617
|
observe(pathOrOpts, options) {
|
|
3473
3618
|
if (typeof pathOrOpts === "string") {
|
|
3474
3619
|
const path = pathOrOpts;
|
|
3475
|
-
const
|
|
3620
|
+
const resolved = resolveObserveDetail(options);
|
|
3621
|
+
const actor2 = resolved.actor;
|
|
3476
3622
|
const target = this.resolve(path);
|
|
3477
3623
|
if (actor2 != null && !target.allowsObserve(actor2)) {
|
|
3478
3624
|
throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
|
|
3479
3625
|
}
|
|
3480
|
-
const wantsStructured2 =
|
|
3626
|
+
const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
|
|
3481
3627
|
if (wantsStructured2 && _Graph.inspectorEnabled) {
|
|
3482
|
-
return this._createObserveResult(path, target,
|
|
3628
|
+
return this._createObserveResult(path, target, resolved);
|
|
3483
3629
|
}
|
|
3484
3630
|
return {
|
|
3485
3631
|
subscribe(sink) {
|
|
@@ -3495,11 +3641,11 @@ var Graph = class _Graph {
|
|
|
3495
3641
|
}
|
|
3496
3642
|
};
|
|
3497
3643
|
}
|
|
3498
|
-
const opts = pathOrOpts;
|
|
3499
|
-
const actor = opts
|
|
3500
|
-
const wantsStructured = opts
|
|
3644
|
+
const opts = resolveObserveDetail(pathOrOpts);
|
|
3645
|
+
const actor = opts.actor;
|
|
3646
|
+
const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
|
|
3501
3647
|
if (wantsStructured && _Graph.inspectorEnabled) {
|
|
3502
|
-
return this._createObserveResultForAll(opts
|
|
3648
|
+
return this._createObserveResultForAll(opts);
|
|
3503
3649
|
}
|
|
3504
3650
|
return {
|
|
3505
3651
|
subscribe: (sink) => {
|
|
@@ -3531,6 +3677,7 @@ var Graph = class _Graph {
|
|
|
3531
3677
|
const timeline = options.timeline === true;
|
|
3532
3678
|
const causal = options.causal === true;
|
|
3533
3679
|
const derived2 = options.derived === true;
|
|
3680
|
+
const minimal = options.detail === "minimal";
|
|
3534
3681
|
const result = {
|
|
3535
3682
|
values: {},
|
|
3536
3683
|
dirtyCount: 0,
|
|
@@ -3576,6 +3723,11 @@ var Graph = class _Graph {
|
|
|
3576
3723
|
if (t === DATA) {
|
|
3577
3724
|
result.values[path] = m[1];
|
|
3578
3725
|
result.events.push({ type: "data", path, data: m[1], ...base, ...withCausal });
|
|
3726
|
+
} else if (minimal) {
|
|
3727
|
+
if (t === DIRTY) result.dirtyCount++;
|
|
3728
|
+
else if (t === RESOLVED) result.resolvedCount++;
|
|
3729
|
+
else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
|
|
3730
|
+
else if (t === ERROR) result.errored = true;
|
|
3579
3731
|
} else if (t === DIRTY) {
|
|
3580
3732
|
result.dirtyCount++;
|
|
3581
3733
|
result.events.push({ type: "dirty", path, ...base });
|
|
@@ -3591,6 +3743,8 @@ var Graph = class _Graph {
|
|
|
3591
3743
|
}
|
|
3592
3744
|
}
|
|
3593
3745
|
});
|
|
3746
|
+
const graph = this;
|
|
3747
|
+
const basePath = path;
|
|
3594
3748
|
return {
|
|
3595
3749
|
get values() {
|
|
3596
3750
|
return result.values;
|
|
@@ -3613,11 +3767,28 @@ var Graph = class _Graph {
|
|
|
3613
3767
|
dispose() {
|
|
3614
3768
|
unsub();
|
|
3615
3769
|
detachInspectorHook?.();
|
|
3770
|
+
},
|
|
3771
|
+
expand(extra) {
|
|
3772
|
+
unsub();
|
|
3773
|
+
detachInspectorHook?.();
|
|
3774
|
+
const merged = { ...options };
|
|
3775
|
+
if (typeof extra === "string") {
|
|
3776
|
+
merged.detail = extra;
|
|
3777
|
+
} else {
|
|
3778
|
+
Object.assign(merged, extra);
|
|
3779
|
+
}
|
|
3780
|
+
const resolvedTarget = graph.resolve(basePath);
|
|
3781
|
+
return graph._createObserveResult(
|
|
3782
|
+
basePath,
|
|
3783
|
+
resolvedTarget,
|
|
3784
|
+
resolveObserveDetail(merged)
|
|
3785
|
+
);
|
|
3616
3786
|
}
|
|
3617
3787
|
};
|
|
3618
3788
|
}
|
|
3619
3789
|
_createObserveResultForAll(options) {
|
|
3620
3790
|
const timeline = options.timeline === true;
|
|
3791
|
+
const minimal = options.detail === "minimal";
|
|
3621
3792
|
const result = {
|
|
3622
3793
|
values: {},
|
|
3623
3794
|
dirtyCount: 0,
|
|
@@ -3639,6 +3810,11 @@ var Graph = class _Graph {
|
|
|
3639
3810
|
if (t === DATA) {
|
|
3640
3811
|
result.values[path] = m[1];
|
|
3641
3812
|
result.events.push({ type: "data", path, data: m[1], ...base });
|
|
3813
|
+
} else if (minimal) {
|
|
3814
|
+
if (t === DIRTY) result.dirtyCount++;
|
|
3815
|
+
else if (t === RESOLVED) result.resolvedCount++;
|
|
3816
|
+
else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
|
|
3817
|
+
else if (t === ERROR) result.errored = true;
|
|
3642
3818
|
} else if (t === DIRTY) {
|
|
3643
3819
|
result.dirtyCount++;
|
|
3644
3820
|
result.events.push({ type: "dirty", path, ...base });
|
|
@@ -3655,6 +3831,7 @@ var Graph = class _Graph {
|
|
|
3655
3831
|
}
|
|
3656
3832
|
})
|
|
3657
3833
|
);
|
|
3834
|
+
const graph = this;
|
|
3658
3835
|
return {
|
|
3659
3836
|
get values() {
|
|
3660
3837
|
return result.values;
|
|
@@ -3676,6 +3853,16 @@ var Graph = class _Graph {
|
|
|
3676
3853
|
},
|
|
3677
3854
|
dispose() {
|
|
3678
3855
|
for (const u of unsubs) u();
|
|
3856
|
+
},
|
|
3857
|
+
expand(extra) {
|
|
3858
|
+
for (const u of unsubs) u();
|
|
3859
|
+
const merged = { ...options };
|
|
3860
|
+
if (typeof extra === "string") {
|
|
3861
|
+
merged.detail = extra;
|
|
3862
|
+
} else {
|
|
3863
|
+
Object.assign(merged, extra);
|
|
3864
|
+
}
|
|
3865
|
+
return graph._createObserveResultForAll(resolveObserveDetail(merged));
|
|
3679
3866
|
}
|
|
3680
3867
|
};
|
|
3681
3868
|
}
|
|
@@ -3751,6 +3938,9 @@ var Graph = class _Graph {
|
|
|
3751
3938
|
},
|
|
3752
3939
|
dispose() {
|
|
3753
3940
|
stop2();
|
|
3941
|
+
},
|
|
3942
|
+
expand() {
|
|
3943
|
+
throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
|
|
3754
3944
|
}
|
|
3755
3945
|
};
|
|
3756
3946
|
const pushEvent = (path, message) => {
|
|
@@ -3851,16 +4041,16 @@ var Graph = class _Graph {
|
|
|
3851
4041
|
* @returns Rendered graph text.
|
|
3852
4042
|
*/
|
|
3853
4043
|
dumpGraph(options = {}) {
|
|
3854
|
-
const described = this.describe({
|
|
4044
|
+
const { expand: _, ...described } = this.describe({
|
|
3855
4045
|
actor: options.actor,
|
|
3856
|
-
filter: options.filter
|
|
4046
|
+
filter: options.filter,
|
|
4047
|
+
detail: "standard"
|
|
3857
4048
|
});
|
|
3858
4049
|
const includeEdges = options.includeEdges ?? true;
|
|
3859
4050
|
const includeSubgraphs = options.includeSubgraphs ?? true;
|
|
3860
4051
|
if (options.format === "json") {
|
|
3861
4052
|
const payload = {
|
|
3862
|
-
|
|
3863
|
-
nodes: described.nodes,
|
|
4053
|
+
...described,
|
|
3864
4054
|
edges: includeEdges ? described.edges : [],
|
|
3865
4055
|
subgraphs: includeSubgraphs ? described.subgraphs : []
|
|
3866
4056
|
};
|
|
@@ -3930,10 +4120,11 @@ var Graph = class _Graph {
|
|
|
3930
4120
|
* @returns Persistable snapshot with sorted keys.
|
|
3931
4121
|
*/
|
|
3932
4122
|
snapshot() {
|
|
3933
|
-
const d = this.describe();
|
|
4123
|
+
const { expand: _, ...d } = this.describe({ detail: "full" });
|
|
3934
4124
|
const sortedNodes = {};
|
|
3935
4125
|
for (const key of Object.keys(d.nodes).sort()) {
|
|
3936
|
-
|
|
4126
|
+
const { lastMutation: _lm, guard: _g, ...node2 } = d.nodes[key];
|
|
4127
|
+
sortedNodes[key] = node2;
|
|
3937
4128
|
}
|
|
3938
4129
|
const sortedSubgraphs = [...d.subgraphs].sort();
|
|
3939
4130
|
return { ...d, version: 1, nodes: sortedNodes, subgraphs: sortedSubgraphs };
|
|
@@ -4049,20 +4240,28 @@ var Graph = class _Graph {
|
|
|
4049
4240
|
return g;
|
|
4050
4241
|
}
|
|
4051
4242
|
/**
|
|
4052
|
-
* Plain snapshot with **recursively sorted object keys** for deterministic serialization (§3.8).
|
|
4243
|
+
* Plain snapshot object with **recursively sorted object keys** for deterministic serialization (§3.8).
|
|
4053
4244
|
*
|
|
4054
4245
|
* @remarks
|
|
4055
|
-
* ECMAScript `JSON.stringify(graph)` invokes this method; it must return a plain object, not an
|
|
4056
|
-
* already-stringified JSON string (otherwise the graph would be double-encoded).
|
|
4057
4246
|
* For a single UTF-8 string with a trailing newline (convenient for git), use {@link Graph.toJSONString}.
|
|
4058
4247
|
*
|
|
4059
4248
|
* @returns Same object as {@link Graph.snapshot}.
|
|
4060
4249
|
*/
|
|
4061
|
-
|
|
4250
|
+
toObject() {
|
|
4062
4251
|
return this.snapshot();
|
|
4063
4252
|
}
|
|
4064
4253
|
/**
|
|
4065
|
-
*
|
|
4254
|
+
* ECMAScript `JSON.stringify` hook — delegates to {@link Graph.toObject}.
|
|
4255
|
+
*
|
|
4256
|
+
* @remarks
|
|
4257
|
+
* Must return a plain object (not a string) so `JSON.stringify(graph)` works correctly
|
|
4258
|
+
* without double-encoding.
|
|
4259
|
+
*/
|
|
4260
|
+
toJSON() {
|
|
4261
|
+
return this.toObject();
|
|
4262
|
+
}
|
|
4263
|
+
/**
|
|
4264
|
+
* Deterministic JSON **text**: `JSON.stringify` of {@link Graph.toObject} plus a trailing newline (§3.8).
|
|
4066
4265
|
*
|
|
4067
4266
|
* @returns Stable string suitable for diffs.
|
|
4068
4267
|
*/
|
|
@@ -4087,16 +4286,22 @@ var Graph = class _Graph {
|
|
|
4087
4286
|
if (!pending) return;
|
|
4088
4287
|
pending = false;
|
|
4089
4288
|
try {
|
|
4090
|
-
const
|
|
4289
|
+
const { expand: _expand, ...raw } = this.describe({ detail: "full" });
|
|
4290
|
+
const cleanNodes = {};
|
|
4291
|
+
for (const [p, n] of Object.entries(raw.nodes)) {
|
|
4292
|
+
const { lastMutation: _lm, guard: _g, ...node2 } = n;
|
|
4293
|
+
cleanNodes[p] = node2;
|
|
4294
|
+
}
|
|
4295
|
+
const described = { ...raw, nodes: cleanNodes };
|
|
4091
4296
|
const snapshot = { ...described, version: SNAPSHOT_VERSION };
|
|
4092
4297
|
seq += 1;
|
|
4093
4298
|
const shouldCompact = lastDescribe == null || seq % compactEvery === 0;
|
|
4094
4299
|
if (shouldCompact) {
|
|
4095
|
-
adapter.save({ mode: "full", snapshot, seq });
|
|
4300
|
+
adapter.save(this.name, { mode: "full", snapshot, seq });
|
|
4096
4301
|
} else {
|
|
4097
4302
|
const previous = lastDescribe;
|
|
4098
4303
|
if (previous == null) return;
|
|
4099
|
-
adapter.save({
|
|
4304
|
+
adapter.save(this.name, {
|
|
4100
4305
|
mode: "diff",
|
|
4101
4306
|
diff: _Graph.diff(previous, described),
|
|
4102
4307
|
snapshot,
|
|
@@ -4117,8 +4322,10 @@ var Graph = class _Graph {
|
|
|
4117
4322
|
const triggeredByTier = messages.some((m) => messageTier(m[0]) >= 2);
|
|
4118
4323
|
if (!triggeredByTier) return;
|
|
4119
4324
|
if (options.filter) {
|
|
4120
|
-
const
|
|
4121
|
-
if (
|
|
4325
|
+
const nd = this.resolve(path);
|
|
4326
|
+
if (nd == null) return;
|
|
4327
|
+
const described = describeNode(nd, resolveDescribeFields("standard"));
|
|
4328
|
+
if (!options.filter(path, described)) return;
|
|
4122
4329
|
}
|
|
4123
4330
|
schedule();
|
|
4124
4331
|
});
|