Skip to content

Commit 7d4b4f2

Browse files
authored
Merge pull request #8712 from Aejkatappaja/refactor/shared-protocol-types
refactor(devtools): single source of truth for shared protocol types
2 parents b8147cc + 0fdd84a commit 7d4b4f2

7 files changed

Lines changed: 62 additions & 66 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@qwik.dev/devtools': patch
3+
---
4+
5+
refactor(devtools): single source of truth for shared protocol types
6+
7+
The VNode tree node, component detail entry, and render event shapes were declared
8+
three times: in the browser extension, in the devtools UI, and in the kit client
9+
bridge. They now live once in @qwik.dev/devtools/kit (protocol module) as
10+
DevtoolsVNodeTreeNode, DevtoolsComponentDetailEntry, and DevtoolsRenderEvent, and
11+
every consumer imports them from there.

packages/browser-extension/src/shared/types.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import type {
2+
DevtoolsVNodeTreeNode as VNodeTreeNode,
3+
DevtoolsComponentDetailEntry as ComponentDetailEntry,
4+
DevtoolsRenderEvent as RenderEvent,
25
QwikDevtoolsComponentSnapshot,
36
QwikDevtoolsSignalsSnapshot,
47
QwikPerfStoreRemembered,
58
QwikPreloadStoreRemembered,
69
} from '@qwik.dev/devtools/kit';
710

