@qwik.dev/devtools 0.2.1 → 0.2.2
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/plugin/index.d.ts +4 -1
- package/dist/plugin/index.js +1914 -463
- package/dist/ui/_virtual/browser.qwik.mjs +8 -0
- package/dist/ui/_virtual/browser.qwik2.mjs +4 -0
- package/dist/ui/components/DevtoolsButton/DevtoolsButton.qwik.mjs +1 -1
- package/dist/ui/components/DevtoolsPanel/DevtoolsPanel.qwik.mjs +1 -1
- package/dist/ui/components/Tab/Tab.qwik.mjs +1 -1
- package/dist/ui/components/TabContent/TabContent.qwik.mjs +1 -1
- package/dist/ui/components/ThemeToggle/QwikThemeToggle.qwik.mjs +1 -1
- package/dist/ui/components/Tree/Tree.qwik.mjs +1 -1
- package/dist/ui/devtools.qwik.mjs +31 -9
- package/dist/ui/features/Assets/Assets.qwik.mjs +3 -3
- package/dist/ui/features/CodeBreack/CodeBreack.qwik.mjs +4 -4
- package/dist/ui/features/CodeBreack/HtmlParser.qwik.mjs +13 -20
- package/dist/ui/features/CodeBreack/StateParser.qwik.mjs +13 -20
- package/dist/ui/features/Overview/Overview.qwik.mjs +17 -17
- package/dist/ui/features/Packages/Packages.qwik.mjs +4 -4
- package/dist/ui/features/Packages/components/DependencyCard/DependencyCard.qwik.mjs +9 -9
- package/dist/ui/features/Packages/components/PackageIcon/PackageIcon.qwik.mjs +1 -1
- package/dist/ui/features/Performance/Performance.qwik.mjs +307 -0
- package/dist/ui/features/Performance/computePerfViewModel.qwik.mjs +101 -0
- package/dist/ui/features/Performance/transformPerformanceData.qwik.mjs +34 -0
- package/dist/ui/features/RenderTree/RenderTree.qwik.mjs +38 -45
- package/dist/ui/features/RenderTree/TreeBuilder.qwik.mjs +181 -0
- package/dist/ui/features/RenderTree/data.qwik.mjs +30 -16
- package/dist/ui/features/RenderTree/formatTreeData.qwik.mjs +205 -230
- package/dist/ui/features/RenderTree/types.qwik.mjs +50 -0
- package/dist/ui/features/Routes/Routes.qwik.mjs +3 -3
- package/dist/ui/features/inspect/Inspect.qwik.mjs +1 -1
- package/dist/ui/global.css.qwik.mjs +1 -1
- package/dist/ui/lib-types/kit/src/globals.d.ts +56 -5
- package/dist/ui/lib-types/kit/src/index.d.ts +1 -0
- package/dist/ui/lib-types/ui/src/features/Performance/Performance.d.ts +1 -0
- package/dist/ui/lib-types/ui/src/features/Performance/computePerfViewModel.d.ts +33 -0
- package/dist/ui/lib-types/ui/src/features/Performance/computePerfViewModel.test.d.ts +1 -0
- package/dist/ui/lib-types/ui/src/features/Performance/transformPerformanceData.d.ts +22 -0
- package/dist/ui/lib-types/ui/src/features/Performance/transformPerformanceData.test.d.ts +1 -0
- package/dist/ui/lib-types/ui/src/features/RenderTree/TreeBuilder.d.ts +60 -0
- package/dist/ui/lib-types/ui/src/features/RenderTree/data.d.ts +34 -8
- package/dist/ui/lib-types/ui/src/features/RenderTree/formatTreeData.d.ts +79 -148
- package/dist/ui/lib-types/ui/src/features/RenderTree/index.d.ts +6 -0
- package/dist/ui/lib-types/ui/src/features/RenderTree/types.d.ts +116 -0
- package/dist/ui/lib-types/ui/src/types/state.d.ts +1 -1
- package/dist/ui/lib-types/ui/src/utils/shiki.d.ts +2 -0
- package/dist/ui/node_modules/.pnpm/@qwikest_icons@0.0.13_@builder.io_qwik@1.11.0_vite@7.1.3_@types_node@20.14.11_jiti@2.6._02d306fcbd9f637dd624291702bff9c0/node_modules/@qwikest/icons/lib/hi.qwik.qwik.mjs +19 -0
- package/dist/ui/node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/browser.qwik.mjs +177 -0
- package/dist/ui/node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/common.qwik.mjs +182 -0
- package/dist/ui/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.qwik.mjs +120 -0
- package/dist/ui/packages/kit/src/constants.qwik.mjs +0 -2
- package/dist/ui/packages/kit/src/context.qwik.mjs +5 -4
- package/dist/ui/utils/shiki.qwik.mjs +23 -0
- package/package.json +3 -3
- package/dist/ui/features/RenderTree/transfromqseq.qwik.mjs +0 -91
- package/dist/ui/lib-types/ui/src/features/RenderTree/transfromqseq.d.ts +0 -7
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
2
|
-
import { component$, useStyles$,
|
|
2
|
+
import { component$, useSignal, useStyles$, useComputed$, useResource$, useVisibleTask$, $, Resource } from "@qwik.dev/core";
|
|
3
3
|
import { Tree } from "../../components/Tree/Tree.qwik.mjs";
|
|
4
4
|
import { vnode_toObject } from "../../components/Tree/filterVnode.qwik.mjs";
|
|
5
5
|
import { htmlContainer } from "../../utils/location.qwik.mjs";
|
|
6
6
|
import { ISDEVTOOL } from "../../components/Tree/type.qwik.mjs";
|
|
7
7
|
import { removeNodeFromTree } from "../../components/Tree/vnode.qwik.mjs";
|
|
8
8
|
import { isListen } from "../../utils/type.qwik.mjs";
|
|
9
|
-
import
|
|
9
|
+
import debug from "../../_virtual/browser.qwik.mjs";
|
|
10
|
+
import { getHookStore, QrlUtils } from "./formatTreeData.qwik.mjs";
|
|
10
11
|
import { unwrapStore } from "@qwik.dev/core/internal";
|
|
11
12
|
import "../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/index.qwik.mjs";
|
|
12
13
|
import { QRENDERFN, QSEQ, QPROPS } from "../../packages/kit/src/constants.qwik.mjs";
|
|
13
14
|
import { getViteClientRpc } from "../../packages/kit/src/context.qwik.mjs";
|
|
14
15
|
import "../../node_modules/.pnpm/dree@5.1.5/node_modules/dree/bundled/lib/esm/index.esm.qwik.mjs";
|
|
16
|
+
import { getHighlighter } from "../../utils/shiki.qwik.mjs";
|
|
15
17
|
import { getQwikState, returnQrlData } from "./data.qwik.mjs";
|
|
16
18
|
import { HiChevronUpMini } from "../../node_modules/.pnpm/@qwikest_icons@0.0.13_@builder.io_qwik@1.11.0_vite@7.1.3_@types_node@20.14.11_jiti@2.6._02d306fcbd9f637dd624291702bff9c0/node_modules/@qwikest/icons/lib/hi.qwik.qwik.mjs";
|
|
17
|
-
|
|
19
|
+
const log = debug("qwik:devtools:renderTree");
|
|
18
20
|
function getValueColorClass(node, valueText) {
|
|
19
21
|
switch (node.elementType) {
|
|
20
22
|
case "string":
|
|
@@ -34,6 +36,7 @@ function getValueColorClass(node, valueText) {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
const RenderTree = component$(() => {
|
|
39
|
+
const hookStore = useSignal(getHookStore());
|
|
37
40
|
useStyles$(`
|
|
38
41
|
pre.shiki {
|
|
39
42
|
overflow: auto;
|
|
@@ -49,7 +52,7 @@ const RenderTree = component$(() => {
|
|
|
49
52
|
try {
|
|
50
53
|
return htmlContainer();
|
|
51
54
|
} catch (error) {
|
|
52
|
-
|
|
55
|
+
log("get html container failed: %O", error);
|
|
53
56
|
return null;
|
|
54
57
|
}
|
|
55
58
|
});
|
|
@@ -58,17 +61,7 @@ const RenderTree = component$(() => {
|
|
|
58
61
|
if (!codes.value.length) {
|
|
59
62
|
return [];
|
|
60
63
|
}
|
|
61
|
-
const highlighter = await
|
|
62
|
-
themes: [
|
|
63
|
-
"nord"
|
|
64
|
-
],
|
|
65
|
-
langs: [
|
|
66
|
-
"tsx",
|
|
67
|
-
"js",
|
|
68
|
-
"ts",
|
|
69
|
-
"jsx"
|
|
70
|
-
]
|
|
71
|
-
});
|
|
64
|
+
const highlighter = await getHighlighter();
|
|
72
65
|
return codes.value.map((item) => {
|
|
73
66
|
let lang = "tsx";
|
|
74
67
|
if (item.pathId.endsWith(".js")) lang = "js";
|
|
@@ -87,17 +80,17 @@ const RenderTree = component$(() => {
|
|
|
87
80
|
});
|
|
88
81
|
});
|
|
89
82
|
const onNodeClick = $(async (node) => {
|
|
90
|
-
|
|
83
|
+
log(" current node clicked: %O", node);
|
|
91
84
|
const rpc = getViteClientRpc();
|
|
92
85
|
let parsed = [];
|
|
93
|
-
|
|
86
|
+
hookStore.value.clear();
|
|
94
87
|
if (node.props?.[QRENDERFN]) {
|
|
95
|
-
|
|
88
|
+
hookStore.value.add("render", {
|
|
96
89
|
data: {
|
|
97
90
|
render: node.props[QRENDERFN]
|
|
98
91
|
}
|
|
99
92
|
});
|
|
100
|
-
const qrl =
|
|
93
|
+
const qrl = QrlUtils.getChunkName(node.props[QRENDERFN]);
|
|
101
94
|
parsed = getQwikState(qrl);
|
|
102
95
|
}
|
|
103
96
|
if (Array.isArray(node.props?.[QSEQ]) && parsed.length > 0) {
|
|
@@ -106,13 +99,13 @@ const RenderTree = component$(() => {
|
|
|
106
99
|
...returnQrlData(node.props?.[QSEQ])
|
|
107
100
|
];
|
|
108
101
|
normalizedData.forEach((item) => {
|
|
109
|
-
|
|
102
|
+
hookStore.value.add(item.hookType, item);
|
|
110
103
|
});
|
|
111
104
|
}
|
|
112
105
|
if (node.props?.[QPROPS]) {
|
|
113
106
|
const props = unwrapStore(node.props[QPROPS]);
|
|
114
107
|
Object.entries(props).forEach(([key, value]) => {
|
|
115
|
-
|
|
108
|
+
hookStore.value.add(isListen(key) ? "listens" : "props", {
|
|
116
109
|
data: {
|
|
117
110
|
[key]: value
|
|
118
111
|
}
|
|
@@ -120,15 +113,15 @@ const RenderTree = component$(() => {
|
|
|
120
113
|
});
|
|
121
114
|
}
|
|
122
115
|
codes.value = [];
|
|
123
|
-
const res = await rpc?.getModulesByPathIds(
|
|
124
|
-
|
|
116
|
+
const res = await rpc?.getModulesByPathIds(hookStore.value.findAllQrlPaths()) ?? [];
|
|
117
|
+
log("getModulesByPathIds return: %O", res);
|
|
125
118
|
codes.value = res.filter((item) => item.modules);
|
|
126
|
-
stateTree.value = buildTree();
|
|
127
|
-
hookFilters.value =
|
|
119
|
+
stateTree.value = hookStore.value.buildTree();
|
|
120
|
+
hookFilters.value = hookStore.value.getFilterList();
|
|
128
121
|
});
|
|
129
122
|
const currentTab = useSignal("state");
|
|
130
123
|
return /* @__PURE__ */ jsx("div", {
|
|
131
|
-
class: "h-full w-full flex-1 overflow-hidden rounded-md border
|
|
124
|
+
class: "border-border bg-background h-full w-full flex-1 overflow-hidden rounded-md border",
|
|
132
125
|
children: /* @__PURE__ */ jsxs("div", {
|
|
133
126
|
class: "flex h-full w-full",
|
|
134
127
|
children: [
|
|
@@ -143,22 +136,22 @@ const RenderTree = component$(() => {
|
|
|
143
136
|
})
|
|
144
137
|
}),
|
|
145
138
|
/* @__PURE__ */ jsx("div", {
|
|
146
|
-
class: "border-
|
|
139
|
+
class: "border-border border-l"
|
|
147
140
|
}),
|
|
148
141
|
/* @__PURE__ */ jsxs("div", {
|
|
149
142
|
class: "flex h-full min-h-0 w-1/2 flex-col overflow-hidden p-4",
|
|
150
143
|
children: [
|
|
151
144
|
/* @__PURE__ */ jsx("div", {
|
|
152
|
-
class: "border-
|
|
145
|
+
class: "border-border border-b",
|
|
153
146
|
children: /* @__PURE__ */ jsxs("div", {
|
|
154
|
-
class: "flex space-x-4 border-b
|
|
147
|
+
class: "border-border flex space-x-4 border-b",
|
|
155
148
|
children: [
|
|
156
149
|
/* @__PURE__ */ jsx("button", {
|
|
157
150
|
onClick$: () => currentTab.value = "state",
|
|
158
151
|
style: currentTab.value === "state" ? {
|
|
159
152
|
borderBottom: "2px solid var(--color-primary-active)"
|
|
160
153
|
} : {},
|
|
161
|
-
class: "border-b-2 border-b-transparent px-4 py-3 text-sm font-medium
|
|
154
|
+
class: "text-muted-foreground hover:text-foreground border-b-2 border-b-transparent px-4 py-3 text-sm font-medium transition-all duration-300 ease-in-out",
|
|
162
155
|
children: "State"
|
|
163
156
|
}),
|
|
164
157
|
/* @__PURE__ */ jsx("button", {
|
|
@@ -166,7 +159,7 @@ const RenderTree = component$(() => {
|
|
|
166
159
|
style: currentTab.value === "code" ? {
|
|
167
160
|
borderBottom: "2px solid var(--color-primary-active)"
|
|
168
161
|
} : {},
|
|
169
|
-
class: "border-b-2 border-b-transparent px-4 py-3 text-sm font-medium
|
|
162
|
+
class: "text-muted-foreground hover:text-foreground border-b-2 border-b-transparent px-4 py-3 text-sm font-medium transition-all duration-300 ease-in-out",
|
|
170
163
|
children: "Code"
|
|
171
164
|
})
|
|
172
165
|
]
|
|
@@ -176,44 +169,44 @@ const RenderTree = component$(() => {
|
|
|
176
169
|
class: "mt-5 flex min-h-0 flex-1 flex-col",
|
|
177
170
|
children: [
|
|
178
171
|
/* @__PURE__ */ jsxs("div", {
|
|
179
|
-
class: "
|
|
172
|
+
class: "border-border bg-card-item-bg rounded-lg border shadow-sm",
|
|
180
173
|
children: [
|
|
181
174
|
/* @__PURE__ */ jsxs("div", {
|
|
182
|
-
class: "flex items-center justify-between border-b
|
|
175
|
+
class: "border-border flex items-center justify-between border-b px-2 py-2",
|
|
183
176
|
children: [
|
|
184
177
|
/* @__PURE__ */ jsx("span", {
|
|
185
|
-
class: "text-xs font-medium
|
|
178
|
+
class: "text-muted-foreground text-xs font-medium",
|
|
186
179
|
children: "Hooks"
|
|
187
180
|
}),
|
|
188
181
|
/* @__PURE__ */ jsxs("div", {
|
|
189
182
|
class: "flex items-center space-x-2",
|
|
190
183
|
children: [
|
|
191
184
|
/* @__PURE__ */ jsx("button", {
|
|
192
|
-
class: "px-2 py-1 text-xs
|
|
185
|
+
class: "text-primary px-2 py-1 text-xs hover:underline",
|
|
193
186
|
onClick$: $(() => {
|
|
194
187
|
hookFilters.value = hookFilters.value.map((item) => {
|
|
195
188
|
item.display = true;
|
|
196
189
|
return item;
|
|
197
190
|
});
|
|
198
|
-
stateTree.value = buildTree().filter((item) => hookFilters.value.some((hook) => hook.key === item?.label && hook.display));
|
|
191
|
+
stateTree.value = hookStore.value.buildTree().filter((item) => hookFilters.value.some((hook) => hook.key === item?.label && hook.display));
|
|
199
192
|
}),
|
|
200
193
|
children: "Select all"
|
|
201
194
|
}),
|
|
202
195
|
/* @__PURE__ */ jsx("button", {
|
|
203
|
-
class: "px-2 py-1 text-xs
|
|
196
|
+
class: "text-muted-foreground hover:text-foreground px-2 py-1 text-xs hover:underline",
|
|
204
197
|
onClick$: $(() => {
|
|
205
198
|
hookFilters.value = hookFilters.value.map((item) => {
|
|
206
199
|
item.display = false;
|
|
207
200
|
return item;
|
|
208
201
|
});
|
|
209
|
-
stateTree.value = buildTree().filter((item) => hookFilters.value.some((hook) => hook.key === item?.label && hook.display));
|
|
202
|
+
stateTree.value = hookStore.value.buildTree().filter((item) => hookFilters.value.some((hook) => hook.key === item?.label && hook.display));
|
|
210
203
|
}),
|
|
211
204
|
children: "Clear"
|
|
212
205
|
}),
|
|
213
206
|
/* @__PURE__ */ jsx("button", {
|
|
214
207
|
"aria-label": "toggle hooks",
|
|
215
208
|
onClick$: $(() => hooksOpen.value = !hooksOpen.value),
|
|
216
|
-
class: "
|
|
209
|
+
class: "text-muted-foreground hover:text-foreground rounded p-1",
|
|
217
210
|
children: /* @__PURE__ */ jsx(HiChevronUpMini, {
|
|
218
211
|
class: `h-4 w-4 transition-transform duration-200 ${hooksOpen.value ? "rotate-180" : "-rotate-90"}`
|
|
219
212
|
})
|
|
@@ -233,7 +226,7 @@ const RenderTree = component$(() => {
|
|
|
233
226
|
class: "flex items-center",
|
|
234
227
|
children: [
|
|
235
228
|
/* @__PURE__ */ jsx("input", {
|
|
236
|
-
class: "h-4 w-4 rounded-full
|
|
229
|
+
class: "border-border focus:ring-primary-active h-4 w-4 rounded-full focus:ring-offset-0 dark:border-[#374151] dark:bg-[#1F2937]",
|
|
237
230
|
style: {
|
|
238
231
|
accentColor: "var(--color-primary-active)"
|
|
239
232
|
},
|
|
@@ -242,7 +235,7 @@ const RenderTree = component$(() => {
|
|
|
242
235
|
onChange$: (ev) => {
|
|
243
236
|
const target = ev.target;
|
|
244
237
|
hookFilters.value[idx].display = target.checked;
|
|
245
|
-
stateTree.value = buildTree().filter((item2) => hookFilters.value.some((hook) => hook.key === item2?.label && hook.display));
|
|
238
|
+
stateTree.value = hookStore.value.buildTree().filter((item2) => hookFilters.value.some((hook) => hook.key === item2?.label && hook.display));
|
|
246
239
|
}
|
|
247
240
|
}),
|
|
248
241
|
/* @__PURE__ */ jsx("span", {
|
|
@@ -301,20 +294,20 @@ const RenderTree = component$(() => {
|
|
|
301
294
|
]
|
|
302
295
|
}),
|
|
303
296
|
currentTab.value === "code" && /* @__PURE__ */ jsx("div", {
|
|
304
|
-
class: "mt-5 min-h-0 flex-1 overflow-y-auto rounded-lg border
|
|
297
|
+
class: "border-border mt-5 min-h-0 flex-1 overflow-y-auto rounded-lg border p-2 shadow-sm",
|
|
305
298
|
children: /* @__PURE__ */ jsx(Resource, {
|
|
306
299
|
value: highlightedCodesResource,
|
|
307
300
|
onPending: () => /* @__PURE__ */ jsx("div", {
|
|
308
|
-
class: "p-2 text-sm
|
|
301
|
+
class: "text-muted-foreground p-2 text-sm",
|
|
309
302
|
children: "Loading code highlights…"
|
|
310
303
|
}),
|
|
311
304
|
onResolved: (highlighted) => /* @__PURE__ */ jsx(Fragment, {
|
|
312
305
|
children: codes.value.map((item, idx) => /* @__PURE__ */ jsx(Fragment, {
|
|
313
306
|
children: /* @__PURE__ */ jsxs("div", {
|
|
314
|
-
class: "
|
|
307
|
+
class: "border-border bg-card-item-bg hover:bg-card-item-hover-bg mb-4 rounded-xl border p-4 shadow-sm transition-colors",
|
|
315
308
|
children: [
|
|
316
309
|
/* @__PURE__ */ jsx("div", {
|
|
317
|
-
class: "mb-2 break-all text-base font-semibold
|
|
310
|
+
class: "text-primary mb-2 break-all text-base font-semibold",
|
|
318
311
|
children: item.pathId
|
|
319
312
|
}),
|
|
320
313
|
/* @__PURE__ */ jsx("pre", {
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { isValue } from "../../utils/type.qwik.mjs";
|
|
2
|
+
class TreeBuilder {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.idCounter = 0;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Generate a unique ID for a tree node
|
|
8
|
+
*/
|
|
9
|
+
generateId() {
|
|
10
|
+
return `node-${this.idCounter++}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Reset the ID counter (useful for testing)
|
|
14
|
+
*/
|
|
15
|
+
resetIdCounter() {
|
|
16
|
+
this.idCounter = 0;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create a group node (parent node with children)
|
|
20
|
+
*/
|
|
21
|
+
createGroupNode(label, children = []) {
|
|
22
|
+
return {
|
|
23
|
+
id: this.generateId(),
|
|
24
|
+
label,
|
|
25
|
+
props: {},
|
|
26
|
+
children
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Convert any object to TreeNode array
|
|
31
|
+
*/
|
|
32
|
+
objectToTree(obj, parentPath = "") {
|
|
33
|
+
if (!obj || typeof obj !== "object") {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(obj)) {
|
|
37
|
+
return this.arrayToTree(obj, parentPath);
|
|
38
|
+
}
|
|
39
|
+
return this.objectPropertiesToTree(obj, parentPath);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Convert array to TreeNode array
|
|
43
|
+
*/
|
|
44
|
+
arrayToTree(arr, parentPath) {
|
|
45
|
+
return arr.map((item, index) => {
|
|
46
|
+
const path = parentPath ? `${parentPath}[${index}]` : `[${index}]`;
|
|
47
|
+
return this.createNode(item, `[${index}]`, path);
|
|
48
|
+
}).filter((node) => node !== null);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Convert object properties to TreeNode array
|
|
52
|
+
*/
|
|
53
|
+
objectPropertiesToTree(obj, parentPath) {
|
|
54
|
+
const result = [];
|
|
55
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
56
|
+
const path = parentPath ? `${parentPath}.${key}` : key;
|
|
57
|
+
const node = this.createNode(value, key, path);
|
|
58
|
+
if (node) {
|
|
59
|
+
result.push(node);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Create a single TreeNode from a value
|
|
66
|
+
*/
|
|
67
|
+
createNode(value, key, path) {
|
|
68
|
+
if (value === null || value === void 0) {
|
|
69
|
+
return this.createPrimitiveNode(key, value, "null");
|
|
70
|
+
}
|
|
71
|
+
const primitiveNode = this.tryCreatePrimitiveNode(key, value);
|
|
72
|
+
if (primitiveNode) {
|
|
73
|
+
return primitiveNode;
|
|
74
|
+
}
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
return this.createArrayNode(key, value, path);
|
|
77
|
+
}
|
|
78
|
+
if (typeof value === "object") {
|
|
79
|
+
return this.createObjectNode(key, value, path);
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Try to create a primitive node (boolean, number, string, function)
|
|
85
|
+
*/
|
|
86
|
+
tryCreatePrimitiveNode(key, value) {
|
|
87
|
+
switch (typeof value) {
|
|
88
|
+
case "boolean":
|
|
89
|
+
return this.createPrimitiveNode(key, value, "boolean");
|
|
90
|
+
case "number":
|
|
91
|
+
return this.createPrimitiveNode(key, value, "number");
|
|
92
|
+
case "string":
|
|
93
|
+
return this.createPrimitiveNode(key, `"${value}"`, "string");
|
|
94
|
+
case "function":
|
|
95
|
+
return this.createFunctionNode(key, value);
|
|
96
|
+
default:
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Create a node for primitive values
|
|
102
|
+
*/
|
|
103
|
+
createPrimitiveNode(key, value, elementType) {
|
|
104
|
+
return {
|
|
105
|
+
id: this.generateId(),
|
|
106
|
+
label: `${key}: ${value}`,
|
|
107
|
+
props: {},
|
|
108
|
+
elementType
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create a node for function values
|
|
113
|
+
*/
|
|
114
|
+
createFunctionNode(key, fn) {
|
|
115
|
+
const fnName = fn.name ? `ƒ ${fn.name}()` : "ƒ()";
|
|
116
|
+
return {
|
|
117
|
+
id: this.generateId(),
|
|
118
|
+
label: `${key}: ${fnName}`,
|
|
119
|
+
props: {},
|
|
120
|
+
elementType: "function"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Create a node for array values
|
|
125
|
+
*/
|
|
126
|
+
createArrayNode(key, arr, path) {
|
|
127
|
+
const children = arr.map((item, index) => {
|
|
128
|
+
const childPath = `${path}[${index}]`;
|
|
129
|
+
return this.createNode(item, index.toString(), childPath);
|
|
130
|
+
}).filter((node) => node !== null);
|
|
131
|
+
return {
|
|
132
|
+
id: this.generateId(),
|
|
133
|
+
label: `${key}: Array[${arr.length}]`,
|
|
134
|
+
props: {},
|
|
135
|
+
elementType: "array",
|
|
136
|
+
children
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Create a node for object values
|
|
141
|
+
*/
|
|
142
|
+
createObjectNode(key, obj, path) {
|
|
143
|
+
const constructorName = obj.constructor?.name;
|
|
144
|
+
const isPlainObject = constructorName === "Object";
|
|
145
|
+
if (!isPlainObject) {
|
|
146
|
+
return this.createClassInstanceNode(key, obj, constructorName);
|
|
147
|
+
}
|
|
148
|
+
const keys = Object.keys(obj);
|
|
149
|
+
const children = Object.entries(obj).map(([childKey, childValue]) => {
|
|
150
|
+
const childPath = `${path}.${childKey}`;
|
|
151
|
+
return this.createNode(childValue, childKey, childPath);
|
|
152
|
+
}).filter((node) => node !== null);
|
|
153
|
+
return {
|
|
154
|
+
id: this.generateId(),
|
|
155
|
+
label: `${key}: Object {${keys.length}}`,
|
|
156
|
+
props: {},
|
|
157
|
+
elementType: "object",
|
|
158
|
+
children
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Create a node for class instances (non-plain objects)
|
|
163
|
+
*/
|
|
164
|
+
createClassInstanceNode(key, obj, className) {
|
|
165
|
+
const node = {
|
|
166
|
+
id: this.generateId(),
|
|
167
|
+
label: `${key}: Class {${className}}`,
|
|
168
|
+
props: {},
|
|
169
|
+
elementType: "object"
|
|
170
|
+
};
|
|
171
|
+
if (isValue(obj)) {
|
|
172
|
+
node.children = [
|
|
173
|
+
this.createNode(obj.value, "value", "value")
|
|
174
|
+
].filter((n) => n !== null);
|
|
175
|
+
}
|
|
176
|
+
return node;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
export {
|
|
180
|
+
TreeBuilder
|
|
181
|
+
};
|
|
@@ -1,25 +1,39 @@
|
|
|
1
1
|
import "../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/index.qwik.mjs";
|
|
2
|
-
import { QRL_KEY,
|
|
2
|
+
import { QRL_KEY, COMPUTED_QRL_KEY, INNER_USE_HOOK } from "../../packages/kit/src/constants.qwik.mjs";
|
|
3
3
|
import "../../node_modules/.pnpm/dree@5.1.5/node_modules/dree/bundled/lib/esm/index.esm.qwik.mjs";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
const
|
|
12
|
-
|
|
4
|
+
function isUserDefinedHook(seq) {
|
|
5
|
+
const qrl = seq[QRL_KEY] ?? seq[COMPUTED_QRL_KEY];
|
|
6
|
+
const chunkPath = qrl?.$chunk$ ?? "";
|
|
7
|
+
return !chunkPath.includes(INNER_USE_HOOK);
|
|
8
|
+
}
|
|
9
|
+
function getQwikState(qrlChunkName) {
|
|
10
|
+
const globalState = window.QWIK_DEVTOOLS_GLOBAL_STATE ?? {};
|
|
11
|
+
const matchingKey = Object.keys(globalState).find((key) => key.endsWith(qrlChunkName));
|
|
12
|
+
if (!matchingKey) return [];
|
|
13
|
+
const componentState = globalState[matchingKey];
|
|
14
|
+
if (!componentState) return [];
|
|
15
|
+
const entries = componentState.hooks ?? [];
|
|
16
|
+
return entries.filter((item) => item.data !== void 0);
|
|
17
|
+
}
|
|
18
|
+
function getHookTypeFromChunk(chunkPath) {
|
|
19
|
+
return chunkPath.includes("useTask") ? "useTask" : "useVisibleTask";
|
|
20
|
+
}
|
|
21
|
+
function transformQrlSequenceData(seqs) {
|
|
22
|
+
return seqs.filter(isUserDefinedHook).filter((item) => item[QRL_KEY]).map((item) => {
|
|
23
|
+
const qrl = item[QRL_KEY];
|
|
24
|
+
const chunkPath = qrl.$chunk$ ?? "";
|
|
25
|
+
const hookType = getHookTypeFromChunk(chunkPath);
|
|
13
26
|
return {
|
|
14
27
|
category: "expressionStatement",
|
|
15
|
-
data:
|
|
16
|
-
hookType
|
|
17
|
-
|
|
18
|
-
variableName: item[QRL_KEY]?.[CHUNK_KEY]?.includes("useTask") ? "useTask" : "useVisibleTask"
|
|
28
|
+
data: qrl,
|
|
29
|
+
hookType,
|
|
30
|
+
variableName: hookType
|
|
19
31
|
};
|
|
20
32
|
});
|
|
21
|
-
}
|
|
33
|
+
}
|
|
34
|
+
const returnQrlData = transformQrlSequenceData;
|
|
22
35
|
export {
|
|
23
36
|
getQwikState,
|
|
24
|
-
returnQrlData
|
|
37
|
+
returnQrlData,
|
|
38
|
+
transformQrlSequenceData
|
|
25
39
|
};
|