@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.
- package/dist/callsite.cjs +9 -0
- package/dist/callsite.d.ts.map +1 -1
- package/dist/callsite.js +9 -0
- package/dist/callsite.mjs +9 -0
- package/dist/export.cjs +1 -0
- package/dist/export.mjs +1 -0
- 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/hook.cjs +173 -21
- package/dist/hook.mjs +174 -21
- package/dist/index.cjs +199 -29
- package/dist/index.mjs +200 -29
- package/dist/inspector.cjs +6 -2
- package/dist/inspector.js +1 -1
- package/dist/inspector.mjs +6 -2
- 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.js +3 -3
- package/dist/kind-filter.mjs +5 -2
- package/dist/observe.cjs +172 -21
- package/dist/observe.d.ts.map +1 -1
- package/dist/observe.js +191 -22
- package/dist/observe.mjs +173 -21
- 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/plugins/index.cjs +1 -1
- package/dist/plugins/index.mjs +1 -1
- package/dist/source.cjs +18 -3
- package/dist/source.d.ts +16 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +25 -3
- package/dist/source.mjs +18 -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 +2 -2
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";
|
|
@@ -184,6 +185,7 @@ import {
|
|
|
184
185
|
// src/source.ts
|
|
185
186
|
var MARKER = "__fx_source";
|
|
186
187
|
var COMPONENT_MARKER = "__fx_component";
|
|
188
|
+
var CLASS_MARKER = "__fx_class";
|
|
187
189
|
var HOLE_MARKER = "__fx_hole";
|
|
188
190
|
var PROPS_MARKER = "__fx_props";
|
|
189
191
|
var MARKS = "__FLUIXI_DEVTOOLS_MARKS__";
|
|
@@ -194,12 +196,16 @@ var shared = host[MARKS] ?? {
|
|
|
194
196
|
components: /* @__PURE__ */ new Map()
|
|
195
197
|
};
|
|
196
198
|
host[MARKS] = shared;
|
|
197
|
-
|
|
199
|
+
shared.classes ??= /* @__PURE__ */ new WeakMap();
|
|
200
|
+
function markReactiveSource(file, line, column, name, self) {
|
|
198
201
|
const location2 = locate(file, line, column);
|
|
199
202
|
if (shared.pending && location2.external && !shared.pending.location?.external) return;
|
|
200
|
-
shared.pending = { name, location: location2 };
|
|
203
|
+
shared.pending = self && typeof self === "object" ? { name, location: location2, self } : { name, location: location2 };
|
|
201
204
|
shared.expiring = false;
|
|
202
205
|
}
|
|
206
|
+
function dropReactiveSource() {
|
|
207
|
+
shared.pending = null;
|
|
208
|
+
}
|
|
203
209
|
function locate(file, line, column) {
|
|
204
210
|
const external = !!file && (/^([a-zA-Z]:)?[\\/]/.test(file) || file.includes("node_modules/"));
|
|
205
211
|
return external ? { file, line, column, external } : { file, line, column };
|
|
@@ -213,13 +219,19 @@ function markComponentSource(name, file, line, column) {
|
|
|
213
219
|
}
|
|
214
220
|
if (!seen || seen.file !== file || seen.line !== line) shared.components.set(name, null);
|
|
215
221
|
}
|
|
222
|
+
function markClassSource(constructor, file, line, column) {
|
|
223
|
+
if (typeof constructor === "function") shared.classes.set(constructor, locate(file, line, column));
|
|
224
|
+
}
|
|
225
|
+
function classSource(constructor) {
|
|
226
|
+
return typeof constructor === "function" ? shared.classes.get(constructor) : void 0;
|
|
227
|
+
}
|
|
216
228
|
function componentSource(name) {
|
|
217
229
|
return shared.components.get(name) ?? void 0;
|
|
218
230
|
}
|
|
219
231
|
function takeReactiveSource() {
|
|
220
232
|
const mark = shared.pending;
|
|
221
233
|
if (mark) {
|
|
222
|
-
if (mark.name !== void 0) shared.pending = { location: mark.location };
|
|
234
|
+
if (mark.name !== void 0 || mark.self) shared.pending = { location: mark.location };
|
|
223
235
|
if (!shared.expiring) {
|
|
224
236
|
shared.expiring = true;
|
|
225
237
|
queueMicrotask(() => {
|
|
@@ -259,6 +271,7 @@ function holeLocation(accessor) {
|
|
|
259
271
|
function installSourceMarker() {
|
|
260
272
|
if (typeof host[MARKER] !== "function") host[MARKER] = markReactiveSource;
|
|
261
273
|
if (typeof host[COMPONENT_MARKER] !== "function") host[COMPONENT_MARKER] = markComponentSource;
|
|
274
|
+
if (typeof host[CLASS_MARKER] !== "function") host[CLASS_MARKER] = markClassSource;
|
|
262
275
|
if (typeof host[HOLE_MARKER] !== "function") host[HOLE_MARKER] = markHole;
|
|
263
276
|
if (typeof host[PROPS_MARKER] !== "function") host[PROPS_MARKER] = markProps;
|
|
264
277
|
}
|
|
@@ -270,6 +283,15 @@ var INTERNAL = [
|
|
|
270
283
|
"/packages/dom/",
|
|
271
284
|
"/packages/core/",
|
|
272
285
|
"/packages/devtools/",
|
|
286
|
+
"/packages/web-components/",
|
|
287
|
+
"/packages/auth/",
|
|
288
|
+
"/packages/oauth2/",
|
|
289
|
+
"/packages/session/",
|
|
290
|
+
"/packages/router/",
|
|
291
|
+
"/packages/head/",
|
|
292
|
+
"/packages/start/",
|
|
293
|
+
"/packages/server/",
|
|
294
|
+
"/packages/template-runtime/",
|
|
273
295
|
"/@fluixi/",
|
|
274
296
|
"node_modules",
|
|
275
297
|
"fluixi-devtools",
|
|
@@ -660,7 +682,10 @@ var KIND_COLOR = {
|
|
|
660
682
|
binding: "#5eead4",
|
|
661
683
|
setter: "#fb7185",
|
|
662
684
|
group: "#8a90a2",
|
|
663
|
-
element: "#8a90a2"
|
|
685
|
+
element: "#8a90a2",
|
|
686
|
+
"custom-element": "#2dd4bf",
|
|
687
|
+
module: "#facc15",
|
|
688
|
+
service: "#60a5fa"
|
|
664
689
|
};
|
|
665
690
|
var kindVar = (kind) => `--fx-kind-${kind}`;
|
|
666
691
|
var kindColor = (kind) => `var(${kindVar(kind)}, ${KIND_COLOR[kind]})`;
|
|
@@ -677,7 +702,11 @@ var TREE_KINDS = /* @__PURE__ */ new Set([
|
|
|
677
702
|
"handler",
|
|
678
703
|
// A component a plugin recognised as providing a context. Still a tag the author wrote,
|
|
679
704
|
// so leaving it out took it and everything it rendered out of the tree.
|
|
680
|
-
"provider"
|
|
705
|
+
"provider",
|
|
706
|
+
// Scopes the runtime reported: what their signals and memos belong to.
|
|
707
|
+
"custom-element",
|
|
708
|
+
"module",
|
|
709
|
+
"service"
|
|
681
710
|
]);
|
|
682
711
|
var TREE_CSS = `
|
|
683
712
|
.fx-tree-row {
|
|
@@ -793,9 +822,14 @@ var PREFIX = {
|
|
|
793
822
|
// A plugin's, and it names them itself.
|
|
794
823
|
directive: "d",
|
|
795
824
|
context: "ctx",
|
|
796
|
-
provider: "p"
|
|
825
|
+
provider: "p",
|
|
826
|
+
// Scopes are always named by what opened them.
|
|
827
|
+
"custom-element": "el",
|
|
828
|
+
module: "mod",
|
|
829
|
+
service: "svc"
|
|
797
830
|
};
|
|
798
831
|
function readProps(props) {
|
|
832
|
+
if (readOnce.has(props)) return readOnce.get(props);
|
|
799
833
|
const at = propsLocations(props);
|
|
800
834
|
const out = [];
|
|
801
835
|
for (const name of Object.keys(props)) {
|
|
@@ -806,13 +840,25 @@ function readProps(props) {
|
|
|
806
840
|
...where ? { at: { line: where[0], column: where[1] } } : {}
|
|
807
841
|
};
|
|
808
842
|
try {
|
|
809
|
-
report.value = formatValue(
|
|
843
|
+
report.value = formatValue(
|
|
844
|
+
createRoot2((dispose) => {
|
|
845
|
+
try {
|
|
846
|
+
return untrack2(() => props[name]);
|
|
847
|
+
} finally {
|
|
848
|
+
dispose();
|
|
849
|
+
}
|
|
850
|
+
}),
|
|
851
|
+
200
|
|
852
|
+
);
|
|
810
853
|
} catch {
|
|
811
854
|
}
|
|
812
855
|
out.push(report);
|
|
813
856
|
}
|
|
814
|
-
|
|
857
|
+
const reports = out.length ? out : void 0;
|
|
858
|
+
readOnce.set(props, reports);
|
|
859
|
+
return reports;
|
|
815
860
|
}
|
|
861
|
+
var readOnce = /* @__PURE__ */ new WeakMap();
|
|
816
862
|
function observeGraph(options = {}) {
|
|
817
863
|
installSourceMarker();
|
|
818
864
|
const origin = options.origin ?? (typeof location === "object" ? location.origin : void 0);
|
|
@@ -833,6 +879,10 @@ function observeGraph(options = {}) {
|
|
|
833
879
|
const boundTo = /* @__PURE__ */ new WeakMap();
|
|
834
880
|
const drivenBy = /* @__PURE__ */ new WeakMap();
|
|
835
881
|
let reaches = /* @__PURE__ */ new Map();
|
|
882
|
+
const SCOPE_KINDS = /* @__PURE__ */ new Set(["custom-element", "module", "service"]);
|
|
883
|
+
const scopeIds = /* @__PURE__ */ new WeakMap();
|
|
884
|
+
const scopeOfTarget = /* @__PURE__ */ new WeakMap();
|
|
885
|
+
const fieldsOf = /* @__PURE__ */ new WeakMap();
|
|
836
886
|
let described = null;
|
|
837
887
|
const rendered = /* @__PURE__ */ new Map();
|
|
838
888
|
const elementsIn = (value) => {
|
|
@@ -929,7 +979,9 @@ function observeGraph(options = {}) {
|
|
|
929
979
|
// Mapped, unlike `mark`: these two came off a stack, so they are positions in the
|
|
930
980
|
// compiled file until a host translates them.
|
|
931
981
|
...site && !site.external ? { usedAt: mapped(site.location) } : {},
|
|
932
|
-
|
|
982
|
+
// Not inside a scope: an element's prop is made by the package for the element, and
|
|
983
|
+
// the package's line says less than the scope it sits in already does.
|
|
984
|
+
...site && site.external && !mark?.location && !report.scope ? { source: mapped(site.location) } : {}
|
|
933
985
|
};
|
|
934
986
|
const owner = ancestor(report.parents);
|
|
935
987
|
if (owner !== void 0) node.createdIn = owner;
|
|
@@ -939,6 +991,28 @@ function observeGraph(options = {}) {
|
|
|
939
991
|
node.createdIn = originId;
|
|
940
992
|
if (from.source) node.source = from.source;
|
|
941
993
|
}
|
|
994
|
+
const scopeId = report.scope ? scopeIds.get(report.scope) : void 0;
|
|
995
|
+
if (scopeId !== void 0) {
|
|
996
|
+
node.scope = scopeId;
|
|
997
|
+
const creator = node.createdIn !== void 0 ? graph.get(node.createdIn) : void 0;
|
|
998
|
+
const insideAlready = node.createdIn === scopeId || creator?.scope === scopeId;
|
|
999
|
+
if (!insideAlready) node.createdIn = scopeId;
|
|
1000
|
+
} else if (node.createdIn !== void 0) {
|
|
1001
|
+
const creator = graph.get(node.createdIn);
|
|
1002
|
+
const inherited = creator && SCOPE_KINDS.has(creator.kind) ? creator.id : creator?.scope;
|
|
1003
|
+
if (inherited !== void 0) node.scope = inherited;
|
|
1004
|
+
}
|
|
1005
|
+
const self = mark?.self;
|
|
1006
|
+
if (self) {
|
|
1007
|
+
const list = fieldsOf.get(self);
|
|
1008
|
+
if (list) list.push(id);
|
|
1009
|
+
else fieldsOf.set(self, [id]);
|
|
1010
|
+
const open = scopeOfTarget.get(self);
|
|
1011
|
+
if (open !== void 0 && graph.has(open)) {
|
|
1012
|
+
node.scope = open;
|
|
1013
|
+
node.createdIn = open;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
942
1016
|
if (kind !== "effect" && typeof handle === "function") {
|
|
943
1017
|
const read = handle;
|
|
944
1018
|
node.read = () => untrack2(read);
|
|
@@ -1074,20 +1148,90 @@ function observeGraph(options = {}) {
|
|
|
1074
1148
|
internals.delete(target);
|
|
1075
1149
|
const id = ids.get(target);
|
|
1076
1150
|
if (id === void 0) return;
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1151
|
+
forget(id);
|
|
1152
|
+
},
|
|
1153
|
+
scope(scope, info, parent) {
|
|
1154
|
+
dropReactiveSource();
|
|
1155
|
+
const id = seq++;
|
|
1156
|
+
const kind = info.kind === "element" ? "custom-element" : info.kind;
|
|
1157
|
+
const parentId = parent ? scopeIds.get(parent) : void 0;
|
|
1158
|
+
const found = currentCallSite(origin);
|
|
1159
|
+
const site = found && !/\0|__x00__|^virtual:/.test(found.location.file ?? "") ? found : void 0;
|
|
1160
|
+
const node = {
|
|
1161
|
+
id,
|
|
1162
|
+
label: info.name,
|
|
1163
|
+
kind,
|
|
1164
|
+
// The author named the element, the module and the service; none of them is plumbing.
|
|
1165
|
+
authored: true,
|
|
1166
|
+
deps: /* @__PURE__ */ new Set(),
|
|
1167
|
+
writes: /* @__PURE__ */ new Set(),
|
|
1168
|
+
runs: 0,
|
|
1169
|
+
lastPulse: 0,
|
|
1170
|
+
...info.detail ? { value: info.detail, detail: info.detail } : {},
|
|
1171
|
+
...parentId !== void 0 ? { scope: parentId, createdIn: parentId } : {}
|
|
1172
|
+
};
|
|
1173
|
+
const target = info.target;
|
|
1174
|
+
if (kind === "custom-element") {
|
|
1175
|
+
const defined = target ? classSource(target.constructor) : void 0;
|
|
1176
|
+
if (defined) node.declaredAt = defined;
|
|
1177
|
+
} else if (site && !site.external) {
|
|
1178
|
+
node.usedAt = mapped(site.location);
|
|
1179
|
+
}
|
|
1180
|
+
scopeIds.set(scope, id);
|
|
1181
|
+
if (target && typeof target === "object" && target.nodeType === 1) {
|
|
1182
|
+
rendered.set(id, [new WeakRef(target)]);
|
|
1183
|
+
}
|
|
1184
|
+
graph.set(id, node);
|
|
1185
|
+
history.created(id, node.createdIn, node.label);
|
|
1186
|
+
if (target && typeof target === "object") {
|
|
1187
|
+
scopeOfTarget.set(target, id);
|
|
1188
|
+
for (const field of fieldsOf.get(target) ?? []) {
|
|
1189
|
+
const made = graph.get(field);
|
|
1190
|
+
if (!made) continue;
|
|
1191
|
+
made.scope = id;
|
|
1192
|
+
made.createdIn = id;
|
|
1193
|
+
revs.set(field, ++revision);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
1197
|
+
scopeEnded(scope) {
|
|
1198
|
+
const id = scopeIds.get(scope);
|
|
1199
|
+
if (id === void 0) return;
|
|
1200
|
+
const ended = /* @__PURE__ */ new Set([id]);
|
|
1201
|
+
for (let grew = true; grew; ) {
|
|
1202
|
+
grew = false;
|
|
1203
|
+
for (const [other, node] of graph) {
|
|
1204
|
+
if (!ended.has(other) && node.scope !== void 0 && ended.has(node.scope)) {
|
|
1205
|
+
ended.add(other);
|
|
1206
|
+
grew = true;
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
for (const gone of ended) forget(gone);
|
|
1211
|
+
},
|
|
1212
|
+
scopeAdopted(scope, parent) {
|
|
1213
|
+
const node = graph.get(scopeIds.get(scope) ?? -1);
|
|
1214
|
+
const parentId = scopeIds.get(parent);
|
|
1215
|
+
if (!node || parentId === void 0 || parentId === node.id) return;
|
|
1216
|
+
node.scope = parentId;
|
|
1217
|
+
node.createdIn = parentId;
|
|
1218
|
+
revs.set(node.id, ++revision);
|
|
1089
1219
|
}
|
|
1090
1220
|
});
|
|
1221
|
+
function forget(id) {
|
|
1222
|
+
removed.push({ id, rev: ++revision });
|
|
1223
|
+
revs.delete(id);
|
|
1224
|
+
if (removed.length > REMOVED_LOG) removed.splice(0, removed.length - REMOVED_LOG);
|
|
1225
|
+
history.disposed(id, graph.get(id)?.label);
|
|
1226
|
+
graph.delete(id);
|
|
1227
|
+
handed.delete(id);
|
|
1228
|
+
raws.delete(id);
|
|
1229
|
+
cores.delete(id);
|
|
1230
|
+
rendered.delete(id);
|
|
1231
|
+
setters.delete(id);
|
|
1232
|
+
runsAtLastSample.delete(id);
|
|
1233
|
+
unnamed.delete(id);
|
|
1234
|
+
}
|
|
1091
1235
|
const edges = (id, node) => {
|
|
1092
1236
|
const sources = cores.get(id)?.sources;
|
|
1093
1237
|
node.deps.clear();
|
|
@@ -1107,6 +1251,14 @@ function observeGraph(options = {}) {
|
|
|
1107
1251
|
revs.set(id, ++revision);
|
|
1108
1252
|
};
|
|
1109
1253
|
const now = Date.now();
|
|
1254
|
+
for (const [id, node] of graph) {
|
|
1255
|
+
if (node.kind !== "custom-element" || node.usedAt) continue;
|
|
1256
|
+
const element = rendered.get(id)?.[0]?.deref();
|
|
1257
|
+
const written = element ? element.__fx_loc : void 0;
|
|
1258
|
+
if (!written?.file) continue;
|
|
1259
|
+
node.usedAt = { file: written.file, line: written.line, column: written.column };
|
|
1260
|
+
revs.set(id, ++revision);
|
|
1261
|
+
}
|
|
1110
1262
|
const bindings = /* @__PURE__ */ new Map();
|
|
1111
1263
|
const drives = /* @__PURE__ */ new Map();
|
|
1112
1264
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -1445,6 +1597,7 @@ function serializeGraph(graph, now = Date.now(), options = {}) {
|
|
|
1445
1597
|
declaredAt: node.declaredAt,
|
|
1446
1598
|
usedAt: node.usedAt,
|
|
1447
1599
|
createdIn: node.createdIn,
|
|
1600
|
+
scope: node.scope,
|
|
1448
1601
|
bindings: node.bindings,
|
|
1449
1602
|
targets: node.targets,
|
|
1450
1603
|
setAt: node.setAt,
|