{"version":3,"file":"render-optimizer.mjs","sources":["../../../../src/lib/performance/advanced/render-optimizer.ts"],"sourcesContent":["/**\n * @file Render Optimization Strategies\n * @description Advanced render optimization utilities including batching,\n * debouncing, priority scheduling, and render bailout mechanisms.\n * Designed for React 18+ concurrent features.\n *\n * Features:\n * - Render batching with priority\n * - State update coalescing\n * - Render bailout utilities\n * - Memoization helpers\n * - Virtual list optimization\n * - Component render tracking\n */\n\nimport { isProd } from '@/lib/core/config/env-helper';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Render priority levels\n */\nexport type RenderPriority = 'immediate' | 'high' | 'normal' | 'low' | 'idle';\n\n/**\n * Render batch configuration\n */\nexport interface RenderBatchConfig {\n  /** Maximum items per batch */\n  batchSize: number;\n  /** Delay between batches in ms */\n  batchDelay: number;\n  /** Priority for scheduling */\n  priority: RenderPriority;\n  /** Enable time slicing */\n  timeSlicing: boolean;\n  /** Time budget per frame in ms */\n  frameBudget: number;\n}\n\n/**\n * Render statistics\n */\nexport interface RenderStats {\n  totalRenders: number;\n  skippedRenders: number;\n  batchedUpdates: number;\n  averageRenderTime: number;\n  lastRenderTime: number;\n  renderTimes: number[];\n}\n\n/**\n * Equality comparator function\n */\nexport type EqualityFn<T> = (prev: T, next: T) => boolean;\n\n/**\n * State update function\n */\nexport type StateUpdater<T> = (prev: T) => T;\n\n/**\n * Batched update entry\n */\ninterface BatchedUpdate<T> {\n  key: string;\n  update: StateUpdater<T>;\n  priority: RenderPriority;\n  timestamp: number;\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst PRIORITY_VALUES: Record<RenderPriority, number> = {\n  immediate: 0,\n  high: 1,\n  normal: 2,\n  low: 3,\n  idle: 4,\n};\n\nconst DEFAULT_BATCH_CONFIG: RenderBatchConfig = {\n  batchSize: 10,\n  batchDelay: 16, // ~60fps\n  priority: 'normal',\n  timeSlicing: true,\n  frameBudget: 10, // 10ms per frame budget\n};\n\n// ============================================================================\n// Render Batch Manager\n// ============================================================================\n\n/**\n * Manages batched render updates with priority scheduling\n */\nexport class RenderBatchManager<T = unknown> {\n  private config: RenderBatchConfig;\n  private pendingUpdates: Map<string, BatchedUpdate<T>[]> = new Map();\n  private subscribers: Map<string, Set<(value: T) => void>> = new Map();\n  private currentValues: Map<string, T> = new Map();\n  private batchTimer: ReturnType<typeof setTimeout> | null = null;\n  private isProcessing = false;\n  private stats: RenderStats = {\n    totalRenders: 0,\n    skippedRenders: 0,\n    batchedUpdates: 0,\n    averageRenderTime: 0,\n    lastRenderTime: 0,\n    renderTimes: [],\n  };\n\n  constructor(config: Partial<RenderBatchConfig> = {}) {\n    this.config = { ...DEFAULT_BATCH_CONFIG, ...config };\n  }\n\n  /**\n   * Schedule a state update\n   */\n  scheduleUpdate(\n    key: string,\n    update: StateUpdater<T>,\n    priority: RenderPriority = this.config.priority\n  ): void {\n    const entry: BatchedUpdate<T> = {\n      key,\n      update,\n      priority,\n      timestamp: Date.now(),\n    };\n\n    const updates = this.pendingUpdates.get(key) ?? [];\n    updates.push(entry);\n    this.pendingUpdates.set(key, updates);\n    this.stats.batchedUpdates++;\n\n    this.scheduleBatchProcess();\n  }\n\n  /**\n   * Set a value directly (bypasses batching for immediate updates)\n   */\n  setImmediate(key: string, value: T): void {\n    this.currentValues.set(key, value);\n    this.notifySubscribers(key, value);\n    this.stats.totalRenders++;\n  }\n\n  /**\n   * Get current value\n   */\n  getValue(key: string): T | undefined {\n    return this.currentValues.get(key);\n  }\n\n  /**\n   * Subscribe to value changes\n   */\n  subscribe(key: string, callback: (value: T) => void): () => void {\n    const subs = this.subscribers.get(key) ?? new Set();\n    subs.add(callback);\n    this.subscribers.set(key, subs);\n\n    // Immediately notify with current value if exists\n    const currentValue = this.currentValues.get(key);\n    if (currentValue !== undefined) {\n      callback(currentValue);\n    }\n\n    return () => {\n      subs.delete(callback);\n      if (subs.size === 0) {\n        this.subscribers.delete(key);\n      }\n    };\n  }\n\n  /**\n   * Get render statistics\n   */\n  getStats(): RenderStats {\n    return { ...this.stats };\n  }\n\n  /**\n   * Reset statistics\n   */\n  resetStats(): void {\n    this.stats = {\n      totalRenders: 0,\n      skippedRenders: 0,\n      batchedUpdates: 0,\n      averageRenderTime: 0,\n      lastRenderTime: 0,\n      renderTimes: [],\n    };\n  }\n\n  /**\n   * Flush all pending updates immediately\n   */\n  flush(): void {\n    if (this.batchTimer !== null) {\n      clearTimeout(this.batchTimer);\n      this.batchTimer = null;\n    }\n    this.processBatch();\n  }\n\n  // ============================================================================\n  // Private Methods\n  // ============================================================================\n\n  private scheduleBatchProcess(): void {\n    if (this.batchTimer !== null || this.isProcessing) {\n      return;\n    }\n\n    // Get highest priority among pending updates\n    const highestPriority = this.getHighestPriority();\n\n    if (highestPriority === 'immediate') {\n      this.processBatch();\n      return;\n    }\n\n    const delay = this.getDelayForPriority(highestPriority);\n    this.batchTimer = setTimeout(() => {\n      this.batchTimer = null;\n      this.processBatch();\n    }, delay);\n  }\n\n  private getHighestPriority(): RenderPriority {\n    let highest: RenderPriority = 'idle';\n\n    for (const updates of this.pendingUpdates.values()) {\n      for (const update of updates) {\n        if (PRIORITY_VALUES[update.priority] < PRIORITY_VALUES[highest]) {\n          highest = update.priority;\n        }\n      }\n    }\n\n    return highest;\n  }\n\n  private getDelayForPriority(priority: RenderPriority): number {\n    switch (priority) {\n      case 'immediate':\n        return 0;\n      case 'high':\n        return 4;\n      case 'normal':\n        return this.config.batchDelay;\n      case 'low':\n        return this.config.batchDelay * 2;\n      case 'idle':\n        return this.config.batchDelay * 4;\n    }\n  }\n\n  private processBatch(): void {\n    if (this.isProcessing || this.pendingUpdates.size === 0) {\n      return;\n    }\n\n    this.isProcessing = true;\n    const startTime = performance.now();\n\n    try {\n      if (this.config.timeSlicing) {\n        this.processWithTimeSlicing();\n      } else {\n        this.processAllUpdates();\n      }\n    } finally {\n      this.isProcessing = false;\n      const renderTime = performance.now() - startTime;\n      this.updateRenderStats(renderTime);\n\n      // Continue processing if there are more updates\n      if (this.pendingUpdates.size > 0) {\n        this.scheduleBatchProcess();\n      }\n    }\n  }\n\n  private processWithTimeSlicing(): void {\n    const deadline = performance.now() + this.config.frameBudget;\n    let processed = 0;\n\n    for (const [key, updates] of this.pendingUpdates.entries()) {\n      if (performance.now() >= deadline) {\n        break;\n      }\n\n      this.processKeyUpdates(key, updates);\n      this.pendingUpdates.delete(key);\n      processed++;\n\n      if (processed >= this.config.batchSize) {\n        break;\n      }\n    }\n  }\n\n  private processAllUpdates(): void {\n    for (const [key, updates] of this.pendingUpdates.entries()) {\n      this.processKeyUpdates(key, updates);\n    }\n    this.pendingUpdates.clear();\n  }\n\n  private processKeyUpdates(key: string, updates: BatchedUpdate<T>[]): void {\n    if (updates.length === 0) {\n      return;\n    }\n\n    // Sort by priority and timestamp\n    updates.sort((a, b) => {\n      const priorityDiff = PRIORITY_VALUES[a.priority] - PRIORITY_VALUES[b.priority];\n      if (priorityDiff !== 0) return priorityDiff;\n      return a.timestamp - b.timestamp;\n    });\n\n    // Coalesce updates\n    let currentValue = this.currentValues.get(key);\n    for (const update of updates) {\n      currentValue = update.update(currentValue as T);\n    }\n\n    // Update and notify\n    this.currentValues.set(key, currentValue as T);\n    this.notifySubscribers(key, currentValue as T);\n    this.stats.totalRenders++;\n  }\n\n  private notifySubscribers(key: string, value: T): void {\n    const subs = this.subscribers.get(key);\n    if (subs !== undefined) {\n      subs.forEach((callback) => callback(value));\n    }\n  }\n\n  private updateRenderStats(renderTime: number): void {\n    this.stats.lastRenderTime = renderTime;\n    this.stats.renderTimes.push(renderTime);\n\n    // Keep last 100 render times\n    if (this.stats.renderTimes.length > 100) {\n      this.stats.renderTimes.shift();\n    }\n\n    this.stats.averageRenderTime =\n      this.stats.renderTimes.reduce((a, b) => a + b, 0) / this.stats.renderTimes.length;\n  }\n}\n\n// ============================================================================\n// Render Bailout Utilities\n// ============================================================================\n\n/**\n * Create a shallow equality comparator\n */\nexport function shallowEqual<T extends object>(objA: T, objB: T): boolean {\n  if (Object.is(objA, objB)) {\n    return true;\n  }\n\n  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {\n    return false;\n  }\n\n  const keysA = Object.keys(objA);\n  const keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n\n  for (const key of keysA) {\n    if (\n      !Object.prototype.hasOwnProperty.call(objB, key) ||\n      !Object.is((objA as Record<string, unknown>)[key], (objB as Record<string, unknown>)[key])\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Create a deep equality comparator\n */\nexport function deepEqual<T>(objA: T, objB: T): boolean {\n  if (Object.is(objA, objB)) {\n    return true;\n  }\n\n  if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {\n    return false;\n  }\n\n  if (Array.isArray(objA) && Array.isArray(objB)) {\n    if (objA.length !== objB.length) {\n      return false;\n    }\n    return objA.every((item, index) => deepEqual(item, objB[index]));\n  }\n\n  const keysA = Object.keys(objA);\n  const keysB = Object.keys(objB);\n\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n\n  for (const key of keysA) {\n    if (\n      !Object.prototype.hasOwnProperty.call(objB, key) ||\n      !deepEqual((objA as Record<string, unknown>)[key], (objB as Record<string, unknown>)[key])\n    ) {\n      return false;\n    }\n  }\n\n  return true;\n}\n\n/**\n * Create a memoized selector with custom equality\n */\nexport function createSelector<TInput, TOutput>(\n  selector: (input: TInput) => TOutput,\n  equalityFn: EqualityFn<TOutput> = Object.is\n): (input: TInput) => TOutput {\n  let lastInput: TInput | undefined;\n  let lastOutput: TOutput | undefined;\n  let isInitialized = false;\n\n  return (input: TInput): TOutput => {\n    if (!isInitialized || !Object.is(input, lastInput)) {\n      const newOutput = selector(input);\n\n      if (!isInitialized || lastOutput === undefined || !equalityFn(lastOutput, newOutput)) {\n        lastOutput = newOutput;\n      }\n\n      lastInput = input;\n      isInitialized = true;\n    }\n\n    return lastOutput as TOutput;\n  };\n}\n\n/**\n * Create a memoized function with LRU cache\n */\nexport function memoizeWithLRU<TArgs extends unknown[], TResult>(\n  fn: (...args: TArgs) => TResult,\n  maxSize: number = 100,\n  keyFn: (...args: TArgs) => string = (...args) => JSON.stringify(args)\n): (...args: TArgs) => TResult {\n  const cache = new Map<string, { value: TResult; timestamp: number }>();\n\n  return (...args: TArgs): TResult => {\n    const key = keyFn(...args);\n    const cached = cache.get(key);\n\n    if (cached !== undefined) {\n      // Update timestamp for LRU\n      cached.timestamp = Date.now();\n      return cached.value;\n    }\n\n    const result = fn(...args);\n\n    // Evict oldest if at capacity\n    if (cache.size >= maxSize) {\n      let oldestKey = '';\n      let oldestTime = Infinity;\n\n      for (const [k, v] of cache.entries()) {\n        if (v.timestamp < oldestTime) {\n          oldestKey = k;\n          oldestTime = v.timestamp;\n        }\n      }\n\n      cache.delete(oldestKey);\n    }\n\n    cache.set(key, { value: result, timestamp: Date.now() });\n    return result;\n  };\n}\n\n// ============================================================================\n// Virtual List Optimization\n// ============================================================================\n\n/**\n * Virtual list configuration\n */\nexport interface VirtualListConfig {\n  /** Total number of items */\n  itemCount: number;\n  /** Height of each item in pixels */\n  itemHeight: number;\n  /** Container height in pixels */\n  containerHeight: number;\n  /** Number of items to render above/below visible area */\n  overscan: number;\n}\n\n/**\n * Virtual list range\n */\nexport interface VirtualListRange {\n  startIndex: number;\n  endIndex: number;\n  offsetTop: number;\n  visibleCount: number;\n}\n\n/**\n * Calculate visible range for virtual list\n */\nexport function calculateVirtualListRange(\n  scrollTop: number,\n  config: VirtualListConfig\n): VirtualListRange {\n  const { itemCount, itemHeight, containerHeight, overscan } = config;\n\n  const visibleCount = Math.ceil(containerHeight / itemHeight);\n  const startIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);\n  const endIndex = Math.min(itemCount - 1, startIndex + visibleCount + overscan * 2);\n  const offsetTop = startIndex * itemHeight;\n\n  return {\n    startIndex,\n    endIndex,\n    offsetTop,\n    visibleCount,\n  };\n}\n\n/**\n * Create a stable item key generator\n */\nexport function createStableKeyGenerator<T>(\n  getKey: (item: T, index: number) => string\n): (items: T[]) => Map<string, number> {\n  const keyCache = new Map<string, number>();\n\n  return (items: T[]): Map<string, number> => {\n    const newKeys = new Map<string, number>();\n\n    items.forEach((item, index) => {\n      const key = getKey(item, index);\n      newKeys.set(key, index);\n    });\n\n    // Update cache\n    keyCache.clear();\n    newKeys.forEach((value, key) => keyCache.set(key, value));\n\n    return newKeys;\n  };\n}\n\n// ============================================================================\n// Component Render Tracking\n// ============================================================================\n\n/**\n * Render tracking configuration\n */\nexport interface RenderTrackingConfig {\n  /** Enable tracking */\n  enabled: boolean;\n  /** Log to console */\n  logToConsole: boolean;\n  /** Threshold for slow render warning in ms */\n  slowRenderThreshold: number;\n}\n\n/**\n * Component render info\n */\nexport interface ComponentRenderInfo {\n  componentName: string;\n  renderCount: number;\n  totalRenderTime: number;\n  averageRenderTime: number;\n  lastRenderTime: number;\n  lastRenderReason: string | null;\n}\n\nconst renderTrackingConfig: RenderTrackingConfig = {\n  enabled: !isProd(),\n  logToConsole: false,\n  slowRenderThreshold: 16, // 1 frame at 60fps\n};\n\nconst renderTracking = new Map<string, ComponentRenderInfo>();\n\n/**\n * Configure render tracking\n */\nexport function configureRenderTracking(config: Partial<RenderTrackingConfig>): void {\n  Object.assign(renderTrackingConfig, config);\n}\n\n/**\n * Track a component render\n */\nexport function trackRender(componentName: string, renderTime: number, reason?: string): void {\n  if (!renderTrackingConfig.enabled) {\n    return;\n  }\n\n  let info = renderTracking.get(componentName);\n\n  if (info === undefined) {\n    info = {\n      componentName,\n      renderCount: 0,\n      totalRenderTime: 0,\n      averageRenderTime: 0,\n      lastRenderTime: 0,\n      lastRenderReason: null,\n    };\n    renderTracking.set(componentName, info);\n  }\n\n  info.renderCount++;\n  info.totalRenderTime += renderTime;\n  info.averageRenderTime = info.totalRenderTime / info.renderCount;\n  info.lastRenderTime = renderTime;\n  info.lastRenderReason = reason ?? null;\n\n  if (renderTrackingConfig.logToConsole) {\n    const isSlowRender = renderTime > renderTrackingConfig.slowRenderThreshold;\n    const logFn = isSlowRender ? console.warn : console.log; // eslint-disable-line no-console\n    logFn(\n      `[RenderTracker] ${componentName} rendered in ${renderTime.toFixed(2)}ms`,\n      reason !== undefined ? `(reason: ${reason})` : ''\n    );\n  }\n}\n\n/**\n * Get render tracking info for a component\n */\nexport function getRenderInfo(componentName: string): ComponentRenderInfo | undefined {\n  return renderTracking.get(componentName);\n}\n\n/**\n * Get all render tracking info\n */\nexport function getAllRenderInfo(): Map<string, ComponentRenderInfo> {\n  return new Map(renderTracking);\n}\n\n/**\n * Clear render tracking data\n */\nexport function clearRenderTracking(): void {\n  renderTracking.clear();\n}\n\n/**\n * Get top slow-rendering components\n */\nexport function getSlowComponents(count: number = 10): ComponentRenderInfo[] {\n  return Array.from(renderTracking.values())\n    .sort((a, b) => b.averageRenderTime - a.averageRenderTime)\n    .slice(0, count);\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { DEFAULT_BATCH_CONFIG, PRIORITY_VALUES };\n"],"names":["PRIORITY_VALUES","DEFAULT_BATCH_CONFIG","RenderBatchManager","config","key","update","priority","entry","updates","value","callback","subs","currentValue","highestPriority","delay","highest","startTime","renderTime","deadline","processed","a","b","priorityDiff","shallowEqual","objA","objB","keysA","keysB","deepEqual","item","index","createSelector","selector","equalityFn","lastInput","lastOutput","isInitialized","input","newOutput","memoizeWithLRU","fn","maxSize","keyFn","args","cache","cached","result","oldestKey","oldestTime","k","v","calculateVirtualListRange","scrollTop","itemCount","itemHeight","containerHeight","overscan","visibleCount","startIndex","endIndex","offsetTop","createStableKeyGenerator","getKey","keyCache","items","newKeys","renderTrackingConfig","isProd","renderTracking","configureRenderTracking","getRenderInfo","componentName","getAllRenderInfo","clearRenderTracking","getSlowComponents","count"],"mappings":"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"}