{"version":3,"file":"render-tracker.mjs","sources":["../../../src/lib/performance/render-tracker.tsx"],"sourcesContent":["/**\n * @file Render Performance Tracker\n * @description Comprehensive React component render performance tracking with:\n * - Component render time tracking\n * - Re-render detection and analysis\n * - Render waterfall visualization data\n * - Wasted render detection\n * - Render phase breakdown (render vs commit)\n *\n * This module provides deep insights into React rendering performance,\n * helping identify components that may need optimization.\n *\n * @example\n * ```typescript\n * import { RenderTracker, trackRender, withRenderTracking } from '@/lib/performance';\n *\n * // Manual tracking\n * const tracker = RenderTracker.getInstance();\n * const stop = tracker.startRender('MyComponent');\n * // ... component renders ...\n * stop();\n *\n * // HOC tracking\n * const TrackedComponent = withRenderTracking(MyComponent, 'MyComponent');\n *\n * // Hook tracking (in component)\n * const { startRender, endRender } = useRenderMetrics('MyComponent');\n * ```\n */\n\nimport React from 'react';\nimport { RENDER_CONFIG, formatDuration } from '../../config/performance.config';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Render phase type\n */\nexport type RenderPhase = 'render' | 'commit' | 'layout-effect' | 'effect';\n\n/**\n * Render reason for re-renders\n */\nexport type RenderReason =\n  | 'initial'\n  | 'props-change'\n  | 'state-change'\n  | 'context-change'\n  | 'parent-render'\n  | 'hooks-change'\n  | 'force-update'\n  | 'unknown';\n\n/**\n * Single render entry\n */\nexport interface RenderEntry {\n  readonly id: string;\n  readonly componentName: string;\n  readonly componentId: string;\n  readonly phase: RenderPhase;\n  readonly duration: number;\n  readonly startTime: number;\n  readonly endTime: number;\n  readonly isInitial: boolean;\n  readonly reason: RenderReason;\n  readonly propsChanged?: string[];\n  readonly stateChanged?: string[];\n  readonly isWasted: boolean;\n  readonly parentId?: string;\n  readonly depth: number;\n  readonly timestamp: number;\n}\n\n/**\n * Component render statistics\n */\nexport interface ComponentRenderStats {\n  readonly componentName: string;\n  readonly totalRenders: number;\n  readonly initialRenders: number;\n  readonly reRenders: number;\n  readonly wastedRenders: number;\n  readonly wastedRenderRate: number;\n  readonly totalRenderTime: number;\n  readonly averageRenderTime: number;\n  readonly minRenderTime: number;\n  readonly maxRenderTime: number;\n  readonly p50RenderTime: number;\n  readonly p95RenderTime: number;\n  readonly isSlowComponent: boolean;\n  readonly lastRenderTime: number;\n  readonly rendersByReason: Record<RenderReason, number>;\n}\n\n/**\n * Render waterfall entry for visualization\n */\nexport interface RenderWaterfallEntry {\n  readonly id: string;\n  readonly componentName: string;\n  readonly startOffset: number;\n  readonly duration: number;\n  readonly depth: number;\n  readonly phase: RenderPhase;\n  readonly isWasted: boolean;\n  readonly children: RenderWaterfallEntry[];\n}\n\n/**\n * Render interaction (user interaction leading to renders)\n */\nexport interface RenderInteraction {\n  readonly id: string;\n  readonly name: string;\n  readonly startTime: number;\n  readonly endTime: number;\n  readonly duration: number;\n  readonly renderCount: number;\n  readonly componentCount: number;\n  readonly wastedRenderCount: number;\n  readonly renders: RenderEntry[];\n  readonly timestamp: number;\n}\n\n/**\n * Render tracker configuration\n */\nexport interface RenderTrackerConfig {\n  /** Maximum render history entries */\n  readonly maxHistorySize?: number;\n  /** Slow component threshold (ms) */\n  readonly slowThreshold?: number;\n  /** Wasted render threshold (ms) - renders under this are considered wasted if no visible change */\n  readonly wastedThreshold?: number;\n  /** Enable profiling in production */\n  readonly enableInProduction?: boolean;\n  /** Sample rate (0-1) */\n  readonly sampleRate?: number;\n  /** Callback on slow render */\n  readonly onSlowRender?: (entry: RenderEntry) => void;\n  /** Callback on wasted render */\n  readonly onWastedRender?: (entry: RenderEntry) => void;\n  /** Enable debug logging */\n  readonly debug?: boolean;\n}\n\n/**\n * Active render context for tracking hierarchies\n */\ninterface ActiveRender {\n  readonly id: string;\n  readonly componentName: string;\n  readonly componentId: string;\n  readonly startTime: number;\n  readonly phase: RenderPhase;\n  readonly isInitial: boolean;\n  readonly parentId?: string;\n  readonly depth: number;\n}\n\n/**\n * Component instance tracking\n */\ninterface ComponentInstance {\n  readonly componentId: string;\n  readonly componentName: string;\n  readonly renderCount: number;\n  readonly lastRenderTime: number;\n  readonly lastProps?: Record<string, unknown>;\n  readonly lastState?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst DEFAULT_CONFIG: Required<RenderTrackerConfig> = {\n  maxHistorySize: 1000,\n  slowThreshold: RENDER_CONFIG.slowComponentThreshold,\n  wastedThreshold: RENDER_CONFIG.wastedRenderThreshold,\n  enableInProduction: RENDER_CONFIG.enableProdProfiling,\n  sampleRate: RENDER_CONFIG.sampleRate,\n  onSlowRender: () => {},\n  onWastedRender: () => {},\n  debug: false,\n};\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Generate unique ID\n */\nfunction generateId(): string {\n  return `render_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * Generate component instance ID\n */\nfunction generateComponentId(componentName: string): string {\n  return `${componentName}_${Math.random().toString(36).substr(2, 6)}`;\n}\n\n/**\n * Calculate percentile from sorted array\n */\nfunction percentile(sortedArr: number[], p: number): number {\n  if (sortedArr.length === 0) return 0;\n  const index = Math.ceil((p / 100) * sortedArr.length) - 1;\n  const safeIndex = Math.max(0, Math.min(index, sortedArr.length - 1));\n  const value = sortedArr[safeIndex];\n  return value ?? 0;\n}\n\n/**\n * Check if we should sample this render\n */\nfunction shouldSample(sampleRate: number): boolean {\n  return Math.random() < sampleRate;\n}\n\n/**\n * Deep compare objects to detect changes\n */\nfunction getChangedKeys(\n  prev: Record<string, unknown> | undefined,\n  next: Record<string, unknown> | undefined\n): string[] {\n  if (prev === undefined || prev === null || next === undefined || next === null) return [];\n\n  const changed: string[] = [];\n  const allKeys = new Set([...Object.keys(prev), ...Object.keys(next)]);\n\n  allKeys.forEach((key) => {\n    if (prev[key] !== next[key]) {\n      changed.push(key);\n    }\n  });\n\n  return changed;\n}\n\n// ============================================================================\n// Render Tracker Class\n// ============================================================================\n\n/**\n * Comprehensive render performance tracker\n */\nexport class RenderTracker {\n  private static instance: RenderTracker | null = null;\n\n  private readonly config: Required<RenderTrackerConfig>;\n  private readonly renderHistory: RenderEntry[] = [];\n  private readonly activeRenders: Map<string, ActiveRender> = new Map();\n  private readonly componentInstances: Map<string, ComponentInstance> = new Map();\n  private readonly interactions: RenderInteraction[] = [];\n\n  private currentInteraction: {\n    id: string;\n    name: string;\n    startTime: number;\n    renders: RenderEntry[];\n  } | null = null;\n\n  private renderStack: string[] = [];\n  private isEnabled = true;\n  private readonly isProd = false;\n\n  /**\n   * Private constructor for singleton pattern\n   */\n  private constructor(config: RenderTrackerConfig = {}) {\n    this.config = { ...DEFAULT_CONFIG, ...config };\n\n    // Disable in production unless explicitly enabled\n    if (this.isProd && !this.config.enableInProduction) {\n      this.isEnabled = false;\n    }\n  }\n\n  /**\n   * Get singleton instance\n   */\n  public static getInstance(config?: RenderTrackerConfig): RenderTracker {\n    RenderTracker.instance ??= new RenderTracker(config);\n    return RenderTracker.instance;\n  }\n\n  /**\n   * Reset singleton instance (for testing)\n   */\n  public static resetInstance(): void {\n    RenderTracker.instance = null;\n  }\n\n  // ==========================================================================\n  // Render Tracking\n  // ==========================================================================\n\n  /**\n   * Start tracking a render\n   */\n  public startRender(\n    componentName: string,\n    options: {\n      componentId?: string;\n      phase?: RenderPhase;\n      isInitial?: boolean;\n      props?: Record<string, unknown>;\n      state?: Record<string, unknown>;\n    } = {}\n  ): () => RenderEntry | null {\n    if (!this.isEnabled || !shouldSample(this.config.sampleRate)) {\n      return () => null;\n    }\n\n    const {\n      componentId = this.getOrCreateComponentId(componentName),\n      phase = 'render',\n      isInitial = false,\n      props,\n      state,\n    } = options;\n\n    const id = generateId();\n    const parentId = this.renderStack[this.renderStack.length - 1];\n    const depth = this.renderStack.length;\n\n    const activeRender: ActiveRender = {\n      id,\n      componentName,\n      componentId,\n      startTime: performance.now(),\n      phase,\n      isInitial,\n      parentId,\n      depth,\n    };\n\n    this.activeRenders.set(id, activeRender);\n    this.renderStack.push(id);\n\n    // Store props/state for change detection\n    const instance = this.componentInstances.get(componentId);\n    const propsChanged = props ? getChangedKeys(instance?.lastProps, props) : undefined;\n    const stateChanged = state ? getChangedKeys(instance?.lastState, state) : undefined;\n\n    // Return stop function\n    return () => this.endRender(id, { propsChanged, stateChanged, props, state });\n  }\n\n  /**\n   * Start tracking an interaction (e.g., click, input)\n   */\n  public startInteraction(name: string): () => RenderInteraction | null {\n    if (!this.isEnabled) {\n      return () => null;\n    }\n\n    this.currentInteraction = {\n      id: generateId(),\n      name,\n      startTime: performance.now(),\n      renders: [],\n    };\n\n    return () => this.endInteraction();\n  }\n\n  /**\n   * Get render statistics for a component\n   */\n  public getComponentStats(componentName: string): ComponentRenderStats | null {\n    const renders = this.renderHistory.filter((r) => r.componentName === componentName);\n    if (renders.length === 0) return null;\n\n    const durations = renders.map((r) => r.duration).sort((a, b) => a - b);\n    const totalTime = durations.reduce((sum, d) => sum + d, 0);\n    const wastedCount = renders.filter((r) => r.isWasted).length;\n    const initialCount = renders.filter((r) => r.isInitial).length;\n\n    const rendersByReason: Record<RenderReason, number> = {\n      initial: 0,\n      'props-change': 0,\n      'state-change': 0,\n      'context-change': 0,\n      'parent-render': 0,\n      'hooks-change': 0,\n      'force-update': 0,\n      unknown: 0,\n    };\n\n    renders.forEach((r) => {\n      rendersByReason[r.reason]++;\n    });\n\n    const minDuration = durations[0] ?? 0;\n    const maxDuration = durations[durations.length - 1] ?? 0;\n    const lastRender = renders[renders.length - 1];\n    const lastDuration = lastRender?.duration ?? 0;\n\n    return {\n      componentName,\n      totalRenders: renders.length,\n      initialRenders: initialCount,\n      reRenders: renders.length - initialCount,\n      wastedRenders: wastedCount,\n      wastedRenderRate: (wastedCount / renders.length) * 100,\n      totalRenderTime: totalTime,\n      averageRenderTime: totalTime / renders.length,\n      minRenderTime: minDuration,\n      maxRenderTime: maxDuration,\n      p50RenderTime: percentile(durations, 50),\n      p95RenderTime: percentile(durations, 95),\n      isSlowComponent: percentile(durations, 50) > this.config.slowThreshold,\n      lastRenderTime: lastDuration,\n      rendersByReason,\n    };\n  }\n\n  /**\n   * Get all component statistics\n   */\n  public getAllComponentStats(): ComponentRenderStats[] {\n    const componentNames = new Set(this.renderHistory.map((r) => r.componentName));\n    const stats: ComponentRenderStats[] = [];\n\n    componentNames.forEach((name) => {\n      const stat = this.getComponentStats(name);\n      if (stat) stats.push(stat);\n    });\n\n    // Sort by total render time (most expensive first)\n    return stats.sort((a, b) => b.totalRenderTime - a.totalRenderTime);\n  }\n\n  /**\n   * Get slow components\n   */\n  public getSlowComponents(): ComponentRenderStats[] {\n    return this.getAllComponentStats().filter((s) => s.isSlowComponent);\n  }\n\n  /**\n   * Get components with wasted renders\n   */\n  public getWastedRenderComponents(): ComponentRenderStats[] {\n    return this.getAllComponentStats()\n      .filter((s) => s.wastedRenders > 0)\n      .sort((a, b) => b.wastedRenderRate - a.wastedRenderRate);\n  }\n\n  // ==========================================================================\n  // Interaction Tracking\n  // ==========================================================================\n\n  /**\n   * Build render waterfall for visualization\n   */\n  public buildWaterfall(\n    options: {\n      interactionId?: string;\n      startTime?: number;\n      endTime?: number;\n    } = {}\n  ): RenderWaterfallEntry[] {\n    let renders = [...this.renderHistory];\n\n    // Filter by interaction if specified\n    const { interactionId } = options;\n    if (interactionId !== undefined && interactionId !== null && interactionId !== '') {\n      const interaction = this.interactions.find((i) => i.id === interactionId);\n      if (interaction !== undefined && interaction !== null) {\n        // eslint-disable-next-line prefer-destructuring -- reassigning existing variable\n        renders = interaction.renders;\n      }\n    }\n\n    // Filter by time range\n    if (options.startTime !== undefined) {\n      const {startTime} = options;\n      renders = renders.filter((r) => r.startTime >= startTime);\n    }\n    if (options.endTime !== undefined) {\n      const {endTime} = options;\n      renders = renders.filter((r) => r.endTime <= endTime);\n    }\n\n    if (renders.length === 0) return [];\n\n    // Find root renders (no parent or parent not in list)\n    const renderIds = new Set(renders.map((r) => r.id));\n    const baseTime = renders.reduce((min, r) => Math.min(min, r.startTime), Infinity);\n\n    // Build tree structure\n    const buildEntry = (render: RenderEntry): RenderWaterfallEntry => {\n      const children = renders\n        .filter((r) => r.parentId === render.id)\n        .map(buildEntry);\n\n      return {\n        id: render.id,\n        componentName: render.componentName,\n        startOffset: render.startTime - baseTime,\n        duration: render.duration,\n        depth: render.depth,\n        phase: render.phase,\n        isWasted: render.isWasted,\n        children,\n      };\n    };\n\n    // Get root entries\n    const rootRenders = renders.filter(\n      (r) => r.parentId === undefined || !renderIds.has(r.parentId)\n    );\n\n    return rootRenders.map(buildEntry);\n  }\n\n  /**\n   * Export waterfall as JSON for visualization tools\n   */\n  public exportWaterfallJson(options?: Parameters<typeof this.buildWaterfall>[0]): string {\n    return JSON.stringify(this.buildWaterfall(options), null, 2);\n  }\n\n  // ==========================================================================\n  // Statistics & Analysis\n  // ==========================================================================\n\n  /**\n   * Get render history\n   */\n  public getHistory(): RenderEntry[] {\n    return [...this.renderHistory];\n  }\n\n  /**\n   * Get recent renders\n   */\n  public getRecentRenders(count: number = 50): RenderEntry[] {\n    return this.renderHistory.slice(-count);\n  }\n\n  /**\n   * Get interactions\n   */\n  public getInteractions(): RenderInteraction[] {\n    return [...this.interactions];\n  }\n\n  /**\n   * Clear all history\n   */\n  public clear(): void {\n    this.renderHistory.length = 0;\n    this.interactions.length = 0;\n    this.componentInstances.clear();\n    this.log('History cleared');\n  }\n\n  // ==========================================================================\n  // Waterfall Visualization\n  // ==========================================================================\n\n  /**\n   * Enable tracking\n   */\n  public enable(): void {\n    this.isEnabled = true;\n    this.log('Tracking enabled');\n  }\n\n  /**\n   * Disable tracking\n   */\n  public disable(): void {\n    this.isEnabled = false;\n    this.log('Tracking disabled');\n  }\n\n  // ==========================================================================\n  // History & Management\n  // ==========================================================================\n\n  /**\n   * Check if tracking is enabled\n   */\n  public isTrackingEnabled(): boolean {\n    return this.isEnabled;\n  }\n\n  /**\n   * Generate render performance report\n   */\n  public generateReport(): string {\n    const stats = this.getAllComponentStats();\n    const slowComponents = this.getSlowComponents();\n    const wastedComponents = this.getWastedRenderComponents();\n\n    const totalRenders = this.renderHistory.length;\n    const totalWasted = this.renderHistory.filter((r) => r.isWasted).length;\n    const wastedRate = totalRenders > 0 ? (totalWasted / totalRenders) * 100 : 0;\n\n    const lines = [\n      '='.repeat(60),\n      'RENDER PERFORMANCE REPORT',\n      '='.repeat(60),\n      '',\n      `Generated: ${new Date().toISOString()}`,\n      `Total Renders Tracked: ${totalRenders}`,\n      `Unique Components: ${stats.length}`,\n      `Wasted Render Rate: ${wastedRate.toFixed(1)}%`,\n      '',\n      '--- Slow Components ---',\n      '',\n    ];\n\n    if (slowComponents.length === 0) {\n      lines.push('  No slow components detected');\n    } else {\n      slowComponents.slice(0, 10).forEach((s) => {\n        lines.push(\n          `  - ${s.componentName}: avg ${formatDuration(s.averageRenderTime)}, ` +\n          `p95 ${formatDuration(s.p95RenderTime)}`\n        );\n      });\n    }\n\n    lines.push('');\n    lines.push('--- Components with Wasted Renders ---');\n    lines.push('');\n\n    if (wastedComponents.length === 0) {\n      lines.push('  No wasted renders detected');\n    } else {\n      wastedComponents.slice(0, 10).forEach((s) => {\n        lines.push(\n          `  - ${s.componentName}: ${s.wastedRenders} wasted (${s.wastedRenderRate.toFixed(1)}%)`\n        );\n      });\n    }\n\n    lines.push('');\n    lines.push('--- Top 10 Components by Render Time ---');\n    lines.push('');\n\n    stats.slice(0, 10).forEach((s, i) => {\n      lines.push(\n        `  ${i + 1}. ${s.componentName}: ${formatDuration(s.totalRenderTime)} total, ` +\n        `${s.totalRenders} renders`\n      );\n    });\n\n    lines.push('');\n    lines.push('='.repeat(60));\n\n    return lines.join('\\n');\n  }\n\n  /**\n   * End tracking a render\n   */\n  private endRender(\n    renderId: string,\n    options: {\n      propsChanged?: string[];\n      stateChanged?: string[];\n      props?: Record<string, unknown>;\n      state?: Record<string, unknown>;\n    } = {}\n  ): RenderEntry | null {\n    const activeRender = this.activeRenders.get(renderId);\n    if (activeRender === undefined) return null;\n\n    const endTime = performance.now();\n    const duration = endTime - activeRender.startTime;\n\n    // Pop from render stack\n    const stackIndex = this.renderStack.indexOf(renderId);\n    if (stackIndex !== -1) {\n      this.renderStack.splice(stackIndex, 1);\n    }\n\n    // Determine render reason\n    const reason = this.determineRenderReason(\n      activeRender,\n      options.propsChanged,\n      options.stateChanged\n    );\n\n    // Detect wasted render\n    const isWasted = this.isWastedRender(duration, reason, options.propsChanged, options.stateChanged);\n\n    const entry: RenderEntry = {\n      id: renderId,\n      componentName: activeRender.componentName,\n      componentId: activeRender.componentId,\n      phase: activeRender.phase,\n      duration,\n      startTime: activeRender.startTime,\n      endTime,\n      isInitial: activeRender.isInitial,\n      reason,\n      propsChanged: options.propsChanged,\n      stateChanged: options.stateChanged,\n      isWasted,\n      parentId: activeRender.parentId,\n      depth: activeRender.depth,\n      timestamp: Date.now(),\n    };\n\n    // Update component instance\n    this.updateComponentInstance(activeRender.componentId, activeRender.componentName, {\n      props: options.props,\n      state: options.state,\n      renderTime: duration,\n    });\n\n    // Add to history\n    this.renderHistory.push(entry);\n    this.trimHistory();\n\n    // Add to current interaction if active\n    if (this.currentInteraction !== null) {\n      this.currentInteraction.renders.push(entry);\n    }\n\n    // Callbacks\n    if (duration > this.config.slowThreshold) {\n      this.config.onSlowRender(entry);\n      this.log(`Slow render: ${activeRender.componentName} (${formatDuration(duration)})`);\n    }\n\n    if (isWasted) {\n      this.config.onWastedRender(entry);\n      this.log(`Wasted render: ${activeRender.componentName}`);\n    }\n\n    // Cleanup\n    this.activeRenders.delete(renderId);\n\n    return entry;\n  }\n\n  /**\n   * Determine the reason for a render\n   */\n  private determineRenderReason(\n    activeRender: ActiveRender,\n    propsChanged?: string[],\n    stateChanged?: string[]\n  ): RenderReason {\n    if (activeRender.isInitial) return 'initial';\n    if (propsChanged !== undefined && propsChanged.length > 0) return 'props-change';\n    if (stateChanged !== undefined && stateChanged.length > 0) return 'state-change';\n    if (activeRender.parentId !== undefined) return 'parent-render';\n    return 'unknown';\n  }\n\n  /**\n   * Detect if a render was wasted (no meaningful work done)\n   */\n  private isWastedRender(\n    duration: number,\n    reason: RenderReason,\n    propsChanged?: string[],\n    stateChanged?: string[]\n  ): boolean {\n    // Initial renders are never wasted\n    if (reason === 'initial') return false;\n\n    // Very fast renders with no detected changes are likely wasted\n    if (duration < this.config.wastedThreshold) {\n      if (reason === 'parent-render' || reason === 'unknown') {\n        return true;\n      }\n      // Re-render with no props/state changes\n      if ((propsChanged === undefined || propsChanged.length === 0) &&\n          (stateChanged === undefined || stateChanged.length === 0)) {\n        return true;\n      }\n    }\n\n    return false;\n  }\n\n  /**\n   * Get or create component instance ID\n   */\n  private getOrCreateComponentId(componentName: string): string {\n    // In a real implementation, this would use React fiber to get stable IDs\n    // For now, we generate a simple ID\n    return generateComponentId(componentName);\n  }\n\n  /**\n   * Update component instance tracking\n   */\n  private updateComponentInstance(\n    componentId: string,\n    componentName: string,\n    data: {\n      props?: Record<string, unknown>;\n      state?: Record<string, unknown>;\n      renderTime: number;\n    }\n  ): void {\n    const existing = this.componentInstances.get(componentId);\n\n    this.componentInstances.set(componentId, {\n      componentId,\n      componentName,\n      renderCount: (existing?.renderCount ?? 0) + 1,\n      lastRenderTime: data.renderTime,\n      lastProps: data.props,\n      lastState: data.state,\n    });\n  }\n\n  // ==========================================================================\n  // Reporting\n  // ==========================================================================\n\n  /**\n   * End tracking an interaction\n   */\n  private endInteraction(): RenderInteraction | null {\n    if (this.currentInteraction === null) return null;\n\n    const endTime = performance.now();\n    const { id, name, startTime, renders } = this.currentInteraction;\n\n    const uniqueComponents = new Set(renders.map((r) => r.componentName));\n    const wastedCount = renders.filter((r) => r.isWasted).length;\n\n    const interaction: RenderInteraction = {\n      id,\n      name,\n      startTime,\n      endTime,\n      duration: endTime - startTime,\n      renderCount: renders.length,\n      componentCount: uniqueComponents.size,\n      wastedRenderCount: wastedCount,\n      renders: [...renders],\n      timestamp: Date.now(),\n    };\n\n    this.interactions.push(interaction);\n    this.trimInteractions();\n\n    this.currentInteraction = null;\n\n    this.log(\n      `Interaction \"${name}\": ${renders.length} renders, ` +\n      `${uniqueComponents.size} components, ${formatDuration(interaction.duration)}`\n    );\n\n    return interaction;\n  }\n\n  // ==========================================================================\n  // Utilities\n  // ==========================================================================\n\n  /**\n   * Trim history to max size\n   */\n  private trimHistory(): void {\n    if (this.renderHistory.length > this.config.maxHistorySize) {\n      this.renderHistory.splice(0, this.renderHistory.length - this.config.maxHistorySize);\n    }\n  }\n\n  /**\n   * Trim interactions to reasonable size\n   */\n  private trimInteractions(): void {\n    if (this.interactions.length > 100) {\n      this.interactions.splice(0, this.interactions.length - 100);\n    }\n  }\n\n  /**\n   * Debug logging\n   */\n  private log(message: string, ...args: unknown[]): void {\n    if (this.config.debug) {\n      console.info(`[RenderTracker] ${message}`, ...args);\n    }\n  }\n}\n\n// ============================================================================\n// Convenience Functions\n// ============================================================================\n\n/**\n * Get the singleton RenderTracker instance\n */\nexport function getRenderTracker(config?: RenderTrackerConfig): RenderTracker {\n  return RenderTracker.getInstance(config);\n}\n\n/**\n * Track a render (convenience function)\n */\nexport function trackRender(\n  componentName: string,\n  options?: Parameters<RenderTracker['startRender']>[1]\n): ReturnType<RenderTracker['startRender']> {\n  return getRenderTracker().startRender(componentName, options);\n}\n\n/**\n * Track an interaction (convenience function)\n */\nexport function trackInteraction(\n  name: string\n): ReturnType<RenderTracker['startInteraction']> {\n  return getRenderTracker().startInteraction(name);\n}\n\n// ============================================================================\n// React HOC for Render Tracking\n// ============================================================================\n\n/**\n * HOC that wraps a component with render tracking\n *\n * @example\n * ```tsx\n * const TrackedMyComponent = withRenderTracking(MyComponent, 'MyComponent');\n * ```\n */\nexport function withRenderTracking<P extends object>(\n  Component: React.ComponentType<P>,\n  componentName: string\n): React.ComponentType<P> {\n  const tracker = getRenderTracker();\n\n  const TrackedComponent = (props: P): React.ReactElement => {\n    const stopTracking = tracker.startRender(componentName, {\n      props: props as Record<string, unknown>,\n    });\n\n    // We need to use useEffect to call stopTracking after render\n    // This is a simplified version - in production you'd want to use\n    // React's Profiler API or a more sophisticated approach\n\n    // For now, we'll stop tracking immediately after render phase\n    // A real implementation would hook into React's profiler\n    void Promise.resolve().then(stopTracking);\n\n    return <Component {...props} />;\n  };\n\n  TrackedComponent.displayName = `WithRenderTracking(${componentName})`;\n\n  return TrackedComponent as React.ComponentType<P>;\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n// Note: We can't use JSX here without importing React\n// The withRenderTracking function above is a template - actual implementation\n// would need to be in a .tsx file\n"],"names":["DEFAULT_CONFIG","RENDER_CONFIG","generateId","generateComponentId","componentName","percentile","sortedArr","p","index","safeIndex","shouldSample","sampleRate","getChangedKeys","prev","next","changed","key","RenderTracker","config","options","componentId","phase","isInitial","props","state","id","parentId","depth","activeRender","instance","propsChanged","stateChanged","name","renders","r","durations","a","b","totalTime","sum","d","wastedCount","initialCount","rendersByReason","minDuration","maxDuration","lastDuration","componentNames","stats","stat","s","interactionId","interaction","i","startTime","endTime","renderIds","baseTime","min","buildEntry","render","children","count","slowComponents","wastedComponents","totalRenders","totalWasted","wastedRate","lines","formatDuration","renderId","duration","stackIndex","reason","isWasted","entry","data","existing","uniqueComponents","message","args","getRenderTracker","trackRender","trackInteraction","withRenderTracking","Component","tracker","TrackedComponent","stopTracking","jsx"],"mappings":"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"}