@graphrefly/graphrefly 0.6.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-V3UACY6A.js → chunk-ONLYF6GA.js} +790 -203
- 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 +863 -206
- 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 +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-Bk_idZm1.d.cts → index-D1hgSTzr.d.cts} +406 -61
- 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-B2jmzVxL.d.ts → index-Pm68AYPh.d.ts} +406 -61
- package/dist/index.cjs +2929 -1775
- 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 +392 -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-V3UACY6A.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
|
@@ -544,9 +544,9 @@ declare function node<T = unknown>(depsOrFn?: readonly Node[] | NodeFn<T> | Node
|
|
|
544
544
|
/** JSON-shaped slice of a node for Phase 1 `Graph.describe()` (GRAPHREFLY-SPEC §3.6, Appendix B). */
|
|
545
545
|
type DescribeNodeOutput = {
|
|
546
546
|
type: "state" | "derived" | "producer" | "operator" | "effect";
|
|
547
|
-
status
|
|
547
|
+
status?: Node["status"];
|
|
548
548
|
deps: string[];
|
|
549
|
-
meta
|
|
549
|
+
meta?: Record<string, unknown>;
|
|
550
550
|
name?: string;
|
|
551
551
|
value?: unknown;
|
|
552
552
|
/** Node versioning info (GRAPHREFLY-SPEC §7). Present only when versioning is enabled. */
|
|
@@ -556,7 +556,28 @@ type DescribeNodeOutput = {
|
|
|
556
556
|
cid?: string;
|
|
557
557
|
prev?: string | null;
|
|
558
558
|
};
|
|
559
|
+
/** Guard info (full detail). */
|
|
560
|
+
guard?: string;
|
|
561
|
+
/** Last mutation attribution (full detail). */
|
|
562
|
+
lastMutation?: Readonly<{
|
|
563
|
+
actor: Actor;
|
|
564
|
+
timestamp_ns: number;
|
|
565
|
+
}>;
|
|
559
566
|
};
|
|
567
|
+
/**
|
|
568
|
+
* Detail level for `describe()` progressive disclosure (Phase 3.3b).
|
|
569
|
+
* - `"minimal"` — type + deps only (default). LLM-friendly.
|
|
570
|
+
* - `"standard"` — type, status, value, deps, meta, versioning (`v`).
|
|
571
|
+
* - `"full"` — standard + guard, lastMutation.
|
|
572
|
+
*/
|
|
573
|
+
type DescribeDetail = "minimal" | "standard" | "full";
|
|
574
|
+
/**
|
|
575
|
+
* Valid field names for `describe({ fields: [...] })` (Phase 3.3b).
|
|
576
|
+
* Dotted paths like `"meta.label"` select specific meta keys.
|
|
577
|
+
*/
|
|
578
|
+
type DescribeField = "type" | "status" | "value" | "deps" | "meta" | "v" | "guard" | "lastMutation" | `meta.${string}`;
|
|
579
|
+
/** Resolve which fields to include based on detail level or explicit field list. */
|
|
580
|
+
declare function resolveDescribeFields(detail?: DescribeDetail, fields?: readonly DescribeField[]): Set<string> | null;
|
|
560
581
|
/**
|
|
561
582
|
* Reads the current cached value of every companion meta field on a node,
|
|
562
583
|
* suitable for merging into `describe()`-style JSON (GRAPHREFLY-SPEC §2.3, §3.6).
|
|
@@ -602,6 +623,12 @@ declare function metaSnapshot(node: Node): Record<string, unknown>;
|
|
|
602
623
|
* describeNode(state(0));
|
|
603
624
|
* ```
|
|
604
625
|
*/
|
|
605
|
-
|
|
626
|
+
/**
|
|
627
|
+
* Builds a single-node slice for `Graph.describe()`.
|
|
628
|
+
*
|
|
629
|
+
* @param node - Node to introspect.
|
|
630
|
+
* @param includeFields - Set of fields to include, or `null` for all. When omitted, all fields are included (legacy behavior).
|
|
631
|
+
*/
|
|
632
|
+
declare function describeNode(node: Node, includeFields?: Set<string> | null): DescribeNodeOutput;
|
|
606
633
|
|
|
607
|
-
export {
|
|
634
|
+
export { policy as $, type Actor as A, createVersioning as B, COMPLETE as C, DATA as D, ERROR as E, defaultHash as F, type GuardAction as G, type HashFn as H, INVALIDATE as I, describeNode as J, isKnownMessageType as K, isPhase2Message as L, type Message as M, type Node as N, type OnMessageHandler as O, PAUSE as P, isTerminalMessage as Q, RESOLVED as R, type SubscribeHints as S, TEARDOWN as T, isV1 as U, type V0 as V, knownMessageTypes as W, messageTier as X, metaSnapshot as Y, node as Z, normalizeActor as _, type NodeOptions as a, policyFromRules as a0, propagatesToMeta as a1, resolveDescribeFields as a2, type NodeInspectorHook as a3, type NodeActions as b, type NodeFn as c, DEFAULT_ACTOR as d, DIRTY as e, type DescribeDetail as f, type DescribeField as g, type DescribeNodeOutput as h, GuardDenied as i, type GuardDeniedDetails as j, type Messages as k, type NodeDescribeKind as l, type NodeGuard as m, type NodeSink as n, type NodeStatus as o, type NodeTransportOptions as p, type NodeVersionInfo as q, type PolicyAllow as r, type PolicyDeny as s, type PolicyRuleData as t, RESUME as u, type V1 as v, type VersioningLevel as w, type VersioningOptions as x, accessHintForGuard as y, advanceVersion as z };
|
|
@@ -544,9 +544,9 @@ declare function node<T = unknown>(depsOrFn?: readonly Node[] | NodeFn<T> | Node
|
|
|
544
544
|
/** JSON-shaped slice of a node for Phase 1 `Graph.describe()` (GRAPHREFLY-SPEC §3.6, Appendix B). */
|
|
545
545
|
type DescribeNodeOutput = {
|
|
546
546
|
type: "state" | "derived" | "producer" | "operator" | "effect";
|
|
547
|
-
status
|
|
547
|
+
status?: Node["status"];
|
|
548
548
|
deps: string[];
|
|
549
|
-
meta
|
|
549
|
+
meta?: Record<string, unknown>;
|
|
550
550
|
name?: string;
|
|
551
551
|
value?: unknown;
|
|
552
552
|
/** Node versioning info (GRAPHREFLY-SPEC §7). Present only when versioning is enabled. */
|
|
@@ -556,7 +556,28 @@ type DescribeNodeOutput = {
|
|
|
556
556
|
cid?: string;
|
|
557
557
|
prev?: string | null;
|
|
558
558
|
};
|
|
559
|
+
/** Guard info (full detail). */
|
|
560
|
+
guard?: string;
|
|
561
|
+
/** Last mutation attribution (full detail). */
|
|
562
|
+
lastMutation?: Readonly<{
|
|
563
|
+
actor: Actor;
|
|
564
|
+
timestamp_ns: number;
|
|
565
|
+
}>;
|
|
559
566
|
};
|
|
567
|
+
/**
|
|
568
|
+
* Detail level for `describe()` progressive disclosure (Phase 3.3b).
|
|
569
|
+
* - `"minimal"` — type + deps only (default). LLM-friendly.
|
|
570
|
+
* - `"standard"` — type, status, value, deps, meta, versioning (`v`).
|
|
571
|
+
* - `"full"` — standard + guard, lastMutation.
|
|
572
|
+
*/
|
|
573
|
+
type DescribeDetail = "minimal" | "standard" | "full";
|
|
574
|
+
/**
|
|
575
|
+
* Valid field names for `describe({ fields: [...] })` (Phase 3.3b).
|
|
576
|
+
* Dotted paths like `"meta.label"` select specific meta keys.
|
|
577
|
+
*/
|
|
578
|
+
type DescribeField = "type" | "status" | "value" | "deps" | "meta" | "v" | "guard" | "lastMutation" | `meta.${string}`;
|
|
579
|
+
/** Resolve which fields to include based on detail level or explicit field list. */
|
|
580
|
+
declare function resolveDescribeFields(detail?: DescribeDetail, fields?: readonly DescribeField[]): Set<string> | null;
|
|
560
581
|
/**
|
|
561
582
|
* Reads the current cached value of every companion meta field on a node,
|
|
562
583
|
* suitable for merging into `describe()`-style JSON (GRAPHREFLY-SPEC §2.3, §3.6).
|
|
@@ -602,6 +623,12 @@ declare function metaSnapshot(node: Node): Record<string, unknown>;
|
|
|
602
623
|
* describeNode(state(0));
|
|
603
624
|
* ```
|
|
604
625
|
*/
|
|
605
|
-
|
|
626
|
+
/**
|
|
627
|
+
* Builds a single-node slice for `Graph.describe()`.
|
|
628
|
+
*
|
|
629
|
+
* @param node - Node to introspect.
|
|
630
|
+
* @param includeFields - Set of fields to include, or `null` for all. When omitted, all fields are included (legacy behavior).
|
|
631
|
+
*/
|
|
632
|
+
declare function describeNode(node: Node, includeFields?: Set<string> | null): DescribeNodeOutput;
|
|
606
633
|
|
|
607
|
-
export {
|
|
634
|
+
export { policy as $, type Actor as A, createVersioning as B, COMPLETE as C, DATA as D, ERROR as E, defaultHash as F, type GuardAction as G, type HashFn as H, INVALIDATE as I, describeNode as J, isKnownMessageType as K, isPhase2Message as L, type Message as M, type Node as N, type OnMessageHandler as O, PAUSE as P, isTerminalMessage as Q, RESOLVED as R, type SubscribeHints as S, TEARDOWN as T, isV1 as U, type V0 as V, knownMessageTypes as W, messageTier as X, metaSnapshot as Y, node as Z, normalizeActor as _, type NodeOptions as a, policyFromRules as a0, propagatesToMeta as a1, resolveDescribeFields as a2, type NodeInspectorHook as a3, type NodeActions as b, type NodeFn as c, DEFAULT_ACTOR as d, DIRTY as e, type DescribeDetail as f, type DescribeField as g, type DescribeNodeOutput as h, GuardDenied as i, type GuardDeniedDetails as j, type Messages as k, type NodeDescribeKind as l, type NodeGuard as m, type NodeSink as n, type NodeStatus as o, type NodeTransportOptions as p, type NodeVersionInfo as q, type PolicyAllow as r, type PolicyDeny as s, type PolicyRuleData as t, RESUME as u, type V1 as v, type VersioningLevel as w, type VersioningOptions as x, accessHintForGuard as y, advanceVersion as z };
|
|
@@ -368,10 +368,14 @@ function partitionForBatch(messages) {
|
|
|
368
368
|
}
|
|
369
369
|
return { immediate, deferred, terminal };
|
|
370
370
|
}
|
|
371
|
-
function emitWithBatch(emit, messages, phase = 2) {
|
|
371
|
+
function emitWithBatch(emit, messages, phase = 2, options) {
|
|
372
372
|
if (messages.length === 0) {
|
|
373
373
|
return;
|
|
374
374
|
}
|
|
375
|
+
if (options?.strategy === "sequential") {
|
|
376
|
+
_emitSequential(emit, messages, phase);
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
375
379
|
const queue = phase === 3 ? pendingPhase3 : pendingPhase2;
|
|
376
380
|
if (messages.length === 1) {
|
|
377
381
|
const t = messages[0][0];
|
|
@@ -412,6 +416,29 @@ function emitWithBatch(emit, messages, phase = 2) {
|
|
|
412
416
|
}
|
|
413
417
|
}
|
|
414
418
|
}
|
|
419
|
+
function _emitSequential(emit, messages, phase = 2) {
|
|
420
|
+
const dataQueue = phase === 3 ? pendingPhase3 : pendingPhase2;
|
|
421
|
+
for (const msg of messages) {
|
|
422
|
+
const tier = messageTier(msg[0]);
|
|
423
|
+
if (tier === 2) {
|
|
424
|
+
if (isBatching()) {
|
|
425
|
+
const m = msg;
|
|
426
|
+
dataQueue.push(() => emit([m]));
|
|
427
|
+
} else {
|
|
428
|
+
emit([msg]);
|
|
429
|
+
}
|
|
430
|
+
} else if (tier >= 3) {
|
|
431
|
+
if (isBatching()) {
|
|
432
|
+
const m = msg;
|
|
433
|
+
pendingPhase3.push(() => emit([m]));
|
|
434
|
+
} else {
|
|
435
|
+
emit([msg]);
|
|
436
|
+
}
|
|
437
|
+
} else {
|
|
438
|
+
emit([msg]);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
415
442
|
|
|
416
443
|
// src/core/clock.ts
|
|
417
444
|
function monotonicNs() {
|
|
@@ -620,6 +647,7 @@ var NodeImpl = class {
|
|
|
620
647
|
_producerStarted = false;
|
|
621
648
|
_connecting = false;
|
|
622
649
|
_manualEmitUsed = false;
|
|
650
|
+
_hasEmittedData = false;
|
|
623
651
|
_sinkCount = 0;
|
|
624
652
|
_singleDepSinkCount = 0;
|
|
625
653
|
// --- Object/collection state ---
|
|
@@ -906,6 +934,7 @@ var NodeImpl = class {
|
|
|
906
934
|
this._cleanup = void 0;
|
|
907
935
|
cleanupFn?.();
|
|
908
936
|
this._cached = void 0;
|
|
937
|
+
this._hasEmittedData = false;
|
|
909
938
|
this._lastDepValues = void 0;
|
|
910
939
|
}
|
|
911
940
|
this._status = statusAfterMessage(this._status, m);
|
|
@@ -915,6 +944,7 @@ var NodeImpl = class {
|
|
|
915
944
|
if (t === TEARDOWN) {
|
|
916
945
|
if (this._opts.resetOnTeardown) {
|
|
917
946
|
this._cached = void 0;
|
|
947
|
+
this._hasEmittedData = false;
|
|
918
948
|
}
|
|
919
949
|
const teardownCleanup = this._cleanup;
|
|
920
950
|
this._cleanup = void 0;
|
|
@@ -945,7 +975,16 @@ var NodeImpl = class {
|
|
|
945
975
|
}
|
|
946
976
|
_emitAutoValue(value) {
|
|
947
977
|
const wasDirty = this._status === "dirty";
|
|
948
|
-
|
|
978
|
+
let unchanged;
|
|
979
|
+
try {
|
|
980
|
+
unchanged = this._hasEmittedData && this._equals(this._cached, value);
|
|
981
|
+
} catch (eqErr) {
|
|
982
|
+
const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
|
|
983
|
+
const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
|
|
984
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
this._hasEmittedData = true;
|
|
949
988
|
if (unchanged) {
|
|
950
989
|
this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
|
|
951
990
|
return;
|
|
@@ -992,7 +1031,9 @@ var NodeImpl = class {
|
|
|
992
1031
|
if (out === void 0) return;
|
|
993
1032
|
this._emitAutoValue(out);
|
|
994
1033
|
} catch (err) {
|
|
995
|
-
|
|
1034
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1035
|
+
const wrapped = new Error(`Node "${this.name}": fn threw: ${errMsg}`, { cause: err });
|
|
1036
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
996
1037
|
}
|
|
997
1038
|
}
|
|
998
1039
|
_onDepDirty(index) {
|
|
@@ -1027,7 +1068,11 @@ var NodeImpl = class {
|
|
|
1027
1068
|
try {
|
|
1028
1069
|
if (this._onMessage(msg, index, this._actions)) continue;
|
|
1029
1070
|
} catch (err) {
|
|
1030
|
-
|
|
1071
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1072
|
+
const wrapped = new Error(`Node "${this.name}": onMessage threw: ${errMsg}`, {
|
|
1073
|
+
cause: err
|
|
1074
|
+
});
|
|
1075
|
+
this._downInternal([[ERROR, wrapped]]);
|
|
1031
1076
|
return;
|
|
1032
1077
|
}
|
|
1033
1078
|
}
|
|
@@ -1600,6 +1645,19 @@ var DynamicNodeImpl = class {
|
|
|
1600
1645
|
};
|
|
1601
1646
|
|
|
1602
1647
|
// src/core/meta.ts
|
|
1648
|
+
function resolveDescribeFields(detail, fields) {
|
|
1649
|
+
if (fields != null && fields.length > 0) return new Set(fields);
|
|
1650
|
+
switch (detail) {
|
|
1651
|
+
case "standard":
|
|
1652
|
+
return /* @__PURE__ */ new Set(["type", "status", "value", "deps", "meta", "v"]);
|
|
1653
|
+
case "full":
|
|
1654
|
+
return null;
|
|
1655
|
+
// null = include everything
|
|
1656
|
+
case "minimal":
|
|
1657
|
+
default:
|
|
1658
|
+
return /* @__PURE__ */ new Set(["type", "deps"]);
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1603
1661
|
function inferDescribeType(n) {
|
|
1604
1662
|
if (n._describeKind != null) return n._describeKind;
|
|
1605
1663
|
if (!n._hasDeps) return n._fn != null ? "producer" : "state";
|
|
@@ -1617,12 +1675,10 @@ function metaSnapshot(node2) {
|
|
|
1617
1675
|
}
|
|
1618
1676
|
return out;
|
|
1619
1677
|
}
|
|
1620
|
-
function describeNode(node2) {
|
|
1621
|
-
const
|
|
1622
|
-
const
|
|
1623
|
-
|
|
1624
|
-
meta.access = accessHintForGuard(guard);
|
|
1625
|
-
}
|
|
1678
|
+
function describeNode(node2, includeFields) {
|
|
1679
|
+
const all = includeFields == null;
|
|
1680
|
+
const metaKeys = !all && includeFields != null ? [...includeFields].filter((f) => f.startsWith("meta.")).map((f) => f.slice(5)) : null;
|
|
1681
|
+
const wantsMeta = all || includeFields.has("meta") || metaKeys != null && metaKeys.length > 0;
|
|
1626
1682
|
let type = "state";
|
|
1627
1683
|
let deps = [];
|
|
1628
1684
|
if (node2 instanceof NodeImpl) {
|
|
@@ -1632,20 +1688,36 @@ function describeNode(node2) {
|
|
|
1632
1688
|
type = node2._describeKind ?? "derived";
|
|
1633
1689
|
deps = [];
|
|
1634
1690
|
}
|
|
1635
|
-
const out = {
|
|
1636
|
-
|
|
1637
|
-
status
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1691
|
+
const out = { type, deps };
|
|
1692
|
+
if (all || includeFields.has("status")) {
|
|
1693
|
+
out.status = node2.status;
|
|
1694
|
+
}
|
|
1695
|
+
const guard = node2 instanceof NodeImpl && node2._guard || node2 instanceof DynamicNodeImpl && node2._guard || void 0;
|
|
1696
|
+
if (wantsMeta) {
|
|
1697
|
+
const rawMeta = { ...metaSnapshot(node2) };
|
|
1698
|
+
if (guard != null && rawMeta.access === void 0) {
|
|
1699
|
+
rawMeta.access = accessHintForGuard(guard);
|
|
1700
|
+
}
|
|
1701
|
+
if (metaKeys != null && metaKeys.length > 0 && !includeFields.has("meta")) {
|
|
1702
|
+
const filtered = {};
|
|
1703
|
+
for (const k of metaKeys) {
|
|
1704
|
+
if (k in rawMeta) filtered[k] = rawMeta[k];
|
|
1705
|
+
}
|
|
1706
|
+
out.meta = filtered;
|
|
1707
|
+
} else {
|
|
1708
|
+
out.meta = rawMeta;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1641
1711
|
if (node2.name != null) {
|
|
1642
1712
|
out.name = node2.name;
|
|
1643
1713
|
}
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1714
|
+
if (all || includeFields.has("value")) {
|
|
1715
|
+
try {
|
|
1716
|
+
out.value = node2.get();
|
|
1717
|
+
} catch {
|
|
1718
|
+
}
|
|
1647
1719
|
}
|
|
1648
|
-
if (node2.v != null) {
|
|
1720
|
+
if ((all || includeFields.has("v")) && node2.v != null) {
|
|
1649
1721
|
const vInfo = { id: node2.v.id, version: node2.v.version };
|
|
1650
1722
|
if ("cid" in node2.v) {
|
|
1651
1723
|
vInfo.cid = node2.v.cid;
|
|
@@ -1653,6 +1725,16 @@ function describeNode(node2) {
|
|
|
1653
1725
|
}
|
|
1654
1726
|
out.v = vInfo;
|
|
1655
1727
|
}
|
|
1728
|
+
if (all || includeFields.has("guard")) {
|
|
1729
|
+
if (guard != null) {
|
|
1730
|
+
out.guard = accessHintForGuard(guard);
|
|
1731
|
+
}
|
|
1732
|
+
}
|
|
1733
|
+
if (all || includeFields.has("lastMutation")) {
|
|
1734
|
+
if (node2.lastMutation != null) {
|
|
1735
|
+
out.lastMutation = node2.lastMutation;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1656
1738
|
return out;
|
|
1657
1739
|
}
|
|
1658
1740
|
|
|
@@ -1842,6 +1924,23 @@ function resolveSpyTheme(theme) {
|
|
|
1842
1924
|
reset: theme.reset ?? ""
|
|
1843
1925
|
};
|
|
1844
1926
|
}
|
|
1927
|
+
function resolveObserveDetail(opts) {
|
|
1928
|
+
if (opts == null) return {};
|
|
1929
|
+
const detail = opts.detail;
|
|
1930
|
+
if (detail === "full") {
|
|
1931
|
+
return {
|
|
1932
|
+
...opts,
|
|
1933
|
+
structured: opts.structured ?? true,
|
|
1934
|
+
timeline: opts.timeline ?? true,
|
|
1935
|
+
causal: opts.causal ?? true,
|
|
1936
|
+
derived: opts.derived ?? true
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1939
|
+
if (detail === "minimal") {
|
|
1940
|
+
return { ...opts, structured: opts.structured ?? true };
|
|
1941
|
+
}
|
|
1942
|
+
return opts;
|
|
1943
|
+
}
|
|
1845
1944
|
function assertLocalName(name, graphName, label) {
|
|
1846
1945
|
if (name === "") {
|
|
1847
1946
|
throw new Error(`Graph "${graphName}": ${label} name must be non-empty`);
|
|
@@ -2039,6 +2138,22 @@ var Graph = class _Graph {
|
|
|
2039
2138
|
if (this._defaultVersioningLevel != null) {
|
|
2040
2139
|
node2._applyVersioning(this._defaultVersioningLevel);
|
|
2041
2140
|
}
|
|
2141
|
+
if (node2._deps.length > 0) {
|
|
2142
|
+
for (const dep of node2._deps) {
|
|
2143
|
+
for (const [depName, depNode] of this._nodes) {
|
|
2144
|
+
if (depNode === dep) {
|
|
2145
|
+
this._edges.add(edgeKey(depName, name));
|
|
2146
|
+
break;
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
for (const [otherName, otherNode] of this._nodes) {
|
|
2152
|
+
if (otherName === name) continue;
|
|
2153
|
+
if (otherNode instanceof NodeImpl && otherNode._deps.includes(node2)) {
|
|
2154
|
+
this._edges.add(edgeKey(name, otherName));
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2042
2157
|
}
|
|
2043
2158
|
}
|
|
2044
2159
|
/**
|
|
@@ -2425,6 +2540,9 @@ var Graph = class _Graph {
|
|
|
2425
2540
|
describe(options) {
|
|
2426
2541
|
const actor = options?.actor;
|
|
2427
2542
|
const filter = options?.filter;
|
|
2543
|
+
const includeFields = resolveDescribeFields(options?.detail, options?.fields);
|
|
2544
|
+
const isSpec = options?.format === "spec";
|
|
2545
|
+
const effectiveFields = isSpec ? resolveDescribeFields("minimal") : includeFields;
|
|
2428
2546
|
const targets = [];
|
|
2429
2547
|
this._collectObserveTargets("", targets);
|
|
2430
2548
|
const nodeToPath = /* @__PURE__ */ new Map();
|
|
@@ -2434,7 +2552,7 @@ var Graph = class _Graph {
|
|
|
2434
2552
|
const nodes = {};
|
|
2435
2553
|
for (const [p, n] of targets) {
|
|
2436
2554
|
if (actor != null && !n.allowsObserve(actor)) continue;
|
|
2437
|
-
const raw = describeNode(n);
|
|
2555
|
+
const raw = describeNode(n, effectiveFields);
|
|
2438
2556
|
const deps = n instanceof NodeImpl ? n._deps.map((d) => nodeToPath.get(d) ?? d.name ?? "") : [];
|
|
2439
2557
|
const { name: _name, ...rest } = raw;
|
|
2440
2558
|
const entry = { ...rest, deps };
|
|
@@ -2455,7 +2573,7 @@ var Graph = class _Graph {
|
|
|
2455
2573
|
continue;
|
|
2456
2574
|
}
|
|
2457
2575
|
if (normalizedKey === "metaHas") {
|
|
2458
|
-
if (!Object.hasOwn(entry.meta, String(fv))) {
|
|
2576
|
+
if (!Object.hasOwn(entry.meta ?? {}, String(fv))) {
|
|
2459
2577
|
match = false;
|
|
2460
2578
|
break;
|
|
2461
2579
|
}
|
|
@@ -2488,11 +2606,24 @@ var Graph = class _Graph {
|
|
|
2488
2606
|
const prefix = `${sg}${PATH_SEP}`;
|
|
2489
2607
|
return [...nodeKeys].some((k) => k === sg || k.startsWith(prefix));
|
|
2490
2608
|
}) : allSubgraphs;
|
|
2609
|
+
const graph = this;
|
|
2610
|
+
const baseOpts = options;
|
|
2491
2611
|
return {
|
|
2492
2612
|
name: this.name,
|
|
2493
2613
|
nodes,
|
|
2494
2614
|
edges,
|
|
2495
|
-
subgraphs
|
|
2615
|
+
subgraphs,
|
|
2616
|
+
expand(detailOrFields) {
|
|
2617
|
+
const merged = { ...baseOpts, format: void 0 };
|
|
2618
|
+
if (Array.isArray(detailOrFields)) {
|
|
2619
|
+
merged.fields = detailOrFields;
|
|
2620
|
+
merged.detail = void 0;
|
|
2621
|
+
} else {
|
|
2622
|
+
merged.detail = detailOrFields;
|
|
2623
|
+
merged.fields = void 0;
|
|
2624
|
+
}
|
|
2625
|
+
return graph.describe(merged);
|
|
2626
|
+
}
|
|
2496
2627
|
};
|
|
2497
2628
|
}
|
|
2498
2629
|
_collectSubgraphs(prefix) {
|
|
@@ -2545,14 +2676,15 @@ var Graph = class _Graph {
|
|
|
2545
2676
|
observe(pathOrOpts, options) {
|
|
2546
2677
|
if (typeof pathOrOpts === "string") {
|
|
2547
2678
|
const path = pathOrOpts;
|
|
2548
|
-
const
|
|
2679
|
+
const resolved = resolveObserveDetail(options);
|
|
2680
|
+
const actor2 = resolved.actor;
|
|
2549
2681
|
const target = this.resolve(path);
|
|
2550
2682
|
if (actor2 != null && !target.allowsObserve(actor2)) {
|
|
2551
2683
|
throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
|
|
2552
2684
|
}
|
|
2553
|
-
const wantsStructured2 =
|
|
2685
|
+
const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
|
|
2554
2686
|
if (wantsStructured2 && _Graph.inspectorEnabled) {
|
|
2555
|
-
return this._createObserveResult(path, target,
|
|
2687
|
+
return this._createObserveResult(path, target, resolved);
|
|
2556
2688
|
}
|
|
2557
2689
|
return {
|
|
2558
2690
|
subscribe(sink) {
|
|
@@ -2568,11 +2700,11 @@ var Graph = class _Graph {
|
|
|
2568
2700
|
}
|
|
2569
2701
|
};
|
|
2570
2702
|
}
|
|
2571
|
-
const opts = pathOrOpts;
|
|
2572
|
-
const actor = opts
|
|
2573
|
-
const wantsStructured = opts
|
|
2703
|
+
const opts = resolveObserveDetail(pathOrOpts);
|
|
2704
|
+
const actor = opts.actor;
|
|
2705
|
+
const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
|
|
2574
2706
|
if (wantsStructured && _Graph.inspectorEnabled) {
|
|
2575
|
-
return this._createObserveResultForAll(opts
|
|
2707
|
+
return this._createObserveResultForAll(opts);
|
|
2576
2708
|
}
|
|
2577
2709
|
return {
|
|
2578
2710
|
subscribe: (sink) => {
|
|
@@ -2604,6 +2736,7 @@ var Graph = class _Graph {
|
|
|
2604
2736
|
const timeline = options.timeline === true;
|
|
2605
2737
|
const causal = options.causal === true;
|
|
2606
2738
|
const derived2 = options.derived === true;
|
|
2739
|
+
const minimal = options.detail === "minimal";
|
|
2607
2740
|
const result = {
|
|
2608
2741
|
values: {},
|
|
2609
2742
|
dirtyCount: 0,
|
|
@@ -2649,6 +2782,11 @@ var Graph = class _Graph {
|
|
|
2649
2782
|
if (t === DATA) {
|
|
2650
2783
|
result.values[path] = m[1];
|
|
2651
2784
|
result.events.push({ type: "data", path, data: m[1], ...base, ...withCausal });
|
|
2785
|
+
} else if (minimal) {
|
|
2786
|
+
if (t === DIRTY) result.dirtyCount++;
|
|
2787
|
+
else if (t === RESOLVED) result.resolvedCount++;
|
|
2788
|
+
else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
|
|
2789
|
+
else if (t === ERROR) result.errored = true;
|
|
2652
2790
|
} else if (t === DIRTY) {
|
|
2653
2791
|
result.dirtyCount++;
|
|
2654
2792
|
result.events.push({ type: "dirty", path, ...base });
|
|
@@ -2664,6 +2802,8 @@ var Graph = class _Graph {
|
|
|
2664
2802
|
}
|
|
2665
2803
|
}
|
|
2666
2804
|
});
|
|
2805
|
+
const graph = this;
|
|
2806
|
+
const basePath = path;
|
|
2667
2807
|
return {
|
|
2668
2808
|
get values() {
|
|
2669
2809
|
return result.values;
|
|
@@ -2686,11 +2826,28 @@ var Graph = class _Graph {
|
|
|
2686
2826
|
dispose() {
|
|
2687
2827
|
unsub();
|
|
2688
2828
|
detachInspectorHook?.();
|
|
2829
|
+
},
|
|
2830
|
+
expand(extra) {
|
|
2831
|
+
unsub();
|
|
2832
|
+
detachInspectorHook?.();
|
|
2833
|
+
const merged = { ...options };
|
|
2834
|
+
if (typeof extra === "string") {
|
|
2835
|
+
merged.detail = extra;
|
|
2836
|
+
} else {
|
|
2837
|
+
Object.assign(merged, extra);
|
|
2838
|
+
}
|
|
2839
|
+
const resolvedTarget = graph.resolve(basePath);
|
|
2840
|
+
return graph._createObserveResult(
|
|
2841
|
+
basePath,
|
|
2842
|
+
resolvedTarget,
|
|
2843
|
+
resolveObserveDetail(merged)
|
|
2844
|
+
);
|
|
2689
2845
|
}
|
|
2690
2846
|
};
|
|
2691
2847
|
}
|
|
2692
2848
|
_createObserveResultForAll(options) {
|
|
2693
2849
|
const timeline = options.timeline === true;
|
|
2850
|
+
const minimal = options.detail === "minimal";
|
|
2694
2851
|
const result = {
|
|
2695
2852
|
values: {},
|
|
2696
2853
|
dirtyCount: 0,
|
|
@@ -2712,6 +2869,11 @@ var Graph = class _Graph {
|
|
|
2712
2869
|
if (t === DATA) {
|
|
2713
2870
|
result.values[path] = m[1];
|
|
2714
2871
|
result.events.push({ type: "data", path, data: m[1], ...base });
|
|
2872
|
+
} else if (minimal) {
|
|
2873
|
+
if (t === DIRTY) result.dirtyCount++;
|
|
2874
|
+
else if (t === RESOLVED) result.resolvedCount++;
|
|
2875
|
+
else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
|
|
2876
|
+
else if (t === ERROR) result.errored = true;
|
|
2715
2877
|
} else if (t === DIRTY) {
|
|
2716
2878
|
result.dirtyCount++;
|
|
2717
2879
|
result.events.push({ type: "dirty", path, ...base });
|
|
@@ -2728,6 +2890,7 @@ var Graph = class _Graph {
|
|
|
2728
2890
|
}
|
|
2729
2891
|
})
|
|
2730
2892
|
);
|
|
2893
|
+
const graph = this;
|
|
2731
2894
|
return {
|
|
2732
2895
|
get values() {
|
|
2733
2896
|
return result.values;
|
|
@@ -2749,6 +2912,16 @@ var Graph = class _Graph {
|
|
|
2749
2912
|
},
|
|
2750
2913
|
dispose() {
|
|
2751
2914
|
for (const u of unsubs) u();
|
|
2915
|
+
},
|
|
2916
|
+
expand(extra) {
|
|
2917
|
+
for (const u of unsubs) u();
|
|
2918
|
+
const merged = { ...options };
|
|
2919
|
+
if (typeof extra === "string") {
|
|
2920
|
+
merged.detail = extra;
|
|
2921
|
+
} else {
|
|
2922
|
+
Object.assign(merged, extra);
|
|
2923
|
+
}
|
|
2924
|
+
return graph._createObserveResultForAll(resolveObserveDetail(merged));
|
|
2752
2925
|
}
|
|
2753
2926
|
};
|
|
2754
2927
|
}
|
|
@@ -2824,6 +2997,9 @@ var Graph = class _Graph {
|
|
|
2824
2997
|
},
|
|
2825
2998
|
dispose() {
|
|
2826
2999
|
stop2();
|
|
3000
|
+
},
|
|
3001
|
+
expand() {
|
|
3002
|
+
throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
|
|
2827
3003
|
}
|
|
2828
3004
|
};
|
|
2829
3005
|
const pushEvent = (path, message) => {
|
|
@@ -2924,16 +3100,16 @@ var Graph = class _Graph {
|
|
|
2924
3100
|
* @returns Rendered graph text.
|
|
2925
3101
|
*/
|
|
2926
3102
|
dumpGraph(options = {}) {
|
|
2927
|
-
const described = this.describe({
|
|
3103
|
+
const { expand: _, ...described } = this.describe({
|
|
2928
3104
|
actor: options.actor,
|
|
2929
|
-
filter: options.filter
|
|
3105
|
+
filter: options.filter,
|
|
3106
|
+
detail: "standard"
|
|
2930
3107
|
});
|
|
2931
3108
|
const includeEdges = options.includeEdges ?? true;
|
|
2932
3109
|
const includeSubgraphs = options.includeSubgraphs ?? true;
|
|
2933
3110
|
if (options.format === "json") {
|
|
2934
3111
|
const payload = {
|
|
2935
|
-
|
|
2936
|
-
nodes: described.nodes,
|
|
3112
|
+
...described,
|
|
2937
3113
|
edges: includeEdges ? described.edges : [],
|
|
2938
3114
|
subgraphs: includeSubgraphs ? described.subgraphs : []
|
|
2939
3115
|
};
|
|
@@ -3003,10 +3179,11 @@ var Graph = class _Graph {
|
|
|
3003
3179
|
* @returns Persistable snapshot with sorted keys.
|
|
3004
3180
|
*/
|
|
3005
3181
|
snapshot() {
|
|
3006
|
-
const d = this.describe();
|
|
3182
|
+
const { expand: _, ...d } = this.describe({ detail: "full" });
|
|
3007
3183
|
const sortedNodes = {};
|
|
3008
3184
|
for (const key of Object.keys(d.nodes).sort()) {
|
|
3009
|
-
|
|
3185
|
+
const { lastMutation: _lm, guard: _g, ...node2 } = d.nodes[key];
|
|
3186
|
+
sortedNodes[key] = node2;
|
|
3010
3187
|
}
|
|
3011
3188
|
const sortedSubgraphs = [...d.subgraphs].sort();
|
|
3012
3189
|
return { ...d, version: 1, nodes: sortedNodes, subgraphs: sortedSubgraphs };
|
|
@@ -3160,16 +3337,22 @@ var Graph = class _Graph {
|
|
|
3160
3337
|
if (!pending) return;
|
|
3161
3338
|
pending = false;
|
|
3162
3339
|
try {
|
|
3163
|
-
const
|
|
3340
|
+
const { expand: _expand, ...raw } = this.describe({ detail: "full" });
|
|
3341
|
+
const cleanNodes = {};
|
|
3342
|
+
for (const [p, n] of Object.entries(raw.nodes)) {
|
|
3343
|
+
const { lastMutation: _lm, guard: _g, ...node2 } = n;
|
|
3344
|
+
cleanNodes[p] = node2;
|
|
3345
|
+
}
|
|
3346
|
+
const described = { ...raw, nodes: cleanNodes };
|
|
3164
3347
|
const snapshot = { ...described, version: SNAPSHOT_VERSION };
|
|
3165
3348
|
seq += 1;
|
|
3166
3349
|
const shouldCompact = lastDescribe == null || seq % compactEvery === 0;
|
|
3167
3350
|
if (shouldCompact) {
|
|
3168
|
-
adapter.save({ mode: "full", snapshot, seq });
|
|
3351
|
+
adapter.save(this.name, { mode: "full", snapshot, seq });
|
|
3169
3352
|
} else {
|
|
3170
3353
|
const previous = lastDescribe;
|
|
3171
3354
|
if (previous == null) return;
|
|
3172
|
-
adapter.save({
|
|
3355
|
+
adapter.save(this.name, {
|
|
3173
3356
|
mode: "diff",
|
|
3174
3357
|
diff: _Graph.diff(previous, described),
|
|
3175
3358
|
snapshot,
|
|
@@ -3190,8 +3373,10 @@ var Graph = class _Graph {
|
|
|
3190
3373
|
const triggeredByTier = messages.some((m) => messageTier(m[0]) >= 2);
|
|
3191
3374
|
if (!triggeredByTier) return;
|
|
3192
3375
|
if (options.filter) {
|
|
3193
|
-
const
|
|
3194
|
-
if (
|
|
3376
|
+
const nd = this.resolve(path);
|
|
3377
|
+
if (nd == null) return;
|
|
3378
|
+
const described = describeNode(nd, resolveDescribeFields("standard"));
|
|
3379
|
+
if (!options.filter(path, described)) return;
|
|
3195
3380
|
}
|
|
3196
3381
|
schedule();
|
|
3197
3382
|
});
|