@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.
Files changed (54) hide show
  1. package/dist/plugin/index.d.ts +4 -1
  2. package/dist/plugin/index.js +1914 -463
  3. package/dist/ui/_virtual/browser.qwik.mjs +8 -0
  4. package/dist/ui/_virtual/browser.qwik2.mjs +4 -0
  5. package/dist/ui/components/DevtoolsButton/DevtoolsButton.qwik.mjs +1 -1
  6. package/dist/ui/components/DevtoolsPanel/DevtoolsPanel.qwik.mjs +1 -1
  7. package/dist/ui/components/Tab/Tab.qwik.mjs +1 -1
  8. package/dist/ui/components/TabContent/TabContent.qwik.mjs +1 -1
  9. package/dist/ui/components/ThemeToggle/QwikThemeToggle.qwik.mjs +1 -1
  10. package/dist/ui/components/Tree/Tree.qwik.mjs +1 -1
  11. package/dist/ui/devtools.qwik.mjs +31 -9
  12. package/dist/ui/features/Assets/Assets.qwik.mjs +3 -3
  13. package/dist/ui/features/CodeBreack/CodeBreack.qwik.mjs +4 -4
  14. package/dist/ui/features/CodeBreack/HtmlParser.qwik.mjs +13 -20
  15. package/dist/ui/features/CodeBreack/StateParser.qwik.mjs +13 -20
  16. package/dist/ui/features/Overview/Overview.qwik.mjs +17 -17
  17. package/dist/ui/features/Packages/Packages.qwik.mjs +4 -4
  18. package/dist/ui/features/Packages/components/DependencyCard/DependencyCard.qwik.mjs +9 -9
  19. package/dist/ui/features/Packages/components/PackageIcon/PackageIcon.qwik.mjs +1 -1
  20. package/dist/ui/features/Performance/Performance.qwik.mjs +307 -0
  21. package/dist/ui/features/Performance/computePerfViewModel.qwik.mjs +101 -0
  22. package/dist/ui/features/Performance/transformPerformanceData.qwik.mjs +34 -0
  23. package/dist/ui/features/RenderTree/RenderTree.qwik.mjs +38 -45
  24. package/dist/ui/features/RenderTree/TreeBuilder.qwik.mjs +181 -0
  25. package/dist/ui/features/RenderTree/data.qwik.mjs +30 -16
  26. package/dist/ui/features/RenderTree/formatTreeData.qwik.mjs +205 -230
  27. package/dist/ui/features/RenderTree/types.qwik.mjs +50 -0
  28. package/dist/ui/features/Routes/Routes.qwik.mjs +3 -3
  29. package/dist/ui/features/inspect/Inspect.qwik.mjs +1 -1
  30. package/dist/ui/global.css.qwik.mjs +1 -1
  31. package/dist/ui/lib-types/kit/src/globals.d.ts +56 -5
  32. package/dist/ui/lib-types/kit/src/index.d.ts +1 -0
  33. package/dist/ui/lib-types/ui/src/features/Performance/Performance.d.ts +1 -0
  34. package/dist/ui/lib-types/ui/src/features/Performance/computePerfViewModel.d.ts +33 -0
  35. package/dist/ui/lib-types/ui/src/features/Performance/computePerfViewModel.test.d.ts +1 -0
  36. package/dist/ui/lib-types/ui/src/features/Performance/transformPerformanceData.d.ts +22 -0
  37. package/dist/ui/lib-types/ui/src/features/Performance/transformPerformanceData.test.d.ts +1 -0
  38. package/dist/ui/lib-types/ui/src/features/RenderTree/TreeBuilder.d.ts +60 -0
  39. package/dist/ui/lib-types/ui/src/features/RenderTree/data.d.ts +34 -8
  40. package/dist/ui/lib-types/ui/src/features/RenderTree/formatTreeData.d.ts +79 -148
  41. package/dist/ui/lib-types/ui/src/features/RenderTree/index.d.ts +6 -0
  42. package/dist/ui/lib-types/ui/src/features/RenderTree/types.d.ts +116 -0
  43. package/dist/ui/lib-types/ui/src/types/state.d.ts +1 -1
  44. package/dist/ui/lib-types/ui/src/utils/shiki.d.ts +2 -0
  45. 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
  46. package/dist/ui/node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/browser.qwik.mjs +177 -0
  47. package/dist/ui/node_modules/.pnpm/debug@4.4.3_supports-color@5.5.0/node_modules/debug/src/common.qwik.mjs +182 -0
  48. package/dist/ui/node_modules/.pnpm/ms@2.1.3/node_modules/ms/index.qwik.mjs +120 -0
  49. package/dist/ui/packages/kit/src/constants.qwik.mjs +0 -2
  50. package/dist/ui/packages/kit/src/context.qwik.mjs +5 -4
  51. package/dist/ui/utils/shiki.qwik.mjs +23 -0
  52. package/package.json +3 -3
  53. package/dist/ui/features/RenderTree/transfromqseq.qwik.mjs +0 -91
  54. package/dist/ui/lib-types/ui/src/features/RenderTree/transfromqseq.d.ts +0 -7
