@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.
Files changed (75) hide show
  1. package/README.md +30 -14
  2. package/dist/{chunk-5X3LAO3B.js → chunk-3EVXOI5C.js} +50 -5
  3. package/dist/chunk-3EVXOI5C.js.map +1 -0
  4. package/dist/chunk-47YJEZUJ.js +106 -0
  5. package/dist/chunk-47YJEZUJ.js.map +1 -0
  6. package/dist/{chunk-6W5SGIGB.js → chunk-BLCXEMAD.js} +129 -25
  7. package/dist/chunk-BLCXEMAD.js.map +1 -0
  8. package/dist/{chunk-QW7H3ICI.js → chunk-FGLZ5QID.js} +4 -4
  9. package/dist/{chunk-CP6MNKAA.js → chunk-ISGMZ2T3.js} +10 -4
  10. package/dist/{chunk-CP6MNKAA.js.map → chunk-ISGMZ2T3.js.map} +1 -1
  11. package/dist/{chunk-HP7OKEOE.js → chunk-L4J2K2RT.js} +3 -3
  12. package/dist/chunk-L4J2K2RT.js.map +1 -0
  13. package/dist/{chunk-ZERWUCGK.js → chunk-ONLYF6GA.js} +866 -206
  14. package/dist/chunk-ONLYF6GA.js.map +1 -0
  15. package/dist/{chunk-Z4Y4FMQN.js → chunk-OSR3G3DP.js} +7 -7
  16. package/dist/{chunk-KWXPDASV.js → chunk-PEBORXRA.js} +2 -2
  17. package/dist/chunk-WZ2Z2CRV.js +32 -0
  18. package/dist/chunk-WZ2Z2CRV.js.map +1 -0
  19. package/dist/compat/nestjs/index.cjs +226 -41
  20. package/dist/compat/nestjs/index.cjs.map +1 -1
  21. package/dist/compat/nestjs/index.d.cts +4 -4
  22. package/dist/compat/nestjs/index.d.ts +4 -4
  23. package/dist/compat/nestjs/index.js +8 -7
  24. package/dist/core/index.cjs +134 -20
  25. package/dist/core/index.cjs.map +1 -1
  26. package/dist/core/index.d.cts +2 -2
  27. package/dist/core/index.d.ts +2 -2
  28. package/dist/core/index.js +10 -4
  29. package/dist/extra/index.cjs +939 -209
  30. package/dist/extra/index.cjs.map +1 -1
  31. package/dist/extra/index.d.cts +4 -4
  32. package/dist/extra/index.d.ts +4 -4
  33. package/dist/extra/index.js +26 -3
  34. package/dist/graph/index.cjs +226 -41
  35. package/dist/graph/index.cjs.map +1 -1
  36. package/dist/graph/index.d.cts +3 -3
  37. package/dist/graph/index.d.ts +3 -3
  38. package/dist/graph/index.js +4 -4
  39. package/dist/{graph-CL_ZDAj9.d.cts → graph-B3BoJjcb.d.cts} +58 -7
  40. package/dist/{graph-D18qmsNm.d.ts → graph-CmiUuhaN.d.ts} +58 -7
  41. package/dist/{index-B7eOdgEx.d.ts → index-Bf2X1YSI.d.ts} +3 -3
  42. package/dist/{index-BvhgZRHK.d.cts → index-Bl7hJcc3.d.cts} +4 -2
  43. package/dist/{index-Bvy_6CaN.d.ts → index-BrgtEG-C.d.ts} +47 -4
  44. package/dist/{index-D_geH2Bm.d.cts → index-BsuKSs4L.d.cts} +3 -3
  45. package/dist/{index-BtK55IE2.d.ts → index-CsUq2rrK.d.ts} +4 -2
  46. package/dist/{index-C3BMRmmp.d.cts → index-D0cx-Yht.d.cts} +3 -3
  47. package/dist/{index-Cz8og7-L.d.cts → index-D1hgSTzr.d.cts} +488 -60
  48. package/dist/{index-C5mqLhMX.d.cts → index-D8NIq6om.d.cts} +47 -4
  49. package/dist/{index-CP_QvbWu.d.ts → index-DFFNKYig.d.ts} +3 -3
  50. package/dist/{index-C3LRU4jB.d.ts → index-Pm68AYPh.d.ts} +488 -60
  51. package/dist/index.cjs +3005 -1776
  52. package/dist/index.cjs.map +1 -1
  53. package/dist/index.d.cts +112 -14
  54. package/dist/index.d.ts +112 -14
  55. package/dist/index.js +396 -27
  56. package/dist/index.js.map +1 -1
  57. package/dist/{meta-BsF6Sag9.d.cts → meta-BJEU8fYz.d.cts} +31 -4
  58. package/dist/{meta-BsF6Sag9.d.ts → meta-BJEU8fYz.d.ts} +31 -4
  59. package/dist/patterns/reactive-layout/index.cjs +226 -41
  60. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  61. package/dist/patterns/reactive-layout/index.d.cts +3 -3
  62. package/dist/patterns/reactive-layout/index.d.ts +3 -3
  63. package/dist/patterns/reactive-layout/index.js +4 -4
  64. package/dist/{reactive-log-BfvfNWQh.d.cts → reactive-log-CAXzJ7hw.d.cts} +2 -2
  65. package/dist/{reactive-log-ohLmTXoZ.d.ts → reactive-log-DwNhOe0g.d.ts} +2 -2
  66. package/package.json +29 -18
  67. package/dist/chunk-5X3LAO3B.js.map +0 -1
  68. package/dist/chunk-6W5SGIGB.js.map +0 -1
  69. package/dist/chunk-HP7OKEOE.js.map +0 -1
  70. package/dist/chunk-O3PI7W45.js +0 -68
  71. package/dist/chunk-O3PI7W45.js.map +0 -1
  72. package/dist/chunk-ZERWUCGK.js.map +0 -1
  73. /package/dist/{chunk-QW7H3ICI.js.map → chunk-FGLZ5QID.js.map} +0 -0
  74. /package/dist/{chunk-Z4Y4FMQN.js.map → chunk-OSR3G3DP.js.map} +0 -0
  75. /package/dist/{chunk-KWXPDASV.js.map → chunk-PEBORXRA.js.map} +0 -0