11+
// The VNode/detail/render shapes are the shared data contract, owned by @qwik.dev/devtools/kit.
12+
// Re-export under the local names so consumers keep one import source and cannot drift.
13+
export type { VNodeTreeNode, ComponentDetailEntry, RenderEvent };
14+
815
export interface QwikContainerInfo {
916
detected: boolean;
1017
version: string | null;
@@ -16,27 +23,6 @@ export interface QwikContainerInfo {
1623
runtime: string | null;
1724
}
1825

19-
export interface VNodeTreeNode {
20-
name?: string;
21-
id: string;
22-
label?: string;
23-
props?: Record<string, unknown>;
24-
children?: VNodeTreeNode[];
25-
}
26-
27-
export interface ComponentDetailEntry {
28-
hookType: string;
29-
variableName: string;
30-
data: unknown;
31-
}
32-
33-
export interface RenderEvent {
34-
component: string;
35-
phase: string;
36-
duration: number;
37-
timestamp: number;
38-
}
39-
4026
export type ExtensionMessage =
4127
| { type: 'DETECT_QWIK' }
4228
| { type: 'QWIK_DETECTION_RESULT'; payload: QwikContainerInfo }

packages/devtools/kit/src/client-bridge.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,14 @@ import type { QwikPerfStoreRemembered, QwikPreloadStoreRemembered } from './glob
77
import { getQwikDevtoolsGlobal } from './global-store';
88
import { QWIK_DEVTOOLS_GLOBAL } from './protocol/globals';
99
import { DEVTOOLS_MESSAGES, type QwikDevtoolsPageMessage } from './protocol/messages';
10+
import type { DevtoolsVNodeTreeNode } from './protocol/vnode';
11+
import type { DevtoolsRenderEvent } from './protocol/perf';
12+
import type { DevtoolsComponentDetailEntry } from './protocol/hooks';
1013

1114
export interface InPageBridgeOptions {
1215
isBrowser: boolean;
1316
}
1417

15-
export interface DevtoolsRenderEvent {
16-
component: string;
17-
phase: string;
18-
duration: number;
19-
timestamp: number;
20-
}
21-
22-
export interface DevtoolsComponentDetailEntry {
23-
hookType: string;
24-
variableName: string;
25-
data: unknown;
26-
}
27-
28-
export interface DevtoolsVNodeTreeNode {
29-
name?: string;
30-
id: string;
31-
label?: string;
32-
props?: Record<string, unknown>;
33-
children?: DevtoolsVNodeTreeNode[];
34-
}
35-
3618
export interface InPageBridge {
3719
readPerfData(): Promise<QwikPerfStoreRemembered | null>;
3820
readPreloadStore(): Promise<QwikPreloadStoreRemembered | null>;

packages/devtools/kit/src/protocol/hooks.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ export const SIGNAL_HOOK_TYPES = [
4545
'useContext',
4646
] as const;
4747

48+
/**
49+
* A single component hook entry with deeply serialized data, returned by the devtools hook's
50+
* component detail lookup. Shared data contract: do not redeclare in consumers, import it from
51+
* here.
52+
*/
53+
export interface DevtoolsComponentDetailEntry {
54+
hookType: string;
55+
variableName: string;
56+
data: unknown;
57+
}
58+
4859
export const INNER_USE_HOOK = 'useCollectHooks';
4960
export const VIRTUAL_QWIK_DEVTOOLS_KEY = 'virtual-qwik-devtools.ts';
5061
export const QWIK_DEVTOOLS_HOOK_VERSION = 1;

packages/devtools/kit/src/protocol/perf.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,14 @@ export const PERF_PHASE_CSR = 'csr';
66
export const DEFAULT_PERF_STORE_EXPRESSION = '{ ssr: [], csr: [] }';
77

88
export type QwikDevtoolsPerfPhase = typeof PERF_PHASE_SSR | typeof PERF_PHASE_CSR;
9+
10+
/**
11+
* A single render event emitted by the performance runtime (CSR render with timing). Shared data
12+
* contract: do not redeclare in consumers, import it from here.
13+
*/
14+
export interface DevtoolsRenderEvent {
15+
component: string;
16+
phase: string;
17+
duration: number;
18+
timestamp: number;
19+
}

packages/devtools/kit/src/protocol/vnode.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,15 @@ export const QWIK_VNODE_PROTOCOL = {
1818
},
1919
bridgeVirtualModuleId: 'virtual:qwik-devtools-bridge',
2020
} as const;
21+
22+
/**
23+
* Serializable VNode tree node exchanged between the page hook and the devtools UI/extension.
24+
* Shared data contract: do not redeclare in consumers, import it from here.
25+
*/
26+
export interface DevtoolsVNodeTreeNode {
27+
name?: string;
28+
id: string;
29+
label?: string;
30+
props?: Record<string, unknown>;
31+
children?: DevtoolsVNodeTreeNode[];
32+
}

packages/devtools/ui/src/devtools/page-data-source.ts

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ import {
66
type QwikPreloadStoreRemembered,
77
type QwikDevtoolsComponentSnapshot,
88
type QwikDevtoolsSignalsSnapshot,
9+
type DevtoolsVNodeTreeNode as VNodeTreeNode,
10+
type DevtoolsComponentDetailEntry as ComponentDetailEntry,
11+
type DevtoolsRenderEvent as RenderEvent,
912
} from '@qwik.dev/devtools/kit';
1013
import { isBrowser } from '@qwik.dev/core';
1114

15+
// The VNode/detail/render shapes are the shared data contract, owned by @qwik.dev/devtools/kit.
16+
// Re-export under the local names so feature components keep one import source and cannot drift.
17+
export type { VNodeTreeNode, ComponentDetailEntry, RenderEvent };
18+
1219
/**
1320
* Abstraction for accessing page-level data from different contexts.
1421
*
@@ -78,30 +85,6 @@ export interface PageDataSource {
7885
subscribeRenderEvents(cb: (event: RenderEvent) => void): (() => void) | null;
7986
}
8087

81-
/** A single render event emitted by the performance runtime. */
82-
export interface RenderEvent {
83-
component: string;
84-
phase: string;
85-
duration: number;
86-
timestamp: number;
87-
}
88-
89-
/** A single hook entry with deeply serialized data. */
90-
export interface ComponentDetailEntry {
91-
hookType: string;
92-
variableName: string;
93-
data: unknown;
94-
}
95-
96-
/** Serializable VNode tree node (matches overlay's TreeNode shape). */
97-
export interface VNodeTreeNode {
98-
name?: string;
99-
id: string;
100-
label?: string;
101-
props?: Record<string, unknown>;
102-
children?: VNodeTreeNode[];
103-
}
104-
10588
/**
10689
* Default implementation that reads directly from `window` globals. Used when the devtools UI runs
10790
* as an in-app overlay (same document).

0 commit comments

Comments
 (0)