@fluixi/devtools 0.2.0-alpha.4 → 0.2.0-alpha.6
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/dist/callsite.cjs +9 -0
- package/dist/callsite.d.ts +1 -1
- package/dist/callsite.d.ts.map +1 -1
- package/dist/callsite.js +10 -1
- package/dist/callsite.mjs +9 -0
- package/dist/change-view.js +2 -2
- package/dist/describe.js +2 -2
- package/dist/detail-panel.d.ts +1 -1
- package/dist/detail-panel.d.ts.map +1 -1
- package/dist/detail-panel.js +1 -1
- package/dist/diff.js +1 -1
- package/dist/export.cjs +1 -0
- package/dist/export.d.ts +2 -2
- package/dist/export.d.ts.map +1 -1
- package/dist/export.js +1 -1
- package/dist/export.mjs +1 -0
- package/dist/float.d.ts +1 -1
- package/dist/float.js +3 -3
- package/dist/format.js +3 -3
- package/dist/graph-view.cjs +12 -3
- package/dist/graph-view.d.ts.map +1 -1
- package/dist/graph-view.js +11 -2
- package/dist/graph-view.mjs +12 -3
- package/dist/history.d.ts +2 -2
- package/dist/history.js +2 -2
- package/dist/hook.cjs +158 -19
- package/dist/hook.d.ts +3 -3
- package/dist/hook.js +6 -6
- package/dist/hook.mjs +158 -19
- package/dist/index.cjs +186 -29
- package/dist/index.mjs +186 -29
- package/dist/inspector.cjs +8 -4
- package/dist/inspector.d.ts +2 -2
- package/dist/inspector.js +8 -8
- package/dist/inspector.mjs +8 -4
- package/dist/instrument.cjs +9 -3
- package/dist/instrument.d.ts +16 -1
- package/dist/instrument.d.ts.map +1 -1
- package/dist/instrument.mjs +9 -3
- package/dist/kind-filter.cjs +5 -2
- package/dist/kind-filter.d.ts +2 -2
- package/dist/kind-filter.js +4 -4
- package/dist/kind-filter.mjs +5 -2
- package/dist/observe.cjs +157 -19
- package/dist/observe.d.ts.map +1 -1
- package/dist/observe.js +165 -16
- package/dist/observe.mjs +157 -19
- package/dist/palette.cjs +4 -1
- package/dist/palette.d.ts.map +1 -1
- package/dist/palette.js +3 -0
- package/dist/palette.mjs +4 -1
- package/dist/path.d.ts +2 -2
- package/dist/path.js +2 -2
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/source.cjs +18 -3
- package/dist/source.d.ts +18 -3
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +29 -7
- package/dist/source.mjs +18 -3
- package/dist/timeline.js +3 -3
- package/dist/tree.cjs +19 -4
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +21 -2
- package/dist/tree.mjs +19 -4
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/wire.cjs +3 -1
- package/dist/wire.d.ts +2 -0
- package/dist/wire.d.ts.map +1 -1
- package/dist/wire.js +2 -0
- package/dist/wire.mjs +3 -1
- package/package.json +8 -2
package/dist/instrument.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAe,SAAS,EAAS,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,EAA4D,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEpH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAIxC,MAAM,MAAM,QAAQ,GAChB,OAAO,GACP,MAAM,GACN,QAAQ,GACR,OAAO,GACP,UAAU,GACV,WAAW;AACb,yFAAyF;GACvF,SAAS;AACX,qEAAqE;GACnE,QAAQ;AACV,4DAA4D;GAC1D,SAAS;AACX,oEAAoE;GAClE,OAAO;AACT,8DAA8D;GAC5D,SAAS;AACX,oEAAoE;GAClE,WAAW;AACb,6DAA6D;GAC3D,SAAS;AACX,oDAAoD;GAClD,UAAU;AACZ,0DAA0D;GACxD,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"instrument.d.ts","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"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"}
|
package/dist/instrument.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import { createStore } from "@fluixi/reactive/store";
|
|
|
16
16
|
// src/source.ts
|
|
17
17
|
var MARKER = "__fx_source";
|
|
18
18
|
var COMPONENT_MARKER = "__fx_component";
|
|
19
|
+
var CLASS_MARKER = "__fx_class";
|
|
19
20
|
var HOLE_MARKER = "__fx_hole";
|
|
20
21
|
var PROPS_MARKER = "__fx_props";
|
|
21
22
|
var MARKS = "__FLUIXI_DEVTOOLS_MARKS__";
|
|
@@ -26,10 +27,11 @@ var shared = host[MARKS] ?? {
|
|
|
26
27
|
components: /* @__PURE__ */ new Map()
|
|
27
28
|
};
|
|
28
29
|
host[MARKS] = shared;
|
|
29
|
-
|
|
30
|
+
shared.classes ??= /* @__PURE__ */ new WeakMap();
|
|
31
|
+
function markReactiveSource(file, line, column, name, self) {
|
|
30
32
|
const location = locate(file, line, column);
|
|
31
33
|
if (shared.pending && location.external && !shared.pending.location?.external) return;
|
|
32
|
-
shared.pending = { name, location };
|
|
34
|
+
shared.pending = self && typeof self === "object" ? { name, location, self } : { name, location };
|
|
33
35
|
shared.expiring = false;
|
|
34
36
|
}
|
|
35
37
|
function locate(file, line, column) {
|
|
@@ -45,13 +47,16 @@ function markComponentSource(name, file, line, column) {
|
|
|
45
47
|
}
|
|
46
48
|
if (!seen || seen.file !== file || seen.line !== line) shared.components.set(name, null);
|
|
47
49
|
}
|
|
50
|
+
function markClassSource(constructor, file, line, column) {
|
|
51
|
+
if (typeof constructor === "function") shared.classes.set(constructor, locate(file, line, column));
|
|
52
|
+
}
|
|
48
53
|
function componentSource(name) {
|
|
49
54
|
return shared.components.get(name) ?? void 0;
|
|
50
55
|
}
|
|
51
56
|
function takeReactiveSource() {
|
|
52
57
|
const mark = shared.pending;
|
|
53
58
|
if (mark) {
|
|
54
|
-
if (mark.name !== void 0) shared.pending = { location: mark.location };
|
|
59
|
+
if (mark.name !== void 0 || mark.self) shared.pending = { location: mark.location };
|
|
55
60
|
if (!shared.expiring) {
|
|
56
61
|
shared.expiring = true;
|
|
57
62
|
queueMicrotask(() => {
|
|
@@ -84,6 +89,7 @@ function markProps(props, at) {
|
|
|
84
89
|
function installSourceMarker() {
|
|
85
90
|
if (typeof host[MARKER] !== "function") host[MARKER] = markReactiveSource;
|
|
86
91
|
if (typeof host[COMPONENT_MARKER] !== "function") host[COMPONENT_MARKER] = markComponentSource;
|
|
92
|
+
if (typeof host[CLASS_MARKER] !== "function") host[CLASS_MARKER] = markClassSource;
|
|
87
93
|
if (typeof host[HOLE_MARKER] !== "function") host[HOLE_MARKER] = markHole;
|
|
88
94
|
if (typeof host[PROPS_MARKER] !== "function") host[PROPS_MARKER] = markProps;
|
|
89
95
|
}
|
package/dist/kind-filter.cjs
CHANGED
|
@@ -38,9 +38,12 @@ var FILTERABLE_KINDS = [
|
|
|
38
38
|
"router",
|
|
39
39
|
"handler",
|
|
40
40
|
"context",
|
|
41
|
-
"directive"
|
|
41
|
+
"directive",
|
|
42
|
+
"custom-element",
|
|
43
|
+
"module",
|
|
44
|
+
"service"
|
|
42
45
|
];
|
|
43
|
-
var LABEL = { handler: "route" };
|
|
46
|
+
var LABEL = { handler: "route", "custom-element": "custom element" };
|
|
44
47
|
function createKindFilter(host, options) {
|
|
45
48
|
const doc = host.ownerDocument;
|
|
46
49
|
const kinds = options.kinds ?? FILTERABLE_KINDS;
|
package/dist/kind-filter.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface KindFilterOptions {
|
|
|
14
14
|
/** Offered, in this order. Defaults to every kind a graph can hold. */
|
|
15
15
|
kinds?: readonly NodeKind[];
|
|
16
16
|
/**
|
|
17
|
-
* Called when the selection changes. Null means every kind is on
|
|
17
|
+
* Called when the selection changes. Null means every kind is on, passing a set of all
|
|
18
18
|
* nine instead would hide any kind that has no checkbox here.
|
|
19
19
|
*/
|
|
20
20
|
onChange: (kinds: NodeKind[] | null) => void;
|
|
@@ -30,7 +30,7 @@ export interface KindFilter {
|
|
|
30
30
|
destroy(): void;
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
|
-
* Builds the control inside `host`. Call `destroy` to remove it
|
|
33
|
+
* Builds the control inside `host`. Call `destroy` to remove it, it holds a document
|
|
34
34
|
* listener for closing the panel on an outside click.
|
|
35
35
|
*/
|
|
36
36
|
export declare function createKindFilter(host: HTMLElement, options: KindFilterOptions): KindFilter;
|
package/dist/kind-filter.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/** Every kind a graph can hold, in the order they are offered. */
|
|
2
2
|
export const FILTERABLE_KINDS = [
|
|
3
3
|
'state', 'memo', 'effect', 'store', 'resource', 'component', 'provider', 'control', 'router', 'handler',
|
|
4
|
-
'context', 'directive',
|
|
4
|
+
'context', 'directive', 'custom-element', 'module', 'service',
|
|
5
5
|
];
|
|
6
|
-
/**
|
|
7
|
-
const LABEL = { handler: 'route' };
|
|
6
|
+
/** Kinds whose name does not read as it is. */
|
|
7
|
+
const LABEL = { handler: 'route', 'custom-element': 'custom element' };
|
|
8
8
|
/**
|
|
9
|
-
* Builds the control inside `host`. Call `destroy` to remove it
|
|
9
|
+
* Builds the control inside `host`. Call `destroy` to remove it, it holds a document
|
|
10
10
|
* listener for closing the panel on an outside click.
|
|
11
11
|
*/
|
|
12
12
|
export function createKindFilter(host, options) {
|
package/dist/kind-filter.mjs
CHANGED
|
@@ -11,9 +11,12 @@ var FILTERABLE_KINDS = [
|
|
|
11
11
|
"router",
|
|
12
12
|
"handler",
|
|
13
13
|
"context",
|
|
14
|
-
"directive"
|
|
14
|
+
"directive",
|
|
15
|
+
"custom-element",
|
|
16
|
+
"module",
|
|
17
|
+
"service"
|
|
15
18
|
];
|
|
16
|
-
var LABEL = { handler: "route" };
|
|
19
|
+
var LABEL = { handler: "route", "custom-element": "custom element" };
|
|
17
20
|
function createKindFilter(host, options) {
|
|
18
21
|
const doc = host.ownerDocument;
|
|
19
22
|
const kinds = options.kinds ?? FILTERABLE_KINDS;
|
package/dist/observe.cjs
CHANGED
|
@@ -28,6 +28,7 @@ var import_signal2 = require("@fluixi/reactive/signal");
|
|
|
28
28
|
// src/source.ts
|
|
29
29
|
var MARKER = "__fx_source";
|
|
30
30
|
var COMPONENT_MARKER = "__fx_component";
|
|
31
|
+
var CLASS_MARKER = "__fx_class";
|
|
31
32
|
var HOLE_MARKER = "__fx_hole";
|
|
32
33
|
var PROPS_MARKER = "__fx_props";
|
|
33
34
|
var MARKS = "__FLUIXI_DEVTOOLS_MARKS__";
|
|
@@ -38,12 +39,16 @@ var shared = host[MARKS] ?? {
|
|
|
38
39
|
components: /* @__PURE__ */ new Map()
|
|
39
40
|
};
|
|
40
41
|
host[MARKS] = shared;
|
|
41
|
-
|
|
42
|
+
shared.classes ??= /* @__PURE__ */ new WeakMap();
|
|
43
|
+
function markReactiveSource(file, line, column, name, self) {
|
|
42
44
|
const location2 = locate(file, line, column);
|
|
43
45
|
if (shared.pending && location2.external && !shared.pending.location?.external) return;
|
|
44
|
-
shared.pending = { name, location: location2 };
|
|
46
|
+
shared.pending = self && typeof self === "object" ? { name, location: location2, self } : { name, location: location2 };
|
|
45
47
|
shared.expiring = false;
|
|
46
48
|
}
|
|
49
|
+
function dropReactiveSource() {
|
|
50
|
+
shared.pending = null;
|
|
51
|
+
}
|
|
47
52
|
function locate(file, line, column) {
|
|
48
53
|
const external = !!file && (/^([a-zA-Z]:)?[\\/]/.test(file) || file.includes("node_modules/"));
|
|
49
54
|
return external ? { file, line, column, external } : { file, line, column };
|
|
@@ -57,13 +62,19 @@ function markComponentSource(name, file, line, column) {
|
|
|
57
62
|
}
|
|
58
63
|
if (!seen || seen.file !== file || seen.line !== line) shared.components.set(name, null);
|
|
59
64
|
}
|
|
65
|
+
function markClassSource(constructor, file, line, column) {
|
|
66
|
+
if (typeof constructor === "function") shared.classes.set(constructor, locate(file, line, column));
|
|
67
|
+
}
|
|
68
|
+
function classSource(constructor) {
|
|
69
|
+
return typeof constructor === "function" ? shared.classes.get(constructor) : void 0;
|
|
70
|
+
}
|
|
60
71
|
function componentSource(name) {
|
|
61
72
|
return shared.components.get(name) ?? void 0;
|
|
62
73
|
}
|
|
63
74
|
function takeReactiveSource() {
|
|
64
75
|
const mark = shared.pending;
|
|
65
76
|
if (mark) {
|
|
66
|
-
if (mark.name !== void 0) shared.pending = { location: mark.location };
|
|
77
|
+
if (mark.name !== void 0 || mark.self) shared.pending = { location: mark.location };
|
|
67
78
|
if (!shared.expiring) {
|
|
68
79
|
shared.expiring = true;
|
|
69
80
|
queueMicrotask(() => {
|
|
@@ -103,6 +114,7 @@ function holeLocation(accessor) {
|
|
|
103
114
|
function installSourceMarker() {
|
|
104
115
|
if (typeof host[MARKER] !== "function") host[MARKER] = markReactiveSource;
|
|
105
116
|
if (typeof host[COMPONENT_MARKER] !== "function") host[COMPONENT_MARKER] = markComponentSource;
|
|
117
|
+
if (typeof host[CLASS_MARKER] !== "function") host[CLASS_MARKER] = markClassSource;
|
|
106
118
|
if (typeof host[HOLE_MARKER] !== "function") host[HOLE_MARKER] = markHole;
|
|
107
119
|
if (typeof host[PROPS_MARKER] !== "function") host[PROPS_MARKER] = markProps;
|
|
108
120
|
}
|
|
@@ -114,6 +126,15 @@ var INTERNAL = [
|
|
|
114
126
|
"/packages/dom/",
|
|
115
127
|
"/packages/core/",
|
|
116
128
|
"/packages/devtools/",
|
|
129
|
+
"/packages/web-components/",
|
|
130
|
+
"/packages/auth/",
|
|
131
|
+
"/packages/oauth2/",
|
|
132
|
+
"/packages/session/",
|
|
133
|
+
"/packages/router/",
|
|
134
|
+
"/packages/head/",
|
|
135
|
+
"/packages/start/",
|
|
136
|
+
"/packages/server/",
|
|
137
|
+
"/packages/template-runtime/",
|
|
117
138
|
"/@fluixi/",
|
|
118
139
|
"node_modules",
|
|
119
140
|
"fluixi-devtools",
|
|
@@ -664,7 +685,10 @@ var KIND_COLOR = {
|
|
|
664
685
|
binding: "#5eead4",
|
|
665
686
|
setter: "#fb7185",
|
|
666
687
|
group: "#8a90a2",
|
|
667
|
-
element: "#8a90a2"
|
|
688
|
+
element: "#8a90a2",
|
|
689
|
+
"custom-element": "#2dd4bf",
|
|
690
|
+
module: "#facc15",
|
|
691
|
+
service: "#60a5fa"
|
|
668
692
|
};
|
|
669
693
|
var kindVar = (kind) => `--fx-kind-${kind}`;
|
|
670
694
|
var kindColor = (kind) => `var(${kindVar(kind)}, ${KIND_COLOR[kind]})`;
|
|
@@ -681,7 +705,11 @@ var TREE_KINDS = /* @__PURE__ */ new Set([
|
|
|
681
705
|
"handler",
|
|
682
706
|
// A component a plugin recognised as providing a context. Still a tag the author wrote,
|
|
683
707
|
// so leaving it out took it and everything it rendered out of the tree.
|
|
684
|
-
"provider"
|
|
708
|
+
"provider",
|
|
709
|
+
// Scopes the runtime reported: what their signals and memos belong to.
|
|
710
|
+
"custom-element",
|
|
711
|
+
"module",
|
|
712
|
+
"service"
|
|
685
713
|
]);
|
|
686
714
|
var TREE_CSS = `
|
|
687
715
|
.fx-tree-row {
|
|
@@ -797,7 +825,11 @@ var PREFIX = {
|
|
|
797
825
|
// A plugin's, and it names them itself.
|
|
798
826
|
directive: "d",
|
|
799
827
|
context: "ctx",
|
|
800
|
-
provider: "p"
|
|
828
|
+
provider: "p",
|
|
829
|
+
// Scopes are always named by what opened them.
|
|
830
|
+
"custom-element": "el",
|
|
831
|
+
module: "mod",
|
|
832
|
+
service: "svc"
|
|
801
833
|
};
|
|
802
834
|
function readProps(props) {
|
|
803
835
|
const at = propsLocations(props);
|
|
@@ -837,6 +869,10 @@ function observeGraph(options = {}) {
|
|
|
837
869
|
const boundTo = /* @__PURE__ */ new WeakMap();
|
|
838
870
|
const drivenBy = /* @__PURE__ */ new WeakMap();
|
|
839
871
|
let reaches = /* @__PURE__ */ new Map();
|
|
872
|
+
const SCOPE_KINDS = /* @__PURE__ */ new Set(["custom-element", "module", "service"]);
|
|
873
|
+
const scopeIds = /* @__PURE__ */ new WeakMap();
|
|
874
|
+
const scopeOfTarget = /* @__PURE__ */ new WeakMap();
|
|
875
|
+
const fieldsOf = /* @__PURE__ */ new WeakMap();
|
|
840
876
|
let described = null;
|
|
841
877
|
const rendered = /* @__PURE__ */ new Map();
|
|
842
878
|
const elementsIn = (value) => {
|
|
@@ -933,7 +969,9 @@ function observeGraph(options = {}) {
|
|
|
933
969
|
// Mapped, unlike `mark`: these two came off a stack, so they are positions in the
|
|
934
970
|
// compiled file until a host translates them.
|
|
935
971
|
...site && !site.external ? { usedAt: mapped(site.location) } : {},
|
|
936
|
-
|
|
972
|
+
// Not inside a scope: an element's prop is made by the package for the element, and
|
|
973
|
+
// the package's line says less than the scope it sits in already does.
|
|
974
|
+
...site && site.external && !mark?.location && !report.scope ? { source: mapped(site.location) } : {}
|
|
937
975
|
};
|
|
938
976
|
const owner = ancestor(report.parents);
|
|
939
977
|
if (owner !== void 0) node.createdIn = owner;
|
|
@@ -943,6 +981,28 @@ function observeGraph(options = {}) {
|
|
|
943
981
|
node.createdIn = originId;
|
|
944
982
|
if (from.source) node.source = from.source;
|
|
945
983
|
}
|
|
984
|
+
const scopeId = report.scope ? scopeIds.get(report.scope) : void 0;
|
|
985
|
+
if (scopeId !== void 0) {
|
|
986
|
+
node.scope = scopeId;
|
|
987
|
+
const creator = node.createdIn !== void 0 ? graph.get(node.createdIn) : void 0;
|
|
988
|
+
const insideAlready = node.createdIn === scopeId || creator?.scope === scopeId;
|
|
989
|
+
if (!insideAlready) node.createdIn = scopeId;
|
|
990
|
+
} else if (node.createdIn !== void 0) {
|
|
991
|
+
const creator = graph.get(node.createdIn);
|
|
992
|
+
const inherited = creator && SCOPE_KINDS.has(creator.kind) ? creator.id : creator?.scope;
|
|
993
|
+
if (inherited !== void 0) node.scope = inherited;
|
|
994
|
+
}
|
|
995
|
+
const self = mark?.self;
|
|
996
|
+
if (self) {
|
|
997
|
+
const list = fieldsOf.get(self);
|
|
998
|
+
if (list) list.push(id);
|
|
999
|
+
else fieldsOf.set(self, [id]);
|
|
1000
|
+
const open = scopeOfTarget.get(self);
|
|
1001
|
+
if (open !== void 0 && graph.has(open)) {
|
|
1002
|
+
node.scope = open;
|
|
1003
|
+
node.createdIn = open;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
946
1006
|
if (kind !== "effect" && typeof handle === "function") {
|
|
947
1007
|
const read = handle;
|
|
948
1008
|
node.read = () => (0, import_signal2.untrack)(read);
|
|
@@ -1078,20 +1138,90 @@ function observeGraph(options = {}) {
|
|
|
1078
1138
|
internals.delete(target);
|
|
1079
1139
|
const id = ids.get(target);
|
|
1080
1140
|
if (id === void 0) return;
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1141
|
+
forget(id);
|
|
1142
|
+
},
|
|
1143
|
+
scope(scope, info, parent) {
|
|
1144
|
+
dropReactiveSource();
|
|
1145
|
+
const id = seq++;
|
|
1146
|
+
const kind = info.kind === "element" ? "custom-element" : info.kind;
|
|
1147
|
+
const parentId = parent ? scopeIds.get(parent) : void 0;
|
|
1148
|
+
const found = currentCallSite(origin);
|
|
1149
|
+
const site = found && !/\0|__x00__|^virtual:/.test(found.location.file ?? "") ? found : void 0;
|
|
1150
|
+
const node = {
|
|
1151
|
+
id,
|
|
1152
|
+
label: info.name,
|
|
1153
|
+
kind,
|
|
1154
|
+
// The author named the element, the module and the service; none of them is plumbing.
|
|
1155
|
+
authored: true,
|
|
1156
|
+
deps: /* @__PURE__ */ new Set(),
|
|
1157
|
+
writes: /* @__PURE__ */ new Set(),
|
|
1158
|
+
runs: 0,
|
|
1159
|
+
lastPulse: 0,
|
|
1160
|
+
...info.detail ? { value: info.detail, detail: info.detail } : {},
|
|
1161
|
+
...parentId !== void 0 ? { scope: parentId, createdIn: parentId } : {}
|
|
1162
|
+
};
|
|
1163
|
+
const target = info.target;
|
|
1164
|
+
if (kind === "custom-element") {
|
|
1165
|
+
const defined = target ? classSource(target.constructor) : void 0;
|
|
1166
|
+
if (defined) node.declaredAt = defined;
|
|
1167
|
+
} else if (site && !site.external) {
|
|
1168
|
+
node.usedAt = mapped(site.location);
|
|
1169
|
+
}
|
|
1170
|
+
scopeIds.set(scope, id);
|
|
1171
|
+
if (target && typeof target === "object" && target.nodeType === 1) {
|
|
1172
|
+
rendered.set(id, [new WeakRef(target)]);
|
|
1173
|
+
}
|
|
1174
|
+
graph.set(id, node);
|
|
1175
|
+
history.created(id, node.createdIn, node.label);
|
|
1176
|
+
if (target && typeof target === "object") {
|
|
1177
|
+
scopeOfTarget.set(target, id);
|
|
1178
|
+
for (const field of fieldsOf.get(target) ?? []) {
|
|
1179
|
+
const made = graph.get(field);
|
|
1180
|
+
if (!made) continue;
|
|
1181
|
+
made.scope = id;
|
|
1182
|
+
made.createdIn = id;
|
|
1183
|
+
revs.set(field, ++revision);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
},
|
|
1187
|
+
scopeEnded(scope) {
|
|
1188
|
+
const id = scopeIds.get(scope);
|
|
1189
|
+
if (id === void 0) return;
|
|
1190
|
+
const ended = /* @__PURE__ */ new Set([id]);
|
|
1191
|
+
for (let grew = true; grew; ) {
|
|
1192
|
+
grew = false;
|
|
1193
|
+
for (const [other, node] of graph) {
|
|
1194
|
+
if (!ended.has(other) && node.scope !== void 0 && ended.has(node.scope)) {
|
|
1195
|
+
ended.add(other);
|
|
1196
|
+
grew = true;
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
for (const gone of ended) forget(gone);
|
|
1201
|
+
},
|
|
1202
|
+
scopeAdopted(scope, parent) {
|
|
1203
|
+
const node = graph.get(scopeIds.get(scope) ?? -1);
|
|
1204
|
+
const parentId = scopeIds.get(parent);
|
|
1205
|
+
if (!node || parentId === void 0 || parentId === node.id) return;
|
|
1206
|
+
node.scope = parentId;
|
|
1207
|
+
node.createdIn = parentId;
|
|
1208
|
+
revs.set(node.id, ++revision);
|
|
1093
1209
|
}
|
|
1094
1210
|
});
|
|
1211
|
+
function forget(id) {
|
|
1212
|
+
removed.push({ id, rev: ++revision });
|
|
1213
|
+
revs.delete(id);
|
|
1214
|
+
if (removed.length > REMOVED_LOG) removed.splice(0, removed.length - REMOVED_LOG);
|
|
1215
|
+
history.disposed(id, graph.get(id)?.label);
|
|
1216
|
+
graph.delete(id);
|
|
1217
|
+
handed.delete(id);
|
|
1218
|
+
raws.delete(id);
|
|
1219
|
+
cores.delete(id);
|
|
1220
|
+
rendered.delete(id);
|
|
1221
|
+
setters.delete(id);
|
|
1222
|
+
runsAtLastSample.delete(id);
|
|
1223
|
+
unnamed.delete(id);
|
|
1224
|
+
}
|
|
1095
1225
|
const edges = (id, node) => {
|
|
1096
1226
|
const sources = cores.get(id)?.sources;
|
|
1097
1227
|
node.deps.clear();
|
|
@@ -1111,6 +1241,14 @@ function observeGraph(options = {}) {
|
|
|
1111
1241
|
revs.set(id, ++revision);
|
|
1112
1242
|
};
|
|
1113
1243
|
const now = Date.now();
|
|
1244
|
+
for (const [id, node] of graph) {
|
|
1245
|
+
if (node.kind !== "custom-element" || node.usedAt) continue;
|
|
1246
|
+
const element = rendered.get(id)?.[0]?.deref();
|
|
1247
|
+
const written = element ? element.__fx_loc : void 0;
|
|
1248
|
+
if (!written?.file) continue;
|
|
1249
|
+
node.usedAt = { file: written.file, line: written.line, column: written.column };
|
|
1250
|
+
revs.set(id, ++revision);
|
|
1251
|
+
}
|
|
1114
1252
|
const bindings = /* @__PURE__ */ new Map();
|
|
1115
1253
|
const drives = /* @__PURE__ */ new Map();
|
|
1116
1254
|
const seen = /* @__PURE__ */ new Map();
|
package/dist/observe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAmE,KAAK,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC9G,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAG9D,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAmDhE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnC,gFAAgF;IAChF,MAAM,IAAI,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,6FAA6F;IAC7F,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,4EAA4E;IAC5E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B;;;;;;OAMG;IACH,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB,8EAA8E;IAC9E,UAAU,IAAI,UAAU,EAAE,CAAC;IAC3B,qEAAqE;IACrE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IACnC,wEAAwE;IACxE,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7C,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,MAAM,IAAI,CAAC;IACrD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,sBAAsB,GAAG,SAAS,CAAC;CACtF;
|
|
1
|
+
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAUA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAmE,KAAK,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC9G,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAG9D,OAAO,EAA0B,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAmDhE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACnC,gFAAgF;IAChF,MAAM,IAAI,MAAM,EAAE,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,6FAA6F;IAC7F,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,4EAA4E;IAC5E,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B;;;;;;OAMG;IACH,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB,8EAA8E;IAC9E,UAAU,IAAI,UAAU,EAAE,CAAC;IAC3B,qEAAqE;IACrE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IACnC,wEAAwE;IACxE,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IACpD;;;OAGG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7C,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,MAAM,IAAI,CAAC;IACrD,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,sBAAsB,GAAG,SAAS,CAAC;CACtF;AA0ED,wBAAgB,YAAY,CAAC,OAAO,GAAE,cAAmB,GAAG,aAAa,CAk2BxE"}
|
package/dist/observe.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// The graph it fills is the same Map<number, RNode> createGraphView already draws, so a
|
|
10
10
|
// renderer does not care which of the two produced it.
|
|
11
11
|
import { observeReactiveNodes, untrack, } from '@fluixi/reactive/signal';
|
|
12
|
-
import { componentSource, holeLocation, installSourceMarker, propsLocations, takeReactiveSource } from './source.js';
|
|
12
|
+
import { classSource, componentSource, dropReactiveSource, holeLocation, installSourceMarker, propsLocations, takeReactiveSource } from './source.js';
|
|
13
13
|
import { currentCallSite } from './callsite.js';
|
|
14
14
|
import { KIND_OF_BUILTIN } from './instrument.js';
|
|
15
15
|
import { formatValue, shorten } from './format.js';
|
|
@@ -81,6 +81,10 @@ const PREFIX = {
|
|
|
81
81
|
directive: 'd',
|
|
82
82
|
context: 'ctx',
|
|
83
83
|
provider: 'p',
|
|
84
|
+
// Scopes are always named by what opened them.
|
|
85
|
+
'custom-element': 'el',
|
|
86
|
+
module: 'mod',
|
|
87
|
+
service: 'svc',
|
|
84
88
|
};
|
|
85
89
|
/**
|
|
86
90
|
* Start watching. Nodes made before this returns are not in the graph, so attach before the
|
|
@@ -175,6 +179,14 @@ export function observeGraph(options = {}) {
|
|
|
175
179
|
const drivenBy = new WeakMap();
|
|
176
180
|
/** Per node, the elements it drives. Rebuilt each sample, like the descriptions are. */
|
|
177
181
|
let reaches = new Map();
|
|
182
|
+
/** The kinds a scope node can be. */
|
|
183
|
+
const SCOPE_KINDS = new Set(['custom-element', 'module', 'service']);
|
|
184
|
+
/** Each open scope's node, by the identity the runtime handed over. */
|
|
185
|
+
const scopeIds = new WeakMap();
|
|
186
|
+
/** The open scope standing for an object, an element, by that object. */
|
|
187
|
+
const scopeOfTarget = new WeakMap();
|
|
188
|
+
/** Nodes a class field made, by the instance: they join its scope when it opens. */
|
|
189
|
+
const fieldsOf = new WeakMap();
|
|
178
190
|
/** Cleared on each sample: the page has moved on. */
|
|
179
191
|
let described = null;
|
|
180
192
|
/**
|
|
@@ -343,7 +355,9 @@ export function observeGraph(options = {}) {
|
|
|
343
355
|
// Mapped, unlike `mark`: these two came off a stack, so they are positions in the
|
|
344
356
|
// compiled file until a host translates them.
|
|
345
357
|
...(site && !site.external ? { usedAt: mapped(site.location) } : {}),
|
|
346
|
-
|
|
358
|
+
// Not inside a scope: an element's prop is made by the package for the element, and
|
|
359
|
+
// the package's line says less than the scope it sits in already does.
|
|
360
|
+
...(site && site.external && !mark?.location && !report.scope ? { source: mapped(site.location) } : {}),
|
|
347
361
|
};
|
|
348
362
|
const owner = ancestor(report.parents);
|
|
349
363
|
if (owner !== undefined)
|
|
@@ -357,6 +371,39 @@ export function observeGraph(options = {}) {
|
|
|
357
371
|
if (from.source)
|
|
358
372
|
node.source = from.source;
|
|
359
373
|
}
|
|
374
|
+
// Made inside an element, module or service: it belongs to that scope, and hangs off it
|
|
375
|
+
// unless what created it already sits inside the same scope, which keeps the nesting.
|
|
376
|
+
const scopeId = report.scope ? scopeIds.get(report.scope) : undefined;
|
|
377
|
+
if (scopeId !== undefined) {
|
|
378
|
+
node.scope = scopeId;
|
|
379
|
+
const creator = node.createdIn !== undefined ? graph.get(node.createdIn) : undefined;
|
|
380
|
+
const insideAlready = node.createdIn === scopeId || creator?.scope === scopeId;
|
|
381
|
+
if (!insideAlready)
|
|
382
|
+
node.createdIn = scopeId;
|
|
383
|
+
}
|
|
384
|
+
else if (node.createdIn !== undefined) {
|
|
385
|
+
// Made after the scope closed, by something inside it: a memo read lazily, an effect
|
|
386
|
+
// re-running, a row a list adds. It belongs where its creator belongs.
|
|
387
|
+
const creator = graph.get(node.createdIn);
|
|
388
|
+
const inherited = creator && SCOPE_KINDS.has(creator.kind) ? creator.id : creator?.scope;
|
|
389
|
+
if (inherited !== undefined)
|
|
390
|
+
node.scope = inherited;
|
|
391
|
+
}
|
|
392
|
+
// A class field: made in the constructor, before the element opened its scope. It belongs
|
|
393
|
+
// to the instance, so it goes in that scope now if it is open, or when it opens.
|
|
394
|
+
const self = mark?.self;
|
|
395
|
+
if (self) {
|
|
396
|
+
const list = fieldsOf.get(self);
|
|
397
|
+
if (list)
|
|
398
|
+
list.push(id);
|
|
399
|
+
else
|
|
400
|
+
fieldsOf.set(self, [id]);
|
|
401
|
+
const open = scopeOfTarget.get(self);
|
|
402
|
+
if (open !== undefined && graph.has(open)) {
|
|
403
|
+
node.scope = open;
|
|
404
|
+
node.createdIn = open;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
360
407
|
// An effect returns nothing worth showing, so it has no reader and pulses on its runs.
|
|
361
408
|
if (kind !== 'effect' && typeof handle === 'function') {
|
|
362
409
|
// Not read here: a memo is lazy, and forcing it from inside its own creation would
|
|
@@ -537,22 +584,110 @@ export function observeGraph(options = {}) {
|
|
|
537
584
|
const id = ids.get(target);
|
|
538
585
|
if (id === undefined)
|
|
539
586
|
return;
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
587
|
+
forget(id);
|
|
588
|
+
},
|
|
589
|
+
scope(scope, info, parent) {
|
|
590
|
+
// Whatever mark is pending was left by the code around this scope, not by what it makes.
|
|
591
|
+
dropReactiveSource();
|
|
592
|
+
const id = seq++;
|
|
593
|
+
const kind = info.kind === 'element' ? 'custom-element' : info.kind;
|
|
594
|
+
const parentId = parent ? scopeIds.get(parent) : undefined;
|
|
595
|
+
// Where it was opened: the line that defined the module, built the service, or, for
|
|
596
|
+
// an element, the one that put it on the page. A bundler's virtual module (the
|
|
597
|
+
// generated app config, `\0virtual:…`) is nowhere a reader can go, so it is left out.
|
|
598
|
+
const found = currentCallSite(origin);
|
|
599
|
+
const site = found && !/\0|__x00__|^virtual:/.test(found.location.file ?? '') ? found : undefined;
|
|
600
|
+
const node = {
|
|
601
|
+
id,
|
|
602
|
+
label: info.name,
|
|
603
|
+
kind,
|
|
604
|
+
// The author named the element, the module and the service; none of them is plumbing.
|
|
605
|
+
authored: true,
|
|
606
|
+
deps: new Set(),
|
|
607
|
+
writes: new Set(),
|
|
608
|
+
runs: 0,
|
|
609
|
+
lastPulse: 0,
|
|
610
|
+
...(info.detail ? { value: info.detail, detail: info.detail } : {}),
|
|
611
|
+
...(parentId !== undefined ? { scope: parentId, createdIn: parentId } : {}),
|
|
612
|
+
};
|
|
613
|
+
const target = info.target;
|
|
614
|
+
if (kind === 'custom-element') {
|
|
615
|
+
// The stack here is whatever connected it, often the `define` that upgraded it, so it
|
|
616
|
+
// says nothing about where the tag is written: that comes off the element at sample.
|
|
617
|
+
// Where it is defined is the class declaration, which the compiler marked.
|
|
618
|
+
const defined = target ? classSource(target.constructor) : undefined;
|
|
619
|
+
if (defined)
|
|
620
|
+
node.declaredAt = defined;
|
|
621
|
+
}
|
|
622
|
+
else if (site && !site.external) {
|
|
623
|
+
// Only the app's own line: a package's is where the package opened the scope for it,
|
|
624
|
+
// which says nothing about this module or service.
|
|
625
|
+
node.usedAt = mapped(site.location);
|
|
626
|
+
}
|
|
627
|
+
scopeIds.set(scope, id);
|
|
628
|
+
if (target && typeof target === 'object' && target.nodeType === 1) {
|
|
629
|
+
rendered.set(id, [new WeakRef(target)]);
|
|
630
|
+
}
|
|
631
|
+
graph.set(id, node);
|
|
632
|
+
history.created(id, node.createdIn, node.label);
|
|
633
|
+
if (target && typeof target === 'object') {
|
|
634
|
+
scopeOfTarget.set(target, id);
|
|
635
|
+
for (const field of fieldsOf.get(target) ?? []) {
|
|
636
|
+
const made = graph.get(field);
|
|
637
|
+
if (!made)
|
|
638
|
+
continue;
|
|
639
|
+
made.scope = id;
|
|
640
|
+
made.createdIn = id;
|
|
641
|
+
revs.set(field, ++revision);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
scopeEnded(scope) {
|
|
646
|
+
const id = scopeIds.get(scope);
|
|
647
|
+
if (id === undefined)
|
|
648
|
+
return;
|
|
649
|
+
// What it made goes with it. An element's prop signals have no owner to dispose them,
|
|
650
|
+
// so they outlived the element as cards pointing at a scope that no longer existed.
|
|
651
|
+
const ended = new Set([id]);
|
|
652
|
+
for (let grew = true; grew;) {
|
|
653
|
+
grew = false;
|
|
654
|
+
for (const [other, node] of graph) {
|
|
655
|
+
if (!ended.has(other) && node.scope !== undefined && ended.has(node.scope)) {
|
|
656
|
+
ended.add(other);
|
|
657
|
+
grew = true;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
for (const gone of ended)
|
|
662
|
+
forget(gone);
|
|
663
|
+
},
|
|
664
|
+
scopeAdopted(scope, parent) {
|
|
665
|
+
const node = graph.get(scopeIds.get(scope) ?? -1);
|
|
666
|
+
const parentId = scopeIds.get(parent);
|
|
667
|
+
if (!node || parentId === undefined || parentId === node.id)
|
|
668
|
+
return;
|
|
669
|
+
node.scope = parentId;
|
|
670
|
+
node.createdIn = parentId;
|
|
671
|
+
revs.set(node.id, ++revision);
|
|
554
672
|
},
|
|
555
673
|
});
|
|
674
|
+
/** Drop a node everywhere it is kept, and log it for a consumer catching up. */
|
|
675
|
+
function forget(id) {
|
|
676
|
+
removed.push({ id, rev: ++revision });
|
|
677
|
+
revs.delete(id);
|
|
678
|
+
if (removed.length > REMOVED_LOG)
|
|
679
|
+
removed.splice(0, removed.length - REMOVED_LOG);
|
|
680
|
+
// The label goes with it: nothing is left to look the name up in.
|
|
681
|
+
history.disposed(id, graph.get(id)?.label);
|
|
682
|
+
graph.delete(id);
|
|
683
|
+
handed.delete(id);
|
|
684
|
+
raws.delete(id);
|
|
685
|
+
cores.delete(id);
|
|
686
|
+
rendered.delete(id);
|
|
687
|
+
setters.delete(id);
|
|
688
|
+
runsAtLastSample.delete(id);
|
|
689
|
+
unnamed.delete(id);
|
|
690
|
+
}
|
|
556
691
|
/** What this node read on its last run, as ids: the edges the core already holds. */
|
|
557
692
|
const edges = (id, node) => {
|
|
558
693
|
const sources = cores.get(id)?.sources;
|
|
@@ -576,6 +711,20 @@ export function observeGraph(options = {}) {
|
|
|
576
711
|
revs.set(id, ++revision);
|
|
577
712
|
};
|
|
578
713
|
const now = Date.now();
|
|
714
|
+
// Where each custom element's tag is written. Stamped by the runtime when the template
|
|
715
|
+
// makes or hydrates it, which can be after its scope opened: an element the server
|
|
716
|
+
// rendered upgrades on import, before hydration gets to it.
|
|
717
|
+
for (const [id, node] of graph) {
|
|
718
|
+
if (node.kind !== 'custom-element' || node.usedAt)
|
|
719
|
+
continue;
|
|
720
|
+
const element = rendered.get(id)?.[0]?.deref();
|
|
721
|
+
const written = element ? element.__fx_loc : undefined;
|
|
722
|
+
if (!written?.file)
|
|
723
|
+
continue;
|
|
724
|
+
node.usedAt = { file: written.file, line: written.line, column: written.column };
|
|
725
|
+
// A new revision without counting as a change: nothing ran, so nothing should pulse.
|
|
726
|
+
revs.set(id, ++revision);
|
|
727
|
+
}
|
|
579
728
|
// What the dom reads, per node. Recounted rather than kept: a binding's sources change
|
|
580
729
|
// with every run, and a stale count is worse than none.
|
|
581
730
|
const bindings = new Map();
|