@@ -1,247 +1,222 @@
1
- import { objectToTree, createTreeNodeObj } from "./transfromqseq.qwik.mjs";
2
1
  import "../../node_modules/.pnpm/superjson@2.2.2/node_modules/superjson/dist/index.qwik.mjs";
3
- import { CHUNK_KEY, QRL_KEY, COMPUTED_QRL_KEY, CAPTURE_REF_KEY } from "../../packages/kit/src/constants.qwik.mjs";
2
+ import { CAPTURE_REF_KEY, QRL_KEY, COMPUTED_QRL_KEY } from "../../packages/kit/src/constants.qwik.mjs";
4
3
  import "../../node_modules/.pnpm/dree@5.1.5/node_modules/dree/bundled/lib/esm/index.esm.qwik.mjs";
5
- const schedule = (value) => {
6
- return objectToTree(value);
7
- };
8
- const qSeqs = {
9
- props: {
10
- set: /* @__PURE__ */ new Set(),
11
- toTree: schedule,
12
- display: true
13
- },
14
- listens: {
15
- set: /* @__PURE__ */ new Set(),
16
- toTree: schedule,
17
- display: true
18
- },
19
- useStore: {
20
- set: /* @__PURE__ */ new Set(),
21
- toTree: schedule,
22
- display: true
23
- },
24
- useSignal: {
25
- set: /* @__PURE__ */ new Set(),
26
- toTree: schedule,
27
- display: true
28
- },
29
- useContext: {
30
- set: /* @__PURE__ */ new Set(),
31
- toTree: schedule,
32
- display: true
33
- },
34
- useId: {
35
- set: /* @__PURE__ */ new Set(),
36
- toTree: schedule,
37
- display: true
38
- },
39
- useStyles: {
40
- set: /* @__PURE__ */ new Set(),
41
- toTree: schedule,
42
- display: true
43
- },
44
- useStylesScoped: {
45
- set: /* @__PURE__ */ new Set(),
46
- toTree: schedule,
47
- display: true
48
- },
49
- useConstant: {
50
- set: /* @__PURE__ */ new Set(),
51
- toTree: schedule,
52
- display: true
53
- },
54
- useTask: {
55
- set: /* @__PURE__ */ new Set(),
56
- toTree: schedule,
57
- display: true
58
- },
59
- useVisibleTask: {
60
- set: /* @__PURE__ */ new Set(),
61
- toTree: schedule,
62
- display: true
63
- },
64
- useComputed: {
65
- set: /* @__PURE__ */ new Set(),
66
- toTree: schedule,
67
- display: true
68
- },
69
- useAsyncComputed: {
70
- set: /* @__PURE__ */ new Set(),
71
- toTree: schedule,
72
- display: true
73
- },
74
- useErrorBoundary: {
75
- set: /* @__PURE__ */ new Set(),
76
- toTree: schedule,
77
- display: true
78
- },
79
- useServerData: {
80
- set: /* @__PURE__ */ new Set(),
81
- toTree: schedule,
82
- display: true
83
- },
84
- useSerializer: {
85
- set: /* @__PURE__ */ new Set(),
86
- toTree: schedule,
87
- display: true
88
- },
89
- useResource: {
90
- set: /* @__PURE__ */ new Set(),
91
- toTree: schedule,
92
- display: false
93
- },
94
- useContextProvider: {
95
- set: /* @__PURE__ */ new Set(),
96
- toTree: schedule,
97
- display: true
98
- },
99
- render: {
100
- set: /* @__PURE__ */ new Set(),
101
- toTree: schedule,
102
- display: false
103
- },
104
- useLocation: {
105
- set: /* @__PURE__ */ new Set(),
106
- toTree: schedule,
107
- display: true
108
- },
109
- useNavigate: {
110
- set: /* @__PURE__ */ new Set(),
111
- toTree: schedule,
112
- display: true
113
- },
114
- usePreventNavigate: {
115
- set: /* @__PURE__ */ new Set(),
116
- toTree: schedule,
117
- display: false
118
- },
119
- useContent: {
120
- set: /* @__PURE__ */ new Set(),
121
- toTree: schedule,
122
- display: true
123
- },
124
- useDocumentHead: {
125
- set: /* @__PURE__ */ new Set(),
126
- toTree: schedule,
127
- display: true
128
- },
129
- customhook: {
130
- set: /* @__PURE__ */ new Set(),
131
- toTree: schedule,
132
- display: true
4
+ import debug from "../../_virtual/browser.qwik.mjs";
5
+ import { TreeBuilder } from "./TreeBuilder.qwik.mjs";
6
+ import { HOOK_TYPES, HIDDEN_HOOKS, QRL_HOOKS } from "./types.qwik.mjs";
7
+ const log = debug("qwik:devtools:renderTree");
8
+ class HookStore {
9
+ constructor() {
10
+ this.store = this.createStore();
11
+ this.treeBuilder = new TreeBuilder();
133
12
  }
134
- };
135
- function formatData(type, data) {
136
- qSeqs[type].set.add(data);
137
- }
138
- function getData() {
139
- return Object.entries(qSeqs).map(([name, { set, toTree, display }]) => {
140
- const arr = [
141
- ...set
142
- ].map((item) => {
143
- if (name === "props" || name === "listens" || name === "render") {
144
- return toTree(item.data);
145
- } else if (name === "useTask" || name === "useVisibleTask") {
146
- return toTree({
147
- [`let ${item?.variableName} =`]: findMatchVarfromScope(item)
13
+ createStore() {
14
+ const store = {};
15
+ for (const hookType of HOOK_TYPES) {
16
+ store[hookType] = {
17
+ set: /* @__PURE__ */ new Set(),
18
+ visible: !HIDDEN_HOOKS.includes(hookType)
19
+ };
20
+ }
21
+ return store;
22
+ }
23
+ // ==========================================================================
24
+ // Data Management
25
+ // ==========================================================================
26
+ /**
27
+ * Add data to the store for a specific hook type
28
+ */
29
+ add(type, data) {
30
+ this.store[type].set.add(data);
31
+ }
32
+ /**
33
+ * Clear all stored hook data
34
+ */
35
+ clear() {
36
+ for (const entry of Object.values(this.store)) {
37
+ entry.set.clear();
38
+ }
39
+ }
40
+ /**
41
+ * Reset the entire store
42
+ */
43
+ reset() {
44
+ this.store = this.createStore();
45
+ }
46
+ /**
47
+ * Get entries for a specific hook type
48
+ */
49
+ getEntries(type) {
50
+ return [
51
+ ...this.store[type].set
52
+ ];
53
+ }
54
+ /**
55
+ * Check if a hook type has entries
56
+ */
57
+ hasEntries(type) {
58
+ return this.store[type].set.size > 0;
59
+ }
60
+ // ==========================================================================
61
+ // Visibility Management
62
+ // ==========================================================================
63
+ /**
64
+ * Set visibility for a hook type
65
+ */
66
+ setVisibility(type, visible) {
67
+ this.store[type].visible = visible;
68
+ }
69
+ /**
70
+ * Check if a hook type is visible
71
+ */
72
+ isVisible(type) {
73
+ return this.store[type].visible;
74
+ }
75
+ /**
76
+ * Get filter list for UI
77
+ */
78
+ getFilterList() {
79
+ return HOOK_TYPES.filter((type) => this.hasEntries(type) && this.isVisible(type)).map((key) => ({
80
+ key,
81
+ display: this.store[key].visible
82
+ }));
83
+ }
84
+ // ==========================================================================
85
+ // Tree Building
86
+ // ==========================================================================
87
+ /**
88
+ * Build tree nodes from all stored hook data
89
+ */
90
+ buildTree() {
91
+ const result = [];
92
+ for (const hookType of HOOK_TYPES) {
93
+ if (!this.hasEntries(hookType) || !this.isVisible(hookType)) continue;
94
+ const nodes = this.transformEntries(hookType);
95
+ if (nodes.length > 0) {
96
+ result.push(this.treeBuilder.createGroupNode(hookType, nodes));
97
+ }
98
+ }
99
+ return result;
100
+ }
101
+ transformEntries(hookType) {
102
+ const entries = this.getEntries(hookType);
103
+ return entries.map((entry) => this.transformEntry(hookType, entry)).flat();
104
+ }
105
+ transformEntry(hookType, entry) {
106
+ const typedEntry = entry;
107
+ switch (hookType) {
108
+ case "props":
109
+ case "listens":
110
+ case "render":
111
+ return this.treeBuilder.objectToTree(typedEntry.data);
112
+ case "useTask":
113
+ case "useVisibleTask": {
114
+ const scopeVars = this.findScopeVariables(typedEntry);
115
+ return this.treeBuilder.objectToTree({
116
+ [`let ${typedEntry.variableName ?? hookType} =`]: scopeVars
148
117
  });
149
- } else if (name === "customhook") {
150
- return toTree({
151
- [`let ${item?.variableName} = Scope `]: item.data[CAPTURE_REF_KEY]
118
+ }
119
+ case "customhook": {
120
+ const captureRef = typedEntry.data?.[CAPTURE_REF_KEY];
121
+ return this.treeBuilder.objectToTree({
122
+ [`let ${typedEntry.variableName ?? "customhook"} = Scope `]: captureRef
152
123
  });
153
- } else {
154
- return toTree({
155
- [`let ${item?.variableName} =`]: item.data
124
+ }
125
+ default:
126
+ return this.treeBuilder.objectToTree({
127
+ [`let ${typedEntry.variableName ?? hookType} =`]: typedEntry.data
156
128
  });
129
+ }
130
+ }
131
+ findScopeVariables(item) {
132
+ const targets = item.data?.[CAPTURE_REF_KEY];
133
+ if (!targets) return "Scope []";
134
+ const variableNames = [];
135
+ for (const entry of Object.values(this.store)) {
136
+ for (const storedEntry of entry.set) {
137
+ const entryData = storedEntry;
138
+ const data = entryData?.data ?? entryData;
139
+ if (!data) continue;
140
+ const match = targets.find((target) => target === data);
141
+ if (match && entryData.variableName) {
142
+ variableNames.push(entryData.variableName);
143
+ }
157
144
  }
158
- }).flat();
159
- if (display === false) return null;
160
- return arr.length > 0 ? createTreeNodeObj(name, arr) : null;
161
- }).filter(Boolean);
162
- }
163
- function findMatchVarfromScope(item) {
164
- const targets = item?.data[CAPTURE_REF_KEY];
165
- const variableName = [];
166
- if (!targets) return [];
167
- for (const { set } of Object.values(qSeqs)) {
168
- for (const entry of set) {
169
- const data = entry?.data ?? entry;
170
- if (!data) continue;
171
- const varName = targets.find((target) => target === data);
172
- varName && variableName.push(entry?.variableName);
173
145
  }
146
+ return `Scope [${variableNames.join(", ")}]`;
174
147
  }
175
- return `Scope [${variableName.join(", ")}]`;
176
- }
177
- function buildTree() {
178
- return getData();
179
- }
180
- function clearAll() {
181
- for (const key of Object.keys(qSeqs)) {
182
- qSeqs[key].set.clear();
148
+ // ==========================================================================
149
+ // QRL Path Utilities
150
+ // ==========================================================================
151
+ /**
152
+ * Find all QRL paths for code lookup
153
+ */
154
+ findAllQrlPaths() {
155
+ const paths = [];
156
+ for (const hookType of QRL_HOOKS) {
157
+ const entries = this.getEntries(hookType);
158
+ for (const entry of entries) {
159
+ const extracted = this.extractQrlPath(hookType, entry);
160
+ if (extracted) {
161
+ if (Array.isArray(extracted)) {
162
+ paths.push(...extracted.filter(Boolean));
163
+ } else {
164
+ paths.push(extracted);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ log("findAllQrlPaths return: %O", paths);
170
+ return paths.filter(Boolean);
183
171
  }
184
- }
185
- function getHookFilterList() {
186
- return Object.keys(qSeqs).filter((usename) => qSeqs[usename].set.size > 0 && qSeqs[usename].display).map((key) => ({
187
- key,
188
- display: qSeqs[key].display
189
- }));
190
- }
191
- function getRawDataObj() {
192
- const result = {};
193
- for (const [name, { set }] of Object.entries(qSeqs)) {
194
- result[name] = [
195
- ...set
196
- ];
172
+ extractQrlPath(hookType, entry) {
173
+ if (hookType === "listens") {
174
+ const data2 = entry.data ?? entry;
175
+ return Object.values(data2).map((v) => v?.$chunk$).filter((v) => typeof v === "string");
176
+ }
177
+ if (hookType === "render") {
178
+ const renderFn = entry.data?.render ?? entry;
179
+ return QrlUtils.getPath(renderFn);
180
+ }
181
+ const data = entry.data ?? entry;
182
+ const qrlObj = data[QRL_KEY] ?? data[COMPUTED_QRL_KEY];
183
+ return QrlUtils.getPath(qrlObj);
197
184
  }
198
- return result;
199
185
  }
200
- function findAllQrl() {
201
- const list = [
202
- "useTask",
203
- "useVisibleTask",
204
- "useComputed",
205
- "useAsyncComputed",
206
- "useServerData",
207
- "useSerializer",
208
- "render",
209
- "listens"
210
- ];
211
- const rawData = getRawDataObj();
212
- const result = list.map((item) => {
213
- return rawData[item].map((entry) => {
214
- if (item === "listens") {
215
- return Object.values(entry.data || entry).map((v) => v?.[CHUNK_KEY]);
216
- } else if (item === "render") {
217
- return getQrlPath(entry.data.render || entry);
218
- } else {
219
- const qrlObj = (entry.data || entry)[QRL_KEY] || (entry.data || entry)[COMPUTED_QRL_KEY];
220
- return getQrlPath(qrlObj);
221
- }
222
- });
223
- });
224
- console.log("findAllQrl", result.flat(2).filter(Boolean));
225
- return result.flat(2).filter(Boolean);
226
- }
227
- function getQrlPath(qrl) {
228
- if (qrl?.dev) {
229
- return qrl?.dev.filename;
186
+ class QrlUtils {
187
+ /**
188
+ * Get the file path from a QRL object.
189
+ * In dev mode, uses dev.file; in production, uses $chunk$.
190
+ */
191
+ static getPath(qrl) {
192
+ if (!qrl) return null;
193
+ if (qrl.dev) return qrl.dev.file;
194
+ return qrl.$chunk$;
195
+ }
196
+ /**
197
+ * Get the chunk name from a QRL for component identification
198
+ */
199
+ static getChunkName(qrl) {
200
+ const splitPoint = "_component";
201
+ const chunk = qrl.$chunk$;
202
+ return chunk?.split(splitPoint)?.[0] ?? "";
203
+ }
204
+ /**
205
+ * Normalize raw qseq data with parsed structure metadata
206
+ */
207
+ static normalizeData(qseq, parsed) {
208
+ return qseq.map((item, index) => ({
209
+ data: item,
210
+ ...parsed[index]
211
+ }));
230
212
  }
231
- return qrl?.[CHUNK_KEY];
232
213
  }
233
- function getQrlChunkName(qrl) {
234
- const splitPoint = "_component";
235
- return qrl?.[CHUNK_KEY]?.split(splitPoint)?.[0];
214
+ const hookStore = new HookStore();
215
+ function getHookStore() {
216
+ return hookStore;
236
217
  }
237
218
  export {
238
- buildTree,
239
- clearAll,
240
- findAllQrl,
241
- findMatchVarfromScope,
242
- formatData,
243
- getData,
244
- getHookFilterList,
245
- getQrlChunkName,
246
- getQrlPath
219
+ HookStore,
220
+ QrlUtils,
221
+ getHookStore
247
222
  };
@@ -0,0 +1,50 @@
1
+ const HOOK_TYPES = [
2
+ // Variable declaration hooks
3
+ "useStore",
4
+ "useSignal",
5
+ "useContext",
6
+ "useId",
7
+ "useStyles",
8
+ "useStylesScoped",
9
+ "useConstant",
10
+ "useComputed",
11
+ "useAsyncComputed",
12
+ "useErrorBoundary",
13
+ "useServerData",
14
+ "useSerializer",
15
+ "useLocation",
16
+ "useNavigate",
17
+ "useContent",
18
+ "useDocumentHead",
19
+ // Expression statement hooks
20
+ "useTask",
21
+ "useVisibleTask",
22
+ "useResource",
23
+ "useContextProvider",
24
+ "usePreventNavigate",
25
+ // Special types
26
+ "props",
27
+ "listens",
28
+ "render",
29
+ "customhook"
30
+ ];
31
+ const HIDDEN_HOOKS = [
32
+ "useResource",
33
+ "usePreventNavigate",
34
+ "render"
35
+ ];
36
+ const QRL_HOOKS = [
37
+ "useTask",
38
+ "useVisibleTask",
39
+ "useComputed",
40
+ "useAsyncComputed",
41
+ "useServerData",
42
+ "useSerializer",
43
+ "render",
44
+ "listens"
45
+ ];
46
+ export {
47
+ HIDDEN_HOOKS,
48
+ HOOK_TYPES,
49
+ QRL_HOOKS
50
+ };
@@ -2,10 +2,10 @@ import { jsxs, jsx } from "@qwik.dev/core/jsx-runtime";
2
2
  import { component$ } from "@qwik.dev/core";
3
3
  const Routes = component$(({ state }) => {
4
4
  return /* @__PURE__ */ jsxs("div", {
5
- class: "flex-1 overflow-hidden rounded-xl border border-border",
5
+ class: "border-border flex-1 overflow-hidden rounded-xl border",
6
6
  children: [
7
7
  /* @__PURE__ */ jsxs("div", {
8
- class: "grid grid-cols-4 gap-4 bg-card-item-bg p-4 text-sm font-medium",
8
+ class: "bg-card-item-bg grid grid-cols-4 gap-4 p-4 text-sm font-medium",
9
9
  children: [
10
10
  /* @__PURE__ */ jsx("div", {
11
11
  children: "Route Path"
@@ -25,7 +25,7 @@ const Routes = component$(({ state }) => {
25
25
  const children = route.children || [];
26
26
  const layout = route.relativePath !== "" && route.type === "directory" && children.find((child) => child.name.startsWith("layout"));
27
27
  return /* @__PURE__ */ jsxs("div", {
28
- class: "grid grid-cols-4 gap-4 border-t border-border p-4 text-sm hover:bg-card-item-hover-bg",
28
+ class: "border-border hover:bg-card-item-hover-bg grid grid-cols-4 gap-4 border-t p-4 text-sm",
29
29
  children: [
30
30
  /* @__PURE__ */ jsx("div", {
31
31
  children: /* @__PURE__ */ jsx("span", {
@@ -3,7 +3,7 @@ import { component$ } from "@qwik.dev/core";
3
3
  import { inspectorLink } from "./constant.qwik.mjs";
4
4
  const Inspect = component$(() => {
5
5
  return /* @__PURE__ */ jsx("div", {
6
- class: "flex-1 overflow-hidden",
6
+ class: "h-full flex-1 overflow-hidden",
7
7
  children: /* @__PURE__ */ jsx("iframe", {
8
8
  src: `${location.href}${inspectorLink}`,
9
9
  width: "100%",