@fluixi/devtools 0.2.0-alpha.5 → 0.2.0-alpha.7

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 (50) hide show
  1. package/dist/callsite.cjs +9 -0
  2. package/dist/callsite.d.ts.map +1 -1
  3. package/dist/callsite.js +9 -0
  4. package/dist/callsite.mjs +9 -0
  5. package/dist/export.cjs +1 -0
  6. package/dist/export.mjs +1 -0
  7. package/dist/graph-view.cjs +12 -3
  8. package/dist/graph-view.d.ts.map +1 -1
  9. package/dist/graph-view.js +11 -2
  10. package/dist/graph-view.mjs +12 -3
  11. package/dist/hook.cjs +173 -21
  12. package/dist/hook.mjs +174 -21
  13. package/dist/index.cjs +199 -29
  14. package/dist/index.mjs +200 -29
  15. package/dist/inspector.cjs +6 -2
  16. package/dist/inspector.js +1 -1
  17. package/dist/inspector.mjs +6 -2
  18. package/dist/instrument.cjs +9 -3
  19. package/dist/instrument.d.ts +16 -1
  20. package/dist/instrument.d.ts.map +1 -1
  21. package/dist/instrument.mjs +9 -3
  22. package/dist/kind-filter.cjs +5 -2
  23. package/dist/kind-filter.js +3 -3
  24. package/dist/kind-filter.mjs +5 -2
  25. package/dist/observe.cjs +172 -21
  26. package/dist/observe.d.ts.map +1 -1
  27. package/dist/observe.js +191 -22
  28. package/dist/observe.mjs +173 -21
  29. package/dist/palette.cjs +4 -1
  30. package/dist/palette.d.ts.map +1 -1
  31. package/dist/palette.js +3 -0
  32. package/dist/palette.mjs +4 -1
  33. package/dist/plugins/index.cjs +1 -1
  34. package/dist/plugins/index.mjs +1 -1
  35. package/dist/source.cjs +18 -3
  36. package/dist/source.d.ts +16 -1
  37. package/dist/source.d.ts.map +1 -1
  38. package/dist/source.js +25 -3
  39. package/dist/source.mjs +18 -3
  40. package/dist/tree.cjs +19 -4
  41. package/dist/tree.d.ts.map +1 -1
  42. package/dist/tree.js +21 -2
  43. package/dist/tree.mjs +19 -4
  44. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  45. package/dist/wire.cjs +3 -1
  46. package/dist/wire.d.ts +2 -0
  47. package/dist/wire.d.ts.map +1 -1
  48. package/dist/wire.js +2 -0
  49. package/dist/wire.mjs +3 -1
  50. package/package.json +2 -2