@@ -159,10 +159,14 @@ function partitionForBatch(messages) {
159
159
  }
160
160
  return { immediate, deferred, terminal };
161
161
  }
162
- function emitWithBatch(emit, messages, phase = 2) {
162
+ function emitWithBatch(emit, messages, phase = 2, options) {
163
163
  if (messages.length === 0) {
164
164
  return;
165
165
  }
166
+ if (options?.strategy === "sequential") {
167
+ _emitSequential(emit, messages, phase);
168
+ return;
169
+ }
166
170
  const queue = phase === 3 ? pendingPhase3 : pendingPhase2;
167
171
  if (messages.length === 1) {
168
172
  const t = messages[0][0];
@@ -203,6 +207,29 @@ function emitWithBatch(emit, messages, phase = 2) {
203
207
  }
204
208
  }
205
209
  }
210
+ function _emitSequential(emit, messages, phase = 2) {
211
+ const dataQueue = phase === 3 ? pendingPhase3 : pendingPhase2;
212
+ for (const msg of messages) {
213
+ const tier = messageTier(msg[0]);
214
+ if (tier === 2) {
215
+ if (isBatching()) {
216
+ const m = msg;
217
+ dataQueue.push(() => emit([m]));
218
+ } else {
219
+ emit([msg]);
220
+ }
221
+ } else if (tier >= 3) {
222
+ if (isBatching()) {
223
+ const m = msg;
224
+ pendingPhase3.push(() => emit([m]));
225
+ } else {
226
+ emit([msg]);
227
+ }
228
+ } else {
229
+ emit([msg]);
230
+ }
231
+ }
232
+ }
206
233
 
207
234
  // src/core/clock.ts
208
235
  function monotonicNs() {
@@ -411,6 +438,7 @@ var NodeImpl = class {
411
438
  _producerStarted = false;
412
439
  _connecting = false;
413
440
  _manualEmitUsed = false;
441
+ _hasEmittedData = false;
414
442
  _sinkCount = 0;
415
443
  _singleDepSinkCount = 0;
416
444
  // --- Object/collection state ---
@@ -697,6 +725,7 @@ var NodeImpl = class {
697
725
  this._cleanup = void 0;
698
726
  cleanupFn?.();
699
727
  this._cached = void 0;
728
+ this._hasEmittedData = false;
700
729
  this._lastDepValues = void 0;
701
730
  }
702
731
  this._status = statusAfterMessage(this._status, m);
@@ -706,6 +735,7 @@ var NodeImpl = class {
706
735
  if (t === TEARDOWN) {
707
736
  if (this._opts.resetOnTeardown) {
708
737
  this._cached = void 0;
738
+ this._hasEmittedData = false;
709
739
  }
710
740
  const teardownCleanup = this._cleanup;
711
741
  this._cleanup = void 0;
@@ -736,7 +766,16 @@ var NodeImpl = class {
736
766
  }
737
767
  _emitAutoValue(value) {
738
768
  const wasDirty = this._status === "dirty";
739
- const unchanged = this._equals(this._cached, value);
769
+ let unchanged;
770
+ try {
771
+ unchanged = this._hasEmittedData && this._equals(this._cached, value);
772
+ } catch (eqErr) {
773
+ const eqMsg = eqErr instanceof Error ? eqErr.message : String(eqErr);
774
+ const wrapped = new Error(`Node "${this.name}": equals threw: ${eqMsg}`, { cause: eqErr });
775
+ this._downInternal([[ERROR, wrapped]]);
776
+ return;
777
+ }
778
+ this._hasEmittedData = true;
740
779
  if (unchanged) {
741
780
  this._downInternal(wasDirty ? [[RESOLVED]] : [[DIRTY], [RESOLVED]]);
742
781
  return;
@@ -783,7 +822,9 @@ var NodeImpl = class {
783
822
  if (out === void 0) return;
784
823
  this._emitAutoValue(out);
785
824
  } catch (err) {
786
- this._downInternal([[ERROR, err]]);
825
+ const errMsg = err instanceof Error ? err.message : String(err);
826
+ const wrapped = new Error(`Node "${this.name}": fn threw: ${errMsg}`, { cause: err });
827
+ this._downInternal([[ERROR, wrapped]]);
787
828
  }
788
829
  }
789
830
  _onDepDirty(index) {
@@ -818,7 +859,11 @@ var NodeImpl = class {
818
859
  try {
819
860
  if (this._onMessage(msg, index, this._actions)) continue;
820
861
  } catch (err) {
821
- this._downInternal([[ERROR, err]]);
862
+ const errMsg = err instanceof Error ? err.message : String(err);
863
+ const wrapped = new Error(`Node "${this.name}": onMessage threw: ${errMsg}`, {
864
+ cause: err
865
+ });
866
+ this._downInternal([[ERROR, wrapped]]);
822
867
  return;
823
868
  }
824
869
  }
@@ -1383,6 +1428,19 @@ var DynamicNodeImpl = class {
1383
1428
  };
1384
1429
 
1385
1430
  // src/core/meta.ts
1431
+ function resolveDescribeFields(detail, fields) {
1432
+ if (fields != null && fields.length > 0) return new Set(fields);
1433
+ switch (detail) {
1434
+ case "standard":
1435
+ return /* @__PURE__ */ new Set(["type", "status", "value", "deps", "meta", "v"]);
1436
+ case "full":
1437
+ return null;
1438
+ // null = include everything
1439
+ case "minimal":
1440
+ default:
1441
+ return /* @__PURE__ */ new Set(["type", "deps"]);
1442
+ }
1443
+ }
1386
1444
  function inferDescribeType(n) {
1387
1445
  if (n._describeKind != null) return n._describeKind;
1388
1446
  if (!n._hasDeps) return n._fn != null ? "producer" : "state";
@@ -1400,12 +1458,10 @@ function metaSnapshot(node2) {
1400
1458
  }
1401
1459
  return out;
1402
1460
  }
1403
- function describeNode(node2) {
1404
- const meta = { ...metaSnapshot(node2) };
1405
- const guard = node2 instanceof NodeImpl && node2._guard || node2 instanceof DynamicNodeImpl && node2._guard || void 0;
1406
- if (guard != null && meta.access === void 0) {
1407
- meta.access = accessHintForGuard(guard);
1408
- }
1461
+ function describeNode(node2, includeFields) {
1462
+ const all = includeFields == null;
1463
+ const metaKeys = !all && includeFields != null ? [...includeFields].filter((f) => f.startsWith("meta.")).map((f) => f.slice(5)) : null;
1464
+ const wantsMeta = all || includeFields.has("meta") || metaKeys != null && metaKeys.length > 0;
1409
1465
  let type = "state";
1410
1466
  let deps = [];
1411
1467
  if (node2 instanceof NodeImpl) {
@@ -1415,20 +1471,36 @@ function describeNode(node2) {
1415
1471
  type = node2._describeKind ?? "derived";
1416
1472
  deps = [];
1417
1473
  }
1418
- const out = {
1419
- type,
1420
- status: node2.status,
1421
- deps,
1422
- meta
1423
- };
1474
+ const out = { type, deps };
1475
+ if (all || includeFields.has("status")) {
1476
+ out.status = node2.status;
1477
+ }
1478
+ const guard = node2 instanceof NodeImpl && node2._guard || node2 instanceof DynamicNodeImpl && node2._guard || void 0;
1479
+ if (wantsMeta) {
1480
+ const rawMeta = { ...metaSnapshot(node2) };
1481
+ if (guard != null && rawMeta.access === void 0) {
1482
+ rawMeta.access = accessHintForGuard(guard);
1483
+ }
1484
+ if (metaKeys != null && metaKeys.length > 0 && !includeFields.has("meta")) {
1485
+ const filtered = {};
1486
+ for (const k of metaKeys) {
1487
+ if (k in rawMeta) filtered[k] = rawMeta[k];
1488
+ }
1489
+ out.meta = filtered;
1490
+ } else {
1491
+ out.meta = rawMeta;
1492
+ }
1493
+ }
1424
1494
  if (node2.name != null) {
1425
1495
  out.name = node2.name;
1426
1496
  }
1427
- try {
1428
- out.value = node2.get();
1429
- } catch {
1497
+ if (all || includeFields.has("value")) {
1498
+ try {
1499
+ out.value = node2.get();
1500
+ } catch {
1501
+ }
1430
1502
  }
1431
- if (node2.v != null) {
1503
+ if ((all || includeFields.has("v")) && node2.v != null) {
1432
1504
  const vInfo = { id: node2.v.id, version: node2.v.version };
1433
1505
  if ("cid" in node2.v) {
1434
1506
  vInfo.cid = node2.v.cid;
@@ -1436,6 +1508,16 @@ function describeNode(node2) {
1436
1508
  }
1437
1509
  out.v = vInfo;
1438
1510
  }
1511
+ if (all || includeFields.has("guard")) {
1512
+ if (guard != null) {
1513
+ out.guard = accessHintForGuard(guard);
1514
+ }
1515
+ }
1516
+ if (all || includeFields.has("lastMutation")) {
1517
+ if (node2.lastMutation != null) {
1518
+ out.lastMutation = node2.lastMutation;
1519
+ }
1520
+ }
1439
1521
  return out;
1440
1522
  }
1441
1523
 
@@ -1630,6 +1712,23 @@ function resolveSpyTheme(theme) {
1630
1712
  reset: theme.reset ?? ""
1631
1713
  };
1632
1714
  }
1715
+ function resolveObserveDetail(opts) {
1716
+ if (opts == null) return {};
1717
+ const detail = opts.detail;
1718
+ if (detail === "full") {
1719
+ return {
1720
+ ...opts,
1721
+ structured: opts.structured ?? true,
1722
+ timeline: opts.timeline ?? true,
1723
+ causal: opts.causal ?? true,
1724
+ derived: opts.derived ?? true
1725
+ };
1726
+ }
1727
+ if (detail === "minimal") {
1728
+ return { ...opts, structured: opts.structured ?? true };
1729
+ }
1730
+ return opts;
1731
+ }
1633
1732
  function assertLocalName(name, graphName, label) {
1634
1733
  if (name === "") {
1635
1734
  throw new Error(`Graph "${graphName}": ${label} name must be non-empty`);
@@ -1827,6 +1926,22 @@ var Graph = class _Graph {
1827
1926
  if (this._defaultVersioningLevel != null) {
1828
1927
  node2._applyVersioning(this._defaultVersioningLevel);
1829
1928
  }
1929
+ if (node2._deps.length > 0) {
1930
+ for (const dep of node2._deps) {
1931
+ for (const [depName, depNode] of this._nodes) {
1932
+ if (depNode === dep) {
1933
+ this._edges.add(edgeKey(depName, name));
1934
+ break;
1935
+ }
1936
+ }
1937
+ }
1938
+ }
1939
+ for (const [otherName, otherNode] of this._nodes) {
1940
+ if (otherName === name) continue;
1941
+ if (otherNode instanceof NodeImpl && otherNode._deps.includes(node2)) {
1942
+ this._edges.add(edgeKey(name, otherName));
1943
+ }
1944
+ }
1830
1945
  }
1831
1946
  }
1832
1947
  /**
@@ -2213,6 +2328,9 @@ var Graph = class _Graph {
2213
2328
  describe(options) {
2214
2329
  const actor = options?.actor;
2215
2330
  const filter = options?.filter;
2331
+ const includeFields = resolveDescribeFields(options?.detail, options?.fields);
2332
+ const isSpec = options?.format === "spec";
2333
+ const effectiveFields = isSpec ? resolveDescribeFields("minimal") : includeFields;
2216
2334
  const targets = [];
2217
2335
  this._collectObserveTargets("", targets);
2218
2336
  const nodeToPath = /* @__PURE__ */ new Map();
@@ -2222,7 +2340,7 @@ var Graph = class _Graph {
2222
2340
  const nodes = {};
2223
2341
  for (const [p, n] of targets) {
2224
2342
  if (actor != null && !n.allowsObserve(actor)) continue;
2225
- const raw = describeNode(n);
2343
+ const raw = describeNode(n, effectiveFields);
2226
2344
  const deps = n instanceof NodeImpl ? n._deps.map((d) => nodeToPath.get(d) ?? d.name ?? "") : [];
2227
2345
  const { name: _name, ...rest } = raw;
2228
2346
  const entry = { ...rest, deps };
@@ -2243,7 +2361,7 @@ var Graph = class _Graph {
2243
2361
  continue;
2244
2362
  }
2245
2363
  if (normalizedKey === "metaHas") {
2246
- if (!Object.hasOwn(entry.meta, String(fv))) {
2364
+ if (!Object.hasOwn(entry.meta ?? {}, String(fv))) {
2247
2365
  match = false;
2248
2366
  break;
2249
2367
  }
@@ -2276,11 +2394,24 @@ var Graph = class _Graph {
2276
2394
  const prefix = `${sg}${PATH_SEP}`;
2277
2395
  return [...nodeKeys].some((k) => k === sg || k.startsWith(prefix));
2278
2396
  }) : allSubgraphs;
2397
+ const graph = this;
2398
+ const baseOpts = options;
2279
2399
  return {
2280
2400
  name: this.name,
2281
2401
  nodes,
2282
2402
  edges,
2283
- subgraphs
2403
+ subgraphs,
2404
+ expand(detailOrFields) {
2405
+ const merged = { ...baseOpts, format: void 0 };
2406
+ if (Array.isArray(detailOrFields)) {
2407
+ merged.fields = detailOrFields;
2408
+ merged.detail = void 0;
2409
+ } else {
2410
+ merged.detail = detailOrFields;
2411
+ merged.fields = void 0;
2412
+ }
2413
+ return graph.describe(merged);
2414
+ }
2284
2415
  };
2285
2416
  }
2286
2417
  _collectSubgraphs(prefix) {
@@ -2333,14 +2464,15 @@ var Graph = class _Graph {
2333
2464
  observe(pathOrOpts, options) {
2334
2465
  if (typeof pathOrOpts === "string") {
2335
2466
  const path = pathOrOpts;
2336
- const actor2 = options?.actor;
2467
+ const resolved = resolveObserveDetail(options);
2468
+ const actor2 = resolved.actor;
2337
2469
  const target = this.resolve(path);
2338
2470
  if (actor2 != null && !target.allowsObserve(actor2)) {
2339
2471
  throw new GuardDenied({ actor: actor2, action: "observe", nodeName: path });
2340
2472
  }
2341
- const wantsStructured2 = options?.structured === true || options?.timeline === true || options?.causal === true || options?.derived === true;
2473
+ const wantsStructured2 = resolved.structured === true || resolved.timeline === true || resolved.causal === true || resolved.derived === true || resolved.detail === "minimal" || resolved.detail === "full";
2342
2474
  if (wantsStructured2 && _Graph.inspectorEnabled) {
2343
- return this._createObserveResult(path, target, options);
2475
+ return this._createObserveResult(path, target, resolved);
2344
2476
  }
2345
2477
  return {
2346
2478
  subscribe(sink) {
@@ -2356,11 +2488,11 @@ var Graph = class _Graph {
2356
2488
  }
2357
2489
  };
2358
2490
  }
2359
- const opts = pathOrOpts;
2360
- const actor = opts?.actor;
2361
- const wantsStructured = opts?.structured === true || opts?.timeline === true || opts?.causal === true || opts?.derived === true;
2491
+ const opts = resolveObserveDetail(pathOrOpts);
2492
+ const actor = opts.actor;
2493
+ const wantsStructured = opts.structured === true || opts.timeline === true || opts.causal === true || opts.derived === true || opts.detail === "minimal" || opts.detail === "full";
2362
2494
  if (wantsStructured && _Graph.inspectorEnabled) {
2363
- return this._createObserveResultForAll(opts ?? {});
2495
+ return this._createObserveResultForAll(opts);
2364
2496
  }
2365
2497
  return {
2366
2498
  subscribe: (sink) => {
@@ -2392,6 +2524,7 @@ var Graph = class _Graph {
2392
2524
  const timeline = options.timeline === true;
2393
2525
  const causal = options.causal === true;
2394
2526
  const derived = options.derived === true;
2527
+ const minimal = options.detail === "minimal";
2395
2528
  const result = {
2396
2529
  values: {},
2397
2530
  dirtyCount: 0,
@@ -2437,6 +2570,11 @@ var Graph = class _Graph {
2437
2570
  if (t === DATA) {
2438
2571
  result.values[path] = m[1];
2439
2572
  result.events.push({ type: "data", path, data: m[1], ...base, ...withCausal });
2573
+ } else if (minimal) {
2574
+ if (t === DIRTY) result.dirtyCount++;
2575
+ else if (t === RESOLVED) result.resolvedCount++;
2576
+ else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
2577
+ else if (t === ERROR) result.errored = true;
2440
2578
  } else if (t === DIRTY) {
2441
2579
  result.dirtyCount++;
2442
2580
  result.events.push({ type: "dirty", path, ...base });
@@ -2452,6 +2590,8 @@ var Graph = class _Graph {
2452
2590
  }
2453
2591
  }
2454
2592
  });
2593
+ const graph = this;
2594
+ const basePath = path;
2455
2595
  return {
2456
2596
  get values() {
2457
2597
  return result.values;
@@ -2474,11 +2614,28 @@ var Graph = class _Graph {
2474
2614
  dispose() {
2475
2615
  unsub();
2476
2616
  detachInspectorHook?.();
2617
+ },
2618
+ expand(extra) {
2619
+ unsub();
2620
+ detachInspectorHook?.();
2621
+ const merged = { ...options };
2622
+ if (typeof extra === "string") {
2623
+ merged.detail = extra;
2624
+ } else {
2625
+ Object.assign(merged, extra);
2626
+ }
2627
+ const resolvedTarget = graph.resolve(basePath);
2628
+ return graph._createObserveResult(
2629
+ basePath,
2630
+ resolvedTarget,
2631
+ resolveObserveDetail(merged)
2632
+ );
2477
2633
  }
2478
2634
  };
2479
2635
  }
2480
2636
  _createObserveResultForAll(options) {
2481
2637
  const timeline = options.timeline === true;
2638
+ const minimal = options.detail === "minimal";
2482
2639
  const result = {
2483
2640
  values: {},
2484
2641
  dirtyCount: 0,
@@ -2500,6 +2657,11 @@ var Graph = class _Graph {
2500
2657
  if (t === DATA) {
2501
2658
  result.values[path] = m[1];
2502
2659
  result.events.push({ type: "data", path, data: m[1], ...base });
2660
+ } else if (minimal) {
2661
+ if (t === DIRTY) result.dirtyCount++;
2662
+ else if (t === RESOLVED) result.resolvedCount++;
2663
+ else if (t === COMPLETE && !result.errored) result.completedCleanly = true;
2664
+ else if (t === ERROR) result.errored = true;
2503
2665
  } else if (t === DIRTY) {
2504
2666
  result.dirtyCount++;
2505
2667
  result.events.push({ type: "dirty", path, ...base });
@@ -2516,6 +2678,7 @@ var Graph = class _Graph {
2516
2678
  }
2517
2679
  })
2518
2680
  );
2681
+ const graph = this;
2519
2682
  return {
2520
2683
  get values() {
2521
2684
  return result.values;
@@ -2537,6 +2700,16 @@ var Graph = class _Graph {
2537
2700
  },
2538
2701
  dispose() {
2539
2702
  for (const u of unsubs) u();
2703
+ },
2704
+ expand(extra) {
2705
+ for (const u of unsubs) u();
2706
+ const merged = { ...options };
2707
+ if (typeof extra === "string") {
2708
+ merged.detail = extra;
2709
+ } else {
2710
+ Object.assign(merged, extra);
2711
+ }
2712
+ return graph._createObserveResultForAll(resolveObserveDetail(merged));
2540
2713
  }
2541
2714
  };
2542
2715
  }
@@ -2612,6 +2785,9 @@ var Graph = class _Graph {
2612
2785
  },
2613
2786
  dispose() {
2614
2787
  stop2();
2788
+ },
2789
+ expand() {
2790
+ throw new Error("expand() requires inspector mode (Graph.inspectorEnabled = true)");
2615
2791
  }
2616
2792
  };
2617
2793
  const pushEvent = (path, message) => {
@@ -2712,16 +2888,16 @@ var Graph = class _Graph {
2712
2888
  * @returns Rendered graph text.
2713
2889
  */
2714
2890
  dumpGraph(options = {}) {
2715
- const described = this.describe({
2891
+ const { expand: _, ...described } = this.describe({
2716
2892
  actor: options.actor,
2717
- filter: options.filter
2893
+ filter: options.filter,
2894
+ detail: "standard"
2718
2895
  });
2719
2896
  const includeEdges = options.includeEdges ?? true;
2720
2897
  const includeSubgraphs = options.includeSubgraphs ?? true;
2721
2898
  if (options.format === "json") {
2722
2899
  const payload = {
2723
- name: described.name,
2724
- nodes: described.nodes,
2900
+ ...described,
2725
2901
  edges: includeEdges ? described.edges : [],
2726
2902
  subgraphs: includeSubgraphs ? described.subgraphs : []
2727
2903
  };
@@ -2791,10 +2967,11 @@ var Graph = class _Graph {
2791
2967
  * @returns Persistable snapshot with sorted keys.
2792
2968
  */
2793
2969
  snapshot() {
2794
- const d = this.describe();
2970
+ const { expand: _, ...d } = this.describe({ detail: "full" });
2795
2971
  const sortedNodes = {};
2796
2972
  for (const key of Object.keys(d.nodes).sort()) {
2797
- sortedNodes[key] = d.nodes[key];
2973
+ const { lastMutation: _lm, guard: _g, ...node2 } = d.nodes[key];
2974
+ sortedNodes[key] = node2;
2798
2975
  }
2799
2976
  const sortedSubgraphs = [...d.subgraphs].sort();
2800
2977
  return { ...d, version: 1, nodes: sortedNodes, subgraphs: sortedSubgraphs };
@@ -2948,16 +3125,22 @@ var Graph = class _Graph {
2948
3125
  if (!pending) return;
2949
3126
  pending = false;
2950
3127
  try {
2951
- const described = this.describe();
3128
+ const { expand: _expand, ...raw } = this.describe({ detail: "full" });
3129
+ const cleanNodes = {};
3130
+ for (const [p, n] of Object.entries(raw.nodes)) {
3131
+ const { lastMutation: _lm, guard: _g, ...node2 } = n;
3132
+ cleanNodes[p] = node2;
3133
+ }
3134
+ const described = { ...raw, nodes: cleanNodes };
2952
3135
  const snapshot = { ...described, version: SNAPSHOT_VERSION };
2953
3136
  seq += 1;
2954
3137
  const shouldCompact = lastDescribe == null || seq % compactEvery === 0;
2955
3138
  if (shouldCompact) {
2956
- adapter.save({ mode: "full", snapshot, seq });
3139
+ adapter.save(this.name, { mode: "full", snapshot, seq });
2957
3140
  } else {
2958
3141
  const previous = lastDescribe;
2959
3142
  if (previous == null) return;
2960
- adapter.save({
3143
+ adapter.save(this.name, {
2961
3144
  mode: "diff",
2962
3145
  diff: _Graph.diff(previous, described),
2963
3146
  snapshot,
@@ -2978,8 +3161,10 @@ var Graph = class _Graph {
2978
3161
  const triggeredByTier = messages.some((m) => messageTier(m[0]) >= 2);
2979
3162
  if (!triggeredByTier) return;
2980
3163
  if (options.filter) {
2981
- const described = this.describe().nodes[path];
2982
- if (described == null || !options.filter(path, described)) return;
3164
+ const nd = this.resolve(path);
3165
+ if (nd == null) return;
3166
+ const described = describeNode(nd, resolveDescribeFields("standard"));
3167
+ if (!options.filter(path, described)) return;
2983
3168
  }
2984
3169
  schedule();
2985
3170
  });