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
427import { getNode , getNodeForce } from "./data" ;
528import { 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
2248export 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+
186339export 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