@samitouri / QOS-React-2 / commits / 8b2e903a74

[DevTools] chore: extract getInternalReactConstants (#35986)

The test is quite naive, but worth having as additional check for changes in this logic.

Ruslan Lesiutin committed Mar 20, 2026 at 14:17 UTC 8b2e903a7447d370eb77bb117bc4c0ae240ce831
2 files changed +518 -490
packages/react-devtools-shared/src/backend/fiber/renderer.js
+1 -490
@@ -46,8 +46,6 @@ import {
46 } from 'react-devtools-shared/src/frontend/types';
47 import {
48 deletePathInObject,
49 - getDisplayName,
50 - getWrappedDisplayName,
49 getInObject,
50 getUID,
51 renamePathInObject,
@@ -57,7 +55,6 @@ import {
55 import {
56 formatConsoleArgumentsToSingleString,
57 formatDurationToMicrosecondsGranularity,
60 - gt,
58 gte,
59 serializeToString,
60 } from 'react-devtools-shared/src/backend/utils';
@@ -109,14 +106,6 @@ import {
106 STRICT_MODE_SYMBOL_STRING,
107 PROFILER_NUMBER,
108 PROFILER_SYMBOL_STRING,
112 - REACT_MEMO_CACHE_SENTINEL,
113 - SCOPE_NUMBER,
114 - SCOPE_SYMBOL_STRING,
115 - FORWARD_REF_NUMBER,
116 - FORWARD_REF_SYMBOL_STRING,
117 - MEMO_NUMBER,
118 - MEMO_SYMBOL_STRING,
119 - SERVER_CONTEXT_SYMBOL_STRING,
109 LAZY_SYMBOL_STRING,
110 REACT_OPTIMISTIC_KEY,
111 } from '../shared/ReactSymbols';
@@ -144,6 +133,7 @@ import {
133 getChangedHooksIndices,
134 getChangedKeys,
135 } from './shared/DevToolsFiberChangeDetection';
136 +import {getInternalReactConstants} from './shared/DevToolsFiberInternalReactConstants';
137 import {
138 ioExistsInSuspenseAncestor,
139 getAwaitInSuspendedByFromIO,
@@ -179,7 +169,6 @@ import type {
169 RendererInterface,
170 SerializedElement,
171 SerializedAsyncInfo,
182 - WorkTagMap,
172 CurrentDispatcherRef,
173 LegacyDispatcherRef,
174 ProfilingSettings,
@@ -284,18 +273,6 @@ function createSuspenseNode(
273 });
274 }
275
287 -type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
288 -type getTypeSymbolType = (type: any) => symbol | string | number;
289 -
290 -type ReactPriorityLevelsType = {
291 - ImmediatePriority: number,
292 - UserBlockingPriority: number,
293 - NormalPriority: number,
294 - LowPriority: number,
295 - IdlePriority: number,
296 - NoPriority: number,
297 -};
298 -
276 export function getDispatcherRef(renderer: {
277 +currentDispatcherRef?: LegacyDispatcherRef | CurrentDispatcherRef,
278 ...
@@ -321,472 +298,6 @@ export function getDispatcherRef(renderer: {
298 return (injectedRef: any);
299 }
300
324 -export function getInternalReactConstants(version: string): {
325 - getDisplayNameForFiber: getDisplayNameForFiberType,
326 - getTypeSymbol: getTypeSymbolType,
327 - ReactPriorityLevels: ReactPriorityLevelsType,
328 - ReactTypeOfWork: WorkTagMap,
329 - StrictModeBits: number,
330 - SuspenseyImagesMode: number,
331 -} {
332 - // **********************************************************
333 - // The section below is copied from files in React repo.
334 - // Keep it in sync, and add version guards if it changes.
335 - //
336 - // Technically these priority levels are invalid for versions before 16.9,
337 - // but 16.9 is the first version to report priority level to DevTools,
338 - // so we can avoid checking for earlier versions and support pre-16.9 canary releases in the process.
339 - let ReactPriorityLevels: ReactPriorityLevelsType = {
340 - ImmediatePriority: 99,
341 - UserBlockingPriority: 98,
342 - NormalPriority: 97,
343 - LowPriority: 96,
344 - IdlePriority: 95,
345 - NoPriority: 90,
346 - };
347 -
348 - if (gt(version, '17.0.2')) {
349 - ReactPriorityLevels = {
350 - ImmediatePriority: 1,
351 - UserBlockingPriority: 2,
352 - NormalPriority: 3,
353 - LowPriority: 4,
354 - IdlePriority: 5,
355 - NoPriority: 0,
356 - };
357 - }
358 -
359 - let StrictModeBits = 0;
360 - if (gte(version, '18.0.0-alpha')) {
361 - // 18+
362 - StrictModeBits = 0b011000;
363 - } else if (gte(version, '16.9.0')) {
364 - // 16.9 - 17
365 - StrictModeBits = 0b1;
366 - } else if (gte(version, '16.3.0')) {
367 - // 16.3 - 16.8
368 - StrictModeBits = 0b10;
369 - }
370 -
371 - const SuspenseyImagesMode = 0b0100000;
372 -
373 - let ReactTypeOfWork: WorkTagMap = ((null: any): WorkTagMap);
374 -
375 - // **********************************************************
376 - // The section below is copied from files in React repo.
377 - // Keep it in sync, and add version guards if it changes.
378 - //
379 - // TODO Update the gt() check below to be gte() whichever the next version number is.
380 - // Currently the version in Git is 17.0.2 (but that version has not been/may not end up being released).
381 - if (gt(version, '17.0.1')) {
382 - ReactTypeOfWork = {
383 - CacheComponent: 24, // Experimental
384 - ClassComponent: 1,
385 - ContextConsumer: 9,
386 - ContextProvider: 10,
387 - CoroutineComponent: -1, // Removed
388 - CoroutineHandlerPhase: -1, // Removed
389 - DehydratedSuspenseComponent: 18, // Behind a flag
390 - ForwardRef: 11,
391 - Fragment: 7,
392 - FunctionComponent: 0,
393 - HostComponent: 5,
394 - HostPortal: 4,
395 - HostRoot: 3,
396 - HostHoistable: 26, // In reality, 18.2+. But doesn't hurt to include it here
397 - HostSingleton: 27, // Same as above
398 - HostText: 6,
399 - IncompleteClassComponent: 17,
400 - IncompleteFunctionComponent: 28,
401 - IndeterminateComponent: 2, // removed in 19.0.0
402 - LazyComponent: 16,
403 - LegacyHiddenComponent: 23, // Does not exist in 18+ OSS but exists in fb builds
404 - MemoComponent: 14,
405 - Mode: 8,
406 - OffscreenComponent: 22, // Experimental in 17. Stable in 18+
407 - Profiler: 12,
408 - ScopeComponent: 21, // Experimental
409 - SimpleMemoComponent: 15,
410 - SuspenseComponent: 13,
411 - SuspenseListComponent: 19, // Experimental
412 - TracingMarkerComponent: 25, // Experimental - This is technically in 18 but we don't
413 - // want to fork again so we're adding it here instead
414 - YieldComponent: -1, // Removed
415 - Throw: 29,
416 - ViewTransitionComponent: 30, // Experimental
417 - ActivityComponent: 31,
418 - };
419 - } else if (gte(version, '17.0.0-alpha')) {
420 - ReactTypeOfWork = {
421 - CacheComponent: -1, // Doesn't exist yet
422 - ClassComponent: 1,
423 - ContextConsumer: 9,
424 - ContextProvider: 10,
425 - CoroutineComponent: -1, // Removed
426 - CoroutineHandlerPhase: -1, // Removed
427 - DehydratedSuspenseComponent: 18, // Behind a flag
428 - ForwardRef: 11,
429 - Fragment: 7,
430 - FunctionComponent: 0,
431 - HostComponent: 5,
432 - HostPortal: 4,
433 - HostRoot: 3,
434 - HostHoistable: -1, // Doesn't exist yet
435 - HostSingleton: -1, // Doesn't exist yet
436 - HostText: 6,
437 - IncompleteClassComponent: 17,
438 - IncompleteFunctionComponent: -1, // Doesn't exist yet
439 - IndeterminateComponent: 2,
440 - LazyComponent: 16,
441 - LegacyHiddenComponent: 24,
442 - MemoComponent: 14,
443 - Mode: 8,
444 - OffscreenComponent: 23, // Experimental
445 - Profiler: 12,
446 - ScopeComponent: 21, // Experimental
447 - SimpleMemoComponent: 15,
448 - SuspenseComponent: 13,
449 - SuspenseListComponent: 19, // Experimental
450 - TracingMarkerComponent: -1, // Doesn't exist yet
451 - YieldComponent: -1, // Removed
452 - Throw: -1, // Doesn't exist yet
453 - ViewTransitionComponent: -1, // Doesn't exist yet
454 - ActivityComponent: -1, // Doesn't exist yet
455 - };
456 - } else if (gte(version, '16.6.0-beta.0')) {
457 - ReactTypeOfWork = {
458 - CacheComponent: -1, // Doesn't exist yet
459 - ClassComponent: 1,
460 - ContextConsumer: 9,
461 - ContextProvider: 10,
462 - CoroutineComponent: -1, // Removed
463 - CoroutineHandlerPhase: -1, // Removed
464 - DehydratedSuspenseComponent: 18, // Behind a flag
465 - ForwardRef: 11,
466 - Fragment: 7,
467 - FunctionComponent: 0,
468 - HostComponent: 5,
469 - HostPortal: 4,
470 - HostRoot: 3,
471 - HostHoistable: -1, // Doesn't exist yet
472 - HostSingleton: -1, // Doesn't exist yet
473 - HostText: 6,
474 - IncompleteClassComponent: 17,
475 - IncompleteFunctionComponent: -1, // Doesn't exist yet
476 - IndeterminateComponent: 2,
477 - LazyComponent: 16,
478 - LegacyHiddenComponent: -1,
479 - MemoComponent: 14,
480 - Mode: 8,
481 - OffscreenComponent: -1, // Experimental
482 - Profiler: 12,
483 - ScopeComponent: -1, // Experimental
484 - SimpleMemoComponent: 15,
485 - SuspenseComponent: 13,
486 - SuspenseListComponent: 19, // Experimental
487 - TracingMarkerComponent: -1, // Doesn't exist yet
488 - YieldComponent: -1, // Removed
489 - Throw: -1, // Doesn't exist yet
490 - ViewTransitionComponent: -1, // Doesn't exist yet
491 - ActivityComponent: -1, // Doesn't exist yet
492 - };
493 - } else if (gte(version, '16.4.3-alpha')) {
494 - ReactTypeOfWork = {
495 - CacheComponent: -1, // Doesn't exist yet
496 - ClassComponent: 2,
497 - ContextConsumer: 11,
498 - ContextProvider: 12,
499 - CoroutineComponent: -1, // Removed
500 - CoroutineHandlerPhase: -1, // Removed
501 - DehydratedSuspenseComponent: -1, // Doesn't exist yet
502 - ForwardRef: 13,
503 - Fragment: 9,
504 - FunctionComponent: 0,
505 - HostComponent: 7,
506 - HostPortal: 6,
507 - HostRoot: 5,
508 - HostHoistable: -1, // Doesn't exist yet
509 - HostSingleton: -1, // Doesn't exist yet
510 - HostText: 8,
511 - IncompleteClassComponent: -1, // Doesn't exist yet
512 - IncompleteFunctionComponent: -1, // Doesn't exist yet
513 - IndeterminateComponent: 4,
514 - LazyComponent: -1, // Doesn't exist yet
515 - LegacyHiddenComponent: -1,
516 - MemoComponent: -1, // Doesn't exist yet
517 - Mode: 10,
518 - OffscreenComponent: -1, // Experimental
519 - Profiler: 15,
520 - ScopeComponent: -1, // Experimental
521 - SimpleMemoComponent: -1, // Doesn't exist yet
522 - SuspenseComponent: 16,
523 - SuspenseListComponent: -1, // Doesn't exist yet
524 - TracingMarkerComponent: -1, // Doesn't exist yet
525 - YieldComponent: -1, // Removed
526 - Throw: -1, // Doesn't exist yet
527 - ViewTransitionComponent: -1, // Doesn't exist yet
528 - ActivityComponent: -1, // Doesn't exist yet
529 - };
530 - } else {
531 - ReactTypeOfWork = {
532 - CacheComponent: -1, // Doesn't exist yet
533 - ClassComponent: 2,
534 - ContextConsumer: 12,
535 - ContextProvider: 13,
536 - CoroutineComponent: 7,
537 - CoroutineHandlerPhase: 8,
538 - DehydratedSuspenseComponent: -1, // Doesn't exist yet
539 - ForwardRef: 14,
540 - Fragment: 10,
541 - FunctionComponent: 1,
542 - HostComponent: 5,
543 - HostPortal: 4,
544 - HostRoot: 3,
545 - HostHoistable: -1, // Doesn't exist yet
546 - HostSingleton: -1, // Doesn't exist yet
547 - HostText: 6,
548 - IncompleteClassComponent: -1, // Doesn't exist yet
549 - IncompleteFunctionComponent: -1, // Doesn't exist yet
550 - IndeterminateComponent: 0,
551 - LazyComponent: -1, // Doesn't exist yet
552 - LegacyHiddenComponent: -1,
553 - MemoComponent: -1, // Doesn't exist yet
554 - Mode: 11,
555 - OffscreenComponent: -1, // Experimental
556 - Profiler: 15,
557 - ScopeComponent: -1, // Experimental
558 - SimpleMemoComponent: -1, // Doesn't exist yet
559 - SuspenseComponent: 16,
560 - SuspenseListComponent: -1, // Doesn't exist yet
561 - TracingMarkerComponent: -1, // Doesn't exist yet
562 - YieldComponent: 9,
563 - Throw: -1, // Doesn't exist yet
564 - ViewTransitionComponent: -1, // Doesn't exist yet
565 - ActivityComponent: -1, // Doesn't exist yet
566 - };
567 - }
568 - // **********************************************************
569 - // End of copied code.
570 - // **********************************************************
571 -
572 - function getTypeSymbol(type: any): symbol | string | number {
573 - const symbolOrNumber =
574 - typeof type === 'object' && type !== null ? type.$$typeof : type;
575 -
576 - return typeof symbolOrNumber === 'symbol'
577 - ? symbolOrNumber.toString()
578 - : symbolOrNumber;
579 - }
580 -
581 - const {
582 - CacheComponent,
583 - ClassComponent,
584 - IncompleteClassComponent,
585 - IncompleteFunctionComponent,
586 - FunctionComponent,
587 - IndeterminateComponent,
588 - ForwardRef,
589 - HostRoot,
590 - HostHoistable,
591 - HostSingleton,
592 - HostComponent,
593 - HostPortal,
594 - HostText,
595 - Fragment,
596 - LazyComponent,
597 - LegacyHiddenComponent,
598 - MemoComponent,
599 - OffscreenComponent,
600 - Profiler,
601 - ScopeComponent,
602 - SimpleMemoComponent,
603 - SuspenseComponent,
604 - SuspenseListComponent,
605 - TracingMarkerComponent,
606 - Throw,
607 - ViewTransitionComponent,
608 - ActivityComponent,
609 - } = ReactTypeOfWork;
610 -
611 - function resolveFiberType(type: any): $FlowFixMe {
612 - const typeSymbol = getTypeSymbol(type);
613 - switch (typeSymbol) {
614 - case MEMO_NUMBER:
615 - case MEMO_SYMBOL_STRING:
616 - // recursively resolving memo type in case of memo(forwardRef(Component))
617 - return resolveFiberType(type.type);
618 - case FORWARD_REF_NUMBER:
619 - case FORWARD_REF_SYMBOL_STRING:
620 - return type.render;
621 - default:
622 - return type;
623 - }
624 - }
625 -
626 - // NOTICE Keep in sync with shouldFilterFiber() and other get*ForFiber methods
627 - function getDisplayNameForFiber(
628 - fiber: Fiber,
629 - shouldSkipForgetCheck: boolean = false,
630 - ): string | null {
631 - const {elementType, type, tag} = fiber;
632 -
633 - let resolvedType = type;
634 - if (typeof type === 'object' && type !== null) {
635 - resolvedType = resolveFiberType(type);
636 - }
637 -
638 - let resolvedContext: any = null;
639 - if (
640 - !shouldSkipForgetCheck &&
641 - // $FlowFixMe[incompatible-type] fiber.updateQueue is mixed
642 - (fiber.updateQueue?.memoCache != null ||
643 - (Array.isArray(fiber.memoizedState?.memoizedState) &&
644 - fiber.memoizedState.memoizedState[0]?.[REACT_MEMO_CACHE_SENTINEL]) ||
645 - fiber.memoizedState?.memoizedState?.[REACT_MEMO_CACHE_SENTINEL])
646 - ) {
647 - const displayNameWithoutForgetWrapper = getDisplayNameForFiber(
648 - fiber,
649 - true,
650 - );
651 - if (displayNameWithoutForgetWrapper == null) {
652 - return null;
653 - }
654 -
655 - return `Forget(${displayNameWithoutForgetWrapper})`;
656 - }
657 -
658 - switch (tag) {
659 - case ActivityComponent:
660 - return 'Activity';
661 - case CacheComponent:
662 - return 'Cache';
663 - case ClassComponent:
664 - case IncompleteClassComponent:
665 - case IncompleteFunctionComponent:
666 - case FunctionComponent:
667 - case IndeterminateComponent:
668 - return getDisplayName(resolvedType);
669 - case ForwardRef:
670 - return getWrappedDisplayName(
671 - elementType,
672 - resolvedType,
673 - 'ForwardRef',
674 - 'Anonymous',
675 - );
676 - case HostRoot:
677 - const fiberRoot = fiber.stateNode;
678 - if (fiberRoot != null && fiberRoot._debugRootType !== null) {
679 - return fiberRoot._debugRootType;
680 - }
681 - return null;
682 - case HostComponent:
683 - case HostSingleton:
684 - case HostHoistable:
685 - return type;
686 - case HostPortal:
687 - case HostText:
688 - return null;
689 - case Fragment:
690 - return 'Fragment';
691 - case LazyComponent:
692 - // This display name will not be user visible.
693 - // Once a Lazy component loads its inner component, React replaces the tag and type.
694 - // This display name will only show up in console logs when DevTools DEBUG mode is on.
695 - return 'Lazy';
696 - case MemoComponent:
697 - case SimpleMemoComponent:
698 - // Display name in React does not use `Memo` as a wrapper but fallback name.
699 - return getWrappedDisplayName(
700 - elementType,
701 - resolvedType,
702 - 'Memo',
703 - 'Anonymous',
704 - );
705 - case SuspenseComponent:
706 - return 'Suspense';
707 - case LegacyHiddenComponent:
708 - return 'LegacyHidden';
709 - case OffscreenComponent:
710 - return 'Offscreen';
711 - case ScopeComponent:
712 - return 'Scope';
713 - case SuspenseListComponent:
714 - return 'SuspenseList';
715 - case Profiler:
716 - return 'Profiler';
717 - case TracingMarkerComponent:
718 - return 'TracingMarker';
719 - case ViewTransitionComponent:
720 - return 'ViewTransition';
721 - case Throw:
722 - // This should really never be visible.
723 - return 'Error';
724 - default:
725 - const typeSymbol = getTypeSymbol(type);
726 -
727 - switch (typeSymbol) {
728 - case CONCURRENT_MODE_NUMBER:
729 - case CONCURRENT_MODE_SYMBOL_STRING:
730 - case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
731 - return null;
732 - case PROVIDER_NUMBER:
733 - case PROVIDER_SYMBOL_STRING:
734 - // 16.3.0 exposed the context object as "context"
735 - // PR #12501 changed it to "_context" for 16.3.1+
736 - // NOTE Keep in sync with inspectElementRaw()
737 - resolvedContext = fiber.type._context || fiber.type.context;
738 - return `${resolvedContext.displayName || 'Context'}.Provider`;
739 - case CONTEXT_NUMBER:
740 - case CONTEXT_SYMBOL_STRING:
741 - case SERVER_CONTEXT_SYMBOL_STRING:
742 - if (
743 - fiber.type._context === undefined &&
744 - fiber.type.Provider === fiber.type
745 - ) {
746 - // In 19+, Context.Provider === Context, so this is a provider.
747 - resolvedContext = fiber.type;
748 - return `${resolvedContext.displayName || 'Context'}.Provider`;
749 - }
750 -
751 - // 16.3-16.5 read from "type" because the Consumer is the actual context object.
752 - // 16.6+ should read from "type._context" because Consumer can be different (in DEV).
753 - // NOTE Keep in sync with inspectElementRaw()
754 - resolvedContext = fiber.type._context || fiber.type;
755 -
756 - // NOTE: TraceUpdatesBackendManager depends on the name ending in '.Consumer'
757 - // If you change the name, figure out a more resilient way to detect it.
758 - return `${resolvedContext.displayName || 'Context'}.Consumer`;
759 - case CONSUMER_SYMBOL_STRING:
760 - // 19+
761 - resolvedContext = fiber.type._context;
762 - return `${resolvedContext.displayName || 'Context'}.Consumer`;
763 - case STRICT_MODE_NUMBER:
764 - case STRICT_MODE_SYMBOL_STRING:
765 - return null;
766 - case PROFILER_NUMBER:
767 - case PROFILER_SYMBOL_STRING:
768 - return `Profiler(${fiber.memoizedProps.id})`;
769 - case SCOPE_NUMBER:
770 - case SCOPE_SYMBOL_STRING:
771 - return 'Scope';
772 - default:
773 - // Unknown element type.
774 - // This may mean a new element type that has not yet been added to DevTools.
775 - return null;
776 - }
777 - }
778 - }
779 -
780 - return {
781 - getDisplayNameForFiber,
782 - getTypeSymbol,
783 - ReactPriorityLevels,
784 - ReactTypeOfWork,
785 - StrictModeBits,
786 - SuspenseyImagesMode,
787 - };
788 -}
789 -
301 // All environment names we've seen so far. This lets us create a list of filters to apply.
302 // This should ideally include env of filtered Components too so that you can add those as
303 // filters at the same time as removing some other filter.
packages/react-devtools-shared/src/backend/fiber/shared/DevToolsFiberInternalReactConstants.js new
+517
@@ -0,0 +1,517 @@
1 +/**
2 + * Copyright (c) Meta Platforms, Inc. and affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + *
7 + * @flow
8 + */
9 +
10 +import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
11 +import type {WorkTagMap} from 'react-devtools-shared/src/backend/types';
12 +
13 +import {
14 + getDisplayName,
15 + getWrappedDisplayName,
16 +} from 'react-devtools-shared/src/utils';
17 +import {gt, gte} from 'react-devtools-shared/src/backend/utils';
18 +import {
19 + CONCURRENT_MODE_NUMBER,
20 + CONCURRENT_MODE_SYMBOL_STRING,
21 + DEPRECATED_ASYNC_MODE_SYMBOL_STRING,
22 + PROVIDER_NUMBER,
23 + PROVIDER_SYMBOL_STRING,
24 + CONTEXT_NUMBER,
25 + CONTEXT_SYMBOL_STRING,
26 + CONSUMER_SYMBOL_STRING,
27 + STRICT_MODE_NUMBER,
28 + STRICT_MODE_SYMBOL_STRING,
29 + PROFILER_NUMBER,
30 + PROFILER_SYMBOL_STRING,
31 + REACT_MEMO_CACHE_SENTINEL,
32 + SCOPE_NUMBER,
33 + SCOPE_SYMBOL_STRING,
34 + FORWARD_REF_NUMBER,
35 + FORWARD_REF_SYMBOL_STRING,
36 + MEMO_NUMBER,
37 + MEMO_SYMBOL_STRING,
38 + SERVER_CONTEXT_SYMBOL_STRING,
39 +} from 'react-devtools-shared/src/backend/shared/ReactSymbols';
40 +
41 +export type getDisplayNameForFiberType = (fiber: Fiber) => string | null;
42 +export type getTypeSymbolType = (type: any) => symbol | string | number;
43 +
44 +export type ReactPriorityLevelsType = {
45 + ImmediatePriority: number,
46 + UserBlockingPriority: number,
47 + NormalPriority: number,
48 + LowPriority: number,
49 + IdlePriority: number,
50 + NoPriority: number,
51 +};
52 +
53 +export function getInternalReactConstants(version: string): {
54 + getDisplayNameForFiber: getDisplayNameForFiberType,
55 + getTypeSymbol: getTypeSymbolType,
56 + ReactPriorityLevels: ReactPriorityLevelsType,
57 + ReactTypeOfWork: WorkTagMap,
58 + StrictModeBits: number,
59 + SuspenseyImagesMode: number,
60 +} {
61 + // **********************************************************
62 + // The section below is copied from files in React repo.
63 + // Keep it in sync, and add version guards if it changes.
64 + //
65 + // Technically these priority levels are invalid for versions before 16.9,
66 + // but 16.9 is the first version to report priority level to DevTools,
67 + // so we can avoid checking for earlier versions and support pre-16.9 canary releases in the process.
68 + let ReactPriorityLevels: ReactPriorityLevelsType = {
69 + ImmediatePriority: 99,
70 + UserBlockingPriority: 98,
71 + NormalPriority: 97,
72 + LowPriority: 96,
73 + IdlePriority: 95,
74 + NoPriority: 90,
75 + };
76 +
77 + if (gt(version, '17.0.2')) {
78 + ReactPriorityLevels = {
79 + ImmediatePriority: 1,
80 + UserBlockingPriority: 2,
81 + NormalPriority: 3,
82 + LowPriority: 4,
83 + IdlePriority: 5,
84 + NoPriority: 0,
85 + };
86 + }
87 +
88 + let StrictModeBits = 0;
89 + if (gte(version, '18.0.0-alpha')) {
90 + // 18+
91 + StrictModeBits = 0b011000;
92 + } else if (gte(version, '16.9.0')) {
93 + // 16.9 - 17
94 + StrictModeBits = 0b1;
95 + } else if (gte(version, '16.3.0')) {
96 + // 16.3 - 16.8
97 + StrictModeBits = 0b10;
98 + }
99 +
100 + const SuspenseyImagesMode = 0b0100000;
101 +
102 + let ReactTypeOfWork: WorkTagMap = ((null: any): WorkTagMap);
103 +
104 + // **********************************************************
105 + // The section below is copied from files in React repo.
106 + // Keep it in sync, and add version guards if it changes.
107 + //
108 + // TODO Update the gt() check below to be gte() whichever the next version number is.
109 + // Currently the version in Git is 17.0.2 (but that version has not been/may not end up being released).
110 + if (gt(version, '17.0.1')) {
111 + ReactTypeOfWork = {
112 + CacheComponent: 24, // Experimental
113 + ClassComponent: 1,
114 + ContextConsumer: 9,
115 + ContextProvider: 10,
116 + CoroutineComponent: -1, // Removed
117 + CoroutineHandlerPhase: -1, // Removed
118 + DehydratedSuspenseComponent: 18, // Behind a flag
119 + ForwardRef: 11,
120 + Fragment: 7,
121 + FunctionComponent: 0,
122 + HostComponent: 5,
123 + HostPortal: 4,
124 + HostRoot: 3,
125 + HostHoistable: 26, // In reality, 18.2+. But doesn't hurt to include it here
126 + HostSingleton: 27, // Same as above
127 + HostText: 6,
128 + IncompleteClassComponent: 17,
129 + IncompleteFunctionComponent: 28,
130 + IndeterminateComponent: 2, // removed in 19.0.0
131 + LazyComponent: 16,
132 + LegacyHiddenComponent: 23, // Does not exist in 18+ OSS but exists in fb builds
133 + MemoComponent: 14,
134 + Mode: 8,
135 + OffscreenComponent: 22, // Experimental in 17. Stable in 18+
136 + Profiler: 12,
137 + ScopeComponent: 21, // Experimental
138 + SimpleMemoComponent: 15,
139 + SuspenseComponent: 13,
140 + SuspenseListComponent: 19, // Experimental
141 + TracingMarkerComponent: 25, // Experimental - This is technically in 18 but we don't
142 + // want to fork again so we're adding it here instead
143 + YieldComponent: -1, // Removed
144 + Throw: 29,
145 + ViewTransitionComponent: 30, // Experimental
146 + ActivityComponent: 31,
147 + };
148 + } else if (gte(version, '17.0.0-alpha')) {
149 + ReactTypeOfWork = {
150 + CacheComponent: -1, // Doesn't exist yet
151 + ClassComponent: 1,
152 + ContextConsumer: 9,
153 + ContextProvider: 10,
154 + CoroutineComponent: -1, // Removed
155 + CoroutineHandlerPhase: -1, // Removed
156 + DehydratedSuspenseComponent: 18, // Behind a flag
157 + ForwardRef: 11,
158 + Fragment: 7,
159 + FunctionComponent: 0,
160 + HostComponent: 5,
161 + HostPortal: 4,
162 + HostRoot: 3,
163 + HostHoistable: -1, // Doesn't exist yet
164 + HostSingleton: -1, // Doesn't exist yet
165 + HostText: 6,
166 + IncompleteClassComponent: 17,
167 + IncompleteFunctionComponent: -1, // Doesn't exist yet
168 + IndeterminateComponent: 2,
169 + LazyComponent: 16,
170 + LegacyHiddenComponent: 24,
171 + MemoComponent: 14,
172 + Mode: 8,
173 + OffscreenComponent: 23, // Experimental
174 + Profiler: 12,
175 + ScopeComponent: 21, // Experimental
176 + SimpleMemoComponent: 15,
177 + SuspenseComponent: 13,
178 + SuspenseListComponent: 19, // Experimental
179 + TracingMarkerComponent: -1, // Doesn't exist yet
180 + YieldComponent: -1, // Removed
181 + Throw: -1, // Doesn't exist yet
182 + ViewTransitionComponent: -1, // Doesn't exist yet
183 + ActivityComponent: -1, // Doesn't exist yet
184 + };
185 + } else if (gte(version, '16.6.0-beta.0')) {
186 + ReactTypeOfWork = {
187 + CacheComponent: -1, // Doesn't exist yet
188 + ClassComponent: 1,
189 + ContextConsumer: 9,
190 + ContextProvider: 10,
191 + CoroutineComponent: -1, // Removed
192 + CoroutineHandlerPhase: -1, // Removed
193 + DehydratedSuspenseComponent: 18, // Behind a flag
194 + ForwardRef: 11,
195 + Fragment: 7,
196 + FunctionComponent: 0,
197 + HostComponent: 5,
198 + HostPortal: 4,
199 + HostRoot: 3,
200 + HostHoistable: -1, // Doesn't exist yet
201 + HostSingleton: -1, // Doesn't exist yet
202 + HostText: 6,
203 + IncompleteClassComponent: 17,
204 + IncompleteFunctionComponent: -1, // Doesn't exist yet
205 + IndeterminateComponent: 2,
206 + LazyComponent: 16,
207 + LegacyHiddenComponent: -1,
208 + MemoComponent: 14,
209 + Mode: 8,
210 + OffscreenComponent: -1, // Experimental
211 + Profiler: 12,
212 + ScopeComponent: -1, // Experimental
213 + SimpleMemoComponent: 15,
214 + SuspenseComponent: 13,
215 + SuspenseListComponent: 19, // Experimental
216 + TracingMarkerComponent: -1, // Doesn't exist yet
217 + YieldComponent: -1, // Removed
218 + Throw: -1, // Doesn't exist yet
219 + ViewTransitionComponent: -1, // Doesn't exist yet
220 + ActivityComponent: -1, // Doesn't exist yet
221 + };
222 + } else if (gte(version, '16.4.3-alpha')) {
223 + ReactTypeOfWork = {
224 + CacheComponent: -1, // Doesn't exist yet
225 + ClassComponent: 2,
226 + ContextConsumer: 11,
227 + ContextProvider: 12,
228 + CoroutineComponent: -1, // Removed
229 + CoroutineHandlerPhase: -1, // Removed
230 + DehydratedSuspenseComponent: -1, // Doesn't exist yet
231 + ForwardRef: 13,
232 + Fragment: 9,
233 + FunctionComponent: 0,
234 + HostComponent: 7,
235 + HostPortal: 6,
236 + HostRoot: 5,
237 + HostHoistable: -1, // Doesn't exist yet
238 + HostSingleton: -1, // Doesn't exist yet
239 + HostText: 8,
240 + IncompleteClassComponent: -1, // Doesn't exist yet
241 + IncompleteFunctionComponent: -1, // Doesn't exist yet
242 + IndeterminateComponent: 4,
243 + LazyComponent: -1, // Doesn't exist yet
244 + LegacyHiddenComponent: -1,
245 + MemoComponent: -1, // Doesn't exist yet
246 + Mode: 10,
247 + OffscreenComponent: -1, // Experimental
248 + Profiler: 15,
249 + ScopeComponent: -1, // Experimental
250 + SimpleMemoComponent: -1, // Doesn't exist yet
251 + SuspenseComponent: 16,
252 + SuspenseListComponent: -1, // Doesn't exist yet
253 + TracingMarkerComponent: -1, // Doesn't exist yet
254 + YieldComponent: -1, // Removed
255 + Throw: -1, // Doesn't exist yet
256 + ViewTransitionComponent: -1, // Doesn't exist yet
257 + ActivityComponent: -1, // Doesn't exist yet
258 + };
259 + } else {
260 + ReactTypeOfWork = {
261 + CacheComponent: -1, // Doesn't exist yet
262 + ClassComponent: 2,
263 + ContextConsumer: 12,
264 + ContextProvider: 13,
265 + CoroutineComponent: 7,
266 + CoroutineHandlerPhase: 8,
267 + DehydratedSuspenseComponent: -1, // Doesn't exist yet
268 + ForwardRef: 14,
269 + Fragment: 10,
270 + FunctionComponent: 1,
271 + HostComponent: 5,
272 + HostPortal: 4,
273 + HostRoot: 3,
274 + HostHoistable: -1, // Doesn't exist yet
275 + HostSingleton: -1, // Doesn't exist yet
276 + HostText: 6,
277 + IncompleteClassComponent: -1, // Doesn't exist yet
278 + IncompleteFunctionComponent: -1, // Doesn't exist yet
279 + IndeterminateComponent: 0,
280 + LazyComponent: -1, // Doesn't exist yet
281 + LegacyHiddenComponent: -1,
282 + MemoComponent: -1, // Doesn't exist yet
283 + Mode: 11,
284 + OffscreenComponent: -1, // Experimental
285 + Profiler: 15,
286 + ScopeComponent: -1, // Experimental
287 + SimpleMemoComponent: -1, // Doesn't exist yet
288 + SuspenseComponent: 16,
289 + SuspenseListComponent: -1, // Doesn't exist yet
290 + TracingMarkerComponent: -1, // Doesn't exist yet
291 + YieldComponent: 9,
292 + Throw: -1, // Doesn't exist yet
293 + ViewTransitionComponent: -1, // Doesn't exist yet
294 + ActivityComponent: -1, // Doesn't exist yet
295 + };
296 + }
297 + // **********************************************************
298 + // End of copied code.
299 + // **********************************************************
300 +
301 + function getTypeSymbol(type: any): symbol | string | number {
302 + const symbolOrNumber =
303 + typeof type === 'object' && type !== null ? type.$$typeof : type;
304 +
305 + return typeof symbolOrNumber === 'symbol'
306 + ? symbolOrNumber.toString()
307 + : symbolOrNumber;
308 + }
309 +
310 + const {
311 + CacheComponent,
312 + ClassComponent,
313 + IncompleteClassComponent,
314 + IncompleteFunctionComponent,
315 + FunctionComponent,
316 + IndeterminateComponent,
317 + ForwardRef,
318 + HostRoot,
319 + HostHoistable,
320 + HostSingleton,
321 + HostComponent,
322 + HostPortal,
323 + HostText,
324 + Fragment,
325 + LazyComponent,
326 + LegacyHiddenComponent,
327 + MemoComponent,
328 + OffscreenComponent,
329 + Profiler,
330 + ScopeComponent,
331 + SimpleMemoComponent,
332 + SuspenseComponent,
333 + SuspenseListComponent,
334 + TracingMarkerComponent,
335 + Throw,
336 + ViewTransitionComponent,
337 + ActivityComponent,
338 + } = ReactTypeOfWork;
339 +
340 + function resolveFiberType(type: any): $FlowFixMe {
341 + const typeSymbol = getTypeSymbol(type);
342 + switch (typeSymbol) {
343 + case MEMO_NUMBER:
344 + case MEMO_SYMBOL_STRING:
345 + // recursively resolving memo type in case of memo(forwardRef(Component))
346 + return resolveFiberType(type.type);
347 + case FORWARD_REF_NUMBER:
348 + case FORWARD_REF_SYMBOL_STRING:
349 + return type.render;
350 + default:
351 + return type;
352 + }
353 + }
354 +
355 + // NOTICE Keep in sync with shouldFilterFiber() and other get*ForFiber methods
356 + function getDisplayNameForFiber(
357 + fiber: Fiber,
358 + shouldSkipForgetCheck: boolean = false,
359 + ): string | null {
360 + const {elementType, type, tag} = fiber;
361 +
362 + let resolvedType = type;
363 + if (typeof type === 'object' && type !== null) {
364 + resolvedType = resolveFiberType(type);
365 + }
366 +
367 + let resolvedContext: any = null;
368 + if (
369 + !shouldSkipForgetCheck &&
370 + // $FlowFixMe[incompatible-type] fiber.updateQueue is mixed
371 + (fiber.updateQueue?.memoCache != null ||
372 + (Array.isArray(fiber.memoizedState?.memoizedState) &&
373 + fiber.memoizedState.memoizedState[0]?.[REACT_MEMO_CACHE_SENTINEL]) ||
374 + fiber.memoizedState?.memoizedState?.[REACT_MEMO_CACHE_SENTINEL])
375 + ) {
376 + const displayNameWithoutForgetWrapper = getDisplayNameForFiber(
377 + fiber,
378 + true,
379 + );
380 + if (displayNameWithoutForgetWrapper == null) {
381 + return null;
382 + }
383 +
384 + return `Forget(${displayNameWithoutForgetWrapper})`;
385 + }
386 +
387 + switch (tag) {
388 + case ActivityComponent:
389 + return 'Activity';
390 + case CacheComponent:
391 + return 'Cache';
392 + case ClassComponent:
393 + case IncompleteClassComponent:
394 + case IncompleteFunctionComponent:
395 + case FunctionComponent:
396 + case IndeterminateComponent:
397 + return getDisplayName(resolvedType);
398 + case ForwardRef:
399 + return getWrappedDisplayName(
400 + elementType,
401 + resolvedType,
402 + 'ForwardRef',
403 + 'Anonymous',
404 + );
405 + case HostRoot:
406 + const fiberRoot = fiber.stateNode;
407 + if (fiberRoot != null && fiberRoot._debugRootType !== null) {
408 + return fiberRoot._debugRootType;
409 + }
410 + return null;
411 + case HostComponent:
412 + case HostSingleton:
413 + case HostHoistable:
414 + return type;
415 + case HostPortal:
416 + case HostText:
417 + return null;
418 + case Fragment:
419 + return 'Fragment';
420 + case LazyComponent:
421 + // This display name will not be user visible.
422 + // Once a Lazy component loads its inner component, React replaces the tag and type.
423 + // This display name will only show up in console logs when DevTools DEBUG mode is on.
424 + return 'Lazy';
425 + case MemoComponent:
426 + case SimpleMemoComponent:
427 + // Display name in React does not use `Memo` as a wrapper but fallback name.
428 + return getWrappedDisplayName(
429 + elementType,
430 + resolvedType,
431 + 'Memo',
432 + 'Anonymous',
433 + );
434 + case SuspenseComponent:
435 + return 'Suspense';
436 + case LegacyHiddenComponent:
437 + return 'LegacyHidden';
438 + case OffscreenComponent:
439 + return 'Offscreen';
440 + case ScopeComponent:
441 + return 'Scope';
442 + case SuspenseListComponent:
443 + return 'SuspenseList';
444 + case Profiler:
445 + return 'Profiler';
446 + case TracingMarkerComponent:
447 + return 'TracingMarker';
448 + case ViewTransitionComponent:
449 + return 'ViewTransition';
450 + case Throw:
451 + // This should really never be visible.
452 + return 'Error';
453 + default:
454 + const typeSymbol = getTypeSymbol(type);
455 +
456 + switch (typeSymbol) {
457 + case CONCURRENT_MODE_NUMBER:
458 + case CONCURRENT_MODE_SYMBOL_STRING:
459 + case DEPRECATED_ASYNC_MODE_SYMBOL_STRING:
460 + return null;
461 + case PROVIDER_NUMBER:
462 + case PROVIDER_SYMBOL_STRING:
463 + // 16.3.0 exposed the context object as "context"
464 + // PR #12501 changed it to "_context" for 16.3.1+
465 + // NOTE Keep in sync with inspectElementRaw()
466 + resolvedContext = fiber.type._context || fiber.type.context;
467 + return `${resolvedContext.displayName || 'Context'}.Provider`;
468 + case CONTEXT_NUMBER:
469 + case CONTEXT_SYMBOL_STRING:
470 + case SERVER_CONTEXT_SYMBOL_STRING:
471 + if (
472 + fiber.type._context === undefined &&
473 + fiber.type.Provider === fiber.type
474 + ) {
475 + // In 19+, Context.Provider === Context, so this is a provider.
476 + resolvedContext = fiber.type;
477 + return `${resolvedContext.displayName || 'Context'}.Provider`;
478 + }
479 +
480 + // 16.3-16.5 read from "type" because the Consumer is the actual context object.
481 + // 16.6+ should read from "type._context" because Consumer can be different (in DEV).
482 + // NOTE Keep in sync with inspectElementRaw()
483 + resolvedContext = fiber.type._context || fiber.type;
484 +
485 + // NOTE: TraceUpdatesBackendManager depends on the name ending in '.Consumer'
486 + // If you change the name, figure out a more resilient way to detect it.
487 + return `${resolvedContext.displayName || 'Context'}.Consumer`;
488 + case CONSUMER_SYMBOL_STRING:
489 + // 19+
490 + resolvedContext = fiber.type._context;
491 + return `${resolvedContext.displayName || 'Context'}.Consumer`;
492 + case STRICT_MODE_NUMBER:
493 + case STRICT_MODE_SYMBOL_STRING:
494 + return null;
495 + case PROFILER_NUMBER:
496 + case PROFILER_SYMBOL_STRING:
497 + return `Profiler(${fiber.memoizedProps.id})`;
498 + case SCOPE_NUMBER:
499 + case SCOPE_SYMBOL_STRING:
500 + return 'Scope';
501 + default:
502 + // Unknown element type.
503 + // This may mean a new element type that has not yet been added to DevTools.
504 + return null;
505 + }
506 + }
507 + }
508 +
509 + return {
510 + getDisplayNameForFiber,
511 + getTypeSymbol,
512 + ReactPriorityLevels,
513 + ReactTypeOfWork,
514 + StrictModeBits,
515 + SuspenseyImagesMode,
516 + };
517 +}