Skip to content

Commit 1240ea2

Browse files
improve
1 parent b7a8201 commit 1240ea2

File tree

7 files changed

+2815
-1948
lines changed

7 files changed

+2815
-1948
lines changed

chrome/public/bundle/detector.js

Lines changed: 525 additions & 386 deletions
Large diffs are not rendered by default.

chrome/public/bundle/hook.js

Lines changed: 525 additions & 386 deletions
Large diffs are not rendered by default.

chrome/public/bundle/panel.js

Lines changed: 525 additions & 386 deletions
Large diffs are not rendered by default.

chrome/public/bundle/proxy.js

Lines changed: 525 additions & 386 deletions
Large diffs are not rendered by default.

chrome/public/bundle/service-worker.js

Lines changed: 525 additions & 386 deletions
Large diffs are not rendered by default.

packages/core/src/data.ts

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { getElementName, isValidElement } from "./utils";
2+
13
// eslint-disable-next-line @typescript-eslint/no-unused-vars
24
const KnownType = {
35
Object: true,
@@ -20,6 +22,7 @@ const KnownType = {
2022
RegExp: true,
2123
Element: true,
2224
ReadError: true,
25+
ReactElement: true,
2326
};
2427

2528
export type NodeValue = {
@@ -54,6 +57,10 @@ const valueToIdMap = new Map<any, number>();
5457
let cacheMap = new WeakMap<any, NodeValue>();
5558

5659
const getType = (value: any): NodeValue["t"] => {
60+
if (isValidElement(value)) {
61+
return "ReactElement";
62+
}
63+
5764
if (isInBrowser && value && value instanceof Element) {
5865
return "Element";
5966
}
@@ -82,7 +89,8 @@ const isObject = (value: NodeValue["t"]) => {
8289
value === "Iterable" ||
8390
value === "Map" ||
8491
// value === "Promise" ||
85-
value === "Set"
92+
value === "Set" ||
93+
value === "ReactElement"
8694
);
8795
};
8896

@@ -91,6 +99,16 @@ const getTargetNode = (value: any, type: NodeValue["t"], deep = 3): NodeValue =>
9199

92100
const currentId = existId || id++;
93101

102+
let n = undefined;
103+
104+
if (type === 'Object' && typeof value?.constructor === "function" && value.constructor !== emptyConstructor && value.constructor.name) {
105+
n = value.constructor.name;
106+
}
107+
108+
if (type === 'ReactElement') {
109+
n = getElementName(value);
110+
}
111+
94112
idToValueMap.set(currentId, value);
95113

96114
valueToIdMap.set(value, currentId);
@@ -99,6 +117,7 @@ const getTargetNode = (value: any, type: NodeValue["t"], deep = 3): NodeValue =>
99117
return {
100118
i: currentId,
101119
t: type,
120+
n,
102121
v: undefined,
103122
e: true,
104123
l: false,
@@ -137,21 +156,21 @@ const getTargetNode = (value: any, type: NodeValue["t"], deep = 3): NodeValue =>
137156
e: true,
138157
};
139158
} else if (type === "Object") {
140-
if (typeof value?.constructor === "function" && value.constructor !== emptyConstructor && value.constructor.name) {
141-
return {
142-
i: currentId,
143-
t: type,
144-
n: value.constructor.name,
145-
v: Object.keys(value).reduce((acc, key) => {
146-
acc[key] = getNode(value[key], deep - 1);
147-
return acc;
148-
}, {}),
149-
e: true,
150-
};
151-
}
152159
return {
153160
i: currentId,
154161
t: type,
162+
n,
163+
v: Object.keys(value).reduce((acc, key) => {
164+
acc[key] = getNode(value[key], deep - 1);
165+
return acc;
166+
}, {}),
167+
e: true,
168+
};
169+
} else if (type === 'ReactElement') {
170+
return {
171+
i: currentId,
172+
t: type,
173+
n,
155174
v: Object.keys(value).reduce((acc, key) => {
156175
acc[key] = getNode(value[key], deep - 1);
157176
return acc;

packages/core/src/utils.ts

Lines changed: 158 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
1+
/* eslint-disable max-lines */
12
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
2-
import { HOOK_TYPE } from "@my-react/react-shared";
3+
import { type MyReactFiberNode, type MyReactFiberNodeDev, type MyReactHookNode, type MyReactHookNodeDev } from "@my-react/react-reconciler";
4+
import {
5+
Consumer,
6+
Context,
7+
ForwardRef,
8+
Fragment,
9+
HOOK_TYPE,
10+
KeepLive,
11+
Lazy,
12+
Memo,
13+
Element,
14+
merge,
15+
Portal,
16+
Profiler,
17+
Provider,
18+
Scope,
19+
ScopeLazy,
20+
ScopeSuspense,
21+
Strict,
22+
Suspense,
23+
TYPEKEY,
24+
Comment,
25+
} from "@my-react/react-shared";
326

427
import { getNode, getNodeForce } from "./data";
528
import { inspectHooksOfFiber, type HooksTree } from "./hook";
@@ -14,10 +37,13 @@ import type {
1437
MixinMyReactFunctionComponent,
1538
MixinMyReactObjectComponent,
1639
MyReactElement,
40+
MyReactElementNode,
41+
MyReactObjectComponent,
1742
createContext,
43+
forwardRef,
1844
lazy,
45+
memo,
1946
} from "@my-react/react";
20-
import type { MyReactFiberNode, MyReactFiberNodeDev, MyReactHookNode, MyReactHookNodeDev } from "@my-react/react-reconciler";
2147

2248
export const typeKeys: number[] = [];
2349

@@ -183,6 +209,133 @@ export const getFiberName = (fiber: MyReactFiberNodeDev) => {
183209
return `unknown`;
184210
};
185211

212+
export const isValidElement = (element?: MyReactElementNode | any): element is MyReactElement => {
213+
return typeof element === "object" && !Array.isArray(element) && element !== null && element?.[TYPEKEY] === Element;
214+
};
215+
216+
export const getMockFiberFromElement = (element: MyReactElement): MyReactFiberNodeDev => {
217+
let nodeType = NODE_TYPE.__initial__;
218+
219+
let elementType = element.type;
220+
221+
const finalElement = element;
222+
223+
const pendingProps = element.props;
224+
225+
const ref: MyReactElement["ref"] | null = element.ref ?? undefined;
226+
227+
const key: MyReactElement["key"] | null = element.key ?? undefined;
228+
229+
if (typeof elementType === "object" && elementType !== null) {
230+
const typedElementType = elementType as MyReactObjectComponent;
231+
switch (typedElementType[TYPEKEY]) {
232+
case Provider:
233+
nodeType = merge(nodeType, NODE_TYPE.__provider__);
234+
break;
235+
// support react 19 context api
236+
case Context:
237+
nodeType = merge(nodeType, NODE_TYPE.__context__);
238+
break;
239+
case Consumer:
240+
nodeType = merge(nodeType, NODE_TYPE.__consumer__);
241+
break;
242+
case Memo:
243+
nodeType = merge(nodeType, NODE_TYPE.__memo__);
244+
elementType = (typedElementType as ReturnType<typeof memo>).render;
245+
break;
246+
case ForwardRef:
247+
nodeType = merge(nodeType, NODE_TYPE.__forwardRef__);
248+
elementType = (typedElementType as ReturnType<typeof forwardRef>).render;
249+
break;
250+
case Lazy:
251+
nodeType = merge(nodeType, NODE_TYPE.__lazy__);
252+
break;
253+
default:
254+
throw new Error(`[@my-react/react] invalid object element type "${typedElementType[TYPEKEY]?.toString()}"`);
255+
}
256+
if (typeof elementType === "object") {
257+
if (elementType[TYPEKEY] === ForwardRef) {
258+
nodeType = merge(nodeType, NODE_TYPE.__forwardRef__);
259+
elementType = (elementType as ReturnType<typeof forwardRef>).render;
260+
}
261+
if (elementType[TYPEKEY] === Provider) {
262+
nodeType = merge(nodeType, NODE_TYPE.__provider__);
263+
}
264+
if (elementType[TYPEKEY] === Context) {
265+
nodeType = merge(nodeType, NODE_TYPE.__context__);
266+
}
267+
if (elementType[TYPEKEY] === Consumer) {
268+
nodeType = merge(nodeType, NODE_TYPE.__consumer__);
269+
}
270+
}
271+
if (typeof elementType === "function") {
272+
if (elementType.prototype?.isMyReactComponent) {
273+
nodeType = merge(nodeType, NODE_TYPE.__class__);
274+
} else {
275+
nodeType = merge(nodeType, NODE_TYPE.__function__);
276+
}
277+
}
278+
} else if (typeof elementType === "function") {
279+
if (elementType.prototype?.isMyReactComponent) {
280+
nodeType = merge(nodeType, NODE_TYPE.__class__);
281+
} else {
282+
nodeType = merge(nodeType, NODE_TYPE.__function__);
283+
}
284+
} else if (typeof elementType === "symbol") {
285+
switch (elementType) {
286+
case KeepLive:
287+
nodeType = merge(nodeType, NODE_TYPE.__keepLive__);
288+
break;
289+
case Fragment:
290+
nodeType = merge(nodeType, NODE_TYPE.__fragment__);
291+
break;
292+
case Strict:
293+
nodeType = merge(nodeType, NODE_TYPE.__strict__);
294+
break;
295+
case Suspense:
296+
nodeType = merge(nodeType, NODE_TYPE.__suspense__);
297+
break;
298+
case Scope:
299+
nodeType = merge(nodeType, NODE_TYPE.__scope__);
300+
break;
301+
case ScopeLazy:
302+
nodeType = merge(nodeType, NODE_TYPE.__scopeLazy__);
303+
break;
304+
case ScopeSuspense:
305+
nodeType = merge(nodeType, NODE_TYPE.__scopeSuspense__);
306+
break;
307+
case Comment:
308+
nodeType = merge(nodeType, NODE_TYPE.__comment__);
309+
break;
310+
case Portal:
311+
nodeType = merge(nodeType, NODE_TYPE.__portal__);
312+
break;
313+
case Profiler:
314+
nodeType = merge(nodeType, NODE_TYPE.__profiler__);
315+
break;
316+
default:
317+
throw new Error(`[@my-react/react] invalid symbol element type "${elementType?.toString()}"`);
318+
}
319+
} else if (typeof elementType === "string") {
320+
nodeType = merge(nodeType, NODE_TYPE.__plain__);
321+
} else {
322+
nodeType = merge(nodeType, NODE_TYPE.__empty__);
323+
}
324+
325+
const mockFiber = {
326+
type: nodeType,
327+
elementType: elementType,
328+
pendingProps: pendingProps,
329+
key: key,
330+
ref: ref,
331+
_debugElement: finalElement,
332+
};
333+
334+
return mockFiber as unknown as MyReactFiberNodeDev;
335+
};
336+
337+
export const getElementName = (element: MyReactElement) => `<${getFiberName(getMockFiberFromElement(element))} />`;
338+
186339
export const getHookName = (type: number) => {
187340
switch (type) {
188341
case HOOK_TYPE.useReducer:
@@ -276,7 +429,7 @@ const parseHooksTreeToHOOKTree = (node: HooksTree, d: number, force?: boolean):
276429
return {
277430
k: id?.toString(),
278431
i: id,
279-
n: name || 'Anonymous',
432+
n: name || "Anonymous",
280433
v: force ? getNodeForce(value) : getNode(value),
281434
d,
282435
h: !subHooks.length ? true : false,
@@ -324,9 +477,9 @@ export const getHook = (fiber: MyReactFiberNodeDev, force?: boolean) => {
324477
if (platform && platform.dispatcher) {
325478
try {
326479
return getHookStack(fiber, force);
327-
} catch(e) {
480+
} catch (e) {
328481
console.error(e);
329-
return getHookNormal(fiber, force);
482+
return getHookNormal(fiber, force);
330483
}
331484
} else {
332485
return getHookNormal(fiber, force);

0 commit comments

Comments
 (0)