import * as preact from 'preact'; import { ComponentType } from 'preact'; import { Signal } from '@preact/signals'; import { Fiber, FiberRoot } from 'bippy'; import { ReactNode } from 'preact/compat'; declare enum RenderPhase { Mount = 1, Update = 2, Unmount = 4 } declare const enum ChangeReason { Props = 1, FunctionalState = 2, ClassState = 3, Context = 4 } interface Render { phase: RenderPhase; componentName: string | null; time: number | null; count: number; forget: boolean; changes: Array; unnecessary: boolean | null; didCommit: boolean; fps: number; } type OnRenderHandler = (fiber: Fiber, renders: Array) => void; type OnCommitStartHandler = () => void; type OnCommitFinishHandler = () => void; type OnErrorHandler = (error: unknown) => void; type IsValidFiberHandler = (fiber: Fiber) => boolean; type OnActiveHandler = () => void; interface InstrumentationConfig { onCommitStart: OnCommitStartHandler; isValidFiber: IsValidFiberHandler; onRender: OnRenderHandler; onCommitFinish: OnCommitFinishHandler; onError: OnErrorHandler; onActive?: OnActiveHandler; onPostCommitFiberRoot: () => void; trackChanges: boolean; forceAlwaysTrackRenders?: boolean; } interface Instrumentation { isPaused: Signal; fiberRoots: WeakSet; } declare const createInstrumentation: (instanceKey: string, config: InstrumentationConfig) => Instrumentation; interface RenderData { count: number; time: number; renders: Array; displayName: string | null; type: unknown; changes?: Array; } type States = { kind: 'inspecting'; hoveredDomElement: Element | null; } | { kind: 'inspect-off'; } | { kind: 'focused'; focusedDomElement: Element; fiber: Fiber; } | { kind: 'uninitialized'; }; interface Options { /** * Enable/disable scanning * * Please use the recommended way: * enabled: process.env.NODE_ENV === 'development', * * @default true */ enabled?: boolean; /** * Force React Scan to run in production (not recommended) * * @default false */ dangerouslyForceRunInProduction?: boolean; /** * Log renders to the console * * WARNING: This can add significant overhead when the app re-renders frequently * * @default false */ log?: boolean; /** * Show toolbar bar * * If you set this to true, and set {@link enabled} to false, the toolbar will still show, but scanning will be disabled. * * @default true */ showToolbar?: boolean; /** * Animation speed * * @default "fast" */ animationSpeed?: "slow" | "fast" | "off"; /** * Track unnecessary renders, and mark their outlines gray when detected * * An unnecessary render is defined as the component re-rendering with no change to the component's * corresponding dom subtree * * @default false * @warning tracking unnecessary renders can add meaningful overhead to react-scan */ trackUnnecessaryRenders?: boolean; /** * Should the FPS meter show in the toolbar * * @default true */ showFPS?: boolean; /** * Should the number of slowdown notifications be shown in the toolbar * * @default true */ showNotificationCount?: boolean; /** * Allow React Scan to run inside iframes * * @default false */ allowInIframe?: boolean; /** * Distance (in pixels) the toolbar keeps from the viewport edges. Useful * when other dev overlays (e.g. the Next.js dev indicator) sit in the same * corner. Pass a single number to inset all edges, or an object to inset * edges individually. * * @default 24 */ safeArea?: number | { top?: number; right?: number; bottom?: number; left?: number; }; /** * Render outline overlays via an OffscreenCanvas + Web Worker. Disable when * a strict Content-Security-Policy without `worker-src blob:` would * otherwise reject the blob worker — React Scan automatically falls back * to main-thread rendering. * * @default true */ useOffscreenCanvasWorker?: boolean; /** * Should react scan log internal errors to the console. * * Useful if react scan is not behaving expected and you want to provide information to maintainers when submitting an issue https://github.com/aidenybai/react-scan/issues * * @default false */ _debug?: "verbose" | false; onCommitStart?: () => void; onRender?: (fiber: Fiber, renders: Array) => void; onCommitFinish?: () => void; } interface StoreType { inspectState: Signal; wasDetailsOpen: Signal; lastReportTime: Signal; isInIframe: Signal; fiberRoots: WeakSet; reportData: Map; legacyReportData: Map; changesListeners: Map>; interactionListeningForRenders: ((fiber: Fiber, renders: Array) => void) | null; } type OutlineKey = `${string}-${string}`; interface Internals { instrumentation: ReturnType | null; componentAllowList: WeakMap, Options> | null; options: Signal; onRender: ((fiber: Fiber, renders: Array) => void) | null; Store: StoreType; version: string; runInAllEnvironments: boolean; } type FunctionalComponentStateChange = { type: ChangeReason.FunctionalState; value: unknown; prevValue?: unknown; count?: number | undefined; name: string; }; type ClassComponentStateChange = { type: ChangeReason.ClassState; value: unknown; prevValue?: unknown; count?: number | undefined; name: "state"; }; type StateChange = FunctionalComponentStateChange | ClassComponentStateChange; type PropsChange = { type: ChangeReason.Props; name: string; value: unknown; prevValue?: unknown; count?: number | undefined; }; type ContextChange = { type: ChangeReason.Context; name: string; value: unknown; prevValue?: unknown; count?: number | undefined; contextType: number; }; type Change = StateChange | PropsChange | ContextChange; type ChangesPayload = { propsChanges: Array; stateChanges: Array; contextChanges: Array; }; type ChangesListener = (changes: ChangesPayload) => void; declare const Store: StoreType; declare const ReactScanInternals: Internals; type LocalStorageOptions = Omit; declare const getReport: (type?: ComponentType) => RenderData | Map | null; declare const setOptions: (userOptions: Partial) => { enabled?: boolean; dangerouslyForceRunInProduction?: boolean; log?: boolean; showToolbar?: boolean; animationSpeed?: "slow" | "fast" | "off"; trackUnnecessaryRenders?: boolean; showFPS?: boolean; showNotificationCount?: boolean; allowInIframe?: boolean; safeArea?: number | { top?: number; right?: number; bottom?: number; left?: number; }; useOffscreenCanvasWorker?: boolean; _debug?: "verbose" | false; onCommitStart?: () => void; onRender?: (fiber: Fiber, renders: Array) => void; onCommitFinish?: () => void; } | undefined; declare const getOptions: () => Signal; declare const getIsProduction: () => boolean | null; declare const start: () => void; declare const scan: (options?: Options) => void; declare const useScan: (options?: Options) => void; declare const onRender: (type: unknown, _onRender: (fiber: Fiber, renders: Array) => void) => void; declare const ignoredProps: WeakSet>; declare const ignoreScan: (node: ReactNode) => void; export { type Change, type ChangesListener, type ChangesPayload, type ClassComponentStateChange, type ContextChange, type FunctionalComponentStateChange, type Internals, type LocalStorageOptions, type Options, type OutlineKey, type PropsChange, ReactScanInternals, type StateChange, Store, type StoreType, getIsProduction, getOptions, getReport, ignoreScan, ignoredProps, onRender, scan, setOptions, start, useScan };