@qwik.dev/devtools 0.2.6 → 0.2.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/ui/bundle-graph-C-01xqq_.json +1 -0
- package/dist/ui/components/DevtoolsButton/DevtoolsButton.qwik.mjs +10 -12
- package/dist/ui/components/DevtoolsPanel/DevtoolsPanel.qwik.mjs +2 -2
- package/dist/ui/components/Tab/Tab.qwik.mjs +3 -5
- package/dist/ui/components/TabContent/TabContent.qwik.mjs +4 -1
- package/dist/ui/components/TabTitle/TabTitle.qwik.mjs +1 -1
- package/dist/ui/components/Tree/Tree.qwik.mjs +31 -23
- package/dist/ui/components/Tree/filterVnode.qwik.mjs +5 -4
- package/dist/ui/devtools.qwik.mjs +10 -10
- package/dist/ui/features/Assets/Assets.qwik.mjs +2 -2
- package/dist/ui/features/CodeBreack/CodeBreack.qwik.mjs +1 -1
- package/dist/ui/features/CodeBreack/HtmlParser.qwik.mjs +3 -3
- package/dist/ui/features/CodeBreack/StateParser.qwik.mjs +3 -3
- package/dist/ui/features/Packages/components/DependencyCard/DependencyCard.qwik.mjs +1 -1
- package/dist/ui/features/Performance/Performance.qwik.mjs +73 -50
- package/dist/ui/features/Performance/computePerfViewModel.qwik.mjs +53 -37
- package/dist/ui/features/RenderTree/RenderTree.qwik.mjs +16 -20
- package/dist/ui/features/RenderTree/formatTreeData.qwik.mjs +13 -13
- package/dist/ui/features/inspect/Inspect.qwik.mjs +14 -3
- package/dist/ui/features/inspect/iframe-theme.qwik.mjs +66 -0
- package/dist/ui/lib-types/ui/src/components/Tree/Tree.d.ts +5 -12
- package/dist/ui/lib-types/ui/src/components/Tree/filterVnode.d.ts +1 -1
- package/dist/ui/lib-types/ui/src/components/Tree/type.d.ts +19 -1
- package/dist/ui/lib-types/ui/src/components/Tree/vnode.d.ts +1 -1
- package/dist/ui/lib-types/ui/src/features/RenderTree/TreeBuilder.d.ts +1 -1
- package/dist/ui/lib-types/ui/src/features/RenderTree/formatTreeData.d.ts +5 -7
- package/dist/ui/lib-types/ui/src/features/RenderTree/types.d.ts +7 -3
- package/dist/ui/lib-types/ui/src/features/inspect/iframe-theme.d.ts +2 -0
- package/dist/ui/lib-types/ui/src/utils/type.d.ts +4 -1
- package/dist/ui/q-manifest.json +54 -45
- package/dist/ui/styles.css +326 -273
- package/package.json +2 -2
- package/dist/ui/bundle-graph-D9X2wpYX.json +0 -1
|
@@ -2,18 +2,68 @@ import { computeEventRows, computePerfViewModel } from "./computePerfViewModel.q
|
|
|
2
2
|
import { _captures, _fnSignal, _jsxSorted, _wrapProp, componentQrl, inlinedQrl, isBrowser, useComputedQrl, useSignal, useTaskQrl } from "@qwik.dev/core";
|
|
3
3
|
import { Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
4
4
|
//#region src/features/Performance/Performance.tsx
|
|
5
|
-
var _hf0 = (p0) => p0
|
|
6
|
-
var _hf1 = (p0) => p0.
|
|
7
|
-
var _hf2 = (p0) => p0.
|
|
8
|
-
var _hf3 = (p0) =>
|
|
9
|
-
var _hf4 = (p0) => p0.
|
|
10
|
-
var _hf5 = (p0) => p0.
|
|
5
|
+
var _hf0 = (p0) => p0?.componentName || "-";
|
|
6
|
+
var _hf1 = (p0) => typeof p0.ssr?.ssrCount === "number" ? p0.ssr.ssrCount : "-";
|
|
7
|
+
var _hf2 = (p0) => p0.row.eventName;
|
|
8
|
+
var _hf3 = (p0) => p0.row.calls;
|
|
9
|
+
var _hf4 = (p0) => p0.component.componentName;
|
|
10
|
+
var _hf5 = (p0) => p0.component.calls;
|
|
11
|
+
var _hf6 = (p0) => p0.value.overview;
|
|
12
|
+
var _hf7 = (p0) => p0.value.components.length;
|
|
13
|
+
var _hf8 = (p0, p1) => p1.value === p0.componentName;
|
|
11
14
|
function formatMs(ms) {
|
|
12
15
|
if (!Number.isFinite(ms)) return "-";
|
|
13
16
|
if (ms >= 1e3) return `${(ms / 1e3).toFixed(2)}s`;
|
|
14
17
|
if (ms >= 10) return `${ms.toFixed(0)}ms`;
|
|
15
18
|
return `${ms.toFixed(2)}ms`;
|
|
16
19
|
}
|
|
20
|
+
/** Single stat card shown in the overview row. */ var StatCard = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg hover:bg-card-item-hover-bg flex items-center gap-4 rounded-xl border p-5 transition-all duration-200" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex-1" }, [
|
|
21
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-xs font-medium" }, _wrapProp(props, "label"), 1, null),
|
|
22
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "mt-1 text-3xl font-semibold" }, _wrapProp(props), 1, null),
|
|
23
|
+
props.subtitle && /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground mt-1 text-xs" }, _wrapProp(props, "subtitle"), 1, "qe_0")
|
|
24
|
+
], 1, null), 1, "qe_1"), "StatCard_component_mWodOf0kFyU"));
|
|
25
|
+
/** Top overview row of four stat cards. */ var PerformanceOverview = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
|
|
26
|
+
const { overview } = props;
|
|
27
|
+
const slowest = overview.slowestComponent;
|
|
28
|
+
return /* @__PURE__ */ _jsxSorted("div", null, { class: "grid grid-cols-1 gap-5 md:grid-cols-4" }, [
|
|
29
|
+
/* @__PURE__ */ _jsxSorted(StatCard, { value: formatMs(overview.totalRenderTime) }, { label: "TOTAL RENDER TIME" }, null, 3, "qe_2"),
|
|
30
|
+
/* @__PURE__ */ _jsxSorted(StatCard, { subtitle: slowest ? `${formatMs(slowest.avgTime)} avg` : "-" }, {
|
|
31
|
+
label: "SLOWEST COMPONENT",
|
|
32
|
+
value: _fnSignal(_hf0, [slowest])
|
|
33
|
+
}, null, 3, "qe_3"),
|
|
34
|
+
/* @__PURE__ */ _jsxSorted(StatCard, { value: formatMs(overview.avgTime) }, { label: "AVG TIME" }, null, 3, "qe_4"),
|
|
35
|
+
/* @__PURE__ */ _jsxSorted(StatCard, { value: String(overview.totalCalls) }, { label: "TOTAL CALLS" }, null, 3, "qe_5")
|
|
36
|
+
], 1, "qe_6");
|
|
37
|
+
}, "PerformanceOverview_component_PccfcJbBcQM"));
|
|
38
|
+
/** A single component card in the left-hand list. */ var ComponentCard = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
|
|
39
|
+
const { component: c, selected } = props;
|
|
40
|
+
return /* @__PURE__ */ _jsxSorted("button", {
|
|
41
|
+
class: ["border-border bg-card-item-bg hover:bg-card-item-hover-bg w-full rounded-xl border p-4 text-left transition-all duration-200 hover:-translate-y-0.5", selected ? "ring-primary-active ring-2" : ""].join(" "),
|
|
42
|
+
"q-e:click": props.onClick$
|
|
43
|
+
}, null, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex items-start justify-between gap-4" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "min-w-0 flex-1" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "truncate text-base font-semibold" }, _wrapProp(c, "componentName"), 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground mt-1 text-xs" }, ["Avg: ", formatMs(c.avgTime)], 1, null)], 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "shrink-0 text-right" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "text-primary text-lg font-semibold" }, formatMs(c.totalTime), 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-xs" }, ["SSR: ", _fnSignal(_hf1, [c])], 1, null)], 1, null)], 1, null), 0, c.componentName);
|
|
44
|
+
}, "ComponentCard_component_shbcW80ev2U"));
|
|
45
|
+
/** Single row inside the hook-details table. */ var HookRow = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => /* @__PURE__ */ _jsxSorted("div", null, { class: "grid grid-cols-3 px-3 py-2 text-sm" }, [
|
|
46
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "truncate" }, _fnSignal(_hf2, [props]), 1, null),
|
|
47
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-right" }, formatMs(props.row.time), 1, null),
|
|
48
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-right" }, _fnSignal(_hf3, [props]), 1, null)
|
|
49
|
+
], 1, "qe_7"), "HookRow_component_rMs9Cl7A50U"));
|
|
50
|
+
/** Right-hand panel showing hook-level details for a selected component. */ var HookDetailsPanel = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl((props) => {
|
|
51
|
+
const rows = computeEventRows(props.component.csrItems);
|
|
52
|
+
return /* @__PURE__ */ _jsxSorted(Fragment, null, null, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-glass-border flex items-center justify-between border-b p-4" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "min-w-0" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "truncate text-base font-semibold" }, [_fnSignal(_hf4, [props]), " Hook Details"], 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground mt-1 text-xs" }, [
|
|
53
|
+
"Total: ",
|
|
54
|
+
formatMs(props.component.totalTime),
|
|
55
|
+
" • ",
|
|
56
|
+
_fnSignal(_hf5, [props]),
|
|
57
|
+
" calls"
|
|
58
|
+
], 1, null)], 1, null), /* @__PURE__ */ _jsxSorted("button", { "q-e:click": props.onClose$ }, {
|
|
59
|
+
"aria-label": "close",
|
|
60
|
+
class: "text-muted-foreground hover:text-foreground rounded p-2 transition-colors"
|
|
61
|
+
}, "✕", 2, null)], 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "min-h-0 flex-1 overflow-y-auto p-4" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg rounded-lg border" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border grid grid-cols-3 border-b px-3 py-2 text-xs font-medium" }, [
|
|
62
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground" }, "HOOK NAME", 3, null),
|
|
63
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-right" }, "TIME", 3, null),
|
|
64
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-right" }, "CALLS", 3, null)
|
|
65
|
+
], 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "divide-y divide-glass-border" }, [rows.map((row) => /* @__PURE__ */ _jsxSorted(HookRow, { row }, null, null, 3, row.eventName)), rows.length === 0 && /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground px-3 py-4 text-center text-sm" }, "No CSR records for this component.", 3, "qe_8")], 1, null)], 1, null), 1, null)], 1, "qe_9");
|
|
66
|
+
}, "HookDetailsPanel_component_SLSFgmtRaew"));
|
|
17
67
|
var Performance = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() => {
|
|
18
68
|
const perf = useSignal(null);
|
|
19
69
|
const selectedComponent = useSignal(null);
|
|
@@ -33,7 +83,7 @@ var Performance = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() =>
|
|
|
33
83
|
const selectedComponent = _captures[0], vm = _captures[1];
|
|
34
84
|
const name = selectedComponent.value;
|
|
35
85
|
if (!name) return null;
|
|
36
|
-
return vm.value.components.find((c) => c.componentName === name)
|
|
86
|
+
return vm.value.components.find((c) => c.componentName === name) ?? null;
|
|
37
87
|
}, "Performance_component_selectedVm_useComputed_nZ4k4WZsvQ0", [selectedComponent, vm]));
|
|
38
88
|
const onSelect = /* @__PURE__ */ inlinedQrl((name) => {
|
|
39
89
|
const selectedComponent = _captures[0];
|
|
@@ -43,53 +93,26 @@ var Performance = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() =>
|
|
|
43
93
|
const selectedComponent = _captures[0];
|
|
44
94
|
selectedComponent.value = null;
|
|
45
95
|
}, "Performance_component_clearSelect_DiCJxQzE8DE", [selectedComponent]);
|
|
46
|
-
return /* @__PURE__ */ _jsxSorted("div", null, { class: "h-full w-full flex-1 overflow-hidden" },
|
|
47
|
-
|
|
48
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg hover:bg-card-item-hover-bg flex items-center gap-4 rounded-xl border p-5 transition-all duration-200" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex-1" }, [
|
|
49
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-xs font-medium" }, "SLOWEST COMPONENT", 3, null),
|
|
50
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "mt-1 text-lg font-semibold" }, _fnSignal(_hf0, [vm]), 3, null),
|
|
51
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground mt-1 text-xs" }, vm.value.overview.slowestComponent ? `${formatMs(vm.value.overview.slowestComponent.avgTime)} avg` : "-", 1, null)
|
|
52
|
-
], 1, null), 1, null),
|
|
53
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg hover:bg-card-item-hover-bg flex items-center gap-4 rounded-xl border p-5 transition-all duration-200" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex-1" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-xs font-medium" }, "AVG TIME", 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-1 text-3xl font-semibold" }, formatMs(vm.value.overview.avgTime), 1, null)], 1, null), 1, null),
|
|
54
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg hover:bg-card-item-hover-bg flex items-center gap-4 rounded-xl border p-5 transition-all duration-200" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex-1" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-xs font-medium" }, "TOTAL CALLS", 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-1 text-3xl font-semibold" }, _fnSignal(_hf1, [vm]), 3, null)], 3, null), 3, null)
|
|
55
|
-
], 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-background flex min-h-0 flex-1 overflow-hidden rounded-md border" }, [
|
|
96
|
+
if (!(perf.value?.ssr?.length || perf.value?.csr?.length)) return /* @__PURE__ */ _jsxSorted("div", null, { class: "h-full w-full flex-1 overflow-hidden" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg flex h-full items-center justify-center rounded-xl border p-8" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-center text-sm" }, ["No performance data found.", /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-1 text-xs" }, "Ensure instrumentation is enabled and interact with the app, then reopen this tab.", 3, null)], 3, null), 3, null), 3, "qe_10");
|
|
97
|
+
return /* @__PURE__ */ _jsxSorted("div", null, { class: "h-full w-full flex-1 overflow-hidden" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full min-h-0 flex-col gap-4" }, [/* @__PURE__ */ _jsxSorted(PerformanceOverview, null, { overview: _fnSignal(_hf6, [vm]) }, null, 3, "qe_11"), /* @__PURE__ */ _jsxSorted("div", null, { class: "border-glass-border flex min-h-0 flex-1 overflow-hidden rounded-2xl border bg-card-item-bg" }, [
|
|
56
98
|
/* @__PURE__ */ _jsxSorted("div", null, { class: "min-h-0 flex-1 overflow-y-auto p-4" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "mb-3 flex items-center justify-between" }, /* @__PURE__ */ _jsxSorted("div", null, null, [/* @__PURE__ */ _jsxSorted("div", null, { class: "text-lg font-semibold" }, "Components", 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-xs" }, [
|
|
57
99
|
"CSR only • ",
|
|
58
|
-
_fnSignal(
|
|
100
|
+
_fnSignal(_hf7, [vm]),
|
|
59
101
|
" total"
|
|
60
|
-
], 3, null)], 3, null), 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "grid grid-cols-1 gap-4 md:grid-cols-2" }, vm.value.components.map((c) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
102
|
+
], 3, null)], 3, null), 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "grid grid-cols-1 gap-4 md:grid-cols-2" }, vm.value.components.map((c) => /* @__PURE__ */ _jsxSorted(ComponentCard, {
|
|
103
|
+
component: c,
|
|
104
|
+
onClick$: /* @__PURE__ */ inlinedQrl(() => {
|
|
105
|
+
const c = _captures[0], onSelect = _captures[1];
|
|
64
106
|
return onSelect(c.componentName);
|
|
65
|
-
}, "
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "
|
|
73
|
-
|
|
74
|
-
"Total: ",
|
|
75
|
-
formatMs(selectedVm.value.totalTime),
|
|
76
|
-
" • ",
|
|
77
|
-
_fnSignal(_hf5, [selectedVm]),
|
|
78
|
-
" calls"
|
|
79
|
-
], 1, null)], 1, null), /* @__PURE__ */ _jsxSorted("button", null, {
|
|
80
|
-
"aria-label": "close",
|
|
81
|
-
"q-e:click": clearSelect,
|
|
82
|
-
class: "text-muted-foreground hover:text-foreground rounded p-2 transition-colors"
|
|
83
|
-
}, "✕", 3, null)], 1, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "min-h-0 flex-1 overflow-y-auto p-4" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg rounded-lg border" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border grid grid-cols-3 border-b px-3 py-2 text-xs font-medium" }, [
|
|
84
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground" }, "HOOK NAME", 3, null),
|
|
85
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-right" }, "TIME", 3, null),
|
|
86
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-right" }, "CALLS", 3, null)
|
|
87
|
-
], 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "divide-border divide-y" }, [computeEventRows(selectedVm.value.csrItems).map((row) => /* @__PURE__ */ _jsxSorted("div", null, { class: "grid grid-cols-3 px-3 py-2 text-sm" }, [
|
|
88
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "truncate" }, _wrapProp(row, "eventName"), 1, null),
|
|
89
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-right" }, formatMs(row.time), 1, null),
|
|
90
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "text-right" }, _wrapProp(row, "calls"), 1, null)
|
|
91
|
-
], 1, row.eventName)), !selectedVm.value.csrItems.length && /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground px-3 py-4 text-center text-sm" }, "No CSR records for this component.", 3, "qe_1")], 1, null)], 1, null), 1, null)], 1, "qe_2") : /* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full items-center justify-center p-8" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-center text-sm" }, "Select a component to view hook details.", 3, null), 3, "qe_3"), 1, null)
|
|
92
|
-
], 1, null)], 1, "qe_4"), 1, "qe_5");
|
|
107
|
+
}, "Performance_component_div_div_div_div_div_ComponentCard_onClick_Wdj23rRG0YU", [c, onSelect]),
|
|
108
|
+
selected: _fnSignal(_hf8, [c, selectedComponent])
|
|
109
|
+
}, null, null, 2, c.componentName)), 1, null)], 1, null),
|
|
110
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "border-l border-glass-border" }, null, 3, null),
|
|
111
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "flex w-[420px] min-w-[320px] flex-col overflow-hidden" }, selectedVm.value ? /* @__PURE__ */ _jsxSorted(HookDetailsPanel, null, {
|
|
112
|
+
component: _wrapProp(selectedVm),
|
|
113
|
+
onClose$: clearSelect
|
|
114
|
+
}, null, 3, "qe_12") : /* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full items-center justify-center p-8" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground text-center text-sm" }, "Select a component to view hook details.", 3, null), 3, "qe_13"), 1, null)
|
|
115
|
+
], 1, null)], 1, null), 1, "qe_14");
|
|
93
116
|
}, "Performance_component_7v0oxuZ12AM"));
|
|
94
117
|
//#endregion
|
|
95
118
|
export { Performance };
|
|
@@ -38,33 +38,40 @@ function computeComponentVmFromCsr(componentName, csrItems, ssr) {
|
|
|
38
38
|
csrItems
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
function
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
components.push(computeComponentVmFromCsr(componentName, csrItems, ssrItem));
|
|
53
|
-
}
|
|
54
|
-
} else if (safe.csr?.length) {
|
|
55
|
-
const byName = /* @__PURE__ */ new Map();
|
|
56
|
-
for (const csrItem of safe.csr) {
|
|
57
|
-
const parsed = parseComponentAndEventName(csrItem.component);
|
|
58
|
-
const list = byName.get(parsed.componentName) || [];
|
|
59
|
-
list.push({
|
|
60
|
-
...csrItem,
|
|
61
|
-
...parsed
|
|
62
|
-
});
|
|
63
|
-
byName.set(parsed.componentName, list);
|
|
64
|
-
}
|
|
65
|
-
for (const [componentName, csrItems] of byName.entries()) components.push(computeComponentVmFromCsr(componentName, csrItems));
|
|
41
|
+
/** Build component view-models when SSR entries are available. */ function groupComponentsBySsr(safe) {
|
|
42
|
+
const grouped = groupCsrBySsr(safe);
|
|
43
|
+
const result = [];
|
|
44
|
+
for (const raw of safe.ssr) {
|
|
45
|
+
const ssrItem = {
|
|
46
|
+
...raw,
|
|
47
|
+
phase: "ssr"
|
|
48
|
+
};
|
|
49
|
+
const componentName = parseComponentAndEventName(ssrItem.component).componentName;
|
|
50
|
+
const csrItems = grouped.get(raw) || [];
|
|
51
|
+
result.push(computeComponentVmFromCsr(componentName, csrItems, ssrItem));
|
|
66
52
|
}
|
|
67
|
-
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/** Build component view-models from CSR-only data, grouped by component name. */ function groupComponentsByName(csrRaw) {
|
|
56
|
+
const byName = /* @__PURE__ */ new Map();
|
|
57
|
+
for (const entry of csrRaw) {
|
|
58
|
+
const csrItem = {
|
|
59
|
+
...entry,
|
|
60
|
+
phase: "csr"
|
|
61
|
+
};
|
|
62
|
+
const parsed = parseComponentAndEventName(csrItem.component);
|
|
63
|
+
const list = byName.get(parsed.componentName) || [];
|
|
64
|
+
list.push({
|
|
65
|
+
...csrItem,
|
|
66
|
+
...parsed
|
|
67
|
+
});
|
|
68
|
+
byName.set(parsed.componentName, list);
|
|
69
|
+
}
|
|
70
|
+
const result = [];
|
|
71
|
+
for (const [componentName, csrItems] of byName.entries()) result.push(computeComponentVmFromCsr(componentName, csrItems));
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
function computeOverview(components) {
|
|
68
75
|
let totalRenderTime = 0;
|
|
69
76
|
let totalCalls = 0;
|
|
70
77
|
for (const c of components) {
|
|
@@ -77,17 +84,26 @@ function computePerfViewModel(perf) {
|
|
|
77
84
|
return cur.avgTime > acc.avgTime ? cur : acc;
|
|
78
85
|
}, void 0);
|
|
79
86
|
return {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
totalRenderTime,
|
|
88
|
+
totalCalls,
|
|
89
|
+
avgTime,
|
|
90
|
+
slowestComponent: slowest ? {
|
|
91
|
+
componentName: slowest.componentName,
|
|
92
|
+
avgTime: slowest.avgTime,
|
|
93
|
+
totalTime: slowest.totalTime,
|
|
94
|
+
calls: slowest.calls
|
|
95
|
+
} : void 0
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function computePerfViewModel(perf) {
|
|
99
|
+
const safe = perf || {
|
|
100
|
+
ssr: [],
|
|
101
|
+
csr: []
|
|
102
|
+
};
|
|
103
|
+
const components = safe.ssr?.length ? groupComponentsBySsr(safe) : safe.csr?.length ? groupComponentsByName(safe.csr) : [];
|
|
104
|
+
components.sort((a, b) => b.totalTime - a.totalTime);
|
|
105
|
+
return {
|
|
106
|
+
overview: computeOverview(components),
|
|
91
107
|
components
|
|
92
108
|
};
|
|
93
109
|
}
|
|
@@ -18,8 +18,8 @@ import { Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
|
18
18
|
import { unwrapStore } from "@qwik.dev/core/internal";
|
|
19
19
|
//#region src/features/RenderTree/RenderTree.tsx
|
|
20
20
|
var import_browser = /* @__PURE__ */ __toESM(require_browser(), 1);
|
|
21
|
-
var _hf0 = (p0) => p0.value === "state" ? {
|
|
22
|
-
var _hf1 = (p0) => p0.value === "code" ? {
|
|
21
|
+
var _hf0 = (p0) => p0.value === "state" ? { boxShadow: "inset 0 -2px 0 0 var(--color-primary)" } : {};
|
|
22
|
+
var _hf1 = (p0) => p0.value === "code" ? { boxShadow: "inset 0 -2px 0 0 var(--color-primary)" } : {};
|
|
23
23
|
var _hf2 = (p0) => `h-4 w-4 transition-transform duration-200 ${p0.value ? "rotate-180" : "-rotate-90"}`;
|
|
24
24
|
var _hf3 = (p0) => ({
|
|
25
25
|
maxHeight: p0.value ? "800px" : "0px",
|
|
@@ -115,30 +115,26 @@ var RenderTree = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() => {
|
|
|
115
115
|
stateTree
|
|
116
116
|
]);
|
|
117
117
|
const currentTab = useSignal("state");
|
|
118
|
-
return /* @__PURE__ */ _jsxSorted("div", null, { class: "
|
|
118
|
+
return /* @__PURE__ */ _jsxSorted("div", null, { class: "h-full w-full flex-1 overflow-hidden rounded-2xl border border-glass-border bg-card-item-bg" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full w-full" }, [
|
|
119
119
|
/* @__PURE__ */ _jsxSorted("div", null, {
|
|
120
|
-
class: "w-1/2 overflow-hidden p-
|
|
121
|
-
style: { minWidth: "
|
|
120
|
+
class: "w-1/2 overflow-hidden p-3 custom-scrollbar",
|
|
121
|
+
style: { minWidth: "360px" }
|
|
122
122
|
}, /* @__PURE__ */ _jsxSorted(Tree, null, {
|
|
123
123
|
data,
|
|
124
124
|
onNodeClick
|
|
125
125
|
}, null, 3, "N0_0"), 1, null),
|
|
126
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "border-
|
|
126
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "border-l border-glass-border" }, null, 3, null),
|
|
127
127
|
/* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full min-h-0 w-1/2 flex-col overflow-hidden p-4" }, [
|
|
128
|
-
/* @__PURE__ */ _jsxSorted("div", null, { class: "
|
|
128
|
+
/* @__PURE__ */ _jsxSorted("div", null, { class: "" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-b border-glass-border flex space-x-2 pb-1" }, [/* @__PURE__ */ _jsxSorted("button", {
|
|
129
|
+
class: ["px-4 py-2.5 text-sm font-medium rounded-lg transition-all duration-200", currentTab.value === "state" ? "text-primary bg-primary/10" : "text-muted-foreground hover:text-foreground hover:bg-foreground/5"],
|
|
129
130
|
"q-e:click": /* @__PURE__ */ inlinedQrl((_, _1, currentTab) => currentTab.value = "state", "RenderTree_component_div_div_div_div_div_button_q_e_click_0BjFkeQoET0"),
|
|
130
131
|
"q:p": currentTab
|
|
131
|
-
}, {
|
|
132
|
-
|
|
133
|
-
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"
|
|
134
|
-
}, "State", 6, null), /* @__PURE__ */ _jsxSorted("button", {
|
|
132
|
+
}, { style: _fnSignal(_hf0, [currentTab]) }, "State", 6, null), /* @__PURE__ */ _jsxSorted("button", {
|
|
133
|
+
class: ["px-4 py-2.5 text-sm font-medium rounded-lg transition-all duration-200", currentTab.value === "code" ? "text-primary bg-primary/10" : "text-muted-foreground hover:text-foreground hover:bg-foreground/5"],
|
|
135
134
|
"q-e:click": /* @__PURE__ */ inlinedQrl((_, _1, currentTab) => currentTab.value = "code", "RenderTree_component_div_div_div_div_div_button_q_e_click_1_39v2rkQNmhc"),
|
|
136
135
|
"q:p": currentTab
|
|
137
|
-
}, {
|
|
138
|
-
|
|
139
|
-
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"
|
|
140
|
-
}, "Code", 6, null)], 1, null), 1, null),
|
|
141
|
-
currentTab.value === "state" && /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-5 flex min-h-0 flex-1 flex-col" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg rounded-lg border shadow-sm" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-border flex items-center justify-between border-b px-2 py-2" }, [/* @__PURE__ */ _jsxSorted("span", null, { class: "text-muted-foreground text-xs font-medium" }, "Hooks", 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "flex items-center space-x-2" }, [
|
|
136
|
+
}, { style: _fnSignal(_hf1, [currentTab]) }, "Code", 6, null)], 1, null), 1, null),
|
|
137
|
+
currentTab.value === "state" && /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-5 flex min-h-0 flex-1 flex-col" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "rounded-xl border border-glass-border bg-card-item-bg" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-b border-glass-border flex items-center justify-between px-2 py-2" }, [/* @__PURE__ */ _jsxSorted("span", null, { class: "text-muted-foreground text-xs font-medium" }, "Hooks", 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "flex items-center space-x-2" }, [
|
|
142
138
|
/* @__PURE__ */ _jsxSorted("button", { "q-e:click": /* @__PURE__ */ inlinedQrl(() => {
|
|
143
139
|
const hookFilters = _captures[0], hookStore = _captures[1], stateTree = _captures[2];
|
|
144
140
|
hookFilters.value = hookFilters.value.map((item) => {
|
|
@@ -184,12 +180,12 @@ var RenderTree = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() => {
|
|
|
184
180
|
hookStore,
|
|
185
181
|
stateTree
|
|
186
182
|
]);
|
|
187
|
-
return /* @__PURE__ */ _jsxSorted("label", null, { class: "flex items-center" }, [/* @__PURE__ */ _jsxSorted("input", {
|
|
183
|
+
return /* @__PURE__ */ _jsxSorted("label", null, { class: "flex items-center gap-2 cursor-pointer" }, [/* @__PURE__ */ _jsxSorted("input", {
|
|
188
184
|
checked: _wrapProp(item, "display"),
|
|
189
185
|
"q-e:change": qrl_4294901769,
|
|
190
186
|
"q:p": idx
|
|
191
187
|
}, {
|
|
192
|
-
class: "
|
|
188
|
+
class: "h-4 w-4 rounded focus:ring-0 cursor-pointer",
|
|
193
189
|
style: { accentColor: "var(--color-primary-active)" },
|
|
194
190
|
type: "checkbox"
|
|
195
191
|
}, null, 6, null), /* @__PURE__ */ _jsxSorted("span", null, { class: "ml-2 select-none" }, _wrapProp(item, "key"), 1, null)], 1, idx);
|
|
@@ -215,10 +211,10 @@ var RenderTree = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() => {
|
|
|
215
211
|
animationDuration: 200,
|
|
216
212
|
isHover: true
|
|
217
213
|
}, null, 3, "N0_5"), 1, null)], 1, "N0_6"),
|
|
218
|
-
currentTab.value === "code" && /* @__PURE__ */ _jsxSorted("div", null, { class: "
|
|
214
|
+
currentTab.value === "code" && /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-4 min-h-0 flex-1 overflow-y-auto rounded-xl border border-glass-border bg-card-item-bg p-2" }, /* @__PURE__ */ _jsxSorted(Resource, null, {
|
|
219
215
|
value: highlightedCodesResource,
|
|
220
216
|
onPending: () => /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground p-2 text-sm" }, "Loading code highlights…", 3, "N0_7"),
|
|
221
|
-
onResolved: (highlighted) => /* @__PURE__ */ _jsxSorted(Fragment, null, null, codes.value.map((item, idx) => /* @__PURE__ */ _jsxSorted(Fragment, null, null, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border bg-card-item-bg hover:bg-card-item-hover-bg mb-4 rounded-xl border p-4
|
|
217
|
+
onResolved: (highlighted) => /* @__PURE__ */ _jsxSorted(Fragment, null, null, codes.value.map((item, idx) => /* @__PURE__ */ _jsxSorted(Fragment, null, null, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-glass-border bg-card-item-bg hover:bg-card-item-hover-bg mb-4 rounded-xl border p-4 transition-colors" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "text-primary mb-2 break-all text-base font-semibold" }, _wrapProp(item, "pathId"), 1, null), /* @__PURE__ */ _jsxSorted("pre", { dangerouslySetInnerHTML: _fnSignal(_hf4, [highlighted, idx]) }, { class: "overflow-hidden" }, null, 3, null)], 1, null), 1, "N0_8")), 1, "N0_9")
|
|
222
218
|
}, null, 3, "N0_10"), 1, "N0_11")
|
|
223
219
|
], 1, null)
|
|
224
220
|
], 1, null), 1, "N0_12");
|
|
@@ -103,21 +103,22 @@ var log = (0, (/* @__PURE__ */ __toESM(require_browser(), 1)).default)("qwik:dev
|
|
|
103
103
|
return this.getEntries(hookType).map((entry) => this.transformEntry(hookType, entry)).flat();
|
|
104
104
|
}
|
|
105
105
|
transformEntry(hookType, entry) {
|
|
106
|
-
const
|
|
106
|
+
const variableName = "hookType" in entry ? entry.variableName : void 0;
|
|
107
|
+
const data = entry.data;
|
|
107
108
|
switch (hookType) {
|
|
108
109
|
case "props":
|
|
109
110
|
case "listens":
|
|
110
|
-
case "render": return this.treeBuilder.objectToTree(
|
|
111
|
+
case "render": return this.treeBuilder.objectToTree(data);
|
|
111
112
|
case "useTask":
|
|
112
113
|
case "useVisibleTask": {
|
|
113
|
-
const scopeVars = this.findScopeVariables(
|
|
114
|
-
return this.treeBuilder.objectToTree({ [`let ${
|
|
114
|
+
const scopeVars = this.findScopeVariables(entry);
|
|
115
|
+
return this.treeBuilder.objectToTree({ [`let ${variableName ?? hookType} =`]: scopeVars });
|
|
115
116
|
}
|
|
116
117
|
case "customhook": {
|
|
117
|
-
const captureRef =
|
|
118
|
-
return this.treeBuilder.objectToTree({ [`let ${
|
|
118
|
+
const captureRef = data?.[CAPTURE_REF_KEY];
|
|
119
|
+
return this.treeBuilder.objectToTree({ [`let ${variableName ?? "customhook"} = Scope `]: captureRef });
|
|
119
120
|
}
|
|
120
|
-
default: return this.treeBuilder.objectToTree({ [`let ${
|
|
121
|
+
default: return this.treeBuilder.objectToTree({ [`let ${variableName ?? hookType} =`]: data });
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
findScopeVariables(item) {
|
|
@@ -125,10 +126,9 @@ var log = (0, (/* @__PURE__ */ __toESM(require_browser(), 1)).default)("qwik:dev
|
|
|
125
126
|
if (!targets) return "Scope []";
|
|
126
127
|
const variableNames = [];
|
|
127
128
|
for (const entry of Object.values(this.store)) for (const storedEntry of entry.set) {
|
|
128
|
-
const
|
|
129
|
-
const data = entryData?.data ?? entryData;
|
|
129
|
+
const data = storedEntry.data;
|
|
130
130
|
if (!data) continue;
|
|
131
|
-
if (targets.find((target) => target === data) &&
|
|
131
|
+
if (targets.find((target) => target === data) && "variableName" in storedEntry && storedEntry.variableName) variableNames.push(storedEntry.variableName);
|
|
132
132
|
}
|
|
133
133
|
return `Scope [${variableNames.join(", ")}]`;
|
|
134
134
|
}
|
|
@@ -149,14 +149,14 @@ var log = (0, (/* @__PURE__ */ __toESM(require_browser(), 1)).default)("qwik:dev
|
|
|
149
149
|
}
|
|
150
150
|
extractQrlPath(hookType, entry) {
|
|
151
151
|
if (hookType === "listens") {
|
|
152
|
-
const data = entry.data
|
|
152
|
+
const data = entry.data;
|
|
153
153
|
return Object.values(data).map((v) => v?.$chunk$).filter((v) => typeof v === "string");
|
|
154
154
|
}
|
|
155
155
|
if (hookType === "render") {
|
|
156
|
-
const renderFn = entry.data?.render ?? entry;
|
|
156
|
+
const renderFn = entry.data?.render ?? entry.data;
|
|
157
157
|
return QrlUtils.getPath(renderFn);
|
|
158
158
|
}
|
|
159
|
-
const data = entry.data
|
|
159
|
+
const data = entry.data;
|
|
160
160
|
const qrlObj = data["$qrl$"] ?? data["$computeQrl$"];
|
|
161
161
|
return QrlUtils.getPath(qrlObj);
|
|
162
162
|
}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { inspectorLink } from "./constant.qwik.mjs";
|
|
2
|
+
import { setupIframeThemeSync } from "./iframe-theme.qwik.mjs";
|
|
2
3
|
import { _jsxSorted, componentQrl, inlinedQrl } from "@qwik.dev/core";
|
|
3
4
|
//#region src/features/inspect/Inspect.tsx
|
|
4
5
|
var Inspect = /* @__PURE__ */ componentQrl(/* @__PURE__ */ inlinedQrl(() => {
|
|
5
|
-
return /* @__PURE__ */ _jsxSorted("div", null, { class: "h-full flex-1 overflow-hidden" }, /* @__PURE__ */ _jsxSorted("iframe", {
|
|
6
|
+
return /* @__PURE__ */ _jsxSorted("div", null, { class: "h-full w-full flex-1 overflow-hidden rounded-2xl border border-glass-border bg-card-item-bg" }, /* @__PURE__ */ _jsxSorted("iframe", {
|
|
7
|
+
"q-e:load": /* @__PURE__ */ inlinedQrl((_, el) => {
|
|
8
|
+
try {
|
|
9
|
+
setupIframeThemeSync(el);
|
|
10
|
+
} catch (err) {
|
|
11
|
+
console.error("Failed to inject theme into inspect iframe:", err);
|
|
12
|
+
}
|
|
13
|
+
}, "Inspect_component_div_iframe_q_e_load_dBYi9MiDVFM"),
|
|
14
|
+
src: `${location.href}${inspectorLink}`
|
|
15
|
+
}, {
|
|
6
16
|
width: "100%",
|
|
7
17
|
height: "100%",
|
|
8
|
-
id: "inspect_qwik"
|
|
9
|
-
|
|
18
|
+
id: "inspect_qwik",
|
|
19
|
+
class: "rounded-xl w-full h-full"
|
|
20
|
+
}, null, 2, null), 1, "o0_0");
|
|
10
21
|
}, "Inspect_component_hp0adRBjF9Q"));
|
|
11
22
|
//#endregion
|
|
12
23
|
export { Inspect };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/features/inspect/iframe-theme.ts
|
|
2
|
+
var STYLE_ID = "qwik-inspect-custom-style";
|
|
3
|
+
var GLASSMORPHISM_CSS = `
|
|
4
|
+
:root {
|
|
5
|
+
--c-bg-base: transparent !important;
|
|
6
|
+
--c-bg-nav: transparent !important;
|
|
7
|
+
--c-bg-active: transparent !important;
|
|
8
|
+
--iframe-border: rgba(0, 0, 0, 0.1) !important;
|
|
9
|
+
--iframe-hover: rgba(0, 0, 0, 0.04) !important;
|
|
10
|
+
color-scheme: light;
|
|
11
|
+
}
|
|
12
|
+
html.dark {
|
|
13
|
+
--c-bg-base: transparent !important;
|
|
14
|
+
--c-bg-nav: transparent !important;
|
|
15
|
+
--c-bg-active: transparent !important;
|
|
16
|
+
--iframe-border: rgba(255, 255, 255, 0.08) !important;
|
|
17
|
+
--iframe-hover: rgba(255, 255, 255, 0.06) !important;
|
|
18
|
+
color-scheme: dark;
|
|
19
|
+
}
|
|
20
|
+
/* 仅针对主视图容器做透明处理,不再暴力让所有 div/section 变透明 */
|
|
21
|
+
html, body, #app, main, header, nav, footer { background-color: transparent !important; }
|
|
22
|
+
.bg-active, .hover\\\\:bg-active:hover, tr:hover, li:hover,
|
|
23
|
+
.hover\\\\:bg-gray-400\\\\/10:hover, a:hover { background-color: var(--iframe-hover) !important; }
|
|
24
|
+
input, button, select, [role="button"] { background-color: var(--iframe-hover) !important; }
|
|
25
|
+
.border-base, [class*="border-b"], [class*="border-r"],
|
|
26
|
+
[class*="border-t"], [class*="border-l"], .border { border-color: var(--iframe-border) !important; }
|
|
27
|
+
html.dark { color: #fafafa !important; }
|
|
28
|
+
html, body, #app { overflow-x: hidden !important; max-width: 100vw !important; }
|
|
29
|
+
`;
|
|
30
|
+
/** 在 iframe onLoad 中调用,同步父主题 + 注入透明背景样式 */ function setupIframeThemeSync(iframe) {
|
|
31
|
+
const doc = iframe.contentDocument;
|
|
32
|
+
const win = iframe.contentWindow;
|
|
33
|
+
if (!doc || !win) return;
|
|
34
|
+
const syncTheme = () => {
|
|
35
|
+
const dark = document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark";
|
|
36
|
+
win.localStorage.setItem("vueuse-color-scheme", dark ? "dark" : "light");
|
|
37
|
+
if (dark) doc.documentElement.classList.add("dark");
|
|
38
|
+
else doc.documentElement.classList.remove("dark");
|
|
39
|
+
};
|
|
40
|
+
const ensureStyle = () => {
|
|
41
|
+
if (!doc.getElementById(STYLE_ID)) {
|
|
42
|
+
const s = doc.createElement("style");
|
|
43
|
+
s.id = STYLE_ID;
|
|
44
|
+
s.textContent = GLASSMORPHISM_CSS;
|
|
45
|
+
doc.head.appendChild(s);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
syncTheme();
|
|
49
|
+
ensureStyle();
|
|
50
|
+
const themeObs = new MutationObserver(syncTheme);
|
|
51
|
+
themeObs.observe(document.documentElement, {
|
|
52
|
+
attributes: true,
|
|
53
|
+
attributeFilter: ["class", "data-theme"]
|
|
54
|
+
});
|
|
55
|
+
const styleObs = new MutationObserver(ensureStyle);
|
|
56
|
+
styleObs.observe(doc.body || doc.documentElement, {
|
|
57
|
+
childList: true,
|
|
58
|
+
subtree: true
|
|
59
|
+
});
|
|
60
|
+
doc.defaultView?.addEventListener("unload", () => {
|
|
61
|
+
themeObs.disconnect();
|
|
62
|
+
styleObs.disconnect();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//#endregion
|
|
66
|
+
export { setupIframeThemeSync };
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import { QRL } from '@qwik.dev/core';
|
|
1
|
+
import { type QRL } from '@qwik.dev/core';
|
|
2
2
|
import type { JSXOutput, Signal } from '@qwik.dev/core';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
props?: Record<string, any>;
|
|
6
|
-
children?: TreeNode[];
|
|
7
|
-
elementType?: string;
|
|
8
|
-
label?: string;
|
|
9
|
-
isHover?: boolean;
|
|
10
|
-
id: string;
|
|
11
|
-
}
|
|
12
|
-
export declare const Tree: import("@qwik.dev/core").Component<{
|
|
3
|
+
import type { TreeNode } from './type';
|
|
4
|
+
export interface TreeProps {
|
|
13
5
|
data: Signal<TreeNode[]>;
|
|
14
6
|
onNodeClick?: QRL<(node: TreeNode) => void>;
|
|
15
7
|
renderNode?: QRL<(node: TreeNode) => JSXOutput>;
|
|
@@ -18,4 +10,5 @@ export declare const Tree: import("@qwik.dev/core").Component<{
|
|
|
18
10
|
animate?: boolean;
|
|
19
11
|
animationDuration?: number;
|
|
20
12
|
expandLevel?: number;
|
|
21
|
-
}
|
|
13
|
+
}
|
|
14
|
+
export declare const Tree: import("@qwik.dev/core").Component<TreeProps>;
|
|
@@ -1,3 +1,21 @@
|
|
|
1
1
|
export declare const ISDEVTOOL = "Qwikdevtools";
|
|
2
2
|
export declare const QContainerAttr = "q:container";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* A value stored inside a Qwik reactive store proxy.
|
|
5
|
+
* We intentionally keep a narrow union so that `Record<string | symbol, StoreValue>`
|
|
6
|
+
* is assignable without falling back to `any`.
|
|
7
|
+
*/
|
|
8
|
+
export type StoreValue = string | number | boolean | null | undefined | object;
|
|
9
|
+
export type StoreTarget = Record<string | symbol, StoreValue>;
|
|
10
|
+
/** Value types that a Qwik VNode prop can hold. */
|
|
11
|
+
export type TreeNodePropValue = string | number | boolean | null | undefined | object;
|
|
12
|
+
export type ElementType = 'null' | 'boolean' | 'number' | 'string' | 'function' | 'array' | 'object';
|
|
13
|
+
export interface TreeNode {
|
|
14
|
+
name?: string;
|
|
15
|
+
props?: Record<string, TreeNodePropValue>;
|
|
16
|
+
children?: TreeNode[];
|
|
17
|
+
elementType?: ElementType;
|
|
18
|
+
label?: string;
|
|
19
|
+
isHover?: boolean;
|
|
20
|
+
id: string;
|
|
21
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { TreeNode } from '../../components/Tree/
|
|
1
|
+
import type { TreeNode } from '../../components/Tree/type';
|
|
2
2
|
import type { ParsedStructure } from '@devtools/kit';
|
|
3
|
-
import { type HookType, type HookFilterItem, type QRLInternal } from './types';
|
|
3
|
+
import { type HookType, type HookFilterItem, type QRLInternal, type HookDataEntry } from './types';
|
|
4
4
|
/**
|
|
5
5
|
* Manages hook data storage and tree building for the devtools.
|
|
6
6
|
*/
|
|
@@ -12,9 +12,7 @@ export declare class HookStore {
|
|
|
12
12
|
/**
|
|
13
13
|
* Add data to the store for a specific hook type
|
|
14
14
|
*/
|
|
15
|
-
add(type: HookType, data:
|
|
16
|
-
data: Record<string, unknown>;
|
|
17
|
-
}): void;
|
|
15
|
+
add(type: HookType, data: HookDataEntry): void;
|
|
18
16
|
/**
|
|
19
17
|
* Clear all stored hook data
|
|
20
18
|
*/
|
|
@@ -26,7 +24,7 @@ export declare class HookStore {
|
|
|
26
24
|
/**
|
|
27
25
|
* Get entries for a specific hook type
|
|
28
26
|
*/
|
|
29
|
-
getEntries(type: HookType):
|
|
27
|
+
getEntries(type: HookType): HookDataEntry[];
|
|
30
28
|
/**
|
|
31
29
|
* Check if a hook type has entries
|
|
32
30
|
*/
|
|
@@ -49,7 +47,7 @@ export declare class HookStore {
|
|
|
49
47
|
buildTree(): TreeNode[];
|
|
50
48
|
private transformEntries;
|
|
51
49
|
private transformEntry;
|
|
52
|
-
findScopeVariables(item:
|
|
50
|
+
findScopeVariables(item: HookDataEntry): string;
|
|
53
51
|
/**
|
|
54
52
|
* Find all QRL paths for code lookup
|
|
55
53
|
*/
|