@lytjs/devtools 4.2.0 → 6.0.0
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/index.cjs +1700 -564
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +743 -0
- package/dist/index.d.ts +743 -0
- package/dist/index.mjs +1613 -564
- package/dist/index.mjs.map +1 -0
- package/package.json +41 -26
- package/README.md +0 -153
- package/dist/types/batch-analyzer.d.ts +0 -150
- package/dist/types/batch-analyzer.d.ts.map +0 -1
- package/dist/types/component-profiler.d.ts +0 -144
- package/dist/types/component-profiler.d.ts.map +0 -1
- package/dist/types/component-tree.d.ts +0 -69
- package/dist/types/component-tree.d.ts.map +0 -1
- package/dist/types/event-panel.d.ts +0 -129
- package/dist/types/event-panel.d.ts.map +0 -1
- package/dist/types/event-tracker.d.ts +0 -80
- package/dist/types/event-tracker.d.ts.map +0 -1
- package/dist/types/hooks.d.ts +0 -177
- package/dist/types/hooks.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -185
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/memory-tracker.d.ts +0 -148
- package/dist/types/memory-tracker.d.ts.map +0 -1
- package/dist/types/panel.d.ts +0 -182
- package/dist/types/panel.d.ts.map +0 -1
- package/dist/types/perf-collector.d.ts +0 -328
- package/dist/types/perf-collector.d.ts.map +0 -1
- package/dist/types/perf-panel.d.ts +0 -231
- package/dist/types/perf-panel.d.ts.map +0 -1
- package/dist/types/render-tracker.d.ts +0 -147
- package/dist/types/render-tracker.d.ts.map +0 -1
- package/dist/types/route-panel.d.ts +0 -68
- package/dist/types/route-panel.d.ts.map +0 -1
- package/dist/types/router-panel-enhanced.d.ts +0 -118
- package/dist/types/router-panel-enhanced.d.ts.map +0 -1
- package/dist/types/state-inspector.d.ts +0 -80
- package/dist/types/state-inspector.d.ts.map +0 -1
- package/dist/types/time-travel.d.ts +0 -189
- package/dist/types/time-travel.d.ts.map +0 -1
- package/dist/types/virtual-tree.d.ts +0 -168
- package/dist/types/virtual-tree.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,619 +1,1755 @@
|
|
|
1
|
-
|
|
2
|
-
/* === Lyt DevTools \u9762\u677F\u57FA\u7840\u6837\u5F0F === */
|
|
3
|
-
.lyt-devtools-panel {
|
|
4
|
-
position: fixed;
|
|
5
|
-
z-index: 999999;
|
|
6
|
-
background: #1e1e2e;
|
|
7
|
-
border: 1px solid #313244;
|
|
8
|
-
border-radius: 8px;
|
|
9
|
-
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
|
|
10
|
-
font-family: 'SF Mono', 'Monaco', 'Menlo', 'Consolas', monospace;
|
|
11
|
-
font-size: 12px;
|
|
12
|
-
color: #cdd6f4;
|
|
13
|
-
display: flex;
|
|
14
|
-
flex-direction: column;
|
|
15
|
-
overflow: hidden;
|
|
16
|
-
user-select: none;
|
|
17
|
-
transition: opacity 0.2s ease;
|
|
18
|
-
}
|
|
1
|
+
'use strict';
|
|
19
2
|
|
|
20
|
-
|
|
21
|
-
.lyt-devtools-header {
|
|
22
|
-
display: flex;
|
|
23
|
-
align-items: center;
|
|
24
|
-
justify-content: space-between;
|
|
25
|
-
padding: 0 12px;
|
|
26
|
-
height: 36px;
|
|
27
|
-
min-height: 36px;
|
|
28
|
-
background: #181825;
|
|
29
|
-
border-bottom: 1px solid #313244;
|
|
30
|
-
cursor: move;
|
|
31
|
-
border-radius: 8px 8px 0 0;
|
|
32
|
-
}
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
33
4
|
|
|
34
|
-
|
|
35
|
-
font-size: 13px;
|
|
36
|
-
font-weight: 600;
|
|
37
|
-
color: #cba6f7;
|
|
38
|
-
display: flex;
|
|
39
|
-
align-items: center;
|
|
40
|
-
gap: 6px;
|
|
41
|
-
}
|
|
5
|
+
var commonIs = require('@lytjs/common-is');
|
|
42
6
|
|
|
43
|
-
.
|
|
44
|
-
|
|
7
|
+
// src/componentTree.ts
|
|
8
|
+
var componentIdCounter = 0;
|
|
9
|
+
function generateComponentId() {
|
|
10
|
+
return `component-${++componentIdCounter}`;
|
|
45
11
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
12
|
+
function extractComponentInfo(component) {
|
|
13
|
+
if (!component) return null;
|
|
14
|
+
const id = generateComponentId();
|
|
15
|
+
const name = component.name || component.displayName || "Anonymous";
|
|
16
|
+
const props = {};
|
|
17
|
+
if (component.props && commonIs.isObject(component.props)) {
|
|
18
|
+
for (const [key, value] of Object.entries(component.props)) {
|
|
19
|
+
if (typeof value !== "function") {
|
|
20
|
+
props[key] = value;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
id,
|
|
26
|
+
name,
|
|
27
|
+
props: Object.keys(props).length > 0 ? props : void 0
|
|
28
|
+
};
|
|
51
29
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
30
|
+
function buildComponentTreeRecursive(component, parentId) {
|
|
31
|
+
const node = extractComponentInfo(component);
|
|
32
|
+
if (!node) return null;
|
|
33
|
+
if (parentId) {
|
|
34
|
+
node.parent = parentId;
|
|
35
|
+
}
|
|
36
|
+
if (component.children && Array.isArray(component.children)) {
|
|
37
|
+
const children = [];
|
|
38
|
+
for (const child of component.children) {
|
|
39
|
+
const childNode = buildComponentTreeRecursive(child, node.id);
|
|
40
|
+
if (childNode) {
|
|
41
|
+
children.push(childNode);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (children.length > 0) {
|
|
45
|
+
node.children = children;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return node;
|
|
68
49
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
50
|
+
function getComponentTree(rootComponent) {
|
|
51
|
+
if (!rootComponent) {
|
|
52
|
+
const globalRoot = globalThis.__LYTJS_ROOT__;
|
|
53
|
+
if (!globalRoot) {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
rootComponent = globalRoot;
|
|
57
|
+
}
|
|
58
|
+
const tree = buildComponentTreeRecursive(rootComponent);
|
|
59
|
+
return tree ? [tree] : [];
|
|
74
60
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
function serializeComponentTree(nodes, indent = 0) {
|
|
62
|
+
let result = "";
|
|
63
|
+
const prefix = " ".repeat(indent);
|
|
64
|
+
for (const node of nodes) {
|
|
65
|
+
result += `${prefix}- ${node.name}`;
|
|
66
|
+
if (node.props && Object.keys(node.props).length > 0) {
|
|
67
|
+
const propsStr = Object.entries(node.props).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(", ");
|
|
68
|
+
result += ` (${propsStr})`;
|
|
69
|
+
}
|
|
70
|
+
result += "\n";
|
|
71
|
+
if (node.children && node.children.length > 0) {
|
|
72
|
+
result += serializeComponentTree(node.children, indent + 1);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
80
76
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
.lyt-devtools-tabs {
|
|
84
|
-
display: flex;
|
|
85
|
-
background: #181825;
|
|
86
|
-
border-bottom: 1px solid #313244;
|
|
87
|
-
padding: 0 8px;
|
|
88
|
-
min-height: 32px;
|
|
77
|
+
function registerRootComponent(component) {
|
|
78
|
+
globalThis.__LYTJS_ROOT__ = component;
|
|
89
79
|
}
|
|
90
|
-
|
|
91
|
-
.
|
|
92
|
-
padding: 6px 12px;
|
|
93
|
-
cursor: pointer;
|
|
94
|
-
color: #a6adc8;
|
|
95
|
-
border-bottom: 2px solid transparent;
|
|
96
|
-
transition: all 0.15s ease;
|
|
97
|
-
font-size: 12px;
|
|
98
|
-
display: flex;
|
|
99
|
-
align-items: center;
|
|
100
|
-
gap: 4px;
|
|
101
|
-
white-space: nowrap;
|
|
80
|
+
function unregisterRootComponent() {
|
|
81
|
+
delete globalThis.__LYTJS_ROOT__;
|
|
102
82
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
83
|
+
var storeRegistry = /* @__PURE__ */ new Map();
|
|
84
|
+
var subscribers = /* @__PURE__ */ new Map();
|
|
85
|
+
var globalChangeCallbacks = /* @__PURE__ */ new Set();
|
|
86
|
+
function registerStore(id, store) {
|
|
87
|
+
storeRegistry.set(id, store);
|
|
107
88
|
}
|
|
108
|
-
|
|
109
|
-
.
|
|
110
|
-
color: #cba6f7;
|
|
111
|
-
border-bottom-color: #cba6f7;
|
|
89
|
+
function unregisterStore(id) {
|
|
90
|
+
storeRegistry.delete(id);
|
|
112
91
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
92
|
+
function getStoreStates() {
|
|
93
|
+
const states = [];
|
|
94
|
+
for (const [id, store] of storeRegistry.entries()) {
|
|
95
|
+
const stateInfo = {
|
|
96
|
+
id,
|
|
97
|
+
state: {}
|
|
98
|
+
};
|
|
99
|
+
if (store.$state) {
|
|
100
|
+
stateInfo.state = deepClone(store.$state);
|
|
101
|
+
} else if (commonIs.isObject(store)) {
|
|
102
|
+
for (const [key, value] of Object.entries(store)) {
|
|
103
|
+
if (!key.startsWith("$") && !commonIs.isFunction(value)) {
|
|
104
|
+
stateInfo.state[key] = deepClone(value);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (store.$id) {
|
|
109
|
+
stateInfo.id = store.$id;
|
|
110
|
+
}
|
|
111
|
+
states.push(stateInfo);
|
|
112
|
+
}
|
|
113
|
+
return states;
|
|
116
114
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
function getStoreState(storeId) {
|
|
116
|
+
const store = storeRegistry.get(storeId);
|
|
117
|
+
if (!store) return null;
|
|
118
|
+
const stateInfo = {
|
|
119
|
+
id: storeId,
|
|
120
|
+
state: {}
|
|
121
|
+
};
|
|
122
|
+
if (store.$state) {
|
|
123
|
+
stateInfo.state = deepClone(store.$state);
|
|
124
|
+
} else if (commonIs.isObject(store)) {
|
|
125
|
+
for (const [key, value] of Object.entries(store)) {
|
|
126
|
+
if (!key.startsWith("$") && !commonIs.isFunction(value)) {
|
|
127
|
+
stateInfo.state[key] = deepClone(value);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return stateInfo;
|
|
124
132
|
}
|
|
125
|
-
|
|
126
|
-
.
|
|
127
|
-
|
|
128
|
-
|
|
133
|
+
function setStoreState(storeId, path, value) {
|
|
134
|
+
const store = storeRegistry.get(storeId);
|
|
135
|
+
if (!store) return false;
|
|
136
|
+
const keys = path.split(".");
|
|
137
|
+
let current = store.$state || store;
|
|
138
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
139
|
+
const key = keys[i];
|
|
140
|
+
if (!commonIs.isObject(current[key])) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
current = current[key];
|
|
144
|
+
}
|
|
145
|
+
const lastKey = keys[keys.length - 1];
|
|
146
|
+
if (lastKey) {
|
|
147
|
+
current[lastKey] = value;
|
|
148
|
+
}
|
|
149
|
+
return true;
|
|
129
150
|
}
|
|
130
|
-
|
|
131
|
-
.
|
|
132
|
-
|
|
151
|
+
function dispatchStoreAction(storeId, actionName, ...args) {
|
|
152
|
+
const store = storeRegistry.get(storeId);
|
|
153
|
+
if (!store) return null;
|
|
154
|
+
const action = store[actionName];
|
|
155
|
+
if (!commonIs.isFunction(action)) {
|
|
156
|
+
throw new Error(`Action "${actionName}" not found in store "${storeId}"`);
|
|
157
|
+
}
|
|
158
|
+
return action.apply(store, args);
|
|
133
159
|
}
|
|
134
|
-
|
|
135
|
-
.
|
|
136
|
-
background: #45475a;
|
|
137
|
-
border-radius: 3px;
|
|
160
|
+
function serializeStoreStates(states) {
|
|
161
|
+
return JSON.stringify(states, null, 2);
|
|
138
162
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
163
|
+
function deepClone(obj) {
|
|
164
|
+
if (obj === null || typeof obj !== "object") {
|
|
165
|
+
return obj;
|
|
166
|
+
}
|
|
167
|
+
if (obj instanceof Date) {
|
|
168
|
+
return new Date(obj.getTime());
|
|
169
|
+
}
|
|
170
|
+
if (Array.isArray(obj)) {
|
|
171
|
+
return obj.map((item) => deepClone(item));
|
|
172
|
+
}
|
|
173
|
+
if (commonIs.isObject(obj)) {
|
|
174
|
+
const cloned = {};
|
|
175
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
176
|
+
cloned[key] = deepClone(value);
|
|
177
|
+
}
|
|
178
|
+
return cloned;
|
|
179
|
+
}
|
|
180
|
+
return obj;
|
|
142
181
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
182
|
+
function subscribeStore(storeId) {
|
|
183
|
+
const store = storeRegistry.get(storeId);
|
|
184
|
+
if (!store) return false;
|
|
185
|
+
if (subscribers.has(storeId)) {
|
|
186
|
+
unsubscribeStore(storeId);
|
|
187
|
+
}
|
|
188
|
+
if (commonIs.isFunction(store.$subscribe)) {
|
|
189
|
+
const unsubscribe = store.$subscribe((_mutation, state) => {
|
|
190
|
+
const currentState = commonIs.isObject(state) ? deepClone(state) : {};
|
|
191
|
+
globalChangeCallbacks.forEach((cb) => cb(storeId, currentState));
|
|
192
|
+
});
|
|
193
|
+
subscribers.set(storeId, commonIs.isFunction(unsubscribe) ? unsubscribe : () => {
|
|
194
|
+
});
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
157
198
|
}
|
|
158
|
-
|
|
159
|
-
.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
199
|
+
function unsubscribeStore(storeId) {
|
|
200
|
+
const unsubscribe = subscribers.get(storeId);
|
|
201
|
+
if (unsubscribe) {
|
|
202
|
+
unsubscribe();
|
|
203
|
+
subscribers.delete(storeId);
|
|
204
|
+
}
|
|
163
205
|
}
|
|
164
|
-
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
206
|
+
function onStoreChange(callback) {
|
|
207
|
+
globalChangeCallbacks.add(callback);
|
|
208
|
+
return () => {
|
|
209
|
+
globalChangeCallbacks.delete(callback);
|
|
210
|
+
};
|
|
169
211
|
}
|
|
170
|
-
|
|
171
|
-
.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
212
|
+
function clearStoreRegistry() {
|
|
213
|
+
for (const storeId of subscribers.keys()) {
|
|
214
|
+
unsubscribeStore(storeId);
|
|
215
|
+
}
|
|
216
|
+
globalChangeCallbacks.clear();
|
|
217
|
+
storeRegistry.clear();
|
|
176
218
|
}
|
|
177
|
-
|
|
178
|
-
.
|
|
179
|
-
background: #f38ba8;
|
|
219
|
+
function getRegisteredStoreIds() {
|
|
220
|
+
return Array.from(storeRegistry.keys());
|
|
180
221
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
right: 0;
|
|
187
|
-
width: 16px;
|
|
188
|
-
height: 16px;
|
|
189
|
-
cursor: nwse-resize;
|
|
190
|
-
z-index: 10;
|
|
222
|
+
var routerInstance = null;
|
|
223
|
+
var routeHistory = [];
|
|
224
|
+
var afterEachHandler = null;
|
|
225
|
+
function registerRouter(router) {
|
|
226
|
+
routerInstance = router;
|
|
191
227
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
position: absolute;
|
|
196
|
-
bottom: 3px;
|
|
197
|
-
right: 3px;
|
|
198
|
-
width: 8px;
|
|
199
|
-
height: 8px;
|
|
200
|
-
border-right: 2px solid #585b70;
|
|
201
|
-
border-bottom: 2px solid #585b70;
|
|
228
|
+
function unregisterRouter() {
|
|
229
|
+
unwatchRouteChanges();
|
|
230
|
+
routerInstance = null;
|
|
202
231
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
232
|
+
function getCurrentRoute() {
|
|
233
|
+
if (!routerInstance) return null;
|
|
234
|
+
const currentRoute = routerInstance.currentRoute?.();
|
|
235
|
+
if (!currentRoute) return null;
|
|
236
|
+
return {
|
|
237
|
+
path: currentRoute.path || "/",
|
|
238
|
+
name: currentRoute.name || null,
|
|
239
|
+
params: currentRoute.params || {},
|
|
240
|
+
query: currentRoute.query || {},
|
|
241
|
+
matched: (currentRoute.matched || []).map((m) => ({
|
|
242
|
+
path: m.path || "",
|
|
243
|
+
name: m.name || null
|
|
244
|
+
}))
|
|
245
|
+
};
|
|
210
246
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
width: auto !important;
|
|
214
|
-
height: auto !important;
|
|
215
|
-
border-radius: 8px;
|
|
247
|
+
function getRouteHistory() {
|
|
248
|
+
return [...routeHistory];
|
|
216
249
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
.
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
250
|
+
function watchRouteChanges() {
|
|
251
|
+
if (!routerInstance) return false;
|
|
252
|
+
if (!commonIs.isFunction(routerInstance.afterEach)) return false;
|
|
253
|
+
if (afterEachHandler !== null) {
|
|
254
|
+
unwatchRouteChanges();
|
|
255
|
+
}
|
|
256
|
+
routerInstance.afterEach((to) => {
|
|
257
|
+
const routeInfo = {
|
|
258
|
+
path: to.path || "/",
|
|
259
|
+
name: to.name || null,
|
|
260
|
+
params: to.params || {},
|
|
261
|
+
query: to.query || {},
|
|
262
|
+
matched: (to.matched || []).map((m) => ({
|
|
263
|
+
path: m.path || "",
|
|
264
|
+
name: m.name || null
|
|
265
|
+
}))
|
|
266
|
+
};
|
|
267
|
+
routeHistory.push(routeInfo);
|
|
268
|
+
});
|
|
269
|
+
afterEachHandler = () => {
|
|
270
|
+
afterEachHandler = null;
|
|
271
|
+
};
|
|
272
|
+
return true;
|
|
231
273
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
274
|
+
function unwatchRouteChanges() {
|
|
275
|
+
if (afterEachHandler) {
|
|
276
|
+
afterEachHandler();
|
|
277
|
+
afterEachHandler = null;
|
|
278
|
+
}
|
|
235
279
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
280
|
+
function navigateTo(path) {
|
|
281
|
+
if (!routerInstance) {
|
|
282
|
+
return Promise.reject(new Error("Router not registered"));
|
|
283
|
+
}
|
|
284
|
+
return routerInstance.push?.(path) || Promise.resolve();
|
|
285
|
+
}
|
|
286
|
+
function navigateToName(name, params) {
|
|
287
|
+
if (!routerInstance) {
|
|
288
|
+
return Promise.reject(new Error("Router not registered"));
|
|
289
|
+
}
|
|
290
|
+
return routerInstance.push?.({ name, params }) || Promise.resolve();
|
|
291
|
+
}
|
|
292
|
+
function goBack() {
|
|
293
|
+
if (!routerInstance) {
|
|
294
|
+
return Promise.reject(new Error("Router not registered"));
|
|
295
|
+
}
|
|
296
|
+
return routerInstance.back?.() || Promise.resolve();
|
|
297
|
+
}
|
|
298
|
+
function serializeRouteInfo(route) {
|
|
299
|
+
if (!route) return "No route information available";
|
|
300
|
+
let result = `Path: ${route.path}
|
|
301
|
+
`;
|
|
302
|
+
result += `Name: ${route.name || "N/A"}
|
|
303
|
+
`;
|
|
304
|
+
result += `Params: ${JSON.stringify(route.params)}
|
|
305
|
+
`;
|
|
306
|
+
result += `Query: ${JSON.stringify(route.query)}
|
|
307
|
+
`;
|
|
308
|
+
result += `Matched Routes:
|
|
309
|
+
`;
|
|
310
|
+
if (route.matched.length === 0) {
|
|
311
|
+
result += " (none)\n";
|
|
312
|
+
} else {
|
|
313
|
+
for (const match of route.matched) {
|
|
314
|
+
result += ` - ${match.path}${match.name ? ` (${match.name})` : ""}
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return result;
|
|
319
|
+
}
|
|
320
|
+
function getRoutes() {
|
|
321
|
+
if (!routerInstance) return [];
|
|
322
|
+
const routes = routerInstance.getRoutes?.() || [];
|
|
323
|
+
return routes.map((r) => ({
|
|
324
|
+
path: r.path || "",
|
|
325
|
+
name: r.name || null
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
function isRouterRegistered() {
|
|
329
|
+
return routerInstance !== null;
|
|
330
|
+
}
|
|
331
|
+
function clearRouteHistory() {
|
|
332
|
+
routeHistory.length = 0;
|
|
239
333
|
}
|
|
240
334
|
|
|
241
|
-
.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
335
|
+
// src/signalsInspector.ts
|
|
336
|
+
var signalRegistry = /* @__PURE__ */ new Map();
|
|
337
|
+
var snapshotManager = {
|
|
338
|
+
snapshots: [],
|
|
339
|
+
maxSnapshots: 100,
|
|
340
|
+
add(snapshot) {
|
|
341
|
+
this.snapshots.push(snapshot);
|
|
342
|
+
if (this.snapshots.length > this.maxSnapshots) {
|
|
343
|
+
this.snapshots.shift();
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
getAll() {
|
|
347
|
+
return [...this.snapshots];
|
|
348
|
+
},
|
|
349
|
+
get(index) {
|
|
350
|
+
return this.snapshots[index];
|
|
351
|
+
},
|
|
352
|
+
clear() {
|
|
353
|
+
this.snapshots = [];
|
|
354
|
+
},
|
|
355
|
+
getLength() {
|
|
356
|
+
return this.snapshots.length;
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
var performanceRecords = [];
|
|
360
|
+
var maxPerformanceRecords = 1e3;
|
|
361
|
+
function registerSignal(id, name, type, initialValue) {
|
|
362
|
+
signalRegistry.set(id, {
|
|
363
|
+
type,
|
|
364
|
+
name,
|
|
365
|
+
dependencies: /* @__PURE__ */ new Set(),
|
|
366
|
+
dependents: /* @__PURE__ */ new Set(),
|
|
367
|
+
value: initialValue,
|
|
368
|
+
updateCount: 0,
|
|
369
|
+
updateTimes: [],
|
|
370
|
+
lastUpdateTime: 0
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
function unregisterSignal(id) {
|
|
374
|
+
const node = signalRegistry.get(id);
|
|
375
|
+
if (node) {
|
|
376
|
+
node.dependencies.forEach((depId) => {
|
|
377
|
+
const dep = signalRegistry.get(depId);
|
|
378
|
+
if (dep) {
|
|
379
|
+
dep.dependents.delete(id);
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
node.dependents.forEach((depId) => {
|
|
383
|
+
const dep = signalRegistry.get(depId);
|
|
384
|
+
if (dep) {
|
|
385
|
+
dep.dependencies.delete(id);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
signalRegistry.delete(id);
|
|
390
|
+
}
|
|
391
|
+
function recordSignalUpdate(id, newValue, duration) {
|
|
392
|
+
const node = signalRegistry.get(id);
|
|
393
|
+
if (node) {
|
|
394
|
+
node.previousValue = node.value;
|
|
395
|
+
node.value = newValue;
|
|
396
|
+
node.updateCount++;
|
|
397
|
+
node.lastUpdateTime = Date.now();
|
|
398
|
+
if (duration !== void 0) {
|
|
399
|
+
node.updateTimes.push(duration);
|
|
400
|
+
if (node.updateTimes.length > 10) {
|
|
401
|
+
node.updateTimes.shift();
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
if (duration !== void 0) {
|
|
405
|
+
recordPerformance({
|
|
406
|
+
id,
|
|
407
|
+
name: node.name,
|
|
408
|
+
type: node.type,
|
|
409
|
+
duration,
|
|
410
|
+
timestamp: Date.now()
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function recordDependency(sourceId, targetId) {
|
|
416
|
+
const source = signalRegistry.get(sourceId);
|
|
417
|
+
const target = signalRegistry.get(targetId);
|
|
418
|
+
if (source && target) {
|
|
419
|
+
source.dependencies.add(targetId);
|
|
420
|
+
target.dependents.add(sourceId);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function getSignalNodes() {
|
|
424
|
+
return Array.from(signalRegistry.entries()).map(([id, node]) => ({
|
|
425
|
+
id,
|
|
426
|
+
name: node.name,
|
|
427
|
+
type: node.type,
|
|
428
|
+
value: node.value,
|
|
429
|
+
previousValue: node.previousValue,
|
|
430
|
+
dependencies: Array.from(node.dependencies),
|
|
431
|
+
dependents: Array.from(node.dependents),
|
|
432
|
+
updateCount: node.updateCount,
|
|
433
|
+
lastUpdateTime: node.lastUpdateTime,
|
|
434
|
+
averageUpdateTime: node.updateTimes.length > 0 ? node.updateTimes.reduce((a, b) => a + b, 0) / node.updateTimes.length : 0
|
|
435
|
+
}));
|
|
436
|
+
}
|
|
437
|
+
function getSignalNode(id) {
|
|
438
|
+
const node = signalRegistry.get(id);
|
|
439
|
+
if (!node) return void 0;
|
|
440
|
+
return {
|
|
441
|
+
id,
|
|
442
|
+
name: node.name,
|
|
443
|
+
type: node.type,
|
|
444
|
+
value: node.value,
|
|
445
|
+
previousValue: node.previousValue,
|
|
446
|
+
dependencies: Array.from(node.dependencies),
|
|
447
|
+
dependents: Array.from(node.dependents),
|
|
448
|
+
updateCount: node.updateCount,
|
|
449
|
+
lastUpdateTime: node.lastUpdateTime,
|
|
450
|
+
averageUpdateTime: node.updateTimes.length > 0 ? node.updateTimes.reduce((a, b) => a + b, 0) / node.updateTimes.length : 0
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
function getDependencyGraph() {
|
|
454
|
+
const nodes = [];
|
|
455
|
+
const edges = [];
|
|
456
|
+
signalRegistry.forEach((node, id) => {
|
|
457
|
+
nodes.push({
|
|
458
|
+
id,
|
|
459
|
+
name: node.name,
|
|
460
|
+
type: node.type
|
|
461
|
+
});
|
|
462
|
+
node.dependencies.forEach((depId) => {
|
|
463
|
+
edges.push({
|
|
464
|
+
source: depId,
|
|
465
|
+
target: id,
|
|
466
|
+
type: "dependency"
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
return { nodes, edges };
|
|
471
|
+
}
|
|
472
|
+
function createSnapshot(label) {
|
|
473
|
+
const snapshot = {
|
|
474
|
+
id: `snapshot_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
475
|
+
timestamp: Date.now(),
|
|
476
|
+
label,
|
|
477
|
+
signals: {}
|
|
478
|
+
};
|
|
479
|
+
signalRegistry.forEach((node, id) => {
|
|
480
|
+
snapshot.signals[id] = {
|
|
481
|
+
value: node.value,
|
|
482
|
+
dependencies: Array.from(node.dependencies)
|
|
483
|
+
};
|
|
484
|
+
});
|
|
485
|
+
snapshotManager.add(snapshot);
|
|
486
|
+
return snapshot;
|
|
487
|
+
}
|
|
488
|
+
function getSnapshots() {
|
|
489
|
+
return snapshotManager.getAll();
|
|
490
|
+
}
|
|
491
|
+
function getTimeTravelState() {
|
|
492
|
+
const length = snapshotManager.getLength();
|
|
493
|
+
return {
|
|
494
|
+
snapshots: snapshotManager.getAll(),
|
|
495
|
+
currentIndex: length - 1,
|
|
496
|
+
canUndo: length > 1,
|
|
497
|
+
canRedo: false
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
function restoreSnapshot(index) {
|
|
501
|
+
const snapshot = snapshotManager.get(index);
|
|
502
|
+
if (!snapshot) return void 0;
|
|
503
|
+
Object.entries(snapshot.signals).forEach(([id, signalSnapshot]) => {
|
|
504
|
+
const node = signalRegistry.get(id);
|
|
505
|
+
if (node) {
|
|
506
|
+
node.value = signalSnapshot.value;
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
return snapshot;
|
|
510
|
+
}
|
|
511
|
+
function clearSnapshots() {
|
|
512
|
+
snapshotManager.clear();
|
|
513
|
+
}
|
|
514
|
+
function recordPerformance(record) {
|
|
515
|
+
performanceRecords.push(record);
|
|
516
|
+
if (performanceRecords.length > maxPerformanceRecords) {
|
|
517
|
+
performanceRecords.shift();
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
function getPerformanceRecords(limit) {
|
|
521
|
+
const records = [...performanceRecords];
|
|
522
|
+
if (limit !== void 0) {
|
|
523
|
+
return records.slice(-limit);
|
|
524
|
+
}
|
|
525
|
+
return records;
|
|
526
|
+
}
|
|
527
|
+
function getPerformanceStats() {
|
|
528
|
+
if (performanceRecords.length === 0) {
|
|
529
|
+
return {
|
|
530
|
+
totalRecords: 0,
|
|
531
|
+
averageDuration: 0,
|
|
532
|
+
maxDuration: 0,
|
|
533
|
+
minDuration: 0,
|
|
534
|
+
byType: {}
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
const durations = performanceRecords.map((r) => r.duration);
|
|
538
|
+
const byType = {};
|
|
539
|
+
performanceRecords.forEach((record) => {
|
|
540
|
+
if (!byType[record.type]) {
|
|
541
|
+
byType[record.type] = { count: 0, total: 0, max: 0 };
|
|
542
|
+
}
|
|
543
|
+
const typeStats = byType[record.type];
|
|
544
|
+
typeStats.count++;
|
|
545
|
+
typeStats.total += record.duration;
|
|
546
|
+
typeStats.max = Math.max(typeStats.max, record.duration);
|
|
547
|
+
});
|
|
548
|
+
const byTypeResult = {};
|
|
549
|
+
Object.entries(byType).forEach(([type, data]) => {
|
|
550
|
+
byTypeResult[type] = {
|
|
551
|
+
count: data.count,
|
|
552
|
+
average: data.total / data.count,
|
|
553
|
+
max: data.max
|
|
554
|
+
};
|
|
555
|
+
});
|
|
556
|
+
return {
|
|
557
|
+
totalRecords: performanceRecords.length,
|
|
558
|
+
averageDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
|
|
559
|
+
maxDuration: Math.max(...durations),
|
|
560
|
+
minDuration: Math.min(...durations),
|
|
561
|
+
byType: byTypeResult
|
|
562
|
+
};
|
|
246
563
|
}
|
|
564
|
+
function clearPerformanceRecords() {
|
|
565
|
+
performanceRecords.length = 0;
|
|
566
|
+
}
|
|
567
|
+
function clearSignalRegistry() {
|
|
568
|
+
signalRegistry.clear();
|
|
569
|
+
}
|
|
570
|
+
function serializeSignalNode(node) {
|
|
571
|
+
let result = `\u{1F4CA} ${node.name} (${node.type})
|
|
572
|
+
`;
|
|
573
|
+
result += ` ID: ${node.id}
|
|
574
|
+
`;
|
|
575
|
+
result += ` \u66F4\u65B0\u6B21\u6570: ${node.updateCount}
|
|
576
|
+
`;
|
|
577
|
+
result += ` \u6700\u540E\u66F4\u65B0: ${new Date(node.lastUpdateTime).toLocaleTimeString()}
|
|
578
|
+
`;
|
|
579
|
+
if (node.averageUpdateTime > 0) {
|
|
580
|
+
result += ` \u5E73\u5747\u66F4\u65B0\u8017\u65F6: ${node.averageUpdateTime.toFixed(2)}ms
|
|
581
|
+
`;
|
|
582
|
+
}
|
|
583
|
+
if (node.dependencies.length > 0) {
|
|
584
|
+
result += ` \u4F9D\u8D56: ${node.dependencies.join(", ")}
|
|
585
|
+
`;
|
|
586
|
+
}
|
|
587
|
+
if (node.dependents.length > 0) {
|
|
588
|
+
result += ` \u88AB\u4F9D\u8D56: ${node.dependents.join(", ")}
|
|
589
|
+
`;
|
|
590
|
+
}
|
|
591
|
+
return result;
|
|
592
|
+
}
|
|
593
|
+
function serializeDependencyGraph() {
|
|
594
|
+
const graph = getDependencyGraph();
|
|
595
|
+
if (graph.nodes.length === 0) {
|
|
596
|
+
return "\u6682\u65E0\u4FE1\u53F7\u6570\u636E";
|
|
597
|
+
}
|
|
598
|
+
let result = `\u{1F4C8} \u4F9D\u8D56\u56FE (${graph.nodes.length} \u4E2A\u8282\u70B9, ${graph.edges.length} \u6761\u8FB9)
|
|
247
599
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
600
|
+
`;
|
|
601
|
+
graph.nodes.forEach((node) => {
|
|
602
|
+
const nodeInfo = signalRegistry.get(node.id);
|
|
603
|
+
const deps = nodeInfo?.dependencies || /* @__PURE__ */ new Set();
|
|
604
|
+
const dependents = nodeInfo?.dependents || /* @__PURE__ */ new Set();
|
|
605
|
+
result += `\u{1F539} ${node.name} (${node.type})
|
|
606
|
+
`;
|
|
607
|
+
if (deps.size > 0) {
|
|
608
|
+
result += ` \u2193 \u4F9D\u8D56: ${Array.from(deps).join(", ")}
|
|
609
|
+
`;
|
|
610
|
+
}
|
|
611
|
+
if (dependents.size > 0) {
|
|
612
|
+
result += ` \u2191 \u88AB\u4F9D\u8D56: ${Array.from(dependents).join(", ")}
|
|
613
|
+
`;
|
|
614
|
+
}
|
|
615
|
+
result += "\n";
|
|
616
|
+
});
|
|
617
|
+
return result;
|
|
254
618
|
}
|
|
619
|
+
function serializePerformanceStats() {
|
|
620
|
+
const stats = getPerformanceStats();
|
|
621
|
+
if (stats.totalRecords === 0) {
|
|
622
|
+
return "\u6682\u65E0\u6027\u80FD\u6570\u636E";
|
|
623
|
+
}
|
|
624
|
+
let result = `\u26A1 \u6027\u80FD\u7EDF\u8BA1
|
|
625
|
+
|
|
626
|
+
`;
|
|
627
|
+
result += `\u603B\u8BB0\u5F55\u6570: ${stats.totalRecords}
|
|
628
|
+
`;
|
|
629
|
+
result += `\u5E73\u5747\u8017\u65F6: ${stats.averageDuration.toFixed(2)}ms
|
|
630
|
+
`;
|
|
631
|
+
result += `\u6700\u5927\u8017\u65F6: ${stats.maxDuration.toFixed(2)}ms
|
|
632
|
+
`;
|
|
633
|
+
result += `\u6700\u5C0F\u8017\u65F6: ${stats.minDuration.toFixed(2)}ms
|
|
255
634
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
635
|
+
`;
|
|
636
|
+
result += `\u6309\u7C7B\u578B\u7EDF\u8BA1:
|
|
637
|
+
`;
|
|
638
|
+
Object.entries(stats.byType).forEach(([type, data]) => {
|
|
639
|
+
result += ` ${type}: ${data.count} \u6B21, \u5E73\u5747 ${data.average.toFixed(2)}ms, \u6700\u5927 ${data.max.toFixed(2)}ms
|
|
640
|
+
`;
|
|
641
|
+
});
|
|
642
|
+
return result;
|
|
259
643
|
}
|
|
260
644
|
|
|
261
|
-
.
|
|
262
|
-
|
|
263
|
-
|
|
645
|
+
// src/performance.ts
|
|
646
|
+
var DEFAULT_OPTIONS = {
|
|
647
|
+
enabled: true,
|
|
648
|
+
maxRecords: 1e3,
|
|
649
|
+
sampleRate: 1,
|
|
650
|
+
autoRecordPageMetrics: true,
|
|
651
|
+
autoRecordLongTasks: true,
|
|
652
|
+
longTaskThreshold: 50
|
|
653
|
+
};
|
|
654
|
+
var metrics = [];
|
|
655
|
+
var alertRules = /* @__PURE__ */ new Map();
|
|
656
|
+
var alerts = [];
|
|
657
|
+
var alertCooldowns = /* @__PURE__ */ new Map();
|
|
658
|
+
var options = { ...DEFAULT_OPTIONS };
|
|
659
|
+
var observers = /* @__PURE__ */ new Set();
|
|
660
|
+
function initPerformanceMonitor(opts) {
|
|
661
|
+
options = { ...DEFAULT_OPTIONS, ...opts };
|
|
662
|
+
if (options.enabled) {
|
|
663
|
+
if (options.autoRecordPageMetrics) {
|
|
664
|
+
initPageMetrics();
|
|
665
|
+
}
|
|
666
|
+
if (options.autoRecordLongTasks) {
|
|
667
|
+
initLongTaskObserver();
|
|
668
|
+
}
|
|
669
|
+
initDefaultAlertRules();
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
function initPageMetrics() {
|
|
673
|
+
if (typeof window === "undefined") return;
|
|
674
|
+
if (typeof PerformanceObserver !== "undefined") {
|
|
675
|
+
try {
|
|
676
|
+
new PerformanceObserver((list) => {
|
|
677
|
+
for (const entry of list.getEntries()) {
|
|
678
|
+
if (entry.entryType === "paint") {
|
|
679
|
+
recordMetric({
|
|
680
|
+
name: entry.name,
|
|
681
|
+
type: "custom",
|
|
682
|
+
duration: entry.startTime,
|
|
683
|
+
metadata: { entryType: entry.entryType }
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}).observe({ type: "paint", buffered: true });
|
|
688
|
+
} catch (e) {
|
|
689
|
+
console.warn("[LytJS Performance] Failed to observe paint metrics:", e);
|
|
690
|
+
}
|
|
691
|
+
try {
|
|
692
|
+
new PerformanceObserver((list) => {
|
|
693
|
+
for (const entry of list.getEntries()) {
|
|
694
|
+
const firstInputEntry = entry;
|
|
695
|
+
if (firstInputEntry.processingStart !== void 0) {
|
|
696
|
+
recordMetric({
|
|
697
|
+
name: "First Input Delay",
|
|
698
|
+
type: "custom",
|
|
699
|
+
duration: firstInputEntry.processingStart - firstInputEntry.startTime,
|
|
700
|
+
metadata: { entryType: entry.entryType }
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
}).observe({ type: "first-input", buffered: true });
|
|
705
|
+
} catch (e) {
|
|
706
|
+
console.warn("[LytJS Performance] Failed to observe first-input:", e);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
function initLongTaskObserver() {
|
|
711
|
+
if (typeof PerformanceObserver === "undefined") return;
|
|
712
|
+
try {
|
|
713
|
+
new PerformanceObserver((list) => {
|
|
714
|
+
for (const entry of list.getEntries()) {
|
|
715
|
+
if (entry.entryType === "longtask") {
|
|
716
|
+
recordMetric({
|
|
717
|
+
name: "Long Task",
|
|
718
|
+
type: "custom",
|
|
719
|
+
duration: entry.duration,
|
|
720
|
+
metadata: { attribution: entry.attribution }
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}).observe({ type: "longtask", buffered: true });
|
|
725
|
+
} catch (e) {
|
|
726
|
+
console.warn("[LytJS Performance] Failed to observe long tasks:", e);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function initDefaultAlertRules() {
|
|
730
|
+
registerAlertRule({
|
|
731
|
+
id: "long_task_warning",
|
|
732
|
+
name: "\u957F\u4EFB\u52A1\u8B66\u544A",
|
|
733
|
+
level: "warning",
|
|
734
|
+
condition: (metric) => metric.duration > options.longTaskThreshold,
|
|
735
|
+
message: "\u68C0\u6D4B\u5230\u957F\u4EFB\u52A1: {{name}}, \u8017\u65F6 {{duration}}ms",
|
|
736
|
+
enabled: true,
|
|
737
|
+
cooldown: 5e3
|
|
738
|
+
});
|
|
739
|
+
registerAlertRule({
|
|
740
|
+
id: "slow_render_error",
|
|
741
|
+
name: "\u6E32\u67D3\u8FC7\u6162",
|
|
742
|
+
level: "error",
|
|
743
|
+
condition: (metric, stats) => metric.duration > stats.p99 * 1.5 && stats.count > 10,
|
|
744
|
+
message: "\u6E32\u67D3\u6027\u80FD\u5F02\u5E38: {{name}}, \u8017\u65F6 {{duration}}ms",
|
|
745
|
+
enabled: true,
|
|
746
|
+
cooldown: 1e4
|
|
747
|
+
});
|
|
748
|
+
registerAlertRule({
|
|
749
|
+
id: "critical_render",
|
|
750
|
+
name: "\u4E25\u91CD\u6E32\u67D3\u95EE\u9898",
|
|
751
|
+
level: "critical",
|
|
752
|
+
condition: (metric) => metric.duration > 500,
|
|
753
|
+
message: "\u4E25\u91CD\u6027\u80FD\u95EE\u9898: {{name}} \u8017\u65F6\u8D85\u8FC7 500ms!",
|
|
754
|
+
enabled: true,
|
|
755
|
+
cooldown: 3e4
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
function recordMetric(metric) {
|
|
759
|
+
if (!options.enabled) {
|
|
760
|
+
return { id: "", timestamp: 0, ...metric };
|
|
761
|
+
}
|
|
762
|
+
if (Math.random() > options.sampleRate) {
|
|
763
|
+
return { id: "", timestamp: 0, ...metric };
|
|
764
|
+
}
|
|
765
|
+
const fullMetric = {
|
|
766
|
+
id: `metric_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
767
|
+
timestamp: Date.now(),
|
|
768
|
+
...metric
|
|
769
|
+
};
|
|
770
|
+
metrics.push(fullMetric);
|
|
771
|
+
if (metrics.length > options.maxRecords) {
|
|
772
|
+
metrics.shift();
|
|
773
|
+
}
|
|
774
|
+
observers.forEach((cb) => cb(fullMetric));
|
|
775
|
+
checkAlertRules(fullMetric);
|
|
776
|
+
return fullMetric;
|
|
777
|
+
}
|
|
778
|
+
function getMetrics(limit) {
|
|
779
|
+
const result = [...metrics];
|
|
780
|
+
if (limit !== void 0) {
|
|
781
|
+
return result.slice(-limit);
|
|
782
|
+
}
|
|
783
|
+
return result;
|
|
784
|
+
}
|
|
785
|
+
function getStats(type) {
|
|
786
|
+
const filteredMetrics = type ? metrics.filter((m) => m.type === type) : [...metrics];
|
|
787
|
+
if (filteredMetrics.length === 0) {
|
|
788
|
+
return {
|
|
789
|
+
count: 0,
|
|
790
|
+
total: 0,
|
|
791
|
+
average: 0,
|
|
792
|
+
min: 0,
|
|
793
|
+
max: 0,
|
|
794
|
+
p50: 0,
|
|
795
|
+
p90: 0,
|
|
796
|
+
p99: 0
|
|
797
|
+
};
|
|
798
|
+
}
|
|
799
|
+
const durations = filteredMetrics.map((m) => m.duration).sort((a, b) => a - b);
|
|
800
|
+
const total = durations.reduce((a, b) => a + b, 0);
|
|
801
|
+
return {
|
|
802
|
+
count: durations.length,
|
|
803
|
+
total,
|
|
804
|
+
average: total / durations.length,
|
|
805
|
+
min: durations[0] ?? 0,
|
|
806
|
+
max: durations[durations.length - 1] ?? 0,
|
|
807
|
+
p50: percentile(durations, 50),
|
|
808
|
+
p90: percentile(durations, 90),
|
|
809
|
+
p99: percentile(durations, 99)
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function percentile(sortedArray, p) {
|
|
813
|
+
if (sortedArray.length === 0) return 0;
|
|
814
|
+
const index = Math.ceil(sortedArray.length * p / 100) - 1;
|
|
815
|
+
return sortedArray[Math.max(0, index)] ?? 0;
|
|
816
|
+
}
|
|
817
|
+
function registerAlertRule(rule) {
|
|
818
|
+
alertRules.set(rule.id, rule);
|
|
819
|
+
}
|
|
820
|
+
function unregisterAlertRule(ruleId) {
|
|
821
|
+
alertRules.delete(ruleId);
|
|
822
|
+
}
|
|
823
|
+
function setAlertRuleEnabled(ruleId, enabled) {
|
|
824
|
+
const rule = alertRules.get(ruleId);
|
|
825
|
+
if (rule) {
|
|
826
|
+
rule.enabled = enabled;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
function getAlertRules() {
|
|
830
|
+
return Array.from(alertRules.values());
|
|
831
|
+
}
|
|
832
|
+
function getAlerts(includeAcknowledged = true) {
|
|
833
|
+
if (includeAcknowledged) {
|
|
834
|
+
return [...alerts];
|
|
835
|
+
}
|
|
836
|
+
return alerts.filter((a) => !a.acknowledged);
|
|
264
837
|
}
|
|
838
|
+
function acknowledgeAlert(alertId) {
|
|
839
|
+
const alert = alerts.find((a) => a.id === alertId);
|
|
840
|
+
if (alert) {
|
|
841
|
+
alert.acknowledged = true;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
function acknowledgeAllAlerts() {
|
|
845
|
+
alerts.forEach((alert) => {
|
|
846
|
+
alert.acknowledged = true;
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
function clearAlerts() {
|
|
850
|
+
alerts.length = 0;
|
|
851
|
+
}
|
|
852
|
+
function checkAlertRules(metric) {
|
|
853
|
+
const stats = getStats(metric.type);
|
|
854
|
+
alertRules.forEach((rule) => {
|
|
855
|
+
if (!rule.enabled) return;
|
|
856
|
+
const lastTriggered = alertCooldowns.get(rule.id) || 0;
|
|
857
|
+
if (Date.now() - lastTriggered < rule.cooldown) return;
|
|
858
|
+
if (rule.condition(metric, stats)) {
|
|
859
|
+
const alert = {
|
|
860
|
+
id: `alert_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
861
|
+
ruleId: rule.id,
|
|
862
|
+
ruleName: rule.name,
|
|
863
|
+
level: rule.level,
|
|
864
|
+
message: interpolateMessage(rule.message, metric),
|
|
865
|
+
metric,
|
|
866
|
+
timestamp: Date.now(),
|
|
867
|
+
acknowledged: false
|
|
868
|
+
};
|
|
869
|
+
alerts.push(alert);
|
|
870
|
+
alertCooldowns.set(rule.id, Date.now());
|
|
871
|
+
if (alerts.length > 100) {
|
|
872
|
+
alerts.shift();
|
|
873
|
+
}
|
|
874
|
+
outputAlert(alert);
|
|
875
|
+
}
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
function interpolateMessage(message, metric) {
|
|
879
|
+
return message.replace(/\{\{name\}\}/g, metric.name).replace(/\{\{duration\}\}/g, metric.duration.toFixed(2)).replace(/\{\{type\}\}/g, metric.type);
|
|
880
|
+
}
|
|
881
|
+
function outputAlert(alert) {
|
|
882
|
+
const levelStyles = {
|
|
883
|
+
info: "color: #1890ff;",
|
|
884
|
+
warning: "color: #faad14;",
|
|
885
|
+
error: "color: #ff4d4f;",
|
|
886
|
+
critical: "color: #722ed1; background: #ff4d4f; padding: 2px 5px;"
|
|
887
|
+
};
|
|
888
|
+
console.log(
|
|
889
|
+
`%c[LytJS Alert] ${alert.ruleName}%c ${alert.message}`,
|
|
890
|
+
levelStyles[alert.level],
|
|
891
|
+
"color: inherit;"
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
function addObserver(callback) {
|
|
895
|
+
observers.add(callback);
|
|
896
|
+
}
|
|
897
|
+
function removeObserver(callback) {
|
|
898
|
+
observers.delete(callback);
|
|
899
|
+
}
|
|
900
|
+
function clearMetrics() {
|
|
901
|
+
metrics.length = 0;
|
|
902
|
+
}
|
|
903
|
+
function resetPerformanceMonitor() {
|
|
904
|
+
metrics.length = 0;
|
|
905
|
+
alerts.length = 0;
|
|
906
|
+
observers.clear();
|
|
907
|
+
alertCooldowns.clear();
|
|
908
|
+
alertRules.clear();
|
|
909
|
+
}
|
|
910
|
+
function getPerformanceReport() {
|
|
911
|
+
const stats = {
|
|
912
|
+
render: getStats("render"),
|
|
913
|
+
update: getStats("update"),
|
|
914
|
+
effect: getStats("effect"),
|
|
915
|
+
computed: getStats("computed"),
|
|
916
|
+
reaction: getStats("reaction"),
|
|
917
|
+
custom: getStats("custom")
|
|
918
|
+
};
|
|
919
|
+
const allStats = getStats();
|
|
920
|
+
return {
|
|
921
|
+
metrics: [...metrics],
|
|
922
|
+
stats,
|
|
923
|
+
alerts: [...alerts],
|
|
924
|
+
summary: {
|
|
925
|
+
totalMetrics: metrics.length,
|
|
926
|
+
totalAlerts: alerts.length,
|
|
927
|
+
unacknowledgedAlerts: alerts.filter((a) => !a.acknowledged).length,
|
|
928
|
+
averageDuration: allStats.average
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
}
|
|
932
|
+
function serializePerformanceReport() {
|
|
933
|
+
const report = getPerformanceReport();
|
|
934
|
+
let result = `\u26A1 \u6027\u80FD\u62A5\u544A
|
|
935
|
+
|
|
936
|
+
`;
|
|
937
|
+
result += `\u{1F4CA} \u7EDF\u8BA1\u6458\u8981:
|
|
938
|
+
`;
|
|
939
|
+
result += ` \u603B\u8BB0\u5F55\u6570: ${report.summary.totalMetrics}
|
|
940
|
+
`;
|
|
941
|
+
result += ` \u5E73\u5747\u8017\u65F6: ${report.summary.averageDuration.toFixed(2)}ms
|
|
942
|
+
`;
|
|
943
|
+
result += ` \u603B\u544A\u8B66\u6570: ${report.summary.totalAlerts}
|
|
944
|
+
`;
|
|
945
|
+
result += ` \u672A\u786E\u8BA4\u544A\u8B66: ${report.summary.unacknowledgedAlerts}
|
|
265
946
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
947
|
+
`;
|
|
948
|
+
result += `\u{1F4C8} \u5206\u7C7B\u578B\u7EDF\u8BA1:
|
|
949
|
+
`;
|
|
950
|
+
Object.entries(report.stats).forEach(([type, stats]) => {
|
|
951
|
+
if (stats.count > 0) {
|
|
952
|
+
result += ` ${type}: ${stats.count} \u6B21, \u5E73\u5747 ${stats.average.toFixed(2)}ms, \u6700\u5927 ${stats.max.toFixed(2)}ms
|
|
953
|
+
`;
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
if (report.alerts.length > 0) {
|
|
957
|
+
result += `
|
|
958
|
+
\u{1F6A8} \u6700\u8FD1\u544A\u8B66:
|
|
959
|
+
`;
|
|
960
|
+
report.alerts.slice(-5).forEach((alert) => {
|
|
961
|
+
const levelIcon = alert.level === "critical" ? "\u{1F534}" : alert.level === "error" ? "\u274C" : alert.level === "warning" ? "\u26A0\uFE0F" : "\u2139\uFE0F";
|
|
962
|
+
result += ` ${levelIcon} [${alert.level}] ${alert.ruleName}: ${alert.message}
|
|
963
|
+
`;
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
return result;
|
|
967
|
+
}
|
|
968
|
+
function startTimer(name, type = "custom") {
|
|
969
|
+
const startTime = performance.now();
|
|
970
|
+
return () => {
|
|
971
|
+
const duration = performance.now() - startTime;
|
|
972
|
+
recordMetric({ name, type, duration });
|
|
973
|
+
};
|
|
269
974
|
}
|
|
270
975
|
|
|
271
|
-
.
|
|
272
|
-
|
|
273
|
-
|
|
976
|
+
// src/benchmark.ts
|
|
977
|
+
var LARGE_SCALE_SCENARIOS = [
|
|
978
|
+
{ name: "\u865A\u62DF\u5217\u8868-1000\u8282\u70B9", nodeCount: 1e3, description: "1000 \u4E2A\u865A\u62DF\u5217\u8868\u8282\u70B9\u6E32\u67D3" },
|
|
979
|
+
{ name: "\u865A\u62DF\u5217\u8868-5000\u8282\u70B9", nodeCount: 5e3, description: "5000 \u4E2A\u865A\u62DF\u5217\u8868\u8282\u70B9\u6E32\u67D3" },
|
|
980
|
+
{ name: "\u865A\u62DF\u5217\u8868-10000\u8282\u70B9", nodeCount: 1e4, description: "10000 \u4E2A\u865A\u62DF\u5217\u8868\u8282\u70B9\u6E32\u67D3" },
|
|
981
|
+
{ name: "\u7EC4\u4EF6\u6811-100\u7EC4\u4EF6", nodeCount: 100, description: "100 \u4E2A\u7EC4\u4EF6\u540C\u65F6\u6E32\u67D3" },
|
|
982
|
+
{ name: "\u7EC4\u4EF6\u6811-500\u7EC4\u4EF6", nodeCount: 500, description: "500 \u4E2A\u7EC4\u4EF6\u540C\u65F6\u6E32\u67D3" },
|
|
983
|
+
{ name: "\u7EC4\u4EF6\u6811-1000\u7EC4\u4EF6", nodeCount: 1e3, description: "1000 \u4E2A\u7EC4\u4EF6\u540C\u65F6\u6E32\u67D3" },
|
|
984
|
+
{ name: "\u4FE1\u53F7\u8FFD\u8E2A-500\u4FE1\u53F7", nodeCount: 500, description: "500 \u4E2A\u4FE1\u53F7\u540C\u65F6\u8FFD\u8E2A" },
|
|
985
|
+
{ name: "\u4FE1\u53F7\u8FFD\u8E2A-1000\u4FE1\u53F7", nodeCount: 1e3, description: "1000 \u4E2A\u4FE1\u53F7\u540C\u65F6\u8FFD\u8E2A" }
|
|
986
|
+
];
|
|
987
|
+
var benchmarkResults = /* @__PURE__ */ new Map();
|
|
988
|
+
function runBenchmark(config) {
|
|
989
|
+
const { name, iterations, warmup = 10, fn } = config;
|
|
990
|
+
for (let i = 0; i < warmup; i++) {
|
|
991
|
+
fn();
|
|
992
|
+
}
|
|
993
|
+
const durations = [];
|
|
994
|
+
const startTime = performance.now();
|
|
995
|
+
for (let i = 0; i < iterations; i++) {
|
|
996
|
+
const iterStart = performance.now();
|
|
997
|
+
fn();
|
|
998
|
+
durations.push(performance.now() - iterStart);
|
|
999
|
+
}
|
|
1000
|
+
const totalDuration = performance.now() - startTime;
|
|
1001
|
+
const result = {
|
|
1002
|
+
name,
|
|
1003
|
+
iterations,
|
|
1004
|
+
totalDuration,
|
|
1005
|
+
averageDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
|
|
1006
|
+
minDuration: Math.min(...durations),
|
|
1007
|
+
maxDuration: Math.max(...durations),
|
|
1008
|
+
opsPerSecond: iterations / totalDuration * 1e3,
|
|
1009
|
+
timestamp: Date.now()
|
|
1010
|
+
};
|
|
1011
|
+
storeBenchmarkResult(name, result);
|
|
1012
|
+
return result;
|
|
1013
|
+
}
|
|
1014
|
+
async function runAsyncBenchmark(config) {
|
|
1015
|
+
const { name, iterations, warmup = 10, asyncFn } = config;
|
|
1016
|
+
if (!asyncFn) {
|
|
1017
|
+
throw new Error("asyncFn is required for async benchmark");
|
|
1018
|
+
}
|
|
1019
|
+
for (let i = 0; i < warmup; i++) {
|
|
1020
|
+
await asyncFn();
|
|
1021
|
+
}
|
|
1022
|
+
const durations = [];
|
|
1023
|
+
const startTime = performance.now();
|
|
1024
|
+
for (let i = 0; i < iterations; i++) {
|
|
1025
|
+
const iterStart = performance.now();
|
|
1026
|
+
await asyncFn();
|
|
1027
|
+
durations.push(performance.now() - iterStart);
|
|
1028
|
+
}
|
|
1029
|
+
const totalDuration = performance.now() - startTime;
|
|
1030
|
+
const result = {
|
|
1031
|
+
name,
|
|
1032
|
+
iterations,
|
|
1033
|
+
totalDuration,
|
|
1034
|
+
averageDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
|
|
1035
|
+
minDuration: Math.min(...durations),
|
|
1036
|
+
maxDuration: Math.max(...durations),
|
|
1037
|
+
opsPerSecond: iterations / totalDuration * 1e3,
|
|
1038
|
+
timestamp: Date.now()
|
|
1039
|
+
};
|
|
1040
|
+
storeBenchmarkResult(name, result);
|
|
1041
|
+
return result;
|
|
1042
|
+
}
|
|
1043
|
+
function storeBenchmarkResult(name, result) {
|
|
1044
|
+
if (!benchmarkResults.has(name)) {
|
|
1045
|
+
benchmarkResults.set(name, []);
|
|
1046
|
+
}
|
|
1047
|
+
const results = benchmarkResults.get(name);
|
|
1048
|
+
results.push(result);
|
|
1049
|
+
if (results.length > 100) {
|
|
1050
|
+
results.shift();
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
function getBenchmarkResults(name) {
|
|
1054
|
+
if (name) {
|
|
1055
|
+
return benchmarkResults.get(name) || [];
|
|
1056
|
+
}
|
|
1057
|
+
const allResults = [];
|
|
1058
|
+
benchmarkResults.forEach((results) => {
|
|
1059
|
+
allResults.push(...results);
|
|
1060
|
+
});
|
|
1061
|
+
return allResults.sort((a, b) => b.timestamp - a.timestamp);
|
|
274
1062
|
}
|
|
1063
|
+
function getLatestBenchmarkResult(name) {
|
|
1064
|
+
const results = benchmarkResults.get(name);
|
|
1065
|
+
if (!results || results.length === 0) return void 0;
|
|
1066
|
+
return results[results.length - 1];
|
|
1067
|
+
}
|
|
1068
|
+
function clearBenchmarkResults(name) {
|
|
1069
|
+
if (name) {
|
|
1070
|
+
benchmarkResults.delete(name);
|
|
1071
|
+
} else {
|
|
1072
|
+
benchmarkResults.clear();
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
function serializeBenchmarkResult(result) {
|
|
1076
|
+
return `
|
|
1077
|
+
\u{1F4CA} ${result.name}
|
|
1078
|
+
\u8FED\u4EE3\u6B21\u6570: ${result.iterations}
|
|
1079
|
+
\u603B\u8017\u65F6: ${result.totalDuration.toFixed(2)}ms
|
|
1080
|
+
\u5E73\u5747\u8017\u65F6: ${result.averageDuration.toFixed(4)}ms
|
|
1081
|
+
\u6700\u5C0F\u8017\u65F6: ${result.minDuration.toFixed(4)}ms
|
|
1082
|
+
\u6700\u5927\u8017\u65F6: ${result.maxDuration.toFixed(4)}ms
|
|
1083
|
+
OPS: ${result.opsPerSecond.toFixed(2)} ops/s
|
|
1084
|
+
\u65F6\u95F4: ${new Date(result.timestamp).toLocaleString()}
|
|
1085
|
+
`.trim();
|
|
1086
|
+
}
|
|
1087
|
+
function serializeAllBenchmarkResults() {
|
|
1088
|
+
const allResults = getBenchmarkResults();
|
|
1089
|
+
if (allResults.length === 0) {
|
|
1090
|
+
return "\u6682\u65E0\u57FA\u51C6\u6D4B\u8BD5\u7ED3\u679C";
|
|
1091
|
+
}
|
|
1092
|
+
let result = `\u{1F4C8} \u57FA\u51C6\u6D4B\u8BD5\u62A5\u544A (${allResults.length} \u6761\u8BB0\u5F55)
|
|
275
1093
|
|
|
276
|
-
|
|
277
|
-
@
|
|
278
|
-
|
|
279
|
-
|
|
1094
|
+
`;
|
|
1095
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
1096
|
+
allResults.forEach((r) => {
|
|
1097
|
+
if (!grouped.has(r.name)) {
|
|
1098
|
+
grouped.set(r.name, []);
|
|
1099
|
+
}
|
|
1100
|
+
grouped.get(r.name).push(r);
|
|
1101
|
+
});
|
|
1102
|
+
grouped.forEach((results, name) => {
|
|
1103
|
+
const latest = results[results.length - 1];
|
|
1104
|
+
if (latest) {
|
|
1105
|
+
result += `\u{1F539} ${name}
|
|
1106
|
+
`;
|
|
1107
|
+
result += ` \u6700\u65B0: ${latest.averageDuration.toFixed(4)}ms (${latest.opsPerSecond.toFixed(2)} ops/s)
|
|
1108
|
+
`;
|
|
1109
|
+
result += ` \u5386\u53F2: ${results.length} \u6B21\u6D4B\u8BD5
|
|
1110
|
+
`;
|
|
1111
|
+
result += "\n";
|
|
1112
|
+
}
|
|
1113
|
+
});
|
|
1114
|
+
return result;
|
|
1115
|
+
}
|
|
1116
|
+
function compareBenchmarkResults(oldResult, newResult) {
|
|
1117
|
+
const durationDiff = oldResult.averageDuration - newResult.averageDuration;
|
|
1118
|
+
const durationDiffPercent = durationDiff / oldResult.averageDuration * 100;
|
|
1119
|
+
const opsDiff = newResult.opsPerSecond - oldResult.opsPerSecond;
|
|
1120
|
+
const opsDiffPercent = opsDiff / oldResult.opsPerSecond * 100;
|
|
1121
|
+
return {
|
|
1122
|
+
durationDiff,
|
|
1123
|
+
durationDiffPercent,
|
|
1124
|
+
opsDiff,
|
|
1125
|
+
opsDiffPercent,
|
|
1126
|
+
improved: durationDiff > 0
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
function createLargeScaleBenchmark(scenario, testFn) {
|
|
1130
|
+
return {
|
|
1131
|
+
name: `\u5927\u89C4\u6A21\u6D4B\u8BD5-${scenario.name}`,
|
|
1132
|
+
iterations: 100,
|
|
1133
|
+
warmup: 10,
|
|
1134
|
+
fn: () => testFn(scenario.nodeCount)
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
function getMemoryUsage() {
|
|
1138
|
+
if (typeof performance === "undefined") return null;
|
|
1139
|
+
const memory = performance.memory;
|
|
1140
|
+
if (!memory) return null;
|
|
1141
|
+
return {
|
|
1142
|
+
usedJSHeapSize: memory.usedJSHeapSize,
|
|
1143
|
+
totalJSHeapSize: memory.totalJSHeapSize,
|
|
1144
|
+
jsHeapSizeLimit: memory.jsHeapSizeLimit
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
function serializeMemoryUsage(usage) {
|
|
1148
|
+
const formatBytes = (bytes) => {
|
|
1149
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
1150
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
|
|
1151
|
+
return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
|
|
1152
|
+
};
|
|
1153
|
+
return `
|
|
1154
|
+
\u{1F4BE} \u5185\u5B58\u4F7F\u7528
|
|
1155
|
+
\u5DF2\u4F7F\u7528\u5806: ${formatBytes(usage.usedJSHeapSize)}
|
|
1156
|
+
\u603B\u5806\u5927\u5C0F: ${formatBytes(usage.totalJSHeapSize)}
|
|
1157
|
+
\u5806\u5927\u5C0F\u9650\u5236: ${formatBytes(usage.jsHeapSizeLimit)}
|
|
1158
|
+
\u4F7F\u7528\u7387: ${(usage.usedJSHeapSize / usage.totalJSHeapSize * 100).toFixed(2)}%
|
|
1159
|
+
`.trim();
|
|
1160
|
+
}
|
|
1161
|
+
function createRegressionDetector(threshold = 0.1) {
|
|
1162
|
+
const history = /* @__PURE__ */ new Map();
|
|
1163
|
+
return {
|
|
1164
|
+
addResult(result) {
|
|
1165
|
+
if (!history.has(result.name)) {
|
|
1166
|
+
history.set(result.name, []);
|
|
1167
|
+
}
|
|
1168
|
+
const results = history.get(result.name);
|
|
1169
|
+
results.push(result);
|
|
1170
|
+
if (results.length < 2) return false;
|
|
1171
|
+
const previous = results[results.length - 2];
|
|
1172
|
+
if (!previous) return false;
|
|
1173
|
+
const regression = previous.averageDuration < result.averageDuration && (result.averageDuration - previous.averageDuration) / previous.averageDuration > threshold;
|
|
1174
|
+
return regression;
|
|
1175
|
+
},
|
|
1176
|
+
getHistory(name) {
|
|
1177
|
+
return history.get(name) || [];
|
|
1178
|
+
},
|
|
1179
|
+
clear() {
|
|
1180
|
+
history.clear();
|
|
1181
|
+
}
|
|
1182
|
+
};
|
|
280
1183
|
}
|
|
281
1184
|
|
|
282
|
-
.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
1185
|
+
// src/devtools.ts
|
|
1186
|
+
var devtoolsInstance = null;
|
|
1187
|
+
var DevTools = class {
|
|
1188
|
+
constructor(options2 = {}) {
|
|
1189
|
+
this.isOpen = false;
|
|
1190
|
+
// API 方法
|
|
1191
|
+
this.getComponentTree = getComponentTree;
|
|
1192
|
+
this.getStoreStates = getStoreStates;
|
|
1193
|
+
this.getCurrentRoute = getCurrentRoute;
|
|
1194
|
+
this.options = {
|
|
1195
|
+
enabled: options2.enabled ?? true,
|
|
1196
|
+
position: options2.position ?? "right",
|
|
1197
|
+
size: options2.size ?? 300
|
|
1198
|
+
};
|
|
1199
|
+
if (this.options.enabled) {
|
|
1200
|
+
this.init();
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* 初始化 DevTools
|
|
1205
|
+
*/
|
|
1206
|
+
init() {
|
|
1207
|
+
if (typeof window === "undefined") return;
|
|
1208
|
+
this.createPanel();
|
|
1209
|
+
window.addEventListener("keydown", (e) => {
|
|
1210
|
+
if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === "D") {
|
|
1211
|
+
e.preventDefault();
|
|
1212
|
+
this.toggle();
|
|
1213
|
+
}
|
|
1214
|
+
});
|
|
1215
|
+
console.log("[LytJS DevTools] Initialized. Press Ctrl+Shift+D to toggle.");
|
|
1216
|
+
}
|
|
1217
|
+
/**
|
|
1218
|
+
* 创建 DevTools 面板
|
|
1219
|
+
*/
|
|
1220
|
+
createPanel() {
|
|
1221
|
+
if (typeof document === "undefined") return;
|
|
1222
|
+
if (document.getElementById("lytjs-devtools")) return;
|
|
1223
|
+
const panel = document.createElement("div");
|
|
1224
|
+
panel.id = "lytjs-devtools";
|
|
1225
|
+
panel.style.cssText = `
|
|
1226
|
+
position: fixed;
|
|
1227
|
+
top: 0;
|
|
1228
|
+
${this.options.position}: -${this.options.size}px;
|
|
1229
|
+
width: ${this.options.size}px;
|
|
1230
|
+
height: 100vh;
|
|
1231
|
+
background: #1e1e1e;
|
|
1232
|
+
color: #d4d4d4;
|
|
1233
|
+
font-family: 'Consolas', 'Monaco', monospace;
|
|
320
1234
|
font-size: 12px;
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
`,d.textContent=t.isUnmounted?"\u{1F480}":"\u{1F4E6}",l.appendChild(d);let u=document.createElement("span");u.style.cssText=`
|
|
324
|
-
flex: 1;
|
|
325
|
-
overflow: hidden;
|
|
326
|
-
text-overflow: ellipsis;
|
|
327
|
-
white-space: nowrap;
|
|
328
|
-
font-size: 12px;
|
|
329
|
-
color: ${s?"#cba6f7":"#cdd6f4"};
|
|
330
|
-
`,u.textContent=t.name,l.appendChild(u);let h=Object.keys(t.state).length;if(h>0){let m=document.createElement("span");m.className="lyt-devtools-badge lyt-devtools-badge-blue",m.textContent=`${h}`,m.title=`${h} \u4E2A\u72B6\u6001\u5C5E\u6027`,l.appendChild(m)}let f=Object.keys(t.computed).length;if(f>0){let m=document.createElement("span");m.className="lyt-devtools-badge lyt-devtools-badge-green",m.textContent=`C:${f}`,m.title=`${f} \u4E2A\u8BA1\u7B97\u5C5E\u6027`,m.style.marginLeft="3px",l.appendChild(m)}if(!t.isMounted&&!t.isUnmounted){let m=document.createElement("span");m.className="lyt-devtools-badge lyt-devtools-badge-yellow",m.textContent="\u672A\u6302\u8F7D",m.style.marginLeft="3px",l.appendChild(m)}else if(t.isUnmounted){let m=document.createElement("span");m.className="lyt-devtools-badge lyt-devtools-badge-red",m.textContent="\u5DF2\u5378\u8F7D",m.style.marginLeft="3px",l.appendChild(m)}if(l.addEventListener("click",m=>{m.stopPropagation(),c&&(this.expandedNodes.has(t.id)?this.expandedNodes.delete(t.id):this.expandedNodes.add(t.id)),W(t.id),this.onSelect(t.id),this.panel.highlightElement(t.el),this.renderTree()}),l.addEventListener("mouseenter",()=>{this.panel.highlightElement(t.el)}),l.addEventListener("mouseleave",()=>{var v;let m=k(),x=m?H(m):null;this.panel.highlightElement((v=x==null?void 0:x.el)!=null?v:null)}),r&&c){let m=j(t.id);for(let x of m){if(this.searchKeyword){let g=this.searchKeyword.toLowerCase(),b=x.name.toLowerCase().includes(g),T=x.id.toLowerCase().includes(g);if(!b&&!T)continue}let v={info:x,children:[],depth:n+1,expanded:this.expandedNodes.has(x.id)},y=this.renderTreeNode(v);y&&l.appendChild(y)}}return l}refresh(){this.renderTree()}destroy(){this.updateTimer&&clearTimeout(this.updateTimer),typeof window!="undefined"&&window.removeEventListener("lyt-devtools-update",this.onUpdate),this.container=null}};function je(i){return i===null?"null":i===void 0?"undefined":typeof i=="string"?"string":typeof i=="number"?"number":typeof i=="boolean"?"boolean":typeof i=="function"?"function":Array.isArray(i)?`Array[${i.length}]`:i instanceof Date?"Date":i instanceof RegExp?"RegExp":typeof i=="object"?"Object":typeof i}function he(i,e=80){if(i===null)return"null";if(i===void 0)return"undefined";if(typeof i=="string")return i.length>e?`"${i.slice(0,e)}..."`:`"${i}"`;if(typeof i=="function")return`fn(${i.name||"anonymous"})`;if(typeof i=="object")try{let t=JSON.stringify(i);return t.length>e?`${t.slice(0,e)}...`:t}catch(t){return"[Object]"}return String(i)}function Se(i){return i!==null&&typeof i=="object"&&!(i instanceof Date)&&!(i instanceof RegExp)}var B=class{constructor(e){this.container=null;this.expandedPaths=new Set;this.changedPaths=new Map;this.highlightTimer=null;this.showHistory=!1;this.updateTimer=null;this.onUpdate=()=>{this.updateTimer&&clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.renderState()},150)};this.panel=e,typeof window!="undefined"&&window.addEventListener("lyt-devtools-update",this.onUpdate)}render(e){this.container=e,this.renderState()}renderState(){if(!this.container)return;this.container.innerHTML="";let e=Y();if(!e){let p=document.createElement("div");p.className="lyt-devtools-empty",p.textContent="\u8BF7\u5148\u5728\u7EC4\u4EF6\u6811\u4E2D\u9009\u62E9\u4E00\u4E2A\u7EC4\u4EF6\u3002",this.container.appendChild(p);return}let t=document.createElement("div");t.style.cssText=`
|
|
1235
|
+
z-index: 999999;
|
|
1236
|
+
transition: ${this.options.position} 0.3s ease;
|
|
331
1237
|
display: flex;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
background: ${this.showHistory?"#cba6f7":"transparent"};
|
|
341
|
-
color: ${this.showHistory?"#1e1e2e":"#a6adc8"};
|
|
342
|
-
border: 1px solid ${this.showHistory?"#cba6f7":"#313244"};
|
|
343
|
-
padding: 2px 8px;
|
|
344
|
-
border-radius: 3px;
|
|
345
|
-
cursor: pointer;
|
|
346
|
-
font-size: 11px;
|
|
347
|
-
font-family: inherit;
|
|
348
|
-
`,r.textContent="\u53D8\u5316\u5386\u53F2",r.addEventListener("click",()=>{this.showHistory=!this.showHistory,this.renderState()}),t.appendChild(n),t.appendChild(r),this.container.appendChild(t),this.showHistory?this.renderHistory(e):(this.renderCategory(this.container,"props",e.props,!0,!1,!1),this.renderCategory(this.container,"state",e.state,!1,!0,!1),this.renderCategory(this.container,"computed",e.computed,!1,!1,!0));let o=Object.keys(e.state).length,s=Object.keys(e.props).length,l=Object.keys(e.computed).length;this.panel.setStatusLeft(`<span class="lyt-devtools-status-dot"></span><span>${e.name}</span><span style="color: #585b70;">|</span><span>P:${s} S:${o} C:${l}</span>`)}renderCategory(e,t,n,r,o,s){let l=Object.keys(n);if(l.length===0)return;let p=document.createElement("div");p.style.cssText=`
|
|
1238
|
+
flex-direction: column;
|
|
1239
|
+
box-shadow: 2px 0 8px rgba(0,0,0,0.3);
|
|
1240
|
+
`;
|
|
1241
|
+
const header = document.createElement("div");
|
|
1242
|
+
header.style.cssText = `
|
|
1243
|
+
padding: 10px 15px;
|
|
1244
|
+
background: #2d2d2d;
|
|
1245
|
+
border-bottom: 1px solid #3d3d3d;
|
|
349
1246
|
display: flex;
|
|
1247
|
+
justify-content: space-between;
|
|
350
1248
|
align-items: center;
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
${o?'<span style="color: #585b70; margin-left: 6px; font-size: 10px;">[\u54CD\u5E94\u5F0F]</span>':""}
|
|
365
|
-
${s?'<span style="color: #585b70; margin-left: 6px; font-size: 10px;">[\u7F13\u5B58]</span>':""}
|
|
366
|
-
`,e.appendChild(p);for(let d of l){let u=n[d],h=`${t}.${d}`,f=this.changedPaths.has(h),m=Se(u);this.renderProperty(e,{key:d,value:u,category:t,isReactive:o,isCached:s,isReadonly:r},h,0,m)}}renderProperty(e,t,n,r,o){let s=document.createElement("div");s.style.cssText=`
|
|
1249
|
+
`;
|
|
1250
|
+
header.innerHTML = `
|
|
1251
|
+
<span style="font-weight: bold; color: #4fc08d;">\u{1F6E0}\uFE0F LytJS DevTools</span>
|
|
1252
|
+
<button id="lytjs-devtools-close" style="
|
|
1253
|
+
background: transparent;
|
|
1254
|
+
border: none;
|
|
1255
|
+
color: #d4d4d4;
|
|
1256
|
+
cursor: pointer;
|
|
1257
|
+
font-size: 16px;
|
|
1258
|
+
">\u2715</button>
|
|
1259
|
+
`;
|
|
1260
|
+
const tabs = document.createElement("div");
|
|
1261
|
+
tabs.style.cssText = `
|
|
367
1262
|
display: flex;
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
width: 14px;
|
|
379
|
-
height: 14px;
|
|
380
|
-
font-size: 9px;
|
|
381
|
-
color: #6c7086;
|
|
382
|
-
flex-shrink: 0;
|
|
383
|
-
transition: transform 0.15s ease;
|
|
384
|
-
${o?"":"visibility: hidden;"}
|
|
385
|
-
${this.expandedPaths.has(n)?"transform: rotate(90deg);":""}
|
|
386
|
-
`,p.textContent="\u25B6",s.appendChild(p);let c=document.createElement("span");c.style.cssText=`
|
|
387
|
-
color: #89b4fa;
|
|
388
|
-
margin-right: 6px;
|
|
389
|
-
flex-shrink: 0;
|
|
390
|
-
font-size: 12px;
|
|
391
|
-
min-width: 60px;
|
|
392
|
-
`,c.textContent=t.key,s.appendChild(c);let a=document.createElement("span");a.style.cssText="color: #6c7086; margin-right: 6px; flex-shrink: 0;",a.textContent=":",s.appendChild(a);let d=document.createElement("span"),u=je(t.value),h={string:"#a6e3a1",number:"#fab387",boolean:"#89b4fa",null:"#6c7086",undefined:"#6c7086",function:"#cba6f7",Object:"#cdd6f4",Array:"#f9e2af",Date:"#f38ba8",RegExp:"#f38ba8"};d.style.cssText=`
|
|
393
|
-
color: ${h[u]||"#cdd6f4"};
|
|
394
|
-
font-size: 12px;
|
|
395
|
-
flex: 1;
|
|
396
|
-
overflow: hidden;
|
|
397
|
-
text-overflow: ellipsis;
|
|
398
|
-
white-space: nowrap;
|
|
399
|
-
cursor: ${t.isReadonly?"default":"text"};
|
|
400
|
-
`,d.textContent=he(t.value),s.appendChild(d);let f=document.createElement("span");if(f.style.cssText=`
|
|
401
|
-
color: #585b70;
|
|
402
|
-
font-size: 10px;
|
|
403
|
-
flex-shrink: 0;
|
|
404
|
-
margin-left: 6px;
|
|
405
|
-
`,f.textContent=u,s.appendChild(f),o&&s.addEventListener("click",m=>{m.stopPropagation(),this.expandedPaths.has(n)?this.expandedPaths.delete(n):this.expandedPaths.add(n),this.renderState()}),!t.isReadonly&&t.category==="state"&&d.addEventListener("dblclick",m=>{m.stopPropagation(),this.startEdit(s,t,n,d)}),e.appendChild(s),o&&this.expandedPaths.has(n)){let m=t.value,x=Object.keys(m);for(let v of x){let y=`${n}.${v}`,g=m[v],b=Se(g);this.renderProperty(e,{key:v,value:g,category:t.category,isReactive:t.isReactive,isCached:t.isCached,isReadonly:t.isReadonly},y,r+1,b)}}}startEdit(e,t,n,r){let o=k();if(!o)return;let s=document.createElement("input");s.type="text",s.style.cssText=`
|
|
406
|
-
background: #181825;
|
|
407
|
-
border: 1px solid #cba6f7;
|
|
408
|
-
color: #cdd6f4;
|
|
409
|
-
font-size: 12px;
|
|
410
|
-
font-family: inherit;
|
|
411
|
-
padding: 1px 4px;
|
|
412
|
-
border-radius: 2px;
|
|
413
|
-
outline: none;
|
|
414
|
-
width: 100%;
|
|
415
|
-
box-sizing: border-box;
|
|
416
|
-
`;let l;typeof t.value=="string"?(l=t.value,s.value=t.value):(l=JSON.stringify(t.value),s.value=l),r.style.display="none",e.insertBefore(s,r.nextSibling),s.focus(),s.select();let p=()=>{let a,d=s.value;try{a=JSON.parse(d)}catch(h){a=d}let u=n.replace(/^state\./,"");K(o,u,a),s.remove(),r.style.display="",this.renderState()},c=()=>{s.remove(),r.style.display=""};s.addEventListener("keydown",a=>{a.key==="Enter"?(a.preventDefault(),p()):a.key==="Escape"&&(a.preventDefault(),c())}),s.addEventListener("blur",()=>{p()})}renderHistory(e){let t=V(e.id);if(t.length===0){let o=document.createElement("div");o.className="lyt-devtools-empty",o.textContent="\u6682\u65E0\u72B6\u6001\u53D8\u5316\u8BB0\u5F55\u3002",this.container.appendChild(o);return}let n=document.createElement("div");n.style.cssText="max-height: 400px; overflow-y: auto;";let r=[...t].reverse();for(let o=0;o<r.length;o++){let s=r[o],l=document.createElement("div");l.style.cssText=`
|
|
417
|
-
padding: 6px 8px;
|
|
418
|
-
border-bottom: 1px solid #313244;
|
|
419
|
-
font-size: 11px;
|
|
420
|
-
cursor: default;
|
|
421
|
-
transition: background 0.1s ease;
|
|
422
|
-
`,l.addEventListener("mouseenter",()=>{l.style.background="rgba(69, 71, 90, 0.3)"}),l.addEventListener("mouseleave",()=>{l.style.background=""});let p=new Date(s.timestamp).toLocaleTimeString();l.innerHTML=`
|
|
423
|
-
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 3px;">
|
|
424
|
-
<span style="color: #89b4fa; font-weight: 600;">${s.path}</span>
|
|
425
|
-
<span style="color: #585b70;">${p}</span>
|
|
426
|
-
</div>
|
|
427
|
-
<div style="display: flex; align-items: center; gap: 6px;">
|
|
428
|
-
<span style="color: #f38ba8; text-decoration: line-through; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 140px;">${he(s.oldValue,40)}</span>
|
|
429
|
-
<span style="color: #6c7086;">\u2192</span>
|
|
430
|
-
<span style="color: #a6e3a1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 140px;">${he(s.newValue,40)}</span>
|
|
431
|
-
</div>
|
|
432
|
-
`,n.appendChild(l)}this.container.appendChild(n)}markChanged(e){this.changedPaths.set(e,Date.now()),this.highlightTimer&&clearTimeout(this.highlightTimer),this.highlightTimer=setTimeout(()=>{this.changedPaths.clear(),this.renderState()},3e3)}refresh(){this.renderState()}destroy(){this.updateTimer&&clearTimeout(this.updateTimer),this.highlightTimer&&clearTimeout(this.highlightTimer),typeof window!="undefined"&&window.removeEventListener("lyt-devtools-update",this.onUpdate),this.container=null,this.expandedPaths.clear(),this.changedPaths.clear()}};function Je(i,e=60){if(i===null)return"null";if(i===void 0)return"undefined";if(typeof i=="string")return i.length>e?`"${i.slice(0,e)}..."`:`"${i}"`;if(typeof i=="function")return`fn(${i.name||"anonymous"})`;if(typeof i=="object")try{let t=JSON.stringify(i);return t.length>e?`${t.slice(0,e)}...`:t}catch(t){return"[Object]"}return String(i)}function Re(i){let e=new Date(i);return e.toLocaleTimeString("zh-CN",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})+`.${String(e.getMilliseconds()).padStart(3,"0")}`}function Ve(i){let t=Date.now()-i;return t<1e3?`${t}ms \u524D`:t<6e4?`${Math.floor(t/1e3)}s \u524D`:`${Math.floor(t/6e4)}m \u524D`}var z=class{constructor(e){this.container=null;this.nameFilter="";this.componentFilter="";this.paused=!1;this.selectedEventId=null;this.updateTimer=null;this.autoScrollTimer=null;this.onUpdate=()=>{this.paused||(this.updateTimer&&clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.renderEvents()},100))};this.panel=e,typeof window!="undefined"&&window.addEventListener("lyt-devtools-update",this.onUpdate)}render(e){this.container=e,this.renderEvents()}renderEvents(){if(!this.container)return;this.container.innerHTML="";let e=document.createElement("div");e.style.cssText="display: flex; gap: 6px; margin-bottom: 8px; align-items: center;";let t=document.createElement("input");t.type="text",t.className="lyt-devtools-search",t.placeholder="\u6309\u4E8B\u4EF6\u540D\u79F0\u8FC7\u6EE4...",t.value=this.nameFilter,t.style.marginBottom="0",t.style.flex="1",t.addEventListener("input",a=>{this.nameFilter=a.target.value,this.renderEvents()}),e.appendChild(t);let n=document.createElement("input");n.type="text",n.className="lyt-devtools-search",n.placeholder="\u6309\u7EC4\u4EF6\u8FC7\u6EE4...",n.value=this.componentFilter,n.style.marginBottom="0",n.style.flex="1",n.addEventListener("input",a=>{this.componentFilter=a.target.value,this.renderEvents()}),e.appendChild(n);let r=document.createElement("button");r.style.cssText=`
|
|
433
|
-
background: ${this.paused?"#f38ba8":"transparent"};
|
|
434
|
-
color: ${this.paused?"#1e1e2e":"#a6adc8"};
|
|
435
|
-
border: 1px solid ${this.paused?"#f38ba8":"#313244"};
|
|
436
|
-
padding: 4px 8px;
|
|
437
|
-
border-radius: 4px;
|
|
438
|
-
cursor: pointer;
|
|
439
|
-
font-size: 11px;
|
|
440
|
-
font-family: inherit;
|
|
441
|
-
white-space: nowrap;
|
|
442
|
-
flex-shrink: 0;
|
|
443
|
-
`,r.textContent=this.paused?"\u7EE7\u7EED":"\u6682\u505C",r.addEventListener("click",()=>{this.paused=!this.paused,this.renderEvents()}),e.appendChild(r);let o=document.createElement("button");o.style.cssText=`
|
|
444
|
-
background: transparent;
|
|
445
|
-
color: #a6adc8;
|
|
446
|
-
border: 1px solid #313244;
|
|
447
|
-
padding: 4px 8px;
|
|
448
|
-
border-radius: 4px;
|
|
449
|
-
cursor: pointer;
|
|
450
|
-
font-size: 11px;
|
|
451
|
-
font-family: inherit;
|
|
452
|
-
white-space: nowrap;
|
|
453
|
-
flex-shrink: 0;
|
|
454
|
-
`,o.textContent="\u6E05\u7A7A",o.addEventListener("click",()=>{this.clearEvents()}),e.appendChild(o),this.container.appendChild(e);let s=J();if(this.nameFilter){let a=this.nameFilter.toLowerCase();s=s.filter(d=>d.name.toLowerCase().includes(a))}if(this.componentFilter){let a=this.componentFilter.toLowerCase();s=s.filter(d=>d.componentName.toLowerCase().includes(a))}if(this.panel.setStatusLeft(`<span class="lyt-devtools-status-dot"></span><span>${s.length} \u4E2A\u4E8B\u4EF6${this.paused?" (\u5DF2\u6682\u505C)":""}</span>`),s.length===0){let a=document.createElement("div");a.className="lyt-devtools-empty",a.textContent=this.nameFilter||this.componentFilter?"\u6CA1\u6709\u5339\u914D\u7684\u4E8B\u4EF6\u8BB0\u5F55\u3002":"\u6682\u65E0\u4E8B\u4EF6\u8BB0\u5F55\uFF0C\u7B49\u5F85\u7EC4\u4EF6\u89E6\u53D1\u4E8B\u4EF6...",this.container.appendChild(a);return}if(this.selectedEventId){let a=s.find(d=>d.id===this.selectedEventId);a&&this.renderEventDetail(a)}let l=document.createElement("div");l.style.cssText="max-height: 360px; overflow-y: auto;";let p=[...s].reverse(),c=Math.min(p.length,200);for(let a=0;a<c;a++){let d=p[a],u=d.id===this.selectedEventId,h=document.createElement("div");h.style.cssText=`
|
|
455
|
-
display: flex;
|
|
456
|
-
align-items: center;
|
|
457
|
-
padding: 4px 8px;
|
|
458
|
-
border-bottom: 1px solid rgba(49, 50, 68, 0.5);
|
|
1263
|
+
background: #252526;
|
|
1264
|
+
border-bottom: 1px solid #3d3d3d;
|
|
1265
|
+
`;
|
|
1266
|
+
tabs.innerHTML = `
|
|
1267
|
+
<button class="lytjs-devtools-tab active" data-tab="components" style="
|
|
1268
|
+
flex: 1;
|
|
1269
|
+
padding: 10px;
|
|
1270
|
+
background: #1e1e1e;
|
|
1271
|
+
border: none;
|
|
1272
|
+
color: #d4d4d4;
|
|
459
1273
|
cursor: pointer;
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
`,h.addEventListener("mouseenter",()=>{u||(h.style.background="rgba(69, 71, 90, 0.3)")}),h.addEventListener("mouseleave",()=>{u||(h.style.background="")});let f=document.createElement("span");f.style.cssText="color: #585b70; margin-right: 8px; flex-shrink: 0; font-size: 10px;",f.textContent=Re(d.timestamp),h.appendChild(f);let m=document.createElement("span");m.style.cssText=`
|
|
464
|
-
color: #f9e2af;
|
|
465
|
-
font-weight: 600;
|
|
466
|
-
margin-right: 8px;
|
|
467
|
-
flex-shrink: 0;
|
|
468
|
-
max-width: 120px;
|
|
469
|
-
overflow: hidden;
|
|
470
|
-
text-overflow: ellipsis;
|
|
471
|
-
white-space: nowrap;
|
|
472
|
-
`,m.textContent=d.name,m.title=d.name,h.appendChild(m);let x=document.createElement("span");x.style.cssText=`
|
|
473
|
-
color: #89b4fa;
|
|
474
|
-
margin-right: 8px;
|
|
475
|
-
flex-shrink: 0;
|
|
476
|
-
max-width: 80px;
|
|
477
|
-
overflow: hidden;
|
|
478
|
-
text-overflow: ellipsis;
|
|
479
|
-
white-space: nowrap;
|
|
480
|
-
`,x.textContent=d.componentName,x.title=d.componentName,h.appendChild(x);let v=d.args.map(b=>Je(b,30)).join(", "),y=document.createElement("span");y.style.cssText=`
|
|
481
|
-
color: #6c7086;
|
|
1274
|
+
border-bottom: 2px solid #4fc08d;
|
|
1275
|
+
">Components</button>
|
|
1276
|
+
<button class="lytjs-devtools-tab" data-tab="store" style="
|
|
482
1277
|
flex: 1;
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
`,y.textContent=d.args.length>0?`(${v})`:"()",y.title=d.args.length>0?v:"\u65E0\u53C2\u6570",h.appendChild(y);let g=document.createElement("span");g.style.cssText="color: #45475a; flex-shrink: 0; font-size: 10px; margin-left: 4px;",g.textContent=Ve(d.timestamp),h.appendChild(g),h.addEventListener("click",()=>{this.selectedEventId===d.id?this.selectedEventId=null:this.selectedEventId=d.id,this.renderEvents()}),l.appendChild(h)}if(p.length>c){let a=document.createElement("div");a.style.cssText="padding: 6px 8px; text-align: center; color: #585b70; font-size: 11px;",a.textContent=`\u8FD8\u6709 ${p.length-c} \u6761\u8BB0\u5F55\u672A\u663E\u793A...`,l.appendChild(a)}this.container.appendChild(l)}renderEventDetail(e){let t=document.createElement("div");t.style.cssText=`
|
|
488
|
-
background: #181825;
|
|
489
|
-
border: 1px solid #313244;
|
|
490
|
-
border-radius: 4px;
|
|
491
|
-
padding: 8px;
|
|
492
|
-
margin-bottom: 8px;
|
|
493
|
-
`;let n=document.createElement("div");n.style.cssText="display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px;";let r=document.createElement("span");r.style.cssText="font-weight: 600; color: #f9e2af; font-size: 12px;",r.textContent=`\u4E8B\u4EF6: ${e.name}`;let o=document.createElement("span");o.style.cssText="cursor: pointer; color: #6c7086; font-size: 14px;",o.textContent="\u2715",o.addEventListener("click",()=>{this.selectedEventId=null,this.renderEvents()}),n.appendChild(r),n.appendChild(o),t.appendChild(n);let s=document.createElement("div");if(s.style.cssText="display: flex; gap: 12px; margin-bottom: 6px; font-size: 11px;",s.innerHTML=`
|
|
494
|
-
<span><span style="color: #6c7086;">\u6765\u6E90\u7EC4\u4EF6:</span> <span style="color: #89b4fa;">${e.componentName}</span></span>
|
|
495
|
-
<span><span style="color: #6c7086;">\u7EC4\u4EF6 ID:</span> <span style="color: #585b70;">${e.componentId}</span></span>
|
|
496
|
-
<span><span style="color: #6c7086;">\u65F6\u95F4:</span> <span style="color: #585b70;">${Re(e.timestamp)}</span></span>
|
|
497
|
-
`,t.appendChild(s),e.args.length>0){let l=document.createElement("div");l.style.cssText="color: #6c7086; font-size: 11px; margin-bottom: 4px; font-weight: 600;",l.textContent=`\u53C2\u6570 (${e.args.length}):`,t.appendChild(l);for(let p=0;p<e.args.length;p++){let c=document.createElement("div");c.style.cssText=`
|
|
498
|
-
padding: 3px 8px;
|
|
499
|
-
background: #1e1e2e;
|
|
500
|
-
border-radius: 2px;
|
|
501
|
-
margin-bottom: 2px;
|
|
502
|
-
font-size: 11px;
|
|
503
|
-
font-family: 'SF Mono', 'Monaco', 'Menlo', 'Consolas', monospace;
|
|
504
|
-
`;let a=e.args[p],d=typeof a,u;try{u=JSON.stringify(a,null,2)}catch(h){u=String(a)}u.length>500&&(u=u.slice(0,500)+`
|
|
505
|
-
... (\u5DF2\u622A\u65AD)`),c.innerHTML=`
|
|
506
|
-
<span style="color: #6c7086;">[${p}]</span>
|
|
507
|
-
<span style="color: #585b70; margin: 0 4px;">${d}:</span>
|
|
508
|
-
<span style="color: #a6e3a1; white-space: pre-wrap; word-break: break-all;">${this.escapeHtml(u)}</span>
|
|
509
|
-
`,t.appendChild(c)}}else{let l=document.createElement("div");l.style.cssText="color: #585b70; font-size: 11px; font-style: italic;",l.textContent="\u6B64\u4E8B\u4EF6\u65E0\u53C2\u6570\u3002",t.appendChild(l)}this.container.appendChild(t)}escapeHtml(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}clearEvents(){this.selectedEventId=null,this.renderEvents()}setPaused(e){this.paused=e}isPaused(){return this.paused}refresh(){this.renderEvents()}destroy(){this.updateTimer&&clearTimeout(this.updateTimer),this.autoScrollTimer&&clearInterval(this.autoScrollTimer),typeof window!="undefined"&&window.removeEventListener("lyt-devtools-update",this.onUpdate),this.container=null}};function P(i){if(i===null||typeof i!="object")return i;if(i instanceof Map){let t=new Map;for(let[n,r]of i)t.set(n,P(r));return t}if(Array.isArray(i))return i.map(t=>P(t));let e={};for(let t of Object.keys(i))e[t]=P(i[t]);return e}function We(i){let e=new Date(i);return e.toLocaleTimeString("zh-CN",{hour12:!1,hour:"2-digit",minute:"2-digit",second:"2-digit"})+`.${String(e.getMilliseconds()).padStart(3,"0")}`}var N=class{constructor(e){this.container=null;this.snapshots=[];this.snapshotCounter=0;this.maxSnapshots=100;this.currentIndex=-1;this.playState="stopped";this.playSpeed=500;this.playTimer=null;this.autoSnapshot=!0;this.updateTimer=null;this.onUpdate=()=>{this.autoSnapshot&&(this.updateTimer&&clearTimeout(this.updateTimer),this.updateTimer=setTimeout(()=>{this.takeSnapshot("\u81EA\u52A8\u5FEB\u7167")},300))};this.panel=e,typeof window!="undefined"&&window.addEventListener("lyt-devtools-update",this.onUpdate)}takeSnapshot(e,t){let n=L(),r=new Map;for(let s of n)r.set(s.id,{id:s.id,name:s.name,state:P(s.state),props:P(s.props),computed:P(s.computed),isMounted:s.isMounted});let o={id:++this.snapshotCounter,timestamp:Date.now(),description:e||`\u5FEB\u7167 #${this.snapshotCounter}`,components:r,trigger:t};return this.snapshots.push(o),this.snapshots.length>this.maxSnapshots&&this.snapshots.splice(0,this.snapshots.length-this.maxSnapshots),(this.currentIndex===-1||this.currentIndex===this.snapshots.length-2)&&(this.currentIndex=this.snapshots.length-1),o}getSnapshots(){return[...this.snapshots]}getSnapshot(e){var t;return(t=this.snapshots[e])!=null?t:null}getCurrentIndex(){return this.currentIndex}clearSnapshots(){this.snapshots=[],this.snapshotCounter=0,this.currentIndex=-1,this.stopPlayback(),this.renderTimeTravel()}setAutoSnapshot(e){this.autoSnapshot=e}travelTo(e){e<0||e>=this.snapshots.length||(this.currentIndex=e,this.renderTimeTravel())}stepBack(){this.currentIndex>0&&this.travelTo(this.currentIndex-1)}stepForward(){this.currentIndex<this.snapshots.length-1&&this.travelTo(this.currentIndex+1)}goToLatest(){this.currentIndex=-1,this.stopPlayback(),this.renderTimeTravel()}restoreSnapshot(e){let t=this.snapshots[e];if(!t)return!1;for(let[n,r]of t.components){let o=H(n);if(!(!o||!o.instance)&&o.instance.state&&typeof o.instance.state=="object"){let s=Object.keys(r.state);for(let l of s)try{o.instance.state[l]=P(r.state[l])}catch(p){}}}return!0}startPlayback(){this.playState!=="playing"&&((this.currentIndex===-1||this.currentIndex>=this.snapshots.length-1)&&(this.currentIndex=0),this.playState="playing",this.renderTimeTravel(),this.playTimer=setInterval(()=>{this.currentIndex<this.snapshots.length-1?(this.currentIndex++,this.renderTimeTravel()):this.stopPlayback()},this.playSpeed))}pausePlayback(){this.playState==="playing"&&(this.playState="paused",this.playTimer&&(clearInterval(this.playTimer),this.playTimer=null),this.renderTimeTravel())}stopPlayback(){this.playState="stopped",this.playTimer&&(clearInterval(this.playTimer),this.playTimer=null),this.renderTimeTravel()}setPlaySpeed(e){this.playSpeed=e,this.playState==="playing"&&(this.pausePlayback(),this.startPlayback())}getPlayState(){return this.playState}render(e){this.container=e,this.renderTimeTravel()}renderTimeTravel(){if(!this.container)return;this.container.innerHTML="";let e=document.createElement("div");e.style.cssText="display: flex; gap: 4px; margin-bottom: 8px; align-items: center; flex-wrap: wrap;";let t=document.createElement("button");t.style.cssText=this.createButtonStyle("#a6e3a1","#1e1e2e"),t.textContent="\u{1F4F8} \u5FEB\u7167",t.title="\u624B\u52A8\u521B\u5EFA\u5FEB\u7167",t.addEventListener("click",()=>{this.takeSnapshot("\u624B\u52A8\u5FEB\u7167"),this.renderTimeTravel()}),e.appendChild(t);let n=document.createElement("button");n.style.cssText=this.createButtonStyle("#89b4fa","#1e1e2e"),n.textContent="\u{1F504} \u6700\u65B0",n.title="\u56DE\u5230\u6700\u65B0\u72B6\u6001",n.addEventListener("click",()=>{this.goToLatest()}),e.appendChild(n);let r=document.createElement("button");r.style.cssText=this.createButtonStyle("#f38ba8","#1e1e2e"),r.textContent="\u{1F5D1} \u6E05\u7A7A",r.title="\u6E05\u7A7A\u6240\u6709\u5FEB\u7167",r.addEventListener("click",()=>{this.clearSnapshots()}),e.appendChild(r);let o=document.createElement("label");o.style.cssText="display: flex; align-items: center; gap: 4px; font-size: 11px; color: #a6adc8; margin-left: 8px; cursor: pointer;";let s=document.createElement("input");s.type="checkbox",s.checked=this.autoSnapshot,s.style.cssText="cursor: pointer;",s.addEventListener("change",()=>{this.autoSnapshot=s.checked}),o.appendChild(s),o.appendChild(document.createTextNode("\u81EA\u52A8\u5FEB\u7167")),e.appendChild(o),this.container.appendChild(e),this.snapshots.length>0&&this.renderPlaybackControls(this.container),this.renderSnapshotList(this.container);let l=this.currentIndex===-1;this.panel.setStatusLeft(`<span class="lyt-devtools-status-dot"></span><span>${this.snapshots.length} \u4E2A\u5FEB\u7167</span><span style="color: #585b70;">|</span><span>${l?"\u5B9E\u65F6":`\u5386\u53F2 #${this.currentIndex+1}`}</span>`)}renderPlaybackControls(e){let t=document.createElement("div");t.style.cssText=`
|
|
510
|
-
display: flex;
|
|
511
|
-
align-items: center;
|
|
512
|
-
gap: 6px;
|
|
513
|
-
padding: 8px;
|
|
514
|
-
background: #181825;
|
|
515
|
-
border: 1px solid #313244;
|
|
516
|
-
border-radius: 4px;
|
|
517
|
-
margin-bottom: 8px;
|
|
518
|
-
`;let n=document.createElement("button");n.style.cssText=this.createSmallButtonStyle(),n.textContent="\u23EE",n.title="\u6B65\u9000",n.disabled=this.currentIndex<=0,n.addEventListener("click",()=>this.stepBack()),t.appendChild(n);let r=document.createElement("button");r.style.cssText=this.createSmallButtonStyle(),this.playState==="playing"?(r.textContent="\u23F8",r.title="\u6682\u505C",r.addEventListener("click",()=>this.pausePlayback())):(r.textContent="\u25B6",r.title="\u64AD\u653E",r.addEventListener("click",()=>this.startPlayback())),t.appendChild(r);let o=document.createElement("button");o.style.cssText=this.createSmallButtonStyle(),o.textContent="\u23F9",o.title="\u505C\u6B62",o.disabled=this.playState==="stopped",o.addEventListener("click",()=>this.stopPlayback()),t.appendChild(o);let s=document.createElement("button");s.style.cssText=this.createSmallButtonStyle(),s.textContent="\u23ED",s.title="\u6B65\u8FDB",s.disabled=this.currentIndex>=this.snapshots.length-1,s.addEventListener("click",()=>this.stepForward()),t.appendChild(s);let l=document.createElement("input");l.type="range",l.min="0",l.max=String(Math.max(0,this.snapshots.length-1)),l.value=String(Math.max(0,this.currentIndex)),l.style.cssText=`
|
|
519
|
-
flex: 1;
|
|
520
|
-
height: 4px;
|
|
521
|
-
-webkit-appearance: none;
|
|
522
|
-
appearance: none;
|
|
523
|
-
background: #313244;
|
|
524
|
-
border-radius: 2px;
|
|
525
|
-
outline: none;
|
|
526
|
-
cursor: pointer;
|
|
527
|
-
`,l.addEventListener("input",d=>{let u=parseInt(d.target.value,10);this.travelTo(u)}),t.appendChild(l);let p=document.createElement("select");p.style.cssText=`
|
|
528
|
-
background: #1e1e2e;
|
|
529
|
-
color: #cdd6f4;
|
|
530
|
-
border: 1px solid #313244;
|
|
531
|
-
border-radius: 3px;
|
|
532
|
-
padding: 2px 4px;
|
|
533
|
-
font-size: 11px;
|
|
534
|
-
font-family: inherit;
|
|
535
|
-
cursor: pointer;
|
|
536
|
-
outline: none;
|
|
537
|
-
`;let c=[{value:200,label:"0.5x"},{value:500,label:"1x"},{value:1e3,label:"2x"},{value:2e3,label:"4x"}];for(let d of c){let u=document.createElement("option");u.value=String(d.value),u.textContent=d.label,d.value===this.playSpeed&&(u.selected=!0),p.appendChild(u)}p.addEventListener("change",d=>{this.setPlaySpeed(parseInt(d.target.value,10))}),t.appendChild(p);let a=document.createElement("span");a.style.cssText="color: #6c7086; font-size: 11px; flex-shrink: 0; min-width: 40px; text-align: right;",a.textContent=this.currentIndex===-1?`--/${this.snapshots.length}`:`${this.currentIndex+1}/${this.snapshots.length}`,t.appendChild(a),e.appendChild(t)}renderSnapshotList(e){if(this.snapshots.length===0){let r=document.createElement("div");r.className="lyt-devtools-empty",r.textContent='\u6682\u65E0\u5FEB\u7167\u3002\u70B9\u51FB"\u5FEB\u7167"\u6309\u94AE\u624B\u52A8\u521B\u5EFA\uFF0C\u6216\u5F00\u542F"\u81EA\u52A8\u5FEB\u7167"\u3002',e.appendChild(r);return}let t=document.createElement("div");t.style.cssText="max-height: 300px; overflow-y: auto;";let n=[...this.snapshots].reverse();for(let r=n.length-1;r>=0;r--){let o=n[r],s=this.snapshots.indexOf(o),l=s===this.currentIndex,p=document.createElement("div");p.style.cssText=`
|
|
538
|
-
display: flex;
|
|
539
|
-
align-items: center;
|
|
540
|
-
padding: 4px 8px;
|
|
541
|
-
border-bottom: 1px solid rgba(49, 50, 68, 0.5);
|
|
1278
|
+
padding: 10px;
|
|
1279
|
+
background: transparent;
|
|
1280
|
+
border: none;
|
|
1281
|
+
color: #d4d4d4;
|
|
542
1282
|
cursor: pointer;
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
1283
|
+
border-bottom: 2px solid transparent;
|
|
1284
|
+
">Store</button>
|
|
1285
|
+
<button class="lytjs-devtools-tab" data-tab="router" style="
|
|
1286
|
+
flex: 1;
|
|
1287
|
+
padding: 10px;
|
|
1288
|
+
background: transparent;
|
|
1289
|
+
border: none;
|
|
1290
|
+
color: #d4d4d4;
|
|
548
1291
|
cursor: pointer;
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
`}refresh(){this.renderTimeTravel()}destroy(){this.stopPlayback(),this.updateTimer&&clearTimeout(this.updateTimer),typeof window!="undefined"&&window.removeEventListener("lyt-devtools-update",this.onUpdate),this.container=null,this.snapshots=[]}};var Z=class{constructor(e,t){this.history=[];this.currentPath="/";this.currentParams={};this.currentQuery={};var n;this.container=e,this.maxHistory=(n=t==null?void 0:t.maxHistory)!=null?n:50,this.render()}updateRoute(e,t,n){this.history.push({path:e,params:t?{...t}:void 0,query:n?{...n}:void 0,timestamp:Date.now()}),this.history.length>this.maxHistory&&this.history.shift(),this.currentPath=e,this.currentParams=t?{...t}:{},this.currentQuery=n?{...n}:{},this.render()}getHistory(){return[...this.history].reverse()}getCurrentPath(){return this.currentPath}clearHistory(){this.history=[],this.render()}render(){this.container.innerHTML="";let e=document.createElement("div");e.style.cssText="margin-bottom: 16px;";let t=document.createElement("div");t.style.cssText="font-size: 11px; color: #a6adc8; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px;",t.textContent="Current Route",e.appendChild(t);let n=document.createElement("div");n.style.cssText="display: flex; align-items: center; gap: 8px; margin-bottom: 6px;";let r=document.createElement("span");r.style.cssText="color: #585b70; font-size: 11px; min-width: 50px;",r.textContent="Path:";let o=document.createElement("span");if(o.style.cssText="color: #cba6f7; font-size: 13px; font-weight: 600;",o.textContent=this.currentPath||"/",n.appendChild(r),n.appendChild(o),e.appendChild(n),Object.keys(this.currentParams).length>0){let c=document.createElement("div");c.style.cssText="display: flex; align-items: flex-start; gap: 8px; margin-bottom: 6px;";let a=document.createElement("span");a.style.cssText="color: #585b70; font-size: 11px; min-width: 50px;",a.textContent="Params:";let d=document.createElement("span");d.style.cssText="color: #a6e3a1; font-size: 12px;",d.textContent=JSON.stringify(this.currentParams),c.appendChild(a),c.appendChild(d),e.appendChild(c)}if(Object.keys(this.currentQuery).length>0){let c=document.createElement("div");c.style.cssText="display: flex; align-items: flex-start; gap: 8px; margin-bottom: 6px;";let a=document.createElement("span");a.style.cssText="color: #585b70; font-size: 11px; min-width: 50px;",a.textContent="Query:";let d=document.createElement("span");d.style.cssText="color: #89b4fa; font-size: 12px;",d.textContent=JSON.stringify(this.currentQuery),c.appendChild(a),c.appendChild(d),e.appendChild(c)}this.container.appendChild(e);let s=document.createElement("div");s.style.cssText="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;";let l=document.createElement("span");l.style.cssText="font-size: 11px; color: #a6adc8; text-transform: uppercase; letter-spacing: 0.5px;",l.textContent=`History (${this.history.length})`,s.appendChild(l);let p=document.createElement("button");if(p.style.cssText="background: transparent; border: 1px solid #45475a; color: #a6adc8; cursor: pointer; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-family: inherit;",p.textContent="Clear",p.addEventListener("click",()=>this.clearHistory()),s.appendChild(p),this.container.appendChild(s),this.history.length===0){let c=document.createElement("div");c.style.cssText="color: #585b70; font-size: 12px; text-align: center; padding: 16px 0; font-style: italic;",c.textContent="No navigation history",this.container.appendChild(c)}else{let c=document.createElement("div");c.style.cssText="max-height: 300px; overflow-y: auto;";let a=[...this.history].reverse();for(let d of a){let u=document.createElement("div");u.style.cssText="display: flex; align-items: center; justify-content: space-between; padding: 4px 8px; border-radius: 3px; font-size: 12px; transition: background 0.15s; cursor: default;",u.addEventListener("mouseenter",()=>{u.style.background="#313244"}),u.addEventListener("mouseleave",()=>{u.style.background="transparent"});let h=document.createElement("span");h.style.cssText="color: #cdd6f4; font-family: inherit;",h.textContent=d.path;let f=document.createElement("span");f.style.cssText="color: #585b70; font-size: 10px; white-space: nowrap;";let m=new Date(d.timestamp);f.textContent=`${m.getHours().toString().padStart(2,"0")}:${m.getMinutes().toString().padStart(2,"0")}:${m.getSeconds().toString().padStart(2,"0")}.${m.getMilliseconds().toString().padStart(3,"0")}`,u.appendChild(h),u.appendChild(f),c.appendChild(u)}this.container.appendChild(c)}}destroy(){this.container.innerHTML="",this.history=[]}};var R=class{constructor(e){this.head=0;this.count=0;this.capacity=e,this.buffer=new Array(e).fill(void 0)}push(e){let t=(this.head+this.count)%this.capacity;this.buffer[t]=e,this.count<this.capacity?this.count++:this.head=(this.head+1)%this.capacity}getAll(){let e=[];for(let t=0;t<this.count;t++){let n=this.buffer[(this.head+t)%this.capacity];n!==void 0&&e.push(n)}return e}get size(){return this.count}get isEmpty(){return this.count===0}clear(){this.buffer.fill(void 0),this.head=0,this.count=0}},Ye=100,Ke=16,$=class{constructor(e=Ye){this.pendingMarks=new Map;this.componentUpdateCounts=new Map;this._isRecording=!1;this.bufferSize=e,this.fcpBuffer=new R(e),this.inpBuffer=new R(e),this.renderBuffer=new R(e),this.updateFrequencyBuffer=new R(e),this.memoryBuffer=new R(e),this.customMarkBuffer=new R(e),this.fpsBuffer=new R(e),this.fpsState={isMonitoring:!1,frameCount:0,lastTime:0,rafId:null}}recordFCP(e){if(e===void 0)if(typeof performance!="undefined"&&performance.getEntriesByType){let n=performance.getEntriesByType("paint").find(r=>r.name==="first-contentful-paint");e=n?n.startTime:0}else e=0;this.fcpBuffer.push({type:"fcp",value:e,timestamp:Date.now()})}recordINP(e,t,n){this.inpBuffer.push({type:"inp",value:e,eventName:t,componentName:n,timestamp:Date.now()})}recordRender(e,t,n="update",r){this.renderBuffer.push({type:"render",value:t,componentName:e,componentId:r,phase:n,timestamp:Date.now()}),this.trackComponentUpdate(e)}trackComponentUpdate(e){let t=Date.now(),n=this.componentUpdateCounts.get(e);if(!n){this.componentUpdateCounts.set(e,{count:1,startTime:t});return}n.count++;let r=t-n.startTime;r>=1e3&&(this.updateFrequencyBuffer.push({type:"update-frequency",componentName:e,count:n.count,windowMs:r,timestamp:t}),n.count=0,n.startTime=t)}recordMemory(e,t){this.memoryBuffer.push({type:"memory",proxyCount:e,reactiveCount:t,timestamp:Date.now()})}startMark(e){this.pendingMarks.set(e,performance.now())}endMark(e){let t=this.pendingMarks.get(e);if(t===void 0)return-1;let n=performance.now()-t;return this.pendingMarks.delete(e),this.customMarkBuffer.push({type:"custom",name:e,value:n,timestamp:Date.now()}),n}startFPSMonitor(){if(this.fpsState.isMonitoring||typeof requestAnimationFrame!="function")return;this.fpsState.isMonitoring=!0,this.fpsState.frameCount=0,this.fpsState.lastTime=performance.now();let e=t=>{if(!this.fpsState.isMonitoring)return;this.fpsState.frameCount++;let n=t-this.fpsState.lastTime;if(n>=1e3){let r=this.fpsState.frameCount/n*1e3;this.fpsBuffer.push({type:"fps",value:Math.round(r),timestamp:Date.now()}),this.fpsState.frameCount=0,this.fpsState.lastTime=t}this.fpsState.rafId=requestAnimationFrame(e)};this.fpsState.rafId=requestAnimationFrame(e)}stopFPSMonitor(){this.fpsState.isMonitoring=!1,this.fpsState.rafId!==null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.fpsState.rafId),this.fpsState.rafId=null)}isFPSMonitoring(){return this.fpsState.isMonitoring}startRecording(){this._isRecording=!0,this.startFPSMonitor()}stopRecording(){this._isRecording=!1,this.stopFPSMonitor()}isRecording(){return this._isRecording}getMetrics(){return[...this.fcpBuffer.getAll(),...this.inpBuffer.getAll(),...this.renderBuffer.getAll(),...this.updateFrequencyBuffer.getAll(),...this.memoryBuffer.getAll(),...this.customMarkBuffer.getAll(),...this.fpsBuffer.getAll()]}getMetricsByType(e){return this.getMetrics().filter(n=>n.type===e)}getCurrentFPS(){let e=this.fpsBuffer.getAll();return e.length===0?0:e[e.length-1].value}getRenderRankings(){let e=new Map;for(let t of this.renderBuffer.getAll()){let n=e.get(t.componentName)||{renderCount:0,totalTime:0,maxTime:0};n.renderCount++,n.totalTime+=t.value,n.maxTime=Math.max(n.maxTime,t.value),e.set(t.componentName,n)}return Array.from(e.entries()).map(([t,n])=>({componentName:t,renderCount:n.renderCount,avgRenderTime:n.renderCount>0?n.totalTime/n.renderCount:0,maxRenderTime:n.maxTime,totalRenderTime:n.totalTime})).sort((t,n)=>n.avgRenderTime-t.avgRenderTime)}getProxyCount(){let e=this.memoryBuffer.getAll();return e.length===0?0:e[e.length-1].proxyCount}getSlowRenders(){return this.renderBuffer.getAll().filter(e=>e.value>Ke)}getReport(){let e=this.fcpBuffer.getAll(),t=e.length>0?e[e.length-1]:null,r=this.inpBuffer.getAll().map(y=>y.value),o={avg:r.length>0?r.reduce((y,g)=>y+g,0)/r.length:0,max:r.length>0?Math.max(...r):0,min:r.length>0?Math.min(...r):0,count:r.length},s=this.getRenderRankings(),l=this.updateFrequencyBuffer.getAll(),p=new Map;for(let y of l){let g=y.count/y.windowMs*1e3,b=p.get(y.componentName)||[];b.push(g),p.set(y.componentName,b)}let c=Array.from(p.entries()).map(([y,g])=>({componentName:y,avgFrequency:g.reduce((b,T)=>b+T,0)/g.length})),a=this.memoryBuffer.getAll(),d=a.length>0?a[a.length-1]:null,h=this.fpsBuffer.getAll().map(y=>y.value),f={avg:h.length>0?h.reduce((y,g)=>y+g,0)/h.length:0,min:h.length>0?Math.min(...h):0,count:h.length},m=this.customMarkBuffer.getAll(),x=new Map;for(let y of m){let g=x.get(y.name)||[];g.push(y.value),x.set(y.name,g)}let v=Array.from(x.entries()).map(([y,g])=>({name:y,avg:g.reduce((b,T)=>b+T,0)/g.length,max:Math.max(...g),count:g.length}));return{generatedAt:Date.now(),fcp:t,inp:o,renderStats:s,updateFrequencyStats:c,memory:d,fps:f,customMarks:v}}exportJSON(){return JSON.stringify({metrics:this.getMetrics(),report:this.getReport()},null,2)}clear(){this.fcpBuffer.clear(),this.inpBuffer.clear(),this.renderBuffer.clear(),this.updateFrequencyBuffer.clear(),this.memoryBuffer.clear(),this.customMarkBuffer.clear(),this.fpsBuffer.clear(),this.pendingMarks.clear(),this.componentUpdateCounts.clear()}destroy(){this.stopFPSMonitor(),this.clear()}};var A=class{constructor(e=16){this.activeProfiles=new Map;this.slowThreshold=e}startProfile(e){return this.activeProfiles.has(e)?!1:(this.activeProfiles.set(e,{componentName:e,startTime:performance.now(),records:[],slowThreshold:this.slowThreshold}),!0)}stopProfile(e){let t=this.activeProfiles.get(e);return t?(this.activeProfiles.delete(e),this.buildResult(t)):null}stopAllProfiles(){let e=[];for(let t of this.activeProfiles.values())e.push(this.buildResult(t));return this.activeProfiles.clear(),e}recordRender(e,t){let n=this.activeProfiles.get(e);if(!n)return;let r={duration:t,timestamp:Date.now(),isSlow:t>n.slowThreshold};n.records.push(r)}getSnapshot(e){let t=this.activeProfiles.get(e);return t?this.buildResult(t):null}isProfiling(e){return this.activeProfiles.has(e)}getActiveProfileNames(){return Array.from(this.activeProfiles.keys())}getActiveProfileCount(){return this.activeProfiles.size}getSlowRenders(e){let t=this.activeProfiles.get(e);return t?t.records.filter(n=>n.isSlow):[]}setSlowThreshold(e){this.slowThreshold=e;for(let t of this.activeProfiles.values()){t.slowThreshold=e;for(let n of t.records)n.isSlow=n.duration>e}}getSlowThreshold(){return this.slowThreshold}clear(){this.activeProfiles.clear()}destroy(){this.clear()}buildResult(e){let t=e.records,n=t.length,r=t.reduce((a,d)=>a+d.duration,0),o=n>0?r/n:0,s=n>0?Math.max(...t.map(a=>a.duration)):0,l=n>0?Math.min(...t.map(a=>a.duration)):0,p=t.filter(a=>a.isSlow).length,c=performance.now()-e.startTime;return{componentName:e.componentName,renderCount:n,avgRenderTime:o,maxRenderTime:s,minRenderTime:l,totalRenderTime:r,slowRenderCount:p,slowThreshold:e.slowThreshold,records:[...t],profileDuration:c}}};var ee=class{constructor(e,t){this.entries=new Map;this.isRecording=!1;this.fpsUpdateTimer=null;var n,r;this.container=e,this.config={autoStartFPS:(n=t==null?void 0:t.autoStartFPS)!=null?n:!1,fpsUpdateInterval:(r=t==null?void 0:t.fpsUpdateInterval)!=null?r:1e3},this.fpsUpdateInterval=this.config.fpsUpdateInterval,this.collector=new $,this.profiler=new A,this.config.autoStartFPS&&this.collector.startFPSMonitor(),this.render()}recordRender(e,t){let n=this.entries.get(e)||{name:e,renders:0,totalTime:0,avgTime:0,maxTime:0,lastTime:0};n.renders++,n.totalTime+=t,n.avgTime=n.totalTime/n.renders,n.maxTime=Math.max(n.maxTime,t),n.lastTime=t,this.entries.set(e,n),this.collector.recordRender(e,t,"update"),this.profiler.recordRender(e,t),this.render()}getStats(){return Array.from(this.entries.values()).sort((e,t)=>t.totalTime-e.totalTime)}getEntry(e){return this.entries.get(e)||null}getTotalRenders(){let e=0;for(let t of this.entries.values())e+=t.renders;return e}getTotalTime(){let e=0;for(let t of this.entries.values())e+=t.totalTime;return e}clear(){this.entries.clear(),this.collector.clear(),this.profiler.clear(),this.render()}getCurrentFPS(){return this.collector.getCurrentFPS()}startFPSMonitor(){this.collector.startFPSMonitor(),this.startFPSUpdateLoop()}stopFPSMonitor(){this.collector.stopFPSMonitor(),this.stopFPSUpdateLoop()}isFPSMonitoring(){return this.collector.isFPSMonitoring()}getRenderRankings(){return this.collector.getRenderRankings()}getUpdateFrequencyStats(){return this.collector.getReport().updateFrequencyStats}recordProxyCount(e,t){this.collector.recordMemory(e,t)}getProxyCount(){return this.collector.getProxyCount()}startRecording(){this.isRecording=!0,this.collector.startRecording(),this.startFPSUpdateLoop(),this.render()}stopRecording(){this.isRecording=!1,this.collector.stopRecording(),this.stopFPSUpdateLoop(),this.render()}isRecordingActive(){return this.isRecording}exportJSON(){return this.collector.exportJSON()}getReport(){return this.collector.getReport()}startProfile(e){return this.profiler.startProfile(e)}stopProfile(e){return this.profiler.stopProfile(e)}getProfileSnapshot(e){return this.profiler.getSnapshot(e)}getSlowRenders(){return this.getStats().filter(e=>e.maxTime>16)}getCollector(){return this.collector}getProfiler(){return this.profiler}render(){this.container.innerHTML="";let e=document.createElement("div");e.style.cssText="display: flex; gap: 8px; margin-bottom: 12px; flex-wrap: wrap;";let t=this.getCurrentFPS(),n=t>=55?"#a6e3a1":t>=30?"#f9e2af":"#f38ba8",r=this.createStatCard("FPS",String(t),n),o=this.createStatCard("Proxies",String(this.getProxyCount()),"#cba6f7"),s=this.createStatCard("Total Renders",String(this.getTotalRenders()),"#89b4fa"),l=this.createStatCard("Total Time",`${this.getTotalTime().toFixed(2)}ms`,"#a6e3a1"),p=this.createStatCard("Components",String(this.entries.size),"#f9e2af");e.appendChild(r),e.appendChild(o),e.appendChild(s),e.appendChild(l),e.appendChild(p),this.container.appendChild(e);let c=document.createElement("div");c.style.cssText="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;";let a=document.createElement("span");a.style.cssText="font-size: 11px; color: #a6adc8; text-transform: uppercase; letter-spacing: 0.5px;",a.textContent="Render Performance",c.appendChild(a);let d=document.createElement("div");d.style.cssText="display: flex; gap: 4px;";let u=document.createElement("button");u.style.cssText=this.getRecordButtonStyle(),u.textContent=this.isRecording?"Stop":"Record",u.addEventListener("click",()=>{this.isRecording?this.stopRecording():this.startRecording()}),d.appendChild(u);let h=document.createElement("button");h.style.cssText="background: transparent; border: 1px solid #45475a; color: #a6adc8; cursor: pointer; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-family: inherit;",h.textContent="Export",h.addEventListener("click",()=>{let x=this.exportJSON(),v=new Blob([x],{type:"application/json"}),y=URL.createObjectURL(v),g=document.createElement("a");g.href=y,g.download=`lyt-perf-${Date.now()}.json`,g.click(),URL.revokeObjectURL(y)}),d.appendChild(h);let f=document.createElement("button");f.style.cssText="background: transparent; border: 1px solid #45475a; color: #a6adc8; cursor: pointer; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-family: inherit;",f.textContent="Clear",f.addEventListener("click",()=>this.clear()),d.appendChild(f),c.appendChild(d),this.container.appendChild(c);let m=this.getStats().sort((x,v)=>v.avgTime-x.avgTime);if(m.length===0){let x=document.createElement("div");x.style.cssText="color: #585b70; font-size: 12px; text-align: center; padding: 16px 0; font-style: italic;",x.textContent="No performance data recorded",this.container.appendChild(x)}else{let x=document.createElement("div");x.style.cssText="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 4px; padding: 4px 8px; font-size: 10px; color: #585b70; text-transform: uppercase; letter-spacing: 0.5px; border-bottom: 1px solid #313244; margin-bottom: 4px;",x.innerHTML="<span>Component</span><span>Renders</span><span>Avg</span><span>Max</span><span>Last</span>",this.container.appendChild(x);let v=document.createElement("div");v.style.cssText="max-height: 300px; overflow-y: auto;";for(let y of m){let g=document.createElement("div");g.style.cssText="display: grid; grid-template-columns: 2fr 1fr 1fr 1fr 1fr; gap: 4px; padding: 6px 8px; font-size: 12px; border-radius: 3px; transition: background 0.15s; cursor: default;",g.addEventListener("mouseenter",()=>{g.style.background="#313244"}),g.addEventListener("mouseleave",()=>{g.style.background="transparent"});let b=document.createElement("span");b.style.cssText="color: #cdd6f4; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;",b.textContent=y.name;let T=document.createElement("span");T.style.cssText="color: #89b4fa;",T.textContent=String(y.renders);let le=document.createElement("span");le.style.cssText=this.getPerfColor(y.avgTime),le.textContent=`${y.avgTime.toFixed(2)}ms`;let de=document.createElement("span");de.style.cssText=this.getPerfColor(y.maxTime),de.textContent=`${y.maxTime.toFixed(2)}ms`;let pe=document.createElement("span");pe.style.cssText=this.getPerfColor(y.lastTime),pe.textContent=`${y.lastTime.toFixed(2)}ms`,g.appendChild(b),g.appendChild(T),g.appendChild(le),g.appendChild(de),g.appendChild(pe),v.appendChild(g)}this.container.appendChild(v)}}createStatCard(e,t,n){let r=document.createElement("div");r.style.cssText="flex: 1; padding: 8px 12px; background: #181825; border: 1px solid #313244; border-radius: 4px; min-width: 70px;";let o=document.createElement("div");o.style.cssText=`font-size: 16px; font-weight: 600; color: ${n}; margin-bottom: 2px;`,o.textContent=t;let s=document.createElement("div");return s.style.cssText="font-size: 10px; color: #585b70; text-transform: uppercase; letter-spacing: 0.5px;",s.textContent=e,r.appendChild(o),r.appendChild(s),r}getRecordButtonStyle(){return this.isRecording?"background: #f38ba8; border: 1px solid #f38ba8; color: #1e1e2e; cursor: pointer; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-family: inherit; font-weight: 600;":"background: transparent; border: 1px solid #45475a; color: #a6adc8; cursor: pointer; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-family: inherit;"}getPerfColor(e){return e<1?"color: #a6e3a1;":e<5?"color: #f9e2af;":e<16?"color: #fab387;":"color: #f38ba8;"}startFPSUpdateLoop(){this.stopFPSUpdateLoop(),this.fpsUpdateTimer=window.setInterval(()=>{this.render()},this.fpsUpdateInterval)}stopFPSUpdateLoop(){this.fpsUpdateTimer!==null&&(clearInterval(this.fpsUpdateTimer),this.fpsUpdateTimer=null)}destroy(){this.stopFPSUpdateLoop(),this.collector.destroy(),this.profiler.destroy(),this.container.innerHTML="",this.entries.clear()}};var te=class{constructor(e){this.buffer=[];this._paused=!1;this.filterPattern="";this.counter=0;this.writeIndex=0;this.bufferFull=!1;this.element=null;var t,n,r;this.maxBuffer=(t=e==null?void 0:e.maxBuffer)!=null?t:200,this.autoScroll=(n=e==null?void 0:e.autoScroll)!=null?n:!0,this.title=(r=e==null?void 0:e.title)!=null?r:"\u4E8B\u4EF6\u9762\u677F"}captureEvent(e,t,n){if(this._paused)return;let r={name:e,payload:t,sourceComponent:n,timestamp:Date.now(),index:this.counter++};this.bufferFull?this.buffer[this.writeIndex]=r:(this.buffer.push(r),this.buffer.length>=this.maxBuffer&&(this.bufferFull=!0)),this.writeIndex=(this.writeIndex+1)%this.maxBuffer}getEvents(){let e=this.bufferFull?this.buffer.slice(this.writeIndex).concat(this.buffer.slice(0,this.writeIndex)):[...this.buffer];if(this.filterPattern){let t=this.filterPattern.toLowerCase();e=e.filter(n=>n.name.toLowerCase().includes(t)||n.sourceComponent&&n.sourceComponent.toLowerCase().includes(t))}return e}getAllEvents(){return this.bufferFull?this.buffer.slice(this.writeIndex).concat(this.buffer.slice(0,this.writeIndex)):[...this.buffer]}clear(){this.buffer=[],this.writeIndex=0,this.bufferFull=!1}setFilter(e){this.filterPattern=e}getFilter(){return this.filterPattern}pause(){this._paused=!0}resume(){this._paused=!1}isPaused(){return this._paused}exportJSON(){let e=this.getEvents();return JSON.stringify(e,null,2)}getCount(){return this.bufferFull?this.maxBuffer:this.buffer.length}getMaxBuffer(){return this.maxBuffer}render(){this.element&&this.element.remove();let e=document.createElement("div");e.className="lyt-event-panel",e.style.cssText="font-family: monospace; font-size: 12px; color: #cdd6f4;";let t=document.createElement("div");t.style.cssText="display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; background: #1e1e2e; border-bottom: 1px solid #313244;";let n=document.createElement("span");n.textContent=this.title,n.style.cssText="font-weight: bold; font-size: 13px;",t.appendChild(n);let r=document.createElement("div");r.style.cssText="display: flex; gap: 4px;";let o=document.createElement("button");o.textContent=this._paused?"\u6062\u590D":"\u6682\u505C",o.style.cssText="padding: 2px 8px; border: 1px solid #45475a; background: #313244; color: #cdd6f4; cursor: pointer; border-radius: 3px; font-size: 11px;",o.addEventListener("click",()=>{this._paused?this.resume():this.pause(),o.textContent=this._paused?"\u6062\u590D":"\u6682\u505C",this.render()}),r.appendChild(o);let s=document.createElement("button");s.textContent="\u6E05\u9664",s.style.cssText="padding: 2px 8px; border: 1px solid #45475a; background: #313244; color: #cdd6f4; cursor: pointer; border-radius: 3px; font-size: 11px;",s.addEventListener("click",()=>{this.clear(),this.render()}),r.appendChild(s);let l=document.createElement("button");l.textContent="\u5BFC\u51FA",l.style.cssText="padding: 2px 8px; border: 1px solid #45475a; background: #313244; color: #cdd6f4; cursor: pointer; border-radius: 3px; font-size: 11px;",l.addEventListener("click",()=>{let u=this.exportJSON(),h=new Blob([u],{type:"application/json"}),f=URL.createObjectURL(h),m=document.createElement("a");m.href=f,m.download=`lyt-events-${Date.now()}.json`,m.click(),URL.revokeObjectURL(f)}),r.appendChild(l),t.appendChild(r),e.appendChild(t);let p=document.createElement("div");p.style.cssText="padding: 6px 12px; background: #181825; border-bottom: 1px solid #313244;";let c=document.createElement("input");c.type="text",c.placeholder="\u8FC7\u6EE4\u4E8B\u4EF6\u540D\u79F0...",c.value=this.filterPattern,c.style.cssText="width: 100%; padding: 4px 8px; border: 1px solid #45475a; background: #1e1e2e; color: #cdd6f4; border-radius: 3px; font-size: 11px; box-sizing: border-box;",c.addEventListener("input",()=>{this.setFilter(c.value),this.render()}),p.appendChild(c),e.appendChild(p);let a=document.createElement("div");a.style.cssText="max-height: 400px; overflow-y: auto; padding: 4px 0;";let d=this.getEvents();if(d.length===0){let u=document.createElement("div");u.style.cssText="padding: 20px; text-align: center; color: #585b70;",u.textContent="\u6682\u65E0\u4E8B\u4EF6",a.appendChild(u)}else for(let u of d){let h=document.createElement("div");h.style.cssText="padding: 4px 12px; border-bottom: 1px solid #1e1e2e; cursor: pointer;";let f=new Date(u.timestamp),m=`${String(f.getHours()).padStart(2,"0")}:${String(f.getMinutes()).padStart(2,"0")}:${String(f.getSeconds()).padStart(2,"0")}.${String(f.getMilliseconds()).padStart(3,"0")}`,x="";try{x=JSON.stringify(u.payload),x.length>50&&(x=x.slice(0,50)+"...")}catch(y){x=String(u.payload)}let v=u.sourceComponent?` [${u.sourceComponent}]`:"";h.textContent=`${m} ${u.name}${v} ${x}`,a.appendChild(h)}return e.appendChild(a),this.autoScroll&&(a.scrollTop=a.scrollHeight),this.element=e,e}destroy(){this.element&&(this.element.remove(),this.element=null),this.clear()}};var ne=class{constructor(e){this.currentRoute=null;this.history=[];this.navCounter=0;this.element=null;this.selectedHistoryIndex=-1;var t,n;this.maxHistory=(t=e==null?void 0:e.maxHistory)!=null?t:50,this.title=(n=e==null?void 0:e.title)!=null?n:"\u8DEF\u7531\u9762\u677F"}onRouteChange(e,t,n){let r={index:this.navCounter++,to:{...e},from:{...t},timestamp:Date.now(),type:n!=null?n:"push"};this.history.push(r),this.history.length>this.maxHistory&&(this.history=this.history.slice(this.history.length-this.maxHistory)),this.currentRoute={...e},this.selectedHistoryIndex=-1}getCurrentRoute(){return this.currentRoute?{...this.currentRoute}:null}getHistory(){return this.history.map(e=>({...e,to:{...e.to},from:{...e.from}}))}clearHistory(){this.history=[],this.navCounter=0,this.selectedHistoryIndex=-1}getHistoryCount(){return this.history.length}getMaxHistory(){return this.maxHistory}selectHistoryEntry(e){e>=0&&e<this.history.length&&(this.selectedHistoryIndex=e)}getSelectedHistoryEntry(){if(this.selectedHistoryIndex>=0&&this.selectedHistoryIndex<this.history.length){let e=this.history[this.selectedHistoryIndex];return{...e,to:{...e.to},from:{...e.from}}}return null}render(){this.element&&this.element.remove();let e=document.createElement("div");e.className="lyt-router-panel",e.style.cssText="font-family: monospace; font-size: 12px; color: #cdd6f4;";let t=document.createElement("div");t.style.cssText="display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; background: #1e1e2e; border-bottom: 1px solid #313244;";let n=document.createElement("span");n.textContent=this.title,n.style.cssText="font-weight: bold; font-size: 13px;",t.appendChild(n);let r=document.createElement("button");r.textContent="\u6E05\u9664\u5386\u53F2",r.style.cssText="padding: 2px 8px; border: 1px solid #45475a; background: #313244; color: #cdd6f4; cursor: pointer; border-radius: 3px; font-size: 11px;",r.addEventListener("click",()=>{this.clearHistory(),this.render()}),t.appendChild(r),e.appendChild(t);let o=document.createElement("div");o.style.cssText="padding: 8px 12px; background: #181825; border-bottom: 1px solid #313244;";let s=document.createElement("div");if(s.style.cssText="color: #a6adc8; font-size: 11px; margin-bottom: 4px;",s.textContent="\u5F53\u524D\u8DEF\u7531",o.appendChild(s),this.currentRoute){let a=document.createElement("div");if(a.style.cssText="font-weight: bold; font-size: 14px; color: #89b4fa;",a.textContent=this.currentRoute.path,o.appendChild(a),this.currentRoute.params&&Object.keys(this.currentRoute.params).length>0){let d=document.createElement("div");d.style.cssText="margin-top: 4px; color: #a6e3a1; font-size: 11px;",d.textContent=`params: ${JSON.stringify(this.currentRoute.params)}`,o.appendChild(d)}if(this.currentRoute.query&&Object.keys(this.currentRoute.query).length>0){let d=document.createElement("div");d.style.cssText="margin-top: 2px; color: #f9e2af; font-size: 11px;",d.textContent=`query: ${JSON.stringify(this.currentRoute.query)}`,o.appendChild(d)}if(this.currentRoute.name){let d=document.createElement("div");d.style.cssText="margin-top: 2px; color: #cba6f7; font-size: 11px;",d.textContent=`name: ${this.currentRoute.name}`,o.appendChild(d)}}else{let a=document.createElement("div");a.style.cssText="color: #585b70; font-size: 11px;",a.textContent="\u6682\u65E0\u8DEF\u7531\u4FE1\u606F",o.appendChild(a)}e.appendChild(o);let l=document.createElement("div");l.style.cssText="padding: 8px 12px; background: #1e1e2e; border-bottom: 1px solid #313244;";let p=document.createElement("div");p.style.cssText="color: #a6adc8; font-size: 11px; margin-bottom: 4px;",p.textContent=`\u5BFC\u822A\u5386\u53F2 (${this.history.length})`,l.appendChild(p),e.appendChild(l);let c=document.createElement("div");if(c.style.cssText="max-height: 300px; overflow-y: auto;",this.history.length===0){let a=document.createElement("div");a.style.cssText="padding: 20px; text-align: center; color: #585b70;",a.textContent="\u6682\u65E0\u5BFC\u822A\u8BB0\u5F55",c.appendChild(a)}else for(let a=this.history.length-1;a>=0;a--){let d=this.history[a],u=document.createElement("div"),h=a===this.selectedHistoryIndex;u.style.cssText=`padding: 4px 12px; border-bottom: 1px solid #1e1e2e; cursor: pointer;${h?" background: #313244;":""}`;let f=new Date(d.timestamp),m=`${String(f.getHours()).padStart(2,"0")}:${String(f.getMinutes()).padStart(2,"0")}:${String(f.getSeconds()).padStart(2,"0")}`,x=d.type==="pop"?"<-":d.type==="replace"?"=":">";u.textContent=`${m} ${x} ${d.from.path} -> ${d.to.path}`;let v=a;u.addEventListener("click",()=>{this.selectHistoryEntry(v),this.render()}),c.appendChild(u)}if(e.appendChild(c),this.selectedHistoryIndex>=0){let a=this.history[this.selectedHistoryIndex];if(a){let d=document.createElement("div");d.style.cssText="padding: 8px 12px; background: #181825; border-top: 1px solid #313244;";let u=document.createElement("div");u.style.cssText="color: #a6adc8; font-size: 11px; margin-bottom: 4px;",u.textContent="\u5BFC\u822A\u8BE6\u60C5",d.appendChild(u);let h=document.createElement("div");h.style.cssText="font-size: 11px; line-height: 1.6;";let f=a.from,m=a.to;h.innerHTML=`
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
`;let l=document.createElement("span");l.style.cssText="display: inline-block; width: 14px; text-align: center; margin-right: 4px; font-size: 10px; color: #585b70;",s?l.textContent=e.expanded?"\u25BC":"\u25B6":l.textContent="\xB7",n.appendChild(l);let p=document.createElement("span");if(p.textContent=e.node.name,p.style.cssText="font-weight: bold;",n.appendChild(p),e.node.stateSummary){let d=document.createElement("span");d.textContent=` ${e.node.stateSummary}`,d.style.cssText="color: #a6adc8; font-size: 10px; margin-left: 6px;",n.appendChild(d)}if(e.node.propsCount!==void 0&&e.node.propsCount>0){let d=document.createElement("span");d.textContent=` [${e.node.propsCount} props]`,d.style.cssText="color: #585b70; font-size: 10px; margin-left: 4px;",n.appendChild(d)}let c=e.node,a=c.id;return n.addEventListener("click",()=>{var d;if(s){let u=(d=this.expandedMap.get(a))!=null?d:!1;this.expandedMap.set(a,!u),this.flatten(),this.renderNodes()}this.selectedId=a,this.onNodeClick&&this.onNodeClick(c)}),n}handleScroll(e){if(this.destroyed)return;let t=e.target;this.scrollTop=t.scrollTop,this.renderNodes()}getFlatNodes(){return[...this.flatNodes]}getVisibleNodeCount(){return this.getVisibleNodes().length}getTotalNodeCount(){return this.flatNodes.length}};var me=class{constructor(e){this.head=0;this.count=0;this.capacity=e,this.buffer=new Array(e).fill(void 0)}push(e){let t=(this.head+this.count)%this.capacity;this.buffer[t]=e,this.count<this.capacity?this.count++:this.head=(this.head+1)%this.capacity}getAll(){let e=[];for(let t=0;t<this.count;t++){let n=this.buffer[(this.head+t)%this.capacity];n!==void 0&&e.push(n)}return e}get size(){return this.count}get isEmpty(){return this.count===0}clear(){this.buffer.fill(void 0),this.head=0,this.count=0}},Xe=100,Ge=1024,Qe=.7,Ze=5,oe=class{constructor(e){this.counter=0;var t,n,r,o;this.config={bufferSize:(t=e==null?void 0:e.bufferSize)!=null?t:Xe,leakGrowthThreshold:(n=e==null?void 0:e.leakGrowthThreshold)!=null?n:Ge,leakRSquaredThreshold:(r=e==null?void 0:e.leakRSquaredThreshold)!=null?r:Qe,leakMinSnapshots:(o=e==null?void 0:e.leakMinSnapshots)!=null?o:Ze},this.snapshots=new me(this.config.bufferSize)}trackMemoryUsage(e,t,n,r){if(e===void 0){let s=performance.memory;s&&(e=s.usedJSHeapSize,t=s.totalJSHeapSize,n=s.jsHeapSizeLimit)}if(e===void 0)return null;let o={timestamp:r!=null?r:Date.now(),usedJSHeapSize:e,totalJSHeapSize:t!=null?t:0,jsHeapSizeLimit:n!=null?n:0,index:this.counter++};return this.snapshots.push(o),o}getMemoryTrend(){let e=this.snapshots.getAll();return e.length===0?[]:e.map((t,n)=>{let r=n>0?e[n-1]:null,o=r?t.usedJSHeapSize-r.usedJSHeapSize:0,s=t.jsHeapSizeLimit>0?t.usedJSHeapSize/t.jsHeapSizeLimit*100:0;return{timestamp:t.timestamp,usedJSHeapSize:t.usedJSHeapSize,delta:o,usagePercent:s}})}detectMemoryLeak(){let e=this.snapshots.getAll();if(e.length<this.config.leakMinSnapshots)return{hasLeak:!1,severity:"none",description:`\u5FEB\u7167\u6570\u91CF\u4E0D\u8DB3\uFF08\u9700\u8981\u81F3\u5C11 ${this.config.leakMinSnapshots} \u4E2A\uFF0C\u5F53\u524D ${e.length} \u4E2A\uFF09`,snapshotCount:e.length,growthRate:0,rSquared:0};let t=e.length,n=0,r=0,o=0,s=0,l=0;for(let g=0;g<t;g++){let b=g,T=e[g].usedJSHeapSize;n+=b,r+=T,o+=b*T,s+=b*b,l+=T*T}let p=t*s-n*n,c=p!==0?(t*o-n*r)/p:0,a=r/t,d=0,u=0;for(let g=0;g<t;g++){let b=e[g].usedJSHeapSize,T=c*g+(r-c*n)/t;d+=(b-a)*(b-a),u+=(b-T)*(b-T)}let h=d!==0?1-u/d:0,f=(e[t-1].timestamp-e[0].timestamp)/1e3,m=f>0?c/f:0,x=h>=this.config.leakRSquaredThreshold&&m>=this.config.leakGrowthThreshold,v="none",y="\u672A\u68C0\u6D4B\u5230\u5185\u5B58\u6CC4\u6F0F";return x&&(m>=this.config.leakGrowthThreshold*10?(v="high",y=`\u68C0\u6D4B\u5230\u4E25\u91CD\u5185\u5B58\u6CC4\u6F0F\uFF0C\u589E\u957F\u901F\u7387 ${Math.round(m)} bytes/s\uFF0CR\xB2=${h.toFixed(3)}`):m>=this.config.leakGrowthThreshold*3?(v="medium",y=`\u68C0\u6D4B\u5230\u4E2D\u7B49\u5185\u5B58\u6CC4\u6F0F\uFF0C\u589E\u957F\u901F\u7387 ${Math.round(m)} bytes/s\uFF0CR\xB2=${h.toFixed(3)}`):(v="low",y=`\u68C0\u6D4B\u5230\u8F7B\u5FAE\u5185\u5B58\u6CC4\u6F0F\uFF0C\u589E\u957F\u901F\u7387 ${Math.round(m)} bytes/s\uFF0CR\xB2=${h.toFixed(3)}`)),{hasLeak:x,severity:v,description:y,snapshotCount:t,growthRate:m,rSquared:h}}getMemoryReport(){let e=this.snapshots.getAll(),t=this.getMemoryTrend(),n=this.detectMemoryLeak(),r=null,o=0,s=0,l=0,p=1/0;for(let d of e)(!r||d.timestamp>r.timestamp)&&(r=d),d.usedJSHeapSize>o&&(o=d.usedJSHeapSize,s=d.timestamp),l+=d.usedJSHeapSize,d.usedJSHeapSize<p&&(p=d.usedJSHeapSize);let c=e.length>0?l/e.length:0;p===1/0&&(p=0);let a=e.length>=2?e[e.length-1].usedJSHeapSize-e[0].usedJSHeapSize:0;return{generatedAt:Date.now(),current:r,peakUsage:o,peakTimestamp:s,averageUsage:c,minUsage:p,totalGrowth:a,trend:t,leakDetection:n,snapshotCount:e.length}}getSnapshots(){return this.snapshots.getAll()}getSnapshotCount(){return this.snapshots.size}clear(){this.snapshots.clear(),this.counter=0}destroy(){this.clear()}};var fe=class{constructor(e){this.head=0;this.count=0;this.capacity=e,this.buffer=new Array(e).fill(void 0)}push(e){let t=(this.head+this.count)%this.capacity;this.buffer[t]=e,this.count<this.capacity?this.count++:this.head=(this.head+1)%this.capacity}getAll(){let e=[];for(let t=0;t<this.count;t++){let n=this.buffer[(this.head+t)%this.capacity];n!==void 0&&e.push(n)}return e}get size(){return this.count}get isEmpty(){return this.count===0}clear(){this.buffer.fill(void 0),this.head=0,this.count=0}},et=200,tt=16,se=class{constructor(e){this.counter=0;var t,n;this.config={bufferSize:(t=e==null?void 0:e.bufferSize)!=null?t:et,slowThreshold:(n=e==null?void 0:e.slowThreshold)!=null?n:tt},this.records=new fe(this.config.bufferSize)}trackRender(e,t){this.records.push({componentName:e,duration:t,timestamp:Date.now(),index:this.counter++})}getSlowRenderers(e){let t=e!=null?e:this.config.slowThreshold;return this.records.getAll().filter(r=>r.duration>t).map(r=>({componentName:r.componentName,duration:r.duration,timestamp:r.timestamp,overThreshold:r.duration-t})).sort((r,o)=>o.duration-r.duration)}getRenderStats(){let e=this.records.getAll(),t=this.config.slowThreshold;if(e.length===0)return{totalRenders:0,totalDuration:0,avgDuration:0,maxDuration:0,minDuration:0,slowRenderCount:0,slowRenderRatio:0,byComponent:[]};let n=0,r=-1/0,o=1/0,s=0,l=new Map;for(let c of e){n+=c.duration,c.duration>r&&(r=c.duration),c.duration<o&&(o=c.duration),c.duration>t&&s++;let a=l.get(c.componentName);a||(a={renderCount:0,totalDuration:0,maxDuration:-1/0,minDuration:1/0,slowCount:0},l.set(c.componentName,a)),a.renderCount++,a.totalDuration+=c.duration,c.duration>a.maxDuration&&(a.maxDuration=c.duration),c.duration<a.minDuration&&(a.minDuration=c.duration),c.duration>t&&a.slowCount++}let p=Array.from(l.entries()).map(([c,a])=>({componentName:c,renderCount:a.renderCount,avgDuration:a.totalDuration/a.renderCount,maxDuration:a.maxDuration===-1/0?0:a.maxDuration,minDuration:a.minDuration===1/0?0:a.minDuration,totalDuration:a.totalDuration,slowCount:a.slowCount})).sort((c,a)=>a.avgDuration-c.avgDuration);return{totalRenders:e.length,totalDuration:n,avgDuration:n/e.length,maxDuration:r===-1/0?0:r,minDuration:o===1/0?0:o,slowRenderCount:s,slowRenderRatio:s/e.length,byComponent:p}}getRenderTimeline(){let e=this.records.getAll(),t=this.config.slowThreshold;return e.map((n,r)=>({componentName:n.componentName,duration:n.duration,timestamp:n.timestamp,isSlow:n.duration>t,gap:r>0?n.timestamp-e[r-1].timestamp:-1}))}getRecords(){return this.records.getAll()}getRecordCount(){return this.records.size}clear(){this.records.clear(),this.counter=0}destroy(){this.clear()}};var ge=class{constructor(e){this.head=0;this.count=0;this.capacity=e,this.buffer=new Array(e).fill(void 0)}push(e){let t=(this.head+this.count)%this.capacity;this.buffer[t]=e,this.count<this.capacity?this.count++:this.head=(this.head+1)%this.capacity}getAll(){let e=[];for(let t=0;t<this.count;t++){let n=this.buffer[(this.head+t)%this.capacity];n!==void 0&&e.push(n)}return e}get size(){return this.count}get isEmpty(){return this.count===0}clear(){this.buffer.fill(void 0),this.head=0,this.count=0}},nt=100,rt=1e3,ot=2,ie=class{constructor(e){this.pending=new Map;this.counter=0;var t,n,r;this.config={bufferSize:(t=e==null?void 0:e.bufferSize)!=null?t:nt,slowThreshold:(n=e==null?void 0:e.slowThreshold)!=null?n:rt,outlierSigmaThreshold:(r=e==null?void 0:e.outlierSigmaThreshold)!=null?r:ot},this.records=new ge(this.config.bufferSize)}startBatch(e){return this.pending.has(e)?!1:(this.pending.set(e,Date.now()),!0)}endBatch(e){let t=this.pending.get(e);if(t===void 0)return null;let n=Date.now(),r=n-t;this.pending.delete(e);let o={name:e,startTime:t,endTime:n,duration:r,index:this.counter++};return this.records.push(o),o}getBatchStats(){let e=this.records.getAll();if(e.length===0)return{totalBatches:0,totalDuration:0,avgDuration:0,maxDuration:0,minDuration:0,byName:[]};let t=0,n=-1/0,r=1/0,o=new Map;for(let l of e){t+=l.duration,l.duration>n&&(n=l.duration),l.duration<r&&(r=l.duration);let p=o.get(l.name);p||(p={count:0,totalDuration:0,maxDuration:-1/0,minDuration:1/0,durations:[]},o.set(l.name,p)),p.count++,p.totalDuration+=l.duration,l.duration>p.maxDuration&&(p.maxDuration=l.duration),l.duration<p.minDuration&&(p.minDuration=l.duration),p.durations.push(l.duration)}let s=Array.from(o.entries()).map(([l,p])=>{let c=p.totalDuration/p.count,a=0;for(let u of p.durations)a+=(u-c)*(u-c);a/=p.count;let d=Math.sqrt(a);return{name:l,count:p.count,avgDuration:c,maxDuration:p.maxDuration===-1/0?0:p.maxDuration,minDuration:p.minDuration===1/0?0:p.minDuration,totalDuration:p.totalDuration,stdDev:d}});return{totalBatches:e.length,totalDuration:t,avgDuration:t/e.length,maxDuration:n===-1/0?0:n,minDuration:r===1/0?0:r,byName:s}}detectAnomalousBatches(){let e=this.records.getAll();if(e.length===0)return[];let t=this.getBatchStats(),n=[],r=new Map;for(let o of t.byName)r.set(o.name,o);for(let o of e){let s=r.get(o.name);if(o.duration>this.config.slowThreshold){n.push({name:o.name,duration:o.duration,timestamp:o.endTime,anomalyType:"slow",description:`\u64CD\u4F5C "${o.name}" \u8017\u65F6 ${o.duration.toFixed(1)}ms\uFF0C\u8D85\u8FC7\u6162\u64CD\u4F5C\u9608\u503C ${this.config.slowThreshold}ms`,deviationSigma:s&&s.stdDev>0?(o.duration-s.avgDuration)/s.stdDev:0});continue}if(s&&s.count>=2&&s.stdDev>0){let l=(o.duration-s.avgDuration)/s.stdDev;if(Math.abs(l)>this.config.outlierSigmaThreshold){let p=l>0?"slow":"fast";n.push({name:o.name,duration:o.duration,timestamp:o.endTime,anomalyType:p,description:`\u64CD\u4F5C "${o.name}" \u8017\u65F6 ${o.duration.toFixed(1)}ms\uFF0C\u504F\u79BB\u5E73\u5747\u503C ${l.toFixed(1)} \u4E2A\u6807\u51C6\u5DEE`,deviationSigma:l})}}}return n.sort((o,s)=>o.timestamp-s.timestamp),n}getRecords(){return this.records.getAll()}getRecordCount(){return this.records.size}getPendingBatches(){return Array.from(this.pending.keys())}clear(){this.records.clear(),this.pending.clear(),this.counter=0}destroy(){this.clear()}};var ae=class{constructor(e){this._installed=!1;this.app=null;var t,n,r,o,s,l;this.config={width:(t=e==null?void 0:e.width)!=null?t:420,height:(n=e==null?void 0:e.height)!=null?n:560,x:(r=e==null?void 0:e.x)!=null?r:0,y:(o=e==null?void 0:e.y)!=null?o:0,autoShow:(s=e==null?void 0:e.autoShow)!=null?s:!0,title:(l=e==null?void 0:e.title)!=null?l:"Lyt DevTools"},this.panel=new D({width:this.config.width,height:this.config.height,x:this.config.x,y:this.config.y,title:this.config.title}),this.componentTree=new I(this.panel,p=>{this.panel.switchTab("state"),this.stateInspector.refresh()}),this.stateInspector=new B(this.panel),this.eventTracker=new z(this.panel),this.timeTravel=new N(this.panel),this.panel.registerTabRenderer("components",p=>{this.componentTree.render(p)}),this.panel.registerTabRenderer("state",p=>{this.stateInspector.render(p)}),this.panel.registerTabRenderer("events",p=>{this.eventTracker.render(p)}),this.panel.registerTabRenderer("router",p=>{this.renderRouterTab(p)}),this.panel.renderContent(),this.config.autoShow||this.panel.hide()}install(e){if(this._installed)return;this.app=e,this._installed=!0,U(e,{onComponentCreated:n=>{this.componentTree.refresh()},onComponentUpdated:n=>{this.componentTree.refresh(),this.stateInspector.refresh()},onComponentUnmounted:n=>{this.componentTree.refresh()},onStateChanged:n=>{this.stateInspector.markChanged(`state.${n.path}`),this.stateInspector.refresh()},onEventEmitted:n=>{this.eventTracker.refresh()}}),this.panel.setConnected(!0)}show(){this.panel.show()}hide(){this.panel.hide()}toggle(){this.panel.toggle()}isVisible(){return this.panel.isVisible()}renderRouterTab(e){e.innerHTML="";let t=document.createElement("div");t.className="lyt-devtools-empty",t.style.cssText="padding: 40px 24px;",t.innerHTML=`
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
1292
|
+
border-bottom: 2px solid transparent;
|
|
1293
|
+
">Router</button>
|
|
1294
|
+
<button class="lytjs-devtools-tab" data-tab="signals" style="
|
|
1295
|
+
flex: 1;
|
|
1296
|
+
padding: 10px;
|
|
1297
|
+
background: transparent;
|
|
1298
|
+
border: none;
|
|
1299
|
+
color: #d4d4d4;
|
|
1300
|
+
cursor: pointer;
|
|
1301
|
+
border-bottom: 2px solid transparent;
|
|
1302
|
+
">Signals</button>
|
|
1303
|
+
<button class="lytjs-devtools-tab" data-tab="performance" style="
|
|
1304
|
+
flex: 1;
|
|
1305
|
+
padding: 10px;
|
|
1306
|
+
background: transparent;
|
|
1307
|
+
border: none;
|
|
1308
|
+
color: #d4d4d4;
|
|
1309
|
+
cursor: pointer;
|
|
1310
|
+
border-bottom: 2px solid transparent;
|
|
1311
|
+
">Performance</button>
|
|
1312
|
+
`;
|
|
1313
|
+
const content = document.createElement("div");
|
|
1314
|
+
content.id = "lytjs-devtools-content";
|
|
1315
|
+
content.style.cssText = `
|
|
1316
|
+
flex: 1;
|
|
1317
|
+
overflow: auto;
|
|
1318
|
+
padding: 15px;
|
|
1319
|
+
`;
|
|
1320
|
+
panel.appendChild(header);
|
|
1321
|
+
panel.appendChild(tabs);
|
|
1322
|
+
panel.appendChild(content);
|
|
1323
|
+
document.body.appendChild(panel);
|
|
1324
|
+
document.getElementById("lytjs-devtools-close")?.addEventListener("click", () => this.close());
|
|
1325
|
+
tabs.querySelectorAll(".lytjs-devtools-tab").forEach((tab) => {
|
|
1326
|
+
tab.addEventListener("click", (e) => {
|
|
1327
|
+
const target = e.target;
|
|
1328
|
+
const tabName = target.dataset.tab;
|
|
1329
|
+
tabs.querySelectorAll(".lytjs-devtools-tab").forEach((t) => {
|
|
1330
|
+
t.style.background = "transparent";
|
|
1331
|
+
t.style.borderBottomColor = "transparent";
|
|
1332
|
+
});
|
|
1333
|
+
target.style.background = "#1e1e1e";
|
|
1334
|
+
target.style.borderBottomColor = "#4fc08d";
|
|
1335
|
+
this.renderTab(tabName || "components");
|
|
1336
|
+
});
|
|
1337
|
+
});
|
|
1338
|
+
this.renderTab("components");
|
|
1339
|
+
}
|
|
1340
|
+
/**
|
|
1341
|
+
* 渲染标签页内容
|
|
1342
|
+
*/
|
|
1343
|
+
renderTab(tab) {
|
|
1344
|
+
const content = document.getElementById("lytjs-devtools-content");
|
|
1345
|
+
if (!content) return;
|
|
1346
|
+
switch (tab) {
|
|
1347
|
+
case "components":
|
|
1348
|
+
content.innerHTML = this.renderComponentsTab();
|
|
1349
|
+
break;
|
|
1350
|
+
case "store":
|
|
1351
|
+
content.innerHTML = this.renderStoreTab();
|
|
1352
|
+
break;
|
|
1353
|
+
case "router":
|
|
1354
|
+
content.innerHTML = this.renderRouterTab();
|
|
1355
|
+
break;
|
|
1356
|
+
case "signals":
|
|
1357
|
+
content.innerHTML = this.renderSignalsTab();
|
|
1358
|
+
break;
|
|
1359
|
+
case "performance":
|
|
1360
|
+
content.innerHTML = this.renderPerformanceTab();
|
|
1361
|
+
break;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* 渲染组件标签页
|
|
1366
|
+
*/
|
|
1367
|
+
renderComponentsTab() {
|
|
1368
|
+
const tree = getComponentTree();
|
|
1369
|
+
if (tree.length === 0) {
|
|
1370
|
+
return '<div style="color: #666; text-align: center; padding: 40px;">No components found.<br>Register your root component with registerRootComponent().</div>';
|
|
1371
|
+
}
|
|
1372
|
+
return `<pre style="margin: 0; white-space: pre-wrap; word-break: break-all;">${serializeComponentTree(tree)}</pre>`;
|
|
1373
|
+
}
|
|
1374
|
+
/**
|
|
1375
|
+
* 渲染 Store 标签页
|
|
1376
|
+
*/
|
|
1377
|
+
renderStoreTab() {
|
|
1378
|
+
const states = getStoreStates();
|
|
1379
|
+
if (states.length === 0) {
|
|
1380
|
+
return '<div style="color: #666; text-align: center; padding: 40px;">No stores registered.<br>Use registerStore() to register your stores.</div>';
|
|
1381
|
+
}
|
|
1382
|
+
let html = '<div style="margin-bottom: 10px;">';
|
|
1383
|
+
html += `<strong>Registered Stores:</strong> ${getRegisteredStoreIds().join(", ")}`;
|
|
1384
|
+
html += "</div>";
|
|
1385
|
+
html += `<pre style="margin: 0; white-space: pre-wrap; word-break: break-all;">${serializeStoreStates(states)}</pre>`;
|
|
1386
|
+
return html;
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* 渲染 Signals 标签页
|
|
1390
|
+
*/
|
|
1391
|
+
renderSignalsTab() {
|
|
1392
|
+
const nodes = getSignalNodes();
|
|
1393
|
+
let html = `
|
|
1394
|
+
<div style="margin-bottom: 15px;">
|
|
1395
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
|
1396
|
+
<strong>\u{1F4CA} Signals (${nodes.length})</strong>
|
|
1397
|
+
<div>
|
|
1398
|
+
<button id="lytjs-devtools-create-snapshot" style="
|
|
1399
|
+
background: #4fc08d;
|
|
1400
|
+
border: none;
|
|
1401
|
+
color: white;
|
|
1402
|
+
padding: 5px 10px;
|
|
1403
|
+
border-radius: 4px;
|
|
1404
|
+
cursor: pointer;
|
|
1405
|
+
font-size: 11px;
|
|
1406
|
+
">\u521B\u5EFA\u5FEB\u7167</button>
|
|
1407
|
+
<button id="lytjs-devtools-clear-signals" style="
|
|
1408
|
+
background: #ff4d4f;
|
|
1409
|
+
border: none;
|
|
1410
|
+
color: white;
|
|
1411
|
+
padding: 5px 10px;
|
|
1412
|
+
border-radius: 4px;
|
|
1413
|
+
cursor: pointer;
|
|
1414
|
+
font-size: 11px;
|
|
1415
|
+
margin-left: 5px;
|
|
1416
|
+
">\u6E05\u7A7A</button>
|
|
1417
|
+
</div>
|
|
1418
|
+
</div>
|
|
1419
|
+
|
|
1420
|
+
<div style="display: flex; gap: 10px; margin-bottom: 10px;">
|
|
1421
|
+
<button id="lytjs-devtools-tab-signals-list" style="
|
|
1422
|
+
flex: 1;
|
|
1423
|
+
padding: 8px;
|
|
1424
|
+
background: #4fc08d;
|
|
1425
|
+
border: none;
|
|
1426
|
+
color: white;
|
|
1427
|
+
border-radius: 4px;
|
|
1428
|
+
cursor: pointer;
|
|
1429
|
+
font-size: 11px;
|
|
1430
|
+
">\u5217\u8868\u89C6\u56FE</button>
|
|
1431
|
+
<button id="lytjs-devtools-tab-signals-graph" style="
|
|
1432
|
+
flex: 1;
|
|
1433
|
+
padding: 8px;
|
|
1434
|
+
background: #333;
|
|
1435
|
+
border: none;
|
|
1436
|
+
color: #d4d4d4;
|
|
1437
|
+
border-radius: 4px;
|
|
1438
|
+
cursor: pointer;
|
|
1439
|
+
font-size: 11px;
|
|
1440
|
+
">\u4F9D\u8D56\u56FE</button>
|
|
1441
|
+
<button id="lytjs-devtools-tab-signals-timetravel" style="
|
|
1442
|
+
flex: 1;
|
|
1443
|
+
padding: 8px;
|
|
1444
|
+
background: #333;
|
|
1445
|
+
border: none;
|
|
1446
|
+
color: #d4d4d4;
|
|
1447
|
+
border-radius: 4px;
|
|
1448
|
+
cursor: pointer;
|
|
1449
|
+
font-size: 11px;
|
|
1450
|
+
">\u65F6\u95F4\u65C5\u884C</button>
|
|
1451
|
+
</div>
|
|
1452
|
+
|
|
1453
|
+
<div id="lytjs-devtools-signals-content">
|
|
1454
|
+
${this.renderSignalsList(nodes)}
|
|
1455
|
+
</div>
|
|
618
1456
|
</div>
|
|
619
|
-
|
|
1457
|
+
`;
|
|
1458
|
+
return html;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* 渲染信号列表
|
|
1462
|
+
*/
|
|
1463
|
+
renderSignalsList(nodes) {
|
|
1464
|
+
if (nodes.length === 0) {
|
|
1465
|
+
return '<div style="color: #666; text-align: center; padding: 40px;">\u6682\u65E0\u4FE1\u53F7\u6570\u636E<br>\u4F7F\u7528 registerSignal() \u6CE8\u518C\u4FE1\u53F7</div>';
|
|
1466
|
+
}
|
|
1467
|
+
let html = '<div style="max-height: 400px; overflow-y: auto;">';
|
|
1468
|
+
nodes.forEach((node) => {
|
|
1469
|
+
const typeIcon = node.type === "signal" ? "\u{1F4CC}" : node.type === "computed" ? "\u{1F9EE}" : "\u26A1";
|
|
1470
|
+
const typeColor = node.type === "signal" ? "#4fc08d" : node.type === "computed" ? "#1890ff" : "#faad14";
|
|
1471
|
+
html += `
|
|
1472
|
+
<div style="
|
|
1473
|
+
background: #252526;
|
|
1474
|
+
border-radius: 4px;
|
|
1475
|
+
padding: 10px;
|
|
1476
|
+
margin-bottom: 8px;
|
|
1477
|
+
border-left: 3px solid ${typeColor};
|
|
1478
|
+
">
|
|
1479
|
+
<div style="display: flex; justify-content: space-between; align-items: center;">
|
|
1480
|
+
<span style="font-weight: bold;">${typeIcon} ${node.name}</span>
|
|
1481
|
+
<span style="color: #888; font-size: 10px;">${node.type}</span>
|
|
1482
|
+
</div>
|
|
1483
|
+
<div style="color: #888; font-size: 11px; margin-top: 5px;">
|
|
1484
|
+
\u66F4\u65B0\u6B21\u6570: ${node.updateCount} |
|
|
1485
|
+
\u6700\u540E\u66F4\u65B0: ${node.lastUpdateTime ? new Date(node.lastUpdateTime).toLocaleTimeString() : "N/A"}
|
|
1486
|
+
</div>
|
|
1487
|
+
${node.averageUpdateTime > 0 ? `<div style="color: #888; font-size: 11px;">\u5E73\u5747\u8017\u65F6: ${node.averageUpdateTime.toFixed(2)}ms</div>` : ""}
|
|
1488
|
+
<div style="color: #888; font-size: 10px; margin-top: 5px;">
|
|
1489
|
+
\u4F9D\u8D56: ${node.dependencies.length > 0 ? node.dependencies.join(", ") : "\u65E0"} |
|
|
1490
|
+
\u88AB\u4F9D\u8D56: ${node.dependents.length > 0 ? node.dependents.join(", ") : "\u65E0"}
|
|
1491
|
+
</div>
|
|
1492
|
+
</div>
|
|
1493
|
+
`;
|
|
1494
|
+
});
|
|
1495
|
+
html += "</div>";
|
|
1496
|
+
return html;
|
|
1497
|
+
}
|
|
1498
|
+
/**
|
|
1499
|
+
* 渲染 Performance 标签页
|
|
1500
|
+
*/
|
|
1501
|
+
renderPerformanceTab() {
|
|
1502
|
+
const stats = getPerformanceStats();
|
|
1503
|
+
const records = getPerformanceRecords(50);
|
|
1504
|
+
let html = `
|
|
1505
|
+
<div style="margin-bottom: 15px;">
|
|
1506
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
|
|
1507
|
+
<strong>\u26A1 Performance</strong>
|
|
1508
|
+
<button id="lytjs-devtools-clear-performance" style="
|
|
1509
|
+
background: #ff4d4f;
|
|
1510
|
+
border: none;
|
|
1511
|
+
color: white;
|
|
1512
|
+
padding: 5px 10px;
|
|
1513
|
+
border-radius: 4px;
|
|
1514
|
+
cursor: pointer;
|
|
1515
|
+
font-size: 11px;
|
|
1516
|
+
">\u6E05\u7A7A\u8BB0\u5F55</button>
|
|
1517
|
+
</div>
|
|
1518
|
+
|
|
1519
|
+
<div style="background: #252526; border-radius: 4px; padding: 15px; margin-bottom: 15px;">
|
|
1520
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
|
|
1521
|
+
<div style="text-align: center;">
|
|
1522
|
+
<div style="color: #888; font-size: 11px;">\u603B\u8BB0\u5F55\u6570</div>
|
|
1523
|
+
<div style="font-size: 24px; font-weight: bold; color: #4fc08d;">${stats.totalRecords}</div>
|
|
1524
|
+
</div>
|
|
1525
|
+
<div style="text-align: center;">
|
|
1526
|
+
<div style="color: #888; font-size: 11px;">\u5E73\u5747\u8017\u65F6</div>
|
|
1527
|
+
<div style="font-size: 24px; font-weight: bold; color: #1890ff;">${stats.averageDuration.toFixed(2)}ms</div>
|
|
1528
|
+
</div>
|
|
1529
|
+
<div style="text-align: center;">
|
|
1530
|
+
<div style="color: #888; font-size: 11px;">\u6700\u5927\u8017\u65F6</div>
|
|
1531
|
+
<div style="font-size: 24px; font-weight: bold; color: #ff4d4f;">${stats.maxDuration.toFixed(2)}ms</div>
|
|
1532
|
+
</div>
|
|
1533
|
+
<div style="text-align: center;">
|
|
1534
|
+
<div style="color: #888; font-size: 11px;">\u6700\u5C0F\u8017\u65F6</div>
|
|
1535
|
+
<div style="font-size: 24px; font-weight: bold; color: #52c41a;">${stats.minDuration.toFixed(2)}ms</div>
|
|
1536
|
+
</div>
|
|
1537
|
+
</div>
|
|
1538
|
+
</div>
|
|
1539
|
+
`;
|
|
1540
|
+
if (Object.keys(stats.byType).length > 0) {
|
|
1541
|
+
html += `
|
|
1542
|
+
<div style="margin-bottom: 15px;">
|
|
1543
|
+
<strong style="display: block; margin-bottom: 10px;">\u6309\u7C7B\u578B\u7EDF\u8BA1</strong>
|
|
1544
|
+
<div style="background: #252526; border-radius: 4px; padding: 10px;">
|
|
1545
|
+
`;
|
|
1546
|
+
Object.entries(stats.byType).forEach(([type, data]) => {
|
|
1547
|
+
const typeColor = type === "signal" ? "#4fc08d" : type === "computed" ? "#1890ff" : "#faad14";
|
|
1548
|
+
html += `
|
|
1549
|
+
<div style="display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #333;">
|
|
1550
|
+
<span style="color: ${typeColor};">${type}</span>
|
|
1551
|
+
<span>${data.count} \u6B21 | \u5E73\u5747 ${data.average.toFixed(2)}ms | \u6700\u5927 ${data.max.toFixed(2)}ms</span>
|
|
1552
|
+
</div>
|
|
1553
|
+
`;
|
|
1554
|
+
});
|
|
1555
|
+
html += "</div></div>";
|
|
1556
|
+
}
|
|
1557
|
+
if (records.length > 0) {
|
|
1558
|
+
html += `
|
|
1559
|
+
<div>
|
|
1560
|
+
<strong style="display: block; margin-bottom: 10px;">\u6700\u8FD1\u8BB0\u5F55 (50\u6761)</strong>
|
|
1561
|
+
<div style="background: #252526; border-radius: 4px; padding: 10px; max-height: 300px; overflow-y: auto;">
|
|
1562
|
+
`;
|
|
1563
|
+
records.slice().reverse().forEach((record) => {
|
|
1564
|
+
const durationColor = record.duration > 16 ? "#ff4d4f" : record.duration > 8 ? "#faad14" : "#4fc08d";
|
|
1565
|
+
html += `
|
|
1566
|
+
<div style="display: flex; justify-content: space-between; padding: 6px 0; border-bottom: 1px solid #333; font-size: 11px;">
|
|
1567
|
+
<span>${record.name}</span>
|
|
1568
|
+
<span style="color: ${durationColor};">${record.duration.toFixed(2)}ms</span>
|
|
1569
|
+
<span style="color: #888;">${new Date(record.timestamp).toLocaleTimeString()}</span>
|
|
1570
|
+
</div>
|
|
1571
|
+
`;
|
|
1572
|
+
});
|
|
1573
|
+
html += "</div></div>";
|
|
1574
|
+
} else {
|
|
1575
|
+
html += '<div style="color: #666; text-align: center; padding: 40px;">\u6682\u65E0\u6027\u80FD\u6570\u636E</div>';
|
|
1576
|
+
}
|
|
1577
|
+
html += "</div>";
|
|
1578
|
+
return html;
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* 渲染 Router 标签页
|
|
1582
|
+
*/
|
|
1583
|
+
renderRouterTab() {
|
|
1584
|
+
if (!isRouterRegistered()) {
|
|
1585
|
+
return '<div style="color: #666; text-align: center; padding: 40px;">Router not registered.<br>Use registerRouter() to register your router.</div>';
|
|
1586
|
+
}
|
|
1587
|
+
const route = getCurrentRoute();
|
|
1588
|
+
const routes = getRoutes();
|
|
1589
|
+
let html = '<div style="margin-bottom: 15px;">';
|
|
1590
|
+
html += "<strong>Current Route:</strong>";
|
|
1591
|
+
html += "</div>";
|
|
1592
|
+
html += `<pre style="margin: 0 0 15px 0; white-space: pre-wrap; word-break: break-all; background: #252526; padding: 10px; border-radius: 4px;">${serializeRouteInfo(route)}</pre>`;
|
|
1593
|
+
if (routes.length > 0) {
|
|
1594
|
+
html += '<div style="margin-bottom: 10px;">';
|
|
1595
|
+
html += "<strong>All Routes:</strong>";
|
|
1596
|
+
html += "</div>";
|
|
1597
|
+
html += '<ul style="margin: 0; padding-left: 20px;">';
|
|
1598
|
+
for (const r of routes) {
|
|
1599
|
+
html += `<li>${r.path}${r.name ? ` (${r.name})` : ""}</li>`;
|
|
1600
|
+
}
|
|
1601
|
+
html += "</ul>";
|
|
1602
|
+
}
|
|
1603
|
+
return html;
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* 打开面板
|
|
1607
|
+
*/
|
|
1608
|
+
open() {
|
|
1609
|
+
if (!this.options.enabled) return;
|
|
1610
|
+
const panel = document.getElementById("lytjs-devtools");
|
|
1611
|
+
if (panel) {
|
|
1612
|
+
panel.style[this.options.position] = "0";
|
|
1613
|
+
this.isOpen = true;
|
|
1614
|
+
this.refresh();
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
/**
|
|
1618
|
+
* 关闭面板
|
|
1619
|
+
*/
|
|
1620
|
+
close() {
|
|
1621
|
+
if (typeof document === "undefined") return;
|
|
1622
|
+
const panel = document.getElementById("lytjs-devtools");
|
|
1623
|
+
if (panel) {
|
|
1624
|
+
panel.style[this.options.position] = `-${this.options.size}px`;
|
|
1625
|
+
this.isOpen = false;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
/**
|
|
1629
|
+
* 切换面板
|
|
1630
|
+
*/
|
|
1631
|
+
toggle() {
|
|
1632
|
+
if (this.isOpen) {
|
|
1633
|
+
this.close();
|
|
1634
|
+
} else {
|
|
1635
|
+
this.open();
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
/**
|
|
1639
|
+
* 刷新内容
|
|
1640
|
+
*/
|
|
1641
|
+
refresh() {
|
|
1642
|
+
const activeTab = document.querySelector(".lytjs-devtools-tab.active");
|
|
1643
|
+
if (activeTab) {
|
|
1644
|
+
this.renderTab(activeTab.dataset.tab || "components");
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1648
|
+
function installDevTools(options2) {
|
|
1649
|
+
if (!devtoolsInstance) {
|
|
1650
|
+
devtoolsInstance = new DevTools(options2);
|
|
1651
|
+
}
|
|
1652
|
+
return devtoolsInstance;
|
|
1653
|
+
}
|
|
1654
|
+
function getDevTools() {
|
|
1655
|
+
return devtoolsInstance;
|
|
1656
|
+
}
|
|
1657
|
+
function uninstallDevTools() {
|
|
1658
|
+
if (devtoolsInstance) {
|
|
1659
|
+
devtoolsInstance.close();
|
|
1660
|
+
devtoolsInstance = null;
|
|
1661
|
+
}
|
|
1662
|
+
if (typeof document !== "undefined") {
|
|
1663
|
+
const panel = document.getElementById("lytjs-devtools");
|
|
1664
|
+
if (panel) {
|
|
1665
|
+
panel.remove();
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
exports.LARGE_SCALE_SCENARIOS = LARGE_SCALE_SCENARIOS;
|
|
1671
|
+
exports.acknowledgeAlert = acknowledgeAlert;
|
|
1672
|
+
exports.acknowledgeAllAlerts = acknowledgeAllAlerts;
|
|
1673
|
+
exports.addObserver = addObserver;
|
|
1674
|
+
exports.clearAlerts = clearAlerts;
|
|
1675
|
+
exports.clearBenchmarkResults = clearBenchmarkResults;
|
|
1676
|
+
exports.clearMetrics = clearMetrics;
|
|
1677
|
+
exports.clearPerformanceRecords = clearPerformanceRecords;
|
|
1678
|
+
exports.clearRouteHistory = clearRouteHistory;
|
|
1679
|
+
exports.clearSignalRegistry = clearSignalRegistry;
|
|
1680
|
+
exports.clearSnapshots = clearSnapshots;
|
|
1681
|
+
exports.clearStoreRegistry = clearStoreRegistry;
|
|
1682
|
+
exports.compareBenchmarkResults = compareBenchmarkResults;
|
|
1683
|
+
exports.createLargeScaleBenchmark = createLargeScaleBenchmark;
|
|
1684
|
+
exports.createRegressionDetector = createRegressionDetector;
|
|
1685
|
+
exports.createSnapshot = createSnapshot;
|
|
1686
|
+
exports.default = installDevTools;
|
|
1687
|
+
exports.dispatchStoreAction = dispatchStoreAction;
|
|
1688
|
+
exports.getAlertRules = getAlertRules;
|
|
1689
|
+
exports.getAlerts = getAlerts;
|
|
1690
|
+
exports.getBenchmarkResults = getBenchmarkResults;
|
|
1691
|
+
exports.getComponentTree = getComponentTree;
|
|
1692
|
+
exports.getCurrentRoute = getCurrentRoute;
|
|
1693
|
+
exports.getDependencyGraph = getDependencyGraph;
|
|
1694
|
+
exports.getDevTools = getDevTools;
|
|
1695
|
+
exports.getLatestBenchmarkResult = getLatestBenchmarkResult;
|
|
1696
|
+
exports.getMemoryUsage = getMemoryUsage;
|
|
1697
|
+
exports.getMetrics = getMetrics;
|
|
1698
|
+
exports.getPerformanceRecords = getPerformanceRecords;
|
|
1699
|
+
exports.getPerformanceReport = getPerformanceReport;
|
|
1700
|
+
exports.getPerformanceStats = getPerformanceStats;
|
|
1701
|
+
exports.getRegisteredStoreIds = getRegisteredStoreIds;
|
|
1702
|
+
exports.getRouteHistory = getRouteHistory;
|
|
1703
|
+
exports.getRoutes = getRoutes;
|
|
1704
|
+
exports.getSignalNode = getSignalNode;
|
|
1705
|
+
exports.getSignalNodes = getSignalNodes;
|
|
1706
|
+
exports.getSnapshots = getSnapshots;
|
|
1707
|
+
exports.getStats = getStats;
|
|
1708
|
+
exports.getStoreState = getStoreState;
|
|
1709
|
+
exports.getStoreStates = getStoreStates;
|
|
1710
|
+
exports.getTimeTravelState = getTimeTravelState;
|
|
1711
|
+
exports.goBack = goBack;
|
|
1712
|
+
exports.initPerformanceMonitor = initPerformanceMonitor;
|
|
1713
|
+
exports.installDevTools = installDevTools;
|
|
1714
|
+
exports.isRouterRegistered = isRouterRegistered;
|
|
1715
|
+
exports.navigateTo = navigateTo;
|
|
1716
|
+
exports.navigateToName = navigateToName;
|
|
1717
|
+
exports.onStoreChange = onStoreChange;
|
|
1718
|
+
exports.recordDependency = recordDependency;
|
|
1719
|
+
exports.recordMetric = recordMetric;
|
|
1720
|
+
exports.recordSignalUpdate = recordSignalUpdate;
|
|
1721
|
+
exports.registerAlertRule = registerAlertRule;
|
|
1722
|
+
exports.registerRootComponent = registerRootComponent;
|
|
1723
|
+
exports.registerRouter = registerRouter;
|
|
1724
|
+
exports.registerSignal = registerSignal;
|
|
1725
|
+
exports.registerStore = registerStore;
|
|
1726
|
+
exports.removeObserver = removeObserver;
|
|
1727
|
+
exports.resetPerformanceMonitor = resetPerformanceMonitor;
|
|
1728
|
+
exports.restoreSnapshot = restoreSnapshot;
|
|
1729
|
+
exports.runAsyncBenchmark = runAsyncBenchmark;
|
|
1730
|
+
exports.runBenchmark = runBenchmark;
|
|
1731
|
+
exports.serializeAllBenchmarkResults = serializeAllBenchmarkResults;
|
|
1732
|
+
exports.serializeBenchmarkResult = serializeBenchmarkResult;
|
|
1733
|
+
exports.serializeComponentTree = serializeComponentTree;
|
|
1734
|
+
exports.serializeDependencyGraph = serializeDependencyGraph;
|
|
1735
|
+
exports.serializeMemoryUsage = serializeMemoryUsage;
|
|
1736
|
+
exports.serializePerformanceReport = serializePerformanceReport;
|
|
1737
|
+
exports.serializePerformanceStats = serializePerformanceStats;
|
|
1738
|
+
exports.serializeRouteInfo = serializeRouteInfo;
|
|
1739
|
+
exports.serializeSignalNode = serializeSignalNode;
|
|
1740
|
+
exports.serializeStoreStates = serializeStoreStates;
|
|
1741
|
+
exports.setAlertRuleEnabled = setAlertRuleEnabled;
|
|
1742
|
+
exports.setStoreState = setStoreState;
|
|
1743
|
+
exports.startTimer = startTimer;
|
|
1744
|
+
exports.subscribeStore = subscribeStore;
|
|
1745
|
+
exports.uninstallDevTools = uninstallDevTools;
|
|
1746
|
+
exports.unregisterAlertRule = unregisterAlertRule;
|
|
1747
|
+
exports.unregisterRootComponent = unregisterRootComponent;
|
|
1748
|
+
exports.unregisterRouter = unregisterRouter;
|
|
1749
|
+
exports.unregisterSignal = unregisterSignal;
|
|
1750
|
+
exports.unregisterStore = unregisterStore;
|
|
1751
|
+
exports.unsubscribeStore = unsubscribeStore;
|
|
1752
|
+
exports.unwatchRouteChanges = unwatchRouteChanges;
|
|
1753
|
+
exports.watchRouteChanges = watchRouteChanges;
|
|
1754
|
+
//# sourceMappingURL=index.cjs.map
|
|
1755
|
+
//# sourceMappingURL=index.cjs.map
|