package/dist/callsite.cjs CHANGED
@@ -30,6 +30,15 @@ var INTERNAL = [
30
30
  "/packages/dom/",
31
31
  "/packages/core/",
32
32
  "/packages/devtools/",
33
+ "/packages/web-components/",
34
+ "/packages/auth/",
35
+ "/packages/oauth2/",
36
+ "/packages/session/",
37
+ "/packages/router/",
38
+ "/packages/head/",
39
+ "/packages/start/",
40
+ "/packages/server/",
41
+ "/packages/template-runtime/",
33
42
  "/@fluixi/",
34
43
  "node_modules",
35
44
  "fluixi-devtools",
@@ -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;AAqD1D;;;;;;;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,CAErE"}
package/dist/callsite.js CHANGED
@@ -12,6 +12,15 @@ const INTERNAL = [
12
12
  '/packages/dom/',
13
13
  '/packages/core/',
14
14
  '/packages/devtools/',
15
+ '/packages/web-components/',
16
+ '/packages/auth/',
17
+ '/packages/oauth2/',
18
+ '/packages/session/',
19
+ '/packages/router/',
20
+ '/packages/head/',
21
+ '/packages/start/',
22
+ '/packages/server/',
23
+ '/packages/template-runtime/',
15
24
  '/@fluixi/',
16
25
  'node_modules',
17
26
  'fluixi-devtools',
package/dist/callsite.mjs CHANGED
@@ -5,6 +5,15 @@ var INTERNAL = [
5
5
  "/packages/dom/",
6
6
  "/packages/core/",
7
7
  "/packages/devtools/",
8
+ "/packages/web-components/",
9
+ "/packages/auth/",
10
+ "/packages/oauth2/",
11
+ "/packages/session/",
12
+ "/packages/router/",
13
+ "/packages/head/",
14
+ "/packages/start/",
15
+ "/packages/server/",
16
+ "/packages/template-runtime/",
8
17
  "/@fluixi/",
9
18
  "node_modules",
10
19
  "fluixi-devtools",
package/dist/export.cjs CHANGED
@@ -38,6 +38,7 @@ var shared = host[MARKS] ?? {
38
38
  components: /* @__PURE__ */ new Map()
39
39
  };
40
40
  host[MARKS] = shared;
41
+ shared.classes ??= /* @__PURE__ */ new WeakMap();
41
42
 
42
43
  // src/format.ts
43
44
  var MAX_DEPTH = 3;
package/dist/export.mjs CHANGED
@@ -22,6 +22,7 @@ var shared = host[MARKS] ?? {
22
22
  components: /* @__PURE__ */ new Map()
23
23
  };
24
24
  host[MARKS] = shared;
25
+ shared.classes ??= /* @__PURE__ */ new WeakMap();
25
26
 
26
27
  // src/format.ts
27
28
  var MAX_DEPTH = 3;
@@ -77,7 +77,10 @@ var KIND_COLOR = {
77
77
  binding: "#5eead4",
78
78
  setter: "#fb7185",
79
79
  group: "#8a90a2",
80
- element: "#8a90a2"
80
+ element: "#8a90a2",
81
+ "custom-element": "#2dd4bf",
82
+ module: "#facc15",
83
+ service: "#60a5fa"
81
84
  };
82
85
  var kindVar = (kind) => `--fx-kind-${kind}`;
83
86
  var kindColor = (kind) => `var(${kindVar(kind)}, ${KIND_COLOR[kind]})`;
@@ -197,8 +200,8 @@ var OVER_NATURAL = 12;
197
200
  var MIN_MAX_ZOOM = 8;
198
201
  var ABSOLUTE_MAX_ZOOM = 4e3;
199
202
  var DRAG_SLOP = 4;
200
- var KIND_CLASS = { state: "n-state", memo: "n-memo", effect: "n-effect", store: "n-store", resource: "n-resource", component: "n-component", control: "n-control", router: "n-router", handler: "n-handler", group: "n-group", binding: "n-binding", setter: "n-setter", directive: "n-directive", context: "n-context", provider: "n-provider" };
201
- var KIND_GLYPH = { state: "◆ state", memo: "ƒ memo", effect: "⚡ effect", store: "▤ store", resource: "⟳ resource", component: "◧ component", control: "⑂ control flow", router: "⤳ router", handler: "⇄ route", group: "▤ framework", binding: "⇥ dom", setter: "✎ sets", directive: "⌘ directive", context: "◈ context", provider: "◈ provider" };
203
+ var KIND_CLASS = { state: "n-state", memo: "n-memo", effect: "n-effect", store: "n-store", resource: "n-resource", component: "n-component", control: "n-control", router: "n-router", handler: "n-handler", group: "n-group", binding: "n-binding", setter: "n-setter", directive: "n-directive", context: "n-context", provider: "n-provider", "custom-element": "n-custom-element", module: "n-module", service: "n-service" };
204
+ var KIND_GLYPH = { state: "◆ state", memo: "ƒ memo", effect: "⚡ effect", store: "▤ store", resource: "⟳ resource", component: "◧ component", control: "⑂ control flow", router: "⤳ router", handler: "⇄ route", group: "▤ framework", binding: "⇥ dom", setter: "✎ sets", directive: "⌘ directive", context: "◈ context", provider: "◈ provider", "custom-element": "⬡ custom element", module: "▦ module", service: "⚙ service" };
202
205
  var GROUP_ID = -1;
203
206
  var bindingIds = /* @__PURE__ */ new Map();
204
207
  var bindingId = (place) => {
@@ -459,6 +462,7 @@ function createGraphView(svg, options = {}) {
459
462
  const inProject = (at) => !!at?.file && at.external !== true;
460
463
  const machinery = (n) => {
461
464
  if (n.authored !== false) return false;
465
+ if (n.scope !== void 0) return false;
462
466
  if (n.kind === "state" || n.kind === "memo" || n.kind === "effect" || n.kind === "context") {
463
467
  return true;
464
468
  }
@@ -868,6 +872,11 @@ ${kindRules((k) => `.fx-node.n-${k}`, "--glow")}
868
872
  .fx-node.n-binding { opacity: .72; }
869
873
  .fx-node.n-setter { opacity: .72; }
870
874
  .fx-node.n-binding .fx-box, .fx-node.n-setter .fx-box { stroke-dasharray: 3 3; }
875
+ /* An element, module or service: a group its signals and memos belong to, so it reads as one. */
876
+ .fx-node.n-custom-element .fx-box, .fx-node.n-module .fx-box, .fx-node.n-service .fx-box {
877
+ stroke-width: 2.2;
878
+ fill: color-mix(in oklab, var(--glow, #5eead4) 14%, var(--fx-node-bg, #131722));
879
+ }
871
880
  .fx-node.n-external { opacity: .55; }
872
881
  .fx-node.n-external .fx-box { stroke-dasharray: 3 2; }
873
882
  .fx-box { fill: var(--fx-node-bg, #131722); stroke: var(--glow, #5eead4); stroke-width: 1.4; stroke-opacity: calc(.5 + var(--pulse,0) * .5); }
@@ -1 +1 @@
1
- {"version":3,"file":"graph-view.d.ts","sourceRoot":"","sources":["../src/graph-view.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAgHvD,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,UAAU,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAClC,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAChC,uDAAuD;IACvD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,wCAAwC;IACxC,SAAS,IAAI,IAAI,CAAC;IAClB,sFAAsF;IACtF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,8CAA8C;IAC9C,YAAY,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,iEAAiE;IACjE,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,sEAAsE;IACtE,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnC,kFAAkF;IAClF,KAAK,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;CAC5C;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,CAuzB7F;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,QAgDxB,CAAC"}
1
+ {"version":3,"file":"graph-view.d.ts","sourceRoot":"","sources":["../src/graph-view.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAgHvD,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,UAAU,CAAC;AAEvD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAClC,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,KAAK,IAAI,IAAI,CAAC;IACd,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;IAChC,uDAAuD;IACvD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,wCAAwC;IACxC,SAAS,IAAI,IAAI,CAAC;IAClB,sFAAsF;IACtF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,8CAA8C;IAC9C,YAAY,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC;IACnC,iEAAiE;IACjE,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,sEAAsE;IACtE,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnC,kFAAkF;IAClF,KAAK,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;CAC5C;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,GAAE,gBAAqB,GAAG,SAAS,CA0zB7F;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,QAqDxB,CAAC"}
@@ -50,8 +50,8 @@ const MIN_MAX_ZOOM = 8;
50
50
  const ABSOLUTE_MAX_ZOOM = 4000;
51
51
  /** Past this the pointer was panning, not clicking. */
52
52
  const DRAG_SLOP = 4;
53
- const KIND_CLASS = { state: 'n-state', memo: 'n-memo', effect: 'n-effect', store: 'n-store', resource: 'n-resource', component: 'n-component', control: 'n-control', router: 'n-router', handler: 'n-handler', group: 'n-group', binding: 'n-binding', setter: 'n-setter', directive: 'n-directive', context: 'n-context', provider: 'n-provider' };
54
- const KIND_GLYPH = { state: '◆ state', memo: 'ƒ memo', effect: '⚡ effect', store: '▤ store', resource: '⟳ resource', component: '◧ component', control: '⑂ control flow', router: '⤳ router', handler: '⇄ route', group: '▤ framework', binding: '⇥ dom', setter: '✎ sets', directive: '⌘ directive', context: '◈ context', provider: '◈ provider' };
53
+ const KIND_CLASS = { state: 'n-state', memo: 'n-memo', effect: 'n-effect', store: 'n-store', resource: 'n-resource', component: 'n-component', control: 'n-control', router: 'n-router', handler: 'n-handler', group: 'n-group', binding: 'n-binding', setter: 'n-setter', directive: 'n-directive', context: 'n-context', provider: 'n-provider', 'custom-element': 'n-custom-element', module: 'n-module', service: 'n-service' };
54
+ const KIND_GLYPH = { state: '◆ state', memo: 'ƒ memo', effect: '⚡ effect', store: '▤ store', resource: '⟳ resource', component: '◧ component', control: '⑂ control flow', router: '⤳ router', handler: '⇄ route', group: '▤ framework', binding: '⇥ dom', setter: '✎ sets', directive: '⌘ directive', context: '◈ context', provider: '◈ provider', 'custom-element': '⬡ custom element', module: '▦ module', service: '⚙ service' };
55
55
  /** The card that stands for everything a dependency made and the application never touched. */
56
56
  const GROUP_ID = -1;
57
57
  /**
@@ -440,6 +440,10 @@ export function createGraphView(svg, options = {}) {
440
440
  const machinery = (n) => {
441
441
  if (n.authored !== false)
442
442
  return false;
443
+ // Inside an element, module or service the app declared: what it holds is the point of
444
+ // showing it, even when a package named the signal rather than the app.
445
+ if (n.scope !== undefined)
446
+ return false;
443
447
  if (n.kind === 'state' || n.kind === 'memo' || n.kind === 'effect' || n.kind === 'context') {
444
448
  return true;
445
449
  }
@@ -956,6 +960,11 @@ ${kindRules((k) => `.fx-node.n-${k}`, '--glow')}
956
960
  .fx-node.n-binding { opacity: .72; }
957
961
  .fx-node.n-setter { opacity: .72; }
958
962
  .fx-node.n-binding .fx-box, .fx-node.n-setter .fx-box { stroke-dasharray: 3 3; }
963
+ /* An element, module or service: a group its signals and memos belong to, so it reads as one. */
964
+ .fx-node.n-custom-element .fx-box, .fx-node.n-module .fx-box, .fx-node.n-service .fx-box {
965
+ stroke-width: 2.2;
966
+ fill: color-mix(in oklab, var(--glow, #5eead4) 14%, var(--fx-node-bg, #131722));
967
+ }
959
968
  .fx-node.n-external { opacity: .55; }
960
969
  .fx-node.n-external .fx-box { stroke-dasharray: 3 2; }
961
970
  .fx-box { fill: var(--fx-node-bg, #131722); stroke: var(--glow, #5eead4); stroke-width: 1.4; stroke-opacity: calc(.5 + var(--pulse,0) * .5); }
@@ -50,7 +50,10 @@ var KIND_COLOR = {
50
50
  binding: "#5eead4",
51
51
  setter: "#fb7185",
52
52
  group: "#8a90a2",
53
- element: "#8a90a2"
53
+ element: "#8a90a2",
54
+ "custom-element": "#2dd4bf",
55
+ module: "#facc15",
56
+ service: "#60a5fa"
54
57
  };
55
58
  var kindVar = (kind) => `--fx-kind-${kind}`;
56
59
  var kindColor = (kind) => `var(${kindVar(kind)}, ${KIND_COLOR[kind]})`;
@@ -170,8 +173,8 @@ var OVER_NATURAL = 12;
170
173
  var MIN_MAX_ZOOM = 8;
171
174
  var ABSOLUTE_MAX_ZOOM = 4e3;
172
175
  var DRAG_SLOP = 4;
173
- var KIND_CLASS = { state: "n-state", memo: "n-memo", effect: "n-effect", store: "n-store", resource: "n-resource", component: "n-component", control: "n-control", router: "n-router", handler: "n-handler", group: "n-group", binding: "n-binding", setter: "n-setter", directive: "n-directive", context: "n-context", provider: "n-provider" };
174
- var KIND_GLYPH = { state: "◆ state", memo: "ƒ memo", effect: "⚡ effect", store: "▤ store", resource: "⟳ resource", component: "◧ component", control: "⑂ control flow", router: "⤳ router", handler: "⇄ route", group: "▤ framework", binding: "⇥ dom", setter: "✎ sets", directive: "⌘ directive", context: "◈ context", provider: "◈ provider" };
176
+ var KIND_CLASS = { state: "n-state", memo: "n-memo", effect: "n-effect", store: "n-store", resource: "n-resource", component: "n-component", control: "n-control", router: "n-router", handler: "n-handler", group: "n-group", binding: "n-binding", setter: "n-setter", directive: "n-directive", context: "n-context", provider: "n-provider", "custom-element": "n-custom-element", module: "n-module", service: "n-service" };
177
+ var KIND_GLYPH = { state: "◆ state", memo: "ƒ memo", effect: "⚡ effect", store: "▤ store", resource: "⟳ resource", component: "◧ component", control: "⑂ control flow", router: "⤳ router", handler: "⇄ route", group: "▤ framework", binding: "⇥ dom", setter: "✎ sets", directive: "⌘ directive", context: "◈ context", provider: "◈ provider", "custom-element": "⬡ custom element", module: "▦ module", service: "⚙ service" };
175
178
  var GROUP_ID = -1;
176
179
  var bindingIds = /* @__PURE__ */ new Map();
177
180
  var bindingId = (place) => {
@@ -432,6 +435,7 @@ function createGraphView(svg, options = {}) {
432
435
  const inProject = (at) => !!at?.file && at.external !== true;
433
436
  const machinery = (n) => {
434
437
  if (n.authored !== false) return false;
438
+ if (n.scope !== void 0) return false;
435
439
  if (n.kind === "state" || n.kind === "memo" || n.kind === "effect" || n.kind === "context") {
436
440
  return true;
437
441
  }
@@ -841,6 +845,11 @@ ${kindRules((k) => `.fx-node.n-${k}`, "--glow")}
841
845
  .fx-node.n-binding { opacity: .72; }
842
846
  .fx-node.n-setter { opacity: .72; }
843
847
  .fx-node.n-binding .fx-box, .fx-node.n-setter .fx-box { stroke-dasharray: 3 3; }
848
+ /* An element, module or service: a group its signals and memos belong to, so it reads as one. */
849
+ .fx-node.n-custom-element .fx-box, .fx-node.n-module .fx-box, .fx-node.n-service .fx-box {
850
+ stroke-width: 2.2;
851
+ fill: color-mix(in oklab, var(--glow, #5eead4) 14%, var(--fx-node-bg, #131722));
852
+ }
844
853
  .fx-node.n-external { opacity: .55; }
845
854
  .fx-node.n-external .fx-box { stroke-dasharray: 3 2; }
846
855
  .fx-box { fill: var(--fx-node-bg, #131722); stroke: var(--glow, #5eead4); stroke-width: 1.4; stroke-opacity: calc(.5 + var(--pulse,0) * .5); }
package/dist/hook.cjs CHANGED
@@ -207,6 +207,7 @@ var import_signal2 = require("@fluixi/reactive/signal");
207
207
  // src/source.ts
208
208
  var MARKER = "__fx_source";
209
209
  var COMPONENT_MARKER = "__fx_component";
210
+ var CLASS_MARKER = "__fx_class";
210
211
  var HOLE_MARKER = "__fx_hole";
211
212
  var PROPS_MARKER = "__fx_props";
212
213
  var MARKS = "__FLUIXI_DEVTOOLS_MARKS__";
@@ -217,12 +218,16 @@ var shared = host[MARKS] ?? {
217
218
  components: /* @__PURE__ */ new Map()
218
219
  };
219
220
  host[MARKS] = shared;
220
- function markReactiveSource(file, line, column, name) {
221
+ shared.classes ??= /* @__PURE__ */ new WeakMap();
222
+ function markReactiveSource(file, line, column, name, self) {
221
223
  const location2 = locate(file, line, column);
222
224
  if (shared.pending && location2.external && !shared.pending.location?.external) return;
223
- shared.pending = { name, location: location2 };
225
+ shared.pending = self && typeof self === "object" ? { name, location: location2, self } : { name, location: location2 };
224
226
  shared.expiring = false;
225
227
  }
228
+ function dropReactiveSource() {
229
+ shared.pending = null;
230
+ }
226
231
  function locate(file, line, column) {
227
232
  const external = !!file && (/^([a-zA-Z]:)?[\\/]/.test(file) || file.includes("node_modules/"));
228
233
  return external ? { file, line, column, external } : { file, line, column };
@@ -236,13 +241,19 @@ function markComponentSource(name, file, line, column) {
236
241
  }
237
242
  if (!seen || seen.file !== file || seen.line !== line) shared.components.set(name, null);
238
243
  }
244
+ function markClassSource(constructor, file, line, column) {
245
+ if (typeof constructor === "function") shared.classes.set(constructor, locate(file, line, column));
246
+ }
247
+ function classSource(constructor) {
248
+ return typeof constructor === "function" ? shared.classes.get(constructor) : void 0;
249
+ }
239
250
  function componentSource(name) {
240
251
  return shared.components.get(name) ?? void 0;
241
252
  }
242
253
  function takeReactiveSource() {
243
254
  const mark = shared.pending;
244
255
  if (mark) {
245
- if (mark.name !== void 0) shared.pending = { location: mark.location };
256
+ if (mark.name !== void 0 || mark.self) shared.pending = { location: mark.location };
246
257
  if (!shared.expiring) {
247
258
  shared.expiring = true;
248
259
  queueMicrotask(() => {
@@ -282,6 +293,7 @@ function holeLocation(accessor) {
282
293
  function installSourceMarker() {
283
294
  if (typeof host[MARKER] !== "function") host[MARKER] = markReactiveSource;
284
295
  if (typeof host[COMPONENT_MARKER] !== "function") host[COMPONENT_MARKER] = markComponentSource;
296
+ if (typeof host[CLASS_MARKER] !== "function") host[CLASS_MARKER] = markClassSource;
285
297
  if (typeof host[HOLE_MARKER] !== "function") host[HOLE_MARKER] = markHole;
286
298
  if (typeof host[PROPS_MARKER] !== "function") host[PROPS_MARKER] = markProps;
287
299
  }
@@ -293,6 +305,15 @@ var INTERNAL = [
293
305
  "/packages/dom/",
294
306
  "/packages/core/",
295
307
  "/packages/devtools/",
308
+ "/packages/web-components/",
309
+ "/packages/auth/",
310
+ "/packages/oauth2/",
311
+ "/packages/session/",
312
+ "/packages/router/",
313
+ "/packages/head/",
314
+ "/packages/start/",
315
+ "/packages/server/",
316
+ "/packages/template-runtime/",
296
317
  "/@fluixi/",
297
318
  "node_modules",
298
319
  "fluixi-devtools",
@@ -672,7 +693,10 @@ var KIND_COLOR = {
672
693
  binding: "#5eead4",
673
694
  setter: "#fb7185",
674
695
  group: "#8a90a2",
675
- element: "#8a90a2"
696
+ element: "#8a90a2",
697
+ "custom-element": "#2dd4bf",
698
+ module: "#facc15",
699
+ service: "#60a5fa"
676
700
  };
677
701
  var kindVar = (kind) => `--fx-kind-${kind}`;
678
702
  var kindColor = (kind) => `var(${kindVar(kind)}, ${KIND_COLOR[kind]})`;
@@ -689,7 +713,11 @@ var TREE_KINDS = /* @__PURE__ */ new Set([
689
713
  "handler",
690
714
  // A component a plugin recognised as providing a context. Still a tag the author wrote,
691
715
  // so leaving it out took it and everything it rendered out of the tree.
692
- "provider"
716
+ "provider",
717
+ // Scopes the runtime reported: what their signals and memos belong to.
718
+ "custom-element",
719
+ "module",
720
+ "service"
693
721
  ]);
694
722
  var TREE_CSS = `
695
723
  .fx-tree-row {
@@ -805,9 +833,14 @@ var PREFIX = {
805
833
  // A plugin's, and it names them itself.
806
834
  directive: "d",
807
835
  context: "ctx",
808
- provider: "p"
836
+ provider: "p",
837
+ // Scopes are always named by what opened them.
838
+ "custom-element": "el",
839
+ module: "mod",
840
+ service: "svc"
809
841
  };
810
842
  function readProps(props) {
843
+ if (readOnce.has(props)) return readOnce.get(props);
811
844
  const at = propsLocations(props);
812
845
  const out = [];
813
846
  for (const name of Object.keys(props)) {
@@ -818,13 +851,25 @@ function readProps(props) {
818
851
  ...where ? { at: { line: where[0], column: where[1] } } : {}
819
852
  };
820
853
  try {
821
- report.value = formatValue((0, import_signal2.untrack)(() => props[name]), 200);
854
+ report.value = formatValue(
855
+ (0, import_signal2.createRoot)((dispose) => {
856
+ try {
857
+ return (0, import_signal2.untrack)(() => props[name]);
858
+ } finally {
859
+ dispose();
860
+ }
861
+ }),
862
+ 200
863
+ );
822
864
  } catch {
823
865
  }
824
866
  out.push(report);
825
867
  }
826
- return out.length ? out : void 0;
868
+ const reports = out.length ? out : void 0;
869
+ readOnce.set(props, reports);
870
+ return reports;
827
871
  }
872
+ var readOnce = /* @__PURE__ */ new WeakMap();
828
873
  function observeGraph(options = {}) {
829
874
  installSourceMarker();
830
875
  const origin = options.origin ?? (typeof location === "object" ? location.origin : void 0);
@@ -845,6 +890,10 @@ function observeGraph(options = {}) {
845
890
  const boundTo = /* @__PURE__ */ new WeakMap();
846
891
  const drivenBy = /* @__PURE__ */ new WeakMap();
847
892
  let reaches = /* @__PURE__ */ new Map();
893
+ const SCOPE_KINDS = /* @__PURE__ */ new Set(["custom-element", "module", "service"]);
894
+ const scopeIds = /* @__PURE__ */ new WeakMap();
895
+ const scopeOfTarget = /* @__PURE__ */ new WeakMap();
896
+ const fieldsOf = /* @__PURE__ */ new WeakMap();
848
897
  let described = null;
849
898
  const rendered = /* @__PURE__ */ new Map();
850
899
  const elementsIn = (value) => {
@@ -941,7 +990,9 @@ function observeGraph(options = {}) {
941
990
  // Mapped, unlike `mark`: these two came off a stack, so they are positions in the
942
991
  // compiled file until a host translates them.
943
992
  ...site && !site.external ? { usedAt: mapped(site.location) } : {},
944
- ...site && site.external && !mark?.location ? { source: mapped(site.location) } : {}
993
+ // Not inside a scope: an element's prop is made by the package for the element, and
994
+ // the package's line says less than the scope it sits in already does.
995
+ ...site && site.external && !mark?.location && !report.scope ? { source: mapped(site.location) } : {}
945
996
  };
946
997
  const owner = ancestor(report.parents);
947
998
  if (owner !== void 0) node.createdIn = owner;
@@ -951,6 +1002,28 @@ function observeGraph(options = {}) {
951
1002
  node.createdIn = originId;
952
1003
  if (from.source) node.source = from.source;
953
1004
  }
1005
+ const scopeId = report.scope ? scopeIds.get(report.scope) : void 0;
1006
+ if (scopeId !== void 0) {
1007
+ node.scope = scopeId;
1008
+ const creator = node.createdIn !== void 0 ? graph.get(node.createdIn) : void 0;
1009
+ const insideAlready = node.createdIn === scopeId || creator?.scope === scopeId;
1010
+ if (!insideAlready) node.createdIn = scopeId;
1011
+ } else if (node.createdIn !== void 0) {
1012
+ const creator = graph.get(node.createdIn);
1013
+ const inherited = creator && SCOPE_KINDS.has(creator.kind) ? creator.id : creator?.scope;
1014
+ if (inherited !== void 0) node.scope = inherited;
1015
+ }
1016
+ const self = mark?.self;
1017
+ if (self) {
1018
+ const list = fieldsOf.get(self);
1019
+ if (list) list.push(id);
1020
+ else fieldsOf.set(self, [id]);
1021
+ const open = scopeOfTarget.get(self);
1022
+ if (open !== void 0 && graph.has(open)) {
1023
+ node.scope = open;
1024
+ node.createdIn = open;
1025
+ }
1026
+ }
954
1027
  if (kind !== "effect" && typeof handle === "function") {
955
1028
  const read = handle;
956
1029
  node.read = () => (0, import_signal2.untrack)(read);
@@ -1086,20 +1159,90 @@ function observeGraph(options = {}) {
1086
1159
  internals.delete(target);
1087
1160
  const id = ids.get(target);
1088
1161
  if (id === void 0) return;
1089
- removed.push({ id, rev: ++revision });
1090
- revs.delete(id);
1091
- if (removed.length > REMOVED_LOG) removed.splice(0, removed.length - REMOVED_LOG);
1092
- history.disposed(id, graph.get(id)?.label);
1093
- graph.delete(id);
1094
- handed.delete(id);
1095
- raws.delete(id);
1096
- cores.delete(id);
1097
- rendered.delete(id);
1098
- setters.delete(id);
1099
- runsAtLastSample.delete(id);
1100
- unnamed.delete(id);
1162
+ forget(id);
1163
+ },
1164
+ scope(scope, info, parent) {
1165
+ dropReactiveSource();
1166
+ const id = seq++;
1167
+ const kind = info.kind === "element" ? "custom-element" : info.kind;
1168
+ const parentId = parent ? scopeIds.get(parent) : void 0;
1169
+ const found = currentCallSite(origin);
1170
+ const site = found && !/\0|__x00__|^virtual:/.test(found.location.file ?? "") ? found : void 0;
1171
+ const node = {
1172
+ id,
1173
+ label: info.name,
1174
+ kind,
1175
+ // The author named the element, the module and the service; none of them is plumbing.
1176
+ authored: true,
1177
+ deps: /* @__PURE__ */ new Set(),
1178
+ writes: /* @__PURE__ */ new Set(),
1179
+ runs: 0,
1180
+ lastPulse: 0,
1181
+ ...info.detail ? { value: info.detail, detail: info.detail } : {},
1182
+ ...parentId !== void 0 ? { scope: parentId, createdIn: parentId } : {}
1183
+ };
1184
+ const target = info.target;
1185
+ if (kind === "custom-element") {
1186
+ const defined = target ? classSource(target.constructor) : void 0;
1187
+ if (defined) node.declaredAt = defined;
1188
+ } else if (site && !site.external) {
1189
+ node.usedAt = mapped(site.location);
1190
+ }
1191
+ scopeIds.set(scope, id);
1192
+ if (target && typeof target === "object" && target.nodeType === 1) {
1193
+ rendered.set(id, [new WeakRef(target)]);
1194
+ }
1195
+ graph.set(id, node);
1196
+ history.created(id, node.createdIn, node.label);
1197
+ if (target && typeof target === "object") {
1198
+ scopeOfTarget.set(target, id);
1199
+ for (const field of fieldsOf.get(target) ?? []) {
1200
+ const made = graph.get(field);
1201
+ if (!made) continue;
1202
+ made.scope = id;
1203
+ made.createdIn = id;
1204
+ revs.set(field, ++revision);
1205
+ }
1206
+ }
1207
+ },
1208
+ scopeEnded(scope) {
1209
+ const id = scopeIds.get(scope);
1210
+ if (id === void 0) return;
1211
+ const ended = /* @__PURE__ */ new Set([id]);
1212
+ for (let grew = true; grew; ) {
1213
+ grew = false;
1214
+ for (const [other, node] of graph) {
1215
+ if (!ended.has(other) && node.scope !== void 0 && ended.has(node.scope)) {
1216
+ ended.add(other);
1217
+ grew = true;
1218
+ }
1219
+ }
1220
+ }
1221
+ for (const gone of ended) forget(gone);
1222
+ },
1223
+ scopeAdopted(scope, parent) {
1224
+ const node = graph.get(scopeIds.get(scope) ?? -1);
1225
+ const parentId = scopeIds.get(parent);
1226
+ if (!node || parentId === void 0 || parentId === node.id) return;
1227
+ node.scope = parentId;
1228
+ node.createdIn = parentId;
1229
+ revs.set(node.id, ++revision);
1101
1230
  }
1102
1231
  });
1232
+ function forget(id) {
1233
+ removed.push({ id, rev: ++revision });
1234
+ revs.delete(id);
1235
+ if (removed.length > REMOVED_LOG) removed.splice(0, removed.length - REMOVED_LOG);
1236
+ history.disposed(id, graph.get(id)?.label);
1237
+ graph.delete(id);
1238
+ handed.delete(id);
1239
+ raws.delete(id);
1240
+ cores.delete(id);
1241
+ rendered.delete(id);
1242
+ setters.delete(id);
1243
+ runsAtLastSample.delete(id);
1244
+ unnamed.delete(id);
1245
+ }
1103
1246
  const edges = (id, node) => {
1104
1247
  const sources = cores.get(id)?.sources;
1105
1248
  node.deps.clear();
@@ -1119,6 +1262,14 @@ function observeGraph(options = {}) {
1119
1262
  revs.set(id, ++revision);
1120
1263
  };
1121
1264
  const now = Date.now();
1265
+ for (const [id, node] of graph) {
1266
+ if (node.kind !== "custom-element" || node.usedAt) continue;
1267
+ const element = rendered.get(id)?.[0]?.deref();
1268
+ const written = element ? element.__fx_loc : void 0;
1269
+ if (!written?.file) continue;
1270
+ node.usedAt = { file: written.file, line: written.line, column: written.column };
1271
+ revs.set(id, ++revision);
1272
+ }
1122
1273
  const bindings = /* @__PURE__ */ new Map();
1123
1274
  const drives = /* @__PURE__ */ new Map();
1124
1275
  const seen = /* @__PURE__ */ new Map();
@@ -1457,6 +1608,7 @@ function serializeGraph(graph, now = Date.now(), options = {}) {
1457
1608
  declaredAt: node.declaredAt,
1458
1609
  usedAt: node.usedAt,
1459
1610
  createdIn: node.createdIn,
1611
+ scope: node.scope,
1460
1612
  bindings: node.bindings,
1461
1613
  targets: node.targets,
1462
1614
  setAt: node.setAt,