@atlassian/chippy 0.0.1-beta.1 → 0.0.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -54
- package/bin/chippy.mjs +53 -95
- package/bin/pack.mjs +20 -0
- package/bin/skill-dir.mjs +15 -0
- package/lib/avalanche.js +54 -23
- package/lib/avalanche.js.map +2 -2
- package/lib/bootstrap.js +20 -1
- package/lib/bootstrap.js.map +3 -3
- package/lib/extension/avalanche.es.js +173 -34
- package/lib/extension/avalanche.es.js.map +1 -1
- package/lib/extension/chippy-page-bridge.js +164 -44
- package/lib/mcp-skill/README.md +2 -4
- package/lib/mcp-skill/SKILL.md +21 -16
- package/lib/mcp-skill/extension/armed-reload-startup.js +83 -0
- package/lib/mcp-skill/extension/avalanche.es.js +173 -34
- package/lib/mcp-skill/extension/avalanche.es.js.map +1 -1
- package/lib/mcp-skill/extension/avalanche.iife.js +173 -34
- package/lib/mcp-skill/extension/avalanche.iife.js.map +1 -1
- package/lib/mcp-skill/extension/background.js +2 -0
- package/lib/mcp-skill/extension/chippy-page-bridge.js +164 -44
- package/lib/mcp-skill/extension/content-script.js +23 -0
- package/lib/mcp-skill/extension/devtools-hook-shim.js +18 -1
- package/lib/mcp-skill/extension/early-bootstrap.js +3 -1
- package/lib/mcp-skill/extension/manifest.json +1 -1
- package/lib/mcp-skill/extension/panel-settings.js +2 -20
- package/lib/mcp-skill/extension/startup-handoff.js +30 -0
- package/lib/mcp-skill/references/README.md +2 -2
- package/lib/mcp-skill/references/avalanche-detector.md +3 -3
- package/lib/mcp-skill/references/browser-runtime-api.md +4 -4
- package/lib/mcp-skill/references/command-output-formats.md +12 -2
- package/lib/mcp-skill/references/command-surface.md +6 -6
- package/lib/mcp-skill/references/mode-a-injection.md +43 -9
- package/lib/mcp-skill/references/playwright-cli-setup.md +5 -5
- package/lib/mcp-skill/references/playwright-probes.md +1 -1
- package/lib/mcp-skill/references/recipes.txt +1 -1
- package/lib/mcp-skill/references/stability-render.md +4 -4
- package/lib/mcp-skill/references/test-mode-playbook.md +2 -1
- package/lib/mcp-skill/references/troubleshooting.md +6 -1
- package/lib/mcp-skill/scripts/chippy-helper-server.js +116 -58
- package/lib/mcp-skill/scripts/chippy.sh +41 -7
- package/lib/mcp-skill/scripts/helper-access.js +20 -6
- package/lib/mcp-skill/scripts/helper-proxy.js +87 -0
- package/lib/mcp-skill/scripts/page-socket-trust.js +81 -0
- package/lib/plugin.js.map +2 -2
- package/lib/storybook/connection-fallback.jsx +1 -1
- package/lib/storybook/manager-owner.js +42 -0
- package/lib/storybook/manager.jsx +22 -0
- package/lib/storybook/preview.js +53 -18
- package/lib/storybook/setup.js +15 -4
- package/lib/types/chippy-bridge/fiber-source.d.ts +14 -3
- package/lib/types/chippy-bridge/react-renderer.d.ts +30 -5
- package/lib/types/chippy-bridge/recorded-source.d.ts +44 -0
- package/lib/types/debug-render/core.d.ts +6 -0
- package/package.json +3 -1
package/lib/avalanche.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/chippy-bridge/source-map.ts", "../src/chippy-bridge/fiber-source.ts", "../src/avalanche/internals.tsx", "../src/avalanche/commit-stats-indices.ts", "../src/avalanche/report-serializer.tsx", "../src/avalanche/commit-metrics-adapter.ts", "../src/avalanche/reporter.tsx", "../src/chippy-bridge/react-renderer.ts", "../src/debug-render/core.ts", "../src/avalanche/commit-surface-ownership.ts", "../src/layout-lab/fiber-walk.ts", "../src/avalanche/interaction-capture.ts", "../src/avalanche/detector.tsx", "../src/plugins/atl/metrics-slot.ts", "../src/plugins/atl/commit-metrics-adapter.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Small, dependency-free Source Map v3 reader.\n *\n * Chippy only needs the generated-position lookup used by React 19's\n * `_debugStack` source path, so it deliberately omits names and source contents.\n */\n\nconst DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst VALUE_OF = new Int8Array(128).fill(-1);\nfor (let index = 0; index < DIGITS.length; index += 1) {\n VALUE_OF[DIGITS.charCodeAt(index)] = index;\n}\n\ntype Segment = {\n generatedColumn: number;\n sourceIndex: number | null;\n originalLine: number | null;\n originalColumn: number | null;\n};\n\nexport type SourceMap = {\n sources: readonly string[];\n lines: readonly (readonly Segment[])[];\n offset: { line: number; column: number };\n};\n\nexport type OriginalPosition = {\n source: string;\n line: number;\n column: number;\n};\n\ntype RawMap = {\n version?: unknown;\n sources?: unknown;\n sourceRoot?: unknown;\n mappings?: unknown;\n sections?: unknown;\n};\n\nfunction decodeVlq(field: string): number[] {\n const values: number[] = [];\n let value = 0;\n let shift = 0;\n\n for (let index = 0; index < field.length; index += 1) {\n const code = field.charCodeAt(index);\n const digit = code < 128 ? VALUE_OF[code]! : -1;\n if (digit < 0) return values;\n\n const more = (digit & 32) !== 0;\n value += (digit & 31) << shift;\n if (more) {\n shift += 5;\n continue;\n }\n\n const negative = (value & 1) === 1;\n const magnitude = value >>> 1;\n values.push(negative ? (magnitude === 0 ? -0x80000000 : -magnitude) : magnitude);\n value = 0;\n shift = 0;\n }\n\n return values;\n}\n\nfunction decodeMappings(mappings: string, sourceCount: number): Segment[][] {\n const lines: Segment[][] = [];\n let sourceIndex = 0;\n let originalLine = 0;\n let originalColumn = 0;\n\n for (const encodedLine of mappings.split(';')) {\n const segments: Segment[] = [];\n let generatedColumn = 0;\n\n for (const field of encodedLine === '' ? [] : encodedLine.split(',')) {\n const values = decodeVlq(field);\n if (values.length < 4) {\n if (values.length > 0) {\n generatedColumn += values[0]!;\n segments.push({ generatedColumn, sourceIndex: null, originalLine: null, originalColumn: null });\n }\n continue;\n }\n\n generatedColumn += values[0]!;\n sourceIndex += values[1]!;\n originalLine += values[2]!;\n originalColumn += values[3]!;\n if (sourceIndex >= 0 && sourceIndex < sourceCount) {\n segments.push({ generatedColumn, sourceIndex, originalLine, originalColumn });\n }\n }\n\n segments.sort((left, right) => left.generatedColumn - right.generatedColumn);\n lines.push(segments);\n }\n\n return lines;\n}\n\nfunction resolveSources(raw: RawMap): string[] | null {\n if (!Array.isArray(raw.sources)) return null;\n const root = typeof raw.sourceRoot === 'string' ? raw.sourceRoot : '';\n\n return raw.sources.map((source) => {\n if (typeof source !== 'string') return '';\n if (root === '' || source === '' || /^[a-z][a-z0-9+.-]*:/i.test(source)) return source;\n if (root.endsWith('/') && source.startsWith('/')) return `${root}${source.slice(1)}`;\n if (root.endsWith('/') || source.startsWith('/')) return `${root}${source}`;\n return `${root}/${source}`;\n });\n}\n\nexport function parseSourceMap(text: string): SourceMap[] {\n let raw: RawMap;\n try {\n raw = JSON.parse(text) as RawMap;\n } catch {\n return [];\n }\n\n if (raw === null || typeof raw !== 'object') return [];\n if (raw.version !== 3) return [];\n\n if (Array.isArray(raw.sections)) {\n return raw.sections.flatMap((section) => {\n if (section === null || typeof section !== 'object') return [];\n const { offset, map } = section as { offset?: unknown; map?: unknown };\n if (offset === null || typeof offset !== 'object' || map === null || typeof map !== 'object') return [];\n const { line, column } = offset as { line?: unknown; column?: unknown };\n if (typeof line !== 'number' || typeof column !== 'number') return [];\n return parseSourceMap(JSON.stringify(map)).map((parsed) => ({ ...parsed, offset: { line, column } }));\n });\n }\n\n const sources = resolveSources(raw);\n if (sources === null || typeof raw.mappings !== 'string') return [];\n return [{ sources, lines: decodeMappings(raw.mappings, sources.length), offset: { line: 0, column: 0 } }];\n}\n\nfunction sectionsFor(maps: readonly SourceMap[], line: number, column: number): readonly SourceMap[] {\n if (\n maps.length === 0 ||\n (maps.length === 1 && maps[0]?.offset.line === 0 && maps[0]?.offset.column === 0)\n ) return maps;\n const zeroBasedLine = line - 1;\n const candidates = maps.filter(\n (map) =>\n map.offset.line < zeroBasedLine ||\n (map.offset.line === zeroBasedLine && map.offset.column < column),\n );\n return candidates.length === 0 ? [] : [candidates[candidates.length - 1]!];\n}\n\nfunction segmentAt(segments: readonly Segment[], column: number): Segment | undefined {\n let low = 0;\n let high = segments.length - 1;\n let found: Segment | undefined;\n\n while (low <= high) {\n const middle = (low + high) >> 1;\n const segment = segments[middle]!;\n if (segment.generatedColumn <= column) {\n found = segment;\n low = middle + 1;\n } else {\n high = middle - 1;\n }\n }\n\n return found;\n}\n\nexport function originalPositionFor(\n maps: readonly SourceMap[],\n line: number,\n column: number,\n): OriginalPosition | null {\n for (const map of sectionsFor(maps, line, column)) {\n const localLine = line - map.offset.line;\n const localColumn = localLine === 1 ? column - map.offset.column : column;\n const segments = map.lines[localLine - 1];\n if (segments === undefined || segments.length === 0) continue;\n\n const found = segmentAt(segments, localColumn - 1);\n if (found === undefined) continue;\n if (\n found.sourceIndex === null ||\n found.originalLine === null ||\n found.originalColumn === null\n ) return null;\n const source = map.sources[found.sourceIndex];\n if (source === undefined || source === '') continue;\n return { source, line: found.originalLine + 1, column: found.originalColumn + 1 };\n }\n\n return null;\n}\n\nexport function sourceMappingUrlOf(code: string): string | null {\n const found = [...code.matchAll(/^[/*]{2,}[#@]\\s*sourceMappingURL=(\\S+)\\s*(?:\\*\\/)?$/gm)];\n return found.at(-1)?.[1] ?? null;\n}\n\nexport function inlineSourceMapOf(url: string): string | null {\n const match = /^data:application\\/json[^,]*,(.*)$/s.exec(url);\n if (match === null) return null;\n const payload = match[1]!;\n\n if (!/;base64/i.test(url)) {\n try {\n return decodeURIComponent(payload);\n } catch {\n return null;\n }\n }\n\n try {\n const decode = (globalThis as { atob?: (input: string) => string }).atob;\n if (decode) {\n const binary = decode(payload);\n const Decoder = (globalThis as {\n TextDecoder?: new () => { decode(bytes: Uint8Array): string };\n }).TextDecoder;\n return Decoder\n ? new Decoder().decode(Uint8Array.from(binary, (character) => character.charCodeAt(0)))\n : binary;\n }\n const buffer = (globalThis as {\n Buffer?: { from(value: string, encoding: string): { toString(encoding: string): string } };\n }).Buffer;\n return buffer?.from(payload, 'base64').toString('utf8') ?? null;\n } catch {\n return null;\n }\n}\n", "import {\n inlineSourceMapOf,\n originalPositionFor,\n parseSourceMap,\n sourceMappingUrlOf,\n type OriginalPosition,\n type SourceMap,\n} from './source-map';\n\nexport type FiberSourceLocation = {\n fileName: string;\n lineNumber: number;\n columnNumber: number | null;\n};\n\nexport type StackFrame = {\n url: string;\n line: number;\n column: number;\n function?: string;\n};\n\nexport type SourceFiber = {\n type?: unknown;\n _debugSource?: unknown;\n _debugStack?: unknown;\n};\n\nexport type FetchModule = (url: string) => Promise<string | null>;\n\nexport type CallSiteResolver = {\n locate(frames: readonly StackFrame[]): Promise<FiberSourceLocation | null>;\n readonly stats: { modules: number; sites: number; located: number };\n};\n\ntype ResolvedMaps = {\n maps: readonly SourceMap[];\n sourceBaseUrl: string;\n};\n\nconst V8_FRAME = /^\\s*at\\s+(?:(.+?)\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/;\nconst AT_FRAME = /^\\s*(?:(.*?)@)(.+?):(\\d+):(\\d+)$/;\nconst MAX_CALL_SITE_FRAMES = 4;\n\nconst resolvedFiberSources = new WeakMap<object, FiberSourceLocation | null>();\nconst pendingFiberSources = new WeakMap<object, Promise<FiberSourceLocation | null>>();\nlet defaultResolver: CallSiteResolver | null = null;\n\nexport function parseStackFrames(stack: string): StackFrame[] {\n const frames: StackFrame[] = [];\n\n for (const raw of stack.split('\\n')) {\n const line = raw.trimEnd();\n if (line === '' || line.includes('(eval at ')) continue;\n const match = V8_FRAME.exec(line) ?? AT_FRAME.exec(line);\n if (!match) continue;\n\n const [, name, url = '', lineDigits = '', columnDigits = ''] = match;\n if (url === '' || url.startsWith('data:')) continue;\n const at = Number(lineDigits);\n const column = Number(columnDigits);\n if (!Number.isFinite(at) || !Number.isFinite(column) || at < 1) continue;\n frames.push({\n url,\n line: at,\n column,\n ...(name !== undefined && name !== '' ? { function: name } : {}),\n });\n }\n\n return frames;\n}\n\nexport function isVendorPath(path: string): boolean {\n return (\n path.includes('node_modules') ||\n path.includes('/.vite/deps/') ||\n path.includes('/.yarn/')\n );\n}\n\nfunction rawLocation(frame: StackFrame): FiberSourceLocation {\n return { fileName: frame.url, lineNumber: frame.line, columnNumber: frame.column };\n}\n\nfunction locationFromOriginal(original: OriginalPosition): FiberSourceLocation {\n return { fileName: original.source, lineNumber: original.line, columnNumber: original.column };\n}\n\nexport function writerLocationOf(\n frames: readonly StackFrame[],\n originalFor: (frame: StackFrame) => OriginalPosition | null,\n): FiberSourceLocation | null {\n for (const frame of frames) {\n if (isVendorPath(frame.url)) continue;\n const original = originalFor(frame);\n if (original === null) return rawLocation(frame);\n if (isVendorPath(original.source)) continue;\n return locationFromOriginal(original);\n }\n return null;\n}\n\nfunction parseUrl(url: string, base?: string): URL | null {\n try {\n return new URL(url, base);\n } catch {\n return null;\n }\n}\n\nfunction sourcePath(source: string, moduleUrl: string): string {\n if (/^\\/(?:Users|home|private|Volumes)\\//.test(source)) return source;\n const direct = parseUrl(source);\n if (direct?.protocol === 'file:') return decodeURIComponent(direct.pathname);\n const resolved = parseUrl(source, moduleUrl)?.href ?? source;\n const parsed = parseUrl(resolved);\n return parsed ? parsed.pathname.replace(/^\\/+/, '') : resolved;\n}\n\nexport function createCallSiteResolver(fetchModule: FetchModule): CallSiteResolver {\n const maps = new Map<string, Promise<ResolvedMaps | null>>();\n const sites = new Map<string, Promise<FiberSourceLocation | null>>();\n const stats = { modules: 0, sites: 0, located: 0 };\n\n async function mapsFor(url: string): Promise<ResolvedMaps | null> {\n const cached = maps.get(url);\n if (cached) return cached;\n\n const pending = (async () => {\n stats.modules += 1;\n const code = await fetchModule(url);\n if (code === null) return null;\n const annotation = sourceMappingUrlOf(code);\n if (annotation === null) return null;\n const inline = inlineSourceMapOf(annotation);\n if (inline !== null) return { maps: parseSourceMap(inline), sourceBaseUrl: url };\n const mapUrl = parseUrl(annotation, url)?.href ?? null;\n const text = mapUrl === null ? null : await fetchModule(mapUrl);\n return text === null || mapUrl === null\n ? null\n : { maps: parseSourceMap(text), sourceBaseUrl: mapUrl };\n })();\n\n maps.set(url, pending);\n return pending;\n }\n\n async function locateFrame(frame: StackFrame): Promise<FiberSourceLocation | null> {\n const parsed = await mapsFor(frame.url);\n if (!parsed || parsed.maps.length === 0) return null;\n const original = originalPositionFor(parsed.maps, frame.line, frame.column);\n if (!original) return null;\n return {\n fileName: sourcePath(original.source, parsed.sourceBaseUrl),\n lineNumber: original.line,\n columnNumber: original.column,\n };\n }\n\n async function locate(frames: readonly StackFrame[]): Promise<FiberSourceLocation | null> {\n for (const frame of frames) {\n if (isVendorPath(frame.url)) continue;\n const key = `${frame.url}:${frame.line}:${frame.column}`;\n let answer = sites.get(key);\n if (!answer) {\n stats.sites += 1;\n answer = locateFrame(frame);\n sites.set(key, answer);\n }\n\n const located = await answer;\n const chosen = located === null\n ? writerLocationOf([frame], () => null)\n : isVendorPath(located.fileName) ? null : located;\n if (chosen) {\n stats.located += 1;\n return chosen;\n }\n }\n return null;\n }\n\n return { locate, stats };\n}\n\nfunction debugSourceOf(value: unknown): FiberSourceLocation | null {\n if (!value || typeof value !== 'object') return null;\n const source = value as { fileName?: unknown; lineNumber?: unknown; columnNumber?: unknown };\n if (typeof source.fileName !== 'string' || typeof source.lineNumber !== 'number') return null;\n return {\n fileName: source.fileName,\n lineNumber: source.lineNumber,\n columnNumber: typeof source.columnNumber === 'number' ? source.columnNumber : null,\n };\n}\n\nfunction recordedSource(fiber: SourceFiber): FiberSourceLocation | null {\n const direct = debugSourceOf(fiber._debugSource);\n if (direct) return direct;\n const type = fiber.type;\n return type && (typeof type === 'object' || typeof type === 'function')\n ? debugSourceOf((type as { _debugSource?: unknown })._debugSource)\n : null;\n}\n\nexport function getFiberStackFrames(fiber: SourceFiber | null | undefined): StackFrame[] {\n if (!fiber || !fiber._debugStack || typeof fiber._debugStack !== 'object') return [];\n const stack = (fiber._debugStack as { stack?: unknown }).stack;\n if (typeof stack !== 'string' || stack === '') return [];\n const candidates: StackFrame[] = [];\n for (const frame of parseStackFrames(stack)) {\n if (isVendorPath(frame.url)) continue;\n candidates.push(frame);\n if (candidates.length >= MAX_CALL_SITE_FRAMES) break;\n }\n return candidates;\n}\n\n/** Stable synchronous source, before any async source-map upgrade. */\nexport function getFiberSourceCandidate(fiber: SourceFiber | null | undefined): FiberSourceLocation | null {\n if (!fiber) return null;\n const recorded = recordedSource(fiber);\n if (recorded) return recorded;\n return writerLocationOf(getFiberStackFrames(fiber), () => null);\n}\n\n/** Synchronous source read used by fiber walks and snapshots. */\nexport function getFiberSource(fiber: SourceFiber | null | undefined): FiberSourceLocation | null {\n if (!fiber) return null;\n const recorded = recordedSource(fiber);\n if (recorded) return recorded;\n const cached = resolvedFiberSources.get(fiber as object);\n if (cached !== undefined) return cached;\n return getFiberSourceCandidate(fiber);\n}\n\nasync function fetchModuleFromPage(url: string): Promise<string | null> {\n const fetchFn = (globalThis as { fetch?: typeof fetch }).fetch;\n if (!fetchFn) return null;\n const controller = typeof AbortController === 'function' ? new AbortController() : null;\n const timeout = controller ? setTimeout(() => controller.abort(), 2000) : null;\n try {\n const response = await fetchFn(url, {\n credentials: 'same-origin',\n signal: controller?.signal,\n });\n return response.ok ? await response.text() : null;\n } catch {\n return null;\n } finally {\n if (timeout !== null) clearTimeout(timeout);\n }\n}\n\nfunction pageResolver(): CallSiteResolver {\n if (!defaultResolver) defaultResolver = createCallSiteResolver(fetchModuleFromPage);\n return defaultResolver;\n}\n\n/** Resolve a React 19 stack frame through the module's inline or external map. */\nexport function resolveFiberSource(\n fiber: SourceFiber | null | undefined,\n resolver: CallSiteResolver = pageResolver(),\n): Promise<FiberSourceLocation | null> {\n if (!fiber) return Promise.resolve(null);\n const recorded = recordedSource(fiber);\n if (recorded) return Promise.resolve(recorded);\n\n const cached = pendingFiberSources.get(fiber as object);\n if (cached) return cached;\n const frames = getFiberStackFrames(fiber);\n const fallback = writerLocationOf(frames, () => null);\n const pending = resolver.locate(frames)\n .catch(() => null)\n .then((source) => {\n const located = source ?? fallback;\n resolvedFiberSources.set(fiber as object, located);\n return located;\n });\n pendingFiberSources.set(fiber as object, pending);\n return pending;\n}\n", "// React fiber constants and structural comparisons used by the commit detector.\n\nimport { getFiberSourceCandidate } from '../chippy-bridge/fiber-source';\n\nexport type ComponentType =\n | Function\n | symbol\n | {\n // ForwardRef/memo/etc may be objects.\n $$typeof?: symbol;\n render?: Function;\n displayName?: string;\n name?: string;\n };\n\ninterface StoreCheck {\n getSnapshot: () => unknown;\n value: unknown;\n}\n\nexport interface Fiber {\n tag: number;\n type: ComponentType;\n alternate: Fiber | null;\n return: Fiber | null;\n child: Fiber | null;\n sibling: Fiber | null;\n flags: number;\n subtreeFlags: number;\n lanes: number;\n memoizedState: Hook | null;\n memoizedProps?: unknown;\n pendingProps?: unknown;\n updateQueue: { stores: StoreCheck[] | null } | null;\n /**\n * React populates this array during the render phase with fibers that will be\n * deleted in the commit phase. Present when subtreeFlags & ChildDeletion !== 0.\n * Only available in React 18+ (replaces the older effectList pattern).\n */\n deletions?: Fiber[] | null;\n\n // Dev-only / optional debug fields (not always present).\n elementType?: unknown;\n _debugSource?: { fileName: string; lineNumber: number };\n _debugStack?: unknown;\n _debugHookTypes?: string[];\n}\n\nexport interface Hook {\n memoizedState: unknown;\n baseState: unknown;\n baseQueue: unknown;\n queue: HookQueue | null;\n next: Hook | null;\n}\n\ninterface HookQueue {\n dispatch?: Function;\n value?: unknown;\n getSnapshot?: Function;\n lastRenderedState?: unknown;\n}\n\nexport interface DepOrigin {\n type: ComponentType;\n hookIndex: number;\n depth: number;\n hookType: 'useCallback' | 'useMemo';\n}\n\nexport interface ThrashInfo {\n hookIndex: number;\n hookType: 'effect' | 'callback' | 'memo';\n deps: unknown[];\n changedDepIndices: number[];\n changedDepOrigins: (DepOrigin | null)[];\n effectTag?: number;\n memoValue?: unknown;\n /** The hook body function (for useCallback) or memoized value (for useMemo) */\n hookBody?: Function | unknown;\n}\n\nexport type ChangedHook =\n | {\n prevValue: unknown;\n currentValue: unknown;\n info?: string; // For structural changes\n }\n | 'repeat'; // Entire object replaced with string if identical to previous commit\n\nexport interface StateChangeResult {\n hasChange: boolean;\n actionable: boolean;\n changedIndices: number[];\n changedHooks: ChangedHook[];\n /** True if any of the changes came from useSyncExternalStore */\n hasExternalStoreChange: boolean;\n}\n\nexport interface ThrashingResult {\n effects: ThrashInfo[];\n callbacks: ThrashInfo[];\n memos: ThrashInfo[];\n}\n\n// React fiber flags (React 18.3.1)\nexport const PerformedWork = 1;\n\n// Flags relevant to filtering out non-preventable work from collateral counts.\n// - Placement: mount/insert work (initial render)\n// - Hydrating: work done while hydrating server-rendered markup\n// These are stable for React 18.x.\nexport const Placement = 2;\nexport const Hydrating = 4096;\n\n// Special sentinel values for hook change detection\n\n// Component fiber tags for React 18.3.1 (stable within 18.x)\n// 0: FunctionComponent, 1: ClassComponent, 2: IndeterminateComponent\n// 11: MemoComponent, 14: SimpleMemoComponent, 15: ForwardRef\nconst COMPONENT_TAGS = new Set([0, 1, 2, 11, 14, 15]);\n\n// Context Provider tag\nconst CONTEXT_PROVIDER_TAG = 10;\n\n// Suspense fiber tag (React 18.3.1 \u2014 stable within 18.x)\nexport const SuspenseTag = 13;\n\n// ChildDeletion \u2014 set on fiber.flags (NOT subtreeFlags) when the fiber has deletions[].\n// Value 16 is stable for React 18.3.1.\nexport const ChildDeletion = 16;\n\n// Update \u2014 set on fiber.flags when the fiber received an update this commit.\n// This is the flag React puts on Suspense fibers when they transition state.\n// Value 4 is stable for React 18.3.1.\nexport const Update = 4;\n\n// DidCapture \u2014 render-phase flag, cleared before commit. Do NOT check at commit time.\n// Kept for documentation. Value 128 in React 18.3.1.\nexport const DidCapture = 128;\n\nexport function isComponentFiber(tag: number): boolean {\n return COMPONENT_TAGS.has(tag);\n}\n\nexport function isContextProviderFiber(tag: number): boolean {\n return tag === CONTEXT_PROVIDER_TAG;\n}\n\nexport function isSuspenseFiber(tag: number): boolean {\n return tag === SuspenseTag;\n}\n\n/**\n * Detect whether a Suspense boundary transitioned between suspended/unsuspended states.\n *\n * Suspense memoizedState is:\n * null \u2192 primary content is showing (not suspended)\n * non-null (object) \u2192 boundary is showing the fallback (suspended/dehydrated)\n *\n * Returns:\n * { entered: true } \u2014 boundary just entered fallback\n * - null \u2192 non-null (update path)\n * - no alternate + memoizedState non-null (first render directly to fallback)\n * { left: true } \u2014 boundary just left fallback / revealed primary (non-null \u2192 null)\n * null \u2014 no state change (both null, both non-null, or first render not suspended)\n *\n * A Suspense that renders without delay never enters fallback, so memoizedState stays\n * null \u2192 returns null \u2192 correctly ignored by the detector.\n */\nexport function didSuspenseStateChange(\n fiber: Fiber\n): { entered: boolean; left: boolean } | null {\n const currSuspended = fiber.memoizedState !== null;\n\n if (!fiber.alternate) {\n // First render of this Suspense boundary.\n // If it went directly to fallback (memoizedState non-null), that IS an enter.\n // If it rendered primary content (memoizedState null), no transition.\n if (currSuspended) {\n return { entered: true, left: false };\n }\n return null;\n }\n\n const prevSuspended = fiber.alternate.memoizedState !== null;\n if (prevSuspended === currSuspended) return null;\n return { entered: currSuspended, left: prevSuspended };\n}\n\n/**\n * Check if a Context Provider's value changed.\n */\nexport function didContextValueChange(fiber: Fiber): boolean {\n if (fiber.tag !== CONTEXT_PROVIDER_TAG || !fiber.alternate) return false;\n\n type FiberWithProps = Fiber & { memoizedProps?: { value?: unknown } };\n const alternateFiber: FiberWithProps = fiber.alternate;\n const currentFiber: FiberWithProps = fiber;\n\n const prevProps = alternateFiber.memoizedProps;\n const currentProps = currentFiber.memoizedProps;\n\n return prevProps && currentProps && !Object.is(prevProps.value, currentProps.value);\n}\n\n// Detect React built-in fiber types (Suspense/Offscreen/etc).\n// IMPORTANT: Do NOT use component names. User components can be named anything.\n// In React 18, built-ins like Suspense/Offscreen are represented as symbols.\nexport function isReactInternalComponentType(type: ComponentType): boolean {\n return typeof type === 'symbol';\n}\n\nexport function getComponentName(fiber: Fiber): string {\n type TypeWithName = {\n displayName?: string;\n name?: string;\n };\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const type = fiber.type as TypeWithName;\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const elementType = fiber.elementType as TypeWithName;\n const named = (\n type?.displayName ||\n type?.name ||\n elementType?.displayName ||\n elementType?.name\n );\n if (named) return named;\n const source = getFiberSourceCandidate(fiber);\n return (source && `<${source.fileName}:${source.lineNumber}>`) || 'Anonymous';\n}\n\n/**\n * Check if hook is a state hook (useState/useReducer/useSyncExternalStore).\n *\n * All hooks share a base shape. The reliable differentiators:\n * - useState/useReducer: queue.dispatch is a function\n * - useSyncExternalStore: queue has 'value' and 'getSnapshot' properties\n */\nexport function isStateHook(hook: Hook): boolean {\n const queue = hook.queue;\n if (!queue) return false;\n\n return typeof queue.dispatch === 'function' || ('value' in queue && 'getSnapshot' in queue);\n}\n\n/** True if the hook is a useSyncExternalStore-like hook. */\nexport function isExternalStoreHook(hook: Hook): boolean {\n const queue = hook.queue;\n return (\n queue && typeof queue.dispatch !== 'function' && 'value' in queue && 'getSnapshot' in queue\n );\n}\n\n/**\n * Compare hook chains to detect state changes.\n *\n * IMPORTANT: Hook indices are React internal memoizedState indices, NOT code order.\n * `useContext` hooks are not in memoizedState, causing index misalignment.\n */\nexport function detectHookStateChanges(\n prevHookChain: Hook | null,\n currentHookChain: Hook | null\n): StateChangeResult {\n if (prevHookChain === currentHookChain) {\n return {\n hasChange: false,\n actionable: false,\n changedIndices: [],\n changedHooks: [],\n hasExternalStoreChange: false,\n };\n }\n\n let prevHook = prevHookChain;\n let currentHook = currentHookChain;\n let memoizedStateIndex = 0;\n const changedIndices: number[] = [];\n const changedHooks: ChangedHook[] = [];\n let hasExternalStoreChange = false;\n\n while (prevHook && currentHook) {\n if (isStateHook(currentHook)) {\n const prevValueRaw =\n prevHook.memoizedState === undefined\n ? prevHook.queue?.lastRenderedState\n : prevHook.memoizedState;\n const curValueRaw =\n currentHook.memoizedState === undefined\n ? currentHook.queue?.lastRenderedState\n : currentHook.memoizedState;\n\n if (!Object.is(prevValueRaw, curValueRaw)) {\n const isExternal = isExternalStoreHook(currentHook);\n if (isExternal) hasExternalStoreChange = true;\n\n changedIndices.push(memoizedStateIndex);\n changedHooks.push({\n prevValue: prevValueRaw,\n currentValue: curValueRaw,\n ...(isExternal && { isExternalStore: true }),\n });\n }\n }\n\n prevHook = prevHook.next;\n currentHook = currentHook.next;\n memoizedStateIndex++;\n }\n\n return {\n hasChange: changedIndices.length > 0,\n actionable: changedIndices.length > 0,\n changedIndices,\n changedHooks,\n hasExternalStoreChange,\n };\n}\n\n/**\n * Detect thrashing for hooks with deps: useEffect/useLayoutEffect/useInsertionEffect,\n * useCallback and useMemo.\n */\nexport function detectHookThrashing(\n prevHookChain: Hook | null,\n currentHookChain: Hook | null,\n mode: 'non-primitive' | 'all' = 'non-primitive',\n valueProvenance: WeakMap<object | Function, DepOrigin> | null = null\n): ThrashingResult {\n if (prevHookChain === currentHookChain) {\n return { effects: [], callbacks: [], memos: [] };\n }\n\n const thrashedEffects: ThrashInfo[] = [];\n const thrashedCallbacks: ThrashInfo[] = [];\n const thrashedMemos: ThrashInfo[] = [];\n\n let prevHook = prevHookChain;\n let currentHook = currentHookChain;\n let hookIndex = 0;\n\n while (prevHook && currentHook) {\n if (!isStateHook(currentHook)) {\n const prevValue = prevHook.memoizedState;\n const currentValue = currentHook.memoizedState;\n\n let prevDeps: unknown[] | null = null;\n let currentDeps: unknown[] | null = null;\n let hookType: ThrashInfo['hookType'] | null = null;\n\n // Effect hooks store an object with `deps`.\n if (\n prevValue &&\n currentValue &&\n typeof prevValue === 'object' &&\n typeof currentValue === 'object' &&\n 'deps' in prevValue &&\n 'deps' in currentValue &&\n 'tag' in currentValue\n ) {\n type EffectHook = { deps: unknown[] };\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n prevDeps = (prevValue as EffectHook).deps;\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n currentDeps = (currentValue as EffectHook).deps;\n hookType = 'effect';\n }\n // useMemo/useCallback store [result, deps].\n else if (\n Array.isArray(prevValue) &&\n Array.isArray(currentValue) &&\n prevValue.length === 2 &&\n currentValue.length === 2 &&\n Array.isArray(prevValue[1]) &&\n Array.isArray(currentValue[1])\n ) {\n prevDeps = prevValue[1];\n currentDeps = currentValue[1];\n hookType = typeof currentValue[0] === 'function' ? 'callback' : 'memo';\n }\n\n if (hookType && Array.isArray(prevDeps) && Array.isArray(currentDeps)) {\n const changedDepIndices: number[] = [];\n const changedDepOrigins: (DepOrigin | null)[] = [];\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n for (let j = 0; j < currentDeps.length; j++) {\n if (!Object.is(prevDeps[j], currentDeps[j])) {\n changedDepIndices.push(j);\n\n let origin: DepOrigin | null = null;\n const dep = currentDeps[j];\n if (\n valueProvenance &&\n dep != null &&\n (typeof dep === 'object' || typeof dep === 'function')\n ) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n origin = valueProvenance.get(dep as object | ((...args: never[]) => unknown)) || null;\n }\n changedDepOrigins.push(origin);\n }\n }\n\n let shouldReport = changedDepIndices.length > 0;\n if (shouldReport && mode === 'non-primitive') {\n // Only report if at least one non-primitive dep changed.\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n shouldReport = changedDepIndices.some((idx) => {\n const dep = currentDeps[idx];\n const t = typeof dep;\n return !(\n dep == null ||\n t === 'string' ||\n t === 'number' ||\n t === 'boolean' ||\n t === 'symbol' ||\n t === 'bigint'\n );\n });\n }\n\n if (shouldReport) {\n const thrashInfo: ThrashInfo = {\n hookIndex,\n hookType,\n deps: currentDeps,\n changedDepIndices,\n changedDepOrigins,\n };\n\n if (hookType === 'effect') {\n type EffectValue = { tag?: number; create?: Function };\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const effectValue = currentValue as EffectValue;\n thrashInfo.effectTag = effectValue.tag;\n // Capture the effect function itself (the create function)\n if (effectValue.create) {\n thrashInfo.hookBody = effectValue.create;\n }\n thrashedEffects.push(thrashInfo);\n } else if (hookType === 'callback') {\n type CallbackValue = [Function, unknown[]];\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const callbackFn = (currentValue as CallbackValue)[0];\n // Capture the callback function itself\n thrashInfo.hookBody = callbackFn;\n thrashedCallbacks.push(thrashInfo);\n } else {\n type MemoValue = [unknown, unknown[]];\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const memoValue = (currentValue as MemoValue)[0];\n thrashInfo.memoValue = memoValue;\n // For useMemo, also expose the memoized value as hookBody\n thrashInfo.hookBody = memoValue;\n thrashedMemos.push(thrashInfo);\n }\n }\n }\n }\n\n prevHook = prevHook.next;\n currentHook = currentHook.next;\n hookIndex++;\n }\n\n return {\n effects: thrashedEffects,\n callbacks: thrashedCallbacks,\n memos: thrashedMemos,\n };\n}\n\nexport function didFiberUpdate(fiber: Fiber): boolean {\n // eslint-disable-next-line no-bitwise\n return (fiber.flags & PerformedWork) !== 0;\n}\n\n/**\n * Detect if fiber has actionable hook state changes by comparing with fiber.alternate.\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \u26A0\uFE0F WARNING: fiber.alternate COMPARISON IS UNRELIABLE \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * This function compares fiber.memoizedState vs fiber.alternate.memoizedState.\n *\n * THE PROBLEM:\n * fiber.alternate is NOT always \"state from the previous commit\".\n * It's \"state from last time this fiber was used as work-in-progress\".\n *\n * If a component re-renders due to parent/context changes (not self-update),\n * its alternate may be stale - from 1 commit ago, or 100 commits ago!\n *\n * This causes FALSE POSITIVES: we detect \"state changed\" when it didn't\n * change in THIS commit - it changed in some PAST commit.\n *\n * WHEN THIS FUNCTION IS RELIABLE:\n * \u2713 Component called setState (it IS the initiator)\n * \u2713 Component has useSyncExternalStore that just triggered\n * \u2713 Used alongside memoizedUpdaters validation\n *\n * WHEN THIS FUNCTION IS UNRELIABLE:\n * \u2717 Component re-rendered due to parent update\n * \u2717 Component re-rendered due to context change\n * \u2717 Component was memoized and skipped N commits\n * \u2717 Any scenario where alternate wasn't recently updated\n *\n * RECOMMENDED USAGE:\n * - In development: Use memoizedUpdaters to verify component is an initiator,\n * THEN use this function to get hook change details.\n * - In production: Use lastSeenHookState tracking (see detector.tsx)\n * instead of relying on fiber.alternate.\n *\n * See detector.tsx for the full explanation of the \"swap\" problem and solution.\n */\nexport function didFiberSelfUpdate(fiber: Fiber): StateChangeResult | null {\n // Early exit: only check fibers that actually rendered (have PerformedWork flag)\n if (!didFiberUpdate(fiber)) return null;\n\n const alt = fiber.alternate;\n if (!alt) return null;\n\n const prevState = alt.memoizedState;\n const currentState = fiber.memoizedState;\n\n const result = detectHookStateChanges(prevState, currentState);\n return result.hasChange ? result : null;\n}\n\nexport function isDevelopment(): boolean {\n return process.env.NODE_ENV !== 'production';\n}\n", "/**\n * Named constants for CommitStats tuple indices.\n *\n * CommitStats is a fixed 10-position tuple per commit. This module provides\n * human-readable names for each index to replace magic numbers in code.\n *\n * Tuple structure:\n * [0] collateral \u2014 total updates caused by this source (collateral damage)\n * [1] sources \u2014 number of distinct sources that fired in this commit\n * [2] restarts \u2014 render count from ATL render-counter delta (or 0 if not available)\n * [3] performedWork \u2014 components with PerformedWork flag set\n * [4] effects \u2014 effect count\n * [5] memos \u2014 memo count\n * [6] callbacks \u2014 callback count\n * [7] contextUpdates \u2014 context update count\n * [8] unmountedComponents \u2014 number of unmounted components\n * [9] unmountedSubtrees \u2014 number of unmounted subtrees\n *\n * This positional layout is shared by the detector, serializer, bridge, and\n * offline readers. Changing an index is a wire-format change even though the\n * tuple remains valid TypeScript, so keep the names and length together.\n */\n\nexport const CS_COLLATERAL = 0;\nexport const CS_SOURCES = 1;\nexport const CS_RESTARTS = 2;\nexport const CS_PERFORMED_WORK = 3;\nexport const CS_EFFECTS = 4;\nexport const CS_MEMOS = 5;\nexport const CS_CALLBACKS = 6;\nexport const CS_CONTEXT_UPDATES = 7;\nexport const CS_UNMOUNTED_COMPONENTS = 8;\nexport const CS_UNMOUNTED_SUBTREES = 9;\n\n/**\n * Total length of the CommitStats tuple.\n * Used for validation and bounds checking.\n */\nexport const COMMIT_STATS_LENGTH = 10;\n\n/**\n * Array of all commitStats indices for iteration/validation.\n */\nexport const ALL_COMMIT_STATS_INDICES = [\n CS_COLLATERAL,\n CS_SOURCES,\n CS_RESTARTS,\n CS_PERFORMED_WORK,\n CS_EFFECTS,\n CS_MEMOS,\n CS_CALLBACKS,\n CS_CONTEXT_UPDATES,\n CS_UNMOUNTED_COMPONENTS,\n CS_UNMOUNTED_SUBTREES,\n] as const;\n", "/**\n * Report Serializer - Converts Report to serializable DTO.\n *\n * PROBLEM:\n * The Report interface contains non-serializable data (Fiber references, ComponentType functions)\n * which makes it unsuitable for JSON.stringify(), IPC, or network transmission.\n *\n * SOLUTION:\n * Strip non-serializable fields (fiber, type). Keep only what's needed:\n * - sourceId already contains component name (e.g., \"MyComponent#1@5\")\n * - Metrics and numerical data\n * - No need to convert anything - just omit problematic fields\n *\n * USAGE:\n * ```typescript\n * const report = detector.report(50);\n * const dto = serializeReport(report);\n *\n * // Now safe to serialize\n * const json = JSON.stringify(dto);\n *\n * // Send over IPC/network\n * postMessage({ type: 'report', data: dto });\n * ```\n *\n * DESIGN:\n * - Minimal DTO - only what you need for metrics/analysis\n * - sourceId already has component name - no conversion needed\n * - Drop fiber and type fields completely\n *\n * The serializer is also the trust boundary between page-side React objects\n * and helper/offline consumers. A DTO must remain stable after the page is\n * gone, so it carries evidence and summaries rather than live object identity.\n */\n\nimport type { CommitMetricsDelta, IntegrationMode } from './commit-metrics-adapter';\n\n// ============================================================================\n// DTO TYPES (Serializable - no function refs, no Fiber refs)\n// ============================================================================\n\n/**\n * Commit stats tuple: [collateral, sources, restarts, performedWork, effects, memos, callbacks,\n * contextUpdates, unmountedComponents, unmountedSubtrees]. Mirrors CommitStats in reporter.tsx.\n */\nexport type CommitStatsDTO = [\n collateral: number,\n sources: number,\n restarts: number,\n performedWork: number,\n effects: number,\n memos: number,\n callbacks: number,\n contextUpdates: number,\n unmountedComponents: number,\n unmountedSubtrees: number,\n];\n\n/**\n * Per-commit counter deltas from the commit metrics adapter, keyed by counter\n * name. The counters depend on the adapter (see `meta.metricsAdapter`).\n */\nexport type CommitMetricsDeltaDTO = CommitMetricsDelta;\n\n/** @deprecated Use CommitMetricsDeltaDTO. Kept for one release. */\nexport type ATLCommitDeltaDTO = CommitMetricsDeltaDTO;\n\n/**\n * Commit timing data - measures React commit duration and detector overhead.\n */\nexport interface CommitTimingDTO {\n timeSinceLastCommit: number;\n detectorOverhead: number;\n}\n\n/**\n * Report metadata - profiling context and overhead metrics.\n */\nexport interface ReportMetaDTO {\n version: number;\n commits: number;\n config: {\n detectionLevel: 'stats' | 'sources' | 'amplifierMetrics' | 'amplifiers' | 'full';\n effectThrashMode: 'non-primitive' | 'all';\n captureFibers: boolean;\n historySize: number;\n };\n memoizedUpdatersSupport: {\n available: boolean;\n commitsWithData: number;\n coverage: string;\n };\n /** Commit-hook integration model; older reports used `'atl'` for `'adapter:atl'`. */\n integrationMode?: IntegrationMode | 'atl';\n /** Id of the commit metrics adapter that drove the report, or null. */\n metricsAdapter?: string | null;\n /** Per-field availability for commitStats indices and metricsByCommit. */\n dataAvailability?: Record<string, boolean>;\n amplifiersMetrics?: {\n totalHookThrashes: number;\n affectedComponentCount: number;\n };\n timing: {\n totalDetectorOverhead: number;\n avgDetectorOverhead: number;\n totalTimeSpan: number;\n avgTimeBetweenCommits: number;\n };\n}\n\n/**\n * Minimal serializable source - just the metrics, no functions/fibers.\n * sourceId already contains component name (e.g., \"MyComponent#1@5\")\n */\nexport interface SourceDTO {\n sourceId: string;\n depth: number;\n collateralUpdates: number;\n maxCollateralUpdates: number;\n maxPenetrationDepth: number;\n causedUpdates: number;\n restartWaste?: number;\n maxRestartWaste?: number;\n}\n\n/**\n * Source entry in sourcesByCommit - which sources fired in each commit.\n */\nexport interface SourceByCommitDTO {\n sourceId: string;\n depth: number;\n collateral: number;\n rank: number | null;\n sourceIndex: number | null;\n trashers?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n isRepeat?: boolean;\n}\n\n/**\n * Serializable Report - minimal data for metrics and analysis.\n * All non-serializable fields (fiber, type) are omitted.\n */\nexport interface SuspenseBoundaryEventDTO {\n depth: number;\n entered: boolean;\n left: boolean;\n}\n\nexport interface UnmountSampleDTO {\n name: string;\n key: string | null;\n depth: number | null;\n count: number;\n source?: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n}\n\nexport type PropChangeKindDTO = 'same' | 'ref-changed' | 'scalar-changed' | 'added' | 'removed';\n\nexport interface PropValueSummaryDTO {\n type: string;\n isArray: boolean;\n isFunction: boolean;\n isNull: boolean;\n preview: string;\n display?: string;\n length?: number;\n keysTop?: string[];\n sample?: unknown[];\n}\n\nexport interface PropChangeEvidenceDTO {\n name: string;\n kind: PropChangeKindDTO;\n prev: PropValueSummaryDTO;\n current: PropValueSummaryDTO;\n}\n\nexport interface RenderedComponentEvidenceDTO {\n sourceId: string;\n name: string;\n depth: number;\n parentSourceId: string | null;\n ownerSourceId: string | null;\n isSelfSource: boolean;\n propChanges: PropChangeEvidenceDTO[];\n hasPropChanges: boolean;\n trasherCounts: { effects: number; callbacks: number; memos: number };\n}\n\nexport interface CommitInteractionActionDTO {\n id: number;\n lastCommitId: number;\n deltaTime: number;\n action: string;\n location: {\n dom: {\n tag: string | null;\n text: string;\n nearestTestId: string | null;\n };\n targetFiber: {\n name: string | null;\n key: string | null;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n ownerStackKind: 'owners' | 'parents';\n ownerStack: Array<{\n name: string | null;\n key: string | null;\n props: string[];\n hookCount: number;\n hookCountTruncated: boolean;\n hookCountMax: number;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n }>;\n } | null;\n };\n}\n\nexport interface ReportDTO {\n meta: ReportMetaDTO;\n sources: SourceDTO[];\n commitStats: Record<number, CommitStatsDTO>;\n suspenseByCommit: Record<number, SuspenseBoundaryEventDTO[]>;\n sourcesByCommit?: Record<number, SourceByCommitDTO[]>;\n interactionsByCommit?: Record<number, CommitInteractionActionDTO[]>;\n renderedByCommit?: Record<number, RenderedComponentEvidenceDTO[]>;\n metricsByCommit?: Record<number, CommitMetricsDeltaDTO>;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit?: Record<number, CommitMetricsDeltaDTO>;\n timing?: Record<number, CommitTimingDTO>;\n}\n\n// ============================================================================\n// SERIALIZATION FUNCTION\n// ============================================================================\n\n/**\n * Convert Report to serializable DTO.\n *\n * Strips non-serializable fields (fiber, type) and keeps only essential metrics.\n *\n * @param report - Full Report from detector.report()\n * @returns Minimal serializable ReportDTO safe for JSON.stringify()\n */\nexport function serializeReport(report: {\n meta: ReportMetaDTO;\n sources: Array<{\n sourceId: string;\n depth: number;\n causedUpdates: number;\n collateralUpdates: number;\n maxCollateralUpdates: number;\n maxPenetrationDepth: number;\n restartWaste?: number;\n maxRestartWaste?: number;\n }>;\n commitStats: Record<number, CommitStatsDTO>;\n sourcesByCommit?: Record<\n number,\n Array<{\n sourceId: string;\n depth: number;\n collateral: number;\n rank: number | null;\n sourceIndex: number | null;\n hooks?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n trashers?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n isRepeat?: boolean;\n }>\n >;\n suspenseByCommit?: Record<number, Array<{ depth: number; entered: boolean; left: boolean; fiber?: unknown }>>;\n interactionsByCommit?: Record<number, CommitInteractionActionDTO[]>;\n renderedByCommit?: Record<number, RenderedComponentEvidenceDTO[]>;\n metricsByCommit?: Record<number, CommitMetricsDeltaDTO>;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit?: Record<number, CommitMetricsDeltaDTO>;\n timing?: Record<number, CommitTimingDTO>;\n}): ReportDTO {\n // Just extract the fields we need - no conversion necessary\n const sources: SourceDTO[] = report.sources.map((source) => ({\n sourceId: source.sourceId,\n depth: source.depth,\n causedUpdates: source.causedUpdates,\n collateralUpdates: source.collateralUpdates,\n maxCollateralUpdates: source.maxCollateralUpdates,\n maxPenetrationDepth: source.maxPenetrationDepth,\n ...(source.restartWaste !== undefined && { restartWaste: source.restartWaste }),\n ...(source.maxRestartWaste !== undefined && { maxRestartWaste: source.maxRestartWaste }),\n }));\n\n // Serialize sourcesByCommit (strip non-serializable type/fiber fields)\n const sourcesByCommit: Record<number, SourceByCommitDTO[]> | undefined = report.sourcesByCommit\n ? Object.fromEntries(\n Object.entries(report.sourcesByCommit).map(([commitId, commitSources]) => [\n commitId,\n commitSources.map((src) => ({\n sourceId: src.sourceId,\n depth: src.depth,\n collateral: src.collateral,\n rank: src.rank,\n sourceIndex: src.sourceIndex,\n ...((src.trashers || src.hooks) && { trashers: src.trashers || src.hooks }),\n ...(src.isRepeat && { isRepeat: true }),\n })),\n ])\n )\n : undefined;\n\n // Serialize suspenseByCommit \u2014 strip fiber refs (not serializable), keep scalar event fields\n const suspenseByCommit: Record<number, SuspenseBoundaryEventDTO[]> = {};\n if (report.suspenseByCommit) {\n for (const [k, evts] of Object.entries(report.suspenseByCommit)) {\n suspenseByCommit[Number(k)] = evts.map((e) => ({\n depth: e.depth,\n entered: e.entered,\n left: e.left,\n }));\n }\n }\n\n return {\n meta: report.meta,\n sources,\n commitStats: report.commitStats,\n suspenseByCommit,\n ...(sourcesByCommit && { sourcesByCommit }),\n ...(report.interactionsByCommit && { interactionsByCommit: report.interactionsByCommit }),\n ...(report.renderedByCommit && { renderedByCommit: report.renderedByCommit }),\n ...((report.metricsByCommit || report.atlByCommit) && {\n metricsByCommit: report.metricsByCommit || report.atlByCommit,\n atlByCommit: report.metricsByCommit || report.atlByCommit,\n }),\n ...(report.timing && { timing: report.timing }),\n };\n}\n", "/**\n * Commit metrics adapter: an optional per-commit counter source that sits next\n * to the DevTools fiber walk.\n *\n * The detector always captures commits through the DevTools hook. Some hosts\n * also run an instrumented react-dom that exposes render counters and calls a\n * commit callback of its own. An adapter wraps one such host surface: it seeds\n * and protects the surface, snapshots its counters, turns two snapshots into a\n * per-commit delta plus a restart count, and wires the host's commit callback\n * to the detector. Without an adapter the detector runs in `devtools` mode and\n * reports restarts as unavailable.\n *\n * One adapter is active at a time. Product adapters live in `src/plugins/`.\n */\n\nimport type { Fiber } from './internals';\n\nexport type CommitMetricsRoot = { current: Fiber; memoizedUpdaters?: Set<Fiber> };\n\n/** Raw counters read from the host surface at one point in time. */\nexport type CommitMetricsSnapshot = Record<string, unknown>;\n\n/** Counter deltas for one commit, keyed by counter name. */\nexport type CommitMetricsDelta = { [counter: string]: number | undefined };\n\nexport type CommitMetricsMeasurement = {\n delta: CommitMetricsDelta;\n /** Render passes React performed but did not commit. Never negative. */\n restarts: number;\n};\n\nexport interface CommitMetricsAdapter {\n /** Stable id; the detector reports `integrationMode: 'adapter:<id>'`. */\n readonly id: string;\n /**\n * Stack frame names the host surface adds to every render. Hook ancestry\n * hides them like other renderer internals.\n */\n readonly frameFilters?: readonly string[];\n /**\n * Setup that must run before React evaluates, such as installing an accessor\n * that survives host cleanup. Called by the extension's early bootstrap\n * through `__AVALANCHE__.runPrePageHooks(config)`.\n */\n prePage?(config: unknown): void;\n /** Seed the host surface before a detector installs, unless the host owns it. */\n prepare?(): void;\n /** Whether the host surface is present right now. */\n isAvailable(): boolean;\n snapshot(): CommitMetricsSnapshot | null;\n measure(\n before: CommitMetricsSnapshot,\n after: CommitMetricsSnapshot,\n committedComponents: number,\n commitId: number,\n ): CommitMetricsMeasurement;\n /**\n * Route the host's commit callback to `onCommit`. Returns false when the\n * surface is absent. A callback is proof that the host surface is live.\n */\n attach(onCommit: (root: CommitMetricsRoot) => void): boolean;\n /** True while the callback from attach() is still wired into the live surface. */\n isAttached(): boolean;\n /** Re-seed and re-wire after the host wiped or replaced its surface. */\n reattach(): void;\n /** Remove the callback from attach(), only if it is still ours. */\n detach(): void;\n}\n\nlet active: CommitMetricsAdapter | null = null;\n\nconst REQUIRED_METHODS = ['isAvailable', 'snapshot', 'measure', 'attach', 'isAttached', 'reattach', 'detach'] as const;\n\n/**\n * Make `adapter` the active commit metrics adapter for detectors installed\n * afterwards. Replaces any earlier adapter. Returns an unregister function.\n */\nexport function registerCommitMetricsAdapter(adapter: CommitMetricsAdapter): () => void {\n if (!adapter || typeof adapter.id !== 'string' || !adapter.id) {\n throw new TypeError('registerCommitMetricsAdapter expects an adapter with a non-empty id');\n }\n for (const method of REQUIRED_METHODS) {\n if (typeof adapter[method] !== 'function') {\n throw new TypeError(`commit metrics adapter ${adapter.id} is missing ${method}()`);\n }\n }\n active = adapter;\n return () => {\n if (active === adapter) active = null;\n };\n}\n\nexport function getCommitMetricsAdapter(): CommitMetricsAdapter | null {\n return active;\n}\n\n/**\n * Run the active adapter's pre-page hook. Returns the adapter id when a hook\n * ran, or null. A failing hook is swallowed: the detector falls back to\n * DevTools capture.\n */\nexport function runPrePageHooks(config?: unknown): string | null {\n const adapter = active;\n if (!adapter || typeof adapter.prePage !== 'function') return null;\n try {\n adapter.prePage(config);\n return adapter.id;\n } catch {\n return null;\n }\n}\n\nexport type IntegrationMode = `adapter:${string}` | 'devtools' | 'none';\n\nexport function adapterIdFromMode(mode: IntegrationMode | string | null | undefined): string | null {\n return typeof mode === 'string' && mode.startsWith('adapter:') ? mode.slice('adapter:'.length) : null;\n}\n", "/**\n * Projects the detector's live fiber history into ranked evidence and the\n * serializable report consumed by bridge commands and offline analysis. The\n * detector owns capture-time truth; this layer owns interpretation and output\n * ordering, so presentation changes do not alter hot-path collection.\n */\n\nimport type { ComponentType, ChangedHook, Fiber, ThrashInfo } from './internals';\nimport { CS_RESTARTS } from './commit-stats-indices';\nimport { getComponentName } from './internals';\nimport type { ReportDTO } from './report-serializer';\nimport { serializeReport } from './report-serializer';\nimport {\n type CommitMetricsAdapter,\n type CommitMetricsDelta,\n type CommitMetricsSnapshot,\n type IntegrationMode,\n adapterIdFromMode,\n} from './commit-metrics-adapter';\n\nexport type SortBy = 'effect' | 'callback' | 'memo' | 'total';\n\nexport interface Source {\n sourceId: string; // Human-readable ID (e.g., \"Counter#1@3\" in dev, \"Unknown#1@3\" in prod)\n type: ComponentType;\n depth: number;\n renderCount: number;\n causedUpdates: number;\n collateralUpdates: number;\n maxCollateralUpdates: number;\n maxPenetrationDepth: number; // Relative to source depth (how deep the avalanche went)\n updateHistory: Record<number, Record<number, ChangedHook> | 'repeat' | string>;\n collateralByCommit: Record<number, number>; // Per-commit collateral for this source\n fiber?: Fiber;\n /** Changed hook indices from this source's latest self-update; maps debugHook indices to debug-render events. */\n debugHookIndices?: number[];\n\n /**\n * RESTART WASTE TRACKING - identifies sources contributing to restart waste\n *\n * Restarts = wasted renders (component rendered but work was discarded)\n * Attribution: proportional to sources that fired in each commit with restarts\n *\n * Example: Commit has 1000 restarts, 2 sources fire\n * \u2192 Each source attributed 500 restarts\n *\n * High restartWaste = this source triggers commits that cause React to restart work\n */\n restartWaste?: number; // Total restarts attributed to this source across all commits\n maxRestartWaste?: number; // Max restarts in a single commit\n restartWasteByCommit?: Record<number, number>; // Per-commit restart waste for this source\n\n /**\n * Components that were amplified when this source triggered them.\n * These are components that re-rendered with unstable hooks (effects, callbacks, memos).\n * Includes both:\n * - This source itself (if it has unstable hooks)\n * - Descendant components that re-rendered with unstable hooks\n */\n amplified?: Array<{\n /** Component that amplified work */\n sourceId: string;\n type: ComponentType;\n depth: number;\n /** Total effect amplifications across all commits */\n effectCount: number;\n /** Total callback amplifications across all commits */\n callbackCount: number;\n /** Total memo amplifications across all commits */\n memoCount: number;\n /** Total hook amplifications (effect + callback + memo) */\n hooksTotal: number;\n /** Commits where this component amplified work */\n commitIds: number[];\n /** Per-commit breakdown: { commitId: { effects, callbacks, memos } } */\n byCommit: Record<number, { effects: number; callbacks: number; memos: number }>;\n /** Latest amplification details */\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n }>;\n}\n\nexport interface Amplifier {\n type: ComponentType;\n renderCount: number;\n instancesTotal: number;\n maxInstancesPerCommit: number;\n hooksTotal: number;\n maxHooksPerCommit: number;\n effectCount: number;\n callbackCount: number;\n memoCount: number;\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n}\n\n/**\n * Linked thrasher - connects thrashing info to source identity.\n *\n * This enables:\n * - thrasher.sourceId \u2192 navigate to source\n * - thrasher.isSource \u2192 prioritize fixes (source+thrasher = high impact)\n * - thrasher.commitIds \u2192 correlate with commitStats\n * - source.thrashing \u2192 see hook instability for a source\n */\nexport interface AmplifierSource {\n /** Human-readable ID (e.g., \"Counter#1@5\" in dev, \"Unknown#1@5\" in prod) */\n sourceId: string;\n /** Component type (function reference) */\n type: ComponentType;\n /** Depth in component tree */\n depth: number;\n\n /** Collateral damage caused by this source (0 if not tracked) */\n collateralUpdates: number;\n\n /** Total effect amplifications across all commits */\n effectCount: number;\n /** Total callback amplifications across all commits */\n callbackCount: number;\n /** Total memo amplifications across all commits */\n memoCount: number;\n /** Total hook amplifications (effect + callback + memo) */\n hooksTotal: number;\n\n /** Commits where this component amplified work */\n commitIds: number[];\n /** Per-commit breakdown: { commitId: { effects, callbacks, memos } } */\n byCommit: Record<number, { effects: number; callbacks: number; memos: number }>;\n\n /** If not a source, which sourceId caused this to re-render? */\n causedBySourceId: string | null;\n\n /** Latest amplification details */\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n}\n\n/**\n * Commit stats tuple: [collateral, sources, restarts, performedWork, effects, memos, callbacks, contextUpdates, unmountedComponents, unmountedSubtrees]\n * Use these numbers to find which commits to investigate in DevTools.\n * - collateral: components re-rendered as victims\n * - sources: components that initiated updates (update sources)\n * - restarts: extra renders due to external store mutations, priority changes, etc.\n * - performedWork: components with PerformedWork flag (actual work React processed)\n * - effects/memos/callbacks: thrashing hooks (effects likely cause next commit!)\n * - contextUpdates: number of Context Providers whose value changed this commit\n * - unmountedComponents: total component fibers unmounted this commit\n * - unmountedSubtrees: number of distinct unmount \"branch starts\" (topmost deleted components)\n */\nexport type CommitStats = [\n collateral: number,\n sources: number,\n restarts: number,\n performedWork: number,\n effects: number,\n memos: number,\n callbacks: number,\n contextUpdates: number,\n unmountedComponents: number,\n unmountedSubtrees: number,\n];\n\n/**\n * Human-readable keys for CommitStats tuple positions.\n * Use with commitStats[commit][commitStatsKeys.collateral]\n */\nexport const commitStatsKeys = {\n collateral: 0,\n sources: 1,\n restarts: 2,\n performedWork: 3,\n effects: 4,\n memos: 5,\n callbacks: 6,\n contextUpdates: 7,\n unmountedComponents: 8,\n unmountedSubtrees: 9,\n} as const;\n\n/**\n * Report metadata - profiling context and overhead metrics.\n */\nexport interface ReportMeta {\n /** Report format version - increment when changing data structure */\n version: number;\n /** Total commits processed */\n commits: number;\n /** Detector configuration used during profiling */\n config: {\n /** Detection level: 'stats' (minimal), 'sources', 'amplifiers', or 'full' */\n detectionLevel: DetectionLevel;\n /** Effect thrashing sensitivity: 'non-primitive' or 'all' */\n effectThrashMode: 'non-primitive' | 'all';\n /** Whether fibers were captured (for debugging) */\n captureFibers: boolean;\n /** Update history size per source */\n historySize: number;\n };\n /** memoizedUpdaters availability and coverage */\n memoizedUpdatersSupport: {\n available: boolean;\n commitsWithData: number;\n coverage: string;\n };\n /**\n * Which commit-hook integration model produced this report. Determines what\n * is reliably present in `commitStats[N]` and `metricsByCommit[N]`.\n *\n * 'adapter:<id>' \u2014 A commit metrics adapter (for example `adapter:atl`) drove\n * the commit callback with host render counters. ALL fields below\n * are populated and `metricsByCommit` is present.\n * 'devtools' \u2014 Reconstructed entirely from the React DevTools commit hook\n * (fiber walk only). The fiber-walk fields are real measurements:\n * collateral, sources, performedWork, effects, memos, callbacks,\n * contextUpdates. The render-counter math (restarts) is NOT\n * available \u2014 `commitStats[N][2]` will be 0 (semantically\n * \"unknown / not measurable in this mode\") and `metricsByCommit`\n * is empty. This is normal on stock react-dom.\n * 'none' \u2014 Detector wasn't installed when this report was generated.\n *\n * Reports before the adapter seam used `'atl'` for `'adapter:atl'`.\n */\n integrationMode: IntegrationMode;\n /** Id of the commit metrics adapter that drove this report, or null. */\n metricsAdapter: string | null;\n /**\n * Per-field availability map for `commitStats[N]` indices. `false` means the\n * value is a placeholder (typically 0) that consumers should treat as unknown\n * rather than a real measurement of zero.\n *\n * Stable across all commits in a given report \u2014 set once from integrationMode.\n */\n dataAvailability: {\n /** [0] perCommit.totalCollateral \u2014 reconstructed from fiber walk */\n collateral: boolean;\n /** [1] perCommit.selfUpdated.size \u2014 reconstructed from fiber walk */\n sources: boolean;\n /** [2] derived from the adapter's render-counter delta \u2014 only in 'adapter:<id>' mode */\n restarts: boolean;\n /** [3] perCommit.committedComponentCount \u2014 reconstructed from fiber walk */\n performedWork: boolean;\n /** [4] perCommit.effectCount \u2014 reconstructed from fiber walk */\n effects: boolean;\n /** [5] perCommit.memoCount \u2014 reconstructed from fiber walk */\n memos: boolean;\n /** [6] perCommit.callbackCount \u2014 reconstructed from fiber walk */\n callbacks: boolean;\n /** [7] perCommit.contextUpdates \u2014 reconstructed from fiber walk */\n contextUpdates: boolean;\n /** Adapter counters in metricsByCommit \u2014 only in 'adapter:<id>' mode */\n metricsByCommit: boolean;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit: boolean;\n };\n /** Amplifier summary (when detectionMode: 'amplifierMetrics') */\n amplifiersMetrics?: {\n totalHookThrashes: number;\n affectedComponentCount: number;\n };\n /**\n * Timing summary - shows detector overhead and commit durations.\n * Use this to justify avalanche-detector overhead in production.\n */\n timing: {\n /** Total time spent in detector across all commits (ms) */\n totalDetectorOverhead: number;\n /** Average detector overhead per commit (ms) */\n avgDetectorOverhead: number;\n /** Total time from first to last commit (ms) */\n totalTimeSpan: number;\n /** Average time between commits (ms) */\n avgTimeBetweenCommits: number;\n };\n}\n\nexport interface HostUnmountSummary {\n elements: number;\n text: number;\n tagsTop: Array<[string, number]>;\n testIdsTop: Array<[string, number]>;\n rolesTop: Array<[string, number]>;\n ariaLabels: string[];\n textHints: string[];\n}\n\nexport interface UnmountSample {\n name: string;\n key: string | null;\n depth: number | null;\n count: number;\n source?: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n host?: HostUnmountSummary;\n}\n\nexport type InteractionCaptureLevel = 'off' | 'explicit' | 'noisy' | 'all';\n\nexport interface InteractionActionLocation {\n dom: {\n tag: string | null;\n text: string;\n nearestTestId: string | null;\n };\n targetFiber: {\n name: string | null;\n key: string | null;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n ownerStackKind: 'owners' | 'parents';\n ownerStack: Array<{\n name: string | null;\n key: string | null;\n props: string[];\n hookCount: number;\n hookCountTruncated: boolean;\n hookCountMax: number;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n }>;\n } | null;\n}\n\nexport interface InteractionAction {\n /** Sequential action id within this detector capture. */\n id: number;\n /** Native event name, e.g. click, keydown, wheel. */\n action: string;\n /** performance.now() at event capture time. Kept live-only; DTO emits deltaTime. */\n timestamp: number;\n /** DOM-grounded event target plus target component/ownership stack. */\n location: InteractionActionLocation;\n}\n\nexport type PropChangeKind = 'same' | 'ref-changed' | 'scalar-changed' | 'added' | 'removed';\n\nexport interface PropValueSummary {\n type: string;\n isArray: boolean;\n isFunction: boolean;\n isNull: boolean;\n preview: string;\n display?: string;\n length?: number;\n keysTop?: string[];\n sample?: unknown[];\n}\n\nexport interface PropChangeEvidence {\n name: string;\n kind: PropChangeKind;\n prev: PropValueSummary;\n current: PropValueSummary;\n}\n\nexport interface RenderedComponentEvidence {\n sourceId: string;\n name: string;\n depth: number;\n parentSourceId: string | null;\n ownerSourceId: string | null;\n isSelfSource: boolean;\n propChanges: PropChangeEvidence[];\n hasPropChanges: boolean;\n trasherCounts: { effects: number; callbacks: number; memos: number };\n}\n\nexport interface CommitInteractionAction {\n /** Original action id \u2014 must match InteractionAction.id for describe-action lookup. */\n id: number;\n /** Last commit id at the moment this action was observed. */\n lastCommitId: number;\n /** Milliseconds from action capture to the linked commit. */\n deltaTime: number;\n action: string;\n location: InteractionAction['location'];\n}\n\nexport interface Report {\n /** Metadata: version, counts, overhead metrics */\n meta: ReportMeta;\n /** Components that caused updates, sorted by collateral damage */\n sources: Source[];\n /** Bridge to DevTools - maps commit ID to sources that fired in that commit */\n sourcesByCommit: Record<\n number,\n Array<{\n sourceId: string;\n type: ComponentType;\n depth: number;\n /** Collateral damage caused by this source in THIS commit */\n collateral: number;\n /** Position in top N sources list (1-based), or null if not in top N */\n rank: number | null;\n /** Index into sources[] array for full accumulated data, or null if not in top N */\n sourceIndex: number | null;\n hooks?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n isRepeat?: boolean;\n }>\n >;\n /**\n * Per-commit metrics to find the needle: [collateral, effects, memos, callbacks]\n * High collateral = avalanche. High effects = likely causes next commit!\n */\n commitStats: Record<number, CommitStats>;\n /**\n * Per-commit timing data - correlate restarts with commit duration.\n * High commitStats[N].restarts + high commitTimings[N].timeSinceLastCommit = React wasted work.\n */\n commitTimings: Record<number, CommitTiming>;\n /**\n * Per-commit counter deltas from the commit metrics adapter - low-level React\n * work per commit. With the ATL adapter:\n * metricsByCommit[N].componentRenderWithHooksCount + finishClassComponentCount\n * should equal commitStats[N].collateral + commitStats[N].sources\n */\n metricsByCommit?: Record<number, CommitMetricsDelta>;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit?: Record<number, CommitMetricsDelta>;\n /** @deprecated Use amplifierSources instead for full source linkage */\n amplifiers?: Amplifier[];\n /**\n * Amplifier sources - components that amplified the update cost with hook re-executions.\n * Shows which components responded to updates with expensive work (effects, memos, callbacks).\n * Linked to the source that triggered them.\n */\n amplifierSources?: AmplifierSource[];\n /**\n * Per-commit Suspense boundary transitions.\n * Only populated for commits where at least one boundary entered or left fallback.\n * Empty object when no Suspense transitions occurred during the capture.\n */\n suspenseByCommit: Record<number, SuspenseBoundaryEvent[]>;\n\n /** Bounded samples of component subtrees unmounted per commit. */\n unmountsByCommit?: Record<number, UnmountSample[]>;\n\n /** Compact user/browser actions linked to nearby commits. */\n interactionsByCommit?: Record<number, CommitInteractionAction[]>;\n\n /** Structural evidence for each component that rendered in a commit. */\n renderedByCommit?: Record<number, RenderedComponentEvidence[]>;\n\n /**\n * Convert this report to a serializable DTO (safe for JSON.stringify, IPC, network).\n * Strips non-serializable fields like Fiber references and ComponentType functions.\n */\n toSerializable(): ReportDTO;\n}\n\nexport interface DetectorOptions {\n ignore?: ComponentType[];\n effectThrashMode?: 'non-primitive' | 'all';\n captureFibers?: boolean;\n /**\n * Detection mode - controls what the detector tracks (tiered for performance):\n *\n * Use DETECTION_LEVEL constants for clarity:\n * - DETECTION_LEVEL.LEVEL1_STATS ('stats'): Only commitStats, super fast\n * - DETECTION_LEVEL.LEVEL2_SOURCES ('sources'): + source tracking\n * - DETECTION_LEVEL.LEVEL3_AMPLIFIER_METRICS ('amplifierMetrics'): + aggregate amplifier counts only\n * - DETECTION_LEVEL.LEVEL3_AMPLIFIERS ('amplifiers'): + full amplifier arrays\n *\n * Shortcuts:\n * - false: Alias for 'stats' (minimal overhead)\n * - true: Alias for 'full' (maximum detail)\n *\n * Performance hierarchy (fastest to slowest):\n * stats < sources < amplifierMetrics < amplifiers \u2248 full\n */\n detectionMode?:\n | boolean\n | 'full'\n | 'amplifiers'\n | 'amplifierMetrics'\n | 'sources'\n | 'stats'\n | false;\n\n historySize?: number;\n\n /**\n * Browser action capture level. Defaults to 'explicit' to capture high-signal\n * actions (click/keyboard/input) while leaving noisy wheel/move capture opt-in.\n */\n interactionCapture?: InteractionCaptureLevel;\n\n /** Extra native event names to capture in addition to the selected level. */\n interactionEvents?: string[];\n\n /** Time window for linking captured actions to a commit, in ms. Default: 1000. */\n interactionWindowMs?: number;\n\n /**\n * Commit metrics adapter for host render counters. Defaults to the adapter\n * registered with `registerCommitMetricsAdapter` when the detector installs.\n * Pass `null` to run on the DevTools hook only.\n */\n metricsAdapter?: CommitMetricsAdapter | null;\n\n /** @deprecated Historical option used by older call sites. Prefer `detector.report(topN)` */\n topN?: number;\n}\n\nexport type ThrashMode = 'full' | 'counts' | false;\nexport type DetectionLevel = 'stats' | 'sources' | 'amplifierMetrics' | 'amplifiers' | 'full';\n\n/**\n * Internal amplifier source state - keyed by sourceId for navigation.\n */\nexport interface AmplifierSourceState {\n type: ComponentType;\n depth: number;\n effectCount: number;\n callbackCount: number;\n memoCount: number;\n hooksTotal: number;\n commitIds: number[];\n byCommit: Record<number, { effects: number; callbacks: number; memos: number }>;\n /** sourceId that caused this component to re-render (if not self-caused) */\n causedBySourceId: string | null;\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n}\n\n/**\n * Commit timing data - measures React commit duration and detector overhead.\n * All times in milliseconds.\n */\nexport interface CommitTiming {\n /** Time from previous commit end to this commit end (includes React work + idle time) */\n timeSinceLastCommit: number;\n /** Time spent in avalanche detector processing (our overhead) */\n detectorOverhead: number;\n}\n\n/**\n * Internal profiler state - tracks all avalanche detection data.\n *\n * This is the core state structure that accumulates across commits.\n * Most users should use the `Report` interface from `detector.report()` instead.\n */\nexport interface ProfilerState {\n /** Total commits processed since install() or reset() */\n commits: number;\n\n /**\n * All detected sources, keyed by stable source ID (e.g., \"Button#1@3\").\n * Source = component that caused an update (not just re-rendered).\n */\n sources: Map<string, Omit<Source, 'sourceId'>>;\n\n /** @deprecated Use amplifierSources instead */\n amplifiers: Map<ComponentType, Omit<Amplifier, 'type'>>;\n\n /**\n * Amplifier sources keyed by sourceId.\n * Enables source\u2194amplifier navigation and per-commit breakdown.\n */\n amplifierSources: Map<string, AmplifierSourceState>;\n\n /**\n * Aggregate thrashing counts (only if detectThrashing: 'counts').\n * Lightweight alternative to full thrashing analysis.\n */\n thrashCounts: null | { totalHooks: number; affectedComponents: Set<ComponentType> };\n\n /** Whether React DevTools hook exposes memoizedUpdaters (React 18.3.1+) */\n memoizedUpdatersAvailable: boolean;\n\n /** Number of commits where memoizedUpdaters data was present */\n commitsWithMemoizedUpdaters: number;\n\n /** Per-commit stats: [collateral, effects, memos, callbacks] */\n commitStats: Record<number, CommitStats>;\n\n /**\n * Per-commit counter deltas from the commit metrics adapter.\n * Enables full reconciliation with Avalanche counts.\n */\n metricsByCommit: Record<number, CommitMetricsDelta>;\n\n /** Last adapter snapshot (for delta calculation) */\n lastMetricsSnapshot: CommitMetricsSnapshot | null;\n\n /**\n * Per-commit timing data - measures commit duration and detector overhead.\n * Enables correlation: high restarts \u2192 longer commit times.\n */\n commitTimings: Record<number, CommitTiming>;\n\n /** Timestamp when last commit ended (for delta calculation) */\n lastCommitEndTime: number;\n\n /**\n * Per-commit Suspense boundary transitions.\n * Only populated for commits where at least one boundary entered or left fallback.\n */\n suspenseByCommit: Record<number, SuspenseBoundaryEvent[]>;\n\n /** Bounded samples of component subtrees unmounted per commit. */\n unmountsByCommit: Record<number, UnmountSample[]>;\n\n /** Recent action breadcrumbs captured from native events. */\n interactionActions: InteractionAction[];\n\n /** Compact user/browser actions linked to nearby commits. */\n interactionsByCommit: Record<number, CommitInteractionAction[]>;\n\n /** Structural evidence for each component that rendered in a commit. */\n renderedByCommit: Record<number, RenderedComponentEvidence[]>;\n}\n\nfunction isTrueSource(s: Source): boolean {\n const commits = Object.values(s.updateHistory);\n if (commits.length === 0) return false;\n\n // A source is \"true\" if ANY commit in the retained window has a concrete hook entry.\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n for (let i = 0; i < commits.length; i++) {\n const entry = commits[i];\n if (!entry || entry === 'repeat') {\n // Skip empty or repeat entries\n } else if (typeof entry === 'object' && entry !== null) {\n if (Object.values(entry).some((hook) => hook !== 'repeat')) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * A Suspense boundary state transition captured during a commit.\n * Only emitted when the boundary actually entered or left the fallback state.\n * Boundaries that render without delay (no fallback shown) produce no events.\n */\nexport interface SuspenseBoundaryEvent {\n /** Tree depth of the Suspense fiber */\n depth: number;\n /** true = boundary entered fallback (primary \u2192 suspended) */\n entered: boolean;\n /** true = boundary left fallback (suspended \u2192 primary revealed) */\n left: boolean;\n /** The Suspense fiber itself (only present when captureFibers is true) */\n fiber?: Fiber;\n}\n\nexport interface ReportOptions {\n /** Minimum collateral damage to include a source in sourcesByCommit (default: 0 - show all) */\n minCollateral?: number;\n}\n\nexport function buildReport(\n state: ProfilerState,\n thrashMode: ThrashMode,\n topN: number,\n sortBy: SortBy,\n options: ReportOptions = {},\n detectorConfig?: {\n effectThrashMode: 'non-primitive' | 'all';\n captureFibers: boolean;\n historySize: number;\n detectionLevel?: DetectionLevel;\n /**\n * Integration model that produced this report. Determines what's reliable\n * in commitStats and metricsByCommit. Defaults to 'none'.\n */\n integrationMode?: IntegrationMode;\n }\n): Report {\n const { minCollateral = 1 } = options;\n\n // Helper to generate human-readable sourceId from internal ID (e.g., \"T1#2@3\" -> \"Counter#2@3\")\n const toHumanReadableId = (internalId: string, type: ComponentType, depth: number): string => {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const componentName = getComponentName({ type } as Fiber);\n // Extract instance number from internal ID (e.g., \"T1#2@3\" -> \"2\")\n const match = internalId.match(/#(\\d+)@/);\n const instanceNum = match ? match[1] : '1';\n return `${componentName}#${instanceNum}@${depth}`;\n };\n\n // Map internal IDs to human-readable IDs for the report\n const idMapping = new Map<string, string>(); // internalId -> humanId\n\n // Build ALL sources first (for accurate sourcesByCommit)\n const allSources = Array.from(state.sources.entries())\n .map(([internalId, s]) => {\n const humanId = toHumanReadableId(internalId, s.type, s.depth);\n idMapping.set(internalId, humanId);\n\n return {\n sourceId: humanId,\n ...s,\n maxPenetrationDepth: Math.max(0, s.maxPenetrationDepth - s.depth), // Convert to relative depth (never negative!)\n // Initialize restart waste tracking\n restartWaste: 0,\n maxRestartWaste: 0,\n restartWasteByCommit: {},\n };\n })\n .filter(isTrueSource);\n\n // RESTART WASTE ATTRIBUTION\n // Distribute restarts proportionally to sources that fired in each commit\n // This identifies sources contributing to restart waste\n Object.entries(state.commitStats).forEach(([commitIdStr, stats]) => {\n const commitId = Number(commitIdStr);\n const restarts = stats[CS_RESTARTS]; // commitStats[CS_RESTARTS] = restart count\n\n if (restarts === 0) return;\n\n // Find all sources that fired in this commit\n const sourcesInCommit = allSources.filter(\n (source) => source.updateHistory[commitId] !== undefined\n );\n\n if (sourcesInCommit.length === 0) {\n // Ghost restarts (Suspense, priority interruption, external store)\n // No sources to attribute to - these are not directly caused by component updates\n return;\n }\n\n // Distribute restarts proportionally among sources\n const restartsPerSource = restarts / sourcesInCommit.length;\n\n // Mutate the source objects directly (they're from allSources array we own)\n for (const sourceItem of sourcesInCommit) {\n sourceItem.restartWaste += restartsPerSource;\n sourceItem.restartWasteByCommit[commitId] = restartsPerSource;\n\n if (restartsPerSource > sourceItem.maxRestartWaste) {\n sourceItem.maxRestartWaste = restartsPerSource;\n }\n }\n });\n\n // Build amplified array for each source (Direction 1: Source \u2192 Amplified components)\n if (thrashMode === 'full') {\n for (const sourceItem of allSources) {\n const amplifiedByThisSource: Source['amplified'] = [];\n\n // Find all components that were amplified when this source triggered them\n state.amplifierSources.forEach((amplifierData, amplifierInternalId) => {\n const amplifierHumanId =\n idMapping.get(amplifierInternalId) ||\n toHumanReadableId(amplifierInternalId, amplifierData.type, amplifierData.depth);\n\n // Check if this component was amplified by the current source\n // amplifierData.causedBySourceId is the INTERNAL id, need to convert to human id\n const causedByHumanId = amplifierData.causedBySourceId\n ? idMapping.get(amplifierData.causedBySourceId)\n : null;\n\n if (causedByHumanId === sourceItem.sourceId || amplifierHumanId === sourceItem.sourceId) {\n // This component was either:\n // 1. Amplified by this source (descendant with unstable hooks)\n // 2. IS this source (self-amplification - source has unstable hooks)\n amplifiedByThisSource.push({\n sourceId: amplifierHumanId,\n type: amplifierData.type,\n depth: amplifierData.depth,\n effectCount: amplifierData.effectCount,\n callbackCount: amplifierData.callbackCount,\n memoCount: amplifierData.memoCount,\n hooksTotal: amplifierData.hooksTotal,\n commitIds: amplifierData.commitIds,\n byCommit: amplifierData.byCommit,\n lastAmplification: amplifierData.lastAmplification,\n });\n }\n });\n\n if (amplifiedByThisSource.length > 0) {\n sourceItem.amplified = amplifiedByThisSource;\n }\n }\n }\n\n // Top N sources - update sources sorted by TOTAL WASTE (collateral + restarts)\n // This identifies the real offenders, including those causing restart waste\n const sources = [...allSources]\n .sort((a, b) => {\n const aTotalWaste = a.collateralUpdates + (a.restartWaste || 0);\n const bTotalWaste = b.collateralUpdates + (b.restartWaste || 0);\n return (\n bTotalWaste - aTotalWaste ||\n b.maxCollateralUpdates - a.maxCollateralUpdates ||\n (b.maxRestartWaste || 0) - (a.maxRestartWaste || 0)\n );\n })\n .slice(0, topN);\n\n const coverage =\n state.commits > 0\n ? Math.round((state.commitsWithMemoizedUpdaters / state.commits) * 100) + '%'\n : '0%';\n\n // Calculate timing summary\n const timingEntries = Object.values(state.commitTimings);\n const totalDetectorOverhead = timingEntries.reduce((sum, t) => sum + t.detectorOverhead, 0);\n const totalTimeSpan = timingEntries.reduce((sum, t) => sum + t.timeSinceLastCommit, 0);\n const avgDetectorOverhead =\n timingEntries.length > 0 ? totalDetectorOverhead / timingEntries.length : 0;\n const avgTimeBetweenCommits = timingEntries.length > 0 ? totalTimeSpan / timingEntries.length : 0;\n\n // Build lookup map for top N sources (sourceId \u2192 { rank, index })\n const topNLookup = new Map<string, { rank: number; index: number }>();\n for (let i = 0; i < sources.length; i++) {\n topNLookup.set(sources[i].sourceId, { rank: i + 1, index: i });\n }\n\n // Build sourcesByCommit from ALL sources (not just top N!)\n // This ensures commitStats[N].sources matches sourcesByCommit[N].length\n const sourcesByCommit: Report['sourcesByCommit'] = {};\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n allSources.forEach((source) => {\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n Object.entries(source.updateHistory).forEach(([commitIdStr, data]) => {\n const commitId = Number(commitIdStr);\n\n // Diagnostic strings like \"detector-only\" are not \"this source fired in this commit\".\n // They exist only to explain detector/React disagreement. Do not surface them in sourcesByCommit.\n if (typeof data === 'string' && data !== 'repeat') {\n return;\n }\n\n // Get per-commit collateral for this source\n const collateral = source.collateralByCommit?.[commitId] ?? 0;\n\n // Skip sources below minCollateral threshold\n if (collateral < minCollateral) {\n return;\n }\n\n if (!sourcesByCommit[commitId]) {\n sourcesByCommit[commitId] = [];\n }\n\n const isRepeat = data === 'repeat';\n\n // Build detailed hook info\n let hookChanges:\n | Array<{ index: number; prevValue: unknown; currentValue: unknown }>\n | undefined;\n if (typeof data === 'object' && data !== null) {\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n hookChanges = Object.entries(data).map(([index, hookData]) => ({\n index: Number(index),\n prevValue:\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n hookData !== 'repeat' ? (hookData as { prevValue: unknown }).prevValue : undefined,\n currentValue:\n hookData !== 'repeat'\n ? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n (hookData as { currentValue: unknown }).currentValue\n : undefined,\n }));\n }\n\n // Get rank and index (null if not in top N)\n const lookup = topNLookup.get(source.sourceId);\n const rank = lookup?.rank ?? null;\n const sourceIndex = lookup?.index ?? null;\n\n const entry: Report['sourcesByCommit'][number][number] = {\n sourceId: source.sourceId,\n type: source.type,\n depth: source.depth,\n collateral,\n rank,\n sourceIndex,\n };\n\n if (hookChanges && hookChanges.length > 0) {\n entry.hooks = hookChanges;\n }\n if (isRepeat) {\n entry.isRepeat = true;\n }\n\n sourcesByCommit[commitId].push(entry);\n });\n });\n\n // Only include metricsByCommit if there's data\n const hasMetricsData = Object.keys(state.metricsByCommit).length > 0;\n\n // Build meta object\n const integrationMode = detectorConfig?.integrationMode ?? 'none';\n const metricsAdapter = adapterIdFromMode(integrationMode);\n const metricsAvailable = metricsAdapter !== null && hasMetricsData;\n const meta: ReportMeta = {\n version: 6, // v6: CommitStats[8,9] = unmountedComponents/unmountedSubtrees; suspenseByCommit\n commits: state.commits,\n config: {\n detectionLevel: detectorConfig?.detectionLevel ?? 'full',\n effectThrashMode: detectorConfig?.effectThrashMode ?? 'non-primitive',\n captureFibers: detectorConfig?.captureFibers ?? false,\n historySize: detectorConfig?.historySize ?? 1,\n },\n memoizedUpdatersSupport: {\n available: state.memoizedUpdatersAvailable,\n commitsWithData: state.commitsWithMemoizedUpdaters,\n coverage,\n },\n integrationMode,\n metricsAdapter,\n // Per-field availability \u2014 fiber-walk fields are always real measurements\n // because recordTree() runs in every mode. The only adapter-exclusive\n // datapoint is the render-counter delta (restarts, metricsByCommit).\n dataAvailability: {\n collateral: true,\n sources: true,\n restarts: metricsAvailable,\n performedWork: true,\n effects: true,\n memos: true,\n callbacks: true,\n contextUpdates: true,\n metricsByCommit: metricsAvailable,\n atlByCommit: metricsAvailable,\n },\n timing: {\n totalDetectorOverhead,\n avgDetectorOverhead,\n totalTimeSpan,\n avgTimeBetweenCommits,\n },\n };\n\n const base: Report = {\n meta,\n sources,\n sourcesByCommit,\n commitStats: state.commitStats,\n commitTimings: state.commitTimings,\n suspenseByCommit: state.suspenseByCommit,\n unmountsByCommit: state.unmountsByCommit,\n interactionsByCommit: state.interactionsByCommit,\n renderedByCommit: state.renderedByCommit,\n ...(hasMetricsData && { metricsByCommit: state.metricsByCommit, atlByCommit: state.metricsByCommit }),\n toSerializable() {\n return serializeReport(this);\n },\n };\n\n if (thrashMode === 'full') {\n const getSortValue = (amplifier: Amplifier) => {\n if (sortBy === 'effect') return amplifier.effectCount;\n if (sortBy === 'callback') return amplifier.callbackCount;\n if (sortBy === 'memo') return amplifier.memoCount;\n if (sortBy === 'total') return amplifier.hooksTotal;\n return amplifier.effectCount;\n };\n\n const getLinkedSortValue = (as: AmplifierSource) => {\n if (sortBy === 'effect') return as.effectCount;\n if (sortBy === 'callback') return as.callbackCount;\n if (sortBy === 'memo') return as.memoCount;\n if (sortBy === 'total') return as.hooksTotal;\n return as.effectCount;\n };\n\n // Build amplifierSources\n const amplifierSources: AmplifierSource[] = Array.from(state.amplifierSources.entries())\n .map(([internalId, lt]) => {\n const humanId =\n idMapping.get(internalId) || toHumanReadableId(internalId, lt.type, lt.depth);\n const sourceData = state.sources.get(internalId);\n\n return {\n sourceId: humanId,\n type: lt.type,\n depth: lt.depth,\n collateralUpdates: sourceData?.collateralUpdates ?? 0,\n effectCount: lt.effectCount,\n callbackCount: lt.callbackCount,\n memoCount: lt.memoCount,\n hooksTotal: lt.hooksTotal,\n commitIds: lt.commitIds,\n byCommit: lt.byCommit,\n causedBySourceId: lt.causedBySourceId\n ? idMapping.get(lt.causedBySourceId) || lt.causedBySourceId\n : null,\n lastAmplification: lt.lastAmplification,\n };\n })\n .sort((a, b) => getLinkedSortValue(b) - getLinkedSortValue(a) || b.hooksTotal - a.hooksTotal)\n .slice(0, topN);\n\n return {\n ...base,\n amplifiers: Array.from(state.amplifiers.entries())\n .map(([type, s]) => ({ type, ...s }))\n .sort(\n (a, b) =>\n getSortValue(b) - getSortValue(a) ||\n b.hooksTotal - a.hooksTotal ||\n b.maxHooksPerCommit - a.maxHooksPerCommit\n )\n .slice(0, topN),\n amplifierSources,\n };\n }\n\n if (thrashMode === 'counts' && state.thrashCounts) {\n // Add amplifier metrics to meta\n meta.amplifiersMetrics = {\n totalHookThrashes: state.thrashCounts.totalHooks,\n affectedComponentCount: state.thrashCounts.affectedComponents.size,\n };\n }\n\n return base;\n}\n", "/**\n * Shared React DevTools renderer discovery.\n *\n * React-DOM registers a renderer object into\n * `window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers` at injection time (only when\n * the hook exists before react-dom evaluates). That renderer object is the single\n * entry point for several Chippy capabilities:\n *\n * - `currentDispatcherRef` \u2192 debug-render hook replay (see debug-render/core.ts)\n * - `scheduleUpdate` \u2192 fiber-schedule-update nudge (see fiber-schedule-update.ts)\n *\n * Both used to walk `hook.renderers` themselves. This module is the one place that\n * knows how to enumerate renderers, so capabilities select the field they need\n * without duplicating the iteration (and its Map/entries quirks).\n */\n\nexport type ReactRenderer = {\n currentDispatcherRef?: { current: unknown } | null;\n scheduleUpdate?: (fiber: unknown) => void;\n version?: string;\n rendererPackageName?: string;\n [key: string]: unknown;\n};\n\nexport type DevtoolsHookLike = {\n renderers?:\n | Map<number, ReactRenderer>\n | { entries(): IterableIterator<[number, ReactRenderer]> };\n};\n\n/**\n * Enumerate every registered React renderer. Returns [] when the DevTools hook\n * is absent or empty (production builds without the shim, or hook installed too\n * late for react-dom to register).\n */\nexport function getReactRenderers(\n scope: typeof globalThis = globalThis,\n): ReactRenderer[] {\n const g = scope as unknown as { __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevtoolsHookLike };\n const hook = g.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook || !hook.renderers || typeof (hook.renderers as { entries?: unknown }).entries !== 'function') {\n return [];\n }\n const out: ReactRenderer[] = [];\n for (const [, renderer] of (hook.renderers as Map<number, ReactRenderer>).entries()) {\n if (renderer) out.push(renderer);\n }\n return out;\n}\n\n/**\n * First renderer that exposes a usable `currentDispatcherRef`. Used by\n * debug-render to patch the hook dispatcher.\n */\nexport function getDispatcherRef(\n scope: typeof globalThis = globalThis,\n): { current: unknown } | null {\n for (const renderer of getReactRenderers(scope)) {\n const ref = renderer.currentDispatcherRef;\n if (ref && typeof ref === 'object') return ref;\n }\n return null;\n}\n\n/**\n * First renderer that exposes a callable `scheduleUpdate`. This is the exact\n * function React DevTools uses to force a re-render on a fiber. It is only\n * present on development React builds. Returns null on production builds (or\n * when the DevTools-hook shim was missing at page boot).\n */\nexport function getScheduleUpdate(\n scope: typeof globalThis = globalThis,\n): ((fiber: unknown) => void) | null {\n for (const renderer of getReactRenderers(scope)) {\n if (typeof renderer.scheduleUpdate === 'function') return renderer.scheduleUpdate;\n }\n return null;\n}\n", "/**\n * Debug-render module.\n *\n * Single responsibility: capture per-render hook events for components, and\n * expose them losslessly to higher layers (the detector projects them).\n *\n * Capture strategy: dispatcher interception via the DevTools global hook.\n *\n * React 18 routes every hook call through `ReactCurrentDispatcher.current`,\n * which is swapped per render phase by react-dom. We do NOT patch\n * `React.useX` (those are facades to the dispatcher) and we do NOT import\n * React here \u2014 this module must not pin a React identity.\n *\n * We discover the *page's* `ReactCurrentDispatcher` ref via the React DevTools\n * global hook contract:\n *\n * __REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.get(id).currentDispatcherRef\n *\n * That ref is page-React-owned and lives where react-dom actually writes.\n * Bootstrap requirement: a DevTools hook shim must already be installed when\n * react-dom evaluates so it calls `hook.inject(internals)`. That bootstrap is\n * Chippy's responsibility (handled by the extension content-script / helper\n * inject path); this module only consumes the result.\n *\n * Capture is intentionally lossless: raw stack + parsed frames are stored.\n * Projection (component name, custom-hook path, loc) is done downstream so\n * the original evidence can be re-projected without re-capturing.\n */\n\nimport { getDispatcherRef, getReactRenderers } from '../chippy-bridge/react-renderer';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type StackFrame = { name: string; loc: string };\n\nexport type HookCallEvent = {\n primitive: string;\n stack: string;\n frames: StackFrame[];\n componentName: string;\n args: unknown[];\n};\n\nexport type CaptureEngineStatus = {\n ok: boolean;\n installed: boolean;\n hasDevtoolsHook: boolean;\n rendererCount: number;\n hasDispatcherRef: boolean;\n totalCapturedComponents: number;\n totalCapturedEvents: number;\n reason?: string;\n hint?: string;\n};\n\nexport type DebugRenderModule = {\n install(): { ok: boolean; reason?: string };\n uninstall(): void;\n reset(): void;\n isInstalled(): boolean;\n dispatcherRef(): DispatcherRef | null;\n rawEvents(componentName: string): HookCallEvent[];\n allComponents(): string[];\n status(): CaptureEngineStatus;\n recordEventForTest?(event: HookCallEvent): void;\n};\n\n// ---------------------------------------------------------------------------\n// Stack parsing \u2014 zero-loss. Caller decides what to filter.\n// ---------------------------------------------------------------------------\n\nexport function parseStackFrames(stack: string): StackFrame[] {\n return stack\n .split('\\n')\n .slice(1)\n .map((line) => {\n const m =\n line.match(/^\\s*at\\s+([^\\s(]+)\\s*\\(([^)]+)\\)/) ||\n line.match(/^\\s*at\\s+()(.+)$/);\n if (!m) return null;\n const name = (m[1] || '').trim();\n const locRaw = (m[2] || '').trim();\n const tail = locRaw.match(/:(\\d+):(\\d+)\\)?$/);\n const loc = tail ? `${tail[1]}:${tail[2]}` : locRaw;\n return name ? { name, loc } : null;\n })\n .filter((f): f is StackFrame => !!f);\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher interception\n// ---------------------------------------------------------------------------\n\n// Hook methods we instrument on the dispatcher. This list intentionally\n// mirrors React 18's HooksDispatcher surface; unknown methods are passed\n// through untouched so future React versions degrade gracefully instead\n// of crashing.\nconst HOOK_METHODS: ReadonlyArray<string> = [\n 'useCallback',\n 'useContext',\n 'useDebugValue',\n 'useDeferredValue',\n 'useEffect',\n 'useImperativeHandle',\n 'useInsertionEffect',\n 'useLayoutEffect',\n 'useMemo',\n 'useReducer',\n 'useRef',\n 'useState',\n 'useSyncExternalStore',\n 'useTransition',\n 'useId',\n 'useCacheRefresh',\n 'useMemoCache',\n];\n\nconst HOOK_PRIMITIVE: Record<string, string> = {\n useCallback: 'Callback',\n useContext: 'Context',\n useDebugValue: 'DebugValue',\n useDeferredValue: 'DeferredValue',\n useEffect: 'Effect',\n useImperativeHandle: 'ImperativeHandle',\n useInsertionEffect: 'InsertionEffect',\n useLayoutEffect: 'LayoutEffect',\n useMemo: 'Memo',\n useReducer: 'Reducer',\n useRef: 'Ref',\n useState: 'State',\n useSyncExternalStore: 'SyncExternalStore',\n useTransition: 'Transition',\n useId: 'Id',\n useCacheRefresh: 'CacheRefresh',\n useMemoCache: 'MemoCache',\n};\n\ntype DispatcherRef = { current: unknown };\n\n/**\n * Find the page's `ReactCurrentDispatcher` ref.\n *\n * Renderer discovery is shared with the fiber-schedule-update capability \u2014 one\n * place (`chippy-bridge/react-renderer`) knows how to enumerate\n * `__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers`. react-dom registers its renderer\n * (with its own `currentDispatcherRef`) on evaluation IF the global hook existed\n * before react-dom was loaded; Chippy installs that shim before page boot.\n *\n * We do NOT touch any bundled React module identity here. There is no React\n * import in this file by design.\n */\n\n// componentName extraction: walk frames and pick the last non-`use*` frame.\n// This is a projection step; raw frames are still kept on the event so a\n// caller can re-derive a different name if this heuristic is wrong.\nfunction isReactInternalFrameName(name: string): boolean {\n return name === 'atlDispatcherHook' ||\n name === 'record' ||\n name.startsWith('Object.') ||\n name === 'renderWithHooks' ||\n name === 'updateFunctionComponent' ||\n name === 'mountIndeterminateComponent' ||\n name === 'beginWork' ||\n /^beginWork\\$/.test(name) ||\n name === 'performUnitOfWork' ||\n name === 'workLoopSync' ||\n name === 'renderRootSync' ||\n name === 'performConcurrentWorkOnRoot' ||\n name === 'workLoop' ||\n name === 'flushWork';\n}\n\nfunction deriveComponentName(frames: StackFrame[]): string {\n for (const { name } of frames) {\n if (!name) continue;\n if (isReactInternalFrameName(name)) continue;\n if (/^use[A-Z0-9_]/.test(name)) continue; // skip use-prefixed (custom + primitive)\n return name;\n }\n return 'Unknown';\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createDebugRender(options: { maxEventsPerComponent?: number } = {}): DebugRenderModule {\n const maxEventsPerComponent = options.maxEventsPerComponent ?? 600;\n\n const eventsByComponent = new Map<string, HookCallEvent[]>();\n\n // We keep a WeakMap of dispatcher object -> patched-method-restore so we\n // can patch each new dispatcher exactly once and never double-wrap. React\n // re-uses dispatcher objects across renders, so this is small and bounded.\n const patchedDispatchers = new WeakMap<object, Map<string, unknown>>();\n\n let installed = false;\n let originalDescriptor: PropertyDescriptor | null | undefined = undefined;\n let dispatcherRef: DispatcherRef | null = null;\n let lastSeenDispatcher: unknown = null;\n\n function record(primitive: string, args: unknown[]): void {\n // Capture once. No filtering. Filtering is a projection concern.\n const stack = new Error().stack || '';\n const frames = parseStackFrames(stack);\n const componentName = deriveComponentName(frames);\n const event: HookCallEvent = {\n primitive,\n stack,\n frames,\n componentName,\n args,\n };\n const list = eventsByComponent.get(componentName) || [];\n list.push(event);\n if (list.length > maxEventsPerComponent) {\n list.splice(0, list.length - maxEventsPerComponent);\n }\n eventsByComponent.set(componentName, list);\n }\n\n function patchDispatcher(dispatcher: unknown): void {\n if (!dispatcher || typeof dispatcher !== 'object') return;\n const obj = dispatcher as Record<string, unknown>;\n if (patchedDispatchers.has(obj)) return; // already wrapped\n\n // React swaps dispatcher objects between render phases. Patch each object\n // once and retain the original methods so uninstall can return ownership\n // to React without leaving wrappers on a dispatcher used later.\n const restoreMap = new Map<string, unknown>();\n for (const methodName of HOOK_METHODS) {\n const original = obj[methodName];\n if (typeof original !== 'function') continue;\n restoreMap.set(methodName, original);\n const primitive = HOOK_PRIMITIVE[methodName] || methodName;\n // Named function so it is identifiable in stack traces and can be\n // skipped by callers that post-process frames.\n obj[methodName] = function atlDispatcherHook(this: unknown, ...args: unknown[]) {\n try {\n record(primitive, args);\n } catch (_) {\n // Recording must never throw inside React render.\n }\n return (original as Function).apply(this, args);\n };\n }\n patchedDispatchers.set(obj, restoreMap);\n }\n\n function unpatchDispatcher(dispatcher: unknown): void {\n if (!dispatcher || typeof dispatcher !== 'object') return;\n const obj = dispatcher as Record<string, unknown>;\n const restoreMap = patchedDispatchers.get(obj);\n if (!restoreMap) return;\n for (const [methodName, fn] of restoreMap.entries()) {\n obj[methodName] = fn;\n }\n patchedDispatchers.delete(obj);\n }\n\n function install(): { ok: boolean; reason?: string } {\n if (installed) return { ok: true };\n const ref = getDispatcherRef();\n if (!ref) return { ok: false, reason: 'ReactCurrentDispatcher not found' };\n dispatcherRef = ref;\n\n // Patch whatever is already current (likely the no-op ContextOnlyDispatcher\n // outside render, but patching it is harmless: it will only be called when\n // React swaps it in). Then trap subsequent assignments.\n patchDispatcher(ref.current);\n lastSeenDispatcher = ref.current;\n\n // Intercept the ref's setter rather than React's hook facades. React owns\n // this ref and changes `current` at render boundaries; observing those\n // transitions is what lets us patch the correct phase-specific dispatcher.\n originalDescriptor = Object.getOwnPropertyDescriptor(ref, 'current') || null;\n\n let stored: unknown = ref.current;\n try {\n Object.defineProperty(ref, 'current', {\n configurable: true,\n get(): unknown {\n return stored;\n },\n set(next: unknown) {\n stored = next;\n if (next !== lastSeenDispatcher) {\n lastSeenDispatcher = next;\n patchDispatcher(next);\n }\n },\n });\n } catch (e) {\n dispatcherRef = null;\n return { ok: false, reason: 'cannot define property on ReactCurrentDispatcher' };\n }\n\n installed = true;\n return { ok: true };\n }\n\n function uninstall(): void {\n if (!installed) return;\n if (dispatcherRef) {\n // Restore original property descriptor (if any) so React owns `current` again.\n try {\n if (originalDescriptor) {\n Object.defineProperty(dispatcherRef, 'current', originalDescriptor);\n } else {\n // Fall back to a plain data property holding the latest dispatcher.\n Object.defineProperty(dispatcherRef, 'current', {\n configurable: true,\n writable: true,\n enumerable: true,\n value: lastSeenDispatcher,\n });\n }\n } catch (_) {\n /* tolerate */\n }\n }\n // Best-effort unpatch of the last dispatcher we touched. Other dispatchers\n // patched earlier remain wrapped until GC; the wrappers are cheap.\n unpatchDispatcher(lastSeenDispatcher);\n installed = false;\n dispatcherRef = null;\n originalDescriptor = undefined;\n lastSeenDispatcher = null;\n }\n\n function reset(): void {\n eventsByComponent.clear();\n }\n\n function rawEvents(componentName: string): HookCallEvent[] {\n return (eventsByComponent.get(componentName) || []).slice();\n }\n\n function allComponents(): string[] {\n return Array.from(eventsByComponent.keys());\n }\n\n function status(): CaptureEngineStatus {\n const g = globalThis as unknown as { __REACT_DEVTOOLS_GLOBAL_HOOK__?: unknown };\n const hasDevtoolsHook = !!g.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n // Renderer enumeration is shared with the fiber-schedule-update capability.\n const rendererCount = getReactRenderers().length;\n const ref = dispatcherRef || getDispatcherRef();\n const hasDispatcherRef = !!ref;\n let totalCapturedEvents = 0;\n for (const list of eventsByComponent.values()) totalCapturedEvents += list.length;\n\n let reason: string | undefined;\n let hint: string | undefined;\n if (!hasDevtoolsHook) {\n reason = 'no __REACT_DEVTOOLS_GLOBAL_HOOK__ on window';\n hint = 'devtools-hook-shim must run before react-dom evaluates (extension document_start, or Playwright addInitScript)';\n } else if (rendererCount === 0) {\n reason = '__REACT_DEVTOOLS_GLOBAL_HOOK__ present but renderers Map is empty';\n hint = 'react-dom evaluated before the hook shim was installed; reload the page after installing the shim, or use addInitScript before navigation';\n } else if (!hasDispatcherRef) {\n reason = 'renderer registered but no currentDispatcherRef';\n hint = 'unsupported react-dom version, or hook was replaced after registration';\n } else if (!installed) {\n reason = 'debug-render not installed';\n hint = 'detector did not call debugRender.install() \u2014 check avalanche install() lifecycle';\n } else if (totalCapturedEvents === 0) {\n reason = 'capture engine installed but no hook events recorded yet';\n hint = 'trigger at least one render of the component you want to inspect after install';\n }\n\n const ok = installed && hasDispatcherRef && totalCapturedEvents > 0;\n return {\n ok,\n installed,\n hasDevtoolsHook,\n rendererCount,\n hasDispatcherRef,\n totalCapturedComponents: eventsByComponent.size,\n totalCapturedEvents,\n reason,\n hint,\n };\n }\n\n return {\n install,\n uninstall,\n reset,\n isInstalled: () => installed,\n dispatcherRef: () => dispatcherRef || getDispatcherRef(),\n rawEvents,\n allComponents,\n status,\n recordEventForTest(event: HookCallEvent) {\n const list = eventsByComponent.get(event.componentName) || [];\n list.push(event);\n eventsByComponent.set(event.componentName, list);\n },\n };\n}\n", "export interface CommitRoot {\n current: object;\n}\n\n// A seeded metrics slot cannot select the capture owner. The first actual\n// adapter callback can arrive before or after DevTools for the same committed\n// fiber.\nexport function createCommitSurfaceOwnership<T>() {\n let adapterObserved = false;\n let devtoolsCaptures = new WeakMap<CommitRoot, { current: object; capture: T }>();\n return {\n get adapterObserved() { return adapterObserved; },\n recordDevtools(root: CommitRoot, capture: T) {\n devtoolsCaptures.set(root, { current: root.current, capture });\n },\n observeAdapter(root: CommitRoot): T | null {\n const previous = devtoolsCaptures.get(root);\n adapterObserved = true;\n devtoolsCaptures.delete(root);\n return previous?.current === root.current ? previous.capture : null;\n },\n reset() {\n adapterObserved = false;\n devtoolsCaptures = new WeakMap();\n },\n };\n}\n", "/**\n * Pure fiber-walk helpers extracted from layout-lab.js.\n * No DOM writes, no side effects \u2014 read-only introspection of React fiber trees.\n */\n\nimport {\n getFiberSource as readFiberSource,\n resolveFiberSource as resolveSourceLocation,\n} from '../chippy-bridge/fiber-source';\n\n/**\n * Minimal duck-typed Fiber shape.\n * Only fields used by these helpers are typed; rest may exist but are not read.\n */\nexport type Fiber = {\n type?: unknown;\n elementType?: unknown;\n key?: string | null;\n memoizedState?: unknown;\n memoizedProps?: Record<string, unknown> | null;\n stateNode?: Element | null;\n return?: Fiber | null;\n child?: Fiber | null;\n sibling?: Fiber | null;\n _debugOwner?: Fiber | null;\n _debugSource?: SourceLocation | null;\n _debugStack?: unknown;\n};\n\nexport type SourceLocation = {\n fileName?: string | null;\n lineNumber?: number | null;\n columnNumber?: number | null;\n};\n\nexport type DescribedSource = {\n fileName: string | null;\n lineNumber: number | null;\n columnNumber: number | null;\n};\n\nexport type HookSummary = {\n hookCount: number;\n hookCountTruncated: boolean;\n hookCountMax: number;\n};\n\nexport type OwnerEntry = {\n name: string | null;\n key: string | null;\n props: string[];\n} & HookSummary & {\n source: DescribedSource | null;\n};\n\nexport type FiberTarget = {\n domTag: string | null;\n domText: string;\n fiberType: string | null;\n source: DescribedSource | null;\n};\n\nexport type ComponentDescription = {\n name: string | null;\n key: string | null;\n props: Record<string, unknown>;\n source: DescribedSource | null;\n stateNode: string | null;\n owners: OwnerEntry[];\n parents: OwnerEntry[];\n} & HookSummary;\n\n/**\n * Find the React fiber key in a DOM node's own properties.\n * Returns the property name (e.g. '__reactFiber$abc123') or null.\n */\nexport function getFiberKey(node: Node | Element | null | undefined): string | null {\n if (!node) return null;\n const keys = Object.getOwnPropertyNames(node as object);\n const key = keys.find((k) => k.startsWith('__reactFiber$'));\n return key || null;\n}\n\n/**\n * Get the React fiber attached to a DOM node, or null if not a React host node.\n */\nexport function getFiber(node: Node | Element | null | undefined): Fiber | null {\n if (!node) return null;\n const key = getFiberKey(node);\n // React stores the fiber as an expando property on the host node.\n return key ? ((node as unknown as Record<string, unknown>)[key] as Fiber | null) : null;\n}\n\n/**\n * Extract display name from a React type (class, function, or string).\n * Returns displayName > name > null for functions; 'string' for primitives.\n */\nexport function getDisplayName(type: unknown): string | null {\n if (!type) return null;\n if (typeof type === 'string') return type;\n const obj = type as { displayName?: unknown; name?: unknown };\n return (obj.displayName as string) || (obj.name as string) || null;\n}\n\n/**\n * True if fiber is a user-defined component (not a DOM string, not a hook-internal wrapper).\n */\nexport function isUserComponent(fiber: Fiber | null | undefined): boolean {\n if (!fiber) return false;\n const name = getDisplayName(fiber.type);\n if (!name || typeof fiber.type === 'string') return false;\n if (['hookified', 'unboundStoryFn', 'Anonymous'].includes(name)) return false;\n return true;\n}\n\n/**\n * Walk DOM parents to find the nearest fiber-attached element.\n */\nexport function getNearestFiber(domNode: Node | Element | null | undefined): Fiber | null {\n let current = domNode as Element | null;\n while (current) {\n const fiber = getFiber(current);\n if (fiber) return fiber;\n current = (current as Element).parentElement;\n }\n return null;\n}\n\n/**\n * Walk DOM parents, then walk fiber return chain, to find the nearest user component.\n */\nexport function getNearestComponent(domNode: Node | Element | null | undefined): Fiber | null {\n let fiber = getNearestFiber(domNode);\n while (fiber) {\n if (isUserComponent(fiber)) return fiber;\n fiber = fiber.return || null;\n }\n return null;\n}\n\n/**\n * Count hooks in fiber.memoizedState linked list; detect cycle.\n */\nexport function getHookSummary(fiber: Fiber | null | undefined): HookSummary {\n const MAX_HOOKS = 500;\n const seen = new Set<unknown>();\n let hookNode = fiber?.memoizedState || null;\n let hookCount = 0;\n let hookCountTruncated = false;\n\n while (hookNode) {\n if (seen.has(hookNode)) break;\n if (hookCount >= MAX_HOOKS) {\n hookCountTruncated = true;\n break;\n }\n seen.add(hookNode);\n hookCount += 1;\n hookNode = (hookNode as { next?: unknown }).next || null;\n }\n\n return { hookCount, hookCountTruncated, hookCountMax: MAX_HOOKS };\n}\n\n/**\n * Walk fiber._debugOwner chain; collect all user components with metadata.\n * Returns empty array if fiber or owner chain is null.\n */\nexport function getOwnerChain(fiber: Fiber | null | undefined): OwnerEntry[] {\n const chain: OwnerEntry[] = [];\n let current = fiber?._debugOwner || null;\n while (current) {\n if (isUserComponent(current)) {\n chain.push({\n name: getDisplayName(current.type),\n key: current.key || null,\n props: current.memoizedProps ? Object.keys(current.memoizedProps) : [],\n ...getHookSummary(current),\n source: describeFiberSource(current),\n });\n }\n current = current._debugOwner || null;\n }\n return chain;\n}\n\n/**\n * Walk fiber._debugOwner chain; return raw fiber nodes (for navigation).\n */\nexport function getOwnerFibers(fiber: Fiber | null | undefined): Fiber[] {\n const fibers: Fiber[] = [];\n let current = fiber?._debugOwner || null;\n while (current) {\n if (isUserComponent(current)) fibers.push(current);\n current = current._debugOwner || null;\n }\n return fibers;\n}\n\n/**\n * Recursively walk fiber.child/sibling to find the first host DOM element rendered by this subtree.\n */\nexport function getFiberDomNode(fiber: Fiber | null | undefined): Element | null {\n if (!fiber) return null;\n // Host fiber \u2014 stateNode is a DOM element\n if (fiber.stateNode instanceof Element) return fiber.stateNode;\n // Walk children\n let child = fiber.child || null;\n while (child) {\n const found = getFiberDomNode(child);\n if (found) return found;\n child = child.sibling || null;\n }\n return null;\n}\n\n/**\n * Walk fiber.return chain; collect all user component parents with metadata.\n */\nexport function getReturnComponentChain(fiber: Fiber | null | undefined): OwnerEntry[] {\n const chain: OwnerEntry[] = [];\n let current = fiber?.return || null;\n while (current) {\n if (isUserComponent(current)) {\n chain.push({\n name: getDisplayName(current.type),\n key: current.key || null,\n props: current.memoizedProps ? Object.keys(current.memoizedProps) : [],\n ...getHookSummary(current),\n source: describeFiberSource(current),\n });\n }\n current = current.return || null;\n }\n return chain;\n}\n\n/**\n * Walk fiber.return chain; return raw fiber nodes (for navigation).\n */\nexport function getReturnComponentFibers(fiber: Fiber | null | undefined): Fiber[] {\n const fibers: Fiber[] = [];\n let current = fiber?.return || null;\n while (current) {\n if (isUserComponent(current)) fibers.push(current);\n current = current.return || null;\n }\n return fibers;\n}\n\n/**\n * Normalize source location object to canonical shape.\n */\nexport function describeSource(source: SourceLocation | null | undefined): DescribedSource | null {\n if (!source) return null;\n return {\n fileName: source.fileName || null,\n lineNumber: source.lineNumber || null,\n columnNumber: source.columnNumber || null,\n };\n}\n\n/**\n * Read a fiber source across React versions.\n *\n * React <=18 exposes `_debugSource`. React 19 exposes `_debugStack`; its first\n * non-vendor frame is returned synchronously and may later be upgraded from the\n * bundle position to the original source position by `resolveFiberSource`.\n */\nexport function describeFiberSource(fiber: Fiber | null | undefined): DescribedSource | null {\n return describeSource(readFiberSource(fiber));\n}\n\nexport async function resolveFiberSource(fiber: Fiber | null | undefined): Promise<DescribedSource | null> {\n return describeSource(await resolveSourceLocation(fiber));\n}\n\n/**\n * Describe a fiber + DOM node pair; used for inspection UI.\n */\nexport function describeFiberTarget(fiber: Fiber | null | undefined, domNode: Element | null | undefined): FiberTarget | null {\n if (!fiber && !domNode) return null;\n return {\n domTag: domNode?.tagName?.toLowerCase() || null,\n domText: domNode?.textContent?.trim().slice(0, 60) || '',\n fiberType: getDisplayName(fiber?.type) || getDisplayName(fiber?.elementType) || null,\n source: describeFiberSource(fiber),\n };\n}\n\n/**\n * Full component description: name, props, hook summary, source, owners, parents.\n */\nexport function describeComponent(fiber: Fiber | null | undefined): ComponentDescription | null {\n if (!fiber) return null;\n return {\n name: getDisplayName(fiber.type),\n key: fiber.key || null,\n props: fiber.memoizedProps || {},\n ...getHookSummary(fiber),\n source: describeFiberSource(fiber),\n stateNode: fiber.stateNode instanceof Element ? fiber.stateNode.tagName.toLowerCase() : null,\n owners: getOwnerChain(fiber),\n parents: getReturnComponentChain(fiber),\n };\n}\n", "/**\n * Records user-side interaction anchors while Avalanche records commits.\n * Capture is intentionally DOM-event based: the detector owns fiber/commit\n * evidence, while this module owns the only signal that a human interaction\n * preceded it. `linkRecent` joins the two later using performance timestamps;\n * it is evidence of temporal proximity, not proof that the event caused every\n * render in the commit.\n */\n\nimport { isComponentFiber, type Fiber } from './internals';\nimport { describeComponent, describeFiberTarget } from '../layout-lab/fiber-walk';\nimport type { CommitInteractionAction, InteractionAction, InteractionCaptureLevel } from './reporter';\n\nconst EXPLICIT_INTERACTION_EVENTS = ['click', 'keydown', 'keyup', 'input', 'change', 'submit'];\nconst NOISY_INTERACTION_EVENTS = ['wheel', 'scroll', 'pointermove', 'mousemove', 'touchmove'];\nconst ALL_INTERACTION_EVENTS = [\n ...EXPLICIT_INTERACTION_EVENTS,\n 'pointerdown',\n 'pointerup',\n 'dblclick',\n 'focusin',\n 'focusout',\n ...NOISY_INTERACTION_EVENTS,\n];\nconst MAX_INTERACTION_ACTIONS = 200;\n\nexport interface InteractionCaptureOptions {\n interactionCapture?: InteractionCaptureLevel;\n interactionEvents?: string[];\n interactionWindowMs?: number;\n}\n\nexport interface InteractionCaptureState {\n actions: InteractionAction[];\n byCommit: Record<number, CommitInteractionAction[]>;\n}\n\nexport function createInteractionCapture(options: InteractionCaptureOptions = {}) {\n const {\n interactionCapture = 'explicit',\n interactionEvents = [],\n interactionWindowMs = 1000,\n } = options;\n\n const state: InteractionCaptureState = {\n actions: [],\n byCommit: {},\n };\n let nextActionId = 1;\n let installed = false;\n\n function eventNames(): string[] {\n const base =\n interactionCapture === 'off' ? [] :\n interactionCapture === 'explicit' ? EXPLICIT_INTERACTION_EVENTS :\n interactionCapture === 'noisy' ? EXPLICIT_INTERACTION_EVENTS.concat(NOISY_INTERACTION_EVENTS) :\n ALL_INTERACTION_EVENTS;\n return Array.from(new Set(base.concat(interactionEvents).map((name) => String(name).trim()).filter(Boolean)));\n }\n\n function findReactFiberKey(node: Element): string | null {\n return Object.getOwnPropertyNames(node).find((key) => key.startsWith('__reactFiber$')) || null;\n }\n\n function nearestFiberFromNode(node: EventTarget | null): Fiber | null {\n let current = node instanceof Element ? node : null;\n while (current) {\n const key = findReactFiberKey(current);\n if (key) return (current as unknown as Record<string, Fiber | undefined>)[key] || null;\n current = current.parentElement;\n }\n return null;\n }\n\n function nearestComponentFiber(node: EventTarget | null): Fiber | null {\n let fiber = nearestFiberFromNode(node);\n while (fiber) {\n if (isComponentFiber(fiber.tag)) return fiber;\n fiber = fiber.return || null;\n }\n return null;\n }\n\n function nearestTestId(node: EventTarget | null): string | null {\n let current = node instanceof Element ? node : null;\n while (current) {\n const value = current.getAttribute('data-testid');\n if (value) return value;\n current = current.parentElement;\n }\n return null;\n }\n\n function describeActionLocation(target: EventTarget | null): InteractionAction['location'] {\n const domTarget = target instanceof Element ? target : null;\n const fiber = nearestComponentFiber(target);\n const describedTarget = describeFiberTarget(fiber as any, domTarget);\n const describedComponent = describeComponent(fiber as any);\n return {\n dom: {\n tag: describedTarget?.domTag || null,\n text: describedTarget?.domText || '',\n nearestTestId: nearestTestId(target),\n },\n targetFiber: describedComponent ? {\n name: describedComponent.name,\n key: describedComponent.key,\n source: describedComponent.source,\n ownerStackKind: describedComponent.owners.length > 0 ? 'owners' : 'parents',\n ownerStack: describedComponent.owners.length > 0 ? describedComponent.owners : describedComponent.parents,\n } : null,\n };\n }\n\n function capture(event: Event): void {\n const pathTarget = typeof event.composedPath === 'function' ? event.composedPath()[0] : null;\n const target = pathTarget instanceof Element ? pathTarget : event.target;\n // Keep a bounded queue because a long-lived page can receive noisy events\n // continuously. Older anchors cannot link to a future commit once they\n // fall outside the configured window.\n state.actions.push({\n id: nextActionId++,\n action: event.type,\n timestamp: performance.now(),\n location: describeActionLocation(target),\n });\n if (state.actions.length > MAX_INTERACTION_ACTIONS) {\n state.actions.splice(0, state.actions.length - MAX_INTERACTION_ACTIONS);\n }\n }\n\n return {\n state,\n\n install(): void {\n if (installed) return;\n const names = eventNames();\n if (names.length === 0 || typeof document === 'undefined') return;\n for (const name of names) document.addEventListener(name, capture, true);\n installed = true;\n },\n\n uninstall(): void {\n if (!installed || typeof document === 'undefined') return;\n for (const name of eventNames()) document.removeEventListener(name, capture, true);\n installed = false;\n },\n\n reset(): void {\n state.actions.length = 0;\n for (const key of Object.keys(state.byCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.byCommit[Number(key)];\n }\n nextActionId = 1;\n },\n\n linkRecent(commitId: number, commitTime: number): void {\n const windowMs = Math.max(0, Number(interactionWindowMs) || 0);\n if (windowMs === 0 || state.actions.length === 0) return;\n // Link only events at or before the commit. A later event may be close in\n // wall-clock time but cannot explain work that already committed.\n const linked = state.actions\n .filter((action) => action.timestamp <= commitTime && commitTime - action.timestamp <= windowMs)\n .map((action) => ({\n id: action.id,\n lastCommitId: Math.max(0, commitId - 1),\n deltaTime: Math.round((commitTime - action.timestamp) * 100) / 100,\n action: action.action,\n location: action.location,\n }));\n if (linked.length > 0) state.byCommit[commitId] = linked;\n while (state.actions.length > 0 && commitTime - state.actions[0].timestamp > windowMs) {\n state.actions.shift();\n }\n },\n };\n}\n", "/**\n * Headless Profiler - React commit profiler (headless / no UI).\n *\n * This file intentionally keeps the commit traversal (`recordTree`) monolithic.\n * It runs on every React commit, and even small function-call overhead inside the\n * fiber-walk loops shows up in perf. We refactor everything *around* it.\n *\n * Detection Levels:\n * - Level 1 (STATS): Only commitStats - <1% overhead (~0.8ms avg)\n * - Level 2 (SOURCES): + source tracking - ~1-2% overhead (~1.3ms avg)\n * - Level 3 (AMPLIFIERS/FULL): + amplifier detection - ~2-3% overhead (~2.4ms avg)\n *\n * Peer FAQ\n * - Why is `recordTree()` huge? Performance: it's on the hot path (every commit).\n * - Why per-hook actionability? React can leave alternate hook memoizedState\n * undefined (Suspense/Offscreen/concurrent artifacts) causing false positives.\n * - Why WeakMaps everywhere? To auto-GC tracked values/fibers without leaks.\n * - Why so few null checks? Debug tool: fail fast and loud on misuse/internals drift.\n * - Production? Use LEVEL1_STATS or LEVEL2_SOURCES for minimal overhead.\n */\n\nimport {\n ChildDeletion,\n detectHookThrashing,\n didContextValueChange,\n didFiberSelfUpdate,\n didFiberUpdate,\n didSuspenseStateChange,\n Hydrating,\n isComponentFiber,\n getComponentName,\n isContextProviderFiber,\n isDevelopment,\n isReactInternalComponentType,\n isSuspenseFiber,\n PerformedWork,\n Placement,\n Update,\n type ChangedHook,\n type ComponentType,\n type DepOrigin,\n type Fiber,\n type ThrashInfo,\n} from './internals';\n\nimport {\n buildReport,\n type DetectorOptions,\n type ProfilerState,\n type PropChangeEvidence,\n type PropValueSummary,\n type RenderedComponentEvidence,\n type Report,\n type ReportOptions,\n type SortBy,\n type Source,\n type SuspenseBoundaryEvent,\n type ThrashMode,\n type UnmountSample,\n} from './reporter';\n\nimport { createDebugRender, type HookCallEvent, type StackFrame } from '../debug-render/core';\nimport { getFiberSourceCandidate } from '../chippy-bridge/fiber-source';\nimport {\n type CommitMetricsAdapter,\n type CommitMetricsSnapshot,\n type IntegrationMode,\n getCommitMetricsAdapter,\n} from './commit-metrics-adapter';\nimport { createCommitSurfaceOwnership } from './commit-surface-ownership';\nimport { createInteractionCapture } from './interaction-capture';\nimport {\n CS_UNMOUNTED_COMPONENTS,\n CS_UNMOUNTED_SUBTREES,\n CS_RESTARTS,\n} from './commit-stats-indices';\n\nfunction summarizeFiberSource(fiber: Fiber): { fileName: string; lineNumber: number } | null {\n const source = getFiberSourceCandidate(fiber);\n return source ? { fileName: source.fileName, lineNumber: source.lineNumber } : null;\n}\n\n/**\n * Installable detector.\n */\nexport function createAvalancheDetector(options: DetectorOptions = {}) {\n const {\n ignore = [],\n effectThrashMode = 'non-primitive',\n captureFibers = isDevelopment(),\n detectionMode = isDevelopment() ? 'full' : 'amplifiers',\n historySize = isDevelopment() ? 10 : 1,\n } = options;\n\n const mode = detectionMode;\n\n // Resolved on install(), so an adapter registered after the detector was\n // created still applies. `metricsAdapter: null` opts out of adapters.\n let metricsAdapter: CommitMetricsAdapter | null = null;\n const resolveMetricsAdapter = (): CommitMetricsAdapter | null =>\n options.metricsAdapter === undefined ? getCommitMetricsAdapter() : options.metricsAdapter;\n\n const ignoreSet = new Set(ignore);\n\n // Normalize detection mode to level\n // Level 1 (stats): Only commitStats with restarts - super fast\n // Level 2 (sources): Stats + source tracking - adds overhead for source detection\n // Level 3a (amplifierMetrics): Sources + aggregate amplifier counts - lightweight\n // Level 3b (amplifiers): Sources + full amplifier arrays - more detail\n // Legacy: 'full' is alias for 'amplifiers' (kept for backward compatibility)\n // TODO: Replace this open conditional chain with an exhaustive runtime\n // normalizer or fail-closed branch. TypeScript protects typed callers only;\n // unchecked shell/helper input can leave both variables undefined.\n let detectionLevel: 'stats' | 'sources' | 'amplifierMetrics' | 'amplifiers' | 'full';\n let thrashMode: ThrashMode;\n\n if (mode === true) {\n detectionLevel = 'full';\n thrashMode = 'full';\n } else if (mode === false) {\n detectionLevel = 'stats';\n thrashMode = false;\n } else if (mode === 'stats') {\n detectionLevel = 'stats';\n thrashMode = false;\n } else if (mode === 'sources') {\n detectionLevel = 'sources';\n thrashMode = false;\n } else if (mode === 'amplifiers') {\n detectionLevel = 'amplifiers';\n thrashMode = 'full';\n } else if (mode === 'amplifierMetrics') {\n detectionLevel = 'amplifierMetrics';\n thrashMode = 'counts';\n } else if (mode === 'full') {\n detectionLevel = 'full';\n thrashMode = 'full';\n }\n\n const enableSourceTracking = detectionLevel !== 'stats';\n const enableAmplifiers = thrashMode !== false;\n\n // Global WeakMap: value -> provenance. WeakMap ensures automatic GC.\n const valueProvenance = new WeakMap<object | Function, DepOrigin>();\n\n // Stable source ID manager - handles fiber alternate swaps\n // Uses WeakMap to track types and generate stable numeric IDs (fast, no string ops!)\n class StableSourceIdManager {\n private idMap = new WeakMap<Fiber, string>();\n // WeakMap only accepts objects/functions, not symbols. Store only valid keys.\n private typeToId = new WeakMap<object | Function, number>();\n private instanceCounters = new Map<string, number>(); // \"typeId@depth\" -> instance count\n private nextTypeId = 1;\n\n getSourceId(fiber: Fiber, type: ComponentType, depth: number): string {\n // Check if we already have an ID for this fiber\n let sourceId = this.idMap.get(fiber);\n if (sourceId) return sourceId;\n\n // Check if the alternate has an ID (same logical instance)\n if (fiber.alternate) {\n sourceId = this.idMap.get(fiber.alternate);\n if (sourceId) {\n // Map current fiber to the same ID\n this.idMap.set(fiber, sourceId);\n return sourceId;\n }\n }\n\n // Get or assign a numeric ID for this type (avoid stringifying functions!)\n // WeakMap keys must be objects/functions only. Strings/symbols/null get an\n // ephemeral numeric id for this pass but are never inserted into the WeakMap.\n const canBeWeakMapKey = (typeof type === 'object' && type !== null) || typeof type === 'function';\n const weakKey = canBeWeakMapKey ? (type as object | Function) : null;\n let typeId = weakKey ? this.typeToId.get(weakKey) : undefined;\n\n if (typeId === undefined) {\n typeId = this.nextTypeId++;\n if (weakKey) {\n this.typeToId.set(weakKey, typeId);\n }\n }\n\n // New instance - create ID with per-component-type counter\n const baseKey = `${typeId}@${depth}`;\n const instanceNum = this.instanceCounters.get(baseKey) || 1;\n this.instanceCounters.set(baseKey, instanceNum + 1);\n sourceId = `T${typeId}#${instanceNum}@${depth}`;\n\n // Map both current and alternate to this ID\n this.idMap.set(fiber, sourceId);\n if (fiber.alternate) {\n this.idMap.set(fiber.alternate, sourceId);\n }\n\n return sourceId;\n }\n\n clear() {\n this.instanceCounters.clear();\n this.typeToId = new WeakMap();\n this.nextTypeId = 1;\n }\n }\n\n const sourceIdManager = new StableSourceIdManager();\n const debugRender = createDebugRender();\n const interactionCapture = createInteractionCapture(options);\n\n function getComponentDisplayName(type: ComponentType | null | undefined): string {\n if (!type) return 'Unknown';\n return (type as { displayName?: string; name?: string }).displayName ||\n (type as { displayName?: string; name?: string }).name ||\n String(type);\n }\n\n function isDebugInternalFrame(frame: StackFrame, componentName: string): boolean {\n const name = frame.name || '';\n // Replay can run before install(), so fall back to the configured adapter.\n return !!(metricsAdapter ?? resolveMetricsAdapter())?.frameFilters?.includes(name) ||\n name === 'record' ||\n name === componentName ||\n name.includes('react-dom') ||\n name.includes('renderWithHooks') ||\n name.includes('mount') ||\n name.includes('update');\n }\n\n function parentFramesForEvent(event: HookCallEvent, componentName: string): StackFrame[] {\n return event.frames.filter((frame) => !isDebugInternalFrame(frame, componentName));\n }\n\n /** Snapshot the adapter's counters, or null when no adapter surface is live. */\n function captureMetricsSnapshot(): CommitMetricsSnapshot | null {\n return metricsAdapter?.snapshot() ?? null;\n }\n\n /**\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 CRITICAL: Understanding fiber.alternate and the \"swap\" problem \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * WHAT WE THOUGHT:\n * \"fiber and fiber.alternate swap on every commit, so alternate always\n * has state from the previous commit.\"\n *\n * WHAT ACTUALLY HAPPENS (from React Fiber Architecture docs):\n * \"At any time, a component instance has at most two fibers:\n * the current (flushed) fiber, and the work-in-progress fiber.\n * The alternate of the current fiber is the work-in-progress,\n * and the alternate of the work-in-progress is the current fiber.\"\n *\n * THE TRAP:\n * The alternate is only UPDATED when React uses it as work-in-progress.\n * If a component re-renders due to parent/context (not self-update),\n * React may or may NOT touch its alternate depending on:\n * - Whether the component is on the \"render path\"\n * - Whether React chose to clone vs reuse the fiber\n * - Concurrent mode interruptions\n * - Suspense/Offscreen boundaries\n *\n * CONCRETE EXAMPLE:\n * Commit 1: Component mounts, state = 'initial'\n * Commit 2: Component calls setState('loaded') via useEffect\n * Commit 3-10: Parent re-renders, component re-renders (but no state change)\n *\n * On commit 10, if we compare fiber vs alternate:\n * - fiber.memoizedState = 'loaded' (current)\n * - alternate.memoizedState = ???\n * - MIGHT be 'loaded' (if alternate was used as work-in-progress recently)\n * - MIGHT be 'initial' (if alternate is stale from commit 1!)\n *\n * Result: FALSE POSITIVE - we detect \"state changed\" when it didn't!\n *\n * SYMPTOMS OF THIS BUG:\n * - causedUpdates: 6 when real updates were 1\n * - updateHistory full of \"repeat\" entries\n * - collateralByCommit has entries for commits where component wasn't initiator\n * - memoizedUpdaters disagrees with our detection\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 WHY CAN'T WE JUST USE memoizedUpdaters? \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * You might think: \"React has `root.memoizedUpdaters` - a Set<Fiber> of\n * components that triggered updates. Why not just use that?\"\n *\n * THE CATCH: memoizedUpdaters is ONLY populated when React DevTools is present!\n *\n * From react-dom source:\n * var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';\n *\n * function addFiberToLanesMap(root, fiber, lanes) {\n * if (!isDevToolsPresent) {\n * return; // \u2190 EARLY RETURN! updaters never populated!\n * }\n * // ... adds to pendingUpdatersLaneMap, eventually to memoizedUpdaters\n * }\n *\n * This means:\n * - Users WITH React DevTools installed: memoizedUpdaters works \u2705\n * - Users WITHOUT DevTools: memoizedUpdaters is EMPTY \u274C\n *\n * THE ADOPTION DILEMMA:\n * To force memoizedUpdaters to work, we'd need to inject:\n * globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { ... }\n *\n * Problems with this approach:\n * - Must be done BEFORE React loads (timing sensitive)\n * - Side effect that might interfere with real DevTools\n * - Side effect that might block tool adoption/approval\n * - Cannot be done lazily (React checks once at startup)\n *\n * SOLUTION:\n * Track our own \"last seen state\" per fiber. Update it on EVERY commit\n * where the fiber renders. Compare against OUR snapshot, not alternate.\n * This gives us accurate \"previous state\" regardless of alternate staleness.\n *\n * DUAL-MODE STRATEGY:\n * - When memoizedUpdaters available (DevTools users): Trust React completely\n * - When memoizedUpdaters empty (everyone else): Use lastSeenHookState\n *\n * This approach:\n * \u2705 Zero side effects - no DevTools hook injection required\n * \u2705 Zero false positives - accurate for all users\n * \u2705 Adoptable by any project - no special requirements\n * \u2705 Graceful dual-mode - best of both worlds\n *\n * The ~100 lines of lastSeenHookState code are NOT over-engineering.\n * Without them, users without DevTools would see 10x false positives\n * (e.g., 100 source detections instead of 10 in typical scenarios).\n *\n * References:\n * - https://github.com/acdlite/react-fiber-architecture\n * - https://jser.dev/2023-07-18-how-react-rerenders/\n * - https://jser.dev/2023-06-19-how-does-usestate-work/\n */\n const lastSeenHookState = new WeakMap<Fiber, unknown[]>();\n\n /**\n * Capture current hook state chain as an array of memoizedState values.\n * Used to track what state we've \"seen\" for this fiber.\n */\n function captureHookStateSnapshot(fiber: Fiber): unknown[] {\n const snapshot: unknown[] = [];\n let hook = fiber.memoizedState;\n while (hook) {\n snapshot.push(hook.memoizedState);\n hook = hook.next;\n }\n return snapshot;\n }\n\n /**\n * Compare current hook state against our last-seen snapshot.\n * Returns indices of hooks that changed since we last saw this fiber.\n */\n function detectChangesFromLastSeen(\n fiber: Fiber,\n currentSnapshot: unknown[]\n ): { changedIndices: number[]; changedHooks: ChangedHook[] } {\n const lastSeen =\n lastSeenHookState.get(fiber) || (fiber.alternate && lastSeenHookState.get(fiber.alternate));\n\n const changedIndices: number[] = [];\n const changedHooks: ChangedHook[] = [];\n\n if (!lastSeen) {\n // First time seeing this fiber - no changes to report\n return { changedIndices, changedHooks };\n }\n\n // Compare each hook\n const maxLen = Math.max(lastSeen.length, currentSnapshot.length);\n for (let i = 0; i < maxLen; i++) {\n const prev = lastSeen[i];\n const curr = currentSnapshot[i];\n\n if (!Object.is(prev, curr)) {\n changedIndices.push(i);\n changedHooks.push({ prevValue: prev, currentValue: curr });\n }\n }\n\n return { changedIndices, changedHooks };\n }\n\n const state: ProfilerState = {\n commits: 0,\n sources: new Map(),\n amplifiers: new Map(),\n amplifierSources: new Map(),\n thrashCounts:\n thrashMode === 'counts'\n ? { totalHooks: 0, affectedComponents: new Set<ComponentType>() }\n : null,\n memoizedUpdatersAvailable: false,\n commitsWithMemoizedUpdaters: 0,\n // Per-commit stats: [collateral, effects, memos, callbacks]\n commitStats: {},\n // Per-commit adapter counter deltas\n metricsByCommit: {},\n lastMetricsSnapshot: null,\n // Per-commit timing data\n commitTimings: {},\n lastCommitEndTime: performance.now(),\n // Per-commit Suspense boundary transitions\n suspenseByCommit: {},\n unmountsByCommit: {},\n interactionActions: interactionCapture.state.actions,\n interactionsByCommit: interactionCapture.state.byCommit,\n renderedByCommit: {},\n };\n\n // Helper: push to history and trim if needed (called in aggregation, not hot path)\n function _pushToHistory<T>(history: T[], item: T, limit: number): void {\n history.push(item);\n if (history.length > limit) {\n history.splice(0, history.length - limit);\n }\n }\n\n type UpdateHistory = Record<\n number,\n Record<number, import('./internals.tsx').ChangedHook> | 'repeat' | string\n >;\n\n function trimHistoryToSize(updHistory: UpdateHistory, limit: number): UpdateHistory {\n const keys = Object.keys(updHistory)\n .map(Number)\n .sort((a, b) => a - b);\n const keysToKeep = keys.slice(keys.length - limit);\n const trimmed: UpdateHistory = {};\n keysToKeep.forEach((key) => {\n trimmed[key] = updHistory[key];\n });\n return trimmed;\n }\n\n function findLastConcreteHook(\n history: UpdateHistory,\n hookIndex: number,\n beforeCommitId: number\n ): ChangedHook | null {\n const commitIds = Object.keys(history)\n .map(Number)\n .filter((id) => id < beforeCommitId)\n .sort((a, b) => b - a);\n\n for (const commitId of commitIds) {\n const entry = history[commitId];\n if (entry && entry !== 'repeat' && typeof entry !== 'string') {\n const prev = entry[hookIndex];\n if (prev && prev !== 'repeat' && typeof prev === 'object') return prev;\n }\n }\n\n return null;\n }\n\n function summarizePropValue(value: unknown): PropValueSummary {\n const isArray = Array.isArray(value);\n const type = value === null ? 'null' : isArray ? 'array' : typeof value;\n const isFunction = typeof value === 'function';\n const isNull = value === null;\n const isPrimitive = value == null ||\n type === 'string' ||\n type === 'number' ||\n type === 'boolean' ||\n type === 'undefined' ||\n type === 'symbol' ||\n type === 'bigint';\n const primitiveDisplay = isPrimitive ? String(value) : undefined;\n const summary: PropValueSummary = {\n type,\n isArray,\n isFunction,\n isNull,\n preview: primitiveDisplay || (isFunction ? 'function' : isArray ? `array(${value.length})` : 'object'),\n };\n\n if (primitiveDisplay !== undefined) {\n summary.display = primitiveDisplay;\n }\n if (typeof value === 'string' || isArray) {\n summary.length = value.length;\n }\n if (isArray) {\n summary.sample = value.slice(0, 3).map((item) => summarizePropValue(item).preview);\n } else if (value && typeof value === 'object') {\n const keys = Object.keys(value as Record<string, unknown>).slice(0, 5);\n summary.keysTop = keys;\n summary.length = Object.keys(value as Record<string, unknown>).length;\n if (keys.length > 0) {\n summary.preview = `object{${keys.join(',')}}`;\n }\n } else if (isFunction) {\n const fn = value as Function;\n summary.preview = fn.name ? `function ${fn.name}` : 'function';\n }\n return summary;\n }\n\n function diffProps(prevProps: unknown, currentProps: unknown): PropChangeEvidence[] {\n const changes: PropChangeEvidence[] = [];\n const prev = prevProps && typeof prevProps === 'object' ? prevProps as Record<string, unknown> : {};\n const current = currentProps && typeof currentProps === 'object' ? currentProps as Record<string, unknown> : {};\n const keys = new Set([...Object.keys(prev), ...Object.keys(current)]);\n\n keys.forEach((name) => {\n const prevHas = Object.prototype.hasOwnProperty.call(prev, name);\n const currentHas = Object.prototype.hasOwnProperty.call(current, name);\n const prevValue = prev[name];\n const currentValue = current[name];\n if (!prevHas && currentHas) {\n changes.push({ name, kind: 'added', prev: summarizePropValue(undefined), current: summarizePropValue(currentValue) });\n } else if (prevHas && !currentHas) {\n changes.push({ name, kind: 'removed', prev: summarizePropValue(prevValue), current: summarizePropValue(undefined) });\n } else if (Object.is(prevValue, currentValue)) {\n // Evidence surface records changes only; unchanged props stay implicit.\n } else if (\n prevValue !== null && currentValue !== null &&\n (typeof prevValue === 'object' || typeof prevValue === 'function' ||\n typeof currentValue === 'object' || typeof currentValue === 'function')\n ) {\n changes.push({ name, kind: 'ref-changed', prev: summarizePropValue(prevValue), current: summarizePropValue(currentValue) });\n } else {\n changes.push({ name, kind: 'scalar-changed', prev: summarizePropValue(prevValue), current: summarizePropValue(currentValue) });\n }\n });\n\n return changes;\n }\n\n function pushUpdateHistory(\n updHistory: UpdateHistory,\n commitId: number,\n changedHookIndices: number[],\n changedHooks: import('./internals.tsx').ChangedHook[]\n ): UpdateHistory {\n const entry: Record<number, import('./internals.tsx').ChangedHook> = {};\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n for (let i = 0; i < changedHookIndices.length; i++) {\n const hookIndex = changedHookIndices[i];\n const hook = changedHooks[i];\n\n if (hook === 'repeat') {\n entry[hookIndex] = 'repeat';\n } else {\n const prevConcrete = findLastConcreteHook(updHistory, hookIndex, commitId);\n entry[hookIndex] =\n prevConcrete &&\n typeof prevConcrete === 'object' &&\n Object.is(hook.prevValue, prevConcrete.prevValue) &&\n Object.is(hook.currentValue, prevConcrete.currentValue)\n ? 'repeat'\n : hook;\n }\n }\n\n const newEntry = Object.values(entry).every((v) => v === 'repeat') ? 'repeat' : entry;\n return { ...updHistory, [commitId]: newEntry };\n }\n\n function recordTree(rootFiber: Fiber, memoizedUpdaters: Set<Fiber> | null = null): number {\n // NOTE: This function is intentionally monolithic for performance.\n // Keep inner loops allocation-free and avoid helper calls.\n\n // Track if memoizedUpdaters is available\n if (memoizedUpdaters && memoizedUpdaters.size > 0) {\n state.memoizedUpdatersAvailable = true;\n state.commitsWithMemoizedUpdaters++;\n }\n\n const perCommit = {\n selfUpdated: new Map<\n string,\n {\n type: ComponentType;\n depth: number;\n count: number;\n changedHookIndices: number[];\n changedHooks: ChangedHook[];\n fiber?: Fiber;\n isUpdater: boolean;\n }\n >(),\n thrashing: new Map<\n ComponentType,\n {\n instanceCount: number;\n hookCount: number;\n lastAmplification: { depth: number; thrashedHooks: ThrashInfo[]; fiber?: Fiber };\n }\n >(),\n /** Linked thrashing: keyed by sourceId, tracks per-component thrashing with linkage */\n linkedThrashing: new Map<\n string,\n {\n type: ComponentType;\n depth: number;\n effects: number;\n callbacks: number;\n memos: number;\n causedBySourceId: string | null;\n lastAmplification: { depth: number; thrashedHooks: ThrashInfo[]; fiber?: Fiber };\n }\n >(),\n rendered: [] as RenderedComponentEvidence[],\n selfFibers: new WeakMap<Fiber, number>(),\n sourceFibers: new Set<Fiber>(), // Track source fibers to exclude from collateral count\n blastBySourceId: new Map<string, number>(),\n depthBySourceId: new Map<string, number>(),\n // Simple counts for commitStats\n totalCollateral: 0,\n committedComponentCount: 0, // Components with PerformedWork that committed\n effectCount: 0,\n memoCount: 0,\n callbackCount: 0,\n contextUpdates: 0,\n // Unmount tracking (populated by deletions-array walk in visit())\n unmountedComponents: 0,\n unmountedSubtrees: 0,\n // Bounded identity samples for branch starts (topmost component fibers in\n // each deleted subtree). Cap to keep payload small.\n unmountSamples: null as UnmountSample[] | null,\n // Suspense boundary transition events collected during this commit's visit pass\n suspenseEvents: null as SuspenseBoundaryEvent[] | null,\n };\n\n // -------------------------------------------------------------------------\n // COMBINED PASS: Identify sources + attribute blast (O(n) not O(n*depth))\n // -------------------------------------------------------------------------\n function visit(\n fiber: Fiber | null,\n depth: number = 0,\n currentOwnerSourceId: string | null = null\n ) {\n if (!fiber) return;\n\n // OPTIMIZATION: Skip subtrees with no PerformedWork using subtreeFlags\n // React uses subtreeFlags to propagate flags up the tree. If neither the fiber\n // nor its subtree have PerformedWork (flag 0x1), we can skip this entire branch.\n // This matches React's own optimization during commit phase.\n //\n // Exception 1: Suspense fibers use DidCapture (128) not PerformedWork when suspending.\n // Exception 2: Fibers with ChildDeletion in subtreeFlags have deletions to track.\n // eslint-disable-next-line no-bitwise -- React fiber flags are bitmasks, bitwise AND is required\n const hasWorkInSubtree =\n // eslint-disable-next-line no-bitwise -- React fiber flags are bitmasks, bitwise AND is required\n (fiber.flags & PerformedWork) !== 0 ||\n // eslint-disable-next-line no-bitwise\n (fiber.subtreeFlags & PerformedWork) !== 0 ||\n // fiber.flags & ChildDeletion = this fiber has children being deleted this commit\n // (React sets ChildDeletion on fiber.flags, NOT subtreeFlags, at commit time)\n // eslint-disable-next-line no-bitwise\n (fiber.flags & ChildDeletion) !== 0 ||\n // subtreeFlags propagation \u2014 some descendant has deletions\n // eslint-disable-next-line no-bitwise\n (fiber.subtreeFlags & ChildDeletion) !== 0 ||\n // Suspense transitioning: React sets Update (4) on the Suspense fiber's flags at commit.\n // eslint-disable-next-line no-bitwise\n (isSuspenseFiber(fiber.tag) && (fiber.flags & Update) !== 0) ||\n // subtreeFlags & Update: a descendant (e.g. Suspense) received an Update this commit.\n // React propagates subtreeFlags upward \u2014 HostRoot and all intermediate host fibers\n // will have Update bit set if any descendant has it. This ensures we don't skip\n // the path to a Suspense boundary when no PerformedWork exists higher in the tree.\n // eslint-disable-next-line no-bitwise\n (fiber.subtreeFlags & Update) !== 0;\n if (!hasWorkInSubtree) {\n // No work in this fiber or its descendants - skip entire subtree\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.sibling) visit(fiber.sibling, depth, currentOwnerSourceId);\n return;\n }\n\n // Check for context provider value changes\n if (isContextProviderFiber(fiber.tag) && didContextValueChange(fiber)) {\n perCommit.contextUpdates++;\n }\n\n // Unmount detection via fiber.deletions.\n // React populates fiber.deletions[] during the render phase for fibers that\n // will be deleted in this commit. At commit time, React sets ChildDeletion (16)\n // on fiber.flags (NOT subtreeFlags) of the parent holding the deletions.\n // fiber.deletions is the list of child fibers being removed.\n // eslint-disable-next-line no-bitwise\n if ((fiber.flags & ChildDeletion) !== 0 && fiber.deletions && fiber.deletions.length > 0) {\n for (let di = 0; di < fiber.deletions.length; di++) {\n const deleted = fiber.deletions[di];\n // Walk the entire deleted subtree to collect all component fibers being removed.\n // We track whether a fiber's parent (in the deleted subtree) is also a component\n // so we can identify branch starts.\n function collectDeletions(\n df: Fiber,\n parentIsComponent: boolean,\n branchStartDepth: number,\n currentBranch: { count: number; sample: typeof perCommit.unmountSamples extends (infer A)[] | null ? A : never } | null\n ): void {\n const dfIsComponent = isComponentFiber(df.tag);\n let nextBranch = currentBranch;\n if (dfIsComponent) {\n perCommit.unmountedComponents++;\n if (!parentIsComponent) {\n // This is a branch start: topmost component in the deleted subtree\n perCommit.unmountedSubtrees++;\n if (perCommit.unmountSamples == null) perCommit.unmountSamples = [];\n if (perCommit.unmountSamples.length < 30) {\n const fiberKey = (df as unknown as { key?: string | number | null }).key;\n const sample = {\n name: getComponentName(df),\n key: fiberKey == null ? null : String(fiberKey),\n depth: branchStartDepth,\n count: 1,\n source: summarizeFiberSource(df),\n host: summarizeHostSubtree(df),\n };\n perCommit.unmountSamples.push(sample);\n nextBranch = { count: 1, sample } as any;\n } else {\n nextBranch = null;\n }\n } else if (currentBranch && currentBranch.sample) {\n currentBranch.sample.count++;\n }\n // Clean up last-seen hook state so future remounts start fresh\n lastSeenHookState.delete(df);\n if (df.alternate) lastSeenHookState.delete(df.alternate);\n }\n if (df.child) collectDeletions(df.child, dfIsComponent, branchStartDepth + 1, nextBranch);\n if (df.sibling) collectDeletions(df.sibling, parentIsComponent, branchStartDepth, currentBranch);\n }\n // Add one branch-level sample for the deleted subtree. React can hand us\n // a host/text wrapper as the deletion root, so find the first component\n // descendant to label the branch.\n if (perCommit.unmountSamples == null) perCommit.unmountSamples = [];\n if (perCommit.unmountSamples.length < 30) {\n let labelFiber: Fiber | null = deleted;\n if (!isComponentFiber(labelFiber.tag)) {\n const stack: Fiber[] = [labelFiber];\n labelFiber = null;\n while (stack.length) {\n const f = stack.pop()!;\n if (isComponentFiber(f.tag)) { labelFiber = f; break; }\n if (f.child) stack.push(f.child);\n if (f.sibling) stack.push(f.sibling);\n }\n }\n if (labelFiber) {\n const counts = countUnmountedComponentSubtree(deleted);\n const fiberKey = (labelFiber as unknown as { key?: string | number | null }).key;\n perCommit.unmountSamples.push({\n name: getComponentName(labelFiber),\n key: fiberKey == null ? null : String(fiberKey),\n depth,\n count: counts.components,\n source: summarizeFiberSource(labelFiber),\n host: summarizeHostSubtree(deleted),\n });\n }\n }\n collectDeletions(deleted, false, depth, null);\n }\n }\n\n const isComponent = isComponentFiber(fiber.tag);\n let ownerSourceId = currentOwnerSourceId;\n\n // Suspense boundary transition detection.\n // Only fires when the boundary actually entered or left the fallback state.\n // Boundaries that render without delay (memoizedState stays null) are silent.\n if (isSuspenseFiber(fiber.tag)) {\n const suspenseChange = didSuspenseStateChange(fiber);\n if (suspenseChange) {\n // Record the boundary transition for this commit\n if (!perCommit.suspenseEvents) {\n perCommit.suspenseEvents = [];\n }\n const event: SuspenseBoundaryEvent = {\n depth,\n entered: suspenseChange.entered,\n left: suspenseChange.left,\n ...(captureFibers && { fiber }),\n };\n perCommit.suspenseEvents.push(event);\n\n // Treat a Suspense boundary state-change as a source.\n // We use a synthetic stable key that encodes type+depth so the same boundary\n // accumulates across commits (same logic as regular sources).\n // The type sentinel is the React.Suspense symbol on the fiber.\n if (enableSourceTracking) {\n const suspenseType = fiber.type; // symbol \u2014 stable across renders\n const sourceId = sourceIdManager.getSourceId(fiber, suspenseType, depth);\n const suspenseHook: ChangedHook = {\n prevValue: suspenseChange.left ? 'suspended' : null,\n currentValue: suspenseChange.entered ? 'suspended' : null,\n info: suspenseChange.entered ? 'suspense:entered-fallback' : 'suspense:left-fallback',\n };\n perCommit.selfUpdated.set(sourceId, {\n type: suspenseType,\n depth,\n count: 1,\n changedHookIndices: [0],\n changedHooks: [suspenseHook],\n fiber: captureFibers ? fiber : undefined,\n isUpdater: true,\n });\n ownerSourceId = sourceId;\n }\n }\n }\n\n if (isComponent) {\n const type = fiber.type;\n\n // Count components with PerformedWork (committed work)\n if (didFiberUpdate(fiber)) {\n perCommit.committedComponentCount++;\n }\n\n // Early bailout: skip components that didn't update (no PerformedWork flag)\n if (!didFiberUpdate(fiber)) {\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.child) visit(fiber.child, depth + 1, ownerSourceId);\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.sibling) visit(fiber.sibling, depth, currentOwnerSourceId);\n return;\n }\n\n if (!ignoreSet.has(type) && !isReactInternalComponentType(type)) {\n const componentSourceId = sourceIdManager.getSourceId(fiber, type, depth);\n const parentFiber = fiber.return && isComponentFiber(fiber.return.tag) ? fiber.return : null;\n const parentSourceId = parentFiber\n ? sourceIdManager.getSourceId(parentFiber, parentFiber.type, depth - 1)\n : null;\n const existingRenderEvidenceIndex = perCommit.rendered.findIndex(\n (entry) => entry.sourceId === componentSourceId\n );\n const initialRenderEvidence: RenderedComponentEvidence = {\n sourceId: componentSourceId,\n name: getComponentName(fiber),\n depth,\n parentSourceId,\n ownerSourceId,\n isSelfSource: false,\n propChanges: fiber.alternate ? diffProps(fiber.alternate.memoizedProps, fiber.memoizedProps) : [],\n hasPropChanges: false,\n trasherCounts: { effects: 0, callbacks: 0, memos: 0 },\n };\n initialRenderEvidence.hasPropChanges = initialRenderEvidence.propChanges.length > 0;\n if (existingRenderEvidenceIndex >= 0) {\n perCommit.rendered[existingRenderEvidenceIndex] = initialRenderEvidence;\n } else {\n perCommit.rendered.push(initialRenderEvidence);\n }\n\n // Track provenance of useCallback/useMemo results (only if amplifier detection enabled)\n if (enableAmplifiers) {\n let hook = fiber.memoizedState;\n let hookIndex = 0;\n\n while (hook) {\n const ms = hook.memoizedState;\n if (Array.isArray(ms) && ms.length === 2 && Array.isArray(ms[1])) {\n const result = ms[0];\n if (\n result != null &&\n (typeof result === 'object' || typeof result === 'function')\n ) {\n valueProvenance.set(result, {\n type,\n hookIndex,\n depth,\n hookType: typeof result === 'function' ? 'useCallback' : 'useMemo',\n });\n }\n }\n\n hook = hook.next;\n hookIndex++;\n }\n }\n\n // Source tracking (Level 2+): Capture hook state and detect sources\n // Skip entirely in 'stats' mode for maximum performance\n let currentHookSnapshot: unknown[] | null = null;\n if (enableSourceTracking) {\n currentHookSnapshot = captureHookStateSnapshot(fiber);\n }\n\n // Source detection strategy (Level 2+):\n // 1. If memoizedUpdaters available (development): trust it completely\n // 2. If memoizedUpdaters NOT available (production): use our own lastSeenHookState\n // to avoid fiber.alternate lag false positives\n // Skip entirely in 'stats' mode (Level 1)\n\n let isRealSource = false;\n let changedIndices: number[] = [];\n let changedHooks: ChangedHook[] = [];\n\n if (enableSourceTracking) {\n const inMemoizedUpdaters = memoizedUpdaters\n ? memoizedUpdaters.has(fiber) ||\n (fiber.alternate && memoizedUpdaters.has(fiber.alternate))\n : null;\n\n if (memoizedUpdaters) {\n // DEVELOPMENT: Trust memoizedUpdaters completely\n if (inMemoizedUpdaters) {\n isRealSource = true;\n // Use didFiberSelfUpdate for the hook change details\n const selfUpdateResult = didFiberSelfUpdate(fiber);\n if (selfUpdateResult && selfUpdateResult.actionable) {\n changedIndices = selfUpdateResult.changedIndices;\n changedHooks = selfUpdateResult.changedHooks;\n }\n }\n // If not in memoizedUpdaters, skip this fiber as source\n } else {\n // PRODUCTION: Use our own tracking to avoid alternate lag\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const changes = detectChangesFromLastSeen(fiber, currentHookSnapshot!);\n if (changes.changedIndices.length > 0) {\n isRealSource = true;\n changedIndices = changes.changedIndices;\n changedHooks = changes.changedHooks;\n }\n }\n\n // Update our last-seen snapshot for this fiber (always, even if not a source)\n // This ensures we have accurate \"previous state\" for next commit\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n lastSeenHookState.set(fiber, currentHookSnapshot!);\n if (fiber.alternate) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n lastSeenHookState.set(fiber.alternate, currentHookSnapshot!);\n }\n }\n\n if (isRealSource && changedIndices.length > 0) {\n const sourceId = componentSourceId;\n\n // Track that this fiber is a source (so we don't count it as its own collateral)\n perCommit.sourceFibers.add(fiber);\n if (fiber.alternate) {\n perCommit.sourceFibers.add(fiber.alternate);\n }\n\n const existing = perCommit.selfUpdated.get(sourceId);\n\n const updateData = {\n type,\n depth,\n count: (existing?.count || 0) + 1,\n changedHookIndices: changedIndices,\n changedHooks: changedHooks,\n fiber: captureFibers ? fiber : undefined,\n isUpdater: true,\n };\n\n perCommit.selfUpdated.set(sourceId, updateData);\n perCommit.selfFibers.set(fiber, depth);\n\n // This fiber is now the owner for all descendants\n ownerSourceId = sourceId;\n }\n\n // Blast radius attribution: if this fiber updated and we have an owner, attribute it\n // ONLY count component fibers (not host nodes like div, span, etc.)\n // DON'T count if this fiber IS the owner (don't count source as its own collateral!)\n const isSourceItself = perCommit.sourceFibers.has(fiber);\n\n // Don't count mount/hydration work as \"collateral\" (not preventable).\n // eslint-disable-next-line no-bitwise\n const isNonPreventable = (fiber.flags & (Placement | Hydrating)) !== 0;\n\n if (\n isComponent &&\n fiber.alternate &&\n didFiberUpdate(fiber) &&\n ownerSourceId &&\n !isSourceItself &&\n !isNonPreventable\n ) {\n perCommit.blastBySourceId.set(\n ownerSourceId,\n (perCommit.blastBySourceId.get(ownerSourceId) || 0) + 1\n );\n\n const currentMax = perCommit.depthBySourceId.get(ownerSourceId) || 0;\n if (depth > currentMax) {\n perCommit.depthBySourceId.set(ownerSourceId, depth);\n }\n\n // Count total collateral for commitStats\n perCommit.totalCollateral++;\n }\n\n const renderedEntry = perCommit.rendered.find((entry) => entry.sourceId === componentSourceId);\n if (renderedEntry) {\n renderedEntry.ownerSourceId = ownerSourceId;\n renderedEntry.isSelfSource = isRealSource && changedIndices.length > 0;\n }\n\n // Amplifier detection (Level 3: counts/full).\n // Skip in 'stats' and 'sources' modes for better performance\n if (enableAmplifiers && didFiberUpdate(fiber) && fiber.alternate) {\n const thrashResult = detectHookThrashing(\n fiber.alternate.memoizedState,\n fiber.memoizedState,\n effectThrashMode,\n valueProvenance\n );\n\n const totalThrashing =\n thrashResult.effects.length +\n thrashResult.callbacks.length +\n thrashResult.memos.length;\n\n if (totalThrashing > 0) {\n if (thrashMode === 'counts') {\n if (state.thrashCounts) {\n state.thrashCounts.affectedComponents.add(type);\n state.thrashCounts.totalHooks += totalThrashing;\n }\n } else if (thrashMode === 'full') {\n const allThrashedHooks: ThrashInfo[] = [\n ...thrashResult.effects,\n ...thrashResult.callbacks,\n ...thrashResult.memos,\n ];\n\n // Legacy amplifiers (keyed by type)\n const existing = perCommit.thrashing.get(type);\n const thrashData = {\n instanceCount: (existing?.instanceCount || 0) + 1,\n hookCount: (existing?.hookCount || 0) + totalThrashing,\n lastAmplification: {\n depth,\n thrashedHooks: allThrashedHooks,\n fiber: captureFibers ? fiber : undefined,\n },\n };\n\n perCommit.thrashing.set(type, thrashData);\n\n // NEW: Linked amplification (keyed by sourceId)\n // Get or create sourceId for this fiber (even if not a source)\n const amplifierSourceId = sourceIdManager.getSourceId(fiber, type, depth);\n const existingLinked = perCommit.linkedThrashing.get(amplifierSourceId);\n\n const effects = (existingLinked?.effects || 0) + thrashResult.effects.length;\n const callbacks = (existingLinked?.callbacks || 0) + thrashResult.callbacks.length;\n const memos = (existingLinked?.memos || 0) + thrashResult.memos.length;\n perCommit.linkedThrashing.set(amplifierSourceId, {\n type,\n depth,\n effects,\n callbacks,\n memos,\n // If this fiber is a source, causedBySourceId is null (self-caused)\n // If this fiber is collateral, ownerSourceId is who caused it\n causedBySourceId: isRealSource ? null : ownerSourceId,\n lastAmplification: {\n depth,\n thrashedHooks: allThrashedHooks,\n fiber: captureFibers ? fiber : undefined,\n },\n });\n\n const renderedEntry = perCommit.rendered.find((entry) => entry.sourceId === amplifierSourceId);\n if (renderedEntry) {\n renderedEntry.trasherCounts = { effects, callbacks, memos };\n }\n\n // Count amplifiers for commitStats\n perCommit.effectCount += thrashResult.effects.length;\n perCommit.memoCount += thrashResult.memos.length;\n perCommit.callbackCount += thrashResult.callbacks.length;\n }\n }\n }\n }\n }\n\n // Propagate current owner to children (depth changes)\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.child) visit(fiber.child, depth + 1, ownerSourceId);\n // Siblings stay at same depth and inherit parent's owner\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.sibling) visit(fiber.sibling, depth, currentOwnerSourceId);\n }\n\n visit(rootFiber);\n\n // -------------------------------------------------------------------------\n // PASS 3: Update global aggregates (not hot loop).\n // -------------------------------------------------------------------------\n state.commits++;\n\n for (const [sourceId, data] of perCommit.selfUpdated.entries()) {\n const { type, depth, count, changedHookIndices, fiber } = data;\n\n let s = state.sources.get(sourceId);\n if (!s) {\n s = {\n type,\n depth,\n renderCount: 0,\n causedUpdates: 0,\n collateralUpdates: 0,\n maxCollateralUpdates: 0,\n maxPenetrationDepth: 0,\n updateHistory: {},\n collateralByCommit: {}, // Per-commit collateral for this source\n debugHookIndices: changedHookIndices.slice(),\n };\n state.sources.set(sourceId, s);\n }\n\n s.renderCount++;\n s.debugHookIndices = changedHookIndices.slice();\n\n // Store update history for this commit - this determines if it's a \"repeat\" or new update\n const historyWithUpdate = pushUpdateHistory(\n s.updateHistory,\n state.commits,\n changedHookIndices,\n data.changedHooks\n );\n s.updateHistory = trimHistoryToSize(historyWithUpdate, historySize);\n\n // Check if this commit was a REAL update or just a \"repeat\"\n // Only count causedUpdates and collateral for REAL updates\n const thisCommitEntry = s.updateHistory[state.commits];\n const isRepeat = thisCommitEntry === 'repeat';\n\n if (!isRepeat && data.isUpdater) {\n // This is a NEW update (not a repeat) - count it\n s.causedUpdates += count;\n\n const blast = perCommit.blastBySourceId.get(sourceId) || 0;\n s.collateralUpdates += blast;\n if (blast > s.maxCollateralUpdates) s.maxCollateralUpdates = blast;\n\n // Store per-commit collateral for this source (only for real updates)\n s.collateralByCommit[state.commits] = blast;\n\n const penetrationDepth = perCommit.depthBySourceId.get(sourceId) || 0;\n if (penetrationDepth > s.maxPenetrationDepth) {\n s.maxPenetrationDepth = penetrationDepth;\n }\n }\n\n if (captureFibers && fiber) {\n s.fiber = fiber;\n }\n }\n\n if (enableAmplifiers && thrashMode === 'full') {\n // Legacy thrashers (keyed by type)\n for (const [type, data] of perCommit.thrashing.entries()) {\n let s = state.amplifiers.get(type);\n if (!s) {\n s = {\n renderCount: 0,\n instancesTotal: 0,\n maxInstancesPerCommit: 0,\n hooksTotal: 0,\n maxHooksPerCommit: 0,\n effectCount: 0,\n callbackCount: 0,\n memoCount: 0,\n lastAmplification: { depth: 0, thrashedHooks: [] },\n };\n state.amplifiers.set(type, s);\n }\n\n s.renderCount++;\n s.instancesTotal += data.instanceCount;\n s.hooksTotal += data.hookCount;\n if (data.instanceCount > s.maxInstancesPerCommit)\n s.maxInstancesPerCommit = data.instanceCount;\n if (data.hookCount > s.maxHooksPerCommit) s.maxHooksPerCommit = data.hookCount;\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n data.lastAmplification.thrashedHooks.forEach((hook: ThrashInfo) => {\n if (hook.hookType === 'effect') s.effectCount++;\n else if (hook.hookType === 'callback') s.callbackCount++;\n else if (hook.hookType === 'memo') s.memoCount++;\n });\n\n s.lastAmplification = data.lastAmplification;\n }\n\n // NEW: Linked thrashers (keyed by sourceId)\n for (const [sourceId, data] of perCommit.linkedThrashing.entries()) {\n let as = state.amplifierSources.get(sourceId);\n if (!as) {\n as = {\n type: data.type,\n depth: data.depth,\n effectCount: 0,\n callbackCount: 0,\n memoCount: 0,\n hooksTotal: 0,\n commitIds: [],\n byCommit: {},\n causedBySourceId: data.causedBySourceId,\n lastAmplification: { depth: 0, thrashedHooks: [] },\n };\n state.amplifierSources.set(sourceId, as);\n }\n\n // Update counts\n as.effectCount += data.effects;\n as.callbackCount += data.callbacks;\n as.memoCount += data.memos;\n as.hooksTotal += data.effects + data.callbacks + data.memos;\n\n // Track which commits this amplifier fired in\n if (!as.commitIds.includes(state.commits)) {\n as.commitIds.push(state.commits);\n }\n\n // Per-commit breakdown\n as.byCommit[state.commits] = {\n effects: data.effects,\n callbacks: data.callbacks,\n memos: data.memos,\n };\n\n // Update causedBySourceId (use latest if different)\n if (data.causedBySourceId !== null) {\n as.causedBySourceId = data.causedBySourceId;\n }\n\n as.lastAmplification = data.lastAmplification;\n }\n }\n\n // Persist Suspense events for this commit\n if (perCommit.suspenseEvents && perCommit.suspenseEvents.length > 0) {\n state.suspenseByCommit[state.commits] = perCommit.suspenseEvents;\n }\n\n if (perCommit.rendered.length > 0) {\n state.renderedByCommit[state.commits] = perCommit.rendered;\n }\n\n // Store commitStats: [collateral, sources, restarts, performedWork, effects, memos, callbacks, contextUpdates, unmountedComponents, unmountedSubtrees]\n //\n // ALL fiber-walk-derived fields (collateral, sources, performedWork, effects,\n // memos, callbacks, contextUpdates) are real measurements that come from this\n // very recordTree() call. They are populated identically in 'adapter:<id>'\n // and 'devtools' integration modes \u2014 the fiber tree is the same in both.\n //\n // The ONLY adapter-exclusive field is `restarts` (index 2). It is\n // initialized to 0 here and overwritten after the adapter's delta\n // calculation in handleCommit. In 'devtools' mode there is no\n // render-counter delta available, so it stays at 0. Consumers should\n // consult report.meta.dataAvailability.restarts to disambiguate \"no\n // restarts measured\" (0 in 'devtools' mode = unknown) from \"zero restarts\n // confirmed\" (0 in 'adapter:<id>' mode = real).\n state.commitStats[state.commits] = [\n perCommit.totalCollateral,\n perCommit.selfUpdated.size, // Number of sources in this commit\n 0, // restarts - will be updated after the adapter's delta calculation\n perCommit.committedComponentCount, // performedWork - components with PerformedWork flag\n perCommit.effectCount,\n perCommit.memoCount,\n perCommit.callbackCount,\n perCommit.contextUpdates,\n perCommit.unmountedComponents,\n perCommit.unmountedSubtrees,\n ];\n\n if (perCommit.unmountSamples && perCommit.unmountSamples.length > 0) {\n state.unmountsByCommit[state.commits] = perCommit.unmountSamples;\n }\n\n // Return committed component count for restart calculation\n return perCommit.committedComponentCount;\n }\n\n function resetState(): void {\n state.commits = 0;\n state.sources.clear();\n state.amplifiers.clear();\n state.amplifierSources.clear();\n if (state.thrashCounts) {\n state.thrashCounts.totalHooks = 0;\n state.thrashCounts.affectedComponents.clear();\n }\n state.memoizedUpdatersAvailable = false;\n state.commitsWithMemoizedUpdaters = 0;\n // Clear commitStats\n for (const key of Object.keys(state.commitStats)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.commitStats[Number(key)];\n }\n // Clear adapter per-commit data\n for (const key of Object.keys(state.metricsByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.metricsByCommit[Number(key)];\n }\n // Clear timing data\n for (const key of Object.keys(state.commitTimings)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.commitTimings[Number(key)];\n }\n // Clear Suspense boundary transitions\n for (const key of Object.keys(state.suspenseByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.suspenseByCommit[Number(key)];\n }\n // Clear unmount samples\n for (const key of Object.keys(state.unmountsByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.unmountsByCommit[Number(key)];\n }\n // Clear rendered component evidence\n for (const key of Object.keys(state.renderedByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.renderedByCommit[Number(key)];\n }\n interactionCapture.reset();\n // Recapture adapter snapshot as new baseline\n state.lastMetricsSnapshot = captureMetricsSnapshot();\n // Reset timing baseline\n state.lastCommitEndTime = performance.now();\n sourceIdManager.clear();\n }\n\n type DevtoolsHook = {\n onCommitFiberRoot?: (...args: unknown[]) => void;\n onCommitFiberUnmount?: (...args: unknown[]) => void;\n [key: string]: unknown;\n };\n\n type GlobalWithDevtools = typeof globalThis & {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevtoolsHook;\n };\n\n const commitSurface = createCommitSurfaceOwnership<{\n commitId: number;\n committedComponents: number;\n metricsBefore: CommitMetricsSnapshot | null;\n }>();\n\n // Chained predecessor on the DevTools hook (real React DevTools, etc.) \u2014 so\n // augmenting the hook never breaks an existing client. Restored on uninstall.\n let devtoolsHookPrev: ((...args: unknown[]) => void) | undefined;\n let devtoolsUnmountPrev: ((...args: unknown[]) => void) | undefined;\n // Was the DevTools hook present before install()? Tells uninstall whether to\n // delete it entirely or just restore the previous handler.\n let devtoolsHookCreatedByUs = false;\n\n // React's DevTools surface reports unmounted fibers via onCommitFiberUnmount.\n // Keep a small buffer between those callbacks and the following root commit;\n // this catches deletion work even if `fiber.deletions[]` has been cleared by\n // the time onCommitFiberRoot runs.\n let pendingDevtoolsUnmounts = { components: 0, subtrees: 0 };\n let pendingDevtoolsUnmountSamples: UnmountSample[] = [];\n\n // Integration mode is OBSERVED, not declared. Starts at 'devtools' (we always\n // own the DevTools surface after install). Promoted to 'adapter:<id>' on the\n // first adapter callback that proves the host surface is actually running.\n // Returns to 'none' only on uninstall.\n let integrationMode: IntegrationMode = 'none';\n\n function countUnmountedComponentSubtree(fiber: Fiber | null, parentIsComponent = false): { components: number; subtrees: number } {\n if (!fiber) return { components: 0, subtrees: 0 };\n const isComponent = isComponentFiber(fiber.tag);\n let components = isComponent ? 1 : 0;\n let subtrees = isComponent && !parentIsComponent ? 1 : 0;\n if (fiber.child) {\n const child = countUnmountedComponentSubtree(fiber.child, isComponent);\n components += child.components;\n subtrees += child.subtrees;\n }\n if (fiber.sibling) {\n const sibling = countUnmountedComponentSubtree(fiber.sibling, parentIsComponent);\n components += sibling.components;\n subtrees += sibling.subtrees;\n }\n return { components, subtrees };\n }\n\n function summarizeHostSubtree(fiber: Fiber | null): {\n elements: number;\n text: number;\n tagsTop: Array<[string, number]>;\n testIdsTop: Array<[string, number]>;\n rolesTop: Array<[string, number]>;\n ariaLabels: string[];\n textHints: string[];\n } {\n const tags = new Map<string, number>();\n const testIds = new Map<string, number>();\n const roles = new Map<string, number>();\n const ariaLabels: string[] = [];\n const textHints: string[] = [];\n let elements = 0;\n let text = 0;\n const add = (map: Map<string, number>, key: unknown) => {\n if (typeof key !== 'string' || !key) return;\n map.set(key, (map.get(key) || 0) + 1);\n };\n const addHint = (arr: string[], value: unknown, max = 6) => {\n if (typeof value !== 'string') return;\n const trimmed = value.replace(/\\s+/g, ' ').trim();\n if (!trimmed || arr.includes(trimmed)) return;\n arr.push(trimmed.length > 80 ? `${trimmed.slice(0, 77)}\u2026` : trimmed);\n if (arr.length > max) arr.length = max;\n };\n const top = (map: Map<string, number>) => Array.from(map.entries()).sort((a, b) => b[1] - a[1]).slice(0, 6);\n const walk = (f: Fiber | null) => {\n if (!f) return;\n if (f.tag === 5) {\n elements++;\n const props = (f.memoizedProps || {}) as Record<string, unknown>;\n add(tags, typeof f.type === 'string' ? f.type : 'host');\n add(testIds, props['data-testid']);\n add(roles, props.role);\n addHint(ariaLabels, props['aria-label']);\n addHint(ariaLabels, props.title);\n addHint(textHints, typeof props.children === 'string' ? props.children : null);\n } else if (f.tag === 6) {\n text++;\n addHint(textHints, f.memoizedProps);\n }\n walk(f.child);\n walk(f.sibling);\n };\n walk(fiber);\n return { elements, text, tagsTop: top(tags), testIdsTop: top(testIds), rolesTop: top(roles), ariaLabels, textHints };\n }\n\n function recordMetricsEvidence(\n commitId: number,\n committedComponents: number,\n before: CommitMetricsSnapshot,\n after: CommitMetricsSnapshot,\n ): void {\n if (!metricsAdapter) return;\n const { delta, restarts } = metricsAdapter.measure(before, after, committedComponents, commitId);\n state.metricsByCommit[commitId] = delta;\n if (state.commitStats[commitId]) {\n state.commitStats[commitId][CS_RESTARTS] = restarts;\n }\n }\n /**\n * Core commit handler \u2014 shared by the adapter and DevTools paths.\n * metricsDeltaAvailable: true only when the adapter's counters are live.\n */\n function handleCommit(\n root: { current: Fiber; memoizedUpdaters?: Set<Fiber> },\n metricsDeltaAvailable: boolean\n ): number {\n // Renderer internals are guaranteed to exist by the time commit hooks fire.\n // Installing here arms passive hook stack capture for subsequent real renders\n // without invoking product components during inspection.\n debugRender.install();\n const commitHookStartTime = performance.now();\n const timeSinceLastCommit = commitHookStartTime - state.lastCommitEndTime;\n\n const metricsBefore = state.lastMetricsSnapshot || captureMetricsSnapshot();\n\n const memoizedUpdaters = root.memoizedUpdaters;\n const committedComponents = recordTree(root.current, memoizedUpdaters || null);\n\n // `recordTree` counts deletions from fiber.deletions[]. Some renderers clear\n // that array before the final root callback, while still calling the DevTools\n // unmount hook. We use the DevTools surface as a FALLBACK when recordTree saw\n // no deletions this commit. We do NOT merge with max() \u2014 DevTools fires\n // onCommitFiberUnmount per-descendant (not per-subtree-root), so summing\n // produces inflated subtree counts for nested deletions (e.g. Mid > Leaf\n // \u2192 DevTools fires twice \u2192 counts as 2 subtrees instead of 1).\n const currentStats = state.commitStats[state.commits];\n if (currentStats && (pendingDevtoolsUnmounts.components > 0 || pendingDevtoolsUnmounts.subtrees > 0)) {\n const recordTreeSawDeletions = (currentStats[CS_UNMOUNTED_COMPONENTS] || 0) > 0;\n if (!recordTreeSawDeletions) {\n // Fallback: recordTree didn't see fiber.deletions[] (renderer cleared it\n // before commit). Trust DevTools counts even though they may over-report\n // subtrees for nested deletions \u2014 better some signal than none.\n currentStats[CS_UNMOUNTED_COMPONENTS] = pendingDevtoolsUnmounts.components;\n currentStats[CS_UNMOUNTED_SUBTREES] = pendingDevtoolsUnmounts.subtrees;\n }\n pendingDevtoolsUnmounts = { components: 0, subtrees: 0 };\n }\n if (pendingDevtoolsUnmountSamples.length > 0) {\n const existing = state.unmountsByCommit[state.commits];\n if (existing && existing.length > 0) {\n // Prefer deletion-walk samples (have depth). Drop devtools samples to\n // avoid noisy duplicates.\n } else {\n state.unmountsByCommit[state.commits] = pendingDevtoolsUnmountSamples;\n }\n pendingDevtoolsUnmountSamples = [];\n }\n\n const metricsAfter = captureMetricsSnapshot();\n if (metricsDeltaAvailable && metricsBefore && metricsAfter) {\n recordMetricsEvidence(state.commits, committedComponents, metricsBefore, metricsAfter);\n }\n state.lastMetricsSnapshot = metricsAfter;\n\n const commitHookEndTime = performance.now();\n interactionCapture.linkRecent(state.commits, commitHookEndTime);\n state.commitTimings[state.commits] = {\n timeSinceLastCommit,\n detectorOverhead: commitHookEndTime - commitHookStartTime,\n };\n state.lastCommitEndTime = commitHookEndTime;\n return committedComponents;\n }\n\n return {\n /**\n * Start profiling React commits.\n *\n * Integration model is OBSERVED at runtime, not declared at install time.\n *\n * 'devtools' \u2014 DevTools `onCommitFiberRoot` is the canonical entry\n * point. We define the hook if absent, augment (chain)\n * if present. On every commit we capture the fiber tree.\n *\n * 'adapter:<id>' \u2014 Promoted from 'devtools' the first time the commit\n * metrics adapter's host callback actually fires for a\n * real commit. From then on the adapter is the\n * authoritative processor and the DevTools surface is\n * chained-observer-only. The adapter is preferred when\n * alive because it carries render-counter deltas\n * (restart math, metricsByCommit).\n *\n * 'none' \u2014 Only when no DevTools hook surface can be created and\n * no adapter surface is reachable. Practically never\n * hit, since the content-script ships a\n * devtools-hook-shim before react-dom.\n *\n * Double-invocation safety:\n * Once an adapter callback has fired, DevTools remains chained for\n * existing tooling but does not capture commits; the adapter alone calls\n * `handleCommit`. Without a live adapter, DevTools is the capture\n * surface. This avoids duplicate capture without relying on per-root\n * timing heuristics.\n *\n * Side effects:\n * - Defines `__REACT_DEVTOOLS_GLOBAL_HOOK__` if it does not already exist\n * (minimal contract: `onCommitFiberRoot` only). React reads the hook at\n * module-eval time; the content-script shim handles ordering.\n * - Asks the adapter (when one is registered) to route its host commit\n * callback here, *if and when* the host calls it.\n *\n * Safe to call multiple times (idempotent: chains skipped when our wrappers\n * are already in place).\n */\n install(): void {\n interactionCapture.install();\n const devtoolsGlobal = globalThis as GlobalWithDevtools;\n metricsAdapter = resolveMetricsAdapter();\n // Capture an initial adapter snapshot regardless. If the host surface is\n // dead these counters stay at zero and the delta is a no-op.\n state.lastMetricsSnapshot = captureMetricsSnapshot();\n\n // \u2500\u2500 1. Ensure a DevTools hook surface exists \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // React calls __REACT_DEVTOOLS_GLOBAL_HOOK__.onCommitFiberRoot on every\n // commit when the hook is present at react-dom eval time. We define a\n // minimal hook if nothing is there; otherwise we augment the existing one.\n let hook = devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) {\n hook = {} as DevtoolsHook;\n devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook;\n devtoolsHookCreatedByUs = true;\n } else {\n devtoolsHookCreatedByUs = false;\n }\n\n devtoolsHookPrev = typeof hook.onCommitFiberRoot === 'function'\n ? hook.onCommitFiberRoot\n : undefined;\n devtoolsUnmountPrev = typeof hook.onCommitFiberUnmount === 'function'\n ? hook.onCommitFiberUnmount\n : undefined;\n\n const devtoolsHandler = (...args: unknown[]) => {\n // Always chain whatever was there first (real React DevTools, other\n // tooling). Errors in third-party handlers must not poison React.\n if (devtoolsHookPrev) {\n try { devtoolsHookPrev(...args); } catch (_) { /* swallow */ }\n }\n\n const root = args[1] as { current: Fiber; memoizedUpdaters?: Set<Fiber> } | undefined;\n if (!root) return;\n\n // The adapter is the canonical fast path (it carries the render-counter\n // deltas). Defer only after an adapter callback has proved that the host\n // surface is live. BUT: a host runtime can wipe or replace its surface\n // mid-session (for example `delete window.__ATL_REACT_METRICS`), which\n // orphans our callback on the old object. Re-seed lazily here: if the\n // callback is no longer wired, re-attach so subsequent commits route\n // through the adapter again.\n if (commitSurface.adapterObserved && metricsAdapter) {\n if (!metricsAdapter.isAttached()) {\n metricsAdapter.reattach();\n // Fall through to capture this commit via devtools so we don't lose it.\n const metricsBefore = state.lastMetricsSnapshot || captureMetricsSnapshot();\n const committedComponents = handleCommit(root, /* metricsDeltaAvailable */ false);\n commitSurface.recordDevtools(root, { commitId: state.commits, committedComponents, metricsBefore });\n return;\n }\n // The adapter is still wired \u2014 let it own this commit.\n return;\n }\n const metricsBefore = state.lastMetricsSnapshot || captureMetricsSnapshot();\n const committedComponents = handleCommit(root, /* metricsDeltaAvailable */ false);\n commitSurface.recordDevtools(root, { commitId: state.commits, committedComponents, metricsBefore });\n };\n hook.onCommitFiberRoot = devtoolsHandler;\n\n const devtoolsUnmountHandler = (...args: unknown[]) => {\n if (devtoolsUnmountPrev) {\n try { devtoolsUnmountPrev(...args); } catch (_) { /* swallow */ }\n }\n const fiber = args[1] as Fiber | undefined;\n if (!fiber) return;\n const counts = countUnmountedComponentSubtree(fiber);\n pendingDevtoolsUnmounts.components += counts.components;\n pendingDevtoolsUnmounts.subtrees += counts.subtrees;\n if (counts.components > 0 && pendingDevtoolsUnmountSamples.length < 30) {\n // Find the topmost component fiber in the deleted subtree (could be the\n // root fiber itself, or a descendant if React handed us a host wrapper).\n let labelFiber: Fiber | null = fiber;\n if (!isComponentFiber(labelFiber.tag)) {\n const stack: Fiber[] = [labelFiber];\n labelFiber = null;\n while (stack.length) {\n const f = stack.pop()!;\n if (isComponentFiber(f.tag)) { labelFiber = f; break; }\n if (f.child) stack.push(f.child);\n if (f.sibling) stack.push(f.sibling);\n }\n }\n if (labelFiber) {\n const fiberKey = (labelFiber as unknown as { key?: string | number | null }).key;\n pendingDevtoolsUnmountSamples.push({\n name: getComponentName(labelFiber),\n key: fiberKey == null ? null : String(fiberKey),\n depth: null,\n count: counts.components,\n source: summarizeFiberSource(labelFiber),\n host: summarizeHostSubtree(fiber),\n });\n }\n }\n lastSeenHookState.delete(fiber);\n if (fiber.alternate) lastSeenHookState.delete(fiber.alternate);\n };\n hook.onCommitFiberUnmount = devtoolsUnmountHandler;\n\n // Default observed mode until an adapter proves itself.\n integrationMode = 'devtools';\n\n // \u2500\u2500 2. Listen on the adapter surface \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // We don't probe whether the host surface is alive \u2014 we let invocation\n // be the proof. Once the adapter's callback fires, its counters are\n // available for the delta math.\n commitSurface.reset();\n const adapter = metricsAdapter;\n if (adapter) {\n const adapterMode: IntegrationMode = `adapter:${adapter.id}`;\n adapter.attach((root) => {\n const previousCapture = commitSurface.observeAdapter(root);\n // First invocation is proof of life. Promote mode permanently.\n if (integrationMode !== adapterMode) {\n integrationMode = adapterMode;\n }\n\n if (previousCapture) {\n // The host may call DevTools first. Enrich that same commit with\n // adapter counters without traversing or recording it a second time.\n const metricsAfter = captureMetricsSnapshot();\n if (previousCapture.metricsBefore && metricsAfter) {\n recordMetricsEvidence(previousCapture.commitId, previousCapture.committedComponents, previousCapture.metricsBefore, metricsAfter);\n }\n state.lastMetricsSnapshot = metricsAfter;\n } else {\n handleCommit(root, /* metricsDeltaAvailable */ true);\n }\n });\n }\n },\n\n /**\n * Stop profiling React commits. Does not clear accumulated state.\n * Call reset() to clear state.\n *\n * Restores the DevTools hook to its prior state:\n * - hook was created by us \u2192 delete the hook entirely\n * - hook had a prior onCommitFiberRoot \u2192 restore it\n * - hook had no handler \u2192 delete the property\n *\n * Asks the adapter to remove its host callback only if it is still ours\n * (don't stomp a concurrent installer).\n */\n uninstall(): void {\n metricsAdapter?.detach();\n\n // Restore DevTools hook.\n const devtoolsGlobal = globalThis as GlobalWithDevtools;\n const hook = devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (hook) {\n if (devtoolsHookCreatedByUs) {\n // We created it; remove the whole thing.\n delete devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n } else {\n if (devtoolsHookPrev) {\n hook.onCommitFiberRoot = devtoolsHookPrev;\n } else {\n delete hook.onCommitFiberRoot;\n }\n if (devtoolsUnmountPrev) {\n hook.onCommitFiberUnmount = devtoolsUnmountPrev;\n } else {\n delete hook.onCommitFiberUnmount;\n }\n }\n }\n debugRender.uninstall();\n interactionCapture.uninstall();\n commitSurface.reset();\n pendingDevtoolsUnmounts = { components: 0, subtrees: 0 };\n pendingDevtoolsUnmountSamples = [];\n devtoolsHookPrev = undefined;\n devtoolsUnmountPrev = undefined;\n devtoolsHookCreatedByUs = false;\n integrationMode = 'none';\n },\n\n /**\n * Clear all accumulated profiling state. Useful for starting fresh measurements.\n * Does not uninstall the profiler - call uninstall() separately if needed.\n */\n reset(): void {\n resetState();\n debugRender.reset();\n },\n\n /**\n * Generate a report of top update sources and thrashing components.\n * @param topN - Number of top sources to include (default: 10)\n * @param sortBy - Sort thrashers by 'effect', 'callback', 'memo', or 'total' (default: 'effect')\n * @param options - Report filtering options (e.g., minCollateral to hide low-impact sources)\n * @returns Report containing sources, blast radius, and optional thrashing data\n */\n report(topN: number = 10, sortBy: SortBy = 'effect', reportOptions?: ReportOptions): Report {\n return buildReport(state, thrashMode, topN, sortBy, reportOptions, {\n effectThrashMode,\n captureFibers,\n historySize,\n detectionLevel,\n integrationMode,\n });\n },\n\n /**\n * Raw passive hook events captured for a component (debug surface).\n */\n _debugRawHookEvents(componentName: string) {\n const components = debugRender.allComponents();\n const events = componentName === '*' ? [] : debugRender.rawEvents(componentName);\n return {\n ok: true,\n componentName,\n status: debugRender.status(),\n components,\n events,\n };\n },\n\n _debugInjectHookEventsForTest(componentName: string, events: HookCallEvent[]) {\n if (typeof debugRender.recordEventForTest !== 'function') return;\n for (const event of events) {\n debugRender.recordEventForTest({ ...event, componentName });\n }\n },\n\n _debugSetSourceForTest(sourceId: string, source: unknown) {\n state.sources.set(sourceId, source as Omit<Source, 'sourceId'>);\n },\n\n debugHook(sourceId: string, hookIndex: number, windowSize: number = 3) {\n let source = state.sources.get(sourceId);\n let resolvedSourceId = sourceId;\n if (!source) {\n for (const [internalId, candidate] of state.sources.entries()) {\n const candidateHumanId = `${getComponentDisplayName(candidate.type)}#${String(internalId).match(/#(\\d+)@/)?.[1] || '1'}@${candidate.depth}`;\n if (candidateHumanId === sourceId) {\n source = candidate;\n resolvedSourceId = internalId;\n break;\n }\n }\n }\n if (!source) return { ok: false, error: 'sourceId not found', sourceId };\n const componentName = getComponentDisplayName(source.type);\n let events = debugRender.rawEvents(componentName);\n let resolvedComponentName = componentName;\n if (events.length === 0) {\n const candidates = debugRender.allComponents();\n const matching = candidates.find((name) => name === componentName || name.includes(componentName) || componentName.includes(name));\n if (matching) {\n resolvedComponentName = matching;\n events = debugRender.rawEvents(matching);\n }\n }\n\n const sourceHookIndices = Array.isArray(source.debugHookIndices)\n ? source.debugHookIndices\n : [];\n const targetIndex = Math.floor(hookIndex);\n const eventIndex = sourceHookIndices[targetIndex] ?? targetIndex;\n const target = events[eventIndex];\n const radius = Math.max(0, Math.floor(windowSize));\n if (!target) {\n return {\n ok: false,\n error: 'hook event not found',\n sourceId: resolvedSourceId,\n requestedSourceId: sourceId,\n componentName,\n resolvedComponentName,\n hookIndex: targetIndex,\n eventIndex,\n sourceHookIndices,\n eventCount: events.length,\n status: debugRender.status(),\n caveat: 'hook ancestry comes from passive stack capture during real renders; component-name stack parsing can be ambiguous in bundled/minified code',\n };\n }\n const neighborhood = events\n .map((event, index) => ({ event, index }))\n .filter(({ index }) => Math.abs(index - eventIndex) <= radius)\n .map(({ event, index }) => ({\n hookIndex: sourceHookIndices.indexOf(index) >= 0 ? sourceHookIndices.indexOf(index) : index,\n eventIndex: index,\n primitive: event.primitive,\n parents: parentFramesForEvent(event, componentName),\n }));\n return {\n ok: true,\n sourceId: resolvedSourceId,\n requestedSourceId: sourceId,\n componentName,\n resolvedComponentName,\n hookIndex: targetIndex,\n eventIndex,\n sourceHookIndices,\n primitive: target.primitive,\n parents: parentFramesForEvent(target, componentName),\n neighborhood,\n eventCount: events.length,\n status: debugRender.status(),\n caveat: 'hook ancestry comes from passive stack capture during real renders; source-local hook indices are mapped onto the captured component event stream',\n };\n },\n\n /**\n * Returns which commit-hook integration model is currently observed.\n * 'devtools' \u2014 DevTools hook is the active processor (no proven adapter callbacks).\n * 'adapter:<id>' \u2014 The adapter's host surface has fired; it owns the math now.\n * 'none' \u2014 Detector not installed.\n */\n getIntegrationMode(): IntegrationMode {\n return integrationMode;\n },\n\n /** Id of the commit metrics adapter resolved on install, or null. */\n getMetricsAdapterId(): string | null {\n return metricsAdapter?.id ?? null;\n },\n };\n}\n\n/**\n * Detection level constants - use these for clarity about the hierarchy.\n * Higher levels include all features from lower levels.\n */\nexport const DETECTION_LEVEL = {\n /** Level 1: Only commitStats (performedWork for restarts) - minimal overhead */\n LEVEL1_STATS: 'stats' as const,\n /** Level 2: Stats + source tracking (which components caused updates) */\n LEVEL2_SOURCES: 'sources' as const,\n /** Level 3a: Sources + aggregate amplifier counts only (meta.amplifiersMetrics) */\n LEVEL3_AMPLIFIER_METRICS: 'amplifierMetrics' as const,\n /** Level 3b: Sources + full amplifier arrays (report.amplifiers, report.amplifierSources) */\n LEVEL3_AMPLIFIERS: 'amplifiers' as const,\n} as const;\n", "/**\n * Seed, protect, and guard a host metrics slot such as `__ATL_REACT_METRICS`.\n *\n * The host page owns the slot. Its instrumented react-dom reads the slot before\n * it calls `onCommitFiberRoot`, and its runtime may zero-fill or delete the slot\n * during hydration cleanup. These helpers never lock the slot: every descriptor\n * they write stays `configurable: true`, and a slot the host already locked is\n * left alone.\n */\n\nexport const DEFAULT_METRICS_SLOT = '__ATL_REACT_METRICS';\n\n/** Counters a zeroed slot starts with. */\nexport const METRICS_COUNTER_KEYS = [\n 'mountWorkCount', 'updateWorkCount', 'commitWorkCount', 'interruptedWorkCount',\n 'priorityInterruptedWorkCount', 'externalStoreRestartCount', 'renderRootSyncCount',\n 'renderRootConcurrentCount', 'componentWorkCount', 'componentMountWorkCount',\n 'componentUpdateWorkCount', 'componentRenderWithHooksCount', 'finishClassComponentCount',\n 'domWorkCount', 'totalTickCount', 'totalCommitCount', 'contextUpdateCount',\n 'legacyContextUpdateCount',\n] as const;\n\n/** Counters the accessor checks before accepting a write; adds the detector's totals. */\nconst ACCESSOR_KEYS = [...METRICS_COUNTER_KEYS, 'totalRestarts', 'totalPerformedWork'] as const;\n\ntype SlotTarget = Record<string, unknown>;\nexport type MetricsSlotValue = Record<string, unknown>;\n\nexport function createZeroMetrics(): MetricsSlotValue {\n const metrics: MetricsSlotValue = {};\n for (const key of METRICS_COUNTER_KEYS) metrics[key] = 0;\n metrics.setStateCount = 0;\n return metrics;\n}\n\nfunction isAllZero(value: unknown): boolean {\n if (!value || typeof value !== 'object') return true;\n const record = value as Record<string, unknown>;\n for (const key of ACCESSOR_KEYS) if (((record[key] as number) || 0) !== 0) return false;\n return true;\n}\n\n/** True when the host owns the slot: non-configurable, or an accessor. */\nexport function isSlotHostLocked(target: SlotTarget, slotName = DEFAULT_METRICS_SLOT): boolean {\n const existing = Object.getOwnPropertyDescriptor(target, slotName);\n return !!existing && (existing.configurable === false || typeof existing.get === 'function');\n}\n\n/**\n * Write `metrics` as a plain, deletable data property. Honors a host lock\n * (configurable: false). Falls back to plain assignment.\n */\nexport function protectMetricsSlot(target: SlotTarget, metrics: MetricsSlotValue, slotName = DEFAULT_METRICS_SLOT): void {\n try {\n const existing = Object.getOwnPropertyDescriptor(target, slotName);\n if (existing && existing.configurable === false) return;\n Object.defineProperty(target, slotName, { configurable: true, enumerable: true, writable: true, value: metrics });\n } catch {\n try { target[slotName] = metrics; } catch { /* host wins */ }\n }\n}\n\n/** Seed a fresh zeroed slot. Returns the new metrics object. */\nexport function seedMetricsSlot(target: SlotTarget, slotName = DEFAULT_METRICS_SLOT): MetricsSlotValue {\n const metrics = createZeroMetrics();\n try { target[slotName] = metrics; } catch { /* protect below retries */ }\n protectMetricsSlot(target, metrics, slotName);\n return metrics;\n}\n\n/**\n * Install a configurable accessor on the slot before React evaluates.\n *\n * - `configurable: true`, so a host `delete` succeeds without a TypeError.\n * After a delete the slot is gone until the next detector install re-seeds it.\n * - `set()` ignores null, undefined, and all-zero writes, so host hydration\n * cleanup that zero-fills the slot cannot orphan the live metrics object.\n * - A slot the host already locked is left alone.\n *\n * Returns true when the accessor was installed.\n */\nexport function installMetricsAccessor(target: SlotTarget, slotName = DEFAULT_METRICS_SLOT): boolean {\n try {\n const existing = Object.getOwnPropertyDescriptor(target, slotName);\n if (existing && existing.configurable === false) return false;\n let live = existing && typeof existing.get === 'function'\n ? target[slotName]\n : existing?.value;\n if (!live || typeof live !== 'object') {\n live = { onCommitFiberRoot: null };\n for (const key of ACCESSOR_KEYS) (live as MetricsSlotValue)[key] = 0;\n }\n Object.defineProperty(target, slotName, {\n configurable: true,\n enumerable: true,\n get() { return live; },\n set(next: unknown) {\n if (next === undefined || next === null || isAllZero(next)) return;\n live = next;\n },\n });\n return true;\n } catch {\n // Non-fatal: the detector falls back to DevTools capture.\n return false;\n }\n}\n", "/**\n * ATL commit metrics adapter: reads the render counters that Atlassian's\n * patched react-dom writes into `__ATL_REACT_METRICS` and routes that slot's\n * `onCommitFiberRoot` callback to the detector.\n *\n * The slot name is configurable, so a renamed slot needs no core change.\n */\n\nimport type {\n CommitMetricsAdapter,\n CommitMetricsRoot,\n CommitMetricsSnapshot,\n} from '../../avalanche/commit-metrics-adapter';\nimport {\n DEFAULT_METRICS_SLOT,\n installMetricsAccessor,\n isSlotHostLocked,\n seedMetricsSlot,\n} from './metrics-slot';\n\n/**\n * Per-commit ATL delta - work done in a single commit.\n * Enables full reconciliation: ATL work counts \u2194 Avalanche component counts.\n *\n * Key relationship (should hold for any commit):\n * componentRenderWithHooksCount + finishClassComponentCount === collateral + sources\n */\nexport type ATLCommitDelta = {\n /** Function components mounted this commit (should be 0 during pure updates!) */\n mountWorkCount: number;\n /** Fiber update work this commit */\n updateWorkCount: number;\n /** Work that reached commit phase */\n commitWorkCount: number;\n performedWorkCount: number;\n /** Work interrupted (priority change) */\n interruptedWorkCount: number;\n /** Component fiber work (class + function) */\n componentWorkCount: number;\n /** Components mounted (should be 0 during pure updates!) */\n componentMountWorkCount: number;\n /** Components updated */\n componentUpdateWorkCount: number;\n /** DOM work (host fibers) */\n domWorkCount: number;\n ticksCount: number;\n /** Context propagation waves */\n contextUpdateCount: number;\n /** Legacy context propagations (tech debt indicator) */\n legacyContextUpdateCount: number;\n /** ALL function components rendered (including hookless) */\n componentRenderWithHooksCount: number;\n /** Class components rendered */\n finishClassComponentCount: number;\n /** useSES-triggered restarts (store mutation detected after concurrent render) */\n externalStoreRestartCount?: number;\n /** Work abandoned due to priority preemption (fibers unwound in prepareFreshStack) */\n priorityInterruptedWorkCount?: number;\n /** Number of sync renderRoot passes in this commit window */\n renderRootSyncCount?: number;\n /** Number of concurrent renderRoot passes in this commit window */\n renderRootConcurrentCount?: number;\n /** useState/useReducer dispatches during this commit (react-dom patch; optional) */\n setStateCount?: number;\n};\n\nexport const ATL_DISPATCHER_FRAME = 'atlDispatcherHook';\n\ntype SlotHandler = (...args: unknown[]) => void;\ntype Slot = Record<string, unknown> & { onCommitFiberRoot?: SlotHandler | null };\n\nconst num = (snapshot: CommitMetricsSnapshot, key: string): number => (snapshot[key] as number | undefined) ?? 0;\nconst diff = (before: CommitMetricsSnapshot, after: CommitMetricsSnapshot, key: string): number => num(after, key) - num(before, key);\n\n/** Counter delta between two ATL snapshots. */\nexport function calculateATLDelta(before: CommitMetricsSnapshot, after: CommitMetricsSnapshot): ATLCommitDelta {\n return {\n // Basic work counters\n mountWorkCount: diff(before, after, 'mountWorkCount'),\n updateWorkCount: diff(before, after, 'updateWorkCount'),\n commitWorkCount: diff(before, after, 'commitWorkCount'),\n performedWorkCount: diff(before, after, 'totalPerformedWork'),\n\n // Interruption/restart counters\n interruptedWorkCount: diff(before, after, 'interruptedWorkCount'),\n externalStoreRestartCount: diff(before, after, 'externalStoreRestartCount'),\n priorityInterruptedWorkCount: diff(before, after, 'priorityInterruptedWorkCount'),\n renderRootSyncCount: diff(before, after, 'renderRootSyncCount'),\n renderRootConcurrentCount: diff(before, after, 'renderRootConcurrentCount'),\n\n // Scheduler\n ticksCount: diff(before, after, 'totalTickCount'),\n\n // Component work counters\n componentWorkCount: diff(before, after, 'componentWorkCount'),\n componentMountWorkCount: diff(before, after, 'componentMountWorkCount'),\n componentUpdateWorkCount: diff(before, after, 'componentUpdateWorkCount'),\n componentRenderWithHooksCount: diff(before, after, 'componentRenderWithHooksCount'),\n finishClassComponentCount: diff(before, after, 'finishClassComponentCount'),\n\n // DOM work\n domWorkCount: diff(before, after, 'domWorkCount'),\n\n // Context updates\n contextUpdateCount: diff(before, after, 'contextUpdateCount'),\n legacyContextUpdateCount: diff(before, after, 'legacyContextUpdateCount'),\n\n // Hook-metric delta (react-dom patch; optional). Omit when neither snapshot\n // carries a numeric setStateCount so we never emit a bogus 0 on unpatched hosts.\n // TODO: Require finite values on both sides or model a counter reset\n // explicitly. Treating a missing/wiped side as zero can emit a negative delta,\n // and typeof NaN === 'number' lets a poisoned counter enter the report.\n ...(typeof after.setStateCount === 'number' || typeof before.setStateCount === 'number'\n ? { setStateCount: diff(before, after, 'setStateCount') }\n : {}),\n };\n}\n\nexport type ATLCommitMetricsAdapterOptions = {\n /** Global slot the patched react-dom writes. Default `__ATL_REACT_METRICS`. */\n slotName?: string;\n /** Object that holds the slot. Default `globalThis`. */\n target?: Record<string, unknown>;\n};\n\nexport function createATLCommitMetricsAdapter(options: ATLCommitMetricsAdapterOptions = {}): CommitMetricsAdapter {\n const slotName = options.slotName ?? DEFAULT_METRICS_SLOT;\n const target = () => options.target ?? (globalThis as unknown as Record<string, unknown>);\n const slot = (): Slot | null => {\n const value = target()[slotName];\n return value && typeof value === 'object' ? (value as Slot) : null;\n };\n let ourHandler: SlotHandler | undefined;\n\n return {\n id: 'atl',\n frameFilters: [ATL_DISPATCHER_FRAME],\n\n prePage() {\n installMetricsAccessor(target(), slotName);\n },\n\n prepare() {\n // Seed only when the slot is absent or a plain configurable data\n // property. A non-configurable slot or an accessor belongs to the host.\n try {\n if (!isSlotHostLocked(target(), slotName)) seedMetricsSlot(target(), slotName);\n } catch { /* host wins */ }\n },\n\n isAvailable: () => !!slot(),\n\n snapshot() {\n const live = slot();\n return live ? { ...live } : null;\n },\n\n measure(before, after, committedComponents, commitId) {\n const delta = calculateATLDelta(before, after);\n delta.performedWorkCount = committedComponents;\n const rendered = (delta.componentRenderWithHooksCount ?? 0) + (delta.finishClassComponentCount ?? 0);\n const restarts = Math.max(0, rendered - committedComponents);\n if (committedComponents > rendered && rendered > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Avalanche] Commit ${commitId}: committedComponents (${committedComponents}) > atlTotal (${rendered}). ` +\n `This indicates a counting bug. Using 0 restarts.`\n );\n }\n // Running totals live on the slot so the next delta covers them.\n const live = slot();\n if (live) {\n live.totalRestarts = ((live.totalRestarts as number) ?? 0) + restarts;\n live.totalPerformedWork = ((live.totalPerformedWork as number) ?? 0) + committedComponents;\n }\n return { delta, restarts };\n },\n\n attach(onCommit) {\n const live = slot();\n if (!live) return false;\n const handler: SlotHandler = (_rendererID, root) => onCommit(root as CommitMetricsRoot);\n live.onCommitFiberRoot = handler;\n ourHandler = handler;\n return true;\n },\n\n isAttached() {\n const live = slot();\n return !!live && !!ourHandler && live.onCommitFiberRoot === ourHandler;\n },\n\n reattach() {\n const fresh = seedMetricsSlot(target(), slotName) as Slot;\n if (ourHandler) fresh.onCommitFiberRoot = ourHandler;\n },\n\n detach() {\n const live = slot();\n if (live && ourHandler && live.onCommitFiberRoot === ourHandler) live.onCommitFiberRoot = undefined;\n ourHandler = undefined;\n },\n };\n}\n\n/** The adapter the shipped bundle registers. */\nexport const atlCommitMetricsAdapter = createATLCommitMetricsAdapter();\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Small, dependency-free Source Map v3 reader.\n *\n * Chippy only needs the generated-position lookup used by React 19's\n * `_debugStack` source path, so it deliberately omits names and source contents.\n */\n\nconst DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';\nconst VALUE_OF = new Int8Array(128).fill(-1);\nfor (let index = 0; index < DIGITS.length; index += 1) {\n VALUE_OF[DIGITS.charCodeAt(index)] = index;\n}\n\ntype Segment = {\n generatedColumn: number;\n sourceIndex: number | null;\n originalLine: number | null;\n originalColumn: number | null;\n};\n\nexport type SourceMap = {\n sources: readonly string[];\n lines: readonly (readonly Segment[])[];\n offset: { line: number; column: number };\n};\n\nexport type OriginalPosition = {\n source: string;\n line: number;\n column: number;\n};\n\ntype RawMap = {\n version?: unknown;\n sources?: unknown;\n sourceRoot?: unknown;\n mappings?: unknown;\n sections?: unknown;\n};\n\nfunction decodeVlq(field: string): number[] {\n const values: number[] = [];\n let value = 0;\n let shift = 0;\n\n for (let index = 0; index < field.length; index += 1) {\n const code = field.charCodeAt(index);\n const digit = code < 128 ? VALUE_OF[code]! : -1;\n if (digit < 0) return values;\n\n const more = (digit & 32) !== 0;\n value += (digit & 31) << shift;\n if (more) {\n shift += 5;\n continue;\n }\n\n const negative = (value & 1) === 1;\n const magnitude = value >>> 1;\n values.push(negative ? (magnitude === 0 ? -0x80000000 : -magnitude) : magnitude);\n value = 0;\n shift = 0;\n }\n\n return values;\n}\n\nfunction decodeMappings(mappings: string, sourceCount: number): Segment[][] {\n const lines: Segment[][] = [];\n let sourceIndex = 0;\n let originalLine = 0;\n let originalColumn = 0;\n\n for (const encodedLine of mappings.split(';')) {\n const segments: Segment[] = [];\n let generatedColumn = 0;\n\n for (const field of encodedLine === '' ? [] : encodedLine.split(',')) {\n const values = decodeVlq(field);\n if (values.length < 4) {\n if (values.length > 0) {\n generatedColumn += values[0]!;\n segments.push({ generatedColumn, sourceIndex: null, originalLine: null, originalColumn: null });\n }\n continue;\n }\n\n generatedColumn += values[0]!;\n sourceIndex += values[1]!;\n originalLine += values[2]!;\n originalColumn += values[3]!;\n if (sourceIndex >= 0 && sourceIndex < sourceCount) {\n segments.push({ generatedColumn, sourceIndex, originalLine, originalColumn });\n }\n }\n\n segments.sort((left, right) => left.generatedColumn - right.generatedColumn);\n lines.push(segments);\n }\n\n return lines;\n}\n\nfunction resolveSources(raw: RawMap): string[] | null {\n if (!Array.isArray(raw.sources)) return null;\n const root = typeof raw.sourceRoot === 'string' ? raw.sourceRoot : '';\n\n return raw.sources.map((source) => {\n if (typeof source !== 'string') return '';\n if (root === '' || source === '' || /^[a-z][a-z0-9+.-]*:/i.test(source)) return source;\n if (root.endsWith('/') && source.startsWith('/')) return `${root}${source.slice(1)}`;\n if (root.endsWith('/') || source.startsWith('/')) return `${root}${source}`;\n return `${root}/${source}`;\n });\n}\n\nexport function parseSourceMap(text: string): SourceMap[] {\n let raw: RawMap;\n try {\n raw = JSON.parse(text) as RawMap;\n } catch {\n return [];\n }\n\n if (raw === null || typeof raw !== 'object') return [];\n if (raw.version !== 3) return [];\n\n if (Array.isArray(raw.sections)) {\n return raw.sections.flatMap((section) => {\n if (section === null || typeof section !== 'object') return [];\n const { offset, map } = section as { offset?: unknown; map?: unknown };\n if (offset === null || typeof offset !== 'object' || map === null || typeof map !== 'object') return [];\n const { line, column } = offset as { line?: unknown; column?: unknown };\n if (typeof line !== 'number' || typeof column !== 'number') return [];\n return parseSourceMap(JSON.stringify(map)).map((parsed) => ({ ...parsed, offset: { line, column } }));\n });\n }\n\n const sources = resolveSources(raw);\n if (sources === null || typeof raw.mappings !== 'string') return [];\n return [{ sources, lines: decodeMappings(raw.mappings, sources.length), offset: { line: 0, column: 0 } }];\n}\n\nfunction sectionsFor(maps: readonly SourceMap[], line: number, column: number): readonly SourceMap[] {\n if (\n maps.length === 0 ||\n (maps.length === 1 && maps[0]?.offset.line === 0 && maps[0]?.offset.column === 0)\n ) return maps;\n const zeroBasedLine = line - 1;\n const candidates = maps.filter(\n (map) =>\n map.offset.line < zeroBasedLine ||\n (map.offset.line === zeroBasedLine && map.offset.column < column),\n );\n return candidates.length === 0 ? [] : [candidates[candidates.length - 1]!];\n}\n\nfunction segmentAt(segments: readonly Segment[], column: number): Segment | undefined {\n let low = 0;\n let high = segments.length - 1;\n let found: Segment | undefined;\n\n while (low <= high) {\n const middle = (low + high) >> 1;\n const segment = segments[middle]!;\n if (segment.generatedColumn <= column) {\n found = segment;\n low = middle + 1;\n } else {\n high = middle - 1;\n }\n }\n\n return found;\n}\n\nexport function originalPositionFor(\n maps: readonly SourceMap[],\n line: number,\n column: number,\n): OriginalPosition | null {\n for (const map of sectionsFor(maps, line, column)) {\n const localLine = line - map.offset.line;\n const localColumn = localLine === 1 ? column - map.offset.column : column;\n const segments = map.lines[localLine - 1];\n if (segments === undefined || segments.length === 0) continue;\n\n const found = segmentAt(segments, localColumn - 1);\n if (found === undefined) continue;\n if (\n found.sourceIndex === null ||\n found.originalLine === null ||\n found.originalColumn === null\n ) return null;\n const source = map.sources[found.sourceIndex];\n if (source === undefined || source === '') continue;\n return { source, line: found.originalLine + 1, column: found.originalColumn + 1 };\n }\n\n return null;\n}\n\nexport function sourceMappingUrlOf(code: string): string | null {\n const found = [...code.matchAll(/^[/*]{2,}[#@]\\s*sourceMappingURL=(\\S+)\\s*(?:\\*\\/)?$/gm)];\n return found.at(-1)?.[1] ?? null;\n}\n\nexport function inlineSourceMapOf(url: string): string | null {\n const match = /^data:application\\/json[^,]*,(.*)$/s.exec(url);\n if (match === null) return null;\n const payload = match[1]!;\n\n if (!/;base64/i.test(url)) {\n try {\n return decodeURIComponent(payload);\n } catch {\n return null;\n }\n }\n\n try {\n const decode = (globalThis as { atob?: (input: string) => string }).atob;\n if (decode) {\n const binary = decode(payload);\n const Decoder = (globalThis as {\n TextDecoder?: new () => { decode(bytes: Uint8Array): string };\n }).TextDecoder;\n return Decoder\n ? new Decoder().decode(Uint8Array.from(binary, (character) => character.charCodeAt(0)))\n : binary;\n }\n const buffer = (globalThis as {\n Buffer?: { from(value: string, encoding: string): { toString(encoding: string): string } };\n }).Buffer;\n return buffer?.from(payload, 'base64').toString('utf8') ?? null;\n } catch {\n return null;\n }\n}\n", "import {\n inlineSourceMapOf,\n originalPositionFor,\n parseSourceMap,\n sourceMappingUrlOf,\n type OriginalPosition,\n type SourceMap,\n} from './source-map';\nimport { baseName, pageModuleUrls, recordedLiteralPosition } from './recorded-source';\n\nexport type FiberSourceLocation = {\n fileName: string;\n lineNumber: number;\n columnNumber: number | null;\n};\n\nexport type StackFrame = {\n url: string;\n line: number;\n column: number;\n function?: string;\n};\n\nexport type SourceFiber = {\n type?: unknown;\n _debugSource?: unknown;\n _debugStack?: unknown;\n};\n\nexport type FetchModule = (url: string) => Promise<string | null>;\n\n/** Module URLs that may serve a file named by React <=18 `_debugSource`. */\nexport type ModuleUrlsFor = (fileName: string) => readonly string[];\n\nexport type CallSiteResolver = {\n locate(frames: readonly StackFrame[]): Promise<FiberSourceLocation | null>;\n /** Map a recorded `_debugSource` position through its served module. */\n locateRecorded(source: FiberSourceLocation): Promise<FiberSourceLocation>;\n readonly stats: { modules: number; sites: number; located: number };\n};\n\ntype ResolvedMaps = {\n code: string;\n maps: readonly SourceMap[];\n sourceBaseUrl: string;\n};\n\nconst V8_FRAME = /^\\s*at\\s+(?:(.+?)\\s+\\()?(.+?):(\\d+):(\\d+)\\)?$/;\nconst AT_FRAME = /^\\s*(?:(.*?)@)(.+?):(\\d+):(\\d+)$/;\nconst MAX_CALL_SITE_FRAMES = 4;\n\nconst resolvedFiberSources = new WeakMap<object, FiberSourceLocation | null>();\nconst pendingFiberSources = new WeakMap<object, Promise<FiberSourceLocation | null>>();\nlet defaultResolver: CallSiteResolver | null = null;\n\nexport function parseStackFrames(stack: string): StackFrame[] {\n const frames: StackFrame[] = [];\n\n for (const raw of stack.split('\\n')) {\n const line = raw.trimEnd();\n if (line === '' || line.includes('(eval at ')) continue;\n const match = V8_FRAME.exec(line) ?? AT_FRAME.exec(line);\n if (!match) continue;\n\n const [, name, url = '', lineDigits = '', columnDigits = ''] = match;\n if (url === '' || url.startsWith('data:')) continue;\n const at = Number(lineDigits);\n const column = Number(columnDigits);\n if (!Number.isFinite(at) || !Number.isFinite(column) || at < 1) continue;\n frames.push({\n url,\n line: at,\n column,\n ...(name !== undefined && name !== '' ? { function: name } : {}),\n });\n }\n\n return frames;\n}\n\nexport function isVendorPath(path: string): boolean {\n return (\n path.includes('node_modules') ||\n path.includes('/.vite/deps/') ||\n path.includes('/.yarn/')\n );\n}\n\nfunction rawLocation(frame: StackFrame): FiberSourceLocation {\n return { fileName: frame.url, lineNumber: frame.line, columnNumber: frame.column };\n}\n\nfunction locationFromOriginal(original: OriginalPosition): FiberSourceLocation {\n return { fileName: original.source, lineNumber: original.line, columnNumber: original.column };\n}\n\nexport function writerLocationOf(\n frames: readonly StackFrame[],\n originalFor: (frame: StackFrame) => OriginalPosition | null,\n): FiberSourceLocation | null {\n for (const frame of frames) {\n if (isVendorPath(frame.url)) continue;\n const original = originalFor(frame);\n if (original === null) return rawLocation(frame);\n if (isVendorPath(original.source)) continue;\n return locationFromOriginal(original);\n }\n return null;\n}\n\nfunction parseUrl(url: string, base?: string): URL | null {\n try {\n return new URL(url, base);\n } catch {\n return null;\n }\n}\n\nfunction sourcePath(source: string, moduleUrl: string): string {\n if (/^\\/(?:Users|home|private|Volumes)\\//.test(source)) return source;\n const direct = parseUrl(source);\n if (direct?.protocol === 'file:') return decodeURIComponent(direct.pathname);\n const resolved = parseUrl(source, moduleUrl)?.href ?? source;\n const parsed = parseUrl(resolved);\n return parsed ? parsed.pathname.replace(/^\\/+/, '') : resolved;\n}\n\nexport function createCallSiteResolver(\n fetchModule: FetchModule,\n moduleUrlsFor: ModuleUrlsFor = () => [],\n): CallSiteResolver {\n const maps = new Map<string, Promise<ResolvedMaps | null>>();\n const sites = new Map<string, Promise<FiberSourceLocation | null>>();\n const recordedSites = new Map<string, Promise<FiberSourceLocation>>();\n const stats = { modules: 0, sites: 0, located: 0 };\n\n async function mapsFor(url: string): Promise<ResolvedMaps | null> {\n const cached = maps.get(url);\n if (cached) return cached;\n\n const pending = (async () => {\n stats.modules += 1;\n const code = await fetchModule(url);\n if (code === null) return null;\n const annotation = sourceMappingUrlOf(code);\n if (annotation === null) return null;\n const inline = inlineSourceMapOf(annotation);\n if (inline !== null) return { code, maps: parseSourceMap(inline), sourceBaseUrl: url };\n const mapUrl = parseUrl(annotation, url)?.href ?? null;\n const text = mapUrl === null ? null : await fetchModule(mapUrl);\n return text === null || mapUrl === null\n ? null\n : { code, maps: parseSourceMap(text), sourceBaseUrl: mapUrl };\n })();\n\n maps.set(url, pending);\n return pending;\n }\n\n async function locateFrame(frame: StackFrame): Promise<FiberSourceLocation | null> {\n const parsed = await mapsFor(frame.url);\n if (!parsed || parsed.maps.length === 0) return null;\n const original = originalPositionFor(parsed.maps, frame.line, frame.column);\n if (!original) return null;\n return {\n fileName: sourcePath(original.source, parsed.sourceBaseUrl),\n lineNumber: original.line,\n columnNumber: original.column,\n };\n }\n\n async function locate(frames: readonly StackFrame[]): Promise<FiberSourceLocation | null> {\n for (const frame of frames) {\n if (isVendorPath(frame.url)) continue;\n const key = `${frame.url}:${frame.line}:${frame.column}`;\n let answer = sites.get(key);\n if (!answer) {\n stats.sites += 1;\n answer = locateFrame(frame);\n sites.set(key, answer);\n }\n\n const located = await answer;\n const chosen = located === null\n ? writerLocationOf([frame], () => null)\n : isVendorPath(located.fileName) ? null : located;\n if (chosen) {\n stats.located += 1;\n return chosen;\n }\n }\n return null;\n }\n\n async function correctRecorded(source: FiberSourceLocation): Promise<FiberSourceLocation> {\n for (const url of moduleUrlsFor(source.fileName)) {\n const parsed = await mapsFor(url);\n if (!parsed || parsed.maps.length === 0) continue;\n const served = recordedLiteralPosition(parsed.code, source);\n if (served === null) continue;\n const original = originalPositionFor(parsed.maps, served.line, served.column);\n // The literal must map back into the recorded file, not a neighbor.\n if (!original || baseName(original.source) !== baseName(source.fileName)) continue;\n return { fileName: source.fileName, lineNumber: original.line, columnNumber: original.column };\n }\n return source;\n }\n\n function locateRecorded(source: FiberSourceLocation): Promise<FiberSourceLocation> {\n const key = `${source.fileName}:${source.lineNumber}:${source.columnNumber}`;\n let answer = recordedSites.get(key);\n if (!answer) {\n answer = correctRecorded(source).catch(() => source);\n recordedSites.set(key, answer);\n }\n return answer;\n }\n\n return { locate, locateRecorded, stats };\n}\n\nfunction debugSourceOf(value: unknown): FiberSourceLocation | null {\n if (!value || typeof value !== 'object') return null;\n const source = value as { fileName?: unknown; lineNumber?: unknown; columnNumber?: unknown };\n if (typeof source.fileName !== 'string' || typeof source.lineNumber !== 'number') return null;\n return {\n fileName: source.fileName,\n lineNumber: source.lineNumber,\n columnNumber: typeof source.columnNumber === 'number' ? source.columnNumber : null,\n };\n}\n\nfunction recordedSource(fiber: SourceFiber): FiberSourceLocation | null {\n const direct = debugSourceOf(fiber._debugSource);\n if (direct) return direct;\n const type = fiber.type;\n return type && (typeof type === 'object' || typeof type === 'function')\n ? debugSourceOf((type as { _debugSource?: unknown })._debugSource)\n : null;\n}\n\nexport function getFiberStackFrames(fiber: SourceFiber | null | undefined): StackFrame[] {\n if (!fiber || !fiber._debugStack || typeof fiber._debugStack !== 'object') return [];\n const stack = (fiber._debugStack as { stack?: unknown }).stack;\n if (typeof stack !== 'string' || stack === '') return [];\n const candidates: StackFrame[] = [];\n for (const frame of parseStackFrames(stack)) {\n if (isVendorPath(frame.url)) continue;\n candidates.push(frame);\n if (candidates.length >= MAX_CALL_SITE_FRAMES) break;\n }\n return candidates;\n}\n\n/** Stable synchronous source, before any async source-map upgrade. */\nexport function getFiberSourceCandidate(fiber: SourceFiber | null | undefined): FiberSourceLocation | null {\n if (!fiber) return null;\n const recorded = recordedSource(fiber);\n if (recorded) return recorded;\n return writerLocationOf(getFiberStackFrames(fiber), () => null);\n}\n\n/**\n * Synchronous source read used by fiber walks and snapshots: the resolved\n * source once `resolveFiberSource` has run for this fiber, else the candidate.\n */\nexport function getFiberSource(fiber: SourceFiber | null | undefined): FiberSourceLocation | null {\n if (!fiber) return null;\n const cached = resolvedFiberSources.get(fiber as object);\n if (cached !== undefined) return cached;\n return getFiberSourceCandidate(fiber);\n}\n\nasync function fetchModuleFromPage(url: string): Promise<string | null> {\n const fetchFn = (globalThis as { fetch?: typeof fetch }).fetch;\n if (!fetchFn) return null;\n const controller = typeof AbortController === 'function' ? new AbortController() : null;\n const timeout = controller ? setTimeout(() => controller.abort(), 2000) : null;\n try {\n const response = await fetchFn(url, {\n credentials: 'same-origin',\n signal: controller?.signal,\n });\n return response.ok ? await response.text() : null;\n } catch {\n return null;\n } finally {\n if (timeout !== null) clearTimeout(timeout);\n }\n}\n\nfunction pageResolver(): CallSiteResolver {\n if (!defaultResolver) defaultResolver = createCallSiteResolver(fetchModuleFromPage, pageModuleUrls);\n return defaultResolver;\n}\n\n/**\n * Resolve a fiber's authored source through the served module's inline or\n * external map: the React 19 `_debugStack` call site, or the React <=18\n * `_debugSource` literal when a transform shifted its recorded line.\n */\nexport function resolveFiberSource(\n fiber: SourceFiber | null | undefined,\n resolver: CallSiteResolver = pageResolver(),\n): Promise<FiberSourceLocation | null> {\n if (!fiber) return Promise.resolve(null);\n const cached = pendingFiberSources.get(fiber as object);\n if (cached) return cached;\n\n const recorded = recordedSource(fiber);\n if (recorded) {\n const pending = resolver.locateRecorded(recorded).then((located) => {\n resolvedFiberSources.set(fiber as object, located);\n return located;\n });\n pendingFiberSources.set(fiber as object, pending);\n return pending;\n }\n\n const frames = getFiberStackFrames(fiber);\n const fallback = writerLocationOf(frames, () => null);\n const pending = resolver.locate(frames)\n .catch(() => null)\n .then((source) => {\n const located = source ?? fallback;\n resolvedFiberSources.set(fiber as object, located);\n return located;\n });\n pendingFiberSources.set(fiber as object, pending);\n return pending;\n}\n", "// React fiber constants and structural comparisons used by the commit detector.\n\nimport { getFiberSourceCandidate } from '../chippy-bridge/fiber-source';\n\nexport type ComponentType =\n | Function\n | symbol\n | {\n // ForwardRef/memo/etc may be objects.\n $$typeof?: symbol;\n render?: Function;\n displayName?: string;\n name?: string;\n };\n\ninterface StoreCheck {\n getSnapshot: () => unknown;\n value: unknown;\n}\n\nexport interface Fiber {\n tag: number;\n type: ComponentType;\n alternate: Fiber | null;\n return: Fiber | null;\n child: Fiber | null;\n sibling: Fiber | null;\n flags: number;\n subtreeFlags: number;\n lanes: number;\n memoizedState: Hook | null;\n memoizedProps?: unknown;\n pendingProps?: unknown;\n updateQueue: { stores: StoreCheck[] | null } | null;\n /**\n * React populates this array during the render phase with fibers that will be\n * deleted in the commit phase. Present when subtreeFlags & ChildDeletion !== 0.\n * Only available in React 18+ (replaces the older effectList pattern).\n */\n deletions?: Fiber[] | null;\n\n // Dev-only / optional debug fields (not always present).\n elementType?: unknown;\n _debugSource?: { fileName: string; lineNumber: number };\n _debugStack?: unknown;\n _debugHookTypes?: string[];\n}\n\nexport interface Hook {\n memoizedState: unknown;\n baseState: unknown;\n baseQueue: unknown;\n queue: HookQueue | null;\n next: Hook | null;\n}\n\ninterface HookQueue {\n dispatch?: Function;\n value?: unknown;\n getSnapshot?: Function;\n lastRenderedState?: unknown;\n}\n\nexport interface DepOrigin {\n type: ComponentType;\n hookIndex: number;\n depth: number;\n hookType: 'useCallback' | 'useMemo';\n}\n\nexport interface ThrashInfo {\n hookIndex: number;\n hookType: 'effect' | 'callback' | 'memo';\n deps: unknown[];\n changedDepIndices: number[];\n changedDepOrigins: (DepOrigin | null)[];\n effectTag?: number;\n memoValue?: unknown;\n /** The hook body function (for useCallback) or memoized value (for useMemo) */\n hookBody?: Function | unknown;\n}\n\nexport type ChangedHook =\n | {\n prevValue: unknown;\n currentValue: unknown;\n info?: string; // For structural changes\n }\n | 'repeat'; // Entire object replaced with string if identical to previous commit\n\nexport interface StateChangeResult {\n hasChange: boolean;\n actionable: boolean;\n changedIndices: number[];\n changedHooks: ChangedHook[];\n /** True if any of the changes came from useSyncExternalStore */\n hasExternalStoreChange: boolean;\n}\n\nexport interface ThrashingResult {\n effects: ThrashInfo[];\n callbacks: ThrashInfo[];\n memos: ThrashInfo[];\n}\n\n// React fiber flags (React 18.3.1)\nexport const PerformedWork = 1;\n\n// Flags relevant to filtering out non-preventable work from collateral counts.\n// - Placement: mount/insert work (initial render)\n// - Hydrating: work done while hydrating server-rendered markup\n// These are stable for React 18.x.\nexport const Placement = 2;\nexport const Hydrating = 4096;\n\n// Special sentinel values for hook change detection\n\n// Component fiber tags for React 18.3.1 (stable within 18.x)\n// 0: FunctionComponent, 1: ClassComponent, 2: IndeterminateComponent\n// 11: MemoComponent, 14: SimpleMemoComponent, 15: ForwardRef\nconst COMPONENT_TAGS = new Set([0, 1, 2, 11, 14, 15]);\n\n// Context Provider tag\nconst CONTEXT_PROVIDER_TAG = 10;\n\n// Suspense fiber tag (React 18.3.1 \u2014 stable within 18.x)\nexport const SuspenseTag = 13;\n\n// ChildDeletion \u2014 set on fiber.flags (NOT subtreeFlags) when the fiber has deletions[].\n// Value 16 is stable for React 18.3.1.\nexport const ChildDeletion = 16;\n\n// Update \u2014 set on fiber.flags when the fiber received an update this commit.\n// This is the flag React puts on Suspense fibers when they transition state.\n// Value 4 is stable for React 18.3.1.\nexport const Update = 4;\n\n// DidCapture \u2014 render-phase flag, cleared before commit. Do NOT check at commit time.\n// Kept for documentation. Value 128 in React 18.3.1.\nexport const DidCapture = 128;\n\nexport function isComponentFiber(tag: number): boolean {\n return COMPONENT_TAGS.has(tag);\n}\n\nexport function isContextProviderFiber(tag: number): boolean {\n return tag === CONTEXT_PROVIDER_TAG;\n}\n\nexport function isSuspenseFiber(tag: number): boolean {\n return tag === SuspenseTag;\n}\n\n/**\n * Detect whether a Suspense boundary transitioned between suspended/unsuspended states.\n *\n * Suspense memoizedState is:\n * null \u2192 primary content is showing (not suspended)\n * non-null (object) \u2192 boundary is showing the fallback (suspended/dehydrated)\n *\n * Returns:\n * { entered: true } \u2014 boundary just entered fallback\n * - null \u2192 non-null (update path)\n * - no alternate + memoizedState non-null (first render directly to fallback)\n * { left: true } \u2014 boundary just left fallback / revealed primary (non-null \u2192 null)\n * null \u2014 no state change (both null, both non-null, or first render not suspended)\n *\n * A Suspense that renders without delay never enters fallback, so memoizedState stays\n * null \u2192 returns null \u2192 correctly ignored by the detector.\n */\nexport function didSuspenseStateChange(\n fiber: Fiber\n): { entered: boolean; left: boolean } | null {\n const currSuspended = fiber.memoizedState !== null;\n\n if (!fiber.alternate) {\n // First render of this Suspense boundary.\n // If it went directly to fallback (memoizedState non-null), that IS an enter.\n // If it rendered primary content (memoizedState null), no transition.\n if (currSuspended) {\n return { entered: true, left: false };\n }\n return null;\n }\n\n const prevSuspended = fiber.alternate.memoizedState !== null;\n if (prevSuspended === currSuspended) return null;\n return { entered: currSuspended, left: prevSuspended };\n}\n\n/**\n * Check if a Context Provider's value changed.\n */\nexport function didContextValueChange(fiber: Fiber): boolean {\n if (fiber.tag !== CONTEXT_PROVIDER_TAG || !fiber.alternate) return false;\n\n type FiberWithProps = Fiber & { memoizedProps?: { value?: unknown } };\n const alternateFiber: FiberWithProps = fiber.alternate;\n const currentFiber: FiberWithProps = fiber;\n\n const prevProps = alternateFiber.memoizedProps;\n const currentProps = currentFiber.memoizedProps;\n\n return prevProps && currentProps && !Object.is(prevProps.value, currentProps.value);\n}\n\n// Detect React built-in fiber types (Suspense/Offscreen/etc).\n// IMPORTANT: Do NOT use component names. User components can be named anything.\n// In React 18, built-ins like Suspense/Offscreen are represented as symbols.\nexport function isReactInternalComponentType(type: ComponentType): boolean {\n return typeof type === 'symbol';\n}\n\nexport function getComponentName(fiber: Fiber): string {\n type TypeWithName = {\n displayName?: string;\n name?: string;\n };\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const type = fiber.type as TypeWithName;\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const elementType = fiber.elementType as TypeWithName;\n const named = (\n type?.displayName ||\n type?.name ||\n elementType?.displayName ||\n elementType?.name\n );\n if (named) return named;\n const source = getFiberSourceCandidate(fiber);\n return (source && `<${source.fileName}:${source.lineNumber}>`) || 'Anonymous';\n}\n\n/**\n * Check if hook is a state hook (useState/useReducer/useSyncExternalStore).\n *\n * All hooks share a base shape. The reliable differentiators:\n * - useState/useReducer: queue.dispatch is a function\n * - useSyncExternalStore: queue has 'value' and 'getSnapshot' properties\n */\nexport function isStateHook(hook: Hook): boolean {\n const queue = hook.queue;\n if (!queue) return false;\n\n return typeof queue.dispatch === 'function' || ('value' in queue && 'getSnapshot' in queue);\n}\n\n/** True if the hook is a useSyncExternalStore-like hook. */\nexport function isExternalStoreHook(hook: Hook): boolean {\n const queue = hook.queue;\n return (\n queue && typeof queue.dispatch !== 'function' && 'value' in queue && 'getSnapshot' in queue\n );\n}\n\n/**\n * Compare hook chains to detect state changes.\n *\n * IMPORTANT: Hook indices are React internal memoizedState indices, NOT code order.\n * `useContext` hooks are not in memoizedState, causing index misalignment.\n */\nexport function detectHookStateChanges(\n prevHookChain: Hook | null,\n currentHookChain: Hook | null\n): StateChangeResult {\n if (prevHookChain === currentHookChain) {\n return {\n hasChange: false,\n actionable: false,\n changedIndices: [],\n changedHooks: [],\n hasExternalStoreChange: false,\n };\n }\n\n let prevHook = prevHookChain;\n let currentHook = currentHookChain;\n let memoizedStateIndex = 0;\n const changedIndices: number[] = [];\n const changedHooks: ChangedHook[] = [];\n let hasExternalStoreChange = false;\n\n while (prevHook && currentHook) {\n if (isStateHook(currentHook)) {\n const prevValueRaw =\n prevHook.memoizedState === undefined\n ? prevHook.queue?.lastRenderedState\n : prevHook.memoizedState;\n const curValueRaw =\n currentHook.memoizedState === undefined\n ? currentHook.queue?.lastRenderedState\n : currentHook.memoizedState;\n\n if (!Object.is(prevValueRaw, curValueRaw)) {\n const isExternal = isExternalStoreHook(currentHook);\n if (isExternal) hasExternalStoreChange = true;\n\n changedIndices.push(memoizedStateIndex);\n changedHooks.push({\n prevValue: prevValueRaw,\n currentValue: curValueRaw,\n ...(isExternal && { isExternalStore: true }),\n });\n }\n }\n\n prevHook = prevHook.next;\n currentHook = currentHook.next;\n memoizedStateIndex++;\n }\n\n return {\n hasChange: changedIndices.length > 0,\n actionable: changedIndices.length > 0,\n changedIndices,\n changedHooks,\n hasExternalStoreChange,\n };\n}\n\n/**\n * Detect thrashing for hooks with deps: useEffect/useLayoutEffect/useInsertionEffect,\n * useCallback and useMemo.\n */\nexport function detectHookThrashing(\n prevHookChain: Hook | null,\n currentHookChain: Hook | null,\n mode: 'non-primitive' | 'all' = 'non-primitive',\n valueProvenance: WeakMap<object | Function, DepOrigin> | null = null\n): ThrashingResult {\n if (prevHookChain === currentHookChain) {\n return { effects: [], callbacks: [], memos: [] };\n }\n\n const thrashedEffects: ThrashInfo[] = [];\n const thrashedCallbacks: ThrashInfo[] = [];\n const thrashedMemos: ThrashInfo[] = [];\n\n let prevHook = prevHookChain;\n let currentHook = currentHookChain;\n let hookIndex = 0;\n\n while (prevHook && currentHook) {\n if (!isStateHook(currentHook)) {\n const prevValue = prevHook.memoizedState;\n const currentValue = currentHook.memoizedState;\n\n let prevDeps: unknown[] | null = null;\n let currentDeps: unknown[] | null = null;\n let hookType: ThrashInfo['hookType'] | null = null;\n\n // Effect hooks store an object with `deps`.\n if (\n prevValue &&\n currentValue &&\n typeof prevValue === 'object' &&\n typeof currentValue === 'object' &&\n 'deps' in prevValue &&\n 'deps' in currentValue &&\n 'tag' in currentValue\n ) {\n type EffectHook = { deps: unknown[] };\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n prevDeps = (prevValue as EffectHook).deps;\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n currentDeps = (currentValue as EffectHook).deps;\n hookType = 'effect';\n }\n // useMemo/useCallback store [result, deps].\n else if (\n Array.isArray(prevValue) &&\n Array.isArray(currentValue) &&\n prevValue.length === 2 &&\n currentValue.length === 2 &&\n Array.isArray(prevValue[1]) &&\n Array.isArray(currentValue[1])\n ) {\n prevDeps = prevValue[1];\n currentDeps = currentValue[1];\n hookType = typeof currentValue[0] === 'function' ? 'callback' : 'memo';\n }\n\n if (hookType && Array.isArray(prevDeps) && Array.isArray(currentDeps)) {\n const changedDepIndices: number[] = [];\n const changedDepOrigins: (DepOrigin | null)[] = [];\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n for (let j = 0; j < currentDeps.length; j++) {\n if (!Object.is(prevDeps[j], currentDeps[j])) {\n changedDepIndices.push(j);\n\n let origin: DepOrigin | null = null;\n const dep = currentDeps[j];\n if (\n valueProvenance &&\n dep != null &&\n (typeof dep === 'object' || typeof dep === 'function')\n ) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n origin = valueProvenance.get(dep as object | ((...args: never[]) => unknown)) || null;\n }\n changedDepOrigins.push(origin);\n }\n }\n\n let shouldReport = changedDepIndices.length > 0;\n if (shouldReport && mode === 'non-primitive') {\n // Only report if at least one non-primitive dep changed.\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n shouldReport = changedDepIndices.some((idx) => {\n const dep = currentDeps[idx];\n const t = typeof dep;\n return !(\n dep == null ||\n t === 'string' ||\n t === 'number' ||\n t === 'boolean' ||\n t === 'symbol' ||\n t === 'bigint'\n );\n });\n }\n\n if (shouldReport) {\n const thrashInfo: ThrashInfo = {\n hookIndex,\n hookType,\n deps: currentDeps,\n changedDepIndices,\n changedDepOrigins,\n };\n\n if (hookType === 'effect') {\n type EffectValue = { tag?: number; create?: Function };\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const effectValue = currentValue as EffectValue;\n thrashInfo.effectTag = effectValue.tag;\n // Capture the effect function itself (the create function)\n if (effectValue.create) {\n thrashInfo.hookBody = effectValue.create;\n }\n thrashedEffects.push(thrashInfo);\n } else if (hookType === 'callback') {\n type CallbackValue = [Function, unknown[]];\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const callbackFn = (currentValue as CallbackValue)[0];\n // Capture the callback function itself\n thrashInfo.hookBody = callbackFn;\n thrashedCallbacks.push(thrashInfo);\n } else {\n type MemoValue = [unknown, unknown[]];\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const memoValue = (currentValue as MemoValue)[0];\n thrashInfo.memoValue = memoValue;\n // For useMemo, also expose the memoized value as hookBody\n thrashInfo.hookBody = memoValue;\n thrashedMemos.push(thrashInfo);\n }\n }\n }\n }\n\n prevHook = prevHook.next;\n currentHook = currentHook.next;\n hookIndex++;\n }\n\n return {\n effects: thrashedEffects,\n callbacks: thrashedCallbacks,\n memos: thrashedMemos,\n };\n}\n\nexport function didFiberUpdate(fiber: Fiber): boolean {\n // eslint-disable-next-line no-bitwise\n return (fiber.flags & PerformedWork) !== 0;\n}\n\n/**\n * Detect if fiber has actionable hook state changes by comparing with fiber.alternate.\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 \u26A0\uFE0F WARNING: fiber.alternate COMPARISON IS UNRELIABLE \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * This function compares fiber.memoizedState vs fiber.alternate.memoizedState.\n *\n * THE PROBLEM:\n * fiber.alternate is NOT always \"state from the previous commit\".\n * It's \"state from last time this fiber was used as work-in-progress\".\n *\n * If a component re-renders due to parent/context changes (not self-update),\n * its alternate may be stale - from 1 commit ago, or 100 commits ago!\n *\n * This causes FALSE POSITIVES: we detect \"state changed\" when it didn't\n * change in THIS commit - it changed in some PAST commit.\n *\n * WHEN THIS FUNCTION IS RELIABLE:\n * \u2713 Component called setState (it IS the initiator)\n * \u2713 Component has useSyncExternalStore that just triggered\n * \u2713 Used alongside memoizedUpdaters validation\n *\n * WHEN THIS FUNCTION IS UNRELIABLE:\n * \u2717 Component re-rendered due to parent update\n * \u2717 Component re-rendered due to context change\n * \u2717 Component was memoized and skipped N commits\n * \u2717 Any scenario where alternate wasn't recently updated\n *\n * RECOMMENDED USAGE:\n * - In development: Use memoizedUpdaters to verify component is an initiator,\n * THEN use this function to get hook change details.\n * - In production: Use lastSeenHookState tracking (see detector.tsx)\n * instead of relying on fiber.alternate.\n *\n * See detector.tsx for the full explanation of the \"swap\" problem and solution.\n */\nexport function didFiberSelfUpdate(fiber: Fiber): StateChangeResult | null {\n // Early exit: only check fibers that actually rendered (have PerformedWork flag)\n if (!didFiberUpdate(fiber)) return null;\n\n const alt = fiber.alternate;\n if (!alt) return null;\n\n const prevState = alt.memoizedState;\n const currentState = fiber.memoizedState;\n\n const result = detectHookStateChanges(prevState, currentState);\n return result.hasChange ? result : null;\n}\n\nexport function isDevelopment(): boolean {\n return process.env.NODE_ENV !== 'production';\n}\n", "/**\n * Named constants for CommitStats tuple indices.\n *\n * CommitStats is a fixed 10-position tuple per commit. This module provides\n * human-readable names for each index to replace magic numbers in code.\n *\n * Tuple structure:\n * [0] collateral \u2014 total updates caused by this source (collateral damage)\n * [1] sources \u2014 number of distinct sources that fired in this commit\n * [2] restarts \u2014 render count from ATL render-counter delta (or 0 if not available)\n * [3] performedWork \u2014 components with PerformedWork flag set\n * [4] effects \u2014 effect count\n * [5] memos \u2014 memo count\n * [6] callbacks \u2014 callback count\n * [7] contextUpdates \u2014 context update count\n * [8] unmountedComponents \u2014 number of unmounted components\n * [9] unmountedSubtrees \u2014 number of unmounted subtrees\n *\n * This positional layout is shared by the detector, serializer, bridge, and\n * offline readers. Changing an index is a wire-format change even though the\n * tuple remains valid TypeScript, so keep the names and length together.\n */\n\nexport const CS_COLLATERAL = 0;\nexport const CS_SOURCES = 1;\nexport const CS_RESTARTS = 2;\nexport const CS_PERFORMED_WORK = 3;\nexport const CS_EFFECTS = 4;\nexport const CS_MEMOS = 5;\nexport const CS_CALLBACKS = 6;\nexport const CS_CONTEXT_UPDATES = 7;\nexport const CS_UNMOUNTED_COMPONENTS = 8;\nexport const CS_UNMOUNTED_SUBTREES = 9;\n\n/**\n * Total length of the CommitStats tuple.\n * Used for validation and bounds checking.\n */\nexport const COMMIT_STATS_LENGTH = 10;\n\n/**\n * Array of all commitStats indices for iteration/validation.\n */\nexport const ALL_COMMIT_STATS_INDICES = [\n CS_COLLATERAL,\n CS_SOURCES,\n CS_RESTARTS,\n CS_PERFORMED_WORK,\n CS_EFFECTS,\n CS_MEMOS,\n CS_CALLBACKS,\n CS_CONTEXT_UPDATES,\n CS_UNMOUNTED_COMPONENTS,\n CS_UNMOUNTED_SUBTREES,\n] as const;\n", "/**\n * Report Serializer - Converts Report to serializable DTO.\n *\n * PROBLEM:\n * The Report interface contains non-serializable data (Fiber references, ComponentType functions)\n * which makes it unsuitable for JSON.stringify(), IPC, or network transmission.\n *\n * SOLUTION:\n * Strip non-serializable fields (fiber, type). Keep only what's needed:\n * - sourceId already contains component name (e.g., \"MyComponent#1@5\")\n * - Metrics and numerical data\n * - No need to convert anything - just omit problematic fields\n *\n * USAGE:\n * ```typescript\n * const report = detector.report(50);\n * const dto = serializeReport(report);\n *\n * // Now safe to serialize\n * const json = JSON.stringify(dto);\n *\n * // Send over IPC/network\n * postMessage({ type: 'report', data: dto });\n * ```\n *\n * DESIGN:\n * - Minimal DTO - only what you need for metrics/analysis\n * - sourceId already has component name - no conversion needed\n * - Drop fiber and type fields completely\n *\n * The serializer is also the trust boundary between page-side React objects\n * and helper/offline consumers. A DTO must remain stable after the page is\n * gone, so it carries evidence and summaries rather than live object identity.\n */\n\nimport type { CommitMetricsDelta, IntegrationMode } from './commit-metrics-adapter';\n\n// ============================================================================\n// DTO TYPES (Serializable - no function refs, no Fiber refs)\n// ============================================================================\n\n/**\n * Commit stats tuple: [collateral, sources, restarts, performedWork, effects, memos, callbacks,\n * contextUpdates, unmountedComponents, unmountedSubtrees]. Mirrors CommitStats in reporter.tsx.\n */\nexport type CommitStatsDTO = [\n collateral: number,\n sources: number,\n restarts: number,\n performedWork: number,\n effects: number,\n memos: number,\n callbacks: number,\n contextUpdates: number,\n unmountedComponents: number,\n unmountedSubtrees: number,\n];\n\n/**\n * Per-commit counter deltas from the commit metrics adapter, keyed by counter\n * name. The counters depend on the adapter (see `meta.metricsAdapter`).\n */\nexport type CommitMetricsDeltaDTO = CommitMetricsDelta;\n\n/** @deprecated Use CommitMetricsDeltaDTO. Kept for one release. */\nexport type ATLCommitDeltaDTO = CommitMetricsDeltaDTO;\n\n/**\n * Commit timing data - measures React commit duration and detector overhead.\n */\nexport interface CommitTimingDTO {\n timeSinceLastCommit: number;\n detectorOverhead: number;\n}\n\n/**\n * Report metadata - profiling context and overhead metrics.\n */\nexport interface ReportMetaDTO {\n version: number;\n commits: number;\n config: {\n detectionLevel: 'stats' | 'sources' | 'amplifierMetrics' | 'amplifiers' | 'full';\n effectThrashMode: 'non-primitive' | 'all';\n captureFibers: boolean;\n historySize: number;\n };\n memoizedUpdatersSupport: {\n available: boolean;\n commitsWithData: number;\n coverage: string;\n };\n /** Commit-hook integration model; older reports used `'atl'` for `'adapter:atl'`. */\n integrationMode?: IntegrationMode | 'atl';\n /** Id of the commit metrics adapter that drove the report, or null. */\n metricsAdapter?: string | null;\n /** Per-field availability for commitStats indices and metricsByCommit. */\n dataAvailability?: Record<string, boolean>;\n amplifiersMetrics?: {\n totalHookThrashes: number;\n affectedComponentCount: number;\n };\n timing: {\n totalDetectorOverhead: number;\n avgDetectorOverhead: number;\n totalTimeSpan: number;\n avgTimeBetweenCommits: number;\n };\n}\n\n/**\n * Minimal serializable source - just the metrics, no functions/fibers.\n * sourceId already contains component name (e.g., \"MyComponent#1@5\")\n */\nexport interface SourceDTO {\n sourceId: string;\n depth: number;\n collateralUpdates: number;\n maxCollateralUpdates: number;\n maxPenetrationDepth: number;\n causedUpdates: number;\n restartWaste?: number;\n maxRestartWaste?: number;\n}\n\n/**\n * Source entry in sourcesByCommit - which sources fired in each commit.\n */\nexport interface SourceByCommitDTO {\n sourceId: string;\n depth: number;\n collateral: number;\n rank: number | null;\n sourceIndex: number | null;\n trashers?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n isRepeat?: boolean;\n}\n\n/**\n * Serializable Report - minimal data for metrics and analysis.\n * All non-serializable fields (fiber, type) are omitted.\n */\nexport interface SuspenseBoundaryEventDTO {\n depth: number;\n entered: boolean;\n left: boolean;\n}\n\nexport interface UnmountSampleDTO {\n name: string;\n key: string | null;\n depth: number | null;\n count: number;\n source?: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n}\n\nexport type PropChangeKindDTO = 'same' | 'ref-changed' | 'scalar-changed' | 'added' | 'removed';\n\nexport interface PropValueSummaryDTO {\n type: string;\n isArray: boolean;\n isFunction: boolean;\n isNull: boolean;\n preview: string;\n display?: string;\n length?: number;\n keysTop?: string[];\n sample?: unknown[];\n}\n\nexport interface PropChangeEvidenceDTO {\n name: string;\n kind: PropChangeKindDTO;\n prev: PropValueSummaryDTO;\n current: PropValueSummaryDTO;\n}\n\nexport interface RenderedComponentEvidenceDTO {\n sourceId: string;\n name: string;\n depth: number;\n parentSourceId: string | null;\n ownerSourceId: string | null;\n isSelfSource: boolean;\n propChanges: PropChangeEvidenceDTO[];\n hasPropChanges: boolean;\n trasherCounts: { effects: number; callbacks: number; memos: number };\n}\n\nexport interface CommitInteractionActionDTO {\n id: number;\n lastCommitId: number;\n deltaTime: number;\n action: string;\n location: {\n dom: {\n tag: string | null;\n text: string;\n nearestTestId: string | null;\n };\n targetFiber: {\n name: string | null;\n key: string | null;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n ownerStackKind: 'owners' | 'parents';\n ownerStack: Array<{\n name: string | null;\n key: string | null;\n props: string[];\n hookCount: number;\n hookCountTruncated: boolean;\n hookCountMax: number;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n }>;\n } | null;\n };\n}\n\nexport interface ReportDTO {\n meta: ReportMetaDTO;\n sources: SourceDTO[];\n commitStats: Record<number, CommitStatsDTO>;\n suspenseByCommit: Record<number, SuspenseBoundaryEventDTO[]>;\n sourcesByCommit?: Record<number, SourceByCommitDTO[]>;\n interactionsByCommit?: Record<number, CommitInteractionActionDTO[]>;\n renderedByCommit?: Record<number, RenderedComponentEvidenceDTO[]>;\n metricsByCommit?: Record<number, CommitMetricsDeltaDTO>;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit?: Record<number, CommitMetricsDeltaDTO>;\n timing?: Record<number, CommitTimingDTO>;\n}\n\n// ============================================================================\n// SERIALIZATION FUNCTION\n// ============================================================================\n\n/**\n * Convert Report to serializable DTO.\n *\n * Strips non-serializable fields (fiber, type) and keeps only essential metrics.\n *\n * @param report - Full Report from detector.report()\n * @returns Minimal serializable ReportDTO safe for JSON.stringify()\n */\nexport function serializeReport(report: {\n meta: ReportMetaDTO;\n sources: Array<{\n sourceId: string;\n depth: number;\n causedUpdates: number;\n collateralUpdates: number;\n maxCollateralUpdates: number;\n maxPenetrationDepth: number;\n restartWaste?: number;\n maxRestartWaste?: number;\n }>;\n commitStats: Record<number, CommitStatsDTO>;\n sourcesByCommit?: Record<\n number,\n Array<{\n sourceId: string;\n depth: number;\n collateral: number;\n rank: number | null;\n sourceIndex: number | null;\n hooks?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n trashers?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n isRepeat?: boolean;\n }>\n >;\n suspenseByCommit?: Record<number, Array<{ depth: number; entered: boolean; left: boolean; fiber?: unknown }>>;\n interactionsByCommit?: Record<number, CommitInteractionActionDTO[]>;\n renderedByCommit?: Record<number, RenderedComponentEvidenceDTO[]>;\n metricsByCommit?: Record<number, CommitMetricsDeltaDTO>;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit?: Record<number, CommitMetricsDeltaDTO>;\n timing?: Record<number, CommitTimingDTO>;\n}): ReportDTO {\n // Just extract the fields we need - no conversion necessary\n const sources: SourceDTO[] = report.sources.map((source) => ({\n sourceId: source.sourceId,\n depth: source.depth,\n causedUpdates: source.causedUpdates,\n collateralUpdates: source.collateralUpdates,\n maxCollateralUpdates: source.maxCollateralUpdates,\n maxPenetrationDepth: source.maxPenetrationDepth,\n ...(source.restartWaste !== undefined && { restartWaste: source.restartWaste }),\n ...(source.maxRestartWaste !== undefined && { maxRestartWaste: source.maxRestartWaste }),\n }));\n\n // Serialize sourcesByCommit (strip non-serializable type/fiber fields)\n const sourcesByCommit: Record<number, SourceByCommitDTO[]> | undefined = report.sourcesByCommit\n ? Object.fromEntries(\n Object.entries(report.sourcesByCommit).map(([commitId, commitSources]) => [\n commitId,\n commitSources.map((src) => ({\n sourceId: src.sourceId,\n depth: src.depth,\n collateral: src.collateral,\n rank: src.rank,\n sourceIndex: src.sourceIndex,\n ...((src.trashers || src.hooks) && { trashers: src.trashers || src.hooks }),\n ...(src.isRepeat && { isRepeat: true }),\n })),\n ])\n )\n : undefined;\n\n // Serialize suspenseByCommit \u2014 strip fiber refs (not serializable), keep scalar event fields\n const suspenseByCommit: Record<number, SuspenseBoundaryEventDTO[]> = {};\n if (report.suspenseByCommit) {\n for (const [k, evts] of Object.entries(report.suspenseByCommit)) {\n suspenseByCommit[Number(k)] = evts.map((e) => ({\n depth: e.depth,\n entered: e.entered,\n left: e.left,\n }));\n }\n }\n\n return {\n meta: report.meta,\n sources,\n commitStats: report.commitStats,\n suspenseByCommit,\n ...(sourcesByCommit && { sourcesByCommit }),\n ...(report.interactionsByCommit && { interactionsByCommit: report.interactionsByCommit }),\n ...(report.renderedByCommit && { renderedByCommit: report.renderedByCommit }),\n ...((report.metricsByCommit || report.atlByCommit) && {\n metricsByCommit: report.metricsByCommit || report.atlByCommit,\n atlByCommit: report.metricsByCommit || report.atlByCommit,\n }),\n ...(report.timing && { timing: report.timing }),\n };\n}\n", "/**\n * Commit metrics adapter: an optional per-commit counter source that sits next\n * to the DevTools fiber walk.\n *\n * The detector always captures commits through the DevTools hook. Some hosts\n * also run an instrumented react-dom that exposes render counters and calls a\n * commit callback of its own. An adapter wraps one such host surface: it seeds\n * and protects the surface, snapshots its counters, turns two snapshots into a\n * per-commit delta plus a restart count, and wires the host's commit callback\n * to the detector. Without an adapter the detector runs in `devtools` mode and\n * reports restarts as unavailable.\n *\n * One adapter is active at a time. Product adapters live in `src/plugins/`.\n */\n\nimport type { Fiber } from './internals';\n\nexport type CommitMetricsRoot = { current: Fiber; memoizedUpdaters?: Set<Fiber> };\n\n/** Raw counters read from the host surface at one point in time. */\nexport type CommitMetricsSnapshot = Record<string, unknown>;\n\n/** Counter deltas for one commit, keyed by counter name. */\nexport type CommitMetricsDelta = { [counter: string]: number | undefined };\n\nexport type CommitMetricsMeasurement = {\n delta: CommitMetricsDelta;\n /** Render passes React performed but did not commit. Never negative. */\n restarts: number;\n};\n\nexport interface CommitMetricsAdapter {\n /** Stable id; the detector reports `integrationMode: 'adapter:<id>'`. */\n readonly id: string;\n /**\n * Stack frame names the host surface adds to every render. Hook ancestry\n * hides them like other renderer internals.\n */\n readonly frameFilters?: readonly string[];\n /**\n * Setup that must run before React evaluates, such as installing an accessor\n * that survives host cleanup. Called by the extension's early bootstrap\n * through `__AVALANCHE__.runPrePageHooks(config)`.\n */\n prePage?(config: unknown): void;\n /** Seed the host surface before a detector installs, unless the host owns it. */\n prepare?(): void;\n /** Whether the host surface is present right now. */\n isAvailable(): boolean;\n snapshot(): CommitMetricsSnapshot | null;\n measure(\n before: CommitMetricsSnapshot,\n after: CommitMetricsSnapshot,\n committedComponents: number,\n commitId: number,\n ): CommitMetricsMeasurement;\n /**\n * Route the host's commit callback to `onCommit`. Returns false when the\n * surface is absent. A callback is proof that the host surface is live.\n */\n attach(onCommit: (root: CommitMetricsRoot) => void): boolean;\n /** True while the callback from attach() is still wired into the live surface. */\n isAttached(): boolean;\n /** Re-seed and re-wire after the host wiped or replaced its surface. */\n reattach(): void;\n /** Remove the callback from attach(), only if it is still ours. */\n detach(): void;\n}\n\nlet active: CommitMetricsAdapter | null = null;\n\nconst REQUIRED_METHODS = ['isAvailable', 'snapshot', 'measure', 'attach', 'isAttached', 'reattach', 'detach'] as const;\n\n/**\n * Make `adapter` the active commit metrics adapter for detectors installed\n * afterwards. Replaces any earlier adapter. Returns an unregister function.\n */\nexport function registerCommitMetricsAdapter(adapter: CommitMetricsAdapter): () => void {\n if (!adapter || typeof adapter.id !== 'string' || !adapter.id) {\n throw new TypeError('registerCommitMetricsAdapter expects an adapter with a non-empty id');\n }\n for (const method of REQUIRED_METHODS) {\n if (typeof adapter[method] !== 'function') {\n throw new TypeError(`commit metrics adapter ${adapter.id} is missing ${method}()`);\n }\n }\n active = adapter;\n return () => {\n if (active === adapter) active = null;\n };\n}\n\nexport function getCommitMetricsAdapter(): CommitMetricsAdapter | null {\n return active;\n}\n\n/**\n * Run the active adapter's pre-page hook. Returns the adapter id when a hook\n * ran, or null. A failing hook is swallowed: the detector falls back to\n * DevTools capture.\n */\nexport function runPrePageHooks(config?: unknown): string | null {\n const adapter = active;\n if (!adapter || typeof adapter.prePage !== 'function') return null;\n try {\n adapter.prePage(config);\n return adapter.id;\n } catch {\n return null;\n }\n}\n\nexport type IntegrationMode = `adapter:${string}` | 'devtools' | 'none';\n\nexport function adapterIdFromMode(mode: IntegrationMode | string | null | undefined): string | null {\n return typeof mode === 'string' && mode.startsWith('adapter:') ? mode.slice('adapter:'.length) : null;\n}\n", "/**\n * Projects the detector's live fiber history into ranked evidence and the\n * serializable report consumed by bridge commands and offline analysis. The\n * detector owns capture-time truth; this layer owns interpretation and output\n * ordering, so presentation changes do not alter hot-path collection.\n */\n\nimport type { ComponentType, ChangedHook, Fiber, ThrashInfo } from './internals';\nimport { CS_RESTARTS } from './commit-stats-indices';\nimport { getComponentName } from './internals';\nimport type { ReportDTO } from './report-serializer';\nimport { serializeReport } from './report-serializer';\nimport {\n type CommitMetricsAdapter,\n type CommitMetricsDelta,\n type CommitMetricsSnapshot,\n type IntegrationMode,\n adapterIdFromMode,\n} from './commit-metrics-adapter';\n\nexport type SortBy = 'effect' | 'callback' | 'memo' | 'total';\n\nexport interface Source {\n sourceId: string; // Human-readable ID (e.g., \"Counter#1@3\" in dev, \"Unknown#1@3\" in prod)\n type: ComponentType;\n depth: number;\n renderCount: number;\n causedUpdates: number;\n collateralUpdates: number;\n maxCollateralUpdates: number;\n maxPenetrationDepth: number; // Relative to source depth (how deep the avalanche went)\n updateHistory: Record<number, Record<number, ChangedHook> | 'repeat' | string>;\n collateralByCommit: Record<number, number>; // Per-commit collateral for this source\n fiber?: Fiber;\n /** Changed hook indices from this source's latest self-update; maps debugHook indices to debug-render events. */\n debugHookIndices?: number[];\n\n /**\n * RESTART WASTE TRACKING - identifies sources contributing to restart waste\n *\n * Restarts = wasted renders (component rendered but work was discarded)\n * Attribution: proportional to sources that fired in each commit with restarts\n *\n * Example: Commit has 1000 restarts, 2 sources fire\n * \u2192 Each source attributed 500 restarts\n *\n * High restartWaste = this source triggers commits that cause React to restart work\n */\n restartWaste?: number; // Total restarts attributed to this source across all commits\n maxRestartWaste?: number; // Max restarts in a single commit\n restartWasteByCommit?: Record<number, number>; // Per-commit restart waste for this source\n\n /**\n * Components that were amplified when this source triggered them.\n * These are components that re-rendered with unstable hooks (effects, callbacks, memos).\n * Includes both:\n * - This source itself (if it has unstable hooks)\n * - Descendant components that re-rendered with unstable hooks\n */\n amplified?: Array<{\n /** Component that amplified work */\n sourceId: string;\n type: ComponentType;\n depth: number;\n /** Total effect amplifications across all commits */\n effectCount: number;\n /** Total callback amplifications across all commits */\n callbackCount: number;\n /** Total memo amplifications across all commits */\n memoCount: number;\n /** Total hook amplifications (effect + callback + memo) */\n hooksTotal: number;\n /** Commits where this component amplified work */\n commitIds: number[];\n /** Per-commit breakdown: { commitId: { effects, callbacks, memos } } */\n byCommit: Record<number, { effects: number; callbacks: number; memos: number }>;\n /** Latest amplification details */\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n }>;\n}\n\nexport interface Amplifier {\n type: ComponentType;\n renderCount: number;\n instancesTotal: number;\n maxInstancesPerCommit: number;\n hooksTotal: number;\n maxHooksPerCommit: number;\n effectCount: number;\n callbackCount: number;\n memoCount: number;\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n}\n\n/**\n * Linked thrasher - connects thrashing info to source identity.\n *\n * This enables:\n * - thrasher.sourceId \u2192 navigate to source\n * - thrasher.isSource \u2192 prioritize fixes (source+thrasher = high impact)\n * - thrasher.commitIds \u2192 correlate with commitStats\n * - source.thrashing \u2192 see hook instability for a source\n */\nexport interface AmplifierSource {\n /** Human-readable ID (e.g., \"Counter#1@5\" in dev, \"Unknown#1@5\" in prod) */\n sourceId: string;\n /** Component type (function reference) */\n type: ComponentType;\n /** Depth in component tree */\n depth: number;\n\n /** Collateral damage caused by this source (0 if not tracked) */\n collateralUpdates: number;\n\n /** Total effect amplifications across all commits */\n effectCount: number;\n /** Total callback amplifications across all commits */\n callbackCount: number;\n /** Total memo amplifications across all commits */\n memoCount: number;\n /** Total hook amplifications (effect + callback + memo) */\n hooksTotal: number;\n\n /** Commits where this component amplified work */\n commitIds: number[];\n /** Per-commit breakdown: { commitId: { effects, callbacks, memos } } */\n byCommit: Record<number, { effects: number; callbacks: number; memos: number }>;\n\n /** If not a source, which sourceId caused this to re-render? */\n causedBySourceId: string | null;\n\n /** Latest amplification details */\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n}\n\n/**\n * Commit stats tuple: [collateral, sources, restarts, performedWork, effects, memos, callbacks, contextUpdates, unmountedComponents, unmountedSubtrees]\n * Use these numbers to find which commits to investigate in DevTools.\n * - collateral: components re-rendered as victims\n * - sources: components that initiated updates (update sources)\n * - restarts: extra renders due to external store mutations, priority changes, etc.\n * - performedWork: components with PerformedWork flag (actual work React processed)\n * - effects/memos/callbacks: thrashing hooks (effects likely cause next commit!)\n * - contextUpdates: number of Context Providers whose value changed this commit\n * - unmountedComponents: total component fibers unmounted this commit\n * - unmountedSubtrees: number of distinct unmount \"branch starts\" (topmost deleted components)\n */\nexport type CommitStats = [\n collateral: number,\n sources: number,\n restarts: number,\n performedWork: number,\n effects: number,\n memos: number,\n callbacks: number,\n contextUpdates: number,\n unmountedComponents: number,\n unmountedSubtrees: number,\n];\n\n/**\n * Human-readable keys for CommitStats tuple positions.\n * Use with commitStats[commit][commitStatsKeys.collateral]\n */\nexport const commitStatsKeys = {\n collateral: 0,\n sources: 1,\n restarts: 2,\n performedWork: 3,\n effects: 4,\n memos: 5,\n callbacks: 6,\n contextUpdates: 7,\n unmountedComponents: 8,\n unmountedSubtrees: 9,\n} as const;\n\n/**\n * Report metadata - profiling context and overhead metrics.\n */\nexport interface ReportMeta {\n /** Report format version - increment when changing data structure */\n version: number;\n /** Total commits processed */\n commits: number;\n /** Detector configuration used during profiling */\n config: {\n /** Detection level: 'stats' (minimal), 'sources', 'amplifiers', or 'full' */\n detectionLevel: DetectionLevel;\n /** Effect thrashing sensitivity: 'non-primitive' or 'all' */\n effectThrashMode: 'non-primitive' | 'all';\n /** Whether fibers were captured (for debugging) */\n captureFibers: boolean;\n /** Update history size per source */\n historySize: number;\n };\n /** memoizedUpdaters availability and coverage */\n memoizedUpdatersSupport: {\n available: boolean;\n commitsWithData: number;\n coverage: string;\n };\n /**\n * Which commit-hook integration model produced this report. Determines what\n * is reliably present in `commitStats[N]` and `metricsByCommit[N]`.\n *\n * 'adapter:<id>' \u2014 A commit metrics adapter (for example `adapter:atl`) drove\n * the commit callback with host render counters. ALL fields below\n * are populated and `metricsByCommit` is present.\n * 'devtools' \u2014 Reconstructed entirely from the React DevTools commit hook\n * (fiber walk only). The fiber-walk fields are real measurements:\n * collateral, sources, performedWork, effects, memos, callbacks,\n * contextUpdates. The render-counter math (restarts) is NOT\n * available \u2014 `commitStats[N][2]` will be 0 (semantically\n * \"unknown / not measurable in this mode\") and `metricsByCommit`\n * is empty. This is normal on stock react-dom.\n * 'none' \u2014 Detector wasn't installed when this report was generated.\n *\n * Reports before the adapter seam used `'atl'` for `'adapter:atl'`.\n */\n integrationMode: IntegrationMode;\n /** Id of the commit metrics adapter that drove this report, or null. */\n metricsAdapter: string | null;\n /**\n * Per-field availability map for `commitStats[N]` indices. `false` means the\n * value is a placeholder (typically 0) that consumers should treat as unknown\n * rather than a real measurement of zero.\n *\n * Stable across all commits in a given report \u2014 set once from integrationMode.\n */\n dataAvailability: {\n /** [0] perCommit.totalCollateral \u2014 reconstructed from fiber walk */\n collateral: boolean;\n /** [1] perCommit.selfUpdated.size \u2014 reconstructed from fiber walk */\n sources: boolean;\n /** [2] derived from the adapter's render-counter delta \u2014 only in 'adapter:<id>' mode */\n restarts: boolean;\n /** [3] perCommit.committedComponentCount \u2014 reconstructed from fiber walk */\n performedWork: boolean;\n /** [4] perCommit.effectCount \u2014 reconstructed from fiber walk */\n effects: boolean;\n /** [5] perCommit.memoCount \u2014 reconstructed from fiber walk */\n memos: boolean;\n /** [6] perCommit.callbackCount \u2014 reconstructed from fiber walk */\n callbacks: boolean;\n /** [7] perCommit.contextUpdates \u2014 reconstructed from fiber walk */\n contextUpdates: boolean;\n /** Adapter counters in metricsByCommit \u2014 only in 'adapter:<id>' mode */\n metricsByCommit: boolean;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit: boolean;\n };\n /** Amplifier summary (when detectionMode: 'amplifierMetrics') */\n amplifiersMetrics?: {\n totalHookThrashes: number;\n affectedComponentCount: number;\n };\n /**\n * Timing summary - shows detector overhead and commit durations.\n * Use this to justify avalanche-detector overhead in production.\n */\n timing: {\n /** Total time spent in detector across all commits (ms) */\n totalDetectorOverhead: number;\n /** Average detector overhead per commit (ms) */\n avgDetectorOverhead: number;\n /** Total time from first to last commit (ms) */\n totalTimeSpan: number;\n /** Average time between commits (ms) */\n avgTimeBetweenCommits: number;\n };\n}\n\nexport interface HostUnmountSummary {\n elements: number;\n text: number;\n tagsTop: Array<[string, number]>;\n testIdsTop: Array<[string, number]>;\n rolesTop: Array<[string, number]>;\n ariaLabels: string[];\n textHints: string[];\n}\n\nexport interface UnmountSample {\n name: string;\n key: string | null;\n depth: number | null;\n count: number;\n source?: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n host?: HostUnmountSummary;\n}\n\nexport type InteractionCaptureLevel = 'off' | 'explicit' | 'noisy' | 'all';\n\nexport interface InteractionActionLocation {\n dom: {\n tag: string | null;\n text: string;\n nearestTestId: string | null;\n };\n targetFiber: {\n name: string | null;\n key: string | null;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n ownerStackKind: 'owners' | 'parents';\n ownerStack: Array<{\n name: string | null;\n key: string | null;\n props: string[];\n hookCount: number;\n hookCountTruncated: boolean;\n hookCountMax: number;\n source: { fileName?: string; lineNumber?: number; columnNumber?: number } | null;\n }>;\n } | null;\n}\n\nexport interface InteractionAction {\n /** Sequential action id within this detector capture. */\n id: number;\n /** Native event name, e.g. click, keydown, wheel. */\n action: string;\n /** performance.now() at event capture time. Kept live-only; DTO emits deltaTime. */\n timestamp: number;\n /** DOM-grounded event target plus target component/ownership stack. */\n location: InteractionActionLocation;\n}\n\nexport type PropChangeKind = 'same' | 'ref-changed' | 'scalar-changed' | 'added' | 'removed';\n\nexport interface PropValueSummary {\n type: string;\n isArray: boolean;\n isFunction: boolean;\n isNull: boolean;\n preview: string;\n display?: string;\n length?: number;\n keysTop?: string[];\n sample?: unknown[];\n}\n\nexport interface PropChangeEvidence {\n name: string;\n kind: PropChangeKind;\n prev: PropValueSummary;\n current: PropValueSummary;\n}\n\nexport interface RenderedComponentEvidence {\n sourceId: string;\n name: string;\n depth: number;\n parentSourceId: string | null;\n ownerSourceId: string | null;\n isSelfSource: boolean;\n propChanges: PropChangeEvidence[];\n hasPropChanges: boolean;\n trasherCounts: { effects: number; callbacks: number; memos: number };\n}\n\nexport interface CommitInteractionAction {\n /** Original action id \u2014 must match InteractionAction.id for describe-action lookup. */\n id: number;\n /** Last commit id at the moment this action was observed. */\n lastCommitId: number;\n /** Milliseconds from action capture to the linked commit. */\n deltaTime: number;\n action: string;\n location: InteractionAction['location'];\n}\n\nexport interface Report {\n /** Metadata: version, counts, overhead metrics */\n meta: ReportMeta;\n /** Components that caused updates, sorted by collateral damage */\n sources: Source[];\n /** Bridge to DevTools - maps commit ID to sources that fired in that commit */\n sourcesByCommit: Record<\n number,\n Array<{\n sourceId: string;\n type: ComponentType;\n depth: number;\n /** Collateral damage caused by this source in THIS commit */\n collateral: number;\n /** Position in top N sources list (1-based), or null if not in top N */\n rank: number | null;\n /** Index into sources[] array for full accumulated data, or null if not in top N */\n sourceIndex: number | null;\n hooks?: Array<{ index: number; prevValue: unknown; currentValue: unknown }>;\n isRepeat?: boolean;\n }>\n >;\n /**\n * Per-commit metrics to find the needle: [collateral, effects, memos, callbacks]\n * High collateral = avalanche. High effects = likely causes next commit!\n */\n commitStats: Record<number, CommitStats>;\n /**\n * Per-commit timing data - correlate restarts with commit duration.\n * High commitStats[N].restarts + high commitTimings[N].timeSinceLastCommit = React wasted work.\n */\n commitTimings: Record<number, CommitTiming>;\n /**\n * Per-commit counter deltas from the commit metrics adapter - low-level React\n * work per commit. With the ATL adapter:\n * metricsByCommit[N].componentRenderWithHooksCount + finishClassComponentCount\n * should equal commitStats[N].collateral + commitStats[N].sources\n */\n metricsByCommit?: Record<number, CommitMetricsDelta>;\n /** @deprecated Alias of `metricsByCommit`, kept for one release. */\n atlByCommit?: Record<number, CommitMetricsDelta>;\n /** @deprecated Use amplifierSources instead for full source linkage */\n amplifiers?: Amplifier[];\n /**\n * Amplifier sources - components that amplified the update cost with hook re-executions.\n * Shows which components responded to updates with expensive work (effects, memos, callbacks).\n * Linked to the source that triggered them.\n */\n amplifierSources?: AmplifierSource[];\n /**\n * Per-commit Suspense boundary transitions.\n * Only populated for commits where at least one boundary entered or left fallback.\n * Empty object when no Suspense transitions occurred during the capture.\n */\n suspenseByCommit: Record<number, SuspenseBoundaryEvent[]>;\n\n /** Bounded samples of component subtrees unmounted per commit. */\n unmountsByCommit?: Record<number, UnmountSample[]>;\n\n /** Compact user/browser actions linked to nearby commits. */\n interactionsByCommit?: Record<number, CommitInteractionAction[]>;\n\n /** Structural evidence for each component that rendered in a commit. */\n renderedByCommit?: Record<number, RenderedComponentEvidence[]>;\n\n /**\n * Convert this report to a serializable DTO (safe for JSON.stringify, IPC, network).\n * Strips non-serializable fields like Fiber references and ComponentType functions.\n */\n toSerializable(): ReportDTO;\n}\n\nexport interface DetectorOptions {\n ignore?: ComponentType[];\n effectThrashMode?: 'non-primitive' | 'all';\n captureFibers?: boolean;\n /**\n * Detection mode - controls what the detector tracks (tiered for performance):\n *\n * Use DETECTION_LEVEL constants for clarity:\n * - DETECTION_LEVEL.LEVEL1_STATS ('stats'): Only commitStats, super fast\n * - DETECTION_LEVEL.LEVEL2_SOURCES ('sources'): + source tracking\n * - DETECTION_LEVEL.LEVEL3_AMPLIFIER_METRICS ('amplifierMetrics'): + aggregate amplifier counts only\n * - DETECTION_LEVEL.LEVEL3_AMPLIFIERS ('amplifiers'): + full amplifier arrays\n *\n * Shortcuts:\n * - false: Alias for 'stats' (minimal overhead)\n * - true: Alias for 'full' (maximum detail)\n *\n * Performance hierarchy (fastest to slowest):\n * stats < sources < amplifierMetrics < amplifiers \u2248 full\n */\n detectionMode?:\n | boolean\n | 'full'\n | 'amplifiers'\n | 'amplifierMetrics'\n | 'sources'\n | 'stats'\n | false;\n\n historySize?: number;\n\n /**\n * Browser action capture level. Defaults to 'explicit' to capture high-signal\n * actions (click/keyboard/input) while leaving noisy wheel/move capture opt-in.\n */\n interactionCapture?: InteractionCaptureLevel;\n\n /** Extra native event names to capture in addition to the selected level. */\n interactionEvents?: string[];\n\n /** Time window for linking captured actions to a commit, in ms. Default: 1000. */\n interactionWindowMs?: number;\n\n /**\n * Commit metrics adapter for host render counters. Defaults to the adapter\n * registered with `registerCommitMetricsAdapter` when the detector installs.\n * Pass `null` to run on the DevTools hook only.\n */\n metricsAdapter?: CommitMetricsAdapter | null;\n\n /** @deprecated Historical option used by older call sites. Prefer `detector.report(topN)` */\n topN?: number;\n}\n\nexport type ThrashMode = 'full' | 'counts' | false;\nexport type DetectionLevel = 'stats' | 'sources' | 'amplifierMetrics' | 'amplifiers' | 'full';\n\n/**\n * Internal amplifier source state - keyed by sourceId for navigation.\n */\nexport interface AmplifierSourceState {\n type: ComponentType;\n depth: number;\n effectCount: number;\n callbackCount: number;\n memoCount: number;\n hooksTotal: number;\n commitIds: number[];\n byCommit: Record<number, { effects: number; callbacks: number; memos: number }>;\n /** sourceId that caused this component to re-render (if not self-caused) */\n causedBySourceId: string | null;\n lastAmplification: {\n depth: number;\n thrashedHooks: ThrashInfo[];\n fiber?: Fiber;\n };\n}\n\n/**\n * Commit timing data - measures React commit duration and detector overhead.\n * All times in milliseconds.\n */\nexport interface CommitTiming {\n /** Time from previous commit end to this commit end (includes React work + idle time) */\n timeSinceLastCommit: number;\n /** Time spent in avalanche detector processing (our overhead) */\n detectorOverhead: number;\n}\n\n/**\n * Internal profiler state - tracks all avalanche detection data.\n *\n * This is the core state structure that accumulates across commits.\n * Most users should use the `Report` interface from `detector.report()` instead.\n */\nexport interface ProfilerState {\n /** Total commits processed since install() or reset() */\n commits: number;\n\n /**\n * All detected sources, keyed by stable source ID (e.g., \"Button#1@3\").\n * Source = component that caused an update (not just re-rendered).\n */\n sources: Map<string, Omit<Source, 'sourceId'>>;\n\n /** @deprecated Use amplifierSources instead */\n amplifiers: Map<ComponentType, Omit<Amplifier, 'type'>>;\n\n /**\n * Amplifier sources keyed by sourceId.\n * Enables source\u2194amplifier navigation and per-commit breakdown.\n */\n amplifierSources: Map<string, AmplifierSourceState>;\n\n /**\n * Aggregate thrashing counts (only if detectThrashing: 'counts').\n * Lightweight alternative to full thrashing analysis.\n */\n thrashCounts: null | { totalHooks: number; affectedComponents: Set<ComponentType> };\n\n /** Whether React DevTools hook exposes memoizedUpdaters (React 18.3.1+) */\n memoizedUpdatersAvailable: boolean;\n\n /** Number of commits where memoizedUpdaters data was present */\n commitsWithMemoizedUpdaters: number;\n\n /** Per-commit stats: [collateral, effects, memos, callbacks] */\n commitStats: Record<number, CommitStats>;\n\n /**\n * Per-commit counter deltas from the commit metrics adapter.\n * Enables full reconciliation with Avalanche counts.\n */\n metricsByCommit: Record<number, CommitMetricsDelta>;\n\n /** Last adapter snapshot (for delta calculation) */\n lastMetricsSnapshot: CommitMetricsSnapshot | null;\n\n /**\n * Per-commit timing data - measures commit duration and detector overhead.\n * Enables correlation: high restarts \u2192 longer commit times.\n */\n commitTimings: Record<number, CommitTiming>;\n\n /** Timestamp when last commit ended (for delta calculation) */\n lastCommitEndTime: number;\n\n /**\n * Per-commit Suspense boundary transitions.\n * Only populated for commits where at least one boundary entered or left fallback.\n */\n suspenseByCommit: Record<number, SuspenseBoundaryEvent[]>;\n\n /** Bounded samples of component subtrees unmounted per commit. */\n unmountsByCommit: Record<number, UnmountSample[]>;\n\n /** Recent action breadcrumbs captured from native events. */\n interactionActions: InteractionAction[];\n\n /** Compact user/browser actions linked to nearby commits. */\n interactionsByCommit: Record<number, CommitInteractionAction[]>;\n\n /** Structural evidence for each component that rendered in a commit. */\n renderedByCommit: Record<number, RenderedComponentEvidence[]>;\n}\n\nfunction isTrueSource(s: Source): boolean {\n const commits = Object.values(s.updateHistory);\n if (commits.length === 0) return false;\n\n // A source is \"true\" if ANY commit in the retained window has a concrete hook entry.\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n for (let i = 0; i < commits.length; i++) {\n const entry = commits[i];\n if (!entry || entry === 'repeat') {\n // Skip empty or repeat entries\n } else if (typeof entry === 'object' && entry !== null) {\n if (Object.values(entry).some((hook) => hook !== 'repeat')) {\n return true;\n }\n }\n }\n\n return false;\n}\n\n/**\n * A Suspense boundary state transition captured during a commit.\n * Only emitted when the boundary actually entered or left the fallback state.\n * Boundaries that render without delay (no fallback shown) produce no events.\n */\nexport interface SuspenseBoundaryEvent {\n /** Tree depth of the Suspense fiber */\n depth: number;\n /** true = boundary entered fallback (primary \u2192 suspended) */\n entered: boolean;\n /** true = boundary left fallback (suspended \u2192 primary revealed) */\n left: boolean;\n /** The Suspense fiber itself (only present when captureFibers is true) */\n fiber?: Fiber;\n}\n\nexport interface ReportOptions {\n /** Minimum collateral damage to include a source in sourcesByCommit (default: 0 - show all) */\n minCollateral?: number;\n}\n\nexport function buildReport(\n state: ProfilerState,\n thrashMode: ThrashMode,\n topN: number,\n sortBy: SortBy,\n options: ReportOptions = {},\n detectorConfig?: {\n effectThrashMode: 'non-primitive' | 'all';\n captureFibers: boolean;\n historySize: number;\n detectionLevel?: DetectionLevel;\n /**\n * Integration model that produced this report. Determines what's reliable\n * in commitStats and metricsByCommit. Defaults to 'none'.\n */\n integrationMode?: IntegrationMode;\n }\n): Report {\n const { minCollateral = 1 } = options;\n\n // Helper to generate human-readable sourceId from internal ID (e.g., \"T1#2@3\" -> \"Counter#2@3\")\n const toHumanReadableId = (internalId: string, type: ComponentType, depth: number): string => {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n const componentName = getComponentName({ type } as Fiber);\n // Extract instance number from internal ID (e.g., \"T1#2@3\" -> \"2\")\n const match = internalId.match(/#(\\d+)@/);\n const instanceNum = match ? match[1] : '1';\n return `${componentName}#${instanceNum}@${depth}`;\n };\n\n // Map internal IDs to human-readable IDs for the report\n const idMapping = new Map<string, string>(); // internalId -> humanId\n\n // Build ALL sources first (for accurate sourcesByCommit)\n const allSources = Array.from(state.sources.entries())\n .map(([internalId, s]) => {\n const humanId = toHumanReadableId(internalId, s.type, s.depth);\n idMapping.set(internalId, humanId);\n\n return {\n sourceId: humanId,\n ...s,\n maxPenetrationDepth: Math.max(0, s.maxPenetrationDepth - s.depth), // Convert to relative depth (never negative!)\n // Initialize restart waste tracking\n restartWaste: 0,\n maxRestartWaste: 0,\n restartWasteByCommit: {},\n };\n })\n .filter(isTrueSource);\n\n // RESTART WASTE ATTRIBUTION\n // Distribute restarts proportionally to sources that fired in each commit\n // This identifies sources contributing to restart waste\n Object.entries(state.commitStats).forEach(([commitIdStr, stats]) => {\n const commitId = Number(commitIdStr);\n const restarts = stats[CS_RESTARTS]; // commitStats[CS_RESTARTS] = restart count\n\n if (restarts === 0) return;\n\n // Find all sources that fired in this commit\n const sourcesInCommit = allSources.filter(\n (source) => source.updateHistory[commitId] !== undefined\n );\n\n if (sourcesInCommit.length === 0) {\n // Ghost restarts (Suspense, priority interruption, external store)\n // No sources to attribute to - these are not directly caused by component updates\n return;\n }\n\n // Distribute restarts proportionally among sources\n const restartsPerSource = restarts / sourcesInCommit.length;\n\n // Mutate the source objects directly (they're from allSources array we own)\n for (const sourceItem of sourcesInCommit) {\n sourceItem.restartWaste += restartsPerSource;\n sourceItem.restartWasteByCommit[commitId] = restartsPerSource;\n\n if (restartsPerSource > sourceItem.maxRestartWaste) {\n sourceItem.maxRestartWaste = restartsPerSource;\n }\n }\n });\n\n // Build amplified array for each source (Direction 1: Source \u2192 Amplified components)\n if (thrashMode === 'full') {\n for (const sourceItem of allSources) {\n const amplifiedByThisSource: Source['amplified'] = [];\n\n // Find all components that were amplified when this source triggered them\n state.amplifierSources.forEach((amplifierData, amplifierInternalId) => {\n const amplifierHumanId =\n idMapping.get(amplifierInternalId) ||\n toHumanReadableId(amplifierInternalId, amplifierData.type, amplifierData.depth);\n\n // Check if this component was amplified by the current source\n // amplifierData.causedBySourceId is the INTERNAL id, need to convert to human id\n const causedByHumanId = amplifierData.causedBySourceId\n ? idMapping.get(amplifierData.causedBySourceId)\n : null;\n\n if (causedByHumanId === sourceItem.sourceId || amplifierHumanId === sourceItem.sourceId) {\n // This component was either:\n // 1. Amplified by this source (descendant with unstable hooks)\n // 2. IS this source (self-amplification - source has unstable hooks)\n amplifiedByThisSource.push({\n sourceId: amplifierHumanId,\n type: amplifierData.type,\n depth: amplifierData.depth,\n effectCount: amplifierData.effectCount,\n callbackCount: amplifierData.callbackCount,\n memoCount: amplifierData.memoCount,\n hooksTotal: amplifierData.hooksTotal,\n commitIds: amplifierData.commitIds,\n byCommit: amplifierData.byCommit,\n lastAmplification: amplifierData.lastAmplification,\n });\n }\n });\n\n if (amplifiedByThisSource.length > 0) {\n sourceItem.amplified = amplifiedByThisSource;\n }\n }\n }\n\n // Top N sources - update sources sorted by TOTAL WASTE (collateral + restarts)\n // This identifies the real offenders, including those causing restart waste\n const sources = [...allSources]\n .sort((a, b) => {\n const aTotalWaste = a.collateralUpdates + (a.restartWaste || 0);\n const bTotalWaste = b.collateralUpdates + (b.restartWaste || 0);\n return (\n bTotalWaste - aTotalWaste ||\n b.maxCollateralUpdates - a.maxCollateralUpdates ||\n (b.maxRestartWaste || 0) - (a.maxRestartWaste || 0)\n );\n })\n .slice(0, topN);\n\n const coverage =\n state.commits > 0\n ? Math.round((state.commitsWithMemoizedUpdaters / state.commits) * 100) + '%'\n : '0%';\n\n // Calculate timing summary\n const timingEntries = Object.values(state.commitTimings);\n const totalDetectorOverhead = timingEntries.reduce((sum, t) => sum + t.detectorOverhead, 0);\n const totalTimeSpan = timingEntries.reduce((sum, t) => sum + t.timeSinceLastCommit, 0);\n const avgDetectorOverhead =\n timingEntries.length > 0 ? totalDetectorOverhead / timingEntries.length : 0;\n const avgTimeBetweenCommits = timingEntries.length > 0 ? totalTimeSpan / timingEntries.length : 0;\n\n // Build lookup map for top N sources (sourceId \u2192 { rank, index })\n const topNLookup = new Map<string, { rank: number; index: number }>();\n for (let i = 0; i < sources.length; i++) {\n topNLookup.set(sources[i].sourceId, { rank: i + 1, index: i });\n }\n\n // Build sourcesByCommit from ALL sources (not just top N!)\n // This ensures commitStats[N].sources matches sourcesByCommit[N].length\n const sourcesByCommit: Report['sourcesByCommit'] = {};\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n allSources.forEach((source) => {\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n Object.entries(source.updateHistory).forEach(([commitIdStr, data]) => {\n const commitId = Number(commitIdStr);\n\n // Diagnostic strings like \"detector-only\" are not \"this source fired in this commit\".\n // They exist only to explain detector/React disagreement. Do not surface them in sourcesByCommit.\n if (typeof data === 'string' && data !== 'repeat') {\n return;\n }\n\n // Get per-commit collateral for this source\n const collateral = source.collateralByCommit?.[commitId] ?? 0;\n\n // Skip sources below minCollateral threshold\n if (collateral < minCollateral) {\n return;\n }\n\n if (!sourcesByCommit[commitId]) {\n sourcesByCommit[commitId] = [];\n }\n\n const isRepeat = data === 'repeat';\n\n // Build detailed hook info\n let hookChanges:\n | Array<{ index: number; prevValue: unknown; currentValue: unknown }>\n | undefined;\n if (typeof data === 'object' && data !== null) {\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n hookChanges = Object.entries(data).map(([index, hookData]) => ({\n index: Number(index),\n prevValue:\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n hookData !== 'repeat' ? (hookData as { prevValue: unknown }).prevValue : undefined,\n currentValue:\n hookData !== 'repeat'\n ? // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n (hookData as { currentValue: unknown }).currentValue\n : undefined,\n }));\n }\n\n // Get rank and index (null if not in top N)\n const lookup = topNLookup.get(source.sourceId);\n const rank = lookup?.rank ?? null;\n const sourceIndex = lookup?.index ?? null;\n\n const entry: Report['sourcesByCommit'][number][number] = {\n sourceId: source.sourceId,\n type: source.type,\n depth: source.depth,\n collateral,\n rank,\n sourceIndex,\n };\n\n if (hookChanges && hookChanges.length > 0) {\n entry.hooks = hookChanges;\n }\n if (isRepeat) {\n entry.isRepeat = true;\n }\n\n sourcesByCommit[commitId].push(entry);\n });\n });\n\n // Only include metricsByCommit if there's data\n const hasMetricsData = Object.keys(state.metricsByCommit).length > 0;\n\n // Build meta object\n const integrationMode = detectorConfig?.integrationMode ?? 'none';\n const metricsAdapter = adapterIdFromMode(integrationMode);\n const metricsAvailable = metricsAdapter !== null && hasMetricsData;\n const meta: ReportMeta = {\n version: 6, // v6: CommitStats[8,9] = unmountedComponents/unmountedSubtrees; suspenseByCommit\n commits: state.commits,\n config: {\n detectionLevel: detectorConfig?.detectionLevel ?? 'full',\n effectThrashMode: detectorConfig?.effectThrashMode ?? 'non-primitive',\n captureFibers: detectorConfig?.captureFibers ?? false,\n historySize: detectorConfig?.historySize ?? 1,\n },\n memoizedUpdatersSupport: {\n available: state.memoizedUpdatersAvailable,\n commitsWithData: state.commitsWithMemoizedUpdaters,\n coverage,\n },\n integrationMode,\n metricsAdapter,\n // Per-field availability \u2014 fiber-walk fields are always real measurements\n // because recordTree() runs in every mode. The only adapter-exclusive\n // datapoint is the render-counter delta (restarts, metricsByCommit).\n dataAvailability: {\n collateral: true,\n sources: true,\n restarts: metricsAvailable,\n performedWork: true,\n effects: true,\n memos: true,\n callbacks: true,\n contextUpdates: true,\n metricsByCommit: metricsAvailable,\n atlByCommit: metricsAvailable,\n },\n timing: {\n totalDetectorOverhead,\n avgDetectorOverhead,\n totalTimeSpan,\n avgTimeBetweenCommits,\n },\n };\n\n const base: Report = {\n meta,\n sources,\n sourcesByCommit,\n commitStats: state.commitStats,\n commitTimings: state.commitTimings,\n suspenseByCommit: state.suspenseByCommit,\n unmountsByCommit: state.unmountsByCommit,\n interactionsByCommit: state.interactionsByCommit,\n renderedByCommit: state.renderedByCommit,\n ...(hasMetricsData && { metricsByCommit: state.metricsByCommit, atlByCommit: state.metricsByCommit }),\n toSerializable() {\n return serializeReport(this);\n },\n };\n\n if (thrashMode === 'full') {\n const getSortValue = (amplifier: Amplifier) => {\n if (sortBy === 'effect') return amplifier.effectCount;\n if (sortBy === 'callback') return amplifier.callbackCount;\n if (sortBy === 'memo') return amplifier.memoCount;\n if (sortBy === 'total') return amplifier.hooksTotal;\n return amplifier.effectCount;\n };\n\n const getLinkedSortValue = (as: AmplifierSource) => {\n if (sortBy === 'effect') return as.effectCount;\n if (sortBy === 'callback') return as.callbackCount;\n if (sortBy === 'memo') return as.memoCount;\n if (sortBy === 'total') return as.hooksTotal;\n return as.effectCount;\n };\n\n // Build amplifierSources\n const amplifierSources: AmplifierSource[] = Array.from(state.amplifierSources.entries())\n .map(([internalId, lt]) => {\n const humanId =\n idMapping.get(internalId) || toHumanReadableId(internalId, lt.type, lt.depth);\n const sourceData = state.sources.get(internalId);\n\n return {\n sourceId: humanId,\n type: lt.type,\n depth: lt.depth,\n collateralUpdates: sourceData?.collateralUpdates ?? 0,\n effectCount: lt.effectCount,\n callbackCount: lt.callbackCount,\n memoCount: lt.memoCount,\n hooksTotal: lt.hooksTotal,\n commitIds: lt.commitIds,\n byCommit: lt.byCommit,\n causedBySourceId: lt.causedBySourceId\n ? idMapping.get(lt.causedBySourceId) || lt.causedBySourceId\n : null,\n lastAmplification: lt.lastAmplification,\n };\n })\n .sort((a, b) => getLinkedSortValue(b) - getLinkedSortValue(a) || b.hooksTotal - a.hooksTotal)\n .slice(0, topN);\n\n return {\n ...base,\n amplifiers: Array.from(state.amplifiers.entries())\n .map(([type, s]) => ({ type, ...s }))\n .sort(\n (a, b) =>\n getSortValue(b) - getSortValue(a) ||\n b.hooksTotal - a.hooksTotal ||\n b.maxHooksPerCommit - a.maxHooksPerCommit\n )\n .slice(0, topN),\n amplifierSources,\n };\n }\n\n if (thrashMode === 'counts' && state.thrashCounts) {\n // Add amplifier metrics to meta\n meta.amplifiersMetrics = {\n totalHookThrashes: state.thrashCounts.totalHooks,\n affectedComponentCount: state.thrashCounts.affectedComponents.size,\n };\n }\n\n return base;\n}\n", "/**\n * Shared React DevTools renderer discovery.\n *\n * React-DOM registers a renderer object into\n * `window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers` at injection time (only when\n * the hook exists before react-dom evaluates). That renderer object is the single\n * entry point for several Chippy capabilities:\n *\n * - `currentDispatcherRef` \u2192 debug-render hook replay (see debug-render/core.ts)\n * - `scheduleUpdate` \u2192 fiber-schedule-update nudge (see fiber-schedule-update.ts)\n *\n * Both used to walk `hook.renderers` themselves. This module is the one place that\n * knows how to enumerate renderers, so capabilities select the field they need\n * without duplicating the iteration (and its Map/entries quirks).\n */\n\nexport type ReactRenderer = {\n /** `{ current }` on React <=18; `ReactSharedInternals` (`H`) on React 19. */\n currentDispatcherRef?: Record<string, unknown> | null;\n scheduleUpdate?: (fiber: unknown) => void;\n version?: string;\n rendererPackageName?: string;\n [key: string]: unknown;\n};\n\nexport type DevtoolsHookLike = {\n renderers?:\n | Map<number, ReactRenderer>\n | { entries(): IterableIterator<[number, ReactRenderer]> };\n};\n\n/**\n * Enumerate every registered React renderer. Returns [] when the DevTools hook\n * is absent or empty (production builds without the shim, or hook installed too\n * late for react-dom to register).\n */\nexport function getReactRenderers(\n scope: typeof globalThis = globalThis,\n): ReactRenderer[] {\n const g = scope as unknown as { __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevtoolsHookLike };\n const hook = g.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook || !hook.renderers || typeof (hook.renderers as { entries?: unknown }).entries !== 'function') {\n return [];\n }\n const out: ReactRenderer[] = [];\n for (const [, renderer] of (hook.renderers as Map<number, ReactRenderer>).entries()) {\n if (renderer) out.push(renderer);\n }\n return out;\n}\n\n/**\n * The writable property that holds React's active hooks dispatcher.\n *\n * React <=18 injects `ReactCurrentDispatcher`, whose dispatcher lives at\n * `current`. React 19 injects `ReactSharedInternals`, whose dispatcher lives\n * at `H` (`current` does not exist there). React DevTools makes the same\n * distinction in its own `getDispatcherRef`.\n */\nexport type DispatcherSlot = { owner: Record<string, unknown>; key: 'current' | 'H' };\n\nexport function dispatcherSlotOf(injected: unknown): DispatcherSlot | null {\n if (!injected || typeof injected !== 'object') return null;\n const owner = injected as Record<string, unknown>;\n if (typeof owner.H !== 'undefined') return { owner, key: 'H' };\n if ('current' in owner) return { owner, key: 'current' };\n return null;\n}\n\n/**\n * First renderer that exposes a usable dispatcher slot. Used by debug-render\n * when it must trap writes to the exact property React assigns.\n */\nexport function getDispatcherSlot(scope: typeof globalThis = globalThis): DispatcherSlot | null {\n for (const renderer of getReactRenderers(scope)) {\n const slot = dispatcherSlotOf(renderer.currentDispatcherRef);\n if (slot) return slot;\n }\n return null;\n}\n\nconst modernRefs = new WeakMap<object, { current: unknown }>();\n\n/**\n * Normalize a slot to a `{ current }` ref. A legacy ref is returned as-is; a\n * React 19 internals object gets one stable accessor view that reads and\n * writes `H`.\n */\nexport function dispatcherRefOf(slot: DispatcherSlot): { current: unknown } {\n if (slot.key === 'current') return slot.owner as { current: unknown };\n let ref = modernRefs.get(slot.owner);\n if (!ref) {\n const { owner } = slot;\n ref = {\n get current(): unknown { return owner.H; },\n set current(value: unknown) { owner.H = value; },\n };\n modernRefs.set(owner, ref);\n }\n return ref;\n}\n\n/**\n * First renderer's hooks dispatcher as a `{ current }` ref, across React\n * versions. Used by debug replay to swap in its stub dispatcher.\n */\nexport function getDispatcherRef(\n scope: typeof globalThis = globalThis,\n): { current: unknown } | null {\n const slot = getDispatcherSlot(scope);\n return slot ? dispatcherRefOf(slot) : null;\n}\n\n/**\n * First renderer that exposes a callable `scheduleUpdate`. This is the exact\n * function React DevTools uses to force a re-render on a fiber. It is only\n * present on development React builds. Returns null on production builds (or\n * when the DevTools-hook shim was missing at page boot).\n */\nexport function getScheduleUpdate(\n scope: typeof globalThis = globalThis,\n): ((fiber: unknown) => void) | null {\n for (const renderer of getReactRenderers(scope)) {\n if (typeof renderer.scheduleUpdate === 'function') return renderer.scheduleUpdate;\n }\n return null;\n}\n", "/**\n * Debug-render module.\n *\n * Single responsibility: capture per-render hook events for components, and\n * expose them losslessly to higher layers (the detector projects them).\n *\n * Capture strategy: dispatcher interception via the DevTools global hook.\n *\n * React 18 routes every hook call through `ReactCurrentDispatcher.current`,\n * which is swapped per render phase by react-dom. We do NOT patch\n * `React.useX` (those are facades to the dispatcher) and we do NOT import\n * React here \u2014 this module must not pin a React identity.\n *\n * We discover the *page's* `ReactCurrentDispatcher` ref via the React DevTools\n * global hook contract:\n *\n * __REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.get(id).currentDispatcherRef\n *\n * That ref is page-React-owned and lives where react-dom actually writes.\n * Bootstrap requirement: a DevTools hook shim must already be installed when\n * react-dom evaluates so it calls `hook.inject(internals)`. That bootstrap is\n * Chippy's responsibility (handled by the extension content-script / helper\n * inject path); this module only consumes the result.\n *\n * Capture is intentionally lossless: raw stack + parsed frames are stored.\n * Projection (component name, custom-hook path, loc) is done downstream so\n * the original evidence can be re-projected without re-capturing.\n */\n\nimport {\n dispatcherRefOf,\n getDispatcherRef,\n getDispatcherSlot,\n getReactRenderers,\n type DispatcherSlot,\n} from '../chippy-bridge/react-renderer';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type StackFrame = { name: string; loc: string };\n\nexport type HookCallEvent = {\n primitive: string;\n stack: string;\n frames: StackFrame[];\n componentName: string;\n args: unknown[];\n};\n\nexport type CaptureEngineStatus = {\n ok: boolean;\n installed: boolean;\n hasDevtoolsHook: boolean;\n rendererCount: number;\n hasDispatcherRef: boolean;\n totalCapturedComponents: number;\n totalCapturedEvents: number;\n reason?: string;\n hint?: string;\n};\n\nexport type DebugRenderModule = {\n install(): { ok: boolean; reason?: string };\n uninstall(): void;\n reset(): void;\n isInstalled(): boolean;\n dispatcherRef(): DispatcherRef | null;\n rawEvents(componentName: string): HookCallEvent[];\n allComponents(): string[];\n status(): CaptureEngineStatus;\n recordEventForTest?(event: HookCallEvent): void;\n};\n\n// ---------------------------------------------------------------------------\n// Stack parsing \u2014 zero-loss. Caller decides what to filter.\n// ---------------------------------------------------------------------------\n\nexport function parseStackFrames(stack: string): StackFrame[] {\n return stack\n .split('\\n')\n .slice(1)\n .map((line) => {\n const m =\n line.match(/^\\s*at\\s+([^\\s(]+)\\s*\\(([^)]+)\\)/) ||\n line.match(/^\\s*at\\s+()(.+)$/);\n if (!m) return null;\n const name = (m[1] || '').trim();\n const locRaw = (m[2] || '').trim();\n const tail = locRaw.match(/:(\\d+):(\\d+)\\)?$/);\n const loc = tail ? `${tail[1]}:${tail[2]}` : locRaw;\n return name ? { name, loc } : null;\n })\n .filter((f): f is StackFrame => !!f);\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher interception\n// ---------------------------------------------------------------------------\n\n// Hook methods we instrument on the dispatcher. This list intentionally\n// mirrors React 18's HooksDispatcher surface; unknown methods are passed\n// through untouched so future React versions degrade gracefully instead\n// of crashing.\nconst HOOK_METHODS: ReadonlyArray<string> = [\n 'useCallback',\n 'useContext',\n 'useDebugValue',\n 'useDeferredValue',\n 'useEffect',\n 'useImperativeHandle',\n 'useInsertionEffect',\n 'useLayoutEffect',\n 'useMemo',\n 'useReducer',\n 'useRef',\n 'useState',\n 'useSyncExternalStore',\n 'useTransition',\n 'useId',\n 'useCacheRefresh',\n 'useMemoCache',\n];\n\nconst HOOK_PRIMITIVE: Record<string, string> = {\n useCallback: 'Callback',\n useContext: 'Context',\n useDebugValue: 'DebugValue',\n useDeferredValue: 'DeferredValue',\n useEffect: 'Effect',\n useImperativeHandle: 'ImperativeHandle',\n useInsertionEffect: 'InsertionEffect',\n useLayoutEffect: 'LayoutEffect',\n useMemo: 'Memo',\n useReducer: 'Reducer',\n useRef: 'Ref',\n useState: 'State',\n useSyncExternalStore: 'SyncExternalStore',\n useTransition: 'Transition',\n useId: 'Id',\n useCacheRefresh: 'CacheRefresh',\n useMemoCache: 'MemoCache',\n};\n\ntype DispatcherRef = { current: unknown };\n\n/**\n * Find the page's `ReactCurrentDispatcher` ref.\n *\n * Renderer discovery is shared with the fiber-schedule-update capability \u2014 one\n * place (`chippy-bridge/react-renderer`) knows how to enumerate\n * `__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers`. react-dom registers its renderer\n * (with its own `currentDispatcherRef`) on evaluation IF the global hook existed\n * before react-dom was loaded; Chippy installs that shim before page boot.\n *\n * We do NOT touch any bundled React module identity here. There is no React\n * import in this file by design.\n */\n\n// componentName extraction: walk frames and pick the last non-`use*` frame.\n// This is a projection step; raw frames are still kept on the event so a\n// caller can re-derive a different name if this heuristic is wrong.\nfunction isReactInternalFrameName(name: string): boolean {\n return name === 'atlDispatcherHook' ||\n name === 'record' ||\n name.startsWith('Object.') ||\n name === 'renderWithHooks' ||\n name === 'updateFunctionComponent' ||\n name === 'mountIndeterminateComponent' ||\n name === 'beginWork' ||\n /^beginWork\\$/.test(name) ||\n name === 'performUnitOfWork' ||\n name === 'workLoopSync' ||\n name === 'renderRootSync' ||\n name === 'performConcurrentWorkOnRoot' ||\n name === 'workLoop' ||\n name === 'flushWork';\n}\n\n/**\n * True for a hook frame, including qualified names. React 19's CommonJS build\n * defines `exports.useState = function (...) {}`, which V8 names\n * `exports.useState`; bundlers can produce similar `ns.useX` names.\n */\nexport function isHookFrameName(name: string): boolean {\n return /^use[A-Z0-9_]/.test(name.slice(name.lastIndexOf('.') + 1));\n}\n\nfunction deriveComponentName(frames: StackFrame[]): string {\n for (const { name } of frames) {\n if (!name) continue;\n if (isReactInternalFrameName(name)) continue;\n if (isHookFrameName(name)) continue; // skip use-prefixed (custom + primitive)\n return name;\n }\n return 'Unknown';\n}\n\n// ---------------------------------------------------------------------------\n// Module factory\n// ---------------------------------------------------------------------------\n\nexport function createDebugRender(options: { maxEventsPerComponent?: number } = {}): DebugRenderModule {\n const maxEventsPerComponent = options.maxEventsPerComponent ?? 600;\n\n const eventsByComponent = new Map<string, HookCallEvent[]>();\n\n // We keep a WeakMap of dispatcher object -> patched-method-restore so we\n // can patch each new dispatcher exactly once and never double-wrap. React\n // re-uses dispatcher objects across renders, so this is small and bounded.\n const patchedDispatchers = new WeakMap<object, Map<string, unknown>>();\n\n let installed = false;\n let originalDescriptor: PropertyDescriptor | null | undefined = undefined;\n let dispatcherSlot: DispatcherSlot | null = null;\n let lastSeenDispatcher: unknown = null;\n\n function record(primitive: string, args: unknown[]): void {\n // Capture once. No filtering. Filtering is a projection concern.\n const stack = new Error().stack || '';\n const frames = parseStackFrames(stack);\n const componentName = deriveComponentName(frames);\n const event: HookCallEvent = {\n primitive,\n stack,\n frames,\n componentName,\n args,\n };\n const list = eventsByComponent.get(componentName) || [];\n list.push(event);\n if (list.length > maxEventsPerComponent) {\n list.splice(0, list.length - maxEventsPerComponent);\n }\n eventsByComponent.set(componentName, list);\n }\n\n function patchDispatcher(dispatcher: unknown): void {\n if (!dispatcher || typeof dispatcher !== 'object') return;\n const obj = dispatcher as Record<string, unknown>;\n if (patchedDispatchers.has(obj)) return; // already wrapped\n\n // React swaps dispatcher objects between render phases. Patch each object\n // once and retain the original methods so uninstall can return ownership\n // to React without leaving wrappers on a dispatcher used later.\n const restoreMap = new Map<string, unknown>();\n for (const methodName of HOOK_METHODS) {\n const original = obj[methodName];\n if (typeof original !== 'function') continue;\n restoreMap.set(methodName, original);\n const primitive = HOOK_PRIMITIVE[methodName] || methodName;\n // Named function so it is identifiable in stack traces and can be\n // skipped by callers that post-process frames.\n obj[methodName] = function atlDispatcherHook(this: unknown, ...args: unknown[]) {\n try {\n record(primitive, args);\n } catch (_) {\n // Recording must never throw inside React render.\n }\n return (original as Function).apply(this, args);\n };\n }\n patchedDispatchers.set(obj, restoreMap);\n }\n\n function unpatchDispatcher(dispatcher: unknown): void {\n if (!dispatcher || typeof dispatcher !== 'object') return;\n const obj = dispatcher as Record<string, unknown>;\n const restoreMap = patchedDispatchers.get(obj);\n if (!restoreMap) return;\n for (const [methodName, fn] of restoreMap.entries()) {\n obj[methodName] = fn;\n }\n patchedDispatchers.delete(obj);\n }\n\n function install(): { ok: boolean; reason?: string } {\n if (installed) return { ok: true };\n const slot = getDispatcherSlot();\n if (!slot) return { ok: false, reason: 'ReactCurrentDispatcher not found' };\n dispatcherSlot = slot;\n const { owner, key } = slot;\n\n // Patch whatever is already current (likely the no-op ContextOnlyDispatcher\n // outside render, but patching it is harmless: it will only be called when\n // React swaps it in). Then trap subsequent assignments.\n patchDispatcher(owner[key]);\n lastSeenDispatcher = owner[key];\n\n // Intercept the slot's setter rather than React's hook facades. React owns\n // this property (`current` on <=18, `H` on 19) and changes it at render\n // boundaries; observing those transitions is what lets us patch the\n // correct phase-specific dispatcher.\n originalDescriptor = Object.getOwnPropertyDescriptor(owner, key) || null;\n\n let stored: unknown = owner[key];\n try {\n Object.defineProperty(owner, key, {\n configurable: true,\n get(): unknown {\n return stored;\n },\n set(next: unknown) {\n stored = next;\n if (next !== lastSeenDispatcher) {\n lastSeenDispatcher = next;\n patchDispatcher(next);\n }\n },\n });\n } catch (e) {\n dispatcherSlot = null;\n return { ok: false, reason: 'cannot define property on ReactCurrentDispatcher' };\n }\n\n installed = true;\n return { ok: true };\n }\n\n function uninstall(): void {\n if (!installed) return;\n if (dispatcherSlot) {\n // Restore original property descriptor (if any) so React owns the slot again.\n const { owner, key } = dispatcherSlot;\n try {\n if (originalDescriptor) {\n Object.defineProperty(owner, key, originalDescriptor);\n } else {\n // Fall back to a plain data property holding the latest dispatcher.\n Object.defineProperty(owner, key, {\n configurable: true,\n writable: true,\n enumerable: true,\n value: lastSeenDispatcher,\n });\n }\n } catch (_) {\n /* tolerate */\n }\n }\n // Best-effort unpatch of the last dispatcher we touched. Other dispatchers\n // patched earlier remain wrapped until GC; the wrappers are cheap.\n unpatchDispatcher(lastSeenDispatcher);\n installed = false;\n dispatcherSlot = null;\n originalDescriptor = undefined;\n lastSeenDispatcher = null;\n }\n\n function reset(): void {\n eventsByComponent.clear();\n }\n\n function rawEvents(componentName: string): HookCallEvent[] {\n return (eventsByComponent.get(componentName) || []).slice();\n }\n\n function allComponents(): string[] {\n return Array.from(eventsByComponent.keys());\n }\n\n function status(): CaptureEngineStatus {\n const g = globalThis as unknown as { __REACT_DEVTOOLS_GLOBAL_HOOK__?: unknown };\n const hasDevtoolsHook = !!g.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n // Renderer enumeration is shared with the fiber-schedule-update capability.\n const rendererCount = getReactRenderers().length;\n const hasDispatcherRef = !!(dispatcherSlot || getDispatcherSlot());\n let totalCapturedEvents = 0;\n for (const list of eventsByComponent.values()) totalCapturedEvents += list.length;\n\n let reason: string | undefined;\n let hint: string | undefined;\n if (!hasDevtoolsHook) {\n reason = 'no __REACT_DEVTOOLS_GLOBAL_HOOK__ on window';\n hint = 'devtools-hook-shim must run before react-dom evaluates (extension document_start, or Playwright addInitScript)';\n } else if (rendererCount === 0) {\n reason = '__REACT_DEVTOOLS_GLOBAL_HOOK__ present but renderers Map is empty';\n hint = 'react-dom evaluated before the hook shim was installed; reload the page after installing the shim, or use addInitScript before navigation';\n } else if (!hasDispatcherRef) {\n reason = 'renderer registered but no currentDispatcherRef';\n hint = 'unsupported react-dom version, or hook was replaced after registration';\n } else if (!installed) {\n reason = 'debug-render not installed';\n hint = 'detector did not call debugRender.install() \u2014 check avalanche install() lifecycle';\n } else if (totalCapturedEvents === 0) {\n reason = 'capture engine installed but no hook events recorded yet';\n hint = 'trigger at least one render of the component you want to inspect after install';\n }\n\n const ok = installed && hasDispatcherRef && totalCapturedEvents > 0;\n return {\n ok,\n installed,\n hasDevtoolsHook,\n rendererCount,\n hasDispatcherRef,\n totalCapturedComponents: eventsByComponent.size,\n totalCapturedEvents,\n reason,\n hint,\n };\n }\n\n return {\n install,\n uninstall,\n reset,\n isInstalled: () => installed,\n dispatcherRef: () => (dispatcherSlot ? dispatcherRefOf(dispatcherSlot) : getDispatcherRef()),\n rawEvents,\n allComponents,\n status,\n recordEventForTest(event: HookCallEvent) {\n const list = eventsByComponent.get(event.componentName) || [];\n list.push(event);\n eventsByComponent.set(event.componentName, list);\n },\n };\n}\n", "export interface CommitRoot {\n current: object;\n}\n\n// A seeded metrics slot cannot select the capture owner. The first actual\n// adapter callback can arrive before or after DevTools for the same committed\n// fiber.\nexport function createCommitSurfaceOwnership<T>() {\n let adapterObserved = false;\n let devtoolsCaptures = new WeakMap<CommitRoot, { current: object; capture: T }>();\n return {\n get adapterObserved() { return adapterObserved; },\n recordDevtools(root: CommitRoot, capture: T) {\n devtoolsCaptures.set(root, { current: root.current, capture });\n },\n observeAdapter(root: CommitRoot): T | null {\n const previous = devtoolsCaptures.get(root);\n adapterObserved = true;\n devtoolsCaptures.delete(root);\n return previous?.current === root.current ? previous.capture : null;\n },\n reset() {\n adapterObserved = false;\n devtoolsCaptures = new WeakMap();\n },\n };\n}\n", "/**\n * Pure fiber-walk helpers extracted from layout-lab.js.\n * No DOM writes, no side effects \u2014 read-only introspection of React fiber trees.\n */\n\nimport {\n getFiberSource as readFiberSource,\n resolveFiberSource as resolveSourceLocation,\n} from '../chippy-bridge/fiber-source';\n\n/**\n * Minimal duck-typed Fiber shape.\n * Only fields used by these helpers are typed; rest may exist but are not read.\n */\nexport type Fiber = {\n type?: unknown;\n elementType?: unknown;\n key?: string | null;\n memoizedState?: unknown;\n memoizedProps?: Record<string, unknown> | null;\n stateNode?: Element | null;\n return?: Fiber | null;\n child?: Fiber | null;\n sibling?: Fiber | null;\n _debugOwner?: Fiber | null;\n _debugSource?: SourceLocation | null;\n _debugStack?: unknown;\n};\n\nexport type SourceLocation = {\n fileName?: string | null;\n lineNumber?: number | null;\n columnNumber?: number | null;\n};\n\nexport type DescribedSource = {\n fileName: string | null;\n lineNumber: number | null;\n columnNumber: number | null;\n};\n\nexport type HookSummary = {\n hookCount: number;\n hookCountTruncated: boolean;\n hookCountMax: number;\n};\n\nexport type OwnerEntry = {\n name: string | null;\n key: string | null;\n props: string[];\n} & HookSummary & {\n source: DescribedSource | null;\n};\n\nexport type FiberTarget = {\n domTag: string | null;\n domText: string;\n fiberType: string | null;\n source: DescribedSource | null;\n};\n\nexport type ComponentDescription = {\n name: string | null;\n key: string | null;\n props: Record<string, unknown>;\n source: DescribedSource | null;\n stateNode: string | null;\n owners: OwnerEntry[];\n parents: OwnerEntry[];\n} & HookSummary;\n\n/**\n * Find the React fiber key in a DOM node's own properties.\n * Returns the property name (e.g. '__reactFiber$abc123') or null.\n */\nexport function getFiberKey(node: Node | Element | null | undefined): string | null {\n if (!node) return null;\n const keys = Object.getOwnPropertyNames(node as object);\n const key = keys.find((k) => k.startsWith('__reactFiber$'));\n return key || null;\n}\n\n/**\n * Get the React fiber attached to a DOM node, or null if not a React host node.\n */\nexport function getFiber(node: Node | Element | null | undefined): Fiber | null {\n if (!node) return null;\n const key = getFiberKey(node);\n // React stores the fiber as an expando property on the host node.\n return key ? ((node as unknown as Record<string, unknown>)[key] as Fiber | null) : null;\n}\n\n/**\n * Extract display name from a React type (class, function, or string).\n * Returns displayName > name > null for functions; 'string' for primitives.\n */\nexport function getDisplayName(type: unknown): string | null {\n if (!type) return null;\n if (typeof type === 'string') return type;\n const obj = type as { displayName?: unknown; name?: unknown };\n return (obj.displayName as string) || (obj.name as string) || null;\n}\n\n/**\n * True if fiber is a user-defined component (not a DOM string, not a hook-internal wrapper).\n */\nexport function isUserComponent(fiber: Fiber | null | undefined): boolean {\n if (!fiber) return false;\n const name = getDisplayName(fiber.type);\n if (!name || typeof fiber.type === 'string') return false;\n if (['hookified', 'unboundStoryFn', 'Anonymous'].includes(name)) return false;\n return true;\n}\n\n/**\n * Walk DOM parents to find the nearest fiber-attached element.\n */\nexport function getNearestFiber(domNode: Node | Element | null | undefined): Fiber | null {\n let current = domNode as Element | null;\n while (current) {\n const fiber = getFiber(current);\n if (fiber) return fiber;\n current = (current as Element).parentElement;\n }\n return null;\n}\n\n/**\n * Walk DOM parents, then walk fiber return chain, to find the nearest user component.\n */\nexport function getNearestComponent(domNode: Node | Element | null | undefined): Fiber | null {\n let fiber = getNearestFiber(domNode);\n while (fiber) {\n if (isUserComponent(fiber)) return fiber;\n fiber = fiber.return || null;\n }\n return null;\n}\n\n/**\n * Count hooks in fiber.memoizedState linked list; detect cycle.\n */\nexport function getHookSummary(fiber: Fiber | null | undefined): HookSummary {\n const MAX_HOOKS = 500;\n const seen = new Set<unknown>();\n let hookNode = fiber?.memoizedState || null;\n let hookCount = 0;\n let hookCountTruncated = false;\n\n while (hookNode) {\n if (seen.has(hookNode)) break;\n if (hookCount >= MAX_HOOKS) {\n hookCountTruncated = true;\n break;\n }\n seen.add(hookNode);\n hookCount += 1;\n hookNode = (hookNode as { next?: unknown }).next || null;\n }\n\n return { hookCount, hookCountTruncated, hookCountMax: MAX_HOOKS };\n}\n\n/**\n * Walk fiber._debugOwner chain; collect all user components with metadata.\n * Returns empty array if fiber or owner chain is null.\n */\nexport function getOwnerChain(fiber: Fiber | null | undefined): OwnerEntry[] {\n const chain: OwnerEntry[] = [];\n let current = fiber?._debugOwner || null;\n while (current) {\n if (isUserComponent(current)) {\n chain.push({\n name: getDisplayName(current.type),\n key: current.key || null,\n props: current.memoizedProps ? Object.keys(current.memoizedProps) : [],\n ...getHookSummary(current),\n source: describeFiberSource(current),\n });\n }\n current = current._debugOwner || null;\n }\n return chain;\n}\n\n/**\n * Walk fiber._debugOwner chain; return raw fiber nodes (for navigation).\n */\nexport function getOwnerFibers(fiber: Fiber | null | undefined): Fiber[] {\n const fibers: Fiber[] = [];\n let current = fiber?._debugOwner || null;\n while (current) {\n if (isUserComponent(current)) fibers.push(current);\n current = current._debugOwner || null;\n }\n return fibers;\n}\n\n/**\n * Recursively walk fiber.child/sibling to find the first host DOM element rendered by this subtree.\n */\nexport function getFiberDomNode(fiber: Fiber | null | undefined): Element | null {\n if (!fiber) return null;\n // Host fiber \u2014 stateNode is a DOM element\n if (fiber.stateNode instanceof Element) return fiber.stateNode;\n // Walk children\n let child = fiber.child || null;\n while (child) {\n const found = getFiberDomNode(child);\n if (found) return found;\n child = child.sibling || null;\n }\n return null;\n}\n\n/**\n * Walk fiber.return chain; collect all user component parents with metadata.\n */\nexport function getReturnComponentChain(fiber: Fiber | null | undefined): OwnerEntry[] {\n const chain: OwnerEntry[] = [];\n let current = fiber?.return || null;\n while (current) {\n if (isUserComponent(current)) {\n chain.push({\n name: getDisplayName(current.type),\n key: current.key || null,\n props: current.memoizedProps ? Object.keys(current.memoizedProps) : [],\n ...getHookSummary(current),\n source: describeFiberSource(current),\n });\n }\n current = current.return || null;\n }\n return chain;\n}\n\n/**\n * Walk fiber.return chain; return raw fiber nodes (for navigation).\n */\nexport function getReturnComponentFibers(fiber: Fiber | null | undefined): Fiber[] {\n const fibers: Fiber[] = [];\n let current = fiber?.return || null;\n while (current) {\n if (isUserComponent(current)) fibers.push(current);\n current = current.return || null;\n }\n return fibers;\n}\n\n/**\n * Normalize source location object to canonical shape.\n */\nexport function describeSource(source: SourceLocation | null | undefined): DescribedSource | null {\n if (!source) return null;\n return {\n fileName: source.fileName || null,\n lineNumber: source.lineNumber || null,\n columnNumber: source.columnNumber || null,\n };\n}\n\n/**\n * Read a fiber source across React versions.\n *\n * React <=18 exposes `_debugSource`. React 19 exposes `_debugStack`; its first\n * non-vendor frame is returned synchronously and may later be upgraded from the\n * bundle position to the original source position by `resolveFiberSource`.\n */\nexport function describeFiberSource(fiber: Fiber | null | undefined): DescribedSource | null {\n return describeSource(readFiberSource(fiber));\n}\n\nexport async function resolveFiberSource(fiber: Fiber | null | undefined): Promise<DescribedSource | null> {\n return describeSource(await resolveSourceLocation(fiber));\n}\n\n/**\n * Describe a fiber + DOM node pair; used for inspection UI.\n */\nexport function describeFiberTarget(fiber: Fiber | null | undefined, domNode: Element | null | undefined): FiberTarget | null {\n if (!fiber && !domNode) return null;\n return {\n domTag: domNode?.tagName?.toLowerCase() || null,\n domText: domNode?.textContent?.trim().slice(0, 60) || '',\n fiberType: getDisplayName(fiber?.type) || getDisplayName(fiber?.elementType) || null,\n source: describeFiberSource(fiber),\n };\n}\n\n/**\n * Full component description: name, props, hook summary, source, owners, parents.\n */\nexport function describeComponent(fiber: Fiber | null | undefined): ComponentDescription | null {\n if (!fiber) return null;\n return {\n name: getDisplayName(fiber.type),\n key: fiber.key || null,\n props: fiber.memoizedProps || {},\n ...getHookSummary(fiber),\n source: describeFiberSource(fiber),\n stateNode: fiber.stateNode instanceof Element ? fiber.stateNode.tagName.toLowerCase() : null,\n owners: getOwnerChain(fiber),\n parents: getReturnComponentChain(fiber),\n };\n}\n", "/**\n * Records user-side interaction anchors while Avalanche records commits.\n * Capture is intentionally DOM-event based: the detector owns fiber/commit\n * evidence, while this module owns the only signal that a human interaction\n * preceded it. `linkRecent` joins the two later using performance timestamps;\n * it is evidence of temporal proximity, not proof that the event caused every\n * render in the commit.\n */\n\nimport { isComponentFiber, type Fiber } from './internals';\nimport { describeComponent, describeFiberTarget } from '../layout-lab/fiber-walk';\nimport type { CommitInteractionAction, InteractionAction, InteractionCaptureLevel } from './reporter';\n\nconst EXPLICIT_INTERACTION_EVENTS = ['click', 'keydown', 'keyup', 'input', 'change', 'submit'];\nconst NOISY_INTERACTION_EVENTS = ['wheel', 'scroll', 'pointermove', 'mousemove', 'touchmove'];\nconst ALL_INTERACTION_EVENTS = [\n ...EXPLICIT_INTERACTION_EVENTS,\n 'pointerdown',\n 'pointerup',\n 'dblclick',\n 'focusin',\n 'focusout',\n ...NOISY_INTERACTION_EVENTS,\n];\nconst MAX_INTERACTION_ACTIONS = 200;\n\nexport interface InteractionCaptureOptions {\n interactionCapture?: InteractionCaptureLevel;\n interactionEvents?: string[];\n interactionWindowMs?: number;\n}\n\nexport interface InteractionCaptureState {\n actions: InteractionAction[];\n byCommit: Record<number, CommitInteractionAction[]>;\n}\n\nexport function createInteractionCapture(options: InteractionCaptureOptions = {}) {\n const {\n interactionCapture = 'explicit',\n interactionEvents = [],\n interactionWindowMs = 1000,\n } = options;\n\n const state: InteractionCaptureState = {\n actions: [],\n byCommit: {},\n };\n let nextActionId = 1;\n let installed = false;\n\n function eventNames(): string[] {\n const base =\n interactionCapture === 'off' ? [] :\n interactionCapture === 'explicit' ? EXPLICIT_INTERACTION_EVENTS :\n interactionCapture === 'noisy' ? EXPLICIT_INTERACTION_EVENTS.concat(NOISY_INTERACTION_EVENTS) :\n ALL_INTERACTION_EVENTS;\n return Array.from(new Set(base.concat(interactionEvents).map((name) => String(name).trim()).filter(Boolean)));\n }\n\n function findReactFiberKey(node: Element): string | null {\n return Object.getOwnPropertyNames(node).find((key) => key.startsWith('__reactFiber$')) || null;\n }\n\n function nearestFiberFromNode(node: EventTarget | null): Fiber | null {\n let current = node instanceof Element ? node : null;\n while (current) {\n const key = findReactFiberKey(current);\n if (key) return (current as unknown as Record<string, Fiber | undefined>)[key] || null;\n current = current.parentElement;\n }\n return null;\n }\n\n function nearestComponentFiber(node: EventTarget | null): Fiber | null {\n let fiber = nearestFiberFromNode(node);\n while (fiber) {\n if (isComponentFiber(fiber.tag)) return fiber;\n fiber = fiber.return || null;\n }\n return null;\n }\n\n function nearestTestId(node: EventTarget | null): string | null {\n let current = node instanceof Element ? node : null;\n while (current) {\n const value = current.getAttribute('data-testid');\n if (value) return value;\n current = current.parentElement;\n }\n return null;\n }\n\n function describeActionLocation(target: EventTarget | null): InteractionAction['location'] {\n const domTarget = target instanceof Element ? target : null;\n const fiber = nearestComponentFiber(target);\n const describedTarget = describeFiberTarget(fiber as any, domTarget);\n const describedComponent = describeComponent(fiber as any);\n return {\n dom: {\n tag: describedTarget?.domTag || null,\n text: describedTarget?.domText || '',\n nearestTestId: nearestTestId(target),\n },\n targetFiber: describedComponent ? {\n name: describedComponent.name,\n key: describedComponent.key,\n source: describedComponent.source,\n ownerStackKind: describedComponent.owners.length > 0 ? 'owners' : 'parents',\n ownerStack: describedComponent.owners.length > 0 ? describedComponent.owners : describedComponent.parents,\n } : null,\n };\n }\n\n function capture(event: Event): void {\n const pathTarget = typeof event.composedPath === 'function' ? event.composedPath()[0] : null;\n const target = pathTarget instanceof Element ? pathTarget : event.target;\n // Keep a bounded queue because a long-lived page can receive noisy events\n // continuously. Older anchors cannot link to a future commit once they\n // fall outside the configured window.\n state.actions.push({\n id: nextActionId++,\n action: event.type,\n timestamp: performance.now(),\n location: describeActionLocation(target),\n });\n if (state.actions.length > MAX_INTERACTION_ACTIONS) {\n state.actions.splice(0, state.actions.length - MAX_INTERACTION_ACTIONS);\n }\n }\n\n return {\n state,\n\n install(): void {\n if (installed) return;\n const names = eventNames();\n if (names.length === 0 || typeof document === 'undefined') return;\n for (const name of names) document.addEventListener(name, capture, true);\n installed = true;\n },\n\n uninstall(): void {\n if (!installed || typeof document === 'undefined') return;\n for (const name of eventNames()) document.removeEventListener(name, capture, true);\n installed = false;\n },\n\n reset(): void {\n state.actions.length = 0;\n for (const key of Object.keys(state.byCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.byCommit[Number(key)];\n }\n nextActionId = 1;\n },\n\n linkRecent(commitId: number, commitTime: number): void {\n const windowMs = Math.max(0, Number(interactionWindowMs) || 0);\n if (windowMs === 0 || state.actions.length === 0) return;\n // Link only events at or before the commit. A later event may be close in\n // wall-clock time but cannot explain work that already committed.\n const linked = state.actions\n .filter((action) => action.timestamp <= commitTime && commitTime - action.timestamp <= windowMs)\n .map((action) => ({\n id: action.id,\n lastCommitId: Math.max(0, commitId - 1),\n deltaTime: Math.round((commitTime - action.timestamp) * 100) / 100,\n action: action.action,\n location: action.location,\n }));\n if (linked.length > 0) state.byCommit[commitId] = linked;\n while (state.actions.length > 0 && commitTime - state.actions[0].timestamp > windowMs) {\n state.actions.shift();\n }\n },\n };\n}\n", "/**\n * Headless Profiler - React commit profiler (headless / no UI).\n *\n * This file intentionally keeps the commit traversal (`recordTree`) monolithic.\n * It runs on every React commit, and even small function-call overhead inside the\n * fiber-walk loops shows up in perf. We refactor everything *around* it.\n *\n * Detection Levels:\n * - Level 1 (STATS): Only commitStats - <1% overhead (~0.8ms avg)\n * - Level 2 (SOURCES): + source tracking - ~1-2% overhead (~1.3ms avg)\n * - Level 3 (AMPLIFIERS/FULL): + amplifier detection - ~2-3% overhead (~2.4ms avg)\n *\n * Peer FAQ\n * - Why is `recordTree()` huge? Performance: it's on the hot path (every commit).\n * - Why per-hook actionability? React can leave alternate hook memoizedState\n * undefined (Suspense/Offscreen/concurrent artifacts) causing false positives.\n * - Why WeakMaps everywhere? To auto-GC tracked values/fibers without leaks.\n * - Why so few null checks? Debug tool: fail fast and loud on misuse/internals drift.\n * - Production? Use LEVEL1_STATS or LEVEL2_SOURCES for minimal overhead.\n */\n\nimport {\n ChildDeletion,\n detectHookThrashing,\n didContextValueChange,\n didFiberSelfUpdate,\n didFiberUpdate,\n didSuspenseStateChange,\n Hydrating,\n isComponentFiber,\n getComponentName,\n isContextProviderFiber,\n isDevelopment,\n isReactInternalComponentType,\n isSuspenseFiber,\n PerformedWork,\n Placement,\n Update,\n type ChangedHook,\n type ComponentType,\n type DepOrigin,\n type Fiber,\n type ThrashInfo,\n} from './internals';\n\nimport {\n buildReport,\n type DetectorOptions,\n type ProfilerState,\n type PropChangeEvidence,\n type PropValueSummary,\n type RenderedComponentEvidence,\n type Report,\n type ReportOptions,\n type SortBy,\n type Source,\n type SuspenseBoundaryEvent,\n type ThrashMode,\n type UnmountSample,\n} from './reporter';\n\nimport { createDebugRender, type HookCallEvent, type StackFrame } from '../debug-render/core';\nimport { getFiberSourceCandidate } from '../chippy-bridge/fiber-source';\nimport {\n type CommitMetricsAdapter,\n type CommitMetricsSnapshot,\n type IntegrationMode,\n getCommitMetricsAdapter,\n} from './commit-metrics-adapter';\nimport { createCommitSurfaceOwnership } from './commit-surface-ownership';\nimport { createInteractionCapture } from './interaction-capture';\nimport {\n CS_UNMOUNTED_COMPONENTS,\n CS_UNMOUNTED_SUBTREES,\n CS_RESTARTS,\n} from './commit-stats-indices';\n\nfunction summarizeFiberSource(fiber: Fiber): { fileName: string; lineNumber: number } | null {\n const source = getFiberSourceCandidate(fiber);\n return source ? { fileName: source.fileName, lineNumber: source.lineNumber } : null;\n}\n\n/**\n * Installable detector.\n */\nexport function createAvalancheDetector(options: DetectorOptions = {}) {\n const {\n ignore = [],\n effectThrashMode = 'non-primitive',\n captureFibers = isDevelopment(),\n detectionMode = isDevelopment() ? 'full' : 'amplifiers',\n historySize = isDevelopment() ? 10 : 1,\n } = options;\n\n const mode = detectionMode;\n\n // Resolved on install(), so an adapter registered after the detector was\n // created still applies. `metricsAdapter: null` opts out of adapters.\n let metricsAdapter: CommitMetricsAdapter | null = null;\n const resolveMetricsAdapter = (): CommitMetricsAdapter | null =>\n options.metricsAdapter === undefined ? getCommitMetricsAdapter() : options.metricsAdapter;\n\n const ignoreSet = new Set(ignore);\n\n // Normalize detection mode to level\n // Level 1 (stats): Only commitStats with restarts - super fast\n // Level 2 (sources): Stats + source tracking - adds overhead for source detection\n // Level 3a (amplifierMetrics): Sources + aggregate amplifier counts - lightweight\n // Level 3b (amplifiers): Sources + full amplifier arrays - more detail\n // Legacy: 'full' is alias for 'amplifiers' (kept for backward compatibility)\n // TODO: Replace this open conditional chain with an exhaustive runtime\n // normalizer or fail-closed branch. TypeScript protects typed callers only;\n // unchecked shell/helper input can leave both variables undefined.\n let detectionLevel: 'stats' | 'sources' | 'amplifierMetrics' | 'amplifiers' | 'full';\n let thrashMode: ThrashMode;\n\n if (mode === true) {\n detectionLevel = 'full';\n thrashMode = 'full';\n } else if (mode === false) {\n detectionLevel = 'stats';\n thrashMode = false;\n } else if (mode === 'stats') {\n detectionLevel = 'stats';\n thrashMode = false;\n } else if (mode === 'sources') {\n detectionLevel = 'sources';\n thrashMode = false;\n } else if (mode === 'amplifiers') {\n detectionLevel = 'amplifiers';\n thrashMode = 'full';\n } else if (mode === 'amplifierMetrics') {\n detectionLevel = 'amplifierMetrics';\n thrashMode = 'counts';\n } else if (mode === 'full') {\n detectionLevel = 'full';\n thrashMode = 'full';\n }\n\n const enableSourceTracking = detectionLevel !== 'stats';\n const enableAmplifiers = thrashMode !== false;\n\n // Global WeakMap: value -> provenance. WeakMap ensures automatic GC.\n const valueProvenance = new WeakMap<object | Function, DepOrigin>();\n\n // Stable source ID manager - handles fiber alternate swaps\n // Uses WeakMap to track types and generate stable numeric IDs (fast, no string ops!)\n class StableSourceIdManager {\n private idMap = new WeakMap<Fiber, string>();\n // WeakMap only accepts objects/functions, not symbols. Store only valid keys.\n private typeToId = new WeakMap<object | Function, number>();\n private instanceCounters = new Map<string, number>(); // \"typeId@depth\" -> instance count\n private nextTypeId = 1;\n\n getSourceId(fiber: Fiber, type: ComponentType, depth: number): string {\n // Check if we already have an ID for this fiber\n let sourceId = this.idMap.get(fiber);\n if (sourceId) return sourceId;\n\n // Check if the alternate has an ID (same logical instance)\n if (fiber.alternate) {\n sourceId = this.idMap.get(fiber.alternate);\n if (sourceId) {\n // Map current fiber to the same ID\n this.idMap.set(fiber, sourceId);\n return sourceId;\n }\n }\n\n // Get or assign a numeric ID for this type (avoid stringifying functions!)\n // WeakMap keys must be objects/functions only. Strings/symbols/null get an\n // ephemeral numeric id for this pass but are never inserted into the WeakMap.\n const canBeWeakMapKey = (typeof type === 'object' && type !== null) || typeof type === 'function';\n const weakKey = canBeWeakMapKey ? (type as object | Function) : null;\n let typeId = weakKey ? this.typeToId.get(weakKey) : undefined;\n\n if (typeId === undefined) {\n typeId = this.nextTypeId++;\n if (weakKey) {\n this.typeToId.set(weakKey, typeId);\n }\n }\n\n // New instance - create ID with per-component-type counter\n const baseKey = `${typeId}@${depth}`;\n const instanceNum = this.instanceCounters.get(baseKey) || 1;\n this.instanceCounters.set(baseKey, instanceNum + 1);\n sourceId = `T${typeId}#${instanceNum}@${depth}`;\n\n // Map both current and alternate to this ID\n this.idMap.set(fiber, sourceId);\n if (fiber.alternate) {\n this.idMap.set(fiber.alternate, sourceId);\n }\n\n return sourceId;\n }\n\n clear() {\n this.instanceCounters.clear();\n this.typeToId = new WeakMap();\n this.nextTypeId = 1;\n }\n }\n\n const sourceIdManager = new StableSourceIdManager();\n const debugRender = createDebugRender();\n const interactionCapture = createInteractionCapture(options);\n\n function getComponentDisplayName(type: ComponentType | null | undefined): string {\n if (!type) return 'Unknown';\n return (type as { displayName?: string; name?: string }).displayName ||\n (type as { displayName?: string; name?: string }).name ||\n String(type);\n }\n\n function isDebugInternalFrame(frame: StackFrame, componentName: string): boolean {\n const name = frame.name || '';\n // Replay can run before install(), so fall back to the configured adapter.\n return !!(metricsAdapter ?? resolveMetricsAdapter())?.frameFilters?.includes(name) ||\n name === 'record' ||\n name === componentName ||\n name.includes('react-dom') ||\n name.includes('renderWithHooks') ||\n name.includes('mount') ||\n name.includes('update');\n }\n\n function parentFramesForEvent(event: HookCallEvent, componentName: string): StackFrame[] {\n return event.frames.filter((frame) => !isDebugInternalFrame(frame, componentName));\n }\n\n /** Snapshot the adapter's counters, or null when no adapter surface is live. */\n function captureMetricsSnapshot(): CommitMetricsSnapshot | null {\n return metricsAdapter?.snapshot() ?? null;\n }\n\n /**\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 CRITICAL: Understanding fiber.alternate and the \"swap\" problem \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * WHAT WE THOUGHT:\n * \"fiber and fiber.alternate swap on every commit, so alternate always\n * has state from the previous commit.\"\n *\n * WHAT ACTUALLY HAPPENS (from React Fiber Architecture docs):\n * \"At any time, a component instance has at most two fibers:\n * the current (flushed) fiber, and the work-in-progress fiber.\n * The alternate of the current fiber is the work-in-progress,\n * and the alternate of the work-in-progress is the current fiber.\"\n *\n * THE TRAP:\n * The alternate is only UPDATED when React uses it as work-in-progress.\n * If a component re-renders due to parent/context (not self-update),\n * React may or may NOT touch its alternate depending on:\n * - Whether the component is on the \"render path\"\n * - Whether React chose to clone vs reuse the fiber\n * - Concurrent mode interruptions\n * - Suspense/Offscreen boundaries\n *\n * CONCRETE EXAMPLE:\n * Commit 1: Component mounts, state = 'initial'\n * Commit 2: Component calls setState('loaded') via useEffect\n * Commit 3-10: Parent re-renders, component re-renders (but no state change)\n *\n * On commit 10, if we compare fiber vs alternate:\n * - fiber.memoizedState = 'loaded' (current)\n * - alternate.memoizedState = ???\n * - MIGHT be 'loaded' (if alternate was used as work-in-progress recently)\n * - MIGHT be 'initial' (if alternate is stale from commit 1!)\n *\n * Result: FALSE POSITIVE - we detect \"state changed\" when it didn't!\n *\n * SYMPTOMS OF THIS BUG:\n * - causedUpdates: 6 when real updates were 1\n * - updateHistory full of \"repeat\" entries\n * - collateralByCommit has entries for commits where component wasn't initiator\n * - memoizedUpdaters disagrees with our detection\n *\n * \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n * \u2502 WHY CAN'T WE JUST USE memoizedUpdaters? \u2502\n * \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n *\n * You might think: \"React has `root.memoizedUpdaters` - a Set<Fiber> of\n * components that triggered updates. Why not just use that?\"\n *\n * THE CATCH: memoizedUpdaters is ONLY populated when React DevTools is present!\n *\n * From react-dom source:\n * var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';\n *\n * function addFiberToLanesMap(root, fiber, lanes) {\n * if (!isDevToolsPresent) {\n * return; // \u2190 EARLY RETURN! updaters never populated!\n * }\n * // ... adds to pendingUpdatersLaneMap, eventually to memoizedUpdaters\n * }\n *\n * This means:\n * - Users WITH React DevTools installed: memoizedUpdaters works \u2705\n * - Users WITHOUT DevTools: memoizedUpdaters is EMPTY \u274C\n *\n * THE ADOPTION DILEMMA:\n * To force memoizedUpdaters to work, we'd need to inject:\n * globalThis.__REACT_DEVTOOLS_GLOBAL_HOOK__ = { ... }\n *\n * Problems with this approach:\n * - Must be done BEFORE React loads (timing sensitive)\n * - Side effect that might interfere with real DevTools\n * - Side effect that might block tool adoption/approval\n * - Cannot be done lazily (React checks once at startup)\n *\n * SOLUTION:\n * Track our own \"last seen state\" per fiber. Update it on EVERY commit\n * where the fiber renders. Compare against OUR snapshot, not alternate.\n * This gives us accurate \"previous state\" regardless of alternate staleness.\n *\n * DUAL-MODE STRATEGY:\n * - When memoizedUpdaters available (DevTools users): Trust React completely\n * - When memoizedUpdaters empty (everyone else): Use lastSeenHookState\n *\n * This approach:\n * \u2705 Zero side effects - no DevTools hook injection required\n * \u2705 Zero false positives - accurate for all users\n * \u2705 Adoptable by any project - no special requirements\n * \u2705 Graceful dual-mode - best of both worlds\n *\n * The ~100 lines of lastSeenHookState code are NOT over-engineering.\n * Without them, users without DevTools would see 10x false positives\n * (e.g., 100 source detections instead of 10 in typical scenarios).\n *\n * References:\n * - https://github.com/acdlite/react-fiber-architecture\n * - https://jser.dev/2023-07-18-how-react-rerenders/\n * - https://jser.dev/2023-06-19-how-does-usestate-work/\n */\n const lastSeenHookState = new WeakMap<Fiber, unknown[]>();\n\n /**\n * Capture current hook state chain as an array of memoizedState values.\n * Used to track what state we've \"seen\" for this fiber.\n */\n function captureHookStateSnapshot(fiber: Fiber): unknown[] {\n const snapshot: unknown[] = [];\n let hook = fiber.memoizedState;\n while (hook) {\n snapshot.push(hook.memoizedState);\n hook = hook.next;\n }\n return snapshot;\n }\n\n /**\n * Compare current hook state against our last-seen snapshot.\n * Returns indices of hooks that changed since we last saw this fiber.\n */\n function detectChangesFromLastSeen(\n fiber: Fiber,\n currentSnapshot: unknown[]\n ): { changedIndices: number[]; changedHooks: ChangedHook[] } {\n const lastSeen =\n lastSeenHookState.get(fiber) || (fiber.alternate && lastSeenHookState.get(fiber.alternate));\n\n const changedIndices: number[] = [];\n const changedHooks: ChangedHook[] = [];\n\n if (!lastSeen) {\n // First time seeing this fiber - no changes to report\n return { changedIndices, changedHooks };\n }\n\n // Compare each hook\n const maxLen = Math.max(lastSeen.length, currentSnapshot.length);\n for (let i = 0; i < maxLen; i++) {\n const prev = lastSeen[i];\n const curr = currentSnapshot[i];\n\n if (!Object.is(prev, curr)) {\n changedIndices.push(i);\n changedHooks.push({ prevValue: prev, currentValue: curr });\n }\n }\n\n return { changedIndices, changedHooks };\n }\n\n const state: ProfilerState = {\n commits: 0,\n sources: new Map(),\n amplifiers: new Map(),\n amplifierSources: new Map(),\n thrashCounts:\n thrashMode === 'counts'\n ? { totalHooks: 0, affectedComponents: new Set<ComponentType>() }\n : null,\n memoizedUpdatersAvailable: false,\n commitsWithMemoizedUpdaters: 0,\n // Per-commit stats: [collateral, effects, memos, callbacks]\n commitStats: {},\n // Per-commit adapter counter deltas\n metricsByCommit: {},\n lastMetricsSnapshot: null,\n // Per-commit timing data\n commitTimings: {},\n lastCommitEndTime: performance.now(),\n // Per-commit Suspense boundary transitions\n suspenseByCommit: {},\n unmountsByCommit: {},\n interactionActions: interactionCapture.state.actions,\n interactionsByCommit: interactionCapture.state.byCommit,\n renderedByCommit: {},\n };\n\n // Helper: push to history and trim if needed (called in aggregation, not hot path)\n function _pushToHistory<T>(history: T[], item: T, limit: number): void {\n history.push(item);\n if (history.length > limit) {\n history.splice(0, history.length - limit);\n }\n }\n\n type UpdateHistory = Record<\n number,\n Record<number, import('./internals.tsx').ChangedHook> | 'repeat' | string\n >;\n\n function trimHistoryToSize(updHistory: UpdateHistory, limit: number): UpdateHistory {\n const keys = Object.keys(updHistory)\n .map(Number)\n .sort((a, b) => a - b);\n const keysToKeep = keys.slice(keys.length - limit);\n const trimmed: UpdateHistory = {};\n keysToKeep.forEach((key) => {\n trimmed[key] = updHistory[key];\n });\n return trimmed;\n }\n\n function findLastConcreteHook(\n history: UpdateHistory,\n hookIndex: number,\n beforeCommitId: number\n ): ChangedHook | null {\n const commitIds = Object.keys(history)\n .map(Number)\n .filter((id) => id < beforeCommitId)\n .sort((a, b) => b - a);\n\n for (const commitId of commitIds) {\n const entry = history[commitId];\n if (entry && entry !== 'repeat' && typeof entry !== 'string') {\n const prev = entry[hookIndex];\n if (prev && prev !== 'repeat' && typeof prev === 'object') return prev;\n }\n }\n\n return null;\n }\n\n function summarizePropValue(value: unknown): PropValueSummary {\n const isArray = Array.isArray(value);\n const type = value === null ? 'null' : isArray ? 'array' : typeof value;\n const isFunction = typeof value === 'function';\n const isNull = value === null;\n const isPrimitive = value == null ||\n type === 'string' ||\n type === 'number' ||\n type === 'boolean' ||\n type === 'undefined' ||\n type === 'symbol' ||\n type === 'bigint';\n const primitiveDisplay = isPrimitive ? String(value) : undefined;\n const summary: PropValueSummary = {\n type,\n isArray,\n isFunction,\n isNull,\n preview: primitiveDisplay || (isFunction ? 'function' : isArray ? `array(${value.length})` : 'object'),\n };\n\n if (primitiveDisplay !== undefined) {\n summary.display = primitiveDisplay;\n }\n if (typeof value === 'string' || isArray) {\n summary.length = value.length;\n }\n if (isArray) {\n summary.sample = value.slice(0, 3).map((item) => summarizePropValue(item).preview);\n } else if (value && typeof value === 'object') {\n const keys = Object.keys(value as Record<string, unknown>).slice(0, 5);\n summary.keysTop = keys;\n summary.length = Object.keys(value as Record<string, unknown>).length;\n if (keys.length > 0) {\n summary.preview = `object{${keys.join(',')}}`;\n }\n } else if (isFunction) {\n const fn = value as Function;\n summary.preview = fn.name ? `function ${fn.name}` : 'function';\n }\n return summary;\n }\n\n function diffProps(prevProps: unknown, currentProps: unknown): PropChangeEvidence[] {\n const changes: PropChangeEvidence[] = [];\n const prev = prevProps && typeof prevProps === 'object' ? prevProps as Record<string, unknown> : {};\n const current = currentProps && typeof currentProps === 'object' ? currentProps as Record<string, unknown> : {};\n const keys = new Set([...Object.keys(prev), ...Object.keys(current)]);\n\n keys.forEach((name) => {\n const prevHas = Object.prototype.hasOwnProperty.call(prev, name);\n const currentHas = Object.prototype.hasOwnProperty.call(current, name);\n const prevValue = prev[name];\n const currentValue = current[name];\n if (!prevHas && currentHas) {\n changes.push({ name, kind: 'added', prev: summarizePropValue(undefined), current: summarizePropValue(currentValue) });\n } else if (prevHas && !currentHas) {\n changes.push({ name, kind: 'removed', prev: summarizePropValue(prevValue), current: summarizePropValue(undefined) });\n } else if (Object.is(prevValue, currentValue)) {\n // Evidence surface records changes only; unchanged props stay implicit.\n } else if (\n prevValue !== null && currentValue !== null &&\n (typeof prevValue === 'object' || typeof prevValue === 'function' ||\n typeof currentValue === 'object' || typeof currentValue === 'function')\n ) {\n changes.push({ name, kind: 'ref-changed', prev: summarizePropValue(prevValue), current: summarizePropValue(currentValue) });\n } else {\n changes.push({ name, kind: 'scalar-changed', prev: summarizePropValue(prevValue), current: summarizePropValue(currentValue) });\n }\n });\n\n return changes;\n }\n\n function pushUpdateHistory(\n updHistory: UpdateHistory,\n commitId: number,\n changedHookIndices: number[],\n changedHooks: import('./internals.tsx').ChangedHook[]\n ): UpdateHistory {\n const entry: Record<number, import('./internals.tsx').ChangedHook> = {};\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n for (let i = 0; i < changedHookIndices.length; i++) {\n const hookIndex = changedHookIndices[i];\n const hook = changedHooks[i];\n\n if (hook === 'repeat') {\n entry[hookIndex] = 'repeat';\n } else {\n const prevConcrete = findLastConcreteHook(updHistory, hookIndex, commitId);\n entry[hookIndex] =\n prevConcrete &&\n typeof prevConcrete === 'object' &&\n Object.is(hook.prevValue, prevConcrete.prevValue) &&\n Object.is(hook.currentValue, prevConcrete.currentValue)\n ? 'repeat'\n : hook;\n }\n }\n\n const newEntry = Object.values(entry).every((v) => v === 'repeat') ? 'repeat' : entry;\n return { ...updHistory, [commitId]: newEntry };\n }\n\n function recordTree(rootFiber: Fiber, memoizedUpdaters: Set<Fiber> | null = null): number {\n // NOTE: This function is intentionally monolithic for performance.\n // Keep inner loops allocation-free and avoid helper calls.\n\n // Track if memoizedUpdaters is available\n if (memoizedUpdaters && memoizedUpdaters.size > 0) {\n state.memoizedUpdatersAvailable = true;\n state.commitsWithMemoizedUpdaters++;\n }\n\n const perCommit = {\n selfUpdated: new Map<\n string,\n {\n type: ComponentType;\n depth: number;\n count: number;\n changedHookIndices: number[];\n changedHooks: ChangedHook[];\n fiber?: Fiber;\n isUpdater: boolean;\n }\n >(),\n thrashing: new Map<\n ComponentType,\n {\n instanceCount: number;\n hookCount: number;\n lastAmplification: { depth: number; thrashedHooks: ThrashInfo[]; fiber?: Fiber };\n }\n >(),\n /** Linked thrashing: keyed by sourceId, tracks per-component thrashing with linkage */\n linkedThrashing: new Map<\n string,\n {\n type: ComponentType;\n depth: number;\n effects: number;\n callbacks: number;\n memos: number;\n causedBySourceId: string | null;\n lastAmplification: { depth: number; thrashedHooks: ThrashInfo[]; fiber?: Fiber };\n }\n >(),\n rendered: [] as RenderedComponentEvidence[],\n selfFibers: new WeakMap<Fiber, number>(),\n sourceFibers: new Set<Fiber>(), // Track source fibers to exclude from collateral count\n blastBySourceId: new Map<string, number>(),\n depthBySourceId: new Map<string, number>(),\n // Simple counts for commitStats\n totalCollateral: 0,\n committedComponentCount: 0, // Components with PerformedWork that committed\n effectCount: 0,\n memoCount: 0,\n callbackCount: 0,\n contextUpdates: 0,\n // Unmount tracking (populated by deletions-array walk in visit())\n unmountedComponents: 0,\n unmountedSubtrees: 0,\n // Bounded identity samples for branch starts (topmost component fibers in\n // each deleted subtree). Cap to keep payload small.\n unmountSamples: null as UnmountSample[] | null,\n // Suspense boundary transition events collected during this commit's visit pass\n suspenseEvents: null as SuspenseBoundaryEvent[] | null,\n };\n\n // -------------------------------------------------------------------------\n // COMBINED PASS: Identify sources + attribute blast (O(n) not O(n*depth))\n // -------------------------------------------------------------------------\n function visit(\n fiber: Fiber | null,\n depth: number = 0,\n currentOwnerSourceId: string | null = null\n ) {\n if (!fiber) return;\n\n // OPTIMIZATION: Skip subtrees with no PerformedWork using subtreeFlags\n // React uses subtreeFlags to propagate flags up the tree. If neither the fiber\n // nor its subtree have PerformedWork (flag 0x1), we can skip this entire branch.\n // This matches React's own optimization during commit phase.\n //\n // Exception 1: Suspense fibers use DidCapture (128) not PerformedWork when suspending.\n // Exception 2: Fibers with ChildDeletion in subtreeFlags have deletions to track.\n // eslint-disable-next-line no-bitwise -- React fiber flags are bitmasks, bitwise AND is required\n const hasWorkInSubtree =\n // eslint-disable-next-line no-bitwise -- React fiber flags are bitmasks, bitwise AND is required\n (fiber.flags & PerformedWork) !== 0 ||\n // eslint-disable-next-line no-bitwise\n (fiber.subtreeFlags & PerformedWork) !== 0 ||\n // fiber.flags & ChildDeletion = this fiber has children being deleted this commit\n // (React sets ChildDeletion on fiber.flags, NOT subtreeFlags, at commit time)\n // eslint-disable-next-line no-bitwise\n (fiber.flags & ChildDeletion) !== 0 ||\n // subtreeFlags propagation \u2014 some descendant has deletions\n // eslint-disable-next-line no-bitwise\n (fiber.subtreeFlags & ChildDeletion) !== 0 ||\n // Suspense transitioning: React sets Update (4) on the Suspense fiber's flags at commit.\n // eslint-disable-next-line no-bitwise\n (isSuspenseFiber(fiber.tag) && (fiber.flags & Update) !== 0) ||\n // subtreeFlags & Update: a descendant (e.g. Suspense) received an Update this commit.\n // React propagates subtreeFlags upward \u2014 HostRoot and all intermediate host fibers\n // will have Update bit set if any descendant has it. This ensures we don't skip\n // the path to a Suspense boundary when no PerformedWork exists higher in the tree.\n // eslint-disable-next-line no-bitwise\n (fiber.subtreeFlags & Update) !== 0;\n if (!hasWorkInSubtree) {\n // No work in this fiber or its descendants - skip entire subtree\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.sibling) visit(fiber.sibling, depth, currentOwnerSourceId);\n return;\n }\n\n // Check for context provider value changes\n if (isContextProviderFiber(fiber.tag) && didContextValueChange(fiber)) {\n perCommit.contextUpdates++;\n }\n\n // Unmount detection via fiber.deletions.\n // React populates fiber.deletions[] during the render phase for fibers that\n // will be deleted in this commit. At commit time, React sets ChildDeletion (16)\n // on fiber.flags (NOT subtreeFlags) of the parent holding the deletions.\n // fiber.deletions is the list of child fibers being removed.\n // eslint-disable-next-line no-bitwise\n if ((fiber.flags & ChildDeletion) !== 0 && fiber.deletions && fiber.deletions.length > 0) {\n for (let di = 0; di < fiber.deletions.length; di++) {\n const deleted = fiber.deletions[di];\n // Walk the entire deleted subtree to collect all component fibers being removed.\n // We track whether a fiber's parent (in the deleted subtree) is also a component\n // so we can identify branch starts.\n function collectDeletions(\n df: Fiber,\n parentIsComponent: boolean,\n branchStartDepth: number,\n currentBranch: { count: number; sample: typeof perCommit.unmountSamples extends (infer A)[] | null ? A : never } | null\n ): void {\n const dfIsComponent = isComponentFiber(df.tag);\n let nextBranch = currentBranch;\n if (dfIsComponent) {\n perCommit.unmountedComponents++;\n if (!parentIsComponent) {\n // This is a branch start: topmost component in the deleted subtree\n perCommit.unmountedSubtrees++;\n if (perCommit.unmountSamples == null) perCommit.unmountSamples = [];\n if (perCommit.unmountSamples.length < 30) {\n const fiberKey = (df as unknown as { key?: string | number | null }).key;\n const sample = {\n name: getComponentName(df),\n key: fiberKey == null ? null : String(fiberKey),\n depth: branchStartDepth,\n count: 1,\n source: summarizeFiberSource(df),\n host: summarizeHostSubtree(df),\n };\n perCommit.unmountSamples.push(sample);\n nextBranch = { count: 1, sample } as any;\n } else {\n nextBranch = null;\n }\n } else if (currentBranch && currentBranch.sample) {\n currentBranch.sample.count++;\n }\n // Clean up last-seen hook state so future remounts start fresh\n lastSeenHookState.delete(df);\n if (df.alternate) lastSeenHookState.delete(df.alternate);\n }\n if (df.child) collectDeletions(df.child, dfIsComponent, branchStartDepth + 1, nextBranch);\n if (df.sibling) collectDeletions(df.sibling, parentIsComponent, branchStartDepth, currentBranch);\n }\n // Add one branch-level sample for the deleted subtree. React can hand us\n // a host/text wrapper as the deletion root, so find the first component\n // descendant to label the branch.\n if (perCommit.unmountSamples == null) perCommit.unmountSamples = [];\n if (perCommit.unmountSamples.length < 30) {\n let labelFiber: Fiber | null = deleted;\n if (!isComponentFiber(labelFiber.tag)) {\n const stack: Fiber[] = [labelFiber];\n labelFiber = null;\n while (stack.length) {\n const f = stack.pop()!;\n if (isComponentFiber(f.tag)) { labelFiber = f; break; }\n if (f.child) stack.push(f.child);\n if (f.sibling) stack.push(f.sibling);\n }\n }\n if (labelFiber) {\n const counts = countUnmountedComponentSubtree(deleted);\n const fiberKey = (labelFiber as unknown as { key?: string | number | null }).key;\n perCommit.unmountSamples.push({\n name: getComponentName(labelFiber),\n key: fiberKey == null ? null : String(fiberKey),\n depth,\n count: counts.components,\n source: summarizeFiberSource(labelFiber),\n host: summarizeHostSubtree(deleted),\n });\n }\n }\n collectDeletions(deleted, false, depth, null);\n }\n }\n\n const isComponent = isComponentFiber(fiber.tag);\n let ownerSourceId = currentOwnerSourceId;\n\n // Suspense boundary transition detection.\n // Only fires when the boundary actually entered or left the fallback state.\n // Boundaries that render without delay (memoizedState stays null) are silent.\n if (isSuspenseFiber(fiber.tag)) {\n const suspenseChange = didSuspenseStateChange(fiber);\n if (suspenseChange) {\n // Record the boundary transition for this commit\n if (!perCommit.suspenseEvents) {\n perCommit.suspenseEvents = [];\n }\n const event: SuspenseBoundaryEvent = {\n depth,\n entered: suspenseChange.entered,\n left: suspenseChange.left,\n ...(captureFibers && { fiber }),\n };\n perCommit.suspenseEvents.push(event);\n\n // Treat a Suspense boundary state-change as a source.\n // We use a synthetic stable key that encodes type+depth so the same boundary\n // accumulates across commits (same logic as regular sources).\n // The type sentinel is the React.Suspense symbol on the fiber.\n if (enableSourceTracking) {\n const suspenseType = fiber.type; // symbol \u2014 stable across renders\n const sourceId = sourceIdManager.getSourceId(fiber, suspenseType, depth);\n const suspenseHook: ChangedHook = {\n prevValue: suspenseChange.left ? 'suspended' : null,\n currentValue: suspenseChange.entered ? 'suspended' : null,\n info: suspenseChange.entered ? 'suspense:entered-fallback' : 'suspense:left-fallback',\n };\n perCommit.selfUpdated.set(sourceId, {\n type: suspenseType,\n depth,\n count: 1,\n changedHookIndices: [0],\n changedHooks: [suspenseHook],\n fiber: captureFibers ? fiber : undefined,\n isUpdater: true,\n });\n ownerSourceId = sourceId;\n }\n }\n }\n\n if (isComponent) {\n const type = fiber.type;\n\n // Count components with PerformedWork (committed work)\n if (didFiberUpdate(fiber)) {\n perCommit.committedComponentCount++;\n }\n\n // Early bailout: skip components that didn't update (no PerformedWork flag)\n if (!didFiberUpdate(fiber)) {\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.child) visit(fiber.child, depth + 1, ownerSourceId);\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.sibling) visit(fiber.sibling, depth, currentOwnerSourceId);\n return;\n }\n\n if (!ignoreSet.has(type) && !isReactInternalComponentType(type)) {\n const componentSourceId = sourceIdManager.getSourceId(fiber, type, depth);\n const parentFiber = fiber.return && isComponentFiber(fiber.return.tag) ? fiber.return : null;\n const parentSourceId = parentFiber\n ? sourceIdManager.getSourceId(parentFiber, parentFiber.type, depth - 1)\n : null;\n const existingRenderEvidenceIndex = perCommit.rendered.findIndex(\n (entry) => entry.sourceId === componentSourceId\n );\n const initialRenderEvidence: RenderedComponentEvidence = {\n sourceId: componentSourceId,\n name: getComponentName(fiber),\n depth,\n parentSourceId,\n ownerSourceId,\n isSelfSource: false,\n propChanges: fiber.alternate ? diffProps(fiber.alternate.memoizedProps, fiber.memoizedProps) : [],\n hasPropChanges: false,\n trasherCounts: { effects: 0, callbacks: 0, memos: 0 },\n };\n initialRenderEvidence.hasPropChanges = initialRenderEvidence.propChanges.length > 0;\n if (existingRenderEvidenceIndex >= 0) {\n perCommit.rendered[existingRenderEvidenceIndex] = initialRenderEvidence;\n } else {\n perCommit.rendered.push(initialRenderEvidence);\n }\n\n // Track provenance of useCallback/useMemo results (only if amplifier detection enabled)\n if (enableAmplifiers) {\n let hook = fiber.memoizedState;\n let hookIndex = 0;\n\n while (hook) {\n const ms = hook.memoizedState;\n if (Array.isArray(ms) && ms.length === 2 && Array.isArray(ms[1])) {\n const result = ms[0];\n if (\n result != null &&\n (typeof result === 'object' || typeof result === 'function')\n ) {\n valueProvenance.set(result, {\n type,\n hookIndex,\n depth,\n hookType: typeof result === 'function' ? 'useCallback' : 'useMemo',\n });\n }\n }\n\n hook = hook.next;\n hookIndex++;\n }\n }\n\n // Source tracking (Level 2+): Capture hook state and detect sources\n // Skip entirely in 'stats' mode for maximum performance\n let currentHookSnapshot: unknown[] | null = null;\n if (enableSourceTracking) {\n currentHookSnapshot = captureHookStateSnapshot(fiber);\n }\n\n // Source detection strategy (Level 2+):\n // 1. If memoizedUpdaters available (development): trust it completely\n // 2. If memoizedUpdaters NOT available (production): use our own lastSeenHookState\n // to avoid fiber.alternate lag false positives\n // Skip entirely in 'stats' mode (Level 1)\n\n let isRealSource = false;\n let changedIndices: number[] = [];\n let changedHooks: ChangedHook[] = [];\n\n if (enableSourceTracking) {\n const inMemoizedUpdaters = memoizedUpdaters\n ? memoizedUpdaters.has(fiber) ||\n (fiber.alternate && memoizedUpdaters.has(fiber.alternate))\n : null;\n\n if (memoizedUpdaters) {\n // DEVELOPMENT: Trust memoizedUpdaters completely\n if (inMemoizedUpdaters) {\n isRealSource = true;\n // Use didFiberSelfUpdate for the hook change details\n const selfUpdateResult = didFiberSelfUpdate(fiber);\n if (selfUpdateResult && selfUpdateResult.actionable) {\n changedIndices = selfUpdateResult.changedIndices;\n changedHooks = selfUpdateResult.changedHooks;\n }\n }\n // If not in memoizedUpdaters, skip this fiber as source\n } else {\n // PRODUCTION: Use our own tracking to avoid alternate lag\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const changes = detectChangesFromLastSeen(fiber, currentHookSnapshot!);\n if (changes.changedIndices.length > 0) {\n isRealSource = true;\n changedIndices = changes.changedIndices;\n changedHooks = changes.changedHooks;\n }\n }\n\n // Update our last-seen snapshot for this fiber (always, even if not a source)\n // This ensures we have accurate \"previous state\" for next commit\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n lastSeenHookState.set(fiber, currentHookSnapshot!);\n if (fiber.alternate) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n lastSeenHookState.set(fiber.alternate, currentHookSnapshot!);\n }\n }\n\n if (isRealSource && changedIndices.length > 0) {\n const sourceId = componentSourceId;\n\n // Track that this fiber is a source (so we don't count it as its own collateral)\n perCommit.sourceFibers.add(fiber);\n if (fiber.alternate) {\n perCommit.sourceFibers.add(fiber.alternate);\n }\n\n const existing = perCommit.selfUpdated.get(sourceId);\n\n const updateData = {\n type,\n depth,\n count: (existing?.count || 0) + 1,\n changedHookIndices: changedIndices,\n changedHooks: changedHooks,\n fiber: captureFibers ? fiber : undefined,\n isUpdater: true,\n };\n\n perCommit.selfUpdated.set(sourceId, updateData);\n perCommit.selfFibers.set(fiber, depth);\n\n // This fiber is now the owner for all descendants\n ownerSourceId = sourceId;\n }\n\n // Blast radius attribution: if this fiber updated and we have an owner, attribute it\n // ONLY count component fibers (not host nodes like div, span, etc.)\n // DON'T count if this fiber IS the owner (don't count source as its own collateral!)\n const isSourceItself = perCommit.sourceFibers.has(fiber);\n\n // Don't count mount/hydration work as \"collateral\" (not preventable).\n // eslint-disable-next-line no-bitwise\n const isNonPreventable = (fiber.flags & (Placement | Hydrating)) !== 0;\n\n if (\n isComponent &&\n fiber.alternate &&\n didFiberUpdate(fiber) &&\n ownerSourceId &&\n !isSourceItself &&\n !isNonPreventable\n ) {\n perCommit.blastBySourceId.set(\n ownerSourceId,\n (perCommit.blastBySourceId.get(ownerSourceId) || 0) + 1\n );\n\n const currentMax = perCommit.depthBySourceId.get(ownerSourceId) || 0;\n if (depth > currentMax) {\n perCommit.depthBySourceId.set(ownerSourceId, depth);\n }\n\n // Count total collateral for commitStats\n perCommit.totalCollateral++;\n }\n\n const renderedEntry = perCommit.rendered.find((entry) => entry.sourceId === componentSourceId);\n if (renderedEntry) {\n renderedEntry.ownerSourceId = ownerSourceId;\n renderedEntry.isSelfSource = isRealSource && changedIndices.length > 0;\n }\n\n // Amplifier detection (Level 3: counts/full).\n // Skip in 'stats' and 'sources' modes for better performance\n if (enableAmplifiers && didFiberUpdate(fiber) && fiber.alternate) {\n const thrashResult = detectHookThrashing(\n fiber.alternate.memoizedState,\n fiber.memoizedState,\n effectThrashMode,\n valueProvenance\n );\n\n const totalThrashing =\n thrashResult.effects.length +\n thrashResult.callbacks.length +\n thrashResult.memos.length;\n\n if (totalThrashing > 0) {\n if (thrashMode === 'counts') {\n if (state.thrashCounts) {\n state.thrashCounts.affectedComponents.add(type);\n state.thrashCounts.totalHooks += totalThrashing;\n }\n } else if (thrashMode === 'full') {\n const allThrashedHooks: ThrashInfo[] = [\n ...thrashResult.effects,\n ...thrashResult.callbacks,\n ...thrashResult.memos,\n ];\n\n // Legacy amplifiers (keyed by type)\n const existing = perCommit.thrashing.get(type);\n const thrashData = {\n instanceCount: (existing?.instanceCount || 0) + 1,\n hookCount: (existing?.hookCount || 0) + totalThrashing,\n lastAmplification: {\n depth,\n thrashedHooks: allThrashedHooks,\n fiber: captureFibers ? fiber : undefined,\n },\n };\n\n perCommit.thrashing.set(type, thrashData);\n\n // NEW: Linked amplification (keyed by sourceId)\n // Get or create sourceId for this fiber (even if not a source)\n const amplifierSourceId = sourceIdManager.getSourceId(fiber, type, depth);\n const existingLinked = perCommit.linkedThrashing.get(amplifierSourceId);\n\n const effects = (existingLinked?.effects || 0) + thrashResult.effects.length;\n const callbacks = (existingLinked?.callbacks || 0) + thrashResult.callbacks.length;\n const memos = (existingLinked?.memos || 0) + thrashResult.memos.length;\n perCommit.linkedThrashing.set(amplifierSourceId, {\n type,\n depth,\n effects,\n callbacks,\n memos,\n // If this fiber is a source, causedBySourceId is null (self-caused)\n // If this fiber is collateral, ownerSourceId is who caused it\n causedBySourceId: isRealSource ? null : ownerSourceId,\n lastAmplification: {\n depth,\n thrashedHooks: allThrashedHooks,\n fiber: captureFibers ? fiber : undefined,\n },\n });\n\n const renderedEntry = perCommit.rendered.find((entry) => entry.sourceId === amplifierSourceId);\n if (renderedEntry) {\n renderedEntry.trasherCounts = { effects, callbacks, memos };\n }\n\n // Count amplifiers for commitStats\n perCommit.effectCount += thrashResult.effects.length;\n perCommit.memoCount += thrashResult.memos.length;\n perCommit.callbackCount += thrashResult.callbacks.length;\n }\n }\n }\n }\n }\n\n // Propagate current owner to children (depth changes)\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.child) visit(fiber.child, depth + 1, ownerSourceId);\n // Siblings stay at same depth and inherit parent's owner\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n if (fiber.sibling) visit(fiber.sibling, depth, currentOwnerSourceId);\n }\n\n visit(rootFiber);\n\n // -------------------------------------------------------------------------\n // PASS 3: Update global aggregates (not hot loop).\n // -------------------------------------------------------------------------\n state.commits++;\n\n for (const [sourceId, data] of perCommit.selfUpdated.entries()) {\n const { type, depth, count, changedHookIndices, fiber } = data;\n\n let s = state.sources.get(sourceId);\n if (!s) {\n s = {\n type,\n depth,\n renderCount: 0,\n causedUpdates: 0,\n collateralUpdates: 0,\n maxCollateralUpdates: 0,\n maxPenetrationDepth: 0,\n updateHistory: {},\n collateralByCommit: {}, // Per-commit collateral for this source\n debugHookIndices: changedHookIndices.slice(),\n };\n state.sources.set(sourceId, s);\n }\n\n s.renderCount++;\n s.debugHookIndices = changedHookIndices.slice();\n\n // Store update history for this commit - this determines if it's a \"repeat\" or new update\n const historyWithUpdate = pushUpdateHistory(\n s.updateHistory,\n state.commits,\n changedHookIndices,\n data.changedHooks\n );\n s.updateHistory = trimHistoryToSize(historyWithUpdate, historySize);\n\n // Check if this commit was a REAL update or just a \"repeat\"\n // Only count causedUpdates and collateral for REAL updates\n const thisCommitEntry = s.updateHistory[state.commits];\n const isRepeat = thisCommitEntry === 'repeat';\n\n if (!isRepeat && data.isUpdater) {\n // This is a NEW update (not a repeat) - count it\n s.causedUpdates += count;\n\n const blast = perCommit.blastBySourceId.get(sourceId) || 0;\n s.collateralUpdates += blast;\n if (blast > s.maxCollateralUpdates) s.maxCollateralUpdates = blast;\n\n // Store per-commit collateral for this source (only for real updates)\n s.collateralByCommit[state.commits] = blast;\n\n const penetrationDepth = perCommit.depthBySourceId.get(sourceId) || 0;\n if (penetrationDepth > s.maxPenetrationDepth) {\n s.maxPenetrationDepth = penetrationDepth;\n }\n }\n\n if (captureFibers && fiber) {\n s.fiber = fiber;\n }\n }\n\n if (enableAmplifiers && thrashMode === 'full') {\n // Legacy thrashers (keyed by type)\n for (const [type, data] of perCommit.thrashing.entries()) {\n let s = state.amplifiers.get(type);\n if (!s) {\n s = {\n renderCount: 0,\n instancesTotal: 0,\n maxInstancesPerCommit: 0,\n hooksTotal: 0,\n maxHooksPerCommit: 0,\n effectCount: 0,\n callbackCount: 0,\n memoCount: 0,\n lastAmplification: { depth: 0, thrashedHooks: [] },\n };\n state.amplifiers.set(type, s);\n }\n\n s.renderCount++;\n s.instancesTotal += data.instanceCount;\n s.hooksTotal += data.hookCount;\n if (data.instanceCount > s.maxInstancesPerCommit)\n s.maxInstancesPerCommit = data.instanceCount;\n if (data.hookCount > s.maxHooksPerCommit) s.maxHooksPerCommit = data.hookCount;\n\n // eslint-disable-next-line @atlassian/perf-linting/no-quadratic-complexity\n data.lastAmplification.thrashedHooks.forEach((hook: ThrashInfo) => {\n if (hook.hookType === 'effect') s.effectCount++;\n else if (hook.hookType === 'callback') s.callbackCount++;\n else if (hook.hookType === 'memo') s.memoCount++;\n });\n\n s.lastAmplification = data.lastAmplification;\n }\n\n // NEW: Linked thrashers (keyed by sourceId)\n for (const [sourceId, data] of perCommit.linkedThrashing.entries()) {\n let as = state.amplifierSources.get(sourceId);\n if (!as) {\n as = {\n type: data.type,\n depth: data.depth,\n effectCount: 0,\n callbackCount: 0,\n memoCount: 0,\n hooksTotal: 0,\n commitIds: [],\n byCommit: {},\n causedBySourceId: data.causedBySourceId,\n lastAmplification: { depth: 0, thrashedHooks: [] },\n };\n state.amplifierSources.set(sourceId, as);\n }\n\n // Update counts\n as.effectCount += data.effects;\n as.callbackCount += data.callbacks;\n as.memoCount += data.memos;\n as.hooksTotal += data.effects + data.callbacks + data.memos;\n\n // Track which commits this amplifier fired in\n if (!as.commitIds.includes(state.commits)) {\n as.commitIds.push(state.commits);\n }\n\n // Per-commit breakdown\n as.byCommit[state.commits] = {\n effects: data.effects,\n callbacks: data.callbacks,\n memos: data.memos,\n };\n\n // Update causedBySourceId (use latest if different)\n if (data.causedBySourceId !== null) {\n as.causedBySourceId = data.causedBySourceId;\n }\n\n as.lastAmplification = data.lastAmplification;\n }\n }\n\n // Persist Suspense events for this commit\n if (perCommit.suspenseEvents && perCommit.suspenseEvents.length > 0) {\n state.suspenseByCommit[state.commits] = perCommit.suspenseEvents;\n }\n\n if (perCommit.rendered.length > 0) {\n state.renderedByCommit[state.commits] = perCommit.rendered;\n }\n\n // Store commitStats: [collateral, sources, restarts, performedWork, effects, memos, callbacks, contextUpdates, unmountedComponents, unmountedSubtrees]\n //\n // ALL fiber-walk-derived fields (collateral, sources, performedWork, effects,\n // memos, callbacks, contextUpdates) are real measurements that come from this\n // very recordTree() call. They are populated identically in 'adapter:<id>'\n // and 'devtools' integration modes \u2014 the fiber tree is the same in both.\n //\n // The ONLY adapter-exclusive field is `restarts` (index 2). It is\n // initialized to 0 here and overwritten after the adapter's delta\n // calculation in handleCommit. In 'devtools' mode there is no\n // render-counter delta available, so it stays at 0. Consumers should\n // consult report.meta.dataAvailability.restarts to disambiguate \"no\n // restarts measured\" (0 in 'devtools' mode = unknown) from \"zero restarts\n // confirmed\" (0 in 'adapter:<id>' mode = real).\n state.commitStats[state.commits] = [\n perCommit.totalCollateral,\n perCommit.selfUpdated.size, // Number of sources in this commit\n 0, // restarts - will be updated after the adapter's delta calculation\n perCommit.committedComponentCount, // performedWork - components with PerformedWork flag\n perCommit.effectCount,\n perCommit.memoCount,\n perCommit.callbackCount,\n perCommit.contextUpdates,\n perCommit.unmountedComponents,\n perCommit.unmountedSubtrees,\n ];\n\n if (perCommit.unmountSamples && perCommit.unmountSamples.length > 0) {\n state.unmountsByCommit[state.commits] = perCommit.unmountSamples;\n }\n\n // Return committed component count for restart calculation\n return perCommit.committedComponentCount;\n }\n\n function resetState(): void {\n state.commits = 0;\n state.sources.clear();\n state.amplifiers.clear();\n state.amplifierSources.clear();\n if (state.thrashCounts) {\n state.thrashCounts.totalHooks = 0;\n state.thrashCounts.affectedComponents.clear();\n }\n state.memoizedUpdatersAvailable = false;\n state.commitsWithMemoizedUpdaters = 0;\n // Clear commitStats\n for (const key of Object.keys(state.commitStats)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.commitStats[Number(key)];\n }\n // Clear adapter per-commit data\n for (const key of Object.keys(state.metricsByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.metricsByCommit[Number(key)];\n }\n // Clear timing data\n for (const key of Object.keys(state.commitTimings)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.commitTimings[Number(key)];\n }\n // Clear Suspense boundary transitions\n for (const key of Object.keys(state.suspenseByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.suspenseByCommit[Number(key)];\n }\n // Clear unmount samples\n for (const key of Object.keys(state.unmountsByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.unmountsByCommit[Number(key)];\n }\n // Clear rendered component evidence\n for (const key of Object.keys(state.renderedByCommit)) {\n // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n delete state.renderedByCommit[Number(key)];\n }\n interactionCapture.reset();\n // Recapture adapter snapshot as new baseline\n state.lastMetricsSnapshot = captureMetricsSnapshot();\n // Reset timing baseline\n state.lastCommitEndTime = performance.now();\n sourceIdManager.clear();\n }\n\n type DevtoolsHook = {\n onCommitFiberRoot?: (...args: unknown[]) => void;\n onCommitFiberUnmount?: (...args: unknown[]) => void;\n [key: string]: unknown;\n };\n\n type GlobalWithDevtools = typeof globalThis & {\n __REACT_DEVTOOLS_GLOBAL_HOOK__?: DevtoolsHook;\n };\n\n const commitSurface = createCommitSurfaceOwnership<{\n commitId: number;\n committedComponents: number;\n metricsBefore: CommitMetricsSnapshot | null;\n }>();\n\n // Chained predecessor on the DevTools hook (real React DevTools, etc.) \u2014 so\n // augmenting the hook never breaks an existing client. Restored on uninstall.\n let devtoolsHookPrev: ((...args: unknown[]) => void) | undefined;\n let devtoolsUnmountPrev: ((...args: unknown[]) => void) | undefined;\n // Was the DevTools hook present before install()? Tells uninstall whether to\n // delete it entirely or just restore the previous handler.\n let devtoolsHookCreatedByUs = false;\n\n // React's DevTools surface reports unmounted fibers via onCommitFiberUnmount.\n // Keep a small buffer between those callbacks and the following root commit;\n // this catches deletion work even if `fiber.deletions[]` has been cleared by\n // the time onCommitFiberRoot runs.\n let pendingDevtoolsUnmounts = { components: 0, subtrees: 0 };\n let pendingDevtoolsUnmountSamples: UnmountSample[] = [];\n\n // Integration mode is OBSERVED, not declared. Starts at 'devtools' (we always\n // own the DevTools surface after install). Promoted to 'adapter:<id>' on the\n // first adapter callback that proves the host surface is actually running.\n // Returns to 'none' only on uninstall.\n let integrationMode: IntegrationMode = 'none';\n\n function countUnmountedComponentSubtree(fiber: Fiber | null, parentIsComponent = false): { components: number; subtrees: number } {\n if (!fiber) return { components: 0, subtrees: 0 };\n const isComponent = isComponentFiber(fiber.tag);\n let components = isComponent ? 1 : 0;\n let subtrees = isComponent && !parentIsComponent ? 1 : 0;\n if (fiber.child) {\n const child = countUnmountedComponentSubtree(fiber.child, isComponent);\n components += child.components;\n subtrees += child.subtrees;\n }\n if (fiber.sibling) {\n const sibling = countUnmountedComponentSubtree(fiber.sibling, parentIsComponent);\n components += sibling.components;\n subtrees += sibling.subtrees;\n }\n return { components, subtrees };\n }\n\n function summarizeHostSubtree(fiber: Fiber | null): {\n elements: number;\n text: number;\n tagsTop: Array<[string, number]>;\n testIdsTop: Array<[string, number]>;\n rolesTop: Array<[string, number]>;\n ariaLabels: string[];\n textHints: string[];\n } {\n const tags = new Map<string, number>();\n const testIds = new Map<string, number>();\n const roles = new Map<string, number>();\n const ariaLabels: string[] = [];\n const textHints: string[] = [];\n let elements = 0;\n let text = 0;\n const add = (map: Map<string, number>, key: unknown) => {\n if (typeof key !== 'string' || !key) return;\n map.set(key, (map.get(key) || 0) + 1);\n };\n const addHint = (arr: string[], value: unknown, max = 6) => {\n if (typeof value !== 'string') return;\n const trimmed = value.replace(/\\s+/g, ' ').trim();\n if (!trimmed || arr.includes(trimmed)) return;\n arr.push(trimmed.length > 80 ? `${trimmed.slice(0, 77)}\u2026` : trimmed);\n if (arr.length > max) arr.length = max;\n };\n const top = (map: Map<string, number>) => Array.from(map.entries()).sort((a, b) => b[1] - a[1]).slice(0, 6);\n const walk = (f: Fiber | null) => {\n if (!f) return;\n if (f.tag === 5) {\n elements++;\n const props = (f.memoizedProps || {}) as Record<string, unknown>;\n add(tags, typeof f.type === 'string' ? f.type : 'host');\n add(testIds, props['data-testid']);\n add(roles, props.role);\n addHint(ariaLabels, props['aria-label']);\n addHint(ariaLabels, props.title);\n addHint(textHints, typeof props.children === 'string' ? props.children : null);\n } else if (f.tag === 6) {\n text++;\n addHint(textHints, f.memoizedProps);\n }\n walk(f.child);\n walk(f.sibling);\n };\n walk(fiber);\n return { elements, text, tagsTop: top(tags), testIdsTop: top(testIds), rolesTop: top(roles), ariaLabels, textHints };\n }\n\n function recordMetricsEvidence(\n commitId: number,\n committedComponents: number,\n before: CommitMetricsSnapshot,\n after: CommitMetricsSnapshot,\n ): void {\n if (!metricsAdapter) return;\n const { delta, restarts } = metricsAdapter.measure(before, after, committedComponents, commitId);\n state.metricsByCommit[commitId] = delta;\n if (state.commitStats[commitId]) {\n state.commitStats[commitId][CS_RESTARTS] = restarts;\n }\n }\n /**\n * Core commit handler \u2014 shared by the adapter and DevTools paths.\n * metricsDeltaAvailable: true only when the adapter's counters are live.\n */\n function handleCommit(\n root: { current: Fiber; memoizedUpdaters?: Set<Fiber> },\n metricsDeltaAvailable: boolean\n ): number {\n // Renderer internals are guaranteed to exist by the time commit hooks fire.\n // Installing here arms passive hook stack capture for subsequent real renders\n // without invoking product components during inspection.\n debugRender.install();\n const commitHookStartTime = performance.now();\n const timeSinceLastCommit = commitHookStartTime - state.lastCommitEndTime;\n\n const metricsBefore = state.lastMetricsSnapshot || captureMetricsSnapshot();\n\n const memoizedUpdaters = root.memoizedUpdaters;\n const committedComponents = recordTree(root.current, memoizedUpdaters || null);\n\n // `recordTree` counts deletions from fiber.deletions[]. Some renderers clear\n // that array before the final root callback, while still calling the DevTools\n // unmount hook. We use the DevTools surface as a FALLBACK when recordTree saw\n // no deletions this commit. We do NOT merge with max() \u2014 DevTools fires\n // onCommitFiberUnmount per-descendant (not per-subtree-root), so summing\n // produces inflated subtree counts for nested deletions (e.g. Mid > Leaf\n // \u2192 DevTools fires twice \u2192 counts as 2 subtrees instead of 1).\n const currentStats = state.commitStats[state.commits];\n if (currentStats && (pendingDevtoolsUnmounts.components > 0 || pendingDevtoolsUnmounts.subtrees > 0)) {\n const recordTreeSawDeletions = (currentStats[CS_UNMOUNTED_COMPONENTS] || 0) > 0;\n if (!recordTreeSawDeletions) {\n // Fallback: recordTree didn't see fiber.deletions[] (renderer cleared it\n // before commit). Trust DevTools counts even though they may over-report\n // subtrees for nested deletions \u2014 better some signal than none.\n currentStats[CS_UNMOUNTED_COMPONENTS] = pendingDevtoolsUnmounts.components;\n currentStats[CS_UNMOUNTED_SUBTREES] = pendingDevtoolsUnmounts.subtrees;\n }\n pendingDevtoolsUnmounts = { components: 0, subtrees: 0 };\n }\n if (pendingDevtoolsUnmountSamples.length > 0) {\n const existing = state.unmountsByCommit[state.commits];\n if (existing && existing.length > 0) {\n // Prefer deletion-walk samples (have depth). Drop devtools samples to\n // avoid noisy duplicates.\n } else {\n state.unmountsByCommit[state.commits] = pendingDevtoolsUnmountSamples;\n }\n pendingDevtoolsUnmountSamples = [];\n }\n\n const metricsAfter = captureMetricsSnapshot();\n if (metricsDeltaAvailable && metricsBefore && metricsAfter) {\n recordMetricsEvidence(state.commits, committedComponents, metricsBefore, metricsAfter);\n }\n state.lastMetricsSnapshot = metricsAfter;\n\n const commitHookEndTime = performance.now();\n interactionCapture.linkRecent(state.commits, commitHookEndTime);\n state.commitTimings[state.commits] = {\n timeSinceLastCommit,\n detectorOverhead: commitHookEndTime - commitHookStartTime,\n };\n state.lastCommitEndTime = commitHookEndTime;\n return committedComponents;\n }\n\n return {\n /**\n * Start profiling React commits.\n *\n * Integration model is OBSERVED at runtime, not declared at install time.\n *\n * 'devtools' \u2014 DevTools `onCommitFiberRoot` is the canonical entry\n * point. We define the hook if absent, augment (chain)\n * if present. On every commit we capture the fiber tree.\n *\n * 'adapter:<id>' \u2014 Promoted from 'devtools' the first time the commit\n * metrics adapter's host callback actually fires for a\n * real commit. From then on the adapter is the\n * authoritative processor and the DevTools surface is\n * chained-observer-only. The adapter is preferred when\n * alive because it carries render-counter deltas\n * (restart math, metricsByCommit).\n *\n * 'none' \u2014 Only when no DevTools hook surface can be created and\n * no adapter surface is reachable. Practically never\n * hit, since the content-script ships a\n * devtools-hook-shim before react-dom.\n *\n * Double-invocation safety:\n * Once an adapter callback has fired, DevTools remains chained for\n * existing tooling but does not capture commits; the adapter alone calls\n * `handleCommit`. Without a live adapter, DevTools is the capture\n * surface. This avoids duplicate capture without relying on per-root\n * timing heuristics.\n *\n * Side effects:\n * - Defines `__REACT_DEVTOOLS_GLOBAL_HOOK__` if it does not already exist\n * (minimal contract: `onCommitFiberRoot` only). React reads the hook at\n * module-eval time; the content-script shim handles ordering.\n * - Asks the adapter (when one is registered) to route its host commit\n * callback here, *if and when* the host calls it.\n *\n * Safe to call multiple times (idempotent: chains skipped when our wrappers\n * are already in place).\n */\n install(): void {\n interactionCapture.install();\n const devtoolsGlobal = globalThis as GlobalWithDevtools;\n metricsAdapter = resolveMetricsAdapter();\n // Capture an initial adapter snapshot regardless. If the host surface is\n // dead these counters stay at zero and the delta is a no-op.\n state.lastMetricsSnapshot = captureMetricsSnapshot();\n\n // \u2500\u2500 1. Ensure a DevTools hook surface exists \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // React calls __REACT_DEVTOOLS_GLOBAL_HOOK__.onCommitFiberRoot on every\n // commit when the hook is present at react-dom eval time. We define a\n // minimal hook if nothing is there; otherwise we augment the existing one.\n let hook = devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (!hook) {\n hook = {} as DevtoolsHook;\n devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__ = hook;\n devtoolsHookCreatedByUs = true;\n } else {\n devtoolsHookCreatedByUs = false;\n }\n\n devtoolsHookPrev = typeof hook.onCommitFiberRoot === 'function'\n ? hook.onCommitFiberRoot\n : undefined;\n devtoolsUnmountPrev = typeof hook.onCommitFiberUnmount === 'function'\n ? hook.onCommitFiberUnmount\n : undefined;\n\n const devtoolsHandler = (...args: unknown[]) => {\n // Always chain whatever was there first (real React DevTools, other\n // tooling). Errors in third-party handlers must not poison React.\n if (devtoolsHookPrev) {\n try { devtoolsHookPrev(...args); } catch (_) { /* swallow */ }\n }\n\n const root = args[1] as { current: Fiber; memoizedUpdaters?: Set<Fiber> } | undefined;\n if (!root) return;\n\n // The adapter is the canonical fast path (it carries the render-counter\n // deltas). Defer only after an adapter callback has proved that the host\n // surface is live. BUT: a host runtime can wipe or replace its surface\n // mid-session (for example `delete window.__ATL_REACT_METRICS`), which\n // orphans our callback on the old object. Re-seed lazily here: if the\n // callback is no longer wired, re-attach so subsequent commits route\n // through the adapter again.\n if (commitSurface.adapterObserved && metricsAdapter) {\n if (!metricsAdapter.isAttached()) {\n metricsAdapter.reattach();\n // Fall through to capture this commit via devtools so we don't lose it.\n const metricsBefore = state.lastMetricsSnapshot || captureMetricsSnapshot();\n const committedComponents = handleCommit(root, /* metricsDeltaAvailable */ false);\n commitSurface.recordDevtools(root, { commitId: state.commits, committedComponents, metricsBefore });\n return;\n }\n // The adapter is still wired \u2014 let it own this commit.\n return;\n }\n const metricsBefore = state.lastMetricsSnapshot || captureMetricsSnapshot();\n const committedComponents = handleCommit(root, /* metricsDeltaAvailable */ false);\n commitSurface.recordDevtools(root, { commitId: state.commits, committedComponents, metricsBefore });\n };\n hook.onCommitFiberRoot = devtoolsHandler;\n\n const devtoolsUnmountHandler = (...args: unknown[]) => {\n if (devtoolsUnmountPrev) {\n try { devtoolsUnmountPrev(...args); } catch (_) { /* swallow */ }\n }\n const fiber = args[1] as Fiber | undefined;\n if (!fiber) return;\n const counts = countUnmountedComponentSubtree(fiber);\n pendingDevtoolsUnmounts.components += counts.components;\n pendingDevtoolsUnmounts.subtrees += counts.subtrees;\n if (counts.components > 0 && pendingDevtoolsUnmountSamples.length < 30) {\n // Find the topmost component fiber in the deleted subtree (could be the\n // root fiber itself, or a descendant if React handed us a host wrapper).\n let labelFiber: Fiber | null = fiber;\n if (!isComponentFiber(labelFiber.tag)) {\n const stack: Fiber[] = [labelFiber];\n labelFiber = null;\n while (stack.length) {\n const f = stack.pop()!;\n if (isComponentFiber(f.tag)) { labelFiber = f; break; }\n if (f.child) stack.push(f.child);\n if (f.sibling) stack.push(f.sibling);\n }\n }\n if (labelFiber) {\n const fiberKey = (labelFiber as unknown as { key?: string | number | null }).key;\n pendingDevtoolsUnmountSamples.push({\n name: getComponentName(labelFiber),\n key: fiberKey == null ? null : String(fiberKey),\n depth: null,\n count: counts.components,\n source: summarizeFiberSource(labelFiber),\n host: summarizeHostSubtree(fiber),\n });\n }\n }\n lastSeenHookState.delete(fiber);\n if (fiber.alternate) lastSeenHookState.delete(fiber.alternate);\n };\n hook.onCommitFiberUnmount = devtoolsUnmountHandler;\n\n // Default observed mode until an adapter proves itself.\n integrationMode = 'devtools';\n\n // \u2500\u2500 2. Listen on the adapter surface \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // We don't probe whether the host surface is alive \u2014 we let invocation\n // be the proof. Once the adapter's callback fires, its counters are\n // available for the delta math.\n commitSurface.reset();\n const adapter = metricsAdapter;\n if (adapter) {\n const adapterMode: IntegrationMode = `adapter:${adapter.id}`;\n adapter.attach((root) => {\n const previousCapture = commitSurface.observeAdapter(root);\n // First invocation is proof of life. Promote mode permanently.\n if (integrationMode !== adapterMode) {\n integrationMode = adapterMode;\n }\n\n if (previousCapture) {\n // The host may call DevTools first. Enrich that same commit with\n // adapter counters without traversing or recording it a second time.\n const metricsAfter = captureMetricsSnapshot();\n if (previousCapture.metricsBefore && metricsAfter) {\n recordMetricsEvidence(previousCapture.commitId, previousCapture.committedComponents, previousCapture.metricsBefore, metricsAfter);\n }\n state.lastMetricsSnapshot = metricsAfter;\n } else {\n handleCommit(root, /* metricsDeltaAvailable */ true);\n }\n });\n }\n },\n\n /**\n * Stop profiling React commits. Does not clear accumulated state.\n * Call reset() to clear state.\n *\n * Restores the DevTools hook to its prior state:\n * - hook was created by us \u2192 delete the hook entirely\n * - hook had a prior onCommitFiberRoot \u2192 restore it\n * - hook had no handler \u2192 delete the property\n *\n * Asks the adapter to remove its host callback only if it is still ours\n * (don't stomp a concurrent installer).\n */\n uninstall(): void {\n metricsAdapter?.detach();\n\n // Restore DevTools hook.\n const devtoolsGlobal = globalThis as GlobalWithDevtools;\n const hook = devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n if (hook) {\n if (devtoolsHookCreatedByUs) {\n // We created it; remove the whole thing.\n delete devtoolsGlobal.__REACT_DEVTOOLS_GLOBAL_HOOK__;\n } else {\n if (devtoolsHookPrev) {\n hook.onCommitFiberRoot = devtoolsHookPrev;\n } else {\n delete hook.onCommitFiberRoot;\n }\n if (devtoolsUnmountPrev) {\n hook.onCommitFiberUnmount = devtoolsUnmountPrev;\n } else {\n delete hook.onCommitFiberUnmount;\n }\n }\n }\n debugRender.uninstall();\n interactionCapture.uninstall();\n commitSurface.reset();\n pendingDevtoolsUnmounts = { components: 0, subtrees: 0 };\n pendingDevtoolsUnmountSamples = [];\n devtoolsHookPrev = undefined;\n devtoolsUnmountPrev = undefined;\n devtoolsHookCreatedByUs = false;\n integrationMode = 'none';\n },\n\n /**\n * Clear all accumulated profiling state. Useful for starting fresh measurements.\n * Does not uninstall the profiler - call uninstall() separately if needed.\n */\n reset(): void {\n resetState();\n debugRender.reset();\n },\n\n /**\n * Generate a report of top update sources and thrashing components.\n * @param topN - Number of top sources to include (default: 10)\n * @param sortBy - Sort thrashers by 'effect', 'callback', 'memo', or 'total' (default: 'effect')\n * @param options - Report filtering options (e.g., minCollateral to hide low-impact sources)\n * @returns Report containing sources, blast radius, and optional thrashing data\n */\n report(topN: number = 10, sortBy: SortBy = 'effect', reportOptions?: ReportOptions): Report {\n return buildReport(state, thrashMode, topN, sortBy, reportOptions, {\n effectThrashMode,\n captureFibers,\n historySize,\n detectionLevel,\n integrationMode,\n });\n },\n\n /**\n * Raw passive hook events captured for a component (debug surface).\n */\n _debugRawHookEvents(componentName: string) {\n const components = debugRender.allComponents();\n const events = componentName === '*' ? [] : debugRender.rawEvents(componentName);\n return {\n ok: true,\n componentName,\n status: debugRender.status(),\n components,\n events,\n };\n },\n\n _debugInjectHookEventsForTest(componentName: string, events: HookCallEvent[]) {\n if (typeof debugRender.recordEventForTest !== 'function') return;\n for (const event of events) {\n debugRender.recordEventForTest({ ...event, componentName });\n }\n },\n\n _debugSetSourceForTest(sourceId: string, source: unknown) {\n state.sources.set(sourceId, source as Omit<Source, 'sourceId'>);\n },\n\n debugHook(sourceId: string, hookIndex: number, windowSize: number = 3) {\n let source = state.sources.get(sourceId);\n let resolvedSourceId = sourceId;\n if (!source) {\n for (const [internalId, candidate] of state.sources.entries()) {\n const candidateHumanId = `${getComponentDisplayName(candidate.type)}#${String(internalId).match(/#(\\d+)@/)?.[1] || '1'}@${candidate.depth}`;\n if (candidateHumanId === sourceId) {\n source = candidate;\n resolvedSourceId = internalId;\n break;\n }\n }\n }\n if (!source) return { ok: false, error: 'sourceId not found', sourceId };\n const componentName = getComponentDisplayName(source.type);\n let events = debugRender.rawEvents(componentName);\n let resolvedComponentName = componentName;\n if (events.length === 0) {\n const candidates = debugRender.allComponents();\n const matching = candidates.find((name) => name === componentName || name.includes(componentName) || componentName.includes(name));\n if (matching) {\n resolvedComponentName = matching;\n events = debugRender.rawEvents(matching);\n }\n }\n\n const sourceHookIndices = Array.isArray(source.debugHookIndices)\n ? source.debugHookIndices\n : [];\n const targetIndex = Math.floor(hookIndex);\n const eventIndex = sourceHookIndices[targetIndex] ?? targetIndex;\n const target = events[eventIndex];\n const radius = Math.max(0, Math.floor(windowSize));\n if (!target) {\n return {\n ok: false,\n error: 'hook event not found',\n sourceId: resolvedSourceId,\n requestedSourceId: sourceId,\n componentName,\n resolvedComponentName,\n hookIndex: targetIndex,\n eventIndex,\n sourceHookIndices,\n eventCount: events.length,\n status: debugRender.status(),\n caveat: 'hook ancestry comes from passive stack capture during real renders; component-name stack parsing can be ambiguous in bundled/minified code',\n };\n }\n const neighborhood = events\n .map((event, index) => ({ event, index }))\n .filter(({ index }) => Math.abs(index - eventIndex) <= radius)\n .map(({ event, index }) => ({\n hookIndex: sourceHookIndices.indexOf(index) >= 0 ? sourceHookIndices.indexOf(index) : index,\n eventIndex: index,\n primitive: event.primitive,\n parents: parentFramesForEvent(event, componentName),\n }));\n return {\n ok: true,\n sourceId: resolvedSourceId,\n requestedSourceId: sourceId,\n componentName,\n resolvedComponentName,\n hookIndex: targetIndex,\n eventIndex,\n sourceHookIndices,\n primitive: target.primitive,\n parents: parentFramesForEvent(target, componentName),\n neighborhood,\n eventCount: events.length,\n status: debugRender.status(),\n caveat: 'hook ancestry comes from passive stack capture during real renders; source-local hook indices are mapped onto the captured component event stream',\n };\n },\n\n /**\n * Returns which commit-hook integration model is currently observed.\n * 'devtools' \u2014 DevTools hook is the active processor (no proven adapter callbacks).\n * 'adapter:<id>' \u2014 The adapter's host surface has fired; it owns the math now.\n * 'none' \u2014 Detector not installed.\n */\n getIntegrationMode(): IntegrationMode {\n return integrationMode;\n },\n\n /** Id of the commit metrics adapter resolved on install, or null. */\n getMetricsAdapterId(): string | null {\n return metricsAdapter?.id ?? null;\n },\n };\n}\n\n/**\n * Detection level constants - use these for clarity about the hierarchy.\n * Higher levels include all features from lower levels.\n */\nexport const DETECTION_LEVEL = {\n /** Level 1: Only commitStats (performedWork for restarts) - minimal overhead */\n LEVEL1_STATS: 'stats' as const,\n /** Level 2: Stats + source tracking (which components caused updates) */\n LEVEL2_SOURCES: 'sources' as const,\n /** Level 3a: Sources + aggregate amplifier counts only (meta.amplifiersMetrics) */\n LEVEL3_AMPLIFIER_METRICS: 'amplifierMetrics' as const,\n /** Level 3b: Sources + full amplifier arrays (report.amplifiers, report.amplifierSources) */\n LEVEL3_AMPLIFIERS: 'amplifiers' as const,\n} as const;\n", "/**\n * Seed, protect, and guard a host metrics slot such as `__ATL_REACT_METRICS`.\n *\n * The host page owns the slot. Its instrumented react-dom reads the slot before\n * it calls `onCommitFiberRoot`, and its runtime may zero-fill or delete the slot\n * during hydration cleanup. These helpers never lock the slot: every descriptor\n * they write stays `configurable: true`, and a slot the host already locked is\n * left alone.\n */\n\nexport const DEFAULT_METRICS_SLOT = '__ATL_REACT_METRICS';\n\n/** Counters a zeroed slot starts with. */\nexport const METRICS_COUNTER_KEYS = [\n 'mountWorkCount', 'updateWorkCount', 'commitWorkCount', 'interruptedWorkCount',\n 'priorityInterruptedWorkCount', 'externalStoreRestartCount', 'renderRootSyncCount',\n 'renderRootConcurrentCount', 'componentWorkCount', 'componentMountWorkCount',\n 'componentUpdateWorkCount', 'componentRenderWithHooksCount', 'finishClassComponentCount',\n 'domWorkCount', 'totalTickCount', 'totalCommitCount', 'contextUpdateCount',\n 'legacyContextUpdateCount',\n] as const;\n\n/** Counters the accessor checks before accepting a write; adds the detector's totals. */\nconst ACCESSOR_KEYS = [...METRICS_COUNTER_KEYS, 'totalRestarts', 'totalPerformedWork'] as const;\n\ntype SlotTarget = Record<string, unknown>;\nexport type MetricsSlotValue = Record<string, unknown>;\n\nexport function createZeroMetrics(): MetricsSlotValue {\n const metrics: MetricsSlotValue = {};\n for (const key of METRICS_COUNTER_KEYS) metrics[key] = 0;\n metrics.setStateCount = 0;\n return metrics;\n}\n\nfunction isAllZero(value: unknown): boolean {\n if (!value || typeof value !== 'object') return true;\n const record = value as Record<string, unknown>;\n for (const key of ACCESSOR_KEYS) if (((record[key] as number) || 0) !== 0) return false;\n return true;\n}\n\n/** True when the host owns the slot: non-configurable, or an accessor. */\nexport function isSlotHostLocked(target: SlotTarget, slotName = DEFAULT_METRICS_SLOT): boolean {\n const existing = Object.getOwnPropertyDescriptor(target, slotName);\n return !!existing && (existing.configurable === false || typeof existing.get === 'function');\n}\n\n/**\n * Write `metrics` as a plain, deletable data property. Honors a host lock\n * (configurable: false). Falls back to plain assignment.\n */\nexport function protectMetricsSlot(target: SlotTarget, metrics: MetricsSlotValue, slotName = DEFAULT_METRICS_SLOT): void {\n try {\n const existing = Object.getOwnPropertyDescriptor(target, slotName);\n if (existing && existing.configurable === false) return;\n Object.defineProperty(target, slotName, { configurable: true, enumerable: true, writable: true, value: metrics });\n } catch {\n try { target[slotName] = metrics; } catch { /* host wins */ }\n }\n}\n\n/** Seed a fresh zeroed slot. Returns the new metrics object. */\nexport function seedMetricsSlot(target: SlotTarget, slotName = DEFAULT_METRICS_SLOT): MetricsSlotValue {\n const metrics = createZeroMetrics();\n try { target[slotName] = metrics; } catch { /* protect below retries */ }\n protectMetricsSlot(target, metrics, slotName);\n return metrics;\n}\n\n/**\n * Install a configurable accessor on the slot before React evaluates.\n *\n * - `configurable: true`, so a host `delete` succeeds without a TypeError.\n * After a delete the slot is gone until the next detector install re-seeds it.\n * - `set()` ignores null, undefined, and all-zero writes, so host hydration\n * cleanup that zero-fills the slot cannot orphan the live metrics object.\n * - A slot the host already locked is left alone.\n *\n * Returns true when the accessor was installed.\n */\nexport function installMetricsAccessor(target: SlotTarget, slotName = DEFAULT_METRICS_SLOT): boolean {\n try {\n const existing = Object.getOwnPropertyDescriptor(target, slotName);\n if (existing && existing.configurable === false) return false;\n let live = existing && typeof existing.get === 'function'\n ? target[slotName]\n : existing?.value;\n if (!live || typeof live !== 'object') {\n live = { onCommitFiberRoot: null };\n for (const key of ACCESSOR_KEYS) (live as MetricsSlotValue)[key] = 0;\n }\n Object.defineProperty(target, slotName, {\n configurable: true,\n enumerable: true,\n get() { return live; },\n set(next: unknown) {\n if (next === undefined || next === null || isAllZero(next)) return;\n live = next;\n },\n });\n return true;\n } catch {\n // Non-fatal: the detector falls back to DevTools capture.\n return false;\n }\n}\n", "/**\n * ATL commit metrics adapter: reads the render counters that Atlassian's\n * patched react-dom writes into `__ATL_REACT_METRICS` and routes that slot's\n * `onCommitFiberRoot` callback to the detector.\n *\n * The slot name is configurable, so a renamed slot needs no core change.\n */\n\nimport type {\n CommitMetricsAdapter,\n CommitMetricsRoot,\n CommitMetricsSnapshot,\n} from '../../avalanche/commit-metrics-adapter';\nimport {\n DEFAULT_METRICS_SLOT,\n installMetricsAccessor,\n isSlotHostLocked,\n seedMetricsSlot,\n} from './metrics-slot';\n\n/**\n * Per-commit ATL delta - work done in a single commit.\n * Enables full reconciliation: ATL work counts \u2194 Avalanche component counts.\n *\n * Key relationship (should hold for any commit):\n * componentRenderWithHooksCount + finishClassComponentCount === collateral + sources\n */\nexport type ATLCommitDelta = {\n /** Function components mounted this commit (should be 0 during pure updates!) */\n mountWorkCount: number;\n /** Fiber update work this commit */\n updateWorkCount: number;\n /** Work that reached commit phase */\n commitWorkCount: number;\n performedWorkCount: number;\n /** Work interrupted (priority change) */\n interruptedWorkCount: number;\n /** Component fiber work (class + function) */\n componentWorkCount: number;\n /** Components mounted (should be 0 during pure updates!) */\n componentMountWorkCount: number;\n /** Components updated */\n componentUpdateWorkCount: number;\n /** DOM work (host fibers) */\n domWorkCount: number;\n ticksCount: number;\n /** Context propagation waves */\n contextUpdateCount: number;\n /** Legacy context propagations (tech debt indicator) */\n legacyContextUpdateCount: number;\n /** ALL function components rendered (including hookless) */\n componentRenderWithHooksCount: number;\n /** Class components rendered */\n finishClassComponentCount: number;\n /** useSES-triggered restarts (store mutation detected after concurrent render) */\n externalStoreRestartCount?: number;\n /** Work abandoned due to priority preemption (fibers unwound in prepareFreshStack) */\n priorityInterruptedWorkCount?: number;\n /** Number of sync renderRoot passes in this commit window */\n renderRootSyncCount?: number;\n /** Number of concurrent renderRoot passes in this commit window */\n renderRootConcurrentCount?: number;\n /** useState/useReducer dispatches during this commit (react-dom patch; optional) */\n setStateCount?: number;\n};\n\nexport const ATL_DISPATCHER_FRAME = 'atlDispatcherHook';\n\ntype SlotHandler = (...args: unknown[]) => void;\ntype Slot = Record<string, unknown> & { onCommitFiberRoot?: SlotHandler | null };\n\nconst num = (snapshot: CommitMetricsSnapshot, key: string): number => (snapshot[key] as number | undefined) ?? 0;\nconst diff = (before: CommitMetricsSnapshot, after: CommitMetricsSnapshot, key: string): number => num(after, key) - num(before, key);\n\n/** Counter delta between two ATL snapshots. */\nexport function calculateATLDelta(before: CommitMetricsSnapshot, after: CommitMetricsSnapshot): ATLCommitDelta {\n return {\n // Basic work counters\n mountWorkCount: diff(before, after, 'mountWorkCount'),\n updateWorkCount: diff(before, after, 'updateWorkCount'),\n commitWorkCount: diff(before, after, 'commitWorkCount'),\n performedWorkCount: diff(before, after, 'totalPerformedWork'),\n\n // Interruption/restart counters\n interruptedWorkCount: diff(before, after, 'interruptedWorkCount'),\n externalStoreRestartCount: diff(before, after, 'externalStoreRestartCount'),\n priorityInterruptedWorkCount: diff(before, after, 'priorityInterruptedWorkCount'),\n renderRootSyncCount: diff(before, after, 'renderRootSyncCount'),\n renderRootConcurrentCount: diff(before, after, 'renderRootConcurrentCount'),\n\n // Scheduler\n ticksCount: diff(before, after, 'totalTickCount'),\n\n // Component work counters\n componentWorkCount: diff(before, after, 'componentWorkCount'),\n componentMountWorkCount: diff(before, after, 'componentMountWorkCount'),\n componentUpdateWorkCount: diff(before, after, 'componentUpdateWorkCount'),\n componentRenderWithHooksCount: diff(before, after, 'componentRenderWithHooksCount'),\n finishClassComponentCount: diff(before, after, 'finishClassComponentCount'),\n\n // DOM work\n domWorkCount: diff(before, after, 'domWorkCount'),\n\n // Context updates\n contextUpdateCount: diff(before, after, 'contextUpdateCount'),\n legacyContextUpdateCount: diff(before, after, 'legacyContextUpdateCount'),\n\n // Hook-metric delta (react-dom patch; optional). Omit when neither snapshot\n // carries a numeric setStateCount so we never emit a bogus 0 on unpatched hosts.\n // TODO: Require finite values on both sides or model a counter reset\n // explicitly. Treating a missing/wiped side as zero can emit a negative delta,\n // and typeof NaN === 'number' lets a poisoned counter enter the report.\n ...(typeof after.setStateCount === 'number' || typeof before.setStateCount === 'number'\n ? { setStateCount: diff(before, after, 'setStateCount') }\n : {}),\n };\n}\n\nexport type ATLCommitMetricsAdapterOptions = {\n /** Global slot the patched react-dom writes. Default `__ATL_REACT_METRICS`. */\n slotName?: string;\n /** Object that holds the slot. Default `globalThis`. */\n target?: Record<string, unknown>;\n};\n\nexport function createATLCommitMetricsAdapter(options: ATLCommitMetricsAdapterOptions = {}): CommitMetricsAdapter {\n const slotName = options.slotName ?? DEFAULT_METRICS_SLOT;\n const target = () => options.target ?? (globalThis as unknown as Record<string, unknown>);\n const slot = (): Slot | null => {\n const value = target()[slotName];\n return value && typeof value === 'object' ? (value as Slot) : null;\n };\n let ourHandler: SlotHandler | undefined;\n\n return {\n id: 'atl',\n frameFilters: [ATL_DISPATCHER_FRAME],\n\n prePage() {\n installMetricsAccessor(target(), slotName);\n },\n\n prepare() {\n // Seed only when the slot is absent or a plain configurable data\n // property. A non-configurable slot or an accessor belongs to the host.\n try {\n if (!isSlotHostLocked(target(), slotName)) seedMetricsSlot(target(), slotName);\n } catch { /* host wins */ }\n },\n\n isAvailable: () => !!slot(),\n\n snapshot() {\n const live = slot();\n return live ? { ...live } : null;\n },\n\n measure(before, after, committedComponents, commitId) {\n const delta = calculateATLDelta(before, after);\n delta.performedWorkCount = committedComponents;\n const rendered = (delta.componentRenderWithHooksCount ?? 0) + (delta.finishClassComponentCount ?? 0);\n const restarts = Math.max(0, rendered - committedComponents);\n if (committedComponents > rendered && rendered > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Avalanche] Commit ${commitId}: committedComponents (${committedComponents}) > atlTotal (${rendered}). ` +\n `This indicates a counting bug. Using 0 restarts.`\n );\n }\n // Running totals live on the slot so the next delta covers them.\n const live = slot();\n if (live) {\n live.totalRestarts = ((live.totalRestarts as number) ?? 0) + restarts;\n live.totalPerformedWork = ((live.totalPerformedWork as number) ?? 0) + committedComponents;\n }\n return { delta, restarts };\n },\n\n attach(onCommit) {\n const live = slot();\n if (!live) return false;\n const handler: SlotHandler = (_rendererID, root) => onCommit(root as CommitMetricsRoot);\n live.onCommitFiberRoot = handler;\n ourHandler = handler;\n return true;\n },\n\n isAttached() {\n const live = slot();\n return !!live && !!ourHandler && live.onCommitFiberRoot === ourHandler;\n },\n\n reattach() {\n const fresh = seedMetricsSlot(target(), slotName) as Slot;\n if (ourHandler) fresh.onCommitFiberRoot = ourHandler;\n },\n\n detach() {\n const live = slot();\n if (live && ourHandler && live.onCommitFiberRoot === ourHandler) live.onCommitFiberRoot = undefined;\n ourHandler = undefined;\n },\n };\n}\n\n/** The adapter the shipped bundle registers. */\nexport const atlCommitMetricsAdapter = createATLCommitMetricsAdapter();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["parseStackFrames", "renderedEntry", "metricsBefore", "committedComponents"]
|
|
7
7
|
}
|