@react-devtools-plus/kit 0.2.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/LICENSE +21 -0
- package/dist/index.cjs +3732 -0
- package/dist/index.d.cts +466 -0
- package/dist/index.d.ts +466 -0
- package/dist/index.js +3649 -0
- package/package.json +42 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3649 @@
|
|
|
1
|
+
import { isBrowser, target } from "@react-devtools-plus/shared";
|
|
2
|
+
|
|
3
|
+
//#region src/types/index.ts
|
|
4
|
+
const REACT_TAGS = {
|
|
5
|
+
FunctionComponent: 0,
|
|
6
|
+
ClassComponent: 1,
|
|
7
|
+
IndeterminateComponent: 2,
|
|
8
|
+
HostRoot: 3,
|
|
9
|
+
HostComponent: 5,
|
|
10
|
+
HostText: 6,
|
|
11
|
+
Fragment: 7,
|
|
12
|
+
Mode: 8,
|
|
13
|
+
ContextConsumer: 9,
|
|
14
|
+
ContextProvider: 10,
|
|
15
|
+
ForwardRef: 11,
|
|
16
|
+
SuspenseComponent: 13,
|
|
17
|
+
MemoComponent: 14,
|
|
18
|
+
SimpleMemoComponent: 15
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/core/fiber/utils.ts
|
|
23
|
+
function getDisplayName(fiber) {
|
|
24
|
+
var _resolvedType$render;
|
|
25
|
+
const { elementType, type, tag } = fiber;
|
|
26
|
+
const resolvedType = elementType || type;
|
|
27
|
+
if (!resolvedType) {
|
|
28
|
+
if (tag === REACT_TAGS.HostRoot) return "Root";
|
|
29
|
+
if (tag === REACT_TAGS.HostComponent) return typeof fiber.type === "string" ? fiber.type : "Host";
|
|
30
|
+
return "Unknown";
|
|
31
|
+
}
|
|
32
|
+
if (typeof resolvedType === "string") return resolvedType;
|
|
33
|
+
if (resolvedType.displayName) return resolvedType.displayName;
|
|
34
|
+
if (resolvedType.name) return resolvedType.name;
|
|
35
|
+
if (resolvedType.__name) return resolvedType.__name;
|
|
36
|
+
if (resolvedType.type) {
|
|
37
|
+
const innerType = resolvedType.type;
|
|
38
|
+
if (innerType === null || innerType === void 0 ? void 0 : innerType.displayName) return innerType.displayName;
|
|
39
|
+
if (innerType === null || innerType === void 0 ? void 0 : innerType.name) return innerType.name;
|
|
40
|
+
if (innerType === null || innerType === void 0 ? void 0 : innerType.__name) return innerType.__name;
|
|
41
|
+
}
|
|
42
|
+
if ((_resolvedType$render = resolvedType.render) === null || _resolvedType$render === void 0 ? void 0 : _resolvedType$render.name) return resolvedType.render.name;
|
|
43
|
+
if (typeof resolvedType === "function") {
|
|
44
|
+
const funcName = resolvedType.name;
|
|
45
|
+
if (funcName && funcName !== "") return funcName;
|
|
46
|
+
}
|
|
47
|
+
return "Anonymous";
|
|
48
|
+
}
|
|
49
|
+
function shouldIncludeFiber(fiber, showHostComponents) {
|
|
50
|
+
if (fiber.tag === REACT_TAGS.HostText) return false;
|
|
51
|
+
if (fiber.tag === REACT_TAGS.Fragment || fiber.tag === REACT_TAGS.Mode || fiber.tag === REACT_TAGS.HostRoot) return false;
|
|
52
|
+
if (!showHostComponents && fiber.tag === REACT_TAGS.HostComponent) return false;
|
|
53
|
+
return [
|
|
54
|
+
REACT_TAGS.HostComponent,
|
|
55
|
+
REACT_TAGS.FunctionComponent,
|
|
56
|
+
REACT_TAGS.ClassComponent,
|
|
57
|
+
REACT_TAGS.ForwardRef,
|
|
58
|
+
REACT_TAGS.MemoComponent,
|
|
59
|
+
REACT_TAGS.SimpleMemoComponent,
|
|
60
|
+
REACT_TAGS.IndeterminateComponent,
|
|
61
|
+
REACT_TAGS.ContextProvider,
|
|
62
|
+
REACT_TAGS.ContextConsumer,
|
|
63
|
+
REACT_TAGS.SuspenseComponent
|
|
64
|
+
].includes(fiber.tag);
|
|
65
|
+
}
|
|
66
|
+
let fiberIdCounter = 0;
|
|
67
|
+
const fiberIdMap = /* @__PURE__ */ new WeakMap();
|
|
68
|
+
function getFiberId(fiber) {
|
|
69
|
+
if (!fiberIdMap.has(fiber)) fiberIdMap.set(fiber, `react-fiber-${++fiberIdCounter}`);
|
|
70
|
+
return fiberIdMap.get(fiber);
|
|
71
|
+
}
|
|
72
|
+
function getFiberFromElement(element) {
|
|
73
|
+
const keys = Object.keys(element);
|
|
74
|
+
for (const key of keys) {
|
|
75
|
+
if (key.startsWith("__reactFiber")) return element[key];
|
|
76
|
+
if (key.startsWith("__reactInternalInstance")) return element[key];
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/core/context/index.ts
|
|
83
|
+
/**
|
|
84
|
+
* Serialize a value into a displayable PropValue
|
|
85
|
+
*/
|
|
86
|
+
function serializeValue$1(value, depth = 0, maxDepth = 6) {
|
|
87
|
+
if (value === null) return {
|
|
88
|
+
type: "null",
|
|
89
|
+
value: "null"
|
|
90
|
+
};
|
|
91
|
+
if (value === void 0) return {
|
|
92
|
+
type: "undefined",
|
|
93
|
+
value: "undefined"
|
|
94
|
+
};
|
|
95
|
+
const type = typeof value;
|
|
96
|
+
if (type === "string") return {
|
|
97
|
+
type: "string",
|
|
98
|
+
value: `"${value.length > 100 ? `${value.slice(0, 100)}...` : value}"`
|
|
99
|
+
};
|
|
100
|
+
if (type === "number") return {
|
|
101
|
+
type: "number",
|
|
102
|
+
value: String(value)
|
|
103
|
+
};
|
|
104
|
+
if (type === "boolean") return {
|
|
105
|
+
type: "boolean",
|
|
106
|
+
value: String(value)
|
|
107
|
+
};
|
|
108
|
+
if (type === "function") return {
|
|
109
|
+
type: "function",
|
|
110
|
+
value: `ƒ ${value.name || "anonymous"}()`
|
|
111
|
+
};
|
|
112
|
+
if (type === "symbol") return {
|
|
113
|
+
type: "symbol",
|
|
114
|
+
value: value.toString()
|
|
115
|
+
};
|
|
116
|
+
if (depth > maxDepth) {
|
|
117
|
+
if (Array.isArray(value)) return {
|
|
118
|
+
type: "array",
|
|
119
|
+
value: `Array(${value.length})`
|
|
120
|
+
};
|
|
121
|
+
return {
|
|
122
|
+
type: "object",
|
|
123
|
+
value: "Object"
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
if (Array.isArray(value)) {
|
|
127
|
+
const children = {};
|
|
128
|
+
value.forEach((item, index) => {
|
|
129
|
+
children[String(index)] = serializeValue$1(item, depth + 1, maxDepth);
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
type: "array",
|
|
133
|
+
value: `Array(${value.length})`,
|
|
134
|
+
children: Object.keys(children).length > 0 ? children : void 0
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (type === "object") {
|
|
138
|
+
if (value.$$typeof) {
|
|
139
|
+
var _value$type, _value$type2;
|
|
140
|
+
return {
|
|
141
|
+
type: "element",
|
|
142
|
+
value: `<${((_value$type = value.type) === null || _value$type === void 0 ? void 0 : _value$type.displayName) || ((_value$type2 = value.type) === null || _value$type2 === void 0 ? void 0 : _value$type2.name) || value.type || "Unknown"} />`
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const keys = Object.keys(value);
|
|
146
|
+
const children = {};
|
|
147
|
+
for (const key of keys) try {
|
|
148
|
+
children[key] = serializeValue$1(value[key], depth + 1, maxDepth);
|
|
149
|
+
} catch (_unused) {
|
|
150
|
+
children[key] = {
|
|
151
|
+
type: "unknown",
|
|
152
|
+
value: "[Error]"
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
type: "object",
|
|
157
|
+
value: `Object`,
|
|
158
|
+
preview: keys.length > 0 ? `{${keys.slice(0, 3).join(", ")}${keys.length > 3 ? ", ..." : ""}}` : "{}",
|
|
159
|
+
children: Object.keys(children).length > 0 ? children : void 0
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
type: "unknown",
|
|
164
|
+
value: String(value)
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the display name of a Context
|
|
169
|
+
*/
|
|
170
|
+
function getContextDisplayName(fiber) {
|
|
171
|
+
var _fiber$type, _contextType$Provider, _contextType$Consumer;
|
|
172
|
+
const contextType = ((_fiber$type = fiber.type) === null || _fiber$type === void 0 ? void 0 : _fiber$type._context) || fiber.type;
|
|
173
|
+
if (!contextType) return "Unknown Context";
|
|
174
|
+
if (contextType.displayName) return contextType.displayName;
|
|
175
|
+
if ((_contextType$Provider = contextType.Provider) === null || _contextType$Provider === void 0 ? void 0 : _contextType$Provider.displayName) return contextType.Provider.displayName.replace(".Provider", "");
|
|
176
|
+
if ((_contextType$Consumer = contextType.Consumer) === null || _contextType$Consumer === void 0 ? void 0 : _contextType$Consumer.displayName) return contextType.Consumer.displayName.replace(".Consumer", "");
|
|
177
|
+
const componentName = getDisplayName(fiber);
|
|
178
|
+
if (componentName && componentName !== "Anonymous") return componentName.replace(".Provider", "").replace(".Consumer", "");
|
|
179
|
+
return "Context";
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Get the context value from a Provider fiber
|
|
183
|
+
*/
|
|
184
|
+
function getContextValue(fiber) {
|
|
185
|
+
if (fiber.memoizedProps && "value" in fiber.memoizedProps) return fiber.memoizedProps.value;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if a fiber is a Context Provider
|
|
189
|
+
*/
|
|
190
|
+
function isContextProvider(fiber) {
|
|
191
|
+
return fiber.tag === REACT_TAGS.ContextProvider;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Find all consumers of a specific context type
|
|
195
|
+
*/
|
|
196
|
+
function findConsumers(fiber, contextType, consumers, visited) {
|
|
197
|
+
if (!fiber || visited.has(fiber)) return;
|
|
198
|
+
visited.add(fiber);
|
|
199
|
+
if (fiber.tag === REACT_TAGS.ContextConsumer) {
|
|
200
|
+
var _fiber$type2;
|
|
201
|
+
if ((((_fiber$type2 = fiber.type) === null || _fiber$type2 === void 0 ? void 0 : _fiber$type2._context) || fiber.type) === contextType) consumers.push({
|
|
202
|
+
id: getFiberId(fiber),
|
|
203
|
+
name: getDisplayName(fiber),
|
|
204
|
+
fiberId: getFiberId(fiber)
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
if (fiber.tag === REACT_TAGS.FunctionComponent || fiber.tag === REACT_TAGS.ForwardRef || fiber.tag === REACT_TAGS.MemoComponent || fiber.tag === REACT_TAGS.SimpleMemoComponent) {
|
|
208
|
+
let hookState = fiber.memoizedState;
|
|
209
|
+
while (hookState) {
|
|
210
|
+
if (hookState.memoizedState !== void 0) {
|
|
211
|
+
const dependencies = fiber.dependencies;
|
|
212
|
+
if (dependencies === null || dependencies === void 0 ? void 0 : dependencies.firstContext) {
|
|
213
|
+
let contextItem = dependencies.firstContext;
|
|
214
|
+
while (contextItem) {
|
|
215
|
+
if (contextItem.context === contextType) {
|
|
216
|
+
consumers.push({
|
|
217
|
+
id: getFiberId(fiber),
|
|
218
|
+
name: getDisplayName(fiber),
|
|
219
|
+
fiberId: getFiberId(fiber)
|
|
220
|
+
});
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
contextItem = contextItem.next;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
hookState = hookState.next;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (fiber.child) findConsumers(fiber.child, contextType, consumers, visited);
|
|
231
|
+
if (fiber.sibling) findConsumers(fiber.sibling, contextType, consumers, visited);
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Build context provider info from a fiber
|
|
235
|
+
*/
|
|
236
|
+
function buildProviderInfo(fiber, visited) {
|
|
237
|
+
var _fiber$type3;
|
|
238
|
+
if (!isContextProvider(fiber)) return null;
|
|
239
|
+
const contextType = (_fiber$type3 = fiber.type) === null || _fiber$type3 === void 0 ? void 0 : _fiber$type3._context;
|
|
240
|
+
const consumers = [];
|
|
241
|
+
if (fiber.child) findConsumers(fiber.child, contextType, consumers, /* @__PURE__ */ new WeakSet());
|
|
242
|
+
const uniqueConsumers = consumers.filter((consumer, index, self) => index === self.findIndex((c) => c.id === consumer.id));
|
|
243
|
+
const info = {
|
|
244
|
+
id: getFiberId(fiber),
|
|
245
|
+
name: getContextDisplayName(fiber),
|
|
246
|
+
value: serializeValue$1(getContextValue(fiber)),
|
|
247
|
+
fiberId: getFiberId(fiber),
|
|
248
|
+
consumerCount: uniqueConsumers.length,
|
|
249
|
+
consumers: uniqueConsumers,
|
|
250
|
+
children: [],
|
|
251
|
+
source: fiber._debugSource ? {
|
|
252
|
+
fileName: fiber._debugSource.fileName,
|
|
253
|
+
lineNumber: fiber._debugSource.lineNumber,
|
|
254
|
+
columnNumber: fiber._debugSource.columnNumber
|
|
255
|
+
} : void 0
|
|
256
|
+
};
|
|
257
|
+
const findNestedProviders = (child) => {
|
|
258
|
+
var _child$type;
|
|
259
|
+
if (!child || visited.has(child)) return;
|
|
260
|
+
visited.add(child);
|
|
261
|
+
if (isContextProvider(child) && ((_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type._context) === contextType) {
|
|
262
|
+
const nestedInfo = buildProviderInfo(child, visited);
|
|
263
|
+
if (nestedInfo) info.children.push(nestedInfo);
|
|
264
|
+
} else {
|
|
265
|
+
if (child.child) findNestedProviders(child.child);
|
|
266
|
+
if (child.sibling) findNestedProviders(child.sibling);
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
if (fiber.child) findNestedProviders(fiber.child);
|
|
270
|
+
return info;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Collect all context providers from the fiber tree
|
|
274
|
+
*/
|
|
275
|
+
function collectProviders(fiber, providers, visited, processedContextTypes) {
|
|
276
|
+
if (!fiber || visited.has(fiber)) return;
|
|
277
|
+
visited.add(fiber);
|
|
278
|
+
if (isContextProvider(fiber)) {
|
|
279
|
+
var _fiber$type4;
|
|
280
|
+
const contextType = (_fiber$type4 = fiber.type) === null || _fiber$type4 === void 0 ? void 0 : _fiber$type4._context;
|
|
281
|
+
if (contextType && !processedContextTypes.has(contextType)) {
|
|
282
|
+
const info = buildProviderInfo(fiber, new WeakSet([fiber]));
|
|
283
|
+
if (info) {
|
|
284
|
+
providers.push(info);
|
|
285
|
+
processedContextTypes.add(contextType);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (fiber.child) collectProviders(fiber.child, providers, visited, processedContextTypes);
|
|
290
|
+
if (fiber.sibling) collectProviders(fiber.sibling, providers, visited, processedContextTypes);
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Get the context tree from a fiber root
|
|
294
|
+
*/
|
|
295
|
+
function getContextTree(root) {
|
|
296
|
+
var _root$current;
|
|
297
|
+
const providers = [];
|
|
298
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
299
|
+
const processedContextTypes = /* @__PURE__ */ new Set();
|
|
300
|
+
if (root === null || root === void 0 || (_root$current = root.current) === null || _root$current === void 0 ? void 0 : _root$current.child) collectProviders(root.current.child, providers, visited, processedContextTypes);
|
|
301
|
+
let totalConsumers = 0;
|
|
302
|
+
const countConsumers = (providerList) => {
|
|
303
|
+
for (const provider of providerList) {
|
|
304
|
+
totalConsumers += provider.consumerCount;
|
|
305
|
+
if (provider.children.length > 0) countConsumers(provider.children);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
countConsumers(providers);
|
|
309
|
+
return {
|
|
310
|
+
providers,
|
|
311
|
+
totalProviders: providers.length,
|
|
312
|
+
totalConsumers
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Get context info for a specific provider by fiber ID
|
|
317
|
+
*/
|
|
318
|
+
function getContextProviderInfo(root, fiberId) {
|
|
319
|
+
const tree = getContextTree(root);
|
|
320
|
+
const findProvider = (providers) => {
|
|
321
|
+
for (const provider of providers) {
|
|
322
|
+
if (provider.fiberId === fiberId) return provider;
|
|
323
|
+
const found = findProvider(provider.children);
|
|
324
|
+
if (found) return found;
|
|
325
|
+
}
|
|
326
|
+
return null;
|
|
327
|
+
};
|
|
328
|
+
return findProvider(tree.providers);
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Get all contexts available in the application
|
|
332
|
+
*/
|
|
333
|
+
function getAllContexts(root) {
|
|
334
|
+
return getContextTree(root);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/core/fiber/details.ts
|
|
339
|
+
/**
|
|
340
|
+
* Serialize a value into a displayable PropValue
|
|
341
|
+
*/
|
|
342
|
+
function serializeValue(value, depth = 0, maxDepth = 8) {
|
|
343
|
+
if (value === null) return {
|
|
344
|
+
type: "null",
|
|
345
|
+
value: "null"
|
|
346
|
+
};
|
|
347
|
+
if (value === void 0) return {
|
|
348
|
+
type: "undefined",
|
|
349
|
+
value: "undefined"
|
|
350
|
+
};
|
|
351
|
+
const type = typeof value;
|
|
352
|
+
if (type === "string") return {
|
|
353
|
+
type: "string",
|
|
354
|
+
value: `"${value.length > 100 ? `${value.slice(0, 100)}...` : value}"`
|
|
355
|
+
};
|
|
356
|
+
if (type === "number") return {
|
|
357
|
+
type: "number",
|
|
358
|
+
value: String(value)
|
|
359
|
+
};
|
|
360
|
+
if (type === "boolean") return {
|
|
361
|
+
type: "boolean",
|
|
362
|
+
value: String(value)
|
|
363
|
+
};
|
|
364
|
+
if (type === "function") return {
|
|
365
|
+
type: "function",
|
|
366
|
+
value: `ƒ ${value.name || "anonymous"}()`
|
|
367
|
+
};
|
|
368
|
+
if (type === "symbol") return {
|
|
369
|
+
type: "symbol",
|
|
370
|
+
value: value.toString()
|
|
371
|
+
};
|
|
372
|
+
if (depth > maxDepth) {
|
|
373
|
+
if (Array.isArray(value)) return {
|
|
374
|
+
type: "array",
|
|
375
|
+
value: `Array(${value.length})`
|
|
376
|
+
};
|
|
377
|
+
return {
|
|
378
|
+
type: "object",
|
|
379
|
+
value: "Object"
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
if (Array.isArray(value)) {
|
|
383
|
+
const children = {};
|
|
384
|
+
value.forEach((item, index) => {
|
|
385
|
+
children[String(index)] = serializeValue(item, depth + 1, maxDepth);
|
|
386
|
+
});
|
|
387
|
+
return {
|
|
388
|
+
type: "array",
|
|
389
|
+
value: `Array(${value.length})`,
|
|
390
|
+
children: Object.keys(children).length > 0 ? children : void 0
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
if (type === "object") {
|
|
394
|
+
if (value.$$typeof) {
|
|
395
|
+
var _value$type, _value$type2;
|
|
396
|
+
return {
|
|
397
|
+
type: "element",
|
|
398
|
+
value: `<${((_value$type = value.type) === null || _value$type === void 0 ? void 0 : _value$type.displayName) || ((_value$type2 = value.type) === null || _value$type2 === void 0 ? void 0 : _value$type2.name) || value.type || "Unknown"} />`
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
const keys = Object.keys(value);
|
|
402
|
+
const children = {};
|
|
403
|
+
for (const key of keys) try {
|
|
404
|
+
children[key] = serializeValue(value[key], depth + 1, maxDepth);
|
|
405
|
+
} catch (_unused) {
|
|
406
|
+
children[key] = {
|
|
407
|
+
type: "unknown",
|
|
408
|
+
value: "[Error]"
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
return {
|
|
412
|
+
type: "object",
|
|
413
|
+
value: `Object`,
|
|
414
|
+
preview: keys.length > 0 ? `{${keys.slice(0, 3).join(", ")}${keys.length > 3 ? ", ..." : ""}}` : "{}",
|
|
415
|
+
children: Object.keys(children).length > 0 ? children : void 0
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
return {
|
|
419
|
+
type: "unknown",
|
|
420
|
+
value: String(value)
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Extract props from fiber
|
|
425
|
+
*/
|
|
426
|
+
function extractProps(fiber) {
|
|
427
|
+
const props = {};
|
|
428
|
+
const memoizedProps = fiber.memoizedProps;
|
|
429
|
+
if (!memoizedProps || typeof memoizedProps !== "object") return props;
|
|
430
|
+
for (const [key, value] of Object.entries(memoizedProps)) {
|
|
431
|
+
if (key === "children") {
|
|
432
|
+
if (value) if (Array.isArray(value)) props[key] = {
|
|
433
|
+
type: "array",
|
|
434
|
+
value: `[${value.length} children]`
|
|
435
|
+
};
|
|
436
|
+
else if (typeof value === "object" && value.$$typeof) {
|
|
437
|
+
var _type, _type2;
|
|
438
|
+
props[key] = {
|
|
439
|
+
type: "element",
|
|
440
|
+
value: `<${((_type = value.type) === null || _type === void 0 ? void 0 : _type.displayName) || ((_type2 = value.type) === null || _type2 === void 0 ? void 0 : _type2.name) || value.type || "Element"} />`
|
|
441
|
+
};
|
|
442
|
+
} else if (typeof value === "string") props[key] = {
|
|
443
|
+
type: "string",
|
|
444
|
+
value: `"${value.slice(0, 50)}${value.length > 50 ? "..." : ""}"`
|
|
445
|
+
};
|
|
446
|
+
else props[key] = serializeValue(value);
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
props[key] = serializeValue(value);
|
|
450
|
+
}
|
|
451
|
+
return props;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Hook type names from React internals
|
|
455
|
+
*/
|
|
456
|
+
const HOOK_NAMES = {
|
|
457
|
+
0: "useState",
|
|
458
|
+
1: "useReducer",
|
|
459
|
+
2: "useContext",
|
|
460
|
+
3: "useRef",
|
|
461
|
+
4: "useEffect",
|
|
462
|
+
5: "useInsertionEffect",
|
|
463
|
+
6: "useLayoutEffect",
|
|
464
|
+
7: "useCallback",
|
|
465
|
+
8: "useMemo",
|
|
466
|
+
9: "useImperativeHandle",
|
|
467
|
+
10: "useDebugValue",
|
|
468
|
+
11: "useDeferredValue",
|
|
469
|
+
12: "useTransition",
|
|
470
|
+
13: "useMutableSource",
|
|
471
|
+
14: "useSyncExternalStore",
|
|
472
|
+
15: "useId",
|
|
473
|
+
16: "useCacheRefresh"
|
|
474
|
+
};
|
|
475
|
+
/**
|
|
476
|
+
* Extract hooks from fiber's memoizedState
|
|
477
|
+
*/
|
|
478
|
+
function extractHooks(fiber) {
|
|
479
|
+
const hooks = [];
|
|
480
|
+
if (fiber.tag !== REACT_TAGS.FunctionComponent && fiber.tag !== REACT_TAGS.ForwardRef && fiber.tag !== REACT_TAGS.SimpleMemoComponent && fiber.tag !== REACT_TAGS.MemoComponent) return hooks;
|
|
481
|
+
const debugHookTypes = fiber._debugHookTypes;
|
|
482
|
+
let hookState = fiber.memoizedState;
|
|
483
|
+
let hookIndex = 0;
|
|
484
|
+
while (hookState) {
|
|
485
|
+
let hookName = "Hook";
|
|
486
|
+
if (debugHookTypes && debugHookTypes[hookIndex]) hookName = debugHookTypes[hookIndex];
|
|
487
|
+
else if (hookState.tag !== void 0 && HOOK_NAMES[hookState.tag]) hookName = HOOK_NAMES[hookState.tag];
|
|
488
|
+
else if (hookState.queue !== void 0 && hookState.baseState !== void 0) hookName = "useState";
|
|
489
|
+
else if (hookState.memoizedState !== void 0 && hookState.deps !== void 0) hookName = "useMemo/useCallback";
|
|
490
|
+
else if (hookState.current !== void 0) hookName = "useRef";
|
|
491
|
+
let value;
|
|
492
|
+
if (hookName === "useState" || hookName === "useReducer") value = serializeValue(hookState.memoizedState);
|
|
493
|
+
else if (hookName === "useRef") {
|
|
494
|
+
var _hookState$memoizedSt;
|
|
495
|
+
value = serializeValue((_hookState$memoizedSt = hookState.memoizedState) === null || _hookState$memoizedSt === void 0 ? void 0 : _hookState$memoizedSt.current);
|
|
496
|
+
} else if (hookName === "useContext") value = serializeValue(hookState.memoizedState);
|
|
497
|
+
else if (hookName === "useMemo" || hookName === "useCallback" || hookName === "useMemo/useCallback") {
|
|
498
|
+
const memoValue = hookState.memoizedState;
|
|
499
|
+
if (Array.isArray(memoValue) && memoValue.length >= 1) value = serializeValue(memoValue[0]);
|
|
500
|
+
else value = serializeValue(memoValue);
|
|
501
|
+
} else value = {
|
|
502
|
+
type: "unknown",
|
|
503
|
+
value: "..."
|
|
504
|
+
};
|
|
505
|
+
hooks.push({
|
|
506
|
+
name: hookName,
|
|
507
|
+
value
|
|
508
|
+
});
|
|
509
|
+
hookState = hookState.next;
|
|
510
|
+
hookIndex++;
|
|
511
|
+
}
|
|
512
|
+
return hooks;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Extract parent component chain (rendered by)
|
|
516
|
+
*/
|
|
517
|
+
function extractRenderedBy(fiber) {
|
|
518
|
+
const renderedBy = [];
|
|
519
|
+
let parent = fiber.return;
|
|
520
|
+
let depth = 0;
|
|
521
|
+
const maxDepth = 10;
|
|
522
|
+
while (parent && depth < maxDepth) {
|
|
523
|
+
if (parent.tag === REACT_TAGS.FunctionComponent || parent.tag === REACT_TAGS.ClassComponent || parent.tag === REACT_TAGS.ForwardRef || parent.tag === REACT_TAGS.MemoComponent || parent.tag === REACT_TAGS.SimpleMemoComponent || parent.tag === REACT_TAGS.ContextProvider) {
|
|
524
|
+
const name = getDisplayName(parent);
|
|
525
|
+
if (name && name !== "Anonymous") renderedBy.push({
|
|
526
|
+
id: getFiberId(parent),
|
|
527
|
+
name,
|
|
528
|
+
tag: parent.tag
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
parent = parent.return;
|
|
532
|
+
depth++;
|
|
533
|
+
}
|
|
534
|
+
return renderedBy;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Extract source location from fiber
|
|
538
|
+
*/
|
|
539
|
+
function extractSource(fiber) {
|
|
540
|
+
if (fiber._debugSource) return {
|
|
541
|
+
fileName: fiber._debugSource.fileName,
|
|
542
|
+
lineNumber: fiber._debugSource.lineNumber,
|
|
543
|
+
columnNumber: fiber._debugSource.columnNumber
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Get detailed information about a component from its fiber
|
|
548
|
+
*/
|
|
549
|
+
function getComponentDetails(fiber) {
|
|
550
|
+
return {
|
|
551
|
+
id: getFiberId(fiber),
|
|
552
|
+
name: getDisplayName(fiber),
|
|
553
|
+
tag: fiber.tag,
|
|
554
|
+
props: extractProps(fiber),
|
|
555
|
+
hooks: extractHooks(fiber),
|
|
556
|
+
renderedBy: extractRenderedBy(fiber),
|
|
557
|
+
source: extractSource(fiber),
|
|
558
|
+
key: fiber.key
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
//#endregion
|
|
563
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/typeof.js
|
|
564
|
+
function _typeof(o) {
|
|
565
|
+
"@babel/helpers - typeof";
|
|
566
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
|
|
567
|
+
return typeof o$1;
|
|
568
|
+
} : function(o$1) {
|
|
569
|
+
return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
|
|
570
|
+
}, _typeof(o);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
//#endregion
|
|
574
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/toPrimitive.js
|
|
575
|
+
function toPrimitive(t, r) {
|
|
576
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
577
|
+
var e = t[Symbol.toPrimitive];
|
|
578
|
+
if (void 0 !== e) {
|
|
579
|
+
var i = e.call(t, r || "default");
|
|
580
|
+
if ("object" != _typeof(i)) return i;
|
|
581
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
582
|
+
}
|
|
583
|
+
return ("string" === r ? String : Number)(t);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
//#endregion
|
|
587
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/toPropertyKey.js
|
|
588
|
+
function toPropertyKey(t) {
|
|
589
|
+
var i = toPrimitive(t, "string");
|
|
590
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
//#endregion
|
|
594
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/defineProperty.js
|
|
595
|
+
function _defineProperty(e, r, t) {
|
|
596
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
597
|
+
value: t,
|
|
598
|
+
enumerable: !0,
|
|
599
|
+
configurable: !0,
|
|
600
|
+
writable: !0
|
|
601
|
+
}) : e[r] = t, e;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
//#endregion
|
|
605
|
+
//#region \0@oxc-project+runtime@0.95.0/helpers/objectSpread2.js
|
|
606
|
+
function ownKeys(e, r) {
|
|
607
|
+
var t = Object.keys(e);
|
|
608
|
+
if (Object.getOwnPropertySymbols) {
|
|
609
|
+
var o = Object.getOwnPropertySymbols(e);
|
|
610
|
+
r && (o = o.filter(function(r$1) {
|
|
611
|
+
return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
|
|
612
|
+
})), t.push.apply(t, o);
|
|
613
|
+
}
|
|
614
|
+
return t;
|
|
615
|
+
}
|
|
616
|
+
function _objectSpread2(e) {
|
|
617
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
618
|
+
var t = null != arguments[r] ? arguments[r] : {};
|
|
619
|
+
r % 2 ? ownKeys(Object(t), !0).forEach(function(r$1) {
|
|
620
|
+
_defineProperty(e, r$1, t[r$1]);
|
|
621
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
|
|
622
|
+
Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
return e;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
//#endregion
|
|
629
|
+
//#region src/core/fiber/highlight.ts
|
|
630
|
+
const CONTAINER_ELEMENT_ID = "__react-devtools-component-inspector__";
|
|
631
|
+
const CARD_ELEMENT_ID = "__react-devtools-component-inspector__card__";
|
|
632
|
+
const COMPONENT_NAME_ELEMENT_ID = "__react-devtools-component-inspector__name__";
|
|
633
|
+
const INDICATOR_ELEMENT_ID = "__react-devtools-component-inspector__indicator__";
|
|
634
|
+
const SOURCE_FILE_ELEMENT_ID = "__react-devtools-component-inspector__source-file__";
|
|
635
|
+
const SOURCE_HINT_ELEMENT_ID = "__react-devtools-component-inspector__source-hint__";
|
|
636
|
+
let highlightHideTimer;
|
|
637
|
+
const containerStyles = {
|
|
638
|
+
display: "block",
|
|
639
|
+
zIndex: "2147483640",
|
|
640
|
+
position: "fixed",
|
|
641
|
+
backgroundColor: "color-mix(in srgb, var(--color-primary-500, #61dafb), transparent 85%)",
|
|
642
|
+
border: "1px solid color-mix(in srgb, var(--color-primary-500, #61dafb), transparent 50%)",
|
|
643
|
+
borderRadius: "5px",
|
|
644
|
+
transition: "all 0.1s ease-in",
|
|
645
|
+
pointerEvents: "none"
|
|
646
|
+
};
|
|
647
|
+
const baseCardStyles = {
|
|
648
|
+
fontFamily: "Arial, Helvetica, sans-serif",
|
|
649
|
+
padding: "5px 8px",
|
|
650
|
+
borderRadius: "4px",
|
|
651
|
+
textAlign: "left",
|
|
652
|
+
position: "absolute",
|
|
653
|
+
left: "0",
|
|
654
|
+
color: "#fff",
|
|
655
|
+
fontSize: "14px",
|
|
656
|
+
fontWeight: "600",
|
|
657
|
+
lineHeight: "24px",
|
|
658
|
+
backgroundColor: "var(--color-primary-500, #61dafb)",
|
|
659
|
+
boxShadow: "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1)",
|
|
660
|
+
whiteSpace: "nowrap"
|
|
661
|
+
};
|
|
662
|
+
const cardStyles = _objectSpread2({}, baseCardStyles);
|
|
663
|
+
const sourceCardStyles = _objectSpread2(_objectSpread2({}, baseCardStyles), {}, {
|
|
664
|
+
fontFamily: "Menlo, Monaco, Consolas, \"Courier New\", monospace",
|
|
665
|
+
padding: "6px 10px",
|
|
666
|
+
boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
|
|
667
|
+
display: "flex",
|
|
668
|
+
flexDirection: "column",
|
|
669
|
+
gap: "2px"
|
|
670
|
+
});
|
|
671
|
+
const indicatorStyles = {
|
|
672
|
+
display: "inline-block",
|
|
673
|
+
fontWeight: "400",
|
|
674
|
+
fontStyle: "normal",
|
|
675
|
+
fontSize: "12px",
|
|
676
|
+
opacity: "0.7",
|
|
677
|
+
marginLeft: "6px"
|
|
678
|
+
};
|
|
679
|
+
const sourceFileStyles = {
|
|
680
|
+
fontSize: "12px",
|
|
681
|
+
fontWeight: "500"
|
|
682
|
+
};
|
|
683
|
+
const sourceHintStyles = {
|
|
684
|
+
fontSize: "10px",
|
|
685
|
+
opacity: "0.8",
|
|
686
|
+
fontWeight: "normal"
|
|
687
|
+
};
|
|
688
|
+
function getContainerElement() {
|
|
689
|
+
return document.getElementById(CONTAINER_ELEMENT_ID);
|
|
690
|
+
}
|
|
691
|
+
function createHighlightElement(rect, name, source) {
|
|
692
|
+
const containerEl = document.createElement("div");
|
|
693
|
+
containerEl.id = CONTAINER_ELEMENT_ID;
|
|
694
|
+
Object.assign(containerEl.style, containerStyles);
|
|
695
|
+
const cardEl = document.createElement("div");
|
|
696
|
+
cardEl.id = CARD_ELEMENT_ID;
|
|
697
|
+
if (source) {
|
|
698
|
+
Object.assign(cardEl.style, sourceCardStyles);
|
|
699
|
+
const sourceFileEl = document.createElement("div");
|
|
700
|
+
sourceFileEl.id = SOURCE_FILE_ELEMENT_ID;
|
|
701
|
+
Object.assign(sourceFileEl.style, sourceFileStyles);
|
|
702
|
+
cardEl.appendChild(sourceFileEl);
|
|
703
|
+
const sourceHintEl = document.createElement("div");
|
|
704
|
+
sourceHintEl.id = SOURCE_HINT_ELEMENT_ID;
|
|
705
|
+
Object.assign(sourceHintEl.style, sourceHintStyles);
|
|
706
|
+
sourceHintEl.textContent = "Click to go to the file";
|
|
707
|
+
cardEl.appendChild(sourceHintEl);
|
|
708
|
+
} else {
|
|
709
|
+
Object.assign(cardEl.style, cardStyles);
|
|
710
|
+
const nameEl = document.createElement("span");
|
|
711
|
+
nameEl.id = COMPONENT_NAME_ELEMENT_ID;
|
|
712
|
+
cardEl.appendChild(nameEl);
|
|
713
|
+
const indicatorEl = document.createElement("i");
|
|
714
|
+
indicatorEl.id = INDICATOR_ELEMENT_ID;
|
|
715
|
+
Object.assign(indicatorEl.style, indicatorStyles);
|
|
716
|
+
cardEl.appendChild(indicatorEl);
|
|
717
|
+
}
|
|
718
|
+
containerEl.appendChild(cardEl);
|
|
719
|
+
document.body.appendChild(containerEl);
|
|
720
|
+
updateHighlightElement(rect, name, source);
|
|
721
|
+
return containerEl;
|
|
722
|
+
}
|
|
723
|
+
function updateHighlightElement(rect, name, source) {
|
|
724
|
+
let containerEl = getContainerElement();
|
|
725
|
+
const cardEl = document.getElementById(CARD_ELEMENT_ID);
|
|
726
|
+
const hasSourceElement = document.getElementById(SOURCE_FILE_ELEMENT_ID);
|
|
727
|
+
if (containerEl && (!!source && !hasSourceElement || !source && hasSourceElement)) {
|
|
728
|
+
containerEl.remove();
|
|
729
|
+
containerEl = null;
|
|
730
|
+
}
|
|
731
|
+
if (!containerEl) {
|
|
732
|
+
createHighlightElement(rect, name, source);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
Object.assign(containerEl.style, {
|
|
736
|
+
left: `${Math.round(rect.left * 100) / 100}px`,
|
|
737
|
+
top: `${Math.round(rect.top * 100) / 100}px`,
|
|
738
|
+
width: `${Math.round(rect.width * 100) / 100}px`,
|
|
739
|
+
height: `${Math.round(rect.height * 100) / 100}px`,
|
|
740
|
+
display: "block",
|
|
741
|
+
opacity: "1",
|
|
742
|
+
backgroundColor: "color-mix(in srgb, var(--color-primary-500, #61dafb), transparent 85%)",
|
|
743
|
+
border: "1px solid color-mix(in srgb, var(--color-primary-500, #61dafb), transparent 50%)"
|
|
744
|
+
});
|
|
745
|
+
if (cardEl) Object.assign(cardEl.style, {
|
|
746
|
+
top: rect.top < 45 ? "100%" : "auto",
|
|
747
|
+
bottom: rect.top < 45 ? "auto" : "100%",
|
|
748
|
+
marginTop: rect.top < 45 ? "4px" : "0",
|
|
749
|
+
marginBottom: rect.top < 45 ? "0" : "4px"
|
|
750
|
+
});
|
|
751
|
+
if (source) {
|
|
752
|
+
const sourceFileEl = document.getElementById(SOURCE_FILE_ELEMENT_ID);
|
|
753
|
+
if (sourceFileEl) {
|
|
754
|
+
let cleanFileName = source.fileName;
|
|
755
|
+
const segments = cleanFileName.split("/");
|
|
756
|
+
const srcIndex = segments.findIndex((seg) => seg === "src");
|
|
757
|
+
if (srcIndex > 0) cleanFileName = segments.slice(srcIndex).join("/");
|
|
758
|
+
else if (segments.length > 1 && !cleanFileName.startsWith("/")) cleanFileName = segments.slice(1).join("/");
|
|
759
|
+
sourceFileEl.textContent = `${cleanFileName}:${source.lineNumber}:${source.columnNumber}`;
|
|
760
|
+
}
|
|
761
|
+
} else {
|
|
762
|
+
const nameEl = document.getElementById(COMPONENT_NAME_ELEMENT_ID);
|
|
763
|
+
if (nameEl) nameEl.textContent = name === "Element" ? "Element" : `<${name}>`;
|
|
764
|
+
const indicatorEl = document.getElementById(INDICATOR_ELEMENT_ID);
|
|
765
|
+
if (indicatorEl) indicatorEl.textContent = `${Math.round(rect.width * 100) / 100} x ${Math.round(rect.height * 100) / 100}`;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
function hideHighlight() {
|
|
769
|
+
const highlight = getContainerElement();
|
|
770
|
+
if (!highlight) return;
|
|
771
|
+
window.clearTimeout(highlightHideTimer);
|
|
772
|
+
highlight.style.opacity = "0";
|
|
773
|
+
highlightHideTimer = window.setTimeout(() => {
|
|
774
|
+
highlight.style.display = "none";
|
|
775
|
+
}, 150);
|
|
776
|
+
}
|
|
777
|
+
function showHighlight(rect, name, source) {
|
|
778
|
+
const highlight = getContainerElement();
|
|
779
|
+
window.clearTimeout(highlightHideTimer);
|
|
780
|
+
if (highlight) updateHighlightElement(rect, name, source);
|
|
781
|
+
else createHighlightElement(rect, name, source);
|
|
782
|
+
}
|
|
783
|
+
function mergeClientRects(rects) {
|
|
784
|
+
if (!rects.length) return null;
|
|
785
|
+
let top = Number.POSITIVE_INFINITY;
|
|
786
|
+
let left = Number.POSITIVE_INFINITY;
|
|
787
|
+
let right = Number.NEGATIVE_INFINITY;
|
|
788
|
+
let bottom = Number.NEGATIVE_INFINITY;
|
|
789
|
+
rects.forEach((rect) => {
|
|
790
|
+
top = Math.min(top, rect.top);
|
|
791
|
+
left = Math.min(left, rect.left);
|
|
792
|
+
right = Math.max(right, rect.right);
|
|
793
|
+
bottom = Math.max(bottom, rect.bottom);
|
|
794
|
+
});
|
|
795
|
+
return new DOMRect(left, top, Math.max(0, right - left), Math.max(0, bottom - top));
|
|
796
|
+
}
|
|
797
|
+
function isInOverlay(node) {
|
|
798
|
+
var _overlayContainer$con;
|
|
799
|
+
if (!node) return false;
|
|
800
|
+
const overlayContainer = document.getElementById("react-devtools-overlay");
|
|
801
|
+
return (_overlayContainer$con = overlayContainer === null || overlayContainer === void 0 ? void 0 : overlayContainer.contains(node)) !== null && _overlayContainer$con !== void 0 ? _overlayContainer$con : false;
|
|
802
|
+
}
|
|
803
|
+
function collectHostElements(fiber, elements, visited = /* @__PURE__ */ new WeakSet()) {
|
|
804
|
+
if (!fiber || visited.has(fiber)) return;
|
|
805
|
+
visited.add(fiber);
|
|
806
|
+
if (fiber.stateNode && isInOverlay(fiber.stateNode)) return;
|
|
807
|
+
if (fiber.tag === REACT_TAGS.HostComponent && fiber.stateNode instanceof Element) {
|
|
808
|
+
if (!isInOverlay(fiber.stateNode)) elements.add(fiber.stateNode);
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (fiber.tag === REACT_TAGS.HostText) {
|
|
812
|
+
var _fiber$stateNode;
|
|
813
|
+
const parent = (_fiber$stateNode = fiber.stateNode) === null || _fiber$stateNode === void 0 ? void 0 : _fiber$stateNode.parentElement;
|
|
814
|
+
if (parent && !isInOverlay(parent)) elements.add(parent);
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
let child = fiber.child;
|
|
818
|
+
while (child) {
|
|
819
|
+
collectHostElements(child, elements, visited);
|
|
820
|
+
child = child.sibling;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
function highlightNode(fiber, source) {
|
|
824
|
+
if (!fiber) {
|
|
825
|
+
hideHighlight();
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (fiber.tag === REACT_TAGS.HostComponent && fiber.stateNode instanceof Element) {
|
|
829
|
+
const element = fiber.stateNode;
|
|
830
|
+
const rect = element.getBoundingClientRect();
|
|
831
|
+
if (rect.width > 0 || rect.height > 0) {
|
|
832
|
+
showHighlight(rect, fiber.type || element.tagName.toLowerCase(), source);
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
const elements = /* @__PURE__ */ new Set();
|
|
837
|
+
collectHostElements(fiber, elements);
|
|
838
|
+
if (elements.size === 0) {
|
|
839
|
+
hideHighlight();
|
|
840
|
+
return;
|
|
841
|
+
}
|
|
842
|
+
const merged = mergeClientRects(Array.from(elements).map((element) => element.getBoundingClientRect()).filter((rect) => rect.width > 0 || rect.height > 0));
|
|
843
|
+
if (!merged || merged.width === 0 && merged.height === 0) {
|
|
844
|
+
hideHighlight();
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
showHighlight(merged, getDisplayName(fiber), source);
|
|
848
|
+
}
|
|
849
|
+
function cleanupHighlight() {
|
|
850
|
+
const el = getContainerElement();
|
|
851
|
+
el === null || el === void 0 || el.remove();
|
|
852
|
+
window.clearTimeout(highlightHideTimer);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Scroll the page to make the component visible
|
|
856
|
+
*/
|
|
857
|
+
function scrollToNode(fiber) {
|
|
858
|
+
if (!fiber) return;
|
|
859
|
+
if (fiber.tag === REACT_TAGS.HostComponent && fiber.stateNode instanceof Element) {
|
|
860
|
+
fiber.stateNode.scrollIntoView({
|
|
861
|
+
behavior: "smooth",
|
|
862
|
+
block: "center",
|
|
863
|
+
inline: "center"
|
|
864
|
+
});
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const elements = /* @__PURE__ */ new Set();
|
|
868
|
+
collectHostElements(fiber, elements);
|
|
869
|
+
if (elements.size === 0) return;
|
|
870
|
+
const firstElement = Array.from(elements)[0];
|
|
871
|
+
if (firstElement) firstElement.scrollIntoView({
|
|
872
|
+
behavior: "smooth",
|
|
873
|
+
block: "center",
|
|
874
|
+
inline: "center"
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
//#endregion
|
|
879
|
+
//#region src/core/fiber/tree.ts
|
|
880
|
+
const fiberRegistry = /* @__PURE__ */ new Map();
|
|
881
|
+
function getFiberById(id) {
|
|
882
|
+
return fiberRegistry.get(id);
|
|
883
|
+
}
|
|
884
|
+
function collectVisibleChildren(fiber, showHostComponents, nodes, visited) {
|
|
885
|
+
let current = fiber;
|
|
886
|
+
while (current) {
|
|
887
|
+
if (visited.has(current)) {
|
|
888
|
+
current = current.sibling;
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
if (shouldIncludeFiber(current, showHostComponents)) {
|
|
892
|
+
visited.add(current);
|
|
893
|
+
const treeChild = fiberToTree(current, showHostComponents, visited);
|
|
894
|
+
if (treeChild) nodes.push(treeChild);
|
|
895
|
+
} else if (current.child) collectVisibleChildren(current.child, showHostComponents, nodes, visited);
|
|
896
|
+
current = current.sibling;
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
function fiberToTree(fiber, showHostComponents, visited) {
|
|
900
|
+
if (!fiber) return null;
|
|
901
|
+
if (fiber.tag === REACT_TAGS.Mode || fiber.tag === REACT_TAGS.Fragment || fiber.tag === REACT_TAGS.HostRoot) return null;
|
|
902
|
+
const displayName = getDisplayName(fiber);
|
|
903
|
+
const node = {
|
|
904
|
+
id: getFiberId(fiber),
|
|
905
|
+
name: displayName,
|
|
906
|
+
children: [],
|
|
907
|
+
meta: { tag: fiber.tag }
|
|
908
|
+
};
|
|
909
|
+
fiberRegistry.set(node.id, fiber);
|
|
910
|
+
const childVisited = /* @__PURE__ */ new WeakSet();
|
|
911
|
+
collectVisibleChildren(fiber.child, showHostComponents, node.children, childVisited);
|
|
912
|
+
return node;
|
|
913
|
+
}
|
|
914
|
+
function buildTree(root, showHostComponents) {
|
|
915
|
+
if (!(root === null || root === void 0 ? void 0 : root.current)) return null;
|
|
916
|
+
const current = root.current;
|
|
917
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
918
|
+
let fiber = current.child;
|
|
919
|
+
let depth = 0;
|
|
920
|
+
while (fiber && depth < 20) {
|
|
921
|
+
depth++;
|
|
922
|
+
if (fiber.tag === REACT_TAGS.Mode || fiber.tag === REACT_TAGS.Fragment || fiber.tag === REACT_TAGS.HostRoot) {
|
|
923
|
+
fiber = fiber.child || fiber.sibling;
|
|
924
|
+
continue;
|
|
925
|
+
}
|
|
926
|
+
if (shouldIncludeFiber(fiber, showHostComponents)) return fiberToTree(fiber, showHostComponents, visited);
|
|
927
|
+
if (fiber.child) {
|
|
928
|
+
fiber = fiber.child;
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
fiber = fiber.sibling;
|
|
932
|
+
}
|
|
933
|
+
return null;
|
|
934
|
+
}
|
|
935
|
+
function clearFiberRegistry() {
|
|
936
|
+
fiberRegistry.clear();
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
//#endregion
|
|
940
|
+
//#region src/core/fiber/props.ts
|
|
941
|
+
/** Stores overridden props for UI display */
|
|
942
|
+
const overriddenProps = /* @__PURE__ */ new Map();
|
|
943
|
+
/** Stores overridden context values for UI display */
|
|
944
|
+
const overriddenContexts = /* @__PURE__ */ new Map();
|
|
945
|
+
/**
|
|
946
|
+
* Get the React renderer that has overrideProps API
|
|
947
|
+
*
|
|
948
|
+
* React DevTools hook may have multiple renderers. We need to find the one
|
|
949
|
+
* that provides the official overrideProps API (React's native renderer).
|
|
950
|
+
*/
|
|
951
|
+
function getRenderer() {
|
|
952
|
+
const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
953
|
+
if (!(hook === null || hook === void 0 ? void 0 : hook.renderers)) return null;
|
|
954
|
+
for (const renderer of hook.renderers.values()) if (renderer === null || renderer === void 0 ? void 0 : renderer.overrideProps) return renderer;
|
|
955
|
+
for (const renderer of hook.renderers.values()) if (renderer) return renderer;
|
|
956
|
+
return null;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Parse a string value to the appropriate JavaScript type
|
|
960
|
+
*
|
|
961
|
+
* @param value - The string representation of the value
|
|
962
|
+
* @param expectedType - The expected type of the value
|
|
963
|
+
* @returns The parsed value in the correct type
|
|
964
|
+
*/
|
|
965
|
+
function parseValue(value, expectedType) {
|
|
966
|
+
if (expectedType === "null" || expectedType === "undefined") {
|
|
967
|
+
if (value === "null") return null;
|
|
968
|
+
if (value === "undefined") return void 0;
|
|
969
|
+
return inferValueType(value);
|
|
970
|
+
}
|
|
971
|
+
switch (expectedType) {
|
|
972
|
+
case "number": return Number(value);
|
|
973
|
+
case "boolean": return value === "true";
|
|
974
|
+
case "object":
|
|
975
|
+
case "array": try {
|
|
976
|
+
return JSON.parse(value);
|
|
977
|
+
} catch (_unused) {
|
|
978
|
+
return value;
|
|
979
|
+
}
|
|
980
|
+
case "string":
|
|
981
|
+
default:
|
|
982
|
+
if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1);
|
|
983
|
+
return value;
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Infer the type of a value from its string representation
|
|
988
|
+
*
|
|
989
|
+
* Used when the original type is null/undefined and user enters a new value.
|
|
990
|
+
*/
|
|
991
|
+
function inferValueType(value) {
|
|
992
|
+
const trimmed = value.trim();
|
|
993
|
+
if (trimmed === "true") return true;
|
|
994
|
+
if (trimmed === "false") return false;
|
|
995
|
+
if (trimmed === "null") return null;
|
|
996
|
+
if (trimmed === "undefined") return void 0;
|
|
997
|
+
const num = Number(trimmed);
|
|
998
|
+
if (!Number.isNaN(num) && trimmed !== "") return num;
|
|
999
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]")) try {
|
|
1000
|
+
return JSON.parse(trimmed);
|
|
1001
|
+
} catch (_unused2) {}
|
|
1002
|
+
if (trimmed.startsWith("\"") && trimmed.endsWith("\"") || trimmed.startsWith("'") && trimmed.endsWith("'")) return trimmed.slice(1, -1);
|
|
1003
|
+
return trimmed;
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Set a nested property on an object immutably
|
|
1007
|
+
*
|
|
1008
|
+
* @param obj - The source object
|
|
1009
|
+
* @param path - Array of keys representing the path to the property
|
|
1010
|
+
* @param value - The value to set
|
|
1011
|
+
* @returns A new object with the updated value
|
|
1012
|
+
*/
|
|
1013
|
+
function setNestedValue(obj, path, value) {
|
|
1014
|
+
if (path.length === 0) return value;
|
|
1015
|
+
const result = Array.isArray(obj) ? [...obj] : _objectSpread2({}, obj);
|
|
1016
|
+
let current = result;
|
|
1017
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
1018
|
+
const key = path[i];
|
|
1019
|
+
const nextKey = path[i + 1];
|
|
1020
|
+
const isNextArray = !Number.isNaN(Number(nextKey));
|
|
1021
|
+
current[key] = current[key] ? Array.isArray(current[key]) ? [...current[key]] : _objectSpread2({}, current[key]) : isNextArray ? [] : {};
|
|
1022
|
+
current = current[key];
|
|
1023
|
+
}
|
|
1024
|
+
current[path[path.length - 1]] = value;
|
|
1025
|
+
return result;
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Force update a specific component and its ancestors
|
|
1029
|
+
*
|
|
1030
|
+
* Strategy:
|
|
1031
|
+
* 1. Try class component forceUpdate (safest)
|
|
1032
|
+
* 2. Try function component hooks with object/array state
|
|
1033
|
+
* 3. Try primitive state with toggle-and-restore
|
|
1034
|
+
*/
|
|
1035
|
+
function forceComponentUpdate(fiber) {
|
|
1036
|
+
if (fiber.stateNode && typeof fiber.stateNode.forceUpdate === "function") try {
|
|
1037
|
+
fiber.stateNode.forceUpdate();
|
|
1038
|
+
return true;
|
|
1039
|
+
} catch (_unused3) {}
|
|
1040
|
+
let current = fiber;
|
|
1041
|
+
let depth = 0;
|
|
1042
|
+
while (current && depth < 50) {
|
|
1043
|
+
if (current.stateNode && typeof current.stateNode.forceUpdate === "function") try {
|
|
1044
|
+
current.stateNode.forceUpdate();
|
|
1045
|
+
return true;
|
|
1046
|
+
} catch (_unused4) {}
|
|
1047
|
+
if (current.memoizedState !== null && typeof current.memoizedState === "object") {
|
|
1048
|
+
if (tryDispatchStateUpdate(current.memoizedState)) return true;
|
|
1049
|
+
}
|
|
1050
|
+
current = current.return;
|
|
1051
|
+
depth++;
|
|
1052
|
+
}
|
|
1053
|
+
return false;
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Try to dispatch a state update through hook state
|
|
1057
|
+
*/
|
|
1058
|
+
function tryDispatchStateUpdate(hookState) {
|
|
1059
|
+
while (hookState) {
|
|
1060
|
+
const queue = hookState.queue;
|
|
1061
|
+
const currentState = hookState.memoizedState;
|
|
1062
|
+
if (queue === null || queue === void 0 ? void 0 : queue.dispatch) try {
|
|
1063
|
+
const dispatch = queue.dispatch;
|
|
1064
|
+
if (currentState !== null && typeof currentState === "object") {
|
|
1065
|
+
dispatch(Array.isArray(currentState) ? [...currentState] : _objectSpread2({}, currentState));
|
|
1066
|
+
return true;
|
|
1067
|
+
} else if (typeof currentState === "boolean") {
|
|
1068
|
+
dispatch(!currentState);
|
|
1069
|
+
setTimeout(() => dispatch(currentState), 0);
|
|
1070
|
+
return true;
|
|
1071
|
+
} else if (typeof currentState === "number") {
|
|
1072
|
+
dispatch(currentState + 1e-7);
|
|
1073
|
+
setTimeout(() => dispatch(currentState), 0);
|
|
1074
|
+
return true;
|
|
1075
|
+
}
|
|
1076
|
+
} catch (_unused5) {}
|
|
1077
|
+
hookState = hookState.next;
|
|
1078
|
+
}
|
|
1079
|
+
return false;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Force update by finding any component in the tree with updatable state
|
|
1083
|
+
*/
|
|
1084
|
+
function forceGlobalUpdate() {
|
|
1085
|
+
try {
|
|
1086
|
+
const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
1087
|
+
if (!(hook === null || hook === void 0 ? void 0 : hook.renderers)) return false;
|
|
1088
|
+
for (const [rendererID] of hook.renderers.entries()) {
|
|
1089
|
+
var _hook$getFiberRoots;
|
|
1090
|
+
const roots = (_hook$getFiberRoots = hook.getFiberRoots) === null || _hook$getFiberRoots === void 0 ? void 0 : _hook$getFiberRoots.call(hook, rendererID);
|
|
1091
|
+
if (roots) {
|
|
1092
|
+
for (const root of roots) if (root.current) {
|
|
1093
|
+
if (findAndForceUpdate(root.current)) return true;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
} catch (_unused6) {}
|
|
1098
|
+
return false;
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Walk fiber tree to find a component that can be force-updated
|
|
1102
|
+
*/
|
|
1103
|
+
function findAndForceUpdate(fiber, depth = 0) {
|
|
1104
|
+
if (!fiber || depth > 100) return false;
|
|
1105
|
+
if (fiber.stateNode && typeof fiber.stateNode.forceUpdate === "function") try {
|
|
1106
|
+
fiber.stateNode.forceUpdate();
|
|
1107
|
+
return true;
|
|
1108
|
+
} catch (_unused7) {}
|
|
1109
|
+
if (fiber.memoizedState !== null && typeof fiber.memoizedState === "object") {
|
|
1110
|
+
if (tryDispatchStateUpdate(fiber.memoizedState)) return true;
|
|
1111
|
+
}
|
|
1112
|
+
if (fiber.child && findAndForceUpdate(fiber.child, depth + 1)) return true;
|
|
1113
|
+
if (fiber.sibling && findAndForceUpdate(fiber.sibling, depth + 1)) return true;
|
|
1114
|
+
return false;
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* Set a prop value on a component
|
|
1118
|
+
*
|
|
1119
|
+
* Uses React's official overrideProps API when available,
|
|
1120
|
+
* falls back to direct fiber manipulation otherwise.
|
|
1121
|
+
*
|
|
1122
|
+
* @param fiberId - The fiber ID of the component
|
|
1123
|
+
* @param propPath - Dot-separated path to the prop (e.g., "user.name")
|
|
1124
|
+
* @param value - The string representation of the new value
|
|
1125
|
+
* @param valueType - The expected type of the value
|
|
1126
|
+
* @returns Whether the operation succeeded
|
|
1127
|
+
*/
|
|
1128
|
+
function setComponentProp(fiberId, propPath, value, valueType) {
|
|
1129
|
+
const fiber = getFiberById(fiberId);
|
|
1130
|
+
if (!fiber) {
|
|
1131
|
+
console.warn(`[React DevTools] Fiber not found: ${fiberId}`);
|
|
1132
|
+
return false;
|
|
1133
|
+
}
|
|
1134
|
+
const parsedValue = parseValue(value, valueType);
|
|
1135
|
+
const pathParts = propPath.split(".");
|
|
1136
|
+
try {
|
|
1137
|
+
if (!overriddenProps.has(fiberId)) overriddenProps.set(fiberId, /* @__PURE__ */ new Map());
|
|
1138
|
+
overriddenProps.get(fiberId).set(propPath, parsedValue);
|
|
1139
|
+
const renderer = getRenderer();
|
|
1140
|
+
if (renderer === null || renderer === void 0 ? void 0 : renderer.overrideProps) try {
|
|
1141
|
+
renderer.overrideProps(fiber, pathParts, parsedValue);
|
|
1142
|
+
return true;
|
|
1143
|
+
} catch (_unused8) {
|
|
1144
|
+
const numericId = Number.parseInt(fiberId.replace("react-fiber-", ""), 10);
|
|
1145
|
+
if (!Number.isNaN(numericId)) try {
|
|
1146
|
+
renderer.overrideProps(numericId, pathParts, parsedValue);
|
|
1147
|
+
return true;
|
|
1148
|
+
} catch (_unused9) {}
|
|
1149
|
+
}
|
|
1150
|
+
const newProps = setNestedValue(fiber.memoizedProps || {}, pathParts, parsedValue);
|
|
1151
|
+
fiber.memoizedProps = newProps;
|
|
1152
|
+
fiber.pendingProps = newProps;
|
|
1153
|
+
if (fiber.alternate) {
|
|
1154
|
+
fiber.alternate.memoizedProps = newProps;
|
|
1155
|
+
fiber.alternate.pendingProps = newProps;
|
|
1156
|
+
}
|
|
1157
|
+
forceComponentUpdate(fiber) || forceGlobalUpdate();
|
|
1158
|
+
return true;
|
|
1159
|
+
} catch (error) {
|
|
1160
|
+
console.warn("[React DevTools] Failed to set prop:", error);
|
|
1161
|
+
return false;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
/**
|
|
1165
|
+
* Get an overridden prop value for UI display
|
|
1166
|
+
*/
|
|
1167
|
+
function getOverriddenProp(fiberId, propPath) {
|
|
1168
|
+
var _overriddenProps$get;
|
|
1169
|
+
return (_overriddenProps$get = overriddenProps.get(fiberId)) === null || _overriddenProps$get === void 0 ? void 0 : _overriddenProps$get.get(propPath);
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Check if a prop is editable
|
|
1173
|
+
*
|
|
1174
|
+
* Some props cannot be edited (children, key, ref, etc.)
|
|
1175
|
+
* Some types cannot be edited (functions, symbols, elements)
|
|
1176
|
+
*/
|
|
1177
|
+
function isEditableProp(propName, valueType) {
|
|
1178
|
+
if ([
|
|
1179
|
+
"children",
|
|
1180
|
+
"key",
|
|
1181
|
+
"ref",
|
|
1182
|
+
"$$typeof"
|
|
1183
|
+
].includes(propName)) return false;
|
|
1184
|
+
if ([
|
|
1185
|
+
"element",
|
|
1186
|
+
"function",
|
|
1187
|
+
"symbol"
|
|
1188
|
+
].includes(valueType)) return false;
|
|
1189
|
+
return true;
|
|
1190
|
+
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Set a Context Provider's value
|
|
1193
|
+
*
|
|
1194
|
+
* @param fiberId - The fiber ID of the Context Provider
|
|
1195
|
+
* @param value - The string representation of the new value
|
|
1196
|
+
* @param valueType - The expected type of the value
|
|
1197
|
+
* @returns Whether the operation succeeded
|
|
1198
|
+
*/
|
|
1199
|
+
function setContextValue(fiberId, value, valueType) {
|
|
1200
|
+
const fiber = getFiberById(fiberId);
|
|
1201
|
+
if (!fiber) {
|
|
1202
|
+
console.warn(`[React DevTools] Fiber not found: ${fiberId}`);
|
|
1203
|
+
return false;
|
|
1204
|
+
}
|
|
1205
|
+
if (fiber.tag !== REACT_TAGS.ContextProvider) {
|
|
1206
|
+
console.warn(`[React DevTools] Fiber is not a Context Provider`);
|
|
1207
|
+
return false;
|
|
1208
|
+
}
|
|
1209
|
+
try {
|
|
1210
|
+
return applyContextValue(fiber, parseValue(value, valueType), fiberId);
|
|
1211
|
+
} catch (error) {
|
|
1212
|
+
console.warn("[React DevTools] Failed to set context value:", error);
|
|
1213
|
+
return false;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
/**
|
|
1217
|
+
* Set a Context Provider's value from a JSON string
|
|
1218
|
+
*
|
|
1219
|
+
* Used for complex objects where JSON editing is more convenient.
|
|
1220
|
+
*/
|
|
1221
|
+
function setContextValueFromJson(fiberId, jsonValue) {
|
|
1222
|
+
const fiber = getFiberById(fiberId);
|
|
1223
|
+
if (!fiber) {
|
|
1224
|
+
console.warn(`[React DevTools] Fiber not found: ${fiberId}`);
|
|
1225
|
+
return false;
|
|
1226
|
+
}
|
|
1227
|
+
if (fiber.tag !== REACT_TAGS.ContextProvider) {
|
|
1228
|
+
console.warn(`[React DevTools] Fiber is not a Context Provider`);
|
|
1229
|
+
return false;
|
|
1230
|
+
}
|
|
1231
|
+
try {
|
|
1232
|
+
return applyContextValue(fiber, JSON.parse(jsonValue), fiberId);
|
|
1233
|
+
} catch (error) {
|
|
1234
|
+
console.warn("[React DevTools] Failed to set context value from JSON:", error);
|
|
1235
|
+
return false;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* Set a nested property within a Context Provider's value
|
|
1240
|
+
*
|
|
1241
|
+
* @param fiberId - The fiber ID of the Context Provider
|
|
1242
|
+
* @param path - Dot-separated path to the property (e.g., "theme.mode")
|
|
1243
|
+
* @param value - The string representation of the new value
|
|
1244
|
+
* @param valueType - The expected type of the value
|
|
1245
|
+
* @returns Whether the operation succeeded
|
|
1246
|
+
*/
|
|
1247
|
+
function setContextValueAtPath(fiberId, path, value, valueType) {
|
|
1248
|
+
const fiber = getFiberById(fiberId);
|
|
1249
|
+
if (!fiber) {
|
|
1250
|
+
console.warn(`[React DevTools] Fiber not found: ${fiberId}`);
|
|
1251
|
+
return false;
|
|
1252
|
+
}
|
|
1253
|
+
if (fiber.tag !== REACT_TAGS.ContextProvider) {
|
|
1254
|
+
console.warn(`[React DevTools] Fiber is not a Context Provider`);
|
|
1255
|
+
return false;
|
|
1256
|
+
}
|
|
1257
|
+
try {
|
|
1258
|
+
var _fiber$memoizedProps;
|
|
1259
|
+
const parsedValue = parseValue(value, valueType);
|
|
1260
|
+
const pathParts = path.split(".");
|
|
1261
|
+
return applyContextValue(fiber, setNestedValue((_fiber$memoizedProps = fiber.memoizedProps) === null || _fiber$memoizedProps === void 0 ? void 0 : _fiber$memoizedProps.value, pathParts, parsedValue), fiberId);
|
|
1262
|
+
} catch (error) {
|
|
1263
|
+
console.warn("[React DevTools] Failed to set context value at path:", error);
|
|
1264
|
+
return false;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
/**
|
|
1268
|
+
* Apply a value to a Context Provider
|
|
1269
|
+
*
|
|
1270
|
+
* Context Provider is essentially a component with a `value` prop.
|
|
1271
|
+
* We use overrideProps to modify this prop.
|
|
1272
|
+
*/
|
|
1273
|
+
function applyContextValue(fiber, newValue, fiberId) {
|
|
1274
|
+
var _fiber$type;
|
|
1275
|
+
overriddenContexts.set(fiberId, newValue);
|
|
1276
|
+
const renderer = getRenderer();
|
|
1277
|
+
if (renderer === null || renderer === void 0 ? void 0 : renderer.overrideProps) try {
|
|
1278
|
+
renderer.overrideProps(fiber, ["value"], newValue);
|
|
1279
|
+
return true;
|
|
1280
|
+
} catch (_unused10) {
|
|
1281
|
+
const numericId = Number.parseInt(fiberId.replace("react-fiber-", ""), 10);
|
|
1282
|
+
if (!Number.isNaN(numericId)) try {
|
|
1283
|
+
renderer.overrideProps(numericId, ["value"], newValue);
|
|
1284
|
+
return true;
|
|
1285
|
+
} catch (_unused11) {}
|
|
1286
|
+
}
|
|
1287
|
+
const newProps = _objectSpread2(_objectSpread2({}, fiber.memoizedProps || {}), {}, { value: newValue });
|
|
1288
|
+
fiber.memoizedProps = newProps;
|
|
1289
|
+
fiber.pendingProps = newProps;
|
|
1290
|
+
if (fiber.alternate) {
|
|
1291
|
+
fiber.alternate.memoizedProps = newProps;
|
|
1292
|
+
fiber.alternate.pendingProps = newProps;
|
|
1293
|
+
}
|
|
1294
|
+
const contextType = (_fiber$type = fiber.type) === null || _fiber$type === void 0 ? void 0 : _fiber$type._context;
|
|
1295
|
+
if (contextType) {
|
|
1296
|
+
contextType._currentValue = newValue;
|
|
1297
|
+
if ("_currentValue2" in contextType) contextType._currentValue2 = newValue;
|
|
1298
|
+
}
|
|
1299
|
+
forceComponentUpdate(fiber) || forceGlobalUpdate();
|
|
1300
|
+
return true;
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* Get an overridden context value for UI display
|
|
1304
|
+
*/
|
|
1305
|
+
function getOverriddenContext(fiberId) {
|
|
1306
|
+
return overriddenContexts.get(fiberId);
|
|
1307
|
+
}
|
|
1308
|
+
/**
|
|
1309
|
+
* Clear all overrides
|
|
1310
|
+
*
|
|
1311
|
+
* Should be called when the page refreshes or DevTools disconnects.
|
|
1312
|
+
*/
|
|
1313
|
+
function clearOverrides() {
|
|
1314
|
+
overriddenProps.clear();
|
|
1315
|
+
overriddenContexts.clear();
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
//#endregion
|
|
1319
|
+
//#region src/core/fiber/state.ts
|
|
1320
|
+
/**
|
|
1321
|
+
* Get all useState/useReducer hooks from a component
|
|
1322
|
+
*/
|
|
1323
|
+
function getComponentHookStates(fiberId) {
|
|
1324
|
+
const fiber = getFiberById(fiberId);
|
|
1325
|
+
if (!fiber) return [];
|
|
1326
|
+
if (fiber.tag !== REACT_TAGS.FunctionComponent && fiber.tag !== REACT_TAGS.ForwardRef && fiber.tag !== REACT_TAGS.SimpleMemoComponent && fiber.tag !== REACT_TAGS.MemoComponent) return [];
|
|
1327
|
+
const states = [];
|
|
1328
|
+
const debugHookTypes = fiber._debugHookTypes;
|
|
1329
|
+
let hookState = fiber.memoizedState;
|
|
1330
|
+
let index = 0;
|
|
1331
|
+
while (hookState) {
|
|
1332
|
+
var _hookState$queue;
|
|
1333
|
+
if ((_hookState$queue = hookState.queue) === null || _hookState$queue === void 0 ? void 0 : _hookState$queue.dispatch) {
|
|
1334
|
+
const hookName = (debugHookTypes === null || debugHookTypes === void 0 ? void 0 : debugHookTypes[index]) || "State";
|
|
1335
|
+
const value = hookState.memoizedState;
|
|
1336
|
+
const valueType = getValueType(value);
|
|
1337
|
+
states.push({
|
|
1338
|
+
index,
|
|
1339
|
+
name: hookName,
|
|
1340
|
+
value: serializeForDisplay(value),
|
|
1341
|
+
type: valueType,
|
|
1342
|
+
canEdit: isEditableType(valueType)
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
hookState = hookState.next;
|
|
1346
|
+
index++;
|
|
1347
|
+
}
|
|
1348
|
+
return states;
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Set a hook state value
|
|
1352
|
+
* This directly calls the useState setter, which is the most reliable way to update React state
|
|
1353
|
+
*/
|
|
1354
|
+
function setHookState(fiberId, hookIndex, value, valueType) {
|
|
1355
|
+
const fiber = getFiberById(fiberId);
|
|
1356
|
+
if (!fiber) {
|
|
1357
|
+
console.warn(`[React DevTools] Fiber not found: ${fiberId}`);
|
|
1358
|
+
return false;
|
|
1359
|
+
}
|
|
1360
|
+
let hookState = fiber.memoizedState;
|
|
1361
|
+
let currentIndex = 0;
|
|
1362
|
+
let targetHook = null;
|
|
1363
|
+
while (hookState) {
|
|
1364
|
+
var _hookState$queue2;
|
|
1365
|
+
if ((_hookState$queue2 = hookState.queue) === null || _hookState$queue2 === void 0 ? void 0 : _hookState$queue2.dispatch) {
|
|
1366
|
+
if (currentIndex === hookIndex) {
|
|
1367
|
+
targetHook = hookState;
|
|
1368
|
+
break;
|
|
1369
|
+
}
|
|
1370
|
+
currentIndex++;
|
|
1371
|
+
}
|
|
1372
|
+
hookState = hookState.next;
|
|
1373
|
+
}
|
|
1374
|
+
if (!targetHook) {
|
|
1375
|
+
console.warn(`[React DevTools] Hook at index ${hookIndex} not found`);
|
|
1376
|
+
return false;
|
|
1377
|
+
}
|
|
1378
|
+
const dispatch = targetHook.queue.dispatch;
|
|
1379
|
+
if (!dispatch) {
|
|
1380
|
+
console.warn(`[React DevTools] Hook has no dispatch function`);
|
|
1381
|
+
return false;
|
|
1382
|
+
}
|
|
1383
|
+
try {
|
|
1384
|
+
dispatch(parseValue$1(value, valueType));
|
|
1385
|
+
return true;
|
|
1386
|
+
} catch (error) {
|
|
1387
|
+
console.warn("[React DevTools] Failed to set hook state:", error);
|
|
1388
|
+
return false;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* Set a hook state value using JSON (for objects/arrays)
|
|
1393
|
+
*/
|
|
1394
|
+
function setHookStateFromJson(fiberId, hookIndex, jsonValue) {
|
|
1395
|
+
try {
|
|
1396
|
+
const parsedValue = JSON.parse(jsonValue);
|
|
1397
|
+
const fiber = getFiberById(fiberId);
|
|
1398
|
+
if (!fiber) return false;
|
|
1399
|
+
let hookState = fiber.memoizedState;
|
|
1400
|
+
let currentIndex = 0;
|
|
1401
|
+
while (hookState) {
|
|
1402
|
+
var _hookState$queue3;
|
|
1403
|
+
if ((_hookState$queue3 = hookState.queue) === null || _hookState$queue3 === void 0 ? void 0 : _hookState$queue3.dispatch) {
|
|
1404
|
+
if (currentIndex === hookIndex) {
|
|
1405
|
+
hookState.queue.dispatch(parsedValue);
|
|
1406
|
+
return true;
|
|
1407
|
+
}
|
|
1408
|
+
currentIndex++;
|
|
1409
|
+
}
|
|
1410
|
+
hookState = hookState.next;
|
|
1411
|
+
}
|
|
1412
|
+
return false;
|
|
1413
|
+
} catch (error) {
|
|
1414
|
+
console.warn("[React DevTools] Failed to set hook state from JSON:", error);
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
function getValueType(value) {
|
|
1419
|
+
if (value === null) return "null";
|
|
1420
|
+
if (value === void 0) return "undefined";
|
|
1421
|
+
if (Array.isArray(value)) return "array";
|
|
1422
|
+
return typeof value;
|
|
1423
|
+
}
|
|
1424
|
+
function isEditableType(type) {
|
|
1425
|
+
return [
|
|
1426
|
+
"string",
|
|
1427
|
+
"number",
|
|
1428
|
+
"boolean",
|
|
1429
|
+
"null",
|
|
1430
|
+
"undefined",
|
|
1431
|
+
"object",
|
|
1432
|
+
"array"
|
|
1433
|
+
].includes(type);
|
|
1434
|
+
}
|
|
1435
|
+
function parseValue$1(value, valueType) {
|
|
1436
|
+
switch (valueType) {
|
|
1437
|
+
case "number": return Number(value);
|
|
1438
|
+
case "boolean": return value === "true";
|
|
1439
|
+
case "null": return null;
|
|
1440
|
+
case "undefined": return;
|
|
1441
|
+
case "object":
|
|
1442
|
+
case "array": try {
|
|
1443
|
+
return JSON.parse(value);
|
|
1444
|
+
} catch (_unused) {
|
|
1445
|
+
return value;
|
|
1446
|
+
}
|
|
1447
|
+
case "string":
|
|
1448
|
+
default:
|
|
1449
|
+
if (value.startsWith("\"") && value.endsWith("\"") || value.startsWith("'") && value.endsWith("'")) return value.slice(1, -1);
|
|
1450
|
+
return value;
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
function serializeForDisplay(value) {
|
|
1454
|
+
if (value === null) return null;
|
|
1455
|
+
if (value === void 0) return void 0;
|
|
1456
|
+
if (typeof value === "function") return `ƒ ${value.name || "anonymous"}()`;
|
|
1457
|
+
if (typeof value === "symbol") return value.toString();
|
|
1458
|
+
return value;
|
|
1459
|
+
}
|
|
1460
|
+
|
|
1461
|
+
//#endregion
|
|
1462
|
+
//#region src/core/router/index.ts
|
|
1463
|
+
/**
|
|
1464
|
+
* Global variable to store the React fiber root reference
|
|
1465
|
+
*/
|
|
1466
|
+
let fiberRoot = null;
|
|
1467
|
+
/**
|
|
1468
|
+
* Navigation history storage
|
|
1469
|
+
*/
|
|
1470
|
+
const navigationHistory = [];
|
|
1471
|
+
let lastNavigationStart = null;
|
|
1472
|
+
let lastNavigationDuration;
|
|
1473
|
+
/**
|
|
1474
|
+
* Max history entries to keep
|
|
1475
|
+
*/
|
|
1476
|
+
const MAX_HISTORY_ENTRIES = 50;
|
|
1477
|
+
/**
|
|
1478
|
+
* Set the fiber root reference (called from hook)
|
|
1479
|
+
*/
|
|
1480
|
+
function setFiberRoot(root) {
|
|
1481
|
+
fiberRoot = root;
|
|
1482
|
+
}
|
|
1483
|
+
/**
|
|
1484
|
+
* Get the current fiber root
|
|
1485
|
+
*/
|
|
1486
|
+
function getFiberRoot() {
|
|
1487
|
+
return fiberRoot;
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Extract dynamic params from a path pattern
|
|
1491
|
+
*/
|
|
1492
|
+
function extractParamsFromPath(path) {
|
|
1493
|
+
const params = [];
|
|
1494
|
+
const regex = /:([^/]+)/g;
|
|
1495
|
+
let match = regex.exec(path);
|
|
1496
|
+
while (match !== null) {
|
|
1497
|
+
params.push(match[1]);
|
|
1498
|
+
match = regex.exec(path);
|
|
1499
|
+
}
|
|
1500
|
+
return params;
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Check if element is lazy loaded
|
|
1504
|
+
*/
|
|
1505
|
+
function isLazyElement(element) {
|
|
1506
|
+
var _element$$$typeof, _element$type;
|
|
1507
|
+
if (!element) return false;
|
|
1508
|
+
if (((_element$$$typeof = element.$$typeof) === null || _element$$$typeof === void 0 ? void 0 : _element$$$typeof.toString()) === "Symbol(react.lazy)") return true;
|
|
1509
|
+
if (((_element$type = element.type) === null || _element$type === void 0 || (_element$type = _element$type.$$typeof) === null || _element$type === void 0 ? void 0 : _element$type.toString()) === "Symbol(react.lazy)") return true;
|
|
1510
|
+
return false;
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Get element name from React element
|
|
1514
|
+
*/
|
|
1515
|
+
function getElementName(element) {
|
|
1516
|
+
var _element$type2, _element$type3, _element$type4;
|
|
1517
|
+
if (!element) return void 0;
|
|
1518
|
+
if (typeof element.type === "string") return element.type;
|
|
1519
|
+
if ((_element$type2 = element.type) === null || _element$type2 === void 0 ? void 0 : _element$type2.name) return element.type.name;
|
|
1520
|
+
if ((_element$type3 = element.type) === null || _element$type3 === void 0 ? void 0 : _element$type3.displayName) return element.type.displayName;
|
|
1521
|
+
if ((_element$type4 = element.type) === null || _element$type4 === void 0 || (_element$type4 = _element$type4._payload) === null || _element$type4 === void 0 || (_element$type4 = _element$type4._result) === null || _element$type4 === void 0 ? void 0 : _element$type4.name) return element.type._payload._result.name;
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Extract route info from a React Router Route element (JSX props)
|
|
1525
|
+
*/
|
|
1526
|
+
function extractRouteFromElement(element, parentPath = "") {
|
|
1527
|
+
if (!element || !element.props) return null;
|
|
1528
|
+
const props = element.props;
|
|
1529
|
+
const isIndex = props.index === true;
|
|
1530
|
+
let fullPath = "";
|
|
1531
|
+
if (isIndex) fullPath = parentPath || "/";
|
|
1532
|
+
else if (props.path) {
|
|
1533
|
+
props.path;
|
|
1534
|
+
fullPath = props.path.startsWith("/") ? props.path : `${parentPath}/${props.path}`.replace(/\/+/g, "/");
|
|
1535
|
+
} else fullPath = parentPath || "/";
|
|
1536
|
+
const childRoutes = [];
|
|
1537
|
+
if (props.children) {
|
|
1538
|
+
const children = Array.isArray(props.children) ? props.children : [props.children];
|
|
1539
|
+
for (const child of children) {
|
|
1540
|
+
var _child$type;
|
|
1541
|
+
if (child && child.type && (child.type.name === "Route" || ((_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type.displayName) === "Route")) {
|
|
1542
|
+
const childRoute = extractRouteFromElement(child, fullPath);
|
|
1543
|
+
if (childRoute) childRoutes.push(childRoute);
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1547
|
+
const hasChildren = childRoutes.length > 0;
|
|
1548
|
+
const params = extractParamsFromPath(props.path || "");
|
|
1549
|
+
const routeInfo = {
|
|
1550
|
+
path: fullPath || "/",
|
|
1551
|
+
name: props.id || void 0,
|
|
1552
|
+
element: getElementName(props.element),
|
|
1553
|
+
isIndex,
|
|
1554
|
+
isLayout: hasChildren,
|
|
1555
|
+
hasLoader: !!props.loader,
|
|
1556
|
+
hasAction: !!props.action,
|
|
1557
|
+
isLazy: isLazyElement(props.element) || !!props.lazy,
|
|
1558
|
+
hasErrorBoundary: !!props.errorElement || !!props.ErrorBoundary,
|
|
1559
|
+
params: params.length > 0 ? params : void 0
|
|
1560
|
+
};
|
|
1561
|
+
if (hasChildren) routeInfo.children = childRoutes;
|
|
1562
|
+
return routeInfo;
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Extract routes from Routes component's children prop
|
|
1566
|
+
*/
|
|
1567
|
+
function extractRoutesFromProps(props) {
|
|
1568
|
+
const routes = [];
|
|
1569
|
+
if (!(props === null || props === void 0 ? void 0 : props.children)) return routes;
|
|
1570
|
+
const children = Array.isArray(props.children) ? props.children : [props.children];
|
|
1571
|
+
for (const child of children) {
|
|
1572
|
+
var _child$type2;
|
|
1573
|
+
if (child && child.type && (child.type.name === "Route" || ((_child$type2 = child.type) === null || _child$type2 === void 0 ? void 0 : _child$type2.displayName) === "Route")) {
|
|
1574
|
+
const route = extractRouteFromElement(child);
|
|
1575
|
+
if (route) routes.push(route);
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
return routes;
|
|
1579
|
+
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Extract route configuration from fiber tree
|
|
1582
|
+
*/
|
|
1583
|
+
function extractRoutesFromFiber(fiber) {
|
|
1584
|
+
const routes = [];
|
|
1585
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
1586
|
+
function traverse$1(node, parentPath = "") {
|
|
1587
|
+
if (!node || visited.has(node)) return;
|
|
1588
|
+
visited.add(node);
|
|
1589
|
+
const name = getDisplayName(node);
|
|
1590
|
+
const props = node.memoizedProps || node.pendingProps;
|
|
1591
|
+
if ((name === "Route" || name === "RenderedRoute" || name === "RouteContext.Provider") && props) {
|
|
1592
|
+
var _props$value, _props$value2;
|
|
1593
|
+
const match = props.match || ((_props$value = props.value) === null || _props$value === void 0 ? void 0 : _props$value.match);
|
|
1594
|
+
const route = props.route || ((_props$value2 = props.value) === null || _props$value2 === void 0 ? void 0 : _props$value2.route);
|
|
1595
|
+
if (match || route) {
|
|
1596
|
+
var _route$element, _route$element2;
|
|
1597
|
+
const routeInfo = {
|
|
1598
|
+
path: (match === null || match === void 0 ? void 0 : match.pathname) || (route === null || route === void 0 ? void 0 : route.path) || parentPath || "/",
|
|
1599
|
+
name: (route === null || route === void 0 ? void 0 : route.id) || void 0,
|
|
1600
|
+
element: (route === null || route === void 0 || (_route$element = route.element) === null || _route$element === void 0 || (_route$element = _route$element.type) === null || _route$element === void 0 ? void 0 : _route$element.name) || (route === null || route === void 0 || (_route$element2 = route.element) === null || _route$element2 === void 0 || (_route$element2 = _route$element2.type) === null || _route$element2 === void 0 ? void 0 : _route$element2.displayName) || getElementName(props.element),
|
|
1601
|
+
hasLoader: !!(route === null || route === void 0 ? void 0 : route.loader),
|
|
1602
|
+
hasAction: !!(route === null || route === void 0 ? void 0 : route.action),
|
|
1603
|
+
hasErrorBoundary: !!(route === null || route === void 0 ? void 0 : route.errorElement)
|
|
1604
|
+
};
|
|
1605
|
+
if (!routes.some((r) => r.path === routeInfo.path)) routes.push(routeInfo);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
if (node.child) traverse$1(node.child, parentPath);
|
|
1609
|
+
if (node.sibling) traverse$1(node.sibling, parentPath);
|
|
1610
|
+
}
|
|
1611
|
+
traverse$1(fiber);
|
|
1612
|
+
return routes;
|
|
1613
|
+
}
|
|
1614
|
+
/**
|
|
1615
|
+
* Find Routes component and extract route configuration
|
|
1616
|
+
*/
|
|
1617
|
+
function findAndExtractRoutes(fiber) {
|
|
1618
|
+
if (!fiber) return [];
|
|
1619
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
1620
|
+
let routes = [];
|
|
1621
|
+
function traverse$1(node) {
|
|
1622
|
+
if (!node || visited.has(node)) return;
|
|
1623
|
+
visited.add(node);
|
|
1624
|
+
const name = getDisplayName(node);
|
|
1625
|
+
const props = node.memoizedProps || node.pendingProps;
|
|
1626
|
+
if (name === "Routes") {
|
|
1627
|
+
const propsRoutes = extractRoutesFromProps(props);
|
|
1628
|
+
if (propsRoutes.length > 0) {
|
|
1629
|
+
routes = propsRoutes;
|
|
1630
|
+
return;
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
if (name === "DataRoutes" || name === "RoutesRenderer") {
|
|
1634
|
+
const fiberRoutes = extractRoutesFromFiber(node);
|
|
1635
|
+
if (fiberRoutes.length > 0) routes.push(...fiberRoutes);
|
|
1636
|
+
}
|
|
1637
|
+
if (node.child) traverse$1(node.child);
|
|
1638
|
+
if (node.sibling) traverse$1(node.sibling);
|
|
1639
|
+
}
|
|
1640
|
+
traverse$1(fiber);
|
|
1641
|
+
return routes;
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* Match a path against a route pattern and extract params
|
|
1645
|
+
*/
|
|
1646
|
+
function matchPath(pattern, pathname) {
|
|
1647
|
+
const params = {};
|
|
1648
|
+
const patternParts = pattern.split("/").filter(Boolean);
|
|
1649
|
+
const pathParts = pathname.split("/").filter(Boolean);
|
|
1650
|
+
if (patternParts.length === 0 && pathParts.length === 0) return {
|
|
1651
|
+
matched: true,
|
|
1652
|
+
params
|
|
1653
|
+
};
|
|
1654
|
+
let patternIndex = 0;
|
|
1655
|
+
let pathIndex = 0;
|
|
1656
|
+
while (patternIndex < patternParts.length && pathIndex < pathParts.length) {
|
|
1657
|
+
const patternPart = patternParts[patternIndex];
|
|
1658
|
+
const pathPart = pathParts[pathIndex];
|
|
1659
|
+
if (patternPart.startsWith(":")) {
|
|
1660
|
+
const paramName = patternPart.slice(1).replace("?", "");
|
|
1661
|
+
params[paramName] = pathPart;
|
|
1662
|
+
} else if (patternPart === "*") {
|
|
1663
|
+
params["*"] = pathParts.slice(pathIndex).join("/");
|
|
1664
|
+
return {
|
|
1665
|
+
matched: true,
|
|
1666
|
+
params
|
|
1667
|
+
};
|
|
1668
|
+
} else if (patternPart !== pathPart) return {
|
|
1669
|
+
matched: false,
|
|
1670
|
+
params: {}
|
|
1671
|
+
};
|
|
1672
|
+
patternIndex++;
|
|
1673
|
+
pathIndex++;
|
|
1674
|
+
}
|
|
1675
|
+
while (patternIndex < patternParts.length) {
|
|
1676
|
+
const part = patternParts[patternIndex];
|
|
1677
|
+
if (!part.endsWith("?") && !part.startsWith(":")) return {
|
|
1678
|
+
matched: false,
|
|
1679
|
+
params: {}
|
|
1680
|
+
};
|
|
1681
|
+
patternIndex++;
|
|
1682
|
+
}
|
|
1683
|
+
return {
|
|
1684
|
+
matched: true,
|
|
1685
|
+
params
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
/**
|
|
1689
|
+
* Find matched routes for a given path
|
|
1690
|
+
*/
|
|
1691
|
+
function findMatchedRoutes(routes, pathname) {
|
|
1692
|
+
const matched = [];
|
|
1693
|
+
function findInRoutes(routeList, currentPath) {
|
|
1694
|
+
for (const route of routeList) {
|
|
1695
|
+
const { matched: isMatch, params } = matchPath(route.path, pathname);
|
|
1696
|
+
if (isMatch) {
|
|
1697
|
+
matched.push({
|
|
1698
|
+
path: route.path,
|
|
1699
|
+
params,
|
|
1700
|
+
element: route.element
|
|
1701
|
+
});
|
|
1702
|
+
if (route.children && route.children.length > 0) findInRoutes(route.children, route.path);
|
|
1703
|
+
if (route.path === pathname || route.isIndex) return true;
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
return matched.length > 0;
|
|
1707
|
+
}
|
|
1708
|
+
findInRoutes(routes, pathname);
|
|
1709
|
+
return matched;
|
|
1710
|
+
}
|
|
1711
|
+
/**
|
|
1712
|
+
* Get current URL information
|
|
1713
|
+
*/
|
|
1714
|
+
function getCurrentUrlInfo() {
|
|
1715
|
+
if (window.location.hash && window.location.hash.startsWith("#/")) {
|
|
1716
|
+
const [pathAndSearch, hash] = window.location.hash.slice(1).split("#");
|
|
1717
|
+
const [path, search] = (pathAndSearch || "/").split("?");
|
|
1718
|
+
return {
|
|
1719
|
+
path: path || "/",
|
|
1720
|
+
search: search ? `?${search}` : "",
|
|
1721
|
+
hash: hash ? `#${hash}` : ""
|
|
1722
|
+
};
|
|
1723
|
+
}
|
|
1724
|
+
return {
|
|
1725
|
+
path: window.location.pathname || "/",
|
|
1726
|
+
search: window.location.search || "",
|
|
1727
|
+
hash: window.location.hash || ""
|
|
1728
|
+
};
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Extract all params from matched routes
|
|
1732
|
+
*/
|
|
1733
|
+
function extractAllParams(matchedRoutes) {
|
|
1734
|
+
const params = {};
|
|
1735
|
+
for (const route of matchedRoutes) Object.assign(params, route.params);
|
|
1736
|
+
return params;
|
|
1737
|
+
}
|
|
1738
|
+
/**
|
|
1739
|
+
* Detect router type from fiber tree
|
|
1740
|
+
*/
|
|
1741
|
+
function detectRouterType(fiber) {
|
|
1742
|
+
if (!fiber) return null;
|
|
1743
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
1744
|
+
function traverse$1(node) {
|
|
1745
|
+
if (!node || visited.has(node)) return null;
|
|
1746
|
+
visited.add(node);
|
|
1747
|
+
const name = getDisplayName(node);
|
|
1748
|
+
if (name === "Router" || name === "BrowserRouter" || name === "HashRouter" || name === "MemoryRouter" || name === "Routes" || name === "Route") return "react-router";
|
|
1749
|
+
if (node.child) {
|
|
1750
|
+
const result = traverse$1(node.child);
|
|
1751
|
+
if (result) return result;
|
|
1752
|
+
}
|
|
1753
|
+
if (node.sibling) {
|
|
1754
|
+
const result = traverse$1(node.sibling);
|
|
1755
|
+
if (result) return result;
|
|
1756
|
+
}
|
|
1757
|
+
return null;
|
|
1758
|
+
}
|
|
1759
|
+
return traverse$1(fiber);
|
|
1760
|
+
}
|
|
1761
|
+
/**
|
|
1762
|
+
* Record navigation to history
|
|
1763
|
+
*/
|
|
1764
|
+
function recordNavigation(path, search, hash) {
|
|
1765
|
+
const now = Date.now();
|
|
1766
|
+
if (lastNavigationStart !== null) lastNavigationDuration = now - lastNavigationStart;
|
|
1767
|
+
navigationHistory.unshift({
|
|
1768
|
+
path,
|
|
1769
|
+
search,
|
|
1770
|
+
hash,
|
|
1771
|
+
timestamp: now,
|
|
1772
|
+
duration: lastNavigationDuration
|
|
1773
|
+
});
|
|
1774
|
+
if (navigationHistory.length > MAX_HISTORY_ENTRIES) navigationHistory.pop();
|
|
1775
|
+
lastNavigationStart = null;
|
|
1776
|
+
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Get router information from the current React app
|
|
1779
|
+
*/
|
|
1780
|
+
function getRouterInfo() {
|
|
1781
|
+
const root = fiberRoot;
|
|
1782
|
+
const urlInfo = getCurrentUrlInfo();
|
|
1783
|
+
if (!(root === null || root === void 0 ? void 0 : root.current)) return {
|
|
1784
|
+
currentPath: urlInfo.path,
|
|
1785
|
+
search: urlInfo.search,
|
|
1786
|
+
hash: urlInfo.hash,
|
|
1787
|
+
routes: [],
|
|
1788
|
+
routerType: null,
|
|
1789
|
+
matchedRoutes: [],
|
|
1790
|
+
params: {},
|
|
1791
|
+
history: [...navigationHistory],
|
|
1792
|
+
lastNavigationDuration
|
|
1793
|
+
};
|
|
1794
|
+
const fiber = root.current;
|
|
1795
|
+
const routerType = detectRouterType(fiber);
|
|
1796
|
+
const routes = findAndExtractRoutes(fiber.child);
|
|
1797
|
+
const matchedRoutes = findMatchedRoutes(routes, urlInfo.path);
|
|
1798
|
+
const params = extractAllParams(matchedRoutes);
|
|
1799
|
+
return {
|
|
1800
|
+
currentPath: urlInfo.path,
|
|
1801
|
+
search: urlInfo.search,
|
|
1802
|
+
hash: urlInfo.hash,
|
|
1803
|
+
routes,
|
|
1804
|
+
routerType,
|
|
1805
|
+
matchedRoutes,
|
|
1806
|
+
params,
|
|
1807
|
+
history: [...navigationHistory],
|
|
1808
|
+
lastNavigationDuration
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
/**
|
|
1812
|
+
* Navigate to a path using various methods
|
|
1813
|
+
*/
|
|
1814
|
+
function navigateTo(path) {
|
|
1815
|
+
try {
|
|
1816
|
+
lastNavigationStart = Date.now();
|
|
1817
|
+
if (window.history && window.history.pushState) {
|
|
1818
|
+
if (window.location.hash && window.location.hash.startsWith("#/")) window.location.hash = path;
|
|
1819
|
+
else {
|
|
1820
|
+
window.history.pushState({}, "", path);
|
|
1821
|
+
window.dispatchEvent(new PopStateEvent("popstate"));
|
|
1822
|
+
}
|
|
1823
|
+
return true;
|
|
1824
|
+
}
|
|
1825
|
+
window.location.href = path;
|
|
1826
|
+
return true;
|
|
1827
|
+
} catch (e) {
|
|
1828
|
+
console.error("[React DevTools] Failed to navigate:", e);
|
|
1829
|
+
lastNavigationStart = null;
|
|
1830
|
+
return false;
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
/**
|
|
1834
|
+
* Clear navigation history
|
|
1835
|
+
*/
|
|
1836
|
+
function clearNavigationHistory() {
|
|
1837
|
+
navigationHistory.length = 0;
|
|
1838
|
+
lastNavigationDuration = void 0;
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* Initialize navigation tracking by listening to navigation events
|
|
1842
|
+
*/
|
|
1843
|
+
if (typeof window !== "undefined") {
|
|
1844
|
+
let currentFullPath = "";
|
|
1845
|
+
const updateCurrentPath = () => {
|
|
1846
|
+
const urlInfo$1 = getCurrentUrlInfo();
|
|
1847
|
+
currentFullPath = `${urlInfo$1.path}${urlInfo$1.search}${urlInfo$1.hash}`;
|
|
1848
|
+
};
|
|
1849
|
+
const handleNavigation = () => {
|
|
1850
|
+
const urlInfo$1 = getCurrentUrlInfo();
|
|
1851
|
+
const newFullPath = `${urlInfo$1.path}${urlInfo$1.search}${urlInfo$1.hash}`;
|
|
1852
|
+
if (newFullPath !== currentFullPath) {
|
|
1853
|
+
recordNavigation(urlInfo$1.path, urlInfo$1.search, urlInfo$1.hash);
|
|
1854
|
+
currentFullPath = newFullPath;
|
|
1855
|
+
}
|
|
1856
|
+
};
|
|
1857
|
+
window.addEventListener("popstate", handleNavigation);
|
|
1858
|
+
window.addEventListener("hashchange", handleNavigation);
|
|
1859
|
+
const originalPushState = window.history.pushState;
|
|
1860
|
+
const originalReplaceState = window.history.replaceState;
|
|
1861
|
+
window.history.pushState = function(...args) {
|
|
1862
|
+
const result = originalPushState.apply(this, args);
|
|
1863
|
+
handleNavigation();
|
|
1864
|
+
return result;
|
|
1865
|
+
};
|
|
1866
|
+
window.history.replaceState = function(...args) {
|
|
1867
|
+
const result = originalReplaceState.apply(this, args);
|
|
1868
|
+
updateCurrentPath();
|
|
1869
|
+
return result;
|
|
1870
|
+
};
|
|
1871
|
+
const urlInfo = getCurrentUrlInfo();
|
|
1872
|
+
recordNavigation(urlInfo.path, urlInfo.search, urlInfo.hash);
|
|
1873
|
+
currentFullPath = `${urlInfo.path}${urlInfo.search}${urlInfo.hash}`;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
//#endregion
|
|
1877
|
+
//#region src/core/hook/index.ts
|
|
1878
|
+
const fiberRoots = /* @__PURE__ */ new Map();
|
|
1879
|
+
let updateTimer = null;
|
|
1880
|
+
let lastRootCurrent = null;
|
|
1881
|
+
const treeUpdateCallbacks = /* @__PURE__ */ new Set();
|
|
1882
|
+
function onTreeUpdated(callback) {
|
|
1883
|
+
treeUpdateCallbacks.add(callback);
|
|
1884
|
+
return () => {
|
|
1885
|
+
treeUpdateCallbacks.delete(callback);
|
|
1886
|
+
};
|
|
1887
|
+
}
|
|
1888
|
+
function emitTree(tree) {
|
|
1889
|
+
treeUpdateCallbacks.forEach((callback) => {
|
|
1890
|
+
try {
|
|
1891
|
+
callback(tree);
|
|
1892
|
+
} catch (e) {}
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
function getRoots(rendererID) {
|
|
1896
|
+
if (!fiberRoots.has(rendererID)) fiberRoots.set(rendererID, /* @__PURE__ */ new Set());
|
|
1897
|
+
return fiberRoots.get(rendererID);
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Get root selector from runtime config
|
|
1901
|
+
*/
|
|
1902
|
+
function getRootSelector() {
|
|
1903
|
+
if (typeof window !== "undefined") {
|
|
1904
|
+
var _REACT_DEVTOOLS_CONFI;
|
|
1905
|
+
return (_REACT_DEVTOOLS_CONFI = window.__REACT_DEVTOOLS_CONFIG__) === null || _REACT_DEVTOOLS_CONFI === void 0 ? void 0 : _REACT_DEVTOOLS_CONFI.rootSelector;
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
function isOverlayRoot(root) {
|
|
1909
|
+
const overlayContainer = document.getElementById("react-devtools-overlay");
|
|
1910
|
+
if (!overlayContainer) return false;
|
|
1911
|
+
const containerInfo = root.containerInfo;
|
|
1912
|
+
return containerInfo && containerInfo instanceof Node && overlayContainer.contains(containerInfo);
|
|
1913
|
+
}
|
|
1914
|
+
/**
|
|
1915
|
+
* Check if a root belongs to the specified rootSelector container
|
|
1916
|
+
*/
|
|
1917
|
+
function isRootInSelector(root, selector) {
|
|
1918
|
+
const containerInfo = root.containerInfo;
|
|
1919
|
+
if (!containerInfo || !(containerInfo instanceof Node)) return false;
|
|
1920
|
+
const targetContainer = document.querySelector(selector);
|
|
1921
|
+
if (!targetContainer) return false;
|
|
1922
|
+
return containerInfo === targetContainer || targetContainer.contains(containerInfo);
|
|
1923
|
+
}
|
|
1924
|
+
/**
|
|
1925
|
+
* Check if a root should be tracked based on rootSelector config
|
|
1926
|
+
*/
|
|
1927
|
+
function shouldTrackRoot(root) {
|
|
1928
|
+
if (isOverlayRoot(root)) return false;
|
|
1929
|
+
const rootSelector = getRootSelector();
|
|
1930
|
+
if (!rootSelector) return true;
|
|
1931
|
+
return isRootInSelector(root, rootSelector);
|
|
1932
|
+
}
|
|
1933
|
+
function findAppRoot() {
|
|
1934
|
+
for (const roots of fiberRoots.values()) for (const root of roots) if (root && shouldTrackRoot(root)) return root;
|
|
1935
|
+
if (!getRootSelector()) {
|
|
1936
|
+
for (const roots of fiberRoots.values()) for (const root of roots) if (root && !isOverlayRoot(root)) return root;
|
|
1937
|
+
}
|
|
1938
|
+
return null;
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* Get the current app fiber root (exported for context debugging)
|
|
1942
|
+
*/
|
|
1943
|
+
function getAppFiberRoot() {
|
|
1944
|
+
return findAppRoot();
|
|
1945
|
+
}
|
|
1946
|
+
function handleTreeUpdate(root, showHostComponents) {
|
|
1947
|
+
if (lastRootCurrent === (root === null || root === void 0 ? void 0 : root.current)) return;
|
|
1948
|
+
lastRootCurrent = root === null || root === void 0 ? void 0 : root.current;
|
|
1949
|
+
setFiberRoot(root);
|
|
1950
|
+
if (updateTimer) clearTimeout(updateTimer);
|
|
1951
|
+
updateTimer = setTimeout(() => {
|
|
1952
|
+
const tree = buildTree(root, showHostComponents());
|
|
1953
|
+
if (tree) emitTree(tree);
|
|
1954
|
+
updateTimer = null;
|
|
1955
|
+
}, 200);
|
|
1956
|
+
}
|
|
1957
|
+
function rebuildTree(showHostComponents) {
|
|
1958
|
+
const appRoot = findAppRoot();
|
|
1959
|
+
if (!appRoot) return;
|
|
1960
|
+
setTimeout(() => {
|
|
1961
|
+
const tree = buildTree(appRoot, showHostComponents);
|
|
1962
|
+
if (tree) emitTree(tree);
|
|
1963
|
+
}, 100);
|
|
1964
|
+
}
|
|
1965
|
+
function createHook(showHostComponents) {
|
|
1966
|
+
let rendererIDCounter = 0;
|
|
1967
|
+
const renderers = /* @__PURE__ */ new Map();
|
|
1968
|
+
return {
|
|
1969
|
+
supportsFiber: true,
|
|
1970
|
+
renderers,
|
|
1971
|
+
inject(renderer) {
|
|
1972
|
+
const id = ++rendererIDCounter;
|
|
1973
|
+
renderers.set(id, renderer);
|
|
1974
|
+
return id;
|
|
1975
|
+
},
|
|
1976
|
+
getFiberRoots(rendererID) {
|
|
1977
|
+
return new Set(getRoots(rendererID));
|
|
1978
|
+
},
|
|
1979
|
+
onCommitFiberRoot(rendererID, root) {
|
|
1980
|
+
getRoots(rendererID).add(root);
|
|
1981
|
+
handleTreeUpdate(root, showHostComponents);
|
|
1982
|
+
},
|
|
1983
|
+
onCommitFiberUnmount() {}
|
|
1984
|
+
};
|
|
1985
|
+
}
|
|
1986
|
+
function patchHook(existingHook, showHostComponents) {
|
|
1987
|
+
if (existingHook.__REACT_DEVTOOLS_PATCHED__) return existingHook;
|
|
1988
|
+
if ((existingHook._instrumentationSource || "").includes("bippy") || window.__REACT_SCAN_INTERNALS__) {
|
|
1989
|
+
if (existingHook.renderers) for (const rendererID of existingHook.renderers.keys()) detectExistingRoots(rendererID);
|
|
1990
|
+
try {
|
|
1991
|
+
const scanInternals = window.__REACT_SCAN_INTERNALS__;
|
|
1992
|
+
if (scanInternals && scanInternals.options) setInterval(() => {
|
|
1993
|
+
if (existingHook.renderers) for (const rendererID of existingHook.renderers.keys()) getRoots(rendererID).forEach((root) => handleTreeUpdate(root, showHostComponents));
|
|
1994
|
+
}, 1e3);
|
|
1995
|
+
} catch (e) {
|
|
1996
|
+
console.warn("[React DevTools] Failed to attach to React Scan", e);
|
|
1997
|
+
}
|
|
1998
|
+
return existingHook;
|
|
1999
|
+
}
|
|
2000
|
+
const originalCommit = existingHook.onCommitFiberRoot;
|
|
2001
|
+
if (originalCommit) {
|
|
2002
|
+
const patchedCallback = function(rendererID, root) {
|
|
2003
|
+
let originalResult;
|
|
2004
|
+
try {
|
|
2005
|
+
originalResult = originalCommit.call(this, rendererID, root);
|
|
2006
|
+
} catch (e) {
|
|
2007
|
+
console.error("[React DevTools] Error in other devtools hook:", e);
|
|
2008
|
+
}
|
|
2009
|
+
try {
|
|
2010
|
+
getRoots(rendererID).add(root);
|
|
2011
|
+
handleTreeUpdate(root, showHostComponents);
|
|
2012
|
+
} catch (error) {}
|
|
2013
|
+
return originalResult;
|
|
2014
|
+
};
|
|
2015
|
+
Object.setPrototypeOf(patchedCallback, Object.getPrototypeOf(originalCommit));
|
|
2016
|
+
existingHook.onCommitFiberRoot = patchedCallback;
|
|
2017
|
+
} else existingHook.onCommitFiberRoot = (rendererID, root) => {
|
|
2018
|
+
getRoots(rendererID).add(root);
|
|
2019
|
+
handleTreeUpdate(root, showHostComponents);
|
|
2020
|
+
};
|
|
2021
|
+
if (!existingHook.getFiberRoots) existingHook.getFiberRoots = (rendererID) => new Set(getRoots(rendererID));
|
|
2022
|
+
existingHook.__REACT_DEVTOOLS_PATCHED__ = true;
|
|
2023
|
+
return existingHook;
|
|
2024
|
+
}
|
|
2025
|
+
function detectExistingRoots(rendererID) {
|
|
2026
|
+
const rootSelector = getRootSelector();
|
|
2027
|
+
function findRootFromContainer(container) {
|
|
2028
|
+
if (!container || typeof container !== "object") return null;
|
|
2029
|
+
if (container.containerInfo) return container;
|
|
2030
|
+
if (container.current) {
|
|
2031
|
+
const fiber = container.current;
|
|
2032
|
+
if (fiber.tag === 3 || fiber.tag === 24) return fiber.stateNode || container;
|
|
2033
|
+
const root = findRootFromFiber(fiber);
|
|
2034
|
+
if (root) return root;
|
|
2035
|
+
}
|
|
2036
|
+
if (container._reactRootContainer) {
|
|
2037
|
+
const root = findRootFromContainer(container._reactRootContainer);
|
|
2038
|
+
if (root) return root;
|
|
2039
|
+
}
|
|
2040
|
+
if (container._internalRoot) {
|
|
2041
|
+
const root = findRootFromContainer(container._internalRoot);
|
|
2042
|
+
if (root) return root;
|
|
2043
|
+
}
|
|
2044
|
+
return null;
|
|
2045
|
+
}
|
|
2046
|
+
function findRootFromFiber(fiber) {
|
|
2047
|
+
let current = fiber;
|
|
2048
|
+
let depth = 0;
|
|
2049
|
+
const maxDepth = 100;
|
|
2050
|
+
while (current && depth < maxDepth) {
|
|
2051
|
+
if (current.tag === 3 || current.tag === 24) return current.stateNode;
|
|
2052
|
+
current = current.return || current._debugOwner;
|
|
2053
|
+
depth++;
|
|
2054
|
+
}
|
|
2055
|
+
return null;
|
|
2056
|
+
}
|
|
2057
|
+
/**
|
|
2058
|
+
* Try to find React root from a single element
|
|
2059
|
+
*/
|
|
2060
|
+
function findRootFromElement(element) {
|
|
2061
|
+
const keys = [...Object.keys(element), ...Object.getOwnPropertyNames(element)];
|
|
2062
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
2063
|
+
for (const key of keys) {
|
|
2064
|
+
if (seenKeys.has(key)) continue;
|
|
2065
|
+
seenKeys.add(key);
|
|
2066
|
+
try {
|
|
2067
|
+
const value = element[key];
|
|
2068
|
+
if (!value || typeof value !== "object") continue;
|
|
2069
|
+
if (key.startsWith("__reactContainer")) {
|
|
2070
|
+
if (value && (value.tag === 3 || value.tag === 24)) {
|
|
2071
|
+
const fiberRoot$1 = value.stateNode;
|
|
2072
|
+
if (fiberRoot$1) return fiberRoot$1;
|
|
2073
|
+
}
|
|
2074
|
+
const root = findRootFromFiber(value);
|
|
2075
|
+
if (root) return root;
|
|
2076
|
+
} else if (key.startsWith("__reactFiber")) {
|
|
2077
|
+
const root = findRootFromFiber(value);
|
|
2078
|
+
if (root) return root;
|
|
2079
|
+
} else if (key.startsWith("__reactInternalInstance")) {
|
|
2080
|
+
const root = findRootFromFiber(value);
|
|
2081
|
+
if (root) return root;
|
|
2082
|
+
}
|
|
2083
|
+
} catch (e) {
|
|
2084
|
+
continue;
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
return null;
|
|
2088
|
+
}
|
|
2089
|
+
/**
|
|
2090
|
+
* Check if a root's containerInfo is inside the target selector
|
|
2091
|
+
*/
|
|
2092
|
+
function isRootContainerInSelector(root, selector) {
|
|
2093
|
+
const containerInfo = root.containerInfo;
|
|
2094
|
+
if (!containerInfo || !(containerInfo instanceof Element)) return false;
|
|
2095
|
+
const targetContainer = document.querySelector(selector);
|
|
2096
|
+
if (!targetContainer) return false;
|
|
2097
|
+
return containerInfo === targetContainer || targetContainer.contains(containerInfo);
|
|
2098
|
+
}
|
|
2099
|
+
function walkDOM(element) {
|
|
2100
|
+
if (rootSelector) {
|
|
2101
|
+
const targetElement = document.querySelector(rootSelector);
|
|
2102
|
+
if (targetElement) {
|
|
2103
|
+
const directRoot = findRootFromElement(targetElement);
|
|
2104
|
+
if (directRoot && isRootContainerInSelector(directRoot, rootSelector)) return directRoot;
|
|
2105
|
+
const walker$2 = document.createTreeWalker(targetElement, NodeFilter.SHOW_ELEMENT);
|
|
2106
|
+
let node$1 = walker$2.currentNode;
|
|
2107
|
+
while (node$1) {
|
|
2108
|
+
const root = findRootFromElement(node$1);
|
|
2109
|
+
if (root) {
|
|
2110
|
+
if (isRootContainerInSelector(root, rootSelector)) return root;
|
|
2111
|
+
}
|
|
2112
|
+
node$1 = walker$2.nextNode();
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
for (const id of [
|
|
2118
|
+
"root",
|
|
2119
|
+
"app",
|
|
2120
|
+
"main",
|
|
2121
|
+
"app-root"
|
|
2122
|
+
]) {
|
|
2123
|
+
const rootElement = document.getElementById(id);
|
|
2124
|
+
if (!rootElement) continue;
|
|
2125
|
+
const root = findRootFromElement(rootElement);
|
|
2126
|
+
if (root) return root;
|
|
2127
|
+
}
|
|
2128
|
+
const walker$1 = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
|
|
2129
|
+
let node = walker$1.currentNode;
|
|
2130
|
+
while (node) {
|
|
2131
|
+
const root = findRootFromElement(node);
|
|
2132
|
+
if (root) return root;
|
|
2133
|
+
node = walker$1.nextNode();
|
|
2134
|
+
}
|
|
2135
|
+
return null;
|
|
2136
|
+
}
|
|
2137
|
+
const existingRoot = walkDOM(document.body || document);
|
|
2138
|
+
if (existingRoot) {
|
|
2139
|
+
getRoots(rendererID).add(existingRoot);
|
|
2140
|
+
setTimeout(() => {
|
|
2141
|
+
handleTreeUpdate(existingRoot, () => false);
|
|
2142
|
+
}, 50);
|
|
2143
|
+
return true;
|
|
2144
|
+
}
|
|
2145
|
+
return false;
|
|
2146
|
+
}
|
|
2147
|
+
/**
|
|
2148
|
+
* Get the React version from the renderer
|
|
2149
|
+
*/
|
|
2150
|
+
function getReactVersion() {
|
|
2151
|
+
const hook = globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
|
2152
|
+
if (!hook || !hook.renderers) return null;
|
|
2153
|
+
for (const renderer of hook.renderers.values()) {
|
|
2154
|
+
if (renderer && renderer.version) return renderer.version;
|
|
2155
|
+
if (renderer && renderer.reconcilerVersion) return renderer.reconcilerVersion;
|
|
2156
|
+
}
|
|
2157
|
+
if (typeof window !== "undefined") {
|
|
2158
|
+
const React = window.React;
|
|
2159
|
+
if (React && React.version) return React.version;
|
|
2160
|
+
}
|
|
2161
|
+
return null;
|
|
2162
|
+
}
|
|
2163
|
+
function installReactHook(showHostComponents) {
|
|
2164
|
+
const globalObj = globalThis;
|
|
2165
|
+
if (globalObj.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
|
|
2166
|
+
const hook$1 = patchHook(globalObj.__REACT_DEVTOOLS_GLOBAL_HOOK__, showHostComponents);
|
|
2167
|
+
if (hook$1.renderers && hook$1.renderers.size > 0) for (const rendererID of hook$1.renderers.keys()) detectExistingRoots(rendererID);
|
|
2168
|
+
else detectExistingRoots(hook$1.inject({}));
|
|
2169
|
+
return;
|
|
2170
|
+
}
|
|
2171
|
+
const hook = createHook(showHostComponents);
|
|
2172
|
+
globalObj.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook;
|
|
2173
|
+
let attempts = 0;
|
|
2174
|
+
const maxAttempts = 10;
|
|
2175
|
+
function tryDetect() {
|
|
2176
|
+
attempts++;
|
|
2177
|
+
if (detectExistingRoots(hook.inject({}))) return;
|
|
2178
|
+
if (hook.renderers && hook.renderers.size > 0) {
|
|
2179
|
+
for (const rendererID of hook.renderers.keys()) if (detectExistingRoots(rendererID)) return;
|
|
2180
|
+
}
|
|
2181
|
+
if (attempts < maxAttempts) setTimeout(tryDetect, 200 * attempts);
|
|
2182
|
+
}
|
|
2183
|
+
tryDetect();
|
|
2184
|
+
setTimeout(() => {
|
|
2185
|
+
tryDetect();
|
|
2186
|
+
}, 50);
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
//#endregion
|
|
2190
|
+
//#region src/core/inspector/index.ts
|
|
2191
|
+
let isInspectorEnabled = false;
|
|
2192
|
+
let inspectorMode = "select-component";
|
|
2193
|
+
const selectCallbacks = /* @__PURE__ */ new Set();
|
|
2194
|
+
const openInEditorCallbacks = /* @__PURE__ */ new Set();
|
|
2195
|
+
function onInspectorSelect(callback) {
|
|
2196
|
+
selectCallbacks.add(callback);
|
|
2197
|
+
return () => selectCallbacks.delete(callback);
|
|
2198
|
+
}
|
|
2199
|
+
function onOpenInEditor(callback) {
|
|
2200
|
+
openInEditorCallbacks.add(callback);
|
|
2201
|
+
return () => openInEditorCallbacks.delete(callback);
|
|
2202
|
+
}
|
|
2203
|
+
function emitSelect(fiberId) {
|
|
2204
|
+
selectCallbacks.forEach((cb) => cb(fiberId));
|
|
2205
|
+
}
|
|
2206
|
+
function emitOpenInEditor(fileName, line, column) {
|
|
2207
|
+
openInEditorCallbacks.forEach((cb) => cb(fileName, line, column));
|
|
2208
|
+
}
|
|
2209
|
+
function findNearestComponentFiber(fiber) {
|
|
2210
|
+
let current = fiber;
|
|
2211
|
+
while (current) {
|
|
2212
|
+
if (shouldIncludeFiber(current, false)) return current;
|
|
2213
|
+
current = current.return;
|
|
2214
|
+
}
|
|
2215
|
+
return null;
|
|
2216
|
+
}
|
|
2217
|
+
function findSourceFiber(fiber) {
|
|
2218
|
+
let current = fiber;
|
|
2219
|
+
while (current) {
|
|
2220
|
+
if (current._debugSource) return current;
|
|
2221
|
+
current = current.return;
|
|
2222
|
+
}
|
|
2223
|
+
return null;
|
|
2224
|
+
}
|
|
2225
|
+
function parseSourcePath(sourcePath) {
|
|
2226
|
+
const lastColon = sourcePath.lastIndexOf(":");
|
|
2227
|
+
if (lastColon === -1) return null;
|
|
2228
|
+
const secondLastColon = sourcePath.lastIndexOf(":", lastColon - 1);
|
|
2229
|
+
if (secondLastColon === -1) return null;
|
|
2230
|
+
const fileName = sourcePath.substring(0, secondLastColon);
|
|
2231
|
+
const lineNumber = Number.parseInt(sourcePath.substring(secondLastColon + 1, lastColon), 10);
|
|
2232
|
+
const columnNumber = Number.parseInt(sourcePath.substring(lastColon + 1), 10);
|
|
2233
|
+
if (Number.isNaN(lineNumber) || Number.isNaN(columnNumber)) return null;
|
|
2234
|
+
return {
|
|
2235
|
+
fileName,
|
|
2236
|
+
lineNumber,
|
|
2237
|
+
columnNumber
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
function getSourceFromElement(element) {
|
|
2241
|
+
if (!element) return null;
|
|
2242
|
+
let current = element;
|
|
2243
|
+
while (current && current !== document.body) {
|
|
2244
|
+
const sourcePath = current.getAttribute("data-source-path");
|
|
2245
|
+
if (sourcePath) return parseSourcePath(sourcePath);
|
|
2246
|
+
current = current.parentElement;
|
|
2247
|
+
}
|
|
2248
|
+
return null;
|
|
2249
|
+
}
|
|
2250
|
+
function handleMouseOver(e) {
|
|
2251
|
+
if (!isInspectorEnabled) return;
|
|
2252
|
+
const target$1 = e.target;
|
|
2253
|
+
const fiber = getFiberFromElement(target$1);
|
|
2254
|
+
if (inspectorMode === "select-component") {
|
|
2255
|
+
const componentFiber = findNearestComponentFiber(fiber);
|
|
2256
|
+
if (componentFiber) highlightNode(componentFiber);
|
|
2257
|
+
else hideHighlight();
|
|
2258
|
+
} else if (inspectorMode === "open-in-editor") {
|
|
2259
|
+
const source = getSourceFromElement(target$1);
|
|
2260
|
+
if (source && fiber) highlightNode(fiber, source);
|
|
2261
|
+
else {
|
|
2262
|
+
const sourceFiber = findSourceFiber(fiber);
|
|
2263
|
+
if (sourceFiber) {
|
|
2264
|
+
const fallbackSource = sourceFiber._debugSource ? {
|
|
2265
|
+
fileName: sourceFiber._debugSource.fileName,
|
|
2266
|
+
lineNumber: sourceFiber._debugSource.lineNumber,
|
|
2267
|
+
columnNumber: sourceFiber._debugSource.columnNumber
|
|
2268
|
+
} : void 0;
|
|
2269
|
+
if (fiber) highlightNode(fiber, fallbackSource);
|
|
2270
|
+
else highlightNode(sourceFiber, fallbackSource);
|
|
2271
|
+
} else hideHighlight();
|
|
2272
|
+
}
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
function handleClick(e) {
|
|
2276
|
+
if (!isInspectorEnabled) return;
|
|
2277
|
+
e.preventDefault();
|
|
2278
|
+
e.stopPropagation();
|
|
2279
|
+
const target$1 = e.target;
|
|
2280
|
+
const fiber = getFiberFromElement(target$1);
|
|
2281
|
+
if (inspectorMode === "select-component") {
|
|
2282
|
+
const componentFiber = findNearestComponentFiber(fiber);
|
|
2283
|
+
if (componentFiber) {
|
|
2284
|
+
emitSelect(getFiberId(componentFiber));
|
|
2285
|
+
toggleInspector(false);
|
|
2286
|
+
hideHighlight();
|
|
2287
|
+
}
|
|
2288
|
+
} else if (inspectorMode === "open-in-editor") {
|
|
2289
|
+
const source = getSourceFromElement(target$1);
|
|
2290
|
+
if (source) {
|
|
2291
|
+
const { fileName, lineNumber, columnNumber } = source;
|
|
2292
|
+
emitOpenInEditor(fileName, lineNumber, columnNumber);
|
|
2293
|
+
toggleInspector(false);
|
|
2294
|
+
hideHighlight();
|
|
2295
|
+
} else {
|
|
2296
|
+
const sourceFiber = findSourceFiber(fiber);
|
|
2297
|
+
if (sourceFiber && sourceFiber._debugSource) {
|
|
2298
|
+
const { fileName, lineNumber, columnNumber } = sourceFiber._debugSource;
|
|
2299
|
+
emitOpenInEditor(fileName, lineNumber, columnNumber);
|
|
2300
|
+
toggleInspector(false);
|
|
2301
|
+
hideHighlight();
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
function toggleInspector(enabled, options = {}) {
|
|
2307
|
+
isInspectorEnabled = enabled;
|
|
2308
|
+
if (options.mode) inspectorMode = options.mode;
|
|
2309
|
+
if (enabled) {
|
|
2310
|
+
window.addEventListener("mouseover", handleMouseOver, true);
|
|
2311
|
+
window.addEventListener("click", handleClick, true);
|
|
2312
|
+
document.body.style.cursor = "default";
|
|
2313
|
+
} else {
|
|
2314
|
+
window.removeEventListener("mouseover", handleMouseOver, true);
|
|
2315
|
+
window.removeEventListener("click", handleClick, true);
|
|
2316
|
+
document.body.style.cursor = "";
|
|
2317
|
+
hideHighlight();
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
//#endregion
|
|
2322
|
+
//#region src/core/open-in-editor/index.ts
|
|
2323
|
+
/**
|
|
2324
|
+
* Try to open a file in the editor using URL protocol (fallback)
|
|
2325
|
+
*/
|
|
2326
|
+
function tryOpenWithProtocol(fileName, line, column) {
|
|
2327
|
+
try {
|
|
2328
|
+
const protocolUrl = `${localStorage.getItem("react_devtools_editor") || "vscode"}://file/${fileName}:${line}:${column}`;
|
|
2329
|
+
const link = document.createElement("a");
|
|
2330
|
+
link.href = protocolUrl;
|
|
2331
|
+
link.click();
|
|
2332
|
+
link.remove();
|
|
2333
|
+
return true;
|
|
2334
|
+
} catch (e) {
|
|
2335
|
+
console.warn("[React DevTools] Failed to open with URL protocol:", e);
|
|
2336
|
+
return false;
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
function openInEditor(fileName, line, column) {
|
|
2340
|
+
try {
|
|
2341
|
+
const url = `/__open-in-editor?file=${encodeURIComponent(`${fileName}:${line}:${column}`)}`;
|
|
2342
|
+
fetch(url).then((response) => {
|
|
2343
|
+
if (!response.ok) {
|
|
2344
|
+
console.warn("[React DevTools] Server endpoint failed, trying URL protocol fallback");
|
|
2345
|
+
tryOpenWithProtocol(fileName, line, column);
|
|
2346
|
+
}
|
|
2347
|
+
}).catch(() => {
|
|
2348
|
+
console.warn("[React DevTools] Fetch failed, trying URL protocol fallback");
|
|
2349
|
+
tryOpenWithProtocol(fileName, line, column);
|
|
2350
|
+
});
|
|
2351
|
+
} catch (e) {
|
|
2352
|
+
console.error("[React DevTools] Failed to open in editor:", e);
|
|
2353
|
+
tryOpenWithProtocol(fileName, line, column);
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
//#endregion
|
|
2358
|
+
//#region src/core/timeline/index.ts
|
|
2359
|
+
const TIMELINE_LAYERS = [
|
|
2360
|
+
{
|
|
2361
|
+
id: "mouse",
|
|
2362
|
+
label: "Mouse",
|
|
2363
|
+
color: "#A451AF",
|
|
2364
|
+
enabled: true
|
|
2365
|
+
},
|
|
2366
|
+
{
|
|
2367
|
+
id: "keyboard",
|
|
2368
|
+
label: "Keyboard",
|
|
2369
|
+
color: "#8151AF",
|
|
2370
|
+
enabled: true
|
|
2371
|
+
},
|
|
2372
|
+
{
|
|
2373
|
+
id: "component-event",
|
|
2374
|
+
label: "Component events",
|
|
2375
|
+
color: "#4FC08D",
|
|
2376
|
+
enabled: true
|
|
2377
|
+
},
|
|
2378
|
+
{
|
|
2379
|
+
id: "performance",
|
|
2380
|
+
label: "Performance",
|
|
2381
|
+
color: "#41B86A",
|
|
2382
|
+
enabled: true
|
|
2383
|
+
}
|
|
2384
|
+
];
|
|
2385
|
+
let timelineState = {
|
|
2386
|
+
recordingState: false,
|
|
2387
|
+
mouseEventEnabled: true,
|
|
2388
|
+
keyboardEventEnabled: true,
|
|
2389
|
+
componentEventEnabled: true,
|
|
2390
|
+
performanceEventEnabled: true,
|
|
2391
|
+
selected: "mouse"
|
|
2392
|
+
};
|
|
2393
|
+
let eventIdCounter = 0;
|
|
2394
|
+
let groupIdCounter = 0;
|
|
2395
|
+
const perfGroupIds = /* @__PURE__ */ new Map();
|
|
2396
|
+
const timelineEventCallbacks = /* @__PURE__ */ new Set();
|
|
2397
|
+
function onTimelineEvent(callback) {
|
|
2398
|
+
timelineEventCallbacks.add(callback);
|
|
2399
|
+
return () => {
|
|
2400
|
+
timelineEventCallbacks.delete(callback);
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
function emitTimelineEvent(layerId, event) {
|
|
2404
|
+
timelineEventCallbacks.forEach((callback) => {
|
|
2405
|
+
try {
|
|
2406
|
+
callback(layerId, event);
|
|
2407
|
+
} catch (e) {}
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
function getTimelineState() {
|
|
2411
|
+
return _objectSpread2({}, timelineState);
|
|
2412
|
+
}
|
|
2413
|
+
function updateTimelineState(state) {
|
|
2414
|
+
timelineState = _objectSpread2(_objectSpread2({}, timelineState), state);
|
|
2415
|
+
}
|
|
2416
|
+
function clearTimeline() {
|
|
2417
|
+
eventIdCounter = 0;
|
|
2418
|
+
groupIdCounter = 0;
|
|
2419
|
+
perfGroupIds.clear();
|
|
2420
|
+
}
|
|
2421
|
+
function addMouseEvent(eventType, x, y) {
|
|
2422
|
+
if (!timelineState.recordingState || !timelineState.mouseEventEnabled) return;
|
|
2423
|
+
emitTimelineEvent("mouse", {
|
|
2424
|
+
id: ++eventIdCounter,
|
|
2425
|
+
time: Date.now(),
|
|
2426
|
+
data: {
|
|
2427
|
+
type: eventType,
|
|
2428
|
+
x,
|
|
2429
|
+
y
|
|
2430
|
+
},
|
|
2431
|
+
title: eventType
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
function addKeyboardEvent(eventType, key, modifiers) {
|
|
2435
|
+
if (!timelineState.recordingState || !timelineState.keyboardEventEnabled) return;
|
|
2436
|
+
emitTimelineEvent("keyboard", {
|
|
2437
|
+
id: ++eventIdCounter,
|
|
2438
|
+
time: Date.now(),
|
|
2439
|
+
data: _objectSpread2({
|
|
2440
|
+
type: eventType,
|
|
2441
|
+
key
|
|
2442
|
+
}, modifiers),
|
|
2443
|
+
title: key,
|
|
2444
|
+
subtitle: eventType
|
|
2445
|
+
});
|
|
2446
|
+
}
|
|
2447
|
+
function addComponentEvent(componentName, eventName, params) {
|
|
2448
|
+
if (!timelineState.recordingState || !timelineState.componentEventEnabled) return;
|
|
2449
|
+
emitTimelineEvent("component-event", {
|
|
2450
|
+
id: ++eventIdCounter,
|
|
2451
|
+
time: Date.now(),
|
|
2452
|
+
data: {
|
|
2453
|
+
component: componentName,
|
|
2454
|
+
event: eventName,
|
|
2455
|
+
params
|
|
2456
|
+
},
|
|
2457
|
+
title: eventName,
|
|
2458
|
+
subtitle: `by ${componentName}`
|
|
2459
|
+
});
|
|
2460
|
+
}
|
|
2461
|
+
function getComponentName(fiber) {
|
|
2462
|
+
if (!fiber) return "Unknown";
|
|
2463
|
+
const type = fiber.elementType || fiber.type;
|
|
2464
|
+
if (!type) return "Unknown";
|
|
2465
|
+
if (typeof type === "string") return type;
|
|
2466
|
+
return type.displayName || type.name || "Anonymous";
|
|
2467
|
+
}
|
|
2468
|
+
function addPerformanceEvent(type, componentName, measure, duration, groupKey) {
|
|
2469
|
+
if (!timelineState.recordingState || !timelineState.performanceEventEnabled) return;
|
|
2470
|
+
let groupId;
|
|
2471
|
+
if (groupKey) if (measure === "start") {
|
|
2472
|
+
groupId = ++groupIdCounter;
|
|
2473
|
+
perfGroupIds.set(groupKey, {
|
|
2474
|
+
groupId,
|
|
2475
|
+
time: Date.now()
|
|
2476
|
+
});
|
|
2477
|
+
} else {
|
|
2478
|
+
const groupInfo = perfGroupIds.get(groupKey);
|
|
2479
|
+
if (groupInfo) {
|
|
2480
|
+
groupId = groupInfo.groupId;
|
|
2481
|
+
if (!duration) duration = Date.now() - groupInfo.time;
|
|
2482
|
+
perfGroupIds.delete(groupKey);
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
emitTimelineEvent("performance", {
|
|
2486
|
+
id: ++eventIdCounter,
|
|
2487
|
+
time: Date.now(),
|
|
2488
|
+
data: _objectSpread2({
|
|
2489
|
+
component: componentName,
|
|
2490
|
+
type,
|
|
2491
|
+
measure
|
|
2492
|
+
}, duration !== void 0 && { duration: {
|
|
2493
|
+
value: duration,
|
|
2494
|
+
display: `${duration.toFixed(2)} ms`
|
|
2495
|
+
} }),
|
|
2496
|
+
title: componentName,
|
|
2497
|
+
subtitle: type,
|
|
2498
|
+
groupId
|
|
2499
|
+
});
|
|
2500
|
+
}
|
|
2501
|
+
const fiberPerfMap = /* @__PURE__ */ new Map();
|
|
2502
|
+
function trackFiberPerformanceStart(fiber, type) {
|
|
2503
|
+
const componentName = getComponentName(fiber);
|
|
2504
|
+
const key = `${fiber.key || "null"}-${componentName}-${type}`;
|
|
2505
|
+
fiberPerfMap.set(key, {
|
|
2506
|
+
time: performance.now(),
|
|
2507
|
+
fiber
|
|
2508
|
+
});
|
|
2509
|
+
addPerformanceEvent(type, componentName, "start", void 0, key);
|
|
2510
|
+
}
|
|
2511
|
+
function trackFiberPerformanceEnd(fiber, type) {
|
|
2512
|
+
const componentName = getComponentName(fiber);
|
|
2513
|
+
const key = `${fiber.key || "null"}-${componentName}-${type}`;
|
|
2514
|
+
const perfData = fiberPerfMap.get(key);
|
|
2515
|
+
if (perfData) {
|
|
2516
|
+
const duration = performance.now() - perfData.time;
|
|
2517
|
+
fiberPerfMap.delete(key);
|
|
2518
|
+
addPerformanceEvent(type, componentName, "end", duration, key);
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
let eventListenersInstalled = false;
|
|
2522
|
+
function installTimelineEventListeners() {
|
|
2523
|
+
if (typeof window === "undefined" || eventListenersInstalled) return;
|
|
2524
|
+
eventListenersInstalled = true;
|
|
2525
|
+
[
|
|
2526
|
+
"mousedown",
|
|
2527
|
+
"mouseup",
|
|
2528
|
+
"click",
|
|
2529
|
+
"dblclick"
|
|
2530
|
+
].forEach((eventType) => {
|
|
2531
|
+
window.addEventListener(eventType, (event) => {
|
|
2532
|
+
addMouseEvent(eventType, event.clientX, event.clientY);
|
|
2533
|
+
}, {
|
|
2534
|
+
capture: true,
|
|
2535
|
+
passive: true
|
|
2536
|
+
});
|
|
2537
|
+
});
|
|
2538
|
+
[
|
|
2539
|
+
"keyup",
|
|
2540
|
+
"keydown",
|
|
2541
|
+
"keypress"
|
|
2542
|
+
].forEach((eventType) => {
|
|
2543
|
+
window.addEventListener(eventType, (event) => {
|
|
2544
|
+
addKeyboardEvent(eventType, event.key, {
|
|
2545
|
+
ctrlKey: event.ctrlKey,
|
|
2546
|
+
shiftKey: event.shiftKey,
|
|
2547
|
+
altKey: event.altKey,
|
|
2548
|
+
metaKey: event.metaKey
|
|
2549
|
+
});
|
|
2550
|
+
}, {
|
|
2551
|
+
capture: true,
|
|
2552
|
+
passive: true
|
|
2553
|
+
});
|
|
2554
|
+
});
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
//#endregion
|
|
2558
|
+
//#region ../../node_modules/.pnpm/birpc@2.8.0/node_modules/birpc/dist/index.mjs
|
|
2559
|
+
const TYPE_REQUEST = "q";
|
|
2560
|
+
const TYPE_RESPONSE = "s";
|
|
2561
|
+
const DEFAULT_TIMEOUT = 6e4;
|
|
2562
|
+
function defaultSerialize(i) {
|
|
2563
|
+
return i;
|
|
2564
|
+
}
|
|
2565
|
+
const defaultDeserialize = defaultSerialize;
|
|
2566
|
+
const { clearTimeout: clearTimeout$1, setTimeout: setTimeout$1 } = globalThis;
|
|
2567
|
+
const random = Math.random.bind(Math);
|
|
2568
|
+
function createBirpc($functions, options) {
|
|
2569
|
+
const { post, on, off = () => {}, eventNames = [], serialize: serialize$1 = defaultSerialize, deserialize: deserialize$1 = defaultDeserialize, resolver, bind = "rpc", timeout = DEFAULT_TIMEOUT } = options;
|
|
2570
|
+
let $closed = false;
|
|
2571
|
+
const _rpcPromiseMap = /* @__PURE__ */ new Map();
|
|
2572
|
+
let _promiseInit;
|
|
2573
|
+
async function _call(method, args, event, optional) {
|
|
2574
|
+
if ($closed) throw new Error(`[birpc] rpc is closed, cannot call "${method}"`);
|
|
2575
|
+
const req = {
|
|
2576
|
+
m: method,
|
|
2577
|
+
a: args,
|
|
2578
|
+
t: TYPE_REQUEST
|
|
2579
|
+
};
|
|
2580
|
+
if (optional) req.o = true;
|
|
2581
|
+
const send = async (_req) => post(serialize$1(_req));
|
|
2582
|
+
if (event) {
|
|
2583
|
+
await send(req);
|
|
2584
|
+
return;
|
|
2585
|
+
}
|
|
2586
|
+
if (_promiseInit) try {
|
|
2587
|
+
await _promiseInit;
|
|
2588
|
+
} finally {
|
|
2589
|
+
_promiseInit = void 0;
|
|
2590
|
+
}
|
|
2591
|
+
let { promise, resolve, reject } = createPromiseWithResolvers();
|
|
2592
|
+
const id = nanoid();
|
|
2593
|
+
req.i = id;
|
|
2594
|
+
let timeoutId;
|
|
2595
|
+
async function handler(newReq = req) {
|
|
2596
|
+
if (timeout >= 0) {
|
|
2597
|
+
var _timeoutId$unref;
|
|
2598
|
+
timeoutId = setTimeout$1(() => {
|
|
2599
|
+
try {
|
|
2600
|
+
var _options$onTimeoutErr;
|
|
2601
|
+
if (((_options$onTimeoutErr = options.onTimeoutError) === null || _options$onTimeoutErr === void 0 ? void 0 : _options$onTimeoutErr.call(options, method, args)) !== true) throw new Error(`[birpc] timeout on calling "${method}"`);
|
|
2602
|
+
} catch (e) {
|
|
2603
|
+
reject(e);
|
|
2604
|
+
}
|
|
2605
|
+
_rpcPromiseMap.delete(id);
|
|
2606
|
+
}, timeout);
|
|
2607
|
+
if (typeof timeoutId === "object") timeoutId = (_timeoutId$unref = timeoutId.unref) === null || _timeoutId$unref === void 0 ? void 0 : _timeoutId$unref.call(timeoutId);
|
|
2608
|
+
}
|
|
2609
|
+
_rpcPromiseMap.set(id, {
|
|
2610
|
+
resolve,
|
|
2611
|
+
reject,
|
|
2612
|
+
timeoutId,
|
|
2613
|
+
method
|
|
2614
|
+
});
|
|
2615
|
+
await send(newReq);
|
|
2616
|
+
return promise;
|
|
2617
|
+
}
|
|
2618
|
+
try {
|
|
2619
|
+
if (options.onRequest) await options.onRequest(req, handler, resolve);
|
|
2620
|
+
else await handler();
|
|
2621
|
+
} catch (e) {
|
|
2622
|
+
var _options$onGeneralErr;
|
|
2623
|
+
if (((_options$onGeneralErr = options.onGeneralError) === null || _options$onGeneralErr === void 0 ? void 0 : _options$onGeneralErr.call(options, e)) !== true) throw e;
|
|
2624
|
+
return;
|
|
2625
|
+
} finally {
|
|
2626
|
+
clearTimeout$1(timeoutId);
|
|
2627
|
+
_rpcPromiseMap.delete(id);
|
|
2628
|
+
}
|
|
2629
|
+
return promise;
|
|
2630
|
+
}
|
|
2631
|
+
const $call = (method, ...args) => _call(method, args, false);
|
|
2632
|
+
const $callOptional = (method, ...args) => _call(method, args, false, true);
|
|
2633
|
+
const $callEvent = (method, ...args) => _call(method, args, true);
|
|
2634
|
+
const $callRaw = (options2) => _call(options2.method, options2.args, options2.event, options2.optional);
|
|
2635
|
+
const builtinMethods = {
|
|
2636
|
+
$call,
|
|
2637
|
+
$callOptional,
|
|
2638
|
+
$callEvent,
|
|
2639
|
+
$callRaw,
|
|
2640
|
+
$rejectPendingCalls,
|
|
2641
|
+
get $closed() {
|
|
2642
|
+
return $closed;
|
|
2643
|
+
},
|
|
2644
|
+
$close,
|
|
2645
|
+
$functions
|
|
2646
|
+
};
|
|
2647
|
+
const rpc = new Proxy({}, { get(_, method) {
|
|
2648
|
+
if (Object.prototype.hasOwnProperty.call(builtinMethods, method)) return builtinMethods[method];
|
|
2649
|
+
if (method === "then" && !eventNames.includes("then") && !("then" in $functions)) return void 0;
|
|
2650
|
+
const sendEvent = (...args) => _call(method, args, true);
|
|
2651
|
+
if (eventNames.includes(method)) {
|
|
2652
|
+
sendEvent.asEvent = sendEvent;
|
|
2653
|
+
return sendEvent;
|
|
2654
|
+
}
|
|
2655
|
+
const sendCall = (...args) => _call(method, args, false);
|
|
2656
|
+
sendCall.asEvent = sendEvent;
|
|
2657
|
+
return sendCall;
|
|
2658
|
+
} });
|
|
2659
|
+
function $close(customError) {
|
|
2660
|
+
$closed = true;
|
|
2661
|
+
_rpcPromiseMap.forEach(({ reject, method }) => {
|
|
2662
|
+
const error = /* @__PURE__ */ new Error(`[birpc] rpc is closed, cannot call "${method}"`);
|
|
2663
|
+
if (customError) {
|
|
2664
|
+
var _customError$cause;
|
|
2665
|
+
(_customError$cause = customError.cause) !== null && _customError$cause !== void 0 || (customError.cause = error);
|
|
2666
|
+
return reject(customError);
|
|
2667
|
+
}
|
|
2668
|
+
reject(error);
|
|
2669
|
+
});
|
|
2670
|
+
_rpcPromiseMap.clear();
|
|
2671
|
+
off(onMessage);
|
|
2672
|
+
}
|
|
2673
|
+
function $rejectPendingCalls(handler) {
|
|
2674
|
+
const handlerResults = Array.from(_rpcPromiseMap.values()).map(({ method, reject }) => {
|
|
2675
|
+
if (!handler) return reject(/* @__PURE__ */ new Error(`[birpc]: rejected pending call "${method}".`));
|
|
2676
|
+
return handler({
|
|
2677
|
+
method,
|
|
2678
|
+
reject
|
|
2679
|
+
});
|
|
2680
|
+
});
|
|
2681
|
+
_rpcPromiseMap.clear();
|
|
2682
|
+
return handlerResults;
|
|
2683
|
+
}
|
|
2684
|
+
async function onMessage(data, ...extra) {
|
|
2685
|
+
let msg;
|
|
2686
|
+
try {
|
|
2687
|
+
msg = deserialize$1(data);
|
|
2688
|
+
} catch (e) {
|
|
2689
|
+
var _options$onGeneralErr2;
|
|
2690
|
+
if (((_options$onGeneralErr2 = options.onGeneralError) === null || _options$onGeneralErr2 === void 0 ? void 0 : _options$onGeneralErr2.call(options, e)) !== true) throw e;
|
|
2691
|
+
return;
|
|
2692
|
+
}
|
|
2693
|
+
if (msg.t === TYPE_REQUEST) {
|
|
2694
|
+
const { m: method, a: args, o: optional } = msg;
|
|
2695
|
+
let result, error;
|
|
2696
|
+
let fn = await (resolver ? resolver(method, $functions[method]) : $functions[method]);
|
|
2697
|
+
if (optional) fn || (fn = () => void 0);
|
|
2698
|
+
if (!fn) error = /* @__PURE__ */ new Error(`[birpc] function "${method}" not found`);
|
|
2699
|
+
else try {
|
|
2700
|
+
result = await fn.apply(bind === "rpc" ? rpc : $functions, args);
|
|
2701
|
+
} catch (e) {
|
|
2702
|
+
error = e;
|
|
2703
|
+
}
|
|
2704
|
+
if (msg.i) {
|
|
2705
|
+
if (error && options.onError) options.onError(error, method, args);
|
|
2706
|
+
if (error && options.onFunctionError) {
|
|
2707
|
+
if (options.onFunctionError(error, method, args) === true) return;
|
|
2708
|
+
}
|
|
2709
|
+
if (!error) try {
|
|
2710
|
+
await post(serialize$1({
|
|
2711
|
+
t: TYPE_RESPONSE,
|
|
2712
|
+
i: msg.i,
|
|
2713
|
+
r: result
|
|
2714
|
+
}), ...extra);
|
|
2715
|
+
return;
|
|
2716
|
+
} catch (e) {
|
|
2717
|
+
var _options$onGeneralErr3;
|
|
2718
|
+
error = e;
|
|
2719
|
+
if (((_options$onGeneralErr3 = options.onGeneralError) === null || _options$onGeneralErr3 === void 0 ? void 0 : _options$onGeneralErr3.call(options, e, method, args)) !== true) throw e;
|
|
2720
|
+
}
|
|
2721
|
+
try {
|
|
2722
|
+
await post(serialize$1({
|
|
2723
|
+
t: TYPE_RESPONSE,
|
|
2724
|
+
i: msg.i,
|
|
2725
|
+
e: error
|
|
2726
|
+
}), ...extra);
|
|
2727
|
+
} catch (e) {
|
|
2728
|
+
var _options$onGeneralErr4;
|
|
2729
|
+
if (((_options$onGeneralErr4 = options.onGeneralError) === null || _options$onGeneralErr4 === void 0 ? void 0 : _options$onGeneralErr4.call(options, e, method, args)) !== true) throw e;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
} else {
|
|
2733
|
+
const { i: ack, r: result, e: error } = msg;
|
|
2734
|
+
const promise = _rpcPromiseMap.get(ack);
|
|
2735
|
+
if (promise) {
|
|
2736
|
+
clearTimeout$1(promise.timeoutId);
|
|
2737
|
+
if (error) promise.reject(error);
|
|
2738
|
+
else promise.resolve(result);
|
|
2739
|
+
}
|
|
2740
|
+
_rpcPromiseMap.delete(ack);
|
|
2741
|
+
}
|
|
2742
|
+
}
|
|
2743
|
+
_promiseInit = on(onMessage);
|
|
2744
|
+
return rpc;
|
|
2745
|
+
}
|
|
2746
|
+
const cacheMap = /* @__PURE__ */ new WeakMap();
|
|
2747
|
+
function cachedMap(items, fn) {
|
|
2748
|
+
return items.map((i) => {
|
|
2749
|
+
let r = cacheMap.get(i);
|
|
2750
|
+
if (!r) {
|
|
2751
|
+
r = fn(i);
|
|
2752
|
+
cacheMap.set(i, r);
|
|
2753
|
+
}
|
|
2754
|
+
return r;
|
|
2755
|
+
});
|
|
2756
|
+
}
|
|
2757
|
+
function createBirpcGroup(functions, channels, options = {}) {
|
|
2758
|
+
const getChannels = () => typeof channels === "function" ? channels() : channels;
|
|
2759
|
+
const getClients = (channels2 = getChannels()) => cachedMap(channels2, (s) => createBirpc(functions, _objectSpread2(_objectSpread2({}, options), s)));
|
|
2760
|
+
function _boardcast(method, args, event, optional) {
|
|
2761
|
+
const clients = getClients();
|
|
2762
|
+
return Promise.all(clients.map((c) => c.$callRaw({
|
|
2763
|
+
method,
|
|
2764
|
+
args,
|
|
2765
|
+
event,
|
|
2766
|
+
optional
|
|
2767
|
+
})));
|
|
2768
|
+
}
|
|
2769
|
+
function $call(method, ...args) {
|
|
2770
|
+
return _boardcast(method, args, false);
|
|
2771
|
+
}
|
|
2772
|
+
function $callOptional(method, ...args) {
|
|
2773
|
+
return _boardcast(method, args, false, true);
|
|
2774
|
+
}
|
|
2775
|
+
function $callEvent(method, ...args) {
|
|
2776
|
+
return _boardcast(method, args, true);
|
|
2777
|
+
}
|
|
2778
|
+
const broadcastBuiltin = {
|
|
2779
|
+
$call,
|
|
2780
|
+
$callOptional,
|
|
2781
|
+
$callEvent
|
|
2782
|
+
};
|
|
2783
|
+
const broadcastProxy = new Proxy({}, { get(_, method) {
|
|
2784
|
+
if (Object.prototype.hasOwnProperty.call(broadcastBuiltin, method)) return broadcastBuiltin[method];
|
|
2785
|
+
const callbacks = getClients().map((c) => c[method]);
|
|
2786
|
+
const sendCall = (...args) => {
|
|
2787
|
+
return Promise.all(callbacks.map((i) => i(...args)));
|
|
2788
|
+
};
|
|
2789
|
+
sendCall.asEvent = async (...args) => {
|
|
2790
|
+
await Promise.all(callbacks.map((i) => i.asEvent(...args)));
|
|
2791
|
+
};
|
|
2792
|
+
return sendCall;
|
|
2793
|
+
} });
|
|
2794
|
+
function updateChannels(fn) {
|
|
2795
|
+
const channels2 = getChannels();
|
|
2796
|
+
fn === null || fn === void 0 || fn(channels2);
|
|
2797
|
+
return getClients(channels2);
|
|
2798
|
+
}
|
|
2799
|
+
getClients();
|
|
2800
|
+
return {
|
|
2801
|
+
get clients() {
|
|
2802
|
+
return getClients();
|
|
2803
|
+
},
|
|
2804
|
+
functions,
|
|
2805
|
+
updateChannels,
|
|
2806
|
+
broadcast: broadcastProxy,
|
|
2807
|
+
boardcast: broadcastProxy
|
|
2808
|
+
};
|
|
2809
|
+
}
|
|
2810
|
+
function createPromiseWithResolvers() {
|
|
2811
|
+
let resolve;
|
|
2812
|
+
let reject;
|
|
2813
|
+
return {
|
|
2814
|
+
promise: new Promise((res, rej) => {
|
|
2815
|
+
resolve = res;
|
|
2816
|
+
reject = rej;
|
|
2817
|
+
}),
|
|
2818
|
+
resolve,
|
|
2819
|
+
reject
|
|
2820
|
+
};
|
|
2821
|
+
}
|
|
2822
|
+
const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
2823
|
+
function nanoid(size = 21) {
|
|
2824
|
+
let id = "";
|
|
2825
|
+
let i = size;
|
|
2826
|
+
while (i--) id += urlAlphabet[random() * 64 | 0];
|
|
2827
|
+
return id;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
//#endregion
|
|
2831
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/double-indexed-kv.js
|
|
2832
|
+
var DoubleIndexedKV = class {
|
|
2833
|
+
constructor() {
|
|
2834
|
+
this.keyToValue = /* @__PURE__ */ new Map();
|
|
2835
|
+
this.valueToKey = /* @__PURE__ */ new Map();
|
|
2836
|
+
}
|
|
2837
|
+
set(key, value) {
|
|
2838
|
+
this.keyToValue.set(key, value);
|
|
2839
|
+
this.valueToKey.set(value, key);
|
|
2840
|
+
}
|
|
2841
|
+
getByKey(key) {
|
|
2842
|
+
return this.keyToValue.get(key);
|
|
2843
|
+
}
|
|
2844
|
+
getByValue(value) {
|
|
2845
|
+
return this.valueToKey.get(value);
|
|
2846
|
+
}
|
|
2847
|
+
clear() {
|
|
2848
|
+
this.keyToValue.clear();
|
|
2849
|
+
this.valueToKey.clear();
|
|
2850
|
+
}
|
|
2851
|
+
};
|
|
2852
|
+
|
|
2853
|
+
//#endregion
|
|
2854
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/registry.js
|
|
2855
|
+
var Registry = class {
|
|
2856
|
+
constructor(generateIdentifier) {
|
|
2857
|
+
this.generateIdentifier = generateIdentifier;
|
|
2858
|
+
this.kv = new DoubleIndexedKV();
|
|
2859
|
+
}
|
|
2860
|
+
register(value, identifier) {
|
|
2861
|
+
if (this.kv.getByValue(value)) return;
|
|
2862
|
+
if (!identifier) identifier = this.generateIdentifier(value);
|
|
2863
|
+
this.kv.set(identifier, value);
|
|
2864
|
+
}
|
|
2865
|
+
clear() {
|
|
2866
|
+
this.kv.clear();
|
|
2867
|
+
}
|
|
2868
|
+
getIdentifier(value) {
|
|
2869
|
+
return this.kv.getByValue(value);
|
|
2870
|
+
}
|
|
2871
|
+
getValue(identifier) {
|
|
2872
|
+
return this.kv.getByKey(identifier);
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
|
|
2876
|
+
//#endregion
|
|
2877
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/class-registry.js
|
|
2878
|
+
var ClassRegistry = class extends Registry {
|
|
2879
|
+
constructor() {
|
|
2880
|
+
super((c) => c.name);
|
|
2881
|
+
this.classToAllowedProps = /* @__PURE__ */ new Map();
|
|
2882
|
+
}
|
|
2883
|
+
register(value, options) {
|
|
2884
|
+
if (typeof options === "object") {
|
|
2885
|
+
if (options.allowProps) this.classToAllowedProps.set(value, options.allowProps);
|
|
2886
|
+
super.register(value, options.identifier);
|
|
2887
|
+
} else super.register(value, options);
|
|
2888
|
+
}
|
|
2889
|
+
getAllowedProps(value) {
|
|
2890
|
+
return this.classToAllowedProps.get(value);
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2893
|
+
|
|
2894
|
+
//#endregion
|
|
2895
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/util.js
|
|
2896
|
+
function valuesOfObj(record) {
|
|
2897
|
+
if ("values" in Object) return Object.values(record);
|
|
2898
|
+
const values = [];
|
|
2899
|
+
for (const key in record) if (record.hasOwnProperty(key)) values.push(record[key]);
|
|
2900
|
+
return values;
|
|
2901
|
+
}
|
|
2902
|
+
function find(record, predicate) {
|
|
2903
|
+
const values = valuesOfObj(record);
|
|
2904
|
+
if ("find" in values) return values.find(predicate);
|
|
2905
|
+
const valuesNotNever = values;
|
|
2906
|
+
for (let i = 0; i < valuesNotNever.length; i++) {
|
|
2907
|
+
const value = valuesNotNever[i];
|
|
2908
|
+
if (predicate(value)) return value;
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
function forEach(record, run) {
|
|
2912
|
+
Object.entries(record).forEach(([key, value]) => run(value, key));
|
|
2913
|
+
}
|
|
2914
|
+
function includes(arr, value) {
|
|
2915
|
+
return arr.indexOf(value) !== -1;
|
|
2916
|
+
}
|
|
2917
|
+
function findArr(record, predicate) {
|
|
2918
|
+
for (let i = 0; i < record.length; i++) {
|
|
2919
|
+
const value = record[i];
|
|
2920
|
+
if (predicate(value)) return value;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
|
|
2924
|
+
//#endregion
|
|
2925
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/custom-transformer-registry.js
|
|
2926
|
+
var CustomTransformerRegistry = class {
|
|
2927
|
+
constructor() {
|
|
2928
|
+
this.transfomers = {};
|
|
2929
|
+
}
|
|
2930
|
+
register(transformer) {
|
|
2931
|
+
this.transfomers[transformer.name] = transformer;
|
|
2932
|
+
}
|
|
2933
|
+
findApplicable(v) {
|
|
2934
|
+
return find(this.transfomers, (transformer) => transformer.isApplicable(v));
|
|
2935
|
+
}
|
|
2936
|
+
findByName(name) {
|
|
2937
|
+
return this.transfomers[name];
|
|
2938
|
+
}
|
|
2939
|
+
};
|
|
2940
|
+
|
|
2941
|
+
//#endregion
|
|
2942
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/is.js
|
|
2943
|
+
const getType$1 = (payload) => Object.prototype.toString.call(payload).slice(8, -1);
|
|
2944
|
+
const isUndefined = (payload) => typeof payload === "undefined";
|
|
2945
|
+
const isNull = (payload) => payload === null;
|
|
2946
|
+
const isPlainObject$1 = (payload) => {
|
|
2947
|
+
if (typeof payload !== "object" || payload === null) return false;
|
|
2948
|
+
if (payload === Object.prototype) return false;
|
|
2949
|
+
if (Object.getPrototypeOf(payload) === null) return true;
|
|
2950
|
+
return Object.getPrototypeOf(payload) === Object.prototype;
|
|
2951
|
+
};
|
|
2952
|
+
const isEmptyObject = (payload) => isPlainObject$1(payload) && Object.keys(payload).length === 0;
|
|
2953
|
+
const isArray$1 = (payload) => Array.isArray(payload);
|
|
2954
|
+
const isString = (payload) => typeof payload === "string";
|
|
2955
|
+
const isNumber = (payload) => typeof payload === "number" && !isNaN(payload);
|
|
2956
|
+
const isBoolean = (payload) => typeof payload === "boolean";
|
|
2957
|
+
const isRegExp = (payload) => payload instanceof RegExp;
|
|
2958
|
+
const isMap = (payload) => payload instanceof Map;
|
|
2959
|
+
const isSet = (payload) => payload instanceof Set;
|
|
2960
|
+
const isSymbol = (payload) => getType$1(payload) === "Symbol";
|
|
2961
|
+
const isDate = (payload) => payload instanceof Date && !isNaN(payload.valueOf());
|
|
2962
|
+
const isError = (payload) => payload instanceof Error;
|
|
2963
|
+
const isNaNValue = (payload) => typeof payload === "number" && isNaN(payload);
|
|
2964
|
+
const isPrimitive = (payload) => isBoolean(payload) || isNull(payload) || isUndefined(payload) || isNumber(payload) || isString(payload) || isSymbol(payload);
|
|
2965
|
+
const isBigint = (payload) => typeof payload === "bigint";
|
|
2966
|
+
const isInfinite = (payload) => payload === Infinity || payload === -Infinity;
|
|
2967
|
+
const isTypedArray = (payload) => ArrayBuffer.isView(payload) && !(payload instanceof DataView);
|
|
2968
|
+
const isURL = (payload) => payload instanceof URL;
|
|
2969
|
+
|
|
2970
|
+
//#endregion
|
|
2971
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/pathstringifier.js
|
|
2972
|
+
const escapeKey = (key) => key.replace(/\\/g, "\\\\").replace(/\./g, "\\.");
|
|
2973
|
+
const stringifyPath = (path) => path.map(String).map(escapeKey).join(".");
|
|
2974
|
+
const parsePath = (string, legacyPaths) => {
|
|
2975
|
+
const result = [];
|
|
2976
|
+
let segment = "";
|
|
2977
|
+
for (let i = 0; i < string.length; i++) {
|
|
2978
|
+
let char = string.charAt(i);
|
|
2979
|
+
if (!legacyPaths && char === "\\") {
|
|
2980
|
+
const escaped = string.charAt(i + 1);
|
|
2981
|
+
if (escaped === "\\") {
|
|
2982
|
+
segment += "\\";
|
|
2983
|
+
i++;
|
|
2984
|
+
continue;
|
|
2985
|
+
} else if (escaped !== ".") throw Error("invalid path");
|
|
2986
|
+
}
|
|
2987
|
+
if (char === "\\" && string.charAt(i + 1) === ".") {
|
|
2988
|
+
segment += ".";
|
|
2989
|
+
i++;
|
|
2990
|
+
continue;
|
|
2991
|
+
}
|
|
2992
|
+
if (char === ".") {
|
|
2993
|
+
result.push(segment);
|
|
2994
|
+
segment = "";
|
|
2995
|
+
continue;
|
|
2996
|
+
}
|
|
2997
|
+
segment += char;
|
|
2998
|
+
}
|
|
2999
|
+
const lastSegment = segment;
|
|
3000
|
+
result.push(lastSegment);
|
|
3001
|
+
return result;
|
|
3002
|
+
};
|
|
3003
|
+
|
|
3004
|
+
//#endregion
|
|
3005
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/transformer.js
|
|
3006
|
+
function simpleTransformation(isApplicable, annotation, transform, untransform) {
|
|
3007
|
+
return {
|
|
3008
|
+
isApplicable,
|
|
3009
|
+
annotation,
|
|
3010
|
+
transform,
|
|
3011
|
+
untransform
|
|
3012
|
+
};
|
|
3013
|
+
}
|
|
3014
|
+
const simpleRules = [
|
|
3015
|
+
simpleTransformation(isUndefined, "undefined", () => null, () => void 0),
|
|
3016
|
+
simpleTransformation(isBigint, "bigint", (v) => v.toString(), (v) => {
|
|
3017
|
+
if (typeof BigInt !== "undefined") return BigInt(v);
|
|
3018
|
+
console.error("Please add a BigInt polyfill.");
|
|
3019
|
+
return v;
|
|
3020
|
+
}),
|
|
3021
|
+
simpleTransformation(isDate, "Date", (v) => v.toISOString(), (v) => new Date(v)),
|
|
3022
|
+
simpleTransformation(isError, "Error", (v, superJson) => {
|
|
3023
|
+
const baseError = {
|
|
3024
|
+
name: v.name,
|
|
3025
|
+
message: v.message
|
|
3026
|
+
};
|
|
3027
|
+
if ("cause" in v) baseError.cause = v.cause;
|
|
3028
|
+
superJson.allowedErrorProps.forEach((prop) => {
|
|
3029
|
+
baseError[prop] = v[prop];
|
|
3030
|
+
});
|
|
3031
|
+
return baseError;
|
|
3032
|
+
}, (v, superJson) => {
|
|
3033
|
+
const e = new Error(v.message, { cause: v.cause });
|
|
3034
|
+
e.name = v.name;
|
|
3035
|
+
e.stack = v.stack;
|
|
3036
|
+
superJson.allowedErrorProps.forEach((prop) => {
|
|
3037
|
+
e[prop] = v[prop];
|
|
3038
|
+
});
|
|
3039
|
+
return e;
|
|
3040
|
+
}),
|
|
3041
|
+
simpleTransformation(isRegExp, "regexp", (v) => "" + v, (regex) => {
|
|
3042
|
+
const body = regex.slice(1, regex.lastIndexOf("/"));
|
|
3043
|
+
const flags = regex.slice(regex.lastIndexOf("/") + 1);
|
|
3044
|
+
return new RegExp(body, flags);
|
|
3045
|
+
}),
|
|
3046
|
+
simpleTransformation(isSet, "set", (v) => [...v.values()], (v) => new Set(v)),
|
|
3047
|
+
simpleTransformation(isMap, "map", (v) => [...v.entries()], (v) => new Map(v)),
|
|
3048
|
+
simpleTransformation((v) => isNaNValue(v) || isInfinite(v), "number", (v) => {
|
|
3049
|
+
if (isNaNValue(v)) return "NaN";
|
|
3050
|
+
if (v > 0) return "Infinity";
|
|
3051
|
+
else return "-Infinity";
|
|
3052
|
+
}, Number),
|
|
3053
|
+
simpleTransformation((v) => v === 0 && 1 / v === -Infinity, "number", () => {
|
|
3054
|
+
return "-0";
|
|
3055
|
+
}, Number),
|
|
3056
|
+
simpleTransformation(isURL, "URL", (v) => v.toString(), (v) => new URL(v))
|
|
3057
|
+
];
|
|
3058
|
+
function compositeTransformation(isApplicable, annotation, transform, untransform) {
|
|
3059
|
+
return {
|
|
3060
|
+
isApplicable,
|
|
3061
|
+
annotation,
|
|
3062
|
+
transform,
|
|
3063
|
+
untransform
|
|
3064
|
+
};
|
|
3065
|
+
}
|
|
3066
|
+
const symbolRule = compositeTransformation((s, superJson) => {
|
|
3067
|
+
if (isSymbol(s)) return !!superJson.symbolRegistry.getIdentifier(s);
|
|
3068
|
+
return false;
|
|
3069
|
+
}, (s, superJson) => {
|
|
3070
|
+
return ["symbol", superJson.symbolRegistry.getIdentifier(s)];
|
|
3071
|
+
}, (v) => v.description, (_, a, superJson) => {
|
|
3072
|
+
const value = superJson.symbolRegistry.getValue(a[1]);
|
|
3073
|
+
if (!value) throw new Error("Trying to deserialize unknown symbol");
|
|
3074
|
+
return value;
|
|
3075
|
+
});
|
|
3076
|
+
const constructorToName = [
|
|
3077
|
+
Int8Array,
|
|
3078
|
+
Uint8Array,
|
|
3079
|
+
Int16Array,
|
|
3080
|
+
Uint16Array,
|
|
3081
|
+
Int32Array,
|
|
3082
|
+
Uint32Array,
|
|
3083
|
+
Float32Array,
|
|
3084
|
+
Float64Array,
|
|
3085
|
+
Uint8ClampedArray
|
|
3086
|
+
].reduce((obj, ctor) => {
|
|
3087
|
+
obj[ctor.name] = ctor;
|
|
3088
|
+
return obj;
|
|
3089
|
+
}, {});
|
|
3090
|
+
const typedArrayRule = compositeTransformation(isTypedArray, (v) => ["typed-array", v.constructor.name], (v) => [...v], (v, a) => {
|
|
3091
|
+
const ctor = constructorToName[a[1]];
|
|
3092
|
+
if (!ctor) throw new Error("Trying to deserialize unknown typed array");
|
|
3093
|
+
return new ctor(v);
|
|
3094
|
+
});
|
|
3095
|
+
function isInstanceOfRegisteredClass(potentialClass, superJson) {
|
|
3096
|
+
if (potentialClass === null || potentialClass === void 0 ? void 0 : potentialClass.constructor) return !!superJson.classRegistry.getIdentifier(potentialClass.constructor);
|
|
3097
|
+
return false;
|
|
3098
|
+
}
|
|
3099
|
+
const classRule = compositeTransformation(isInstanceOfRegisteredClass, (clazz, superJson) => {
|
|
3100
|
+
return ["class", superJson.classRegistry.getIdentifier(clazz.constructor)];
|
|
3101
|
+
}, (clazz, superJson) => {
|
|
3102
|
+
const allowedProps = superJson.classRegistry.getAllowedProps(clazz.constructor);
|
|
3103
|
+
if (!allowedProps) return _objectSpread2({}, clazz);
|
|
3104
|
+
const result = {};
|
|
3105
|
+
allowedProps.forEach((prop) => {
|
|
3106
|
+
result[prop] = clazz[prop];
|
|
3107
|
+
});
|
|
3108
|
+
return result;
|
|
3109
|
+
}, (v, a, superJson) => {
|
|
3110
|
+
const clazz = superJson.classRegistry.getValue(a[1]);
|
|
3111
|
+
if (!clazz) throw new Error(`Trying to deserialize unknown class '${a[1]}' - check https://github.com/blitz-js/superjson/issues/116#issuecomment-773996564`);
|
|
3112
|
+
return Object.assign(Object.create(clazz.prototype), v);
|
|
3113
|
+
});
|
|
3114
|
+
const customRule = compositeTransformation((value, superJson) => {
|
|
3115
|
+
return !!superJson.customTransformerRegistry.findApplicable(value);
|
|
3116
|
+
}, (value, superJson) => {
|
|
3117
|
+
return ["custom", superJson.customTransformerRegistry.findApplicable(value).name];
|
|
3118
|
+
}, (value, superJson) => {
|
|
3119
|
+
return superJson.customTransformerRegistry.findApplicable(value).serialize(value);
|
|
3120
|
+
}, (v, a, superJson) => {
|
|
3121
|
+
const transformer = superJson.customTransformerRegistry.findByName(a[1]);
|
|
3122
|
+
if (!transformer) throw new Error("Trying to deserialize unknown custom value");
|
|
3123
|
+
return transformer.deserialize(v);
|
|
3124
|
+
});
|
|
3125
|
+
const compositeRules = [
|
|
3126
|
+
classRule,
|
|
3127
|
+
symbolRule,
|
|
3128
|
+
customRule,
|
|
3129
|
+
typedArrayRule
|
|
3130
|
+
];
|
|
3131
|
+
const transformValue = (value, superJson) => {
|
|
3132
|
+
const applicableCompositeRule = findArr(compositeRules, (rule) => rule.isApplicable(value, superJson));
|
|
3133
|
+
if (applicableCompositeRule) return {
|
|
3134
|
+
value: applicableCompositeRule.transform(value, superJson),
|
|
3135
|
+
type: applicableCompositeRule.annotation(value, superJson)
|
|
3136
|
+
};
|
|
3137
|
+
const applicableSimpleRule = findArr(simpleRules, (rule) => rule.isApplicable(value, superJson));
|
|
3138
|
+
if (applicableSimpleRule) return {
|
|
3139
|
+
value: applicableSimpleRule.transform(value, superJson),
|
|
3140
|
+
type: applicableSimpleRule.annotation
|
|
3141
|
+
};
|
|
3142
|
+
};
|
|
3143
|
+
const simpleRulesByAnnotation = {};
|
|
3144
|
+
simpleRules.forEach((rule) => {
|
|
3145
|
+
simpleRulesByAnnotation[rule.annotation] = rule;
|
|
3146
|
+
});
|
|
3147
|
+
const untransformValue = (json, type, superJson) => {
|
|
3148
|
+
if (isArray$1(type)) switch (type[0]) {
|
|
3149
|
+
case "symbol": return symbolRule.untransform(json, type, superJson);
|
|
3150
|
+
case "class": return classRule.untransform(json, type, superJson);
|
|
3151
|
+
case "custom": return customRule.untransform(json, type, superJson);
|
|
3152
|
+
case "typed-array": return typedArrayRule.untransform(json, type, superJson);
|
|
3153
|
+
default: throw new Error("Unknown transformation: " + type);
|
|
3154
|
+
}
|
|
3155
|
+
else {
|
|
3156
|
+
const transformation = simpleRulesByAnnotation[type];
|
|
3157
|
+
if (!transformation) throw new Error("Unknown transformation: " + type);
|
|
3158
|
+
return transformation.untransform(json, superJson);
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
|
|
3162
|
+
//#endregion
|
|
3163
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/accessDeep.js
|
|
3164
|
+
const getNthKey = (value, n) => {
|
|
3165
|
+
if (n > value.size) throw new Error("index out of bounds");
|
|
3166
|
+
const keys = value.keys();
|
|
3167
|
+
while (n > 0) {
|
|
3168
|
+
keys.next();
|
|
3169
|
+
n--;
|
|
3170
|
+
}
|
|
3171
|
+
return keys.next().value;
|
|
3172
|
+
};
|
|
3173
|
+
function validatePath(path) {
|
|
3174
|
+
if (includes(path, "__proto__")) throw new Error("__proto__ is not allowed as a property");
|
|
3175
|
+
if (includes(path, "prototype")) throw new Error("prototype is not allowed as a property");
|
|
3176
|
+
if (includes(path, "constructor")) throw new Error("constructor is not allowed as a property");
|
|
3177
|
+
}
|
|
3178
|
+
const getDeep = (object, path) => {
|
|
3179
|
+
validatePath(path);
|
|
3180
|
+
for (let i = 0; i < path.length; i++) {
|
|
3181
|
+
const key = path[i];
|
|
3182
|
+
if (isSet(object)) object = getNthKey(object, +key);
|
|
3183
|
+
else if (isMap(object)) {
|
|
3184
|
+
const row = +key;
|
|
3185
|
+
const type = +path[++i] === 0 ? "key" : "value";
|
|
3186
|
+
const keyOfRow = getNthKey(object, row);
|
|
3187
|
+
switch (type) {
|
|
3188
|
+
case "key":
|
|
3189
|
+
object = keyOfRow;
|
|
3190
|
+
break;
|
|
3191
|
+
case "value":
|
|
3192
|
+
object = object.get(keyOfRow);
|
|
3193
|
+
break;
|
|
3194
|
+
}
|
|
3195
|
+
} else object = object[key];
|
|
3196
|
+
}
|
|
3197
|
+
return object;
|
|
3198
|
+
};
|
|
3199
|
+
const setDeep = (object, path, mapper) => {
|
|
3200
|
+
validatePath(path);
|
|
3201
|
+
if (path.length === 0) return mapper(object);
|
|
3202
|
+
let parent = object;
|
|
3203
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
3204
|
+
const key = path[i];
|
|
3205
|
+
if (isArray$1(parent)) {
|
|
3206
|
+
const index = +key;
|
|
3207
|
+
parent = parent[index];
|
|
3208
|
+
} else if (isPlainObject$1(parent)) parent = parent[key];
|
|
3209
|
+
else if (isSet(parent)) {
|
|
3210
|
+
const row = +key;
|
|
3211
|
+
parent = getNthKey(parent, row);
|
|
3212
|
+
} else if (isMap(parent)) {
|
|
3213
|
+
if (i === path.length - 2) break;
|
|
3214
|
+
const row = +key;
|
|
3215
|
+
const type = +path[++i] === 0 ? "key" : "value";
|
|
3216
|
+
const keyOfRow = getNthKey(parent, row);
|
|
3217
|
+
switch (type) {
|
|
3218
|
+
case "key":
|
|
3219
|
+
parent = keyOfRow;
|
|
3220
|
+
break;
|
|
3221
|
+
case "value":
|
|
3222
|
+
parent = parent.get(keyOfRow);
|
|
3223
|
+
break;
|
|
3224
|
+
}
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
const lastKey = path[path.length - 1];
|
|
3228
|
+
if (isArray$1(parent)) parent[+lastKey] = mapper(parent[+lastKey]);
|
|
3229
|
+
else if (isPlainObject$1(parent)) parent[lastKey] = mapper(parent[lastKey]);
|
|
3230
|
+
if (isSet(parent)) {
|
|
3231
|
+
const oldValue = getNthKey(parent, +lastKey);
|
|
3232
|
+
const newValue = mapper(oldValue);
|
|
3233
|
+
if (oldValue !== newValue) {
|
|
3234
|
+
parent.delete(oldValue);
|
|
3235
|
+
parent.add(newValue);
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
if (isMap(parent)) {
|
|
3239
|
+
const row = +path[path.length - 2];
|
|
3240
|
+
const keyToRow = getNthKey(parent, row);
|
|
3241
|
+
switch (+lastKey === 0 ? "key" : "value") {
|
|
3242
|
+
case "key": {
|
|
3243
|
+
const newKey = mapper(keyToRow);
|
|
3244
|
+
parent.set(newKey, parent.get(keyToRow));
|
|
3245
|
+
if (newKey !== keyToRow) parent.delete(keyToRow);
|
|
3246
|
+
break;
|
|
3247
|
+
}
|
|
3248
|
+
case "value":
|
|
3249
|
+
parent.set(keyToRow, mapper(parent.get(keyToRow)));
|
|
3250
|
+
break;
|
|
3251
|
+
}
|
|
3252
|
+
}
|
|
3253
|
+
return object;
|
|
3254
|
+
};
|
|
3255
|
+
|
|
3256
|
+
//#endregion
|
|
3257
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/plainer.js
|
|
3258
|
+
const enableLegacyPaths = (version) => version < 1;
|
|
3259
|
+
function traverse(tree, walker$1, version, origin = []) {
|
|
3260
|
+
if (!tree) return;
|
|
3261
|
+
const legacyPaths = enableLegacyPaths(version);
|
|
3262
|
+
if (!isArray$1(tree)) {
|
|
3263
|
+
forEach(tree, (subtree, key) => traverse(subtree, walker$1, version, [...origin, ...parsePath(key, legacyPaths)]));
|
|
3264
|
+
return;
|
|
3265
|
+
}
|
|
3266
|
+
const [nodeValue, children] = tree;
|
|
3267
|
+
if (children) forEach(children, (child, key) => {
|
|
3268
|
+
traverse(child, walker$1, version, [...origin, ...parsePath(key, legacyPaths)]);
|
|
3269
|
+
});
|
|
3270
|
+
walker$1(nodeValue, origin);
|
|
3271
|
+
}
|
|
3272
|
+
function applyValueAnnotations(plain, annotations, version, superJson) {
|
|
3273
|
+
traverse(annotations, (type, path) => {
|
|
3274
|
+
plain = setDeep(plain, path, (v) => untransformValue(v, type, superJson));
|
|
3275
|
+
}, version);
|
|
3276
|
+
return plain;
|
|
3277
|
+
}
|
|
3278
|
+
function applyReferentialEqualityAnnotations(plain, annotations, version) {
|
|
3279
|
+
const legacyPaths = enableLegacyPaths(version);
|
|
3280
|
+
function apply(identicalPaths, path) {
|
|
3281
|
+
const object = getDeep(plain, parsePath(path, legacyPaths));
|
|
3282
|
+
identicalPaths.map((path$1) => parsePath(path$1, legacyPaths)).forEach((identicalObjectPath) => {
|
|
3283
|
+
plain = setDeep(plain, identicalObjectPath, () => object);
|
|
3284
|
+
});
|
|
3285
|
+
}
|
|
3286
|
+
if (isArray$1(annotations)) {
|
|
3287
|
+
const [root, other] = annotations;
|
|
3288
|
+
root.forEach((identicalPath) => {
|
|
3289
|
+
plain = setDeep(plain, parsePath(identicalPath, legacyPaths), () => plain);
|
|
3290
|
+
});
|
|
3291
|
+
if (other) forEach(other, apply);
|
|
3292
|
+
} else forEach(annotations, apply);
|
|
3293
|
+
return plain;
|
|
3294
|
+
}
|
|
3295
|
+
const isDeep = (object, superJson) => isPlainObject$1(object) || isArray$1(object) || isMap(object) || isSet(object) || isError(object) || isInstanceOfRegisteredClass(object, superJson);
|
|
3296
|
+
function addIdentity(object, path, identities) {
|
|
3297
|
+
const existingSet = identities.get(object);
|
|
3298
|
+
if (existingSet) existingSet.push(path);
|
|
3299
|
+
else identities.set(object, [path]);
|
|
3300
|
+
}
|
|
3301
|
+
function generateReferentialEqualityAnnotations(identitites, dedupe) {
|
|
3302
|
+
const result = {};
|
|
3303
|
+
let rootEqualityPaths = void 0;
|
|
3304
|
+
identitites.forEach((paths) => {
|
|
3305
|
+
if (paths.length <= 1) return;
|
|
3306
|
+
if (!dedupe) paths = paths.map((path) => path.map(String)).sort((a, b) => a.length - b.length);
|
|
3307
|
+
const [representativePath, ...identicalPaths] = paths;
|
|
3308
|
+
if (representativePath.length === 0) rootEqualityPaths = identicalPaths.map(stringifyPath);
|
|
3309
|
+
else result[stringifyPath(representativePath)] = identicalPaths.map(stringifyPath);
|
|
3310
|
+
});
|
|
3311
|
+
if (rootEqualityPaths) if (isEmptyObject(result)) return [rootEqualityPaths];
|
|
3312
|
+
else return [rootEqualityPaths, result];
|
|
3313
|
+
else return isEmptyObject(result) ? void 0 : result;
|
|
3314
|
+
}
|
|
3315
|
+
const walker = (object, identities, superJson, dedupe, path = [], objectsInThisPath = [], seenObjects = /* @__PURE__ */ new Map()) => {
|
|
3316
|
+
var _transformationResult;
|
|
3317
|
+
const primitive = isPrimitive(object);
|
|
3318
|
+
if (!primitive) {
|
|
3319
|
+
addIdentity(object, path, identities);
|
|
3320
|
+
const seen = seenObjects.get(object);
|
|
3321
|
+
if (seen) return dedupe ? { transformedValue: null } : seen;
|
|
3322
|
+
}
|
|
3323
|
+
if (!isDeep(object, superJson)) {
|
|
3324
|
+
const transformed$1 = transformValue(object, superJson);
|
|
3325
|
+
const result$1 = transformed$1 ? {
|
|
3326
|
+
transformedValue: transformed$1.value,
|
|
3327
|
+
annotations: [transformed$1.type]
|
|
3328
|
+
} : { transformedValue: object };
|
|
3329
|
+
if (!primitive) seenObjects.set(object, result$1);
|
|
3330
|
+
return result$1;
|
|
3331
|
+
}
|
|
3332
|
+
if (includes(objectsInThisPath, object)) return { transformedValue: null };
|
|
3333
|
+
const transformationResult = transformValue(object, superJson);
|
|
3334
|
+
const transformed = (_transformationResult = transformationResult === null || transformationResult === void 0 ? void 0 : transformationResult.value) !== null && _transformationResult !== void 0 ? _transformationResult : object;
|
|
3335
|
+
const transformedValue = isArray$1(transformed) ? [] : {};
|
|
3336
|
+
const innerAnnotations = {};
|
|
3337
|
+
forEach(transformed, (value, index) => {
|
|
3338
|
+
if (index === "__proto__" || index === "constructor" || index === "prototype") throw new Error(`Detected property ${index}. This is a prototype pollution risk, please remove it from your object.`);
|
|
3339
|
+
const recursiveResult = walker(value, identities, superJson, dedupe, [...path, index], [...objectsInThisPath, object], seenObjects);
|
|
3340
|
+
transformedValue[index] = recursiveResult.transformedValue;
|
|
3341
|
+
if (isArray$1(recursiveResult.annotations)) innerAnnotations[escapeKey(index)] = recursiveResult.annotations;
|
|
3342
|
+
else if (isPlainObject$1(recursiveResult.annotations)) forEach(recursiveResult.annotations, (tree, key) => {
|
|
3343
|
+
innerAnnotations[escapeKey(index) + "." + key] = tree;
|
|
3344
|
+
});
|
|
3345
|
+
});
|
|
3346
|
+
const result = isEmptyObject(innerAnnotations) ? {
|
|
3347
|
+
transformedValue,
|
|
3348
|
+
annotations: !!transformationResult ? [transformationResult.type] : void 0
|
|
3349
|
+
} : {
|
|
3350
|
+
transformedValue,
|
|
3351
|
+
annotations: !!transformationResult ? [transformationResult.type, innerAnnotations] : innerAnnotations
|
|
3352
|
+
};
|
|
3353
|
+
if (!primitive) seenObjects.set(object, result);
|
|
3354
|
+
return result;
|
|
3355
|
+
};
|
|
3356
|
+
|
|
3357
|
+
//#endregion
|
|
3358
|
+
//#region ../../node_modules/.pnpm/is-what@5.5.0/node_modules/is-what/dist/getType.js
|
|
3359
|
+
/** Returns the object type of the given payload */
|
|
3360
|
+
function getType(payload) {
|
|
3361
|
+
return Object.prototype.toString.call(payload).slice(8, -1);
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
//#endregion
|
|
3365
|
+
//#region ../../node_modules/.pnpm/is-what@5.5.0/node_modules/is-what/dist/isArray.js
|
|
3366
|
+
/** Returns whether the payload is an array */
|
|
3367
|
+
function isArray(payload) {
|
|
3368
|
+
return getType(payload) === "Array";
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3371
|
+
//#endregion
|
|
3372
|
+
//#region ../../node_modules/.pnpm/is-what@5.5.0/node_modules/is-what/dist/isPlainObject.js
|
|
3373
|
+
/**
|
|
3374
|
+
* Returns whether the payload is a plain JavaScript object (excluding special classes or objects
|
|
3375
|
+
* with other prototypes)
|
|
3376
|
+
*/
|
|
3377
|
+
function isPlainObject(payload) {
|
|
3378
|
+
if (getType(payload) !== "Object") return false;
|
|
3379
|
+
const prototype = Object.getPrototypeOf(payload);
|
|
3380
|
+
return !!prototype && prototype.constructor === Object && prototype === Object.prototype;
|
|
3381
|
+
}
|
|
3382
|
+
|
|
3383
|
+
//#endregion
|
|
3384
|
+
//#region ../../node_modules/.pnpm/copy-anything@4.0.5/node_modules/copy-anything/dist/index.js
|
|
3385
|
+
function assignProp(carry, key, newVal, originalObject, includeNonenumerable) {
|
|
3386
|
+
const propType = {}.propertyIsEnumerable.call(originalObject, key) ? "enumerable" : "nonenumerable";
|
|
3387
|
+
if (propType === "enumerable") carry[key] = newVal;
|
|
3388
|
+
if (includeNonenumerable && propType === "nonenumerable") Object.defineProperty(carry, key, {
|
|
3389
|
+
value: newVal,
|
|
3390
|
+
enumerable: false,
|
|
3391
|
+
writable: true,
|
|
3392
|
+
configurable: true
|
|
3393
|
+
});
|
|
3394
|
+
}
|
|
3395
|
+
/**
|
|
3396
|
+
* Copy (clone) an object and all its props recursively to get rid of any prop referenced of the
|
|
3397
|
+
* original object. Arrays are also cloned, however objects inside arrays are still linked.
|
|
3398
|
+
*
|
|
3399
|
+
* @param target Target can be anything
|
|
3400
|
+
* @param [options={}] See type {@link Options} for more details.
|
|
3401
|
+
*
|
|
3402
|
+
* - `{ props: ['key1'] }` will only copy the `key1` property. When using this you will need to cast
|
|
3403
|
+
* the return type manually (in order to keep the TS implementation in here simple I didn't
|
|
3404
|
+
* built a complex auto resolved type for those few cases people want to use this option)
|
|
3405
|
+
* - `{ nonenumerable: true }` will copy all non-enumerable properties. Default is `{}`
|
|
3406
|
+
*
|
|
3407
|
+
* @returns The target with replaced values
|
|
3408
|
+
*/
|
|
3409
|
+
function copy(target$1, options = {}) {
|
|
3410
|
+
if (isArray(target$1)) return target$1.map((item) => copy(item, options));
|
|
3411
|
+
if (!isPlainObject(target$1)) return target$1;
|
|
3412
|
+
const props = Object.getOwnPropertyNames(target$1);
|
|
3413
|
+
const symbols = Object.getOwnPropertySymbols(target$1);
|
|
3414
|
+
return [...props, ...symbols].reduce((carry, key) => {
|
|
3415
|
+
if (key === "__proto__") return carry;
|
|
3416
|
+
if (isArray(options.props) && !options.props.includes(key)) return carry;
|
|
3417
|
+
const val = target$1[key];
|
|
3418
|
+
assignProp(carry, key, copy(val, options), target$1, options.nonenumerable);
|
|
3419
|
+
return carry;
|
|
3420
|
+
}, {});
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3423
|
+
//#endregion
|
|
3424
|
+
//#region ../../node_modules/.pnpm/superjson@2.2.5/node_modules/superjson/dist/index.js
|
|
3425
|
+
var SuperJSON = class {
|
|
3426
|
+
/**
|
|
3427
|
+
* @param dedupeReferentialEqualities If true, SuperJSON will make sure only one instance of referentially equal objects are serialized and the rest are replaced with `null`.
|
|
3428
|
+
*/
|
|
3429
|
+
constructor({ dedupe = false } = {}) {
|
|
3430
|
+
this.classRegistry = new ClassRegistry();
|
|
3431
|
+
this.symbolRegistry = new Registry((s) => {
|
|
3432
|
+
var _s$description;
|
|
3433
|
+
return (_s$description = s.description) !== null && _s$description !== void 0 ? _s$description : "";
|
|
3434
|
+
});
|
|
3435
|
+
this.customTransformerRegistry = new CustomTransformerRegistry();
|
|
3436
|
+
this.allowedErrorProps = [];
|
|
3437
|
+
this.dedupe = dedupe;
|
|
3438
|
+
}
|
|
3439
|
+
serialize(object) {
|
|
3440
|
+
const identities = /* @__PURE__ */ new Map();
|
|
3441
|
+
const output = walker(object, identities, this, this.dedupe);
|
|
3442
|
+
const res = { json: output.transformedValue };
|
|
3443
|
+
if (output.annotations) res.meta = _objectSpread2(_objectSpread2({}, res.meta), {}, { values: output.annotations });
|
|
3444
|
+
const equalityAnnotations = generateReferentialEqualityAnnotations(identities, this.dedupe);
|
|
3445
|
+
if (equalityAnnotations) res.meta = _objectSpread2(_objectSpread2({}, res.meta), {}, { referentialEqualities: equalityAnnotations });
|
|
3446
|
+
if (res.meta) res.meta.v = 1;
|
|
3447
|
+
return res;
|
|
3448
|
+
}
|
|
3449
|
+
deserialize(payload, options) {
|
|
3450
|
+
const { json, meta } = payload;
|
|
3451
|
+
let result = (options === null || options === void 0 ? void 0 : options.inPlace) ? json : copy(json);
|
|
3452
|
+
if (meta === null || meta === void 0 ? void 0 : meta.values) {
|
|
3453
|
+
var _meta$v;
|
|
3454
|
+
result = applyValueAnnotations(result, meta.values, (_meta$v = meta.v) !== null && _meta$v !== void 0 ? _meta$v : 0, this);
|
|
3455
|
+
}
|
|
3456
|
+
if (meta === null || meta === void 0 ? void 0 : meta.referentialEqualities) {
|
|
3457
|
+
var _meta$v2;
|
|
3458
|
+
result = applyReferentialEqualityAnnotations(result, meta.referentialEqualities, (_meta$v2 = meta.v) !== null && _meta$v2 !== void 0 ? _meta$v2 : 0);
|
|
3459
|
+
}
|
|
3460
|
+
return result;
|
|
3461
|
+
}
|
|
3462
|
+
stringify(object) {
|
|
3463
|
+
return JSON.stringify(this.serialize(object));
|
|
3464
|
+
}
|
|
3465
|
+
parse(string) {
|
|
3466
|
+
return this.deserialize(JSON.parse(string), { inPlace: true });
|
|
3467
|
+
}
|
|
3468
|
+
registerClass(v, options) {
|
|
3469
|
+
this.classRegistry.register(v, options);
|
|
3470
|
+
}
|
|
3471
|
+
registerSymbol(v, identifier) {
|
|
3472
|
+
this.symbolRegistry.register(v, identifier);
|
|
3473
|
+
}
|
|
3474
|
+
registerCustom(transformer, name) {
|
|
3475
|
+
this.customTransformerRegistry.register(_objectSpread2({ name }, transformer));
|
|
3476
|
+
}
|
|
3477
|
+
allowErrorProps(...props) {
|
|
3478
|
+
this.allowedErrorProps.push(...props);
|
|
3479
|
+
}
|
|
3480
|
+
};
|
|
3481
|
+
SuperJSON.defaultInstance = new SuperJSON();
|
|
3482
|
+
SuperJSON.serialize = SuperJSON.defaultInstance.serialize.bind(SuperJSON.defaultInstance);
|
|
3483
|
+
SuperJSON.deserialize = SuperJSON.defaultInstance.deserialize.bind(SuperJSON.defaultInstance);
|
|
3484
|
+
SuperJSON.stringify = SuperJSON.defaultInstance.stringify.bind(SuperJSON.defaultInstance);
|
|
3485
|
+
SuperJSON.parse = SuperJSON.defaultInstance.parse.bind(SuperJSON.defaultInstance);
|
|
3486
|
+
SuperJSON.registerClass = SuperJSON.defaultInstance.registerClass.bind(SuperJSON.defaultInstance);
|
|
3487
|
+
SuperJSON.registerSymbol = SuperJSON.defaultInstance.registerSymbol.bind(SuperJSON.defaultInstance);
|
|
3488
|
+
SuperJSON.registerCustom = SuperJSON.defaultInstance.registerCustom.bind(SuperJSON.defaultInstance);
|
|
3489
|
+
SuperJSON.allowErrorProps = SuperJSON.defaultInstance.allowErrorProps.bind(SuperJSON.defaultInstance);
|
|
3490
|
+
const serialize = SuperJSON.serialize;
|
|
3491
|
+
const deserialize = SuperJSON.deserialize;
|
|
3492
|
+
const stringify = SuperJSON.stringify;
|
|
3493
|
+
const parse = SuperJSON.parse;
|
|
3494
|
+
const registerClass = SuperJSON.registerClass;
|
|
3495
|
+
const registerCustom = SuperJSON.registerCustom;
|
|
3496
|
+
const registerSymbol = SuperJSON.registerSymbol;
|
|
3497
|
+
const allowErrorProps = SuperJSON.allowErrorProps;
|
|
3498
|
+
|
|
3499
|
+
//#endregion
|
|
3500
|
+
//#region src/messaging/presets/broadcast/client.ts
|
|
3501
|
+
const __REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY$1 = "__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGE__";
|
|
3502
|
+
function createBroadcastClientChannel() {
|
|
3503
|
+
if (!isBrowser) return {
|
|
3504
|
+
post: () => {},
|
|
3505
|
+
on: () => {}
|
|
3506
|
+
};
|
|
3507
|
+
const channel = new BroadcastChannel(__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY$1);
|
|
3508
|
+
return {
|
|
3509
|
+
post: (data) => channel.postMessage(SuperJSON.stringify(data)),
|
|
3510
|
+
on: (handler) => channel.addEventListener("message", (event) => {
|
|
3511
|
+
try {
|
|
3512
|
+
handler(SuperJSON.parse(event.data));
|
|
3513
|
+
} catch (e) {}
|
|
3514
|
+
})
|
|
3515
|
+
};
|
|
3516
|
+
}
|
|
3517
|
+
|
|
3518
|
+
//#endregion
|
|
3519
|
+
//#region src/messaging/presets/broadcast/server.ts
|
|
3520
|
+
const __REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY = "__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGE__";
|
|
3521
|
+
function createBroadcastServerChannel() {
|
|
3522
|
+
if (!isBrowser) return {
|
|
3523
|
+
post: () => {},
|
|
3524
|
+
on: () => {}
|
|
3525
|
+
};
|
|
3526
|
+
const channel = new BroadcastChannel(__REACT_DEVTOOLS_KIT_BROADCAST_MESSAGING_EVENT_KEY);
|
|
3527
|
+
return {
|
|
3528
|
+
post: (data) => channel.postMessage(SuperJSON.stringify(data)),
|
|
3529
|
+
on: (handler) => channel.addEventListener("message", (event) => {
|
|
3530
|
+
try {
|
|
3531
|
+
handler(SuperJSON.parse(event.data));
|
|
3532
|
+
} catch (e) {}
|
|
3533
|
+
})
|
|
3534
|
+
};
|
|
3535
|
+
}
|
|
3536
|
+
|
|
3537
|
+
//#endregion
|
|
3538
|
+
//#region src/messaging/presets/iframe/context.ts
|
|
3539
|
+
let iframeServerContext = null;
|
|
3540
|
+
function setIframeServerContext(iframe) {
|
|
3541
|
+
iframeServerContext = iframe;
|
|
3542
|
+
}
|
|
3543
|
+
function getIframeServerContext() {
|
|
3544
|
+
return iframeServerContext;
|
|
3545
|
+
}
|
|
3546
|
+
const __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY = "__REACT_DEVTOOLS_KIT_IFRAME_MESSAGE__";
|
|
3547
|
+
|
|
3548
|
+
//#endregion
|
|
3549
|
+
//#region src/messaging/presets/iframe/client.ts
|
|
3550
|
+
function createIframeClientChannel() {
|
|
3551
|
+
if (!isBrowser) return {
|
|
3552
|
+
post: () => {},
|
|
3553
|
+
on: () => {}
|
|
3554
|
+
};
|
|
3555
|
+
return {
|
|
3556
|
+
post: (data) => window.parent.postMessage(SuperJSON.stringify({
|
|
3557
|
+
event: __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY,
|
|
3558
|
+
data
|
|
3559
|
+
}), "*"),
|
|
3560
|
+
on: (handler) => window.addEventListener("message", (event) => {
|
|
3561
|
+
try {
|
|
3562
|
+
const parsed = SuperJSON.parse(event.data);
|
|
3563
|
+
if (event.source === window.parent && parsed.event === __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) handler(parsed.data);
|
|
3564
|
+
} catch (e) {}
|
|
3565
|
+
})
|
|
3566
|
+
};
|
|
3567
|
+
}
|
|
3568
|
+
|
|
3569
|
+
//#endregion
|
|
3570
|
+
//#region src/messaging/presets/iframe/server.ts
|
|
3571
|
+
function createIframeServerChannel() {
|
|
3572
|
+
if (!isBrowser) return {
|
|
3573
|
+
post: () => {},
|
|
3574
|
+
on: () => {}
|
|
3575
|
+
};
|
|
3576
|
+
return {
|
|
3577
|
+
post: (data) => {
|
|
3578
|
+
var _iframe$contentWindow;
|
|
3579
|
+
const iframe = getIframeServerContext();
|
|
3580
|
+
iframe === null || iframe === void 0 || (_iframe$contentWindow = iframe.contentWindow) === null || _iframe$contentWindow === void 0 || _iframe$contentWindow.postMessage(SuperJSON.stringify({
|
|
3581
|
+
event: __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY,
|
|
3582
|
+
data
|
|
3583
|
+
}), "*");
|
|
3584
|
+
},
|
|
3585
|
+
on: (handler) => {
|
|
3586
|
+
window.addEventListener("message", (event) => {
|
|
3587
|
+
const iframe = getIframeServerContext();
|
|
3588
|
+
try {
|
|
3589
|
+
const parsed = SuperJSON.parse(event.data);
|
|
3590
|
+
if (event.source === (iframe === null || iframe === void 0 ? void 0 : iframe.contentWindow) && parsed.event === __REACT_DEVTOOLS_KIT_IFRAME_MESSAGING_EVENT_KEY) handler(parsed.data);
|
|
3591
|
+
} catch (e) {}
|
|
3592
|
+
});
|
|
3593
|
+
}
|
|
3594
|
+
};
|
|
3595
|
+
}
|
|
3596
|
+
|
|
3597
|
+
//#endregion
|
|
3598
|
+
//#region src/messaging/presets/index.ts
|
|
3599
|
+
function getChannel(preset, host = "client") {
|
|
3600
|
+
return {
|
|
3601
|
+
iframe: {
|
|
3602
|
+
client: createIframeClientChannel,
|
|
3603
|
+
server: createIframeServerChannel
|
|
3604
|
+
},
|
|
3605
|
+
broadcast: {
|
|
3606
|
+
client: createBroadcastClientChannel,
|
|
3607
|
+
server: createBroadcastServerChannel
|
|
3608
|
+
}
|
|
3609
|
+
}[preset][host]();
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3612
|
+
//#endregion
|
|
3613
|
+
//#region src/messaging/index.ts
|
|
3614
|
+
var _target$__REACT_DEVTO, _target$__REACT_DEVTO2;
|
|
3615
|
+
(_target$__REACT_DEVTO = target.__REACT_DEVTOOLS_KIT_RPC_CLIENT__) !== null && _target$__REACT_DEVTO !== void 0 || (target.__REACT_DEVTOOLS_KIT_RPC_CLIENT__ = null);
|
|
3616
|
+
(_target$__REACT_DEVTO2 = target.__REACT_DEVTOOLS_KIT_RPC_SERVER__) !== null && _target$__REACT_DEVTO2 !== void 0 || (target.__REACT_DEVTOOLS_KIT_RPC_SERVER__ = null);
|
|
3617
|
+
function setRpcClientToGlobal(rpc) {
|
|
3618
|
+
target.__REACT_DEVTOOLS_KIT_RPC_CLIENT__ = rpc;
|
|
3619
|
+
}
|
|
3620
|
+
function setRpcServerToGlobal(rpc) {
|
|
3621
|
+
target.__REACT_DEVTOOLS_KIT_RPC_SERVER__ = rpc;
|
|
3622
|
+
}
|
|
3623
|
+
function getRpcClient() {
|
|
3624
|
+
var _target$__REACT_DEVTO3;
|
|
3625
|
+
return (_target$__REACT_DEVTO3 = target.__REACT_DEVTOOLS_KIT_RPC_CLIENT__) !== null && _target$__REACT_DEVTO3 !== void 0 ? _target$__REACT_DEVTO3 : null;
|
|
3626
|
+
}
|
|
3627
|
+
function getRpcServer() {
|
|
3628
|
+
var _target$__REACT_DEVTO4;
|
|
3629
|
+
return (_target$__REACT_DEVTO4 = target.__REACT_DEVTOOLS_KIT_RPC_SERVER__) !== null && _target$__REACT_DEVTO4 !== void 0 ? _target$__REACT_DEVTO4 : null;
|
|
3630
|
+
}
|
|
3631
|
+
function createRpcClient(functions, options = {}) {
|
|
3632
|
+
const { channel: _channel, options: _options, preset } = options;
|
|
3633
|
+
const channel = preset ? getChannel(preset, "client") : _channel;
|
|
3634
|
+
const rpc = createBirpc(functions, _objectSpread2(_objectSpread2(_objectSpread2({}, _options), channel), {}, { timeout: -1 }));
|
|
3635
|
+
setRpcClientToGlobal(rpc);
|
|
3636
|
+
return rpc;
|
|
3637
|
+
}
|
|
3638
|
+
function createRpcServer(functions, options = {}) {
|
|
3639
|
+
const { channel: _channel, preset } = options;
|
|
3640
|
+
const channel = preset ? getChannel(preset, "server") : _channel;
|
|
3641
|
+
const rpcServer = getRpcServer();
|
|
3642
|
+
if (!rpcServer) setRpcServerToGlobal(createBirpcGroup(functions, [channel], { timeout: -1 }));
|
|
3643
|
+
else rpcServer.updateChannels((channels) => {
|
|
3644
|
+
channels.push(channel);
|
|
3645
|
+
});
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3648
|
+
//#endregion
|
|
3649
|
+
export { REACT_TAGS, TIMELINE_LAYERS, addComponentEvent, addPerformanceEvent, buildTree, cleanupHighlight, clearFiberRegistry, clearNavigationHistory, clearOverrides, clearTimeline, createRpcClient, createRpcServer, getAllContexts, getAppFiberRoot, getComponentDetails, getComponentHookStates, getContextProviderInfo, getContextTree, getDisplayName, getFiberById, getFiberFromElement, getFiberId, getFiberRoot, getOverriddenContext, getOverriddenProp, getReactVersion, getRouterInfo, getRpcClient, getRpcServer, getTimelineState, hideHighlight, highlightNode, installReactHook, installTimelineEventListeners, isEditableProp, mergeClientRects, navigateTo, onInspectorSelect, onOpenInEditor, onTimelineEvent, onTreeUpdated, openInEditor, parseValue, rebuildTree, scrollToNode, setComponentProp, setContextValue, setContextValueAtPath, setContextValueFromJson, setFiberRoot, setHookState, setHookStateFromJson, setIframeServerContext, setRpcServerToGlobal, shouldIncludeFiber, showHighlight, toggleInspector, trackFiberPerformanceEnd, trackFiberPerformanceStart, updateTimelineState };
|