vite-plugin-aipanel 1.2.27 → 1.3.1

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.
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Vue DevTools 时间线采集器(页面侧,供 agent 调试)。
3
+ *
4
+ * 为什么自己实现存储:devtools-kit 的 timeline 事件只转发给已连接的 DevTools 客户端,不落盘
5
+ * (没有 clientConnected 时事件即发即弃),且内置层受 recordingState/highPerfModeEnabled 门控。
6
+ * 本模块直接订阅 `__VUE_DEVTOOLS_GLOBAL_HOOK__` 的原始 Vue 事件(实测不受上述两个门控影响),
7
+ * 在页面内存里维护一个有界环形缓冲,供 `vue-devtools_get_timeline` 按窗口查询。
8
+ *
9
+ * 采集约定:
10
+ * - 常驻采集(无 start/stop 状态):`clear()` 等价于"从现在开始录",`mark()` 只插边界不清历史;
11
+ * - 捕获期就把数据降级为 primitive(绝不持有 app/vm/instance 引用),生命周期事件只累计计数;
12
+ * - 所有 hook 回调都包在 try/catch 里:devtools hook 的 emit 是同步遍历,回调抛错会影响页面渲染。
13
+ */
14
+ import { type VueDevtoolsTimelineInclude, type VueDevtoolsTimelineLayer } from "@aipanel/core";
15
+ /**
16
+ * 原始 devtools hook 的事件名(唯一来源)。
17
+ * @vue/devtools-kit 的 DevToolsHooks 枚举只有 d.ts 声明、运行时未导出(import 值为 undefined),
18
+ * 故无法 import;这里集中定义一次,值对齐 @vue/devtools-kit@8.2.1 的 DevToolsHooks
19
+ * (dist/index.d.ts:718-733),升级该依赖时需同步核对(vue-devtools-timeline.test.ts 锁住配合行为)。
20
+ */
21
+ export declare const DEVTOOLS_HOOK_EVENTS: {
22
+ readonly appInit: "app:init";
23
+ readonly appUnmount: "app:unmount";
24
+ readonly componentAdded: "component:added";
25
+ readonly componentUpdated: "component:updated";
26
+ readonly componentRemoved: "component:removed";
27
+ readonly componentEmit: "component:emit";
28
+ readonly performanceStart: "perf:start";
29
+ readonly performanceEnd: "perf:end";
30
+ };
31
+ /**
32
+ * devtools hook 的监听器签名随事件而异,注册时按动态签名处理(devtools-kit 自己用的是 `Function`)。
33
+ * `never[]` 是下界:任何声明了具体参数的监听器都能注册,但取出来调用时需按事件自行收窄。
34
+ */
35
+ export type HookListener = (...args: never[]) => void;
36
+ /**
37
+ * 原始 devtools hook 的最小结构。
38
+ * 不用 devtools-kit 的 DevToolsHook 类型:其 on() 的事件参数是未导出的枚举类型。
39
+ */
40
+ export interface TimelineHook {
41
+ on(event: string, listener: HookListener): () => void;
42
+ }
43
+ /** Vue 应用实例上与时间线相关的最小形状(避免依赖 Vue 类型) */
44
+ export interface TimelineAppLike {
45
+ _instance?: {
46
+ uid?: number;
47
+ };
48
+ /** devtools-kit 写在 app 上的记录标识;按引用比对 appRecords 会漏(实测出现 ?:uid) */
49
+ __VUE_DEVTOOLS_NEXT_APP_RECORD_ID__?: string;
50
+ __VUE_DEVTOOLS_NEXT_APP_RECORD__?: {
51
+ id?: string;
52
+ };
53
+ }
54
+ /** Vue 组件实例上与 nodeId 相关的最小形状 */
55
+ export interface TimelineInstanceLike {
56
+ uid?: number;
57
+ root?: unknown;
58
+ type?: {
59
+ name?: string;
60
+ __name?: string;
61
+ };
62
+ /** devtools-kit 写在实例上的完整 nodeId(与组件树 id 同源) */
63
+ __VUE_DEVTOOLS_NEXT_UID__?: string;
64
+ /** 挂载早期 app 上还没有记录标识时,用它兜底解析 appId */
65
+ appContext?: {
66
+ app?: TimelineAppLike;
67
+ };
68
+ }
69
+ /** vue-router 实例上与时间线相关的最小形状 */
70
+ export interface TimelineRouterLike {
71
+ afterEach: (handler: (to: unknown, from: unknown, failure?: unknown) => void) => () => void;
72
+ }
73
+ export interface TimelineAppRecord {
74
+ id: string;
75
+ app: unknown;
76
+ }
77
+ /** 时间线明细记录(t 为相对查询时刻的毫秒数,负数表示过去) */
78
+ export interface TimelineRecord {
79
+ seq: number;
80
+ t: number;
81
+ layer: VueDevtoolsTimelineLayer;
82
+ kind: string;
83
+ name: string;
84
+ dur?: number;
85
+ nodeId?: string;
86
+ file?: string;
87
+ level?: "default" | "warning" | "error";
88
+ data?: unknown;
89
+ }
90
+ /** 时间线查询参数(来自 MCP 工具入参,全部可省略) */
91
+ export interface TimelineQuery {
92
+ windowMs?: number;
93
+ sinceMark?: string;
94
+ layers?: string[];
95
+ minDurationMs?: number;
96
+ component?: string;
97
+ include?: VueDevtoolsTimelineInclude;
98
+ limit?: number;
99
+ /** 是否用最新组件树补全 file(默认开,2s 缓存) */
100
+ enrich?: boolean;
101
+ }
102
+ export interface TimelineQueryResult {
103
+ window: {
104
+ from: number;
105
+ to: number;
106
+ ms: number;
107
+ sinceMark?: string;
108
+ };
109
+ buffer: {
110
+ capacity: number;
111
+ size: number;
112
+ dropped: number;
113
+ /**
114
+ * 已丢弃记录里最新一条的时间(相对现在的 ms)。
115
+ * 用它判断"窗口内数据是否被丢弃过":只有当它落在窗口内才说明窗口不完整。
116
+ */
117
+ droppedAtMsAgo?: number;
118
+ /** 窗口起点早于被丢弃的记录 ⇒ 窗口内数据不完整(与 droppedAtMsAgo 配套,避免误报) */
119
+ windowTruncated: boolean;
120
+ /** 只有 end 没有 start 的渲染次数(耗时缺失,不等于 0ms) */
121
+ unpaired: number;
122
+ /** 因长时间没有 end 而被清掉的 start 次数(同样属于耗时缺失) */
123
+ prunedStarts: number;
124
+ marks: number;
125
+ startedAtMsAgo: number;
126
+ bootId: string;
127
+ capture: {
128
+ hook: boolean;
129
+ routers: number;
130
+ };
131
+ };
132
+ summary: Record<string, unknown>;
133
+ records: TimelineRecord[];
134
+ /** 明细被 limit / 体积上限裁剪过(阈值裁剪见 omitted.perfBelowThreshold)——摘要计数不受影响 */
135
+ truncated: boolean;
136
+ /**
137
+ * 明细是否全量:omitted 三项全为 0 才为 true。判断"有没有被裁"只看这一个字段。
138
+ * include=summary 时 records 按请求为空、本字段恒 true(按请求口径,不代表窗口内没有事件)。
139
+ */
140
+ detailComplete: boolean;
141
+ /** 明细裁剪的去向,保证"没看到的不是没发生" */
142
+ omitted: {
143
+ perfBelowThreshold: number;
144
+ byLimit: number;
145
+ byPayload: number;
146
+ };
147
+ notes: string[];
148
+ }
149
+ export interface TimelineRecorderOptions {
150
+ hook?: TimelineHook;
151
+ getAppRecords?: () => TimelineAppRecord[];
152
+ /** 组件树(用于把 nodeId 补成源码文件路径) */
153
+ getInspectorTree?: () => Promise<unknown>;
154
+ /** 由桥决定如何从 Vue 应用取 router(采集器不感知 Vue 内部结构) */
155
+ resolveRouter?: (app: unknown) => TimelineRouterLike | undefined;
156
+ now?: () => number;
157
+ capacity?: number;
158
+ }
159
+ export interface TimelineRecorder {
160
+ get(query?: TimelineQuery): Promise<TimelineQueryResult>;
161
+ mark(label: string): {
162
+ markId: string;
163
+ buffered: number;
164
+ };
165
+ clear(): {
166
+ cleared: number;
167
+ marks: number;
168
+ };
169
+ /** 为已注册的应用补订阅 router(桥注入晚于 app 挂载时的兜底;正常路径由 app:init 覆盖) */
170
+ attachRouters(): void;
171
+ dispose(): void;
172
+ }
173
+ export declare function createTimelineRecorder(options?: TimelineRecorderOptions): TimelineRecorder;