@fluixi/devtools 0.2.0-alpha.6 → 1.0.0-alpha.99

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Fluixi
3
+ Copyright (c) 2026 Ibrahima Touré
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/dist/callsite.cjs CHANGED
@@ -77,5 +77,12 @@ function callSite(stack, origin) {
77
77
  return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
78
78
  }
79
79
  function currentCallSite(origin) {
80
- return callSite(new Error().stack, origin);
80
+ const errors = Error;
81
+ const limit = errors.stackTraceLimit;
82
+ errors.stackTraceLimit = 50;
83
+ try {
84
+ return callSite(new Error().stack, origin);
85
+ } finally {
86
+ errors.stackTraceLimit = limit;
87
+ }
81
88
  }
@@ -1 +1 @@
1
- {"version":3,"file":"callsite.d.ts","sourceRoot":"","sources":["../src/callsite.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AA8D1D;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,QAAQ,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAgBrE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,QAAQ,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAErE"}
1
+ {"version":3,"file":"callsite.d.ts","sourceRoot":"","sources":["../src/callsite.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AA8D1D;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,QAAQ,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAgBrE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,QAAQ,EAAE,sBAAsB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAYrE"}
package/dist/callsite.js CHANGED
@@ -87,5 +87,16 @@ export function callSite(stack, origin) {
87
87
  * the frames of the creating call are still on the stack.
88
88
  */
89
89
  export function currentCallSite(origin) {
90
- return callSite(new Error().stack, origin);
90
+ // Deeper than the default ten frames: the reporting machinery and the framework's own calls
91
+ // can fill those, and the application's frame is the one past them.
92
+ // A V8 extension, absent from the DOM types; elsewhere it is an ignored property.
93
+ const errors = Error;
94
+ const limit = errors.stackTraceLimit;
95
+ errors.stackTraceLimit = 50;
96
+ try {
97
+ return callSite(new Error().stack, origin);
98
+ }
99
+ finally {
100
+ errors.stackTraceLimit = limit;
101
+ }
91
102
  }
package/dist/callsite.mjs CHANGED
@@ -52,7 +52,14 @@ function callSite(stack, origin) {
52
52
  return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
53
53
  }
54
54
  function currentCallSite(origin) {
55
- return callSite(new Error().stack, origin);
55
+ const errors = Error;
56
+ const limit = errors.stackTraceLimit;
57
+ errors.stackTraceLimit = 50;
58
+ try {
59
+ return callSite(new Error().stack, origin);
60
+ } finally {
61
+ errors.stackTraceLimit = limit;
62
+ }
56
63
  }
57
64
  export {
58
65
  callSite,
package/dist/diff.cjs CHANGED
@@ -106,6 +106,8 @@ function walk(value, depth, seen) {
106
106
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
107
107
  let read;
108
108
  try {
109
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
110
+ if (descriptor?.get) return `${key}: [getter]`;
109
111
  read = walk(object[key], depth + 1, seen);
110
112
  } catch {
111
113
  read = "[unreadable]";
package/dist/diff.mjs CHANGED
@@ -80,6 +80,8 @@ function walk(value, depth, seen) {
80
80
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
81
81
  let read;
82
82
  try {
83
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
84
+ if (descriptor?.get) return `${key}: [getter]`;
83
85
  read = walk(object[key], depth + 1, seen);
84
86
  } catch {
85
87
  read = "[unreadable]";
package/dist/export.cjs CHANGED
@@ -122,6 +122,8 @@ function walk(value, depth, seen) {
122
122
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
123
123
  let read;
124
124
  try {
125
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
126
+ if (descriptor?.get) return `${key}: [getter]`;
125
127
  read = walk(object[key], depth + 1, seen);
126
128
  } catch {
127
129
  read = "[unreadable]";
package/dist/export.mjs CHANGED
@@ -106,6 +106,8 @@ function walk(value, depth, seen) {
106
106
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
107
107
  let read;
108
108
  try {
109
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
110
+ if (descriptor?.get) return `${key}: [getter]`;
109
111
  read = walk(object[key], depth + 1, seen);
110
112
  } catch {
111
113
  read = "[unreadable]";
package/dist/format.cjs CHANGED
@@ -106,6 +106,8 @@ function walk(value, depth, seen) {
106
106
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
107
107
  let read;
108
108
  try {
109
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
110
+ if (descriptor?.get) return `${key}: [getter]`;
109
111
  read = walk(object[key], depth + 1, seen);
110
112
  } catch {
111
113
  read = "[unreadable]";
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAoHA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAM,GAAG,MAAM,CAQ/D;AAED,+CAA+C;AAC/C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CA4C5D"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAwHA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAM,GAAG,MAAM,CAQ/D;AAED,+CAA+C;AAC/C,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,MAAM,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAO,GAAG,MAAM,CA4C5D"}
package/dist/format.js CHANGED
@@ -98,9 +98,14 @@ function walk(value, depth, seen) {
98
98
  }
99
99
  const keys = Object.keys(object);
100
100
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
101
- // A getter can throw, and a proxy can refuse. Neither is worth losing the whole value.
101
+ // A getter is shown, never called: on a component's props it builds the content
102
+ // (a `children` getter makes fresh nodes per read) and reads signals, so printing it
103
+ // ran the component's work again on every sample. A proxy can still refuse.
102
104
  let read;
103
105
  try {
106
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
107
+ if (descriptor?.get)
108
+ return `${key}: [getter]`;
104
109
  read = walk(object[key], depth + 1, seen);
105
110
  }
106
111
  catch {
package/dist/format.mjs CHANGED
@@ -80,6 +80,8 @@ function walk(value, depth, seen) {
80
80
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
81
81
  let read;
82
82
  try {
83
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
84
+ if (descriptor?.get) return `${key}: [getter]`;
83
85
  read = walk(object[key], depth + 1, seen);
84
86
  } catch {
85
87
  read = "[unreadable]";
package/dist/hook.cjs CHANGED
@@ -352,7 +352,14 @@ function callSite(stack, origin) {
352
352
  return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
353
353
  }
354
354
  function currentCallSite(origin) {
355
- return callSite(new Error().stack, origin);
355
+ const errors = Error;
356
+ const limit = errors.stackTraceLimit;
357
+ errors.stackTraceLimit = 50;
358
+ try {
359
+ return callSite(new Error().stack, origin);
360
+ } finally {
361
+ errors.stackTraceLimit = limit;
362
+ }
356
363
  }
357
364
 
358
365
  // src/instrument.ts
@@ -441,6 +448,8 @@ function walk(value, depth, seen) {
441
448
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
442
449
  let read;
443
450
  try {
451
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
452
+ if (descriptor?.get) return `${key}: [getter]`;
444
453
  read = walk(object[key], depth + 1, seen);
445
454
  } catch {
446
455
  read = "[unreadable]";
@@ -840,6 +849,7 @@ var PREFIX = {
840
849
  service: "svc"
841
850
  };
842
851
  function readProps(props) {
852
+ if (readOnce.has(props)) return readOnce.get(props);
843
853
  const at = propsLocations(props);
844
854
  const out = [];
845
855
  for (const name of Object.keys(props)) {
@@ -850,13 +860,25 @@ function readProps(props) {
850
860
  ...where ? { at: { line: where[0], column: where[1] } } : {}
851
861
  };
852
862
  try {
853
- report.value = formatValue((0, import_signal2.untrack)(() => props[name]), 200);
863
+ report.value = formatValue(
864
+ (0, import_signal2.createRoot)((dispose) => {
865
+ try {
866
+ return (0, import_signal2.untrack)(() => props[name]);
867
+ } finally {
868
+ dispose();
869
+ }
870
+ }),
871
+ 200
872
+ );
854
873
  } catch {
855
874
  }
856
875
  out.push(report);
857
876
  }
858
- return out.length ? out : void 0;
877
+ const reports = out.length ? out : void 0;
878
+ readOnce.set(props, reports);
879
+ return reports;
859
880
  }
881
+ var readOnce = /* @__PURE__ */ new WeakMap();
860
882
  function observeGraph(options = {}) {
861
883
  installSourceMarker();
862
884
  const origin = options.origin ?? (typeof location === "object" ? location.origin : void 0);
@@ -864,7 +886,7 @@ function observeGraph(options = {}) {
864
886
  const claims = (node, value) => {
865
887
  for (const dep of node.deps) {
866
888
  const other = graph.get(dep);
867
- if (other?.read && other.read() === value) return false;
889
+ if (other?.read && readRaw(other) === value) return false;
868
890
  }
869
891
  return true;
870
892
  };
@@ -882,6 +904,7 @@ function observeGraph(options = {}) {
882
904
  const scopeOfTarget = /* @__PURE__ */ new WeakMap();
883
905
  const fieldsOf = /* @__PURE__ */ new WeakMap();
884
906
  let described = null;
907
+ let descendants = null;
885
908
  const rendered = /* @__PURE__ */ new Map();
886
909
  const elementsIn = (value) => {
887
910
  if (value instanceof Element) return [value];
@@ -1243,6 +1266,7 @@ function observeGraph(options = {}) {
1243
1266
  graph,
1244
1267
  sample() {
1245
1268
  described = null;
1269
+ descendants = null;
1246
1270
  const changed = [];
1247
1271
  const moved = (id) => {
1248
1272
  changed.push(id);
@@ -1298,7 +1322,7 @@ function observeGraph(options = {}) {
1298
1322
  runsAtLastSample.set(node.id, node.runs);
1299
1323
  continue;
1300
1324
  }
1301
- const raw = node.read();
1325
+ const raw = readRaw(node);
1302
1326
  if (recording) raws.set(node.id, raw);
1303
1327
  edges(node.id, node);
1304
1328
  const stamped = raw?.$name;
@@ -1373,17 +1397,8 @@ function observeGraph(options = {}) {
1373
1397
  if (live.length) return live;
1374
1398
  collect(id);
1375
1399
  if (!live.length) {
1376
- const inside = (node) => {
1377
- const seen = /* @__PURE__ */ new Set();
1378
- let at = node.createdIn;
1379
- while (at !== void 0 && !seen.has(at)) {
1380
- if (at === id) return true;
1381
- seen.add(at);
1382
- at = graph.get(at)?.createdIn;
1383
- }
1384
- return false;
1385
- };
1386
- for (const node of graph.values()) if (inside(node)) collect(node.id);
1400
+ descendants ??= descendantsByCreator(graph);
1401
+ for (const below of descendants.get(id) ?? []) collect(below);
1387
1402
  }
1388
1403
  return live;
1389
1404
  },
@@ -1496,6 +1511,21 @@ function observeGraph(options = {}) {
1496
1511
  }
1497
1512
  return api;
1498
1513
  }
1514
+ function descendantsByCreator(graph) {
1515
+ const out = /* @__PURE__ */ new Map();
1516
+ for (const node of graph.values()) {
1517
+ const seen = /* @__PURE__ */ new Set();
1518
+ let at = node.createdIn;
1519
+ while (at !== void 0 && !seen.has(at)) {
1520
+ seen.add(at);
1521
+ let list = out.get(at);
1522
+ if (!list) out.set(at, list = []);
1523
+ list.push(node.id);
1524
+ at = graph.get(at)?.createdIn;
1525
+ }
1526
+ }
1527
+ return out;
1528
+ }
1499
1529
 
1500
1530
  // src/highlight.ts
1501
1531
  var LAYER = "fx-highlight-layer";
package/dist/hook.mjs CHANGED
@@ -177,6 +177,7 @@ function withoutElements(nodes) {
177
177
 
178
178
  // src/observe.ts
179
179
  import {
180
+ createRoot as createRoot2,
180
181
  observeReactiveNodes,
181
182
  untrack as untrack2
182
183
  } from "@fluixi/reactive/signal";
@@ -329,7 +330,14 @@ function callSite(stack, origin) {
329
330
  return fallback ? { location: { ...fallback, external: true }, external: true } : void 0;
330
331
  }
331
332
  function currentCallSite(origin) {
332
- return callSite(new Error().stack, origin);
333
+ const errors = Error;
334
+ const limit = errors.stackTraceLimit;
335
+ errors.stackTraceLimit = 50;
336
+ try {
337
+ return callSite(new Error().stack, origin);
338
+ } finally {
339
+ errors.stackTraceLimit = limit;
340
+ }
333
341
  }
334
342
 
335
343
  // src/instrument.ts
@@ -429,6 +437,8 @@ function walk(value, depth, seen) {
429
437
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
430
438
  let read;
431
439
  try {
440
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
441
+ if (descriptor?.get) return `${key}: [getter]`;
432
442
  read = walk(object[key], depth + 1, seen);
433
443
  } catch {
434
444
  read = "[unreadable]";
@@ -828,6 +838,7 @@ var PREFIX = {
828
838
  service: "svc"
829
839
  };
830
840
  function readProps(props) {
841
+ if (readOnce.has(props)) return readOnce.get(props);
831
842
  const at = propsLocations(props);
832
843
  const out = [];
833
844
  for (const name of Object.keys(props)) {
@@ -838,13 +849,25 @@ function readProps(props) {
838
849
  ...where ? { at: { line: where[0], column: where[1] } } : {}
839
850
  };
840
851
  try {
841
- report.value = formatValue(untrack2(() => props[name]), 200);
852
+ report.value = formatValue(
853
+ createRoot2((dispose) => {
854
+ try {
855
+ return untrack2(() => props[name]);
856
+ } finally {
857
+ dispose();
858
+ }
859
+ }),
860
+ 200
861
+ );
842
862
  } catch {
843
863
  }
844
864
  out.push(report);
845
865
  }
846
- return out.length ? out : void 0;
866
+ const reports = out.length ? out : void 0;
867
+ readOnce.set(props, reports);
868
+ return reports;
847
869
  }
870
+ var readOnce = /* @__PURE__ */ new WeakMap();
848
871
  function observeGraph(options = {}) {
849
872
  installSourceMarker();
850
873
  const origin = options.origin ?? (typeof location === "object" ? location.origin : void 0);
@@ -852,7 +875,7 @@ function observeGraph(options = {}) {
852
875
  const claims = (node, value) => {
853
876
  for (const dep of node.deps) {
854
877
  const other = graph.get(dep);
855
- if (other?.read && other.read() === value) return false;
878
+ if (other?.read && readRaw(other) === value) return false;
856
879
  }
857
880
  return true;
858
881
  };
@@ -870,6 +893,7 @@ function observeGraph(options = {}) {
870
893
  const scopeOfTarget = /* @__PURE__ */ new WeakMap();
871
894
  const fieldsOf = /* @__PURE__ */ new WeakMap();
872
895
  let described = null;
896
+ let descendants = null;
873
897
  const rendered = /* @__PURE__ */ new Map();
874
898
  const elementsIn = (value) => {
875
899
  if (value instanceof Element) return [value];
@@ -1231,6 +1255,7 @@ function observeGraph(options = {}) {
1231
1255
  graph,
1232
1256
  sample() {
1233
1257
  described = null;
1258
+ descendants = null;
1234
1259
  const changed = [];
1235
1260
  const moved = (id) => {
1236
1261
  changed.push(id);
@@ -1286,7 +1311,7 @@ function observeGraph(options = {}) {
1286
1311
  runsAtLastSample.set(node.id, node.runs);
1287
1312
  continue;
1288
1313
  }
1289
- const raw = node.read();
1314
+ const raw = readRaw(node);
1290
1315
  if (recording) raws.set(node.id, raw);
1291
1316
  edges(node.id, node);
1292
1317
  const stamped = raw?.$name;
@@ -1361,17 +1386,8 @@ function observeGraph(options = {}) {
1361
1386
  if (live.length) return live;
1362
1387
  collect(id);
1363
1388
  if (!live.length) {
1364
- const inside = (node) => {
1365
- const seen = /* @__PURE__ */ new Set();
1366
- let at = node.createdIn;
1367
- while (at !== void 0 && !seen.has(at)) {
1368
- if (at === id) return true;
1369
- seen.add(at);
1370
- at = graph.get(at)?.createdIn;
1371
- }
1372
- return false;
1373
- };
1374
- for (const node of graph.values()) if (inside(node)) collect(node.id);
1389
+ descendants ??= descendantsByCreator(graph);
1390
+ for (const below of descendants.get(id) ?? []) collect(below);
1375
1391
  }
1376
1392
  return live;
1377
1393
  },
@@ -1484,6 +1500,21 @@ function observeGraph(options = {}) {
1484
1500
  }
1485
1501
  return api;
1486
1502
  }
1503
+ function descendantsByCreator(graph) {
1504
+ const out = /* @__PURE__ */ new Map();
1505
+ for (const node of graph.values()) {
1506
+ const seen = /* @__PURE__ */ new Set();
1507
+ let at = node.createdIn;
1508
+ while (at !== void 0 && !seen.has(at)) {
1509
+ seen.add(at);
1510
+ let list = out.get(at);
1511
+ if (!list) out.set(at, list = []);
1512
+ list.push(node.id);
1513
+ at = graph.get(at)?.createdIn;
1514
+ }
1515
+ }
1516
+ return out;
1517
+ }
1487
1518
 
1488
1519
  // src/highlight.ts
1489
1520
  var LAYER = "fx-highlight-layer";
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @fluixi/devtools v0.2.0-alpha.6 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/devtools v1.0.0-alpha.99 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -259,6 +259,8 @@ function walk(value, depth, seen) {
259
259
  const shown = keys.slice(0, MAX_ENTRIES).map((key) => {
260
260
  let read;
261
261
  try {
262
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
263
+ if (descriptor?.get) return `${key}: [getter]`;
262
264
  read = walk(object[key], depth + 1, seen);
263
265
  } catch {
264
266
  read = "[unreadable]";
@@ -665,7 +667,14 @@ function callSite(stack, origin) {
665
667
  return fallback2 ? { location: { ...fallback2, external: true }, external: true } : void 0;
666
668
  }
667
669
  function currentCallSite(origin) {
668
- return callSite(new Error().stack, origin);
670
+ const errors = Error;
671
+ const limit = errors.stackTraceLimit;
672
+ errors.stackTraceLimit = 50;
673
+ try {
674
+ return callSite(new Error().stack, origin);
675
+ } finally {
676
+ errors.stackTraceLimit = limit;
677
+ }
669
678
  }
670
679
 
671
680
  // src/history.ts
@@ -1672,6 +1681,7 @@ var PREFIX = {
1672
1681
  service: "svc"
1673
1682
  };
1674
1683
  function readProps(props) {
1684
+ if (readOnce.has(props)) return readOnce.get(props);
1675
1685
  const at3 = propsLocations(props);
1676
1686
  const out = [];
1677
1687
  for (const name of Object.keys(props)) {
@@ -1682,13 +1692,25 @@ function readProps(props) {
1682
1692
  ...where ? { at: { line: where[0], column: where[1] } } : {}
1683
1693
  };
1684
1694
  try {
1685
- report.value = formatValue((0, import_signal2.untrack)(() => props[name]), 200);
1695
+ report.value = formatValue(
1696
+ (0, import_signal2.createRoot)((dispose) => {
1697
+ try {
1698
+ return (0, import_signal2.untrack)(() => props[name]);
1699
+ } finally {
1700
+ dispose();
1701
+ }
1702
+ }),
1703
+ 200
1704
+ );
1686
1705
  } catch {
1687
1706
  }
1688
1707
  out.push(report);
1689
1708
  }
1690
- return out.length ? out : void 0;
1709
+ const reports = out.length ? out : void 0;
1710
+ readOnce.set(props, reports);
1711
+ return reports;
1691
1712
  }
1713
+ var readOnce = /* @__PURE__ */ new WeakMap();
1692
1714
  function observeGraph(options = {}) {
1693
1715
  installSourceMarker();
1694
1716
  const origin = options.origin ?? (typeof location === "object" ? location.origin : void 0);
@@ -1696,7 +1718,7 @@ function observeGraph(options = {}) {
1696
1718
  const claims = (node, value) => {
1697
1719
  for (const dep of node.deps) {
1698
1720
  const other = graph.get(dep);
1699
- if (other?.read && other.read() === value) return false;
1721
+ if (other?.read && readRaw(other) === value) return false;
1700
1722
  }
1701
1723
  return true;
1702
1724
  };
@@ -1714,6 +1736,7 @@ function observeGraph(options = {}) {
1714
1736
  const scopeOfTarget = /* @__PURE__ */ new WeakMap();
1715
1737
  const fieldsOf = /* @__PURE__ */ new WeakMap();
1716
1738
  let described = null;
1739
+ let descendants = null;
1717
1740
  const rendered = /* @__PURE__ */ new Map();
1718
1741
  const elementsIn = (value) => {
1719
1742
  if (value instanceof Element) return [value];
@@ -2075,6 +2098,7 @@ function observeGraph(options = {}) {
2075
2098
  graph,
2076
2099
  sample() {
2077
2100
  described = null;
2101
+ descendants = null;
2078
2102
  const changed = [];
2079
2103
  const moved = (id) => {
2080
2104
  changed.push(id);
@@ -2130,7 +2154,7 @@ function observeGraph(options = {}) {
2130
2154
  runsAtLastSample.set(node.id, node.runs);
2131
2155
  continue;
2132
2156
  }
2133
- const raw = node.read();
2157
+ const raw = readRaw(node);
2134
2158
  if (recording) raws.set(node.id, raw);
2135
2159
  edges(node.id, node);
2136
2160
  const stamped = raw?.$name;
@@ -2205,17 +2229,8 @@ function observeGraph(options = {}) {
2205
2229
  if (live.length) return live;
2206
2230
  collect(id);
2207
2231
  if (!live.length) {
2208
- const inside = (node) => {
2209
- const seen = /* @__PURE__ */ new Set();
2210
- let at3 = node.createdIn;
2211
- while (at3 !== void 0 && !seen.has(at3)) {
2212
- if (at3 === id) return true;
2213
- seen.add(at3);
2214
- at3 = graph.get(at3)?.createdIn;
2215
- }
2216
- return false;
2217
- };
2218
- for (const node of graph.values()) if (inside(node)) collect(node.id);
2232
+ descendants ??= descendantsByCreator(graph);
2233
+ for (const below of descendants.get(id) ?? []) collect(below);
2219
2234
  }
2220
2235
  return live;
2221
2236
  },
@@ -2328,6 +2343,21 @@ function observeGraph(options = {}) {
2328
2343
  }
2329
2344
  return api;
2330
2345
  }
2346
+ function descendantsByCreator(graph) {
2347
+ const out = /* @__PURE__ */ new Map();
2348
+ for (const node of graph.values()) {
2349
+ const seen = /* @__PURE__ */ new Set();
2350
+ let at3 = node.createdIn;
2351
+ while (at3 !== void 0 && !seen.has(at3)) {
2352
+ seen.add(at3);
2353
+ let list = out.get(at3);
2354
+ if (!list) out.set(at3, list = []);
2355
+ list.push(node.id);
2356
+ at3 = graph.get(at3)?.createdIn;
2357
+ }
2358
+ }
2359
+ return out;
2360
+ }
2331
2361
 
2332
2362
  // src/highlight.ts
2333
2363
  var LAYER = "fx-highlight-layer";