import type {
ReactContext,
Wakeable,
ReactComponentInfo,
} from 'shared/ReactTypes';
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
import type {
ComponentFilter,
ElementType,
Plugins,
} from 'react-devtools-shared/src/frontend/types';
import type {
ResolveNativeStyle,
SetupNativeStyleEditor,
} from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
import type {InitBackend} from 'react-devtools-shared/src/backend';
import type {TimelineDataExport} from 'react-devtools-timeline/src/types';
import type {BackendBridge} from 'react-devtools-shared/src/bridge';
import type {Source} from 'react-devtools-shared/src/shared/types';
import type Agent from './agent';
type BundleType =
| 0
| 1;
export type WorkTag = number;
export type WorkFlags = number;
export type ExpirationTime = number;
export type WorkTagMap = {
CacheComponent: WorkTag,
ClassComponent: WorkTag,
ContextConsumer: WorkTag,
ContextProvider: WorkTag,
CoroutineComponent: WorkTag,
CoroutineHandlerPhase: WorkTag,
DehydratedSuspenseComponent: WorkTag,
ForwardRef: WorkTag,
Fragment: WorkTag,
FunctionComponent: WorkTag,
HostComponent: WorkTag,
HostPortal: WorkTag,
HostRoot: WorkTag,
HostHoistable: WorkTag,
HostSingleton: WorkTag,
HostText: WorkTag,
IncompleteClassComponent: WorkTag,
IncompleteFunctionComponent: WorkTag,
IndeterminateComponent: WorkTag,
LazyComponent: WorkTag,
LegacyHiddenComponent: WorkTag,
MemoComponent: WorkTag,
Mode: WorkTag,
OffscreenComponent: WorkTag,
Profiler: WorkTag,
ScopeComponent: WorkTag,
SimpleMemoComponent: WorkTag,
SuspenseComponent: WorkTag,
SuspenseListComponent: WorkTag,
TracingMarkerComponent: WorkTag,
YieldComponent: WorkTag,
Throw: WorkTag,
ViewTransitionComponent: WorkTag,
ActivityComponent: WorkTag,
};
export type HostInstance = Object;
export type RendererID = number;
type Dispatcher = any;
export type LegacyDispatcherRef = {current: null | Dispatcher};
type SharedInternalsSubset = {
H: null | Dispatcher,
...
};
export type CurrentDispatcherRef = SharedInternalsSubset;
export type GetDisplayNameForElementID = (id: number) => string | null;
export type GetElementIDForHostInstance = (
component: HostInstance,
) => number | null;
export type FindHostInstancesForElementID = (
id: number,
) => null | $ReadOnlyArray<HostInstance>;
export type ReactProviderType<T> = {
$$typeof: symbol | number,
_context: ReactContext<T>,
...
};
export type Lane = number;
export type Lanes = number;
export type ReactRenderer = {
version: string,
rendererPackageName: string,
bundleType: BundleType,
findFiberByHostInstance?: (hostInstance: HostInstance) => Fiber | null,
overrideHookState?: ?(
fiber: Object,
id: number,
path: Array<string | number>,
value: any,
) => void,
overrideHookStateDeletePath?: ?(
fiber: Object,
id: number,
path: Array<string | number>,
) => void,
overrideHookStateRenamePath?: ?(
fiber: Object,
id: number,
oldPath: Array<string | number>,
newPath: Array<string | number>,
) => void,
overrideProps?: ?(
fiber: Object,
path: Array<string | number>,
value: any,
) => void,
overridePropsDeletePath?: ?(
fiber: Object,
path: Array<string | number>,
) => void,
overridePropsRenamePath?: ?(
fiber: Object,
oldPath: Array<string | number>,
newPath: Array<string | number>,
) => void,
scheduleUpdate?: ?(fiber: Object) => void,
setSuspenseHandler?: ?(shouldSuspend: (fiber: Object) => boolean) => void,
currentDispatcherRef?: LegacyDispatcherRef | CurrentDispatcherRef,
getCurrentFiber?: (() => Fiber | null) | null,
getCurrentComponentInfo?: () => ReactComponentInfo | null,
reconcilerVersion?: string,
ComponentTree?: any,
Mount?: any,
setErrorHandler?: ?(shouldError: (fiber: Object) => ?boolean) => void,
scheduleRefresh?: Function,
injectProfilingHooks?: (profilingHooks: DevToolsProfilingHooks) => void,
getLaneLabelMap?: () => Map<Lane, string> | null,
...
};
export type ChangeDescription = {
context: Array<string> | boolean | null,
didHooksChange: boolean,
isFirstMount: boolean,
props: Array<string> | null,
state: Array<string> | null,
hooks?: Array<number> | null,
};
export type CommitDataBackend = {
changeDescriptions: Array<[number, ChangeDescription]> | null,
duration: number,
effectDuration: number | null,
fiberActualDurations: Array<[number, number]>,
fiberSelfDurations: Array<[number, number]>,
passiveEffectDuration: number | null,
priorityLevel: string | null,
timestamp: number,
updaters: Array<SerializedElement> | null,
};
export type ProfilingDataForRootBackend = {
commitData: Array<CommitDataBackend>,
displayName: string,
initialTreeBaseDurations: Array<[number, number]>,
rootID: number,
};
export type ProfilingDataBackend = {
dataForRoots: Array<ProfilingDataForRootBackend>,
rendererID: number,
timelineData: TimelineDataExport | null,
};
export type PathFrame = {
key: string | null,
index: number,
displayName: string | null,
};
export type PathMatch = {
id: number,
isFullMatch: boolean,
};
export type SerializedElement = {
displayName: string | null,
id: number,
key: number | string | null,
type: ElementType,
};
export type OwnersList = {
id: number,
owners: Array<SerializedElement> | null,
};
export type InspectedElement = {
id: number,
canEditHooks: boolean,
canEditFunctionProps: boolean,
canEditHooksAndDeletePaths: boolean,
canEditHooksAndRenamePaths: boolean,
canEditFunctionPropsDeletePaths: boolean,
canEditFunctionPropsRenamePaths: boolean,
canToggleError: boolean,
isErrored: boolean,
canToggleSuspense: boolean,
canViewSource: boolean,
hasLegacyContext: boolean,
context: Object | null,
hooks: Object | null,
props: Object | null,
state: Object | null,
key: number | string | null,
errors: Array<[string, number]>,
warnings: Array<[string, number]>,
owners: Array<SerializedElement> | null,
source: Source | null,
type: ElementType,
rootType: string | null,
rendererPackageName: string | null,
rendererVersion: string | null,
plugins: Plugins,
nativeTag: number | null,
};
export const InspectElementErrorType = 'error';
export const InspectElementFullDataType = 'full-data';
export const InspectElementNoChangeType = 'no-change';
export const InspectElementNotFoundType = 'not-found';
export type InspectElementError = {
id: number,
responseID: number,
type: 'error',
errorType: 'user' | 'unknown-hook' | 'uncaught',
message: string,
stack?: string,
};
export type InspectElementFullData = {
id: number,
responseID: number,
type: 'full-data',
value: InspectedElement,
};
export type InspectElementHydratedPath = {
id: number,
responseID: number,
type: 'hydrated-path',
path: Array<string | number>,
value: any,
};
export type InspectElementNoChange = {
id: number,
responseID: number,
type: 'no-change',
};
export type InspectElementNotFound = {
id: number,
responseID: number,
type: 'not-found',
};
export type InspectedElementPayload =
| InspectElementError
| InspectElementFullData
| InspectElementHydratedPath
| InspectElementNoChange
| InspectElementNotFound;
export type InstanceAndStyle = {
instance: Object | null,
style: Object | null,
};
type Type = 'props' | 'hooks' | 'state' | 'context';
export type OnErrorOrWarning = (
type: 'error' | 'warn',
args: Array<any>,
) => void;
export type GetComponentStack = (
topFrame: Error,
) => null | {enableOwnerStacks: boolean, componentStack: string};
export type RendererInterface = {
cleanup: () => void,
clearErrorsAndWarnings: () => void,
clearErrorsForElementID: (id: number) => void,
clearWarningsForElementID: (id: number) => void,
deletePath: (
type: Type,
id: number,
hookID: ?number,
path: Array<string | number>,
) => void,
findHostInstancesForElementID: FindHostInstancesForElementID,
flushInitialOperations: () => void,
getBestMatchForTrackedPath: () => PathMatch | null,
getComponentStack?: GetComponentStack,
getNearestMountedDOMNode: (component: Element) => Element | null,
getElementIDForHostInstance: GetElementIDForHostInstance,
getDisplayNameForElementID: GetDisplayNameForElementID,
getInstanceAndStyle(id: number): InstanceAndStyle,
getProfilingData(): ProfilingDataBackend,
getOwnersList: (id: number) => Array<SerializedElement> | null,
getPathForElement: (id: number) => Array<PathFrame> | null,
getSerializedElementValueByPath: (
id: number,
path: Array<string | number>,
) => ?string,
handleCommitFiberRoot: (fiber: Object, commitPriority?: number) => void,
handleCommitFiberUnmount: (fiber: Object) => void,
handlePostCommitFiberRoot: (fiber: Object) => void,
hasElementWithId: (id: number) => boolean,
inspectElement: (
requestID: number,
id: number,
inspectedPaths: Object,
forceFullData: boolean,
) => InspectedElementPayload,
logElementToConsole: (id: number) => void,
onErrorOrWarning?: OnErrorOrWarning,
overrideError: (id: number, forceError: boolean) => void,
overrideSuspense: (id: number, forceFallback: boolean) => void,
overrideValueAtPath: (
type: Type,
id: number,
hook: ?number,
path: Array<string | number>,
value: any,
) => void,
getElementAttributeByPath: (
id: number,
path: Array<string | number>,
) => mixed,
getElementSourceFunctionById: (id: number) => null | Function,
renamePath: (
type: Type,
id: number,
hookID: ?number,
oldPath: Array<string | number>,
newPath: Array<string | number>,
) => void,
renderer: ReactRenderer | null,
setTraceUpdatesEnabled: (enabled: boolean) => void,
setTrackedPath: (path: Array<PathFrame> | null) => void,
startProfiling: (
recordChangeDescriptions: boolean,
recordTimeline: boolean,
) => void,
stopProfiling: () => void,
storeAsGlobal: (
id: number,
path: Array<string | number>,
count: number,
) => void,
updateComponentFilters: (componentFilters: Array<ComponentFilter>) => void,
getEnvironmentNames: () => Array<string>,
...
};
export type Handler = (data: any) => void;
export type DevToolsProfilingHooks = {
markRenderScheduled: (lane: Lane) => void,
markStateUpdateScheduled: (fiber: Fiber, lane: Lane) => void,
markForceUpdateScheduled: (fiber: Fiber, lane: Lane) => void,
markRenderStarted: (lanes: Lanes) => void,
markRenderYielded: () => void,
markRenderStopped: () => void,
markCommitStarted: (lanes: Lanes) => void,
markCommitStopped: () => void,
markLayoutEffectsStarted: (lanes: Lanes) => void,
markLayoutEffectsStopped: () => void,
markPassiveEffectsStarted: (lanes: Lanes) => void,
markPassiveEffectsStopped: () => void,
markComponentRenderStarted: (fiber: Fiber) => void,
markComponentRenderStopped: () => void,
markComponentErrored: (
fiber: Fiber,
thrownValue: mixed,
lanes: Lanes,
) => void,
markComponentSuspended: (
fiber: Fiber,
wakeable: Wakeable,
lanes: Lanes,
) => void,
markComponentLayoutEffectMountStarted: (fiber: Fiber) => void,
markComponentLayoutEffectMountStopped: () => void,
markComponentLayoutEffectUnmountStarted: (fiber: Fiber) => void,
markComponentLayoutEffectUnmountStopped: () => void,
markComponentPassiveEffectMountStarted: (fiber: Fiber) => void,
markComponentPassiveEffectMountStopped: () => void,
markComponentPassiveEffectUnmountStarted: (fiber: Fiber) => void,
markComponentPassiveEffectUnmountStopped: () => void,
};
export type DevToolsBackend = {
Agent: Class<Agent>,
Bridge: Class<BackendBridge>,
initBackend: InitBackend,
setupNativeStyleEditor?: SetupNativeStyleEditor,
};
export type ProfilingSettings = {
recordChangeDescriptions: boolean,
recordTimeline: boolean,
};
export type DevToolsHook = {
listeners: {[key: string]: Array<Handler>, ...},
rendererInterfaces: Map<RendererID, RendererInterface>,
renderers: Map<RendererID, ReactRenderer>,
hasUnsupportedRendererAttached: boolean,
backends: Map<string, DevToolsBackend>,
emit: (event: string, data: any) => void,
getFiberRoots: (rendererID: RendererID) => Set<Object>,
inject: (renderer: ReactRenderer) => number | null,
on: (event: string, handler: Handler) => void,
off: (event: string, handler: Handler) => void,
reactDevtoolsAgent?: ?Object,
sub: (event: string, handler: Handler) => () => void,
resolveRNStyle?: ResolveNativeStyle,
nativeStyleEditorValidAttributes?: $ReadOnlyArray<string>,
checkDCE: (fn: Function) => void,
onCommitFiberUnmount: (rendererID: RendererID, fiber: Object) => void,
onCommitFiberRoot: (
rendererID: RendererID,
fiber: Object,
commitPriority?: number,
didError?: boolean,
) => void,
getInternalModuleRanges: () => Array<[string, string]>,
registerInternalModuleStart: (moduleStartError: Error) => void,
registerInternalModuleStop: (moduleStopError: Error) => void,
dangerous_setTargetConsoleForTesting?: (fakeConsole: Object) => void,
settings?: $ReadOnly<DevToolsHookSettings>,
...
};
export type DevToolsHookSettings = {
appendComponentStack: boolean,
breakOnConsoleErrors: boolean,
showInlineWarningsAndErrors: boolean,
hideConsoleLogsInStrictMode: boolean,
};