@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.
Files changed (33) hide show
  1. package/dist/ui/bundle-graph-C-01xqq_.json +1 -0
  2. package/dist/ui/components/DevtoolsButton/DevtoolsButton.qwik.mjs +10 -12
  3. package/dist/ui/components/DevtoolsPanel/DevtoolsPanel.qwik.mjs +2 -2
  4. package/dist/ui/components/Tab/Tab.qwik.mjs +3 -5
  5. package/dist/ui/components/TabContent/TabContent.qwik.mjs +4 -1
  6. package/dist/ui/components/TabTitle/TabTitle.qwik.mjs +1 -1
  7. package/dist/ui/components/Tree/Tree.qwik.mjs +31 -23
  8. package/dist/ui/components/Tree/filterVnode.qwik.mjs +5 -4
  9. package/dist/ui/devtools.qwik.mjs +10 -10
  10. package/dist/ui/features/Assets/Assets.qwik.mjs +2 -2
  11. package/dist/ui/features/CodeBreack/CodeBreack.qwik.mjs +1 -1
  12. package/dist/ui/features/CodeBreack/HtmlParser.qwik.mjs +3 -3
  13. package/dist/ui/features/CodeBreack/StateParser.qwik.mjs +3 -3
  14. package/dist/ui/features/Packages/components/DependencyCard/DependencyCard.qwik.mjs +1 -1
  15. package/dist/ui/features/Performance/Performance.qwik.mjs +73 -50
  16. package/dist/ui/features/Performance/computePerfViewModel.qwik.mjs +53 -37
  17. package/dist/ui/features/RenderTree/RenderTree.qwik.mjs +16 -20
  18. package/dist/ui/features/RenderTree/formatTreeData.qwik.mjs +13 -13
  19. package/dist/ui/features/inspect/Inspect.qwik.mjs +14 -3
  20. package/dist/ui/features/inspect/iframe-theme.qwik.mjs +66 -0
  21. package/dist/ui/lib-types/ui/src/components/Tree/Tree.d.ts +5 -12
  22. package/dist/ui/lib-types/ui/src/components/Tree/filterVnode.d.ts +1 -1
  23. package/dist/ui/lib-types/ui/src/components/Tree/type.d.ts +19 -1
  24. package/dist/ui/lib-types/ui/src/components/Tree/vnode.d.ts +1 -1
  25. package/dist/ui/lib-types/ui/src/features/RenderTree/TreeBuilder.d.ts +1 -1
  26. package/dist/ui/lib-types/ui/src/features/RenderTree/formatTreeData.d.ts +5 -7
  27. package/dist/ui/lib-types/ui/src/features/RenderTree/types.d.ts +7 -3
  28. package/dist/ui/lib-types/ui/src/features/inspect/iframe-theme.d.ts +2 -0
  29. package/dist/ui/lib-types/ui/src/utils/type.d.ts +4 -1
  30. package/dist/ui/q-manifest.json +54 -45
  31. package/dist/ui/styles.css +326 -273
  32. package/package.json +2 -2
  33. 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.value.overview.slowestComponent?.componentName || "-";
6
- var _hf1 = (p0) => p0.value.overview.totalCalls;
7
- var _hf2 = (p0) => p0.value.components.length;
8
- var _hf3 = (p0) => typeof p0.ssr?.ssrCount === "number" ? p0.ssr.ssrCount : "-";
9
- var _hf4 = (p0) => p0.value.componentName;
10
- var _hf5 = (p0) => p0.value.calls;
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) || null;
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" }, !perf.value?.ssr?.length && !perf.value?.csr?.length ? /* @__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, "qe_0") : /* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full min-h-0 flex-col gap-4" }, [/* @__PURE__ */ _jsxSorted("div", null, { class: "grid grid-cols-1 gap-5 md:grid-cols-4" }, [
47
- /* @__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 RENDER TIME", 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "mt-1 text-3xl font-semibold" }, formatMs(vm.value.overview.totalRenderTime), 1, null)], 1, null), 1, null),
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(_hf2, [vm]),
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
- const selected = selectedComponent.value === c.componentName;
62
- const qrl_4294901764 = /* @__PURE__ */ inlinedQrl((_, _1, c) => {
63
- const onSelect = _captures[0];
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
- }, "Performance_component_div_div_div_div_div_button_q_e_click_85W8GUPoZnc", [onSelect]);
66
- return /* @__PURE__ */ _jsxSorted("button", {
67
- 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(" "),
68
- "q-e:click": qrl_4294901764,
69
- "q:p": c
70
- }, 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(_hf3, [c])], 1, null)], 1, null)], 1, null), 4, c.componentName);
71
- }), 1, null)], 1, null),
72
- /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border border-l" }, null, 3, null),
73
- /* @__PURE__ */ _jsxSorted("div", null, { class: "flex w-[420px] min-w-[320px] flex-col overflow-hidden" }, selectedVm.value ? /* @__PURE__ */ _jsxSorted(Fragment, null, null, [/* @__PURE__ */ _jsxSorted("div", null, { class: "border-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, [selectedVm]), " Hook Details"], 3, null), /* @__PURE__ */ _jsxSorted("div", null, { class: "text-muted-foreground mt-1 text-xs" }, [
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 computePerfViewModel(perf) {
42
- const safe = perf || {
43
- ssr: [],
44
- csr: []
45
- };
46
- const components = [];
47
- if (safe.ssr?.length) {
48
- const grouped = groupCsrBySsr(safe);
49
- for (const ssrItem of safe.ssr) {
50
- const componentName = parseComponentAndEventName(ssrItem.component).componentName;
51
- const csrItems = grouped.get(ssrItem) || [];
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
- components.sort((a, b) => b.totalTime - a.totalTime);
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
- overview: {
81
- totalRenderTime,
82
- totalCalls,
83
- avgTime,
84
- slowestComponent: slowest ? {
85
- componentName: slowest.componentName,
86
- avgTime: slowest.avgTime,
87
- totalTime: slowest.totalTime,
88
- calls: slowest.calls
89
- } : void 0
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" ? { borderBottom: "2px solid var(--color-primary-active)" } : {};
22
- var _hf1 = (p0) => p0.value === "code" ? { borderBottom: "2px solid var(--color-primary-active)" } : {};
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: "border-border bg-background h-full w-full flex-1 overflow-hidden rounded-md border" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "flex h-full w-full" }, [
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-4",
121
- style: { minWidth: "400px" }
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-border border-l" }, null, 3, null),
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: "border-border border-b" }, /* @__PURE__ */ _jsxSorted("div", null, { class: "border-border flex space-x-4 border-b" }, [/* @__PURE__ */ _jsxSorted("button", {
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
- style: _fnSignal(_hf0, [currentTab]),
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
- style: _fnSignal(_hf1, [currentTab]),
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: "border-border focus:ring-primary-active h-4 w-4 rounded-full focus:ring-offset-0 dark:border-[#374151] dark:bg-[#1F2937]",
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: "border-border mt-5 min-h-0 flex-1 overflow-y-auto rounded-lg border p-2 shadow-sm" }, /* @__PURE__ */ _jsxSorted(Resource, null, {
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 shadow-sm 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")
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 typedEntry = entry;
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(typedEntry.data);
111
+ case "render": return this.treeBuilder.objectToTree(data);
111
112
  case "useTask":
112
113
  case "useVisibleTask": {
113
- const scopeVars = this.findScopeVariables(typedEntry);
114
- return this.treeBuilder.objectToTree({ [`let ${typedEntry.variableName ?? hookType} =`]: scopeVars });
114
+ const scopeVars = this.findScopeVariables(entry);
115
+ return this.treeBuilder.objectToTree({ [`let ${variableName ?? hookType} =`]: scopeVars });
115
116
  }
116
117
  case "customhook": {
117
- const captureRef = typedEntry.data?.[CAPTURE_REF_KEY];
118
- return this.treeBuilder.objectToTree({ [`let ${typedEntry.variableName ?? "customhook"} = Scope `]: captureRef });
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 ${typedEntry.variableName ?? hookType} =`]: typedEntry.data });
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 entryData = storedEntry;
129
- const data = entryData?.data ?? entryData;
129
+ const data = storedEntry.data;
130
130
  if (!data) continue;
131
- if (targets.find((target) => target === data) && entryData.variableName) variableNames.push(entryData.variableName);
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 ?? entry;
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 ?? entry;
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", { src: `${location.href}${inspectorLink}` }, {
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
- }, null, 3, null), 1, "o0_0");
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
- export interface TreeNode {
4
- name?: string | 'text';
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,3 @@
1
1
  import { _VNode } from '@qwik.dev/core/internal';
2
- import { TreeNode } from './Tree';
2
+ import { TreeNode } from './type';
3
3
  export declare function vnode_toObject(vnodeItem: _VNode | null): TreeNode[] | null;
@@ -1,3 +1,21 @@
1
1
  export declare const ISDEVTOOL = "Qwikdevtools";
2
2
  export declare const QContainerAttr = "q:container";
3
- export type StoreTarget = Record<string | symbol, any>;
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,3 +1,3 @@
1
- import { TreeNode } from './Tree';
1
+ import { TreeNode } from './type';
2
2
  export declare function normalizeName(str: string): string;
3
3
  export declare function removeNodeFromTree(tree: TreeNode[], callback: (node: TreeNode) => boolean): TreeNode[];
@@ -1,4 +1,4 @@
1
- import type { TreeNode } from '../../components/Tree/Tree';
1
+ import type { TreeNode } from '../../components/Tree/type';
2
2
  /**
3
3
  * Builder class for creating TreeNode structures from objects.
4
4
  * Handles all types of data transformation to tree format.
@@ -1,6 +1,6 @@
1
- import type { TreeNode } from '../../components/Tree/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: ParsedStructure | {
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): unknown[];
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: Record<string, unknown>): string;
50
+ findScopeVariables(item: HookDataEntry): string;
53
51
  /**
54
52
  * Find all QRL paths for code lookup
55
53
  */