{"version":3,"file":"useLongTaskDetector.mjs","sources":["../../../../src/lib/performance/hooks/useLongTaskDetector.ts"],"sourcesContent":["/**\n * @file useLongTaskDetector Hook\n * @description React hook for detecting and responding to long tasks.\n *\n * Long tasks (>50ms) block the main thread and impact user interactivity.\n * This hook provides components with awareness of long tasks, enabling\n * adaptive behavior to improve perceived performance.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const {\n *     longTasks,\n *     isBlocked,\n *     totalBlockingTime,\n *     onLongTask\n *   } = useLongTaskDetector({\n *     onLongTask: (task) => {\n *       analytics.track('long_task', { duration: task.duration });\n *     }\n *   });\n *\n *   // Show loading indicator during blocking\n *   if (isBlocked) {\n *     return <Skeleton />;\n *   }\n *\n *   return <ExpensiveComponent />;\n * }\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { getPerformanceMonitor, type LongTaskEntry, type PerformanceMonitor, } from '../performance-monitor';\nimport { LONG_TASK_CONFIG } from '../../../config/performance.config';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Long task summary statistics\n */\nexport interface LongTaskStats {\n  /** Total number of long tasks */\n  readonly count: number;\n  /** Number of critical long tasks (>100ms) */\n  readonly criticalCount: number;\n  /** Total blocking time (ms) */\n  readonly totalBlockingTime: number;\n  /** Average long task duration (ms) */\n  readonly averageDuration: number;\n  /** Maximum long task duration (ms) */\n  readonly maxDuration: number;\n  /** Recent long task rate (tasks per minute) */\n  readonly ratePerMinute: number;\n  /** Time since last long task (ms) */\n  readonly timeSinceLastTask: number | null;\n}\n\n/**\n * Hook options\n */\nexport interface UseLongTaskDetectorOptions {\n  /** Long task threshold (ms) - default 50ms */\n  readonly threshold?: number;\n  /** Critical threshold (ms) - default 100ms */\n  readonly criticalThreshold?: number;\n  /** Maximum tasks to keep in history */\n  readonly maxHistory?: number;\n  /** Callback when long task is detected */\n  readonly onLongTask?: (task: LongTaskEntry) => void;\n  /** Callback when critical long task is detected */\n  readonly onCriticalTask?: (task: LongTaskEntry) => void;\n  /** Time window for \"isBlocked\" detection (ms) */\n  readonly blockDetectionWindow?: number;\n  /** Enable debug logging */\n  readonly debug?: boolean;\n}\n\n/**\n * Hook return value\n */\nexport interface UseLongTaskDetectorReturn {\n  /** Recent long tasks */\n  readonly longTasks: LongTaskEntry[];\n  /** Long task statistics */\n  readonly stats: LongTaskStats;\n  /** Whether main thread is currently blocked */\n  readonly isBlocked: boolean;\n  /** Whether we're in a high-blocking period */\n  readonly isHighBlocking: boolean;\n  /** Total blocking time */\n  readonly totalBlockingTime: number;\n  /** Most recent long task */\n  readonly lastTask: LongTaskEntry | null;\n  /** Register callback for long tasks */\n  readonly onLongTask: (callback: (task: LongTaskEntry) => void) => () => void;\n  /** Clear long task history */\n  readonly clearHistory: () => void;\n  /** Check if component should defer rendering */\n  readonly shouldDefer: () => boolean;\n  /** Get attribution for last task */\n  readonly getLastTaskAttribution: () => string | null;\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\n/**\n * Hook for long task detection\n */\nexport function useLongTaskDetector(\n  options: UseLongTaskDetectorOptions = {}\n): UseLongTaskDetectorReturn {\n  const {\n    threshold = LONG_TASK_CONFIG.threshold,\n    maxHistory = LONG_TASK_CONFIG.historyBufferSize,\n    onLongTask,\n    onCriticalTask,\n    blockDetectionWindow = 100,\n    debug = false,\n  } = options;\n\n  // Get monitor instance\n  const monitorRef = useRef<PerformanceMonitor | null>(null);\n  monitorRef.current ??= getPerformanceMonitor({ debug });\n  const monitor = monitorRef.current;\n\n  // State\n  const [longTasks, setLongTasks] = useState<LongTaskEntry[]>([]);\n  const [isBlocked, setIsBlocked] = useState(false);\n  const [lastTaskTime, setLastTaskTime] = useState<number | null>(null);\n\n  // Callbacks ref for stable identity\n  const callbacksRef = useRef<Set<(task: LongTaskEntry) => void>>(new Set());\n\n  // Block detection timer\n  const blockTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n  // Subscribe to long tasks from monitor\n  useEffect(() => {\n    // Ensure monitor is running\n    if (!monitor.isMonitoring()) {\n      monitor.start();\n    }\n\n    const unsubscribe = monitor.on<LongTaskEntry>('longTask', (task) => {\n      // Update state\n      setLongTasks((prev) => {\n        const updated = [...prev, task];\n        return updated.slice(-maxHistory);\n      });\n\n      setLastTaskTime(Date.now());\n\n      // Set blocked state\n      setIsBlocked(true);\n      if (blockTimerRef.current) {\n        clearTimeout(blockTimerRef.current);\n      }\n      blockTimerRef.current = setTimeout(() => {\n        setIsBlocked(false);\n      }, blockDetectionWindow);\n\n      // Notify callbacks\n      onLongTask?.(task);\n      callbacksRef.current.forEach((cb) => cb(task));\n\n      // Check for critical\n      if (task.isCritical) {\n        onCriticalTask?.(task);\n      }\n\n      if (debug) {\n        // eslint-disable-next-line no-console\n        console.log(\n          `[useLongTaskDetector] Long task detected: ${task.duration.toFixed(2)}ms`,\n          task.isCritical ? '(CRITICAL)' : ''\n        );\n      }\n    });\n\n    return () => {\n      unsubscribe();\n      if (blockTimerRef.current) {\n        clearTimeout(blockTimerRef.current);\n      }\n    };\n  }, [monitor, maxHistory, blockDetectionWindow, onLongTask, onCriticalTask, debug]);\n\n  // Calculate statistics\n  const stats = useMemo<LongTaskStats>(() => {\n    if (longTasks.length === 0) {\n      return {\n        count: 0,\n        criticalCount: 0,\n        totalBlockingTime: 0,\n        averageDuration: 0,\n        maxDuration: 0,\n        ratePerMinute: 0,\n        timeSinceLastTask: null,\n      };\n    }\n\n    const durations = longTasks.map((t) => t.duration);\n    const criticalTasks = longTasks.filter((t) => t.isCritical);\n    const totalBlocking = durations.reduce((sum, d) => sum + Math.max(0, d - threshold), 0);\n\n    // Calculate rate (tasks in last minute)\n    const oneMinuteAgo = Date.now() - 60000;\n    const recentTasks = longTasks.filter((t) => t.timestamp >= oneMinuteAgo);\n\n    return {\n      count: longTasks.length,\n      criticalCount: criticalTasks.length,\n      totalBlockingTime: totalBlocking,\n      averageDuration: durations.reduce((a, b) => a + b, 0) / durations.length,\n      maxDuration: Math.max(...durations),\n      ratePerMinute: recentTasks.length,\n      timeSinceLastTask:\n        lastTaskTime !== null && lastTaskTime !== 0 ? Date.now() - lastTaskTime : null,\n    };\n  }, [longTasks, threshold, lastTaskTime]);\n\n  // Calculate if high blocking period\n  const isHighBlocking = useMemo(() => {\n    // High blocking if more than 5 long tasks in the last 30 seconds\n    const thirtySecondsAgo = Date.now() - 30000;\n    const recentTasks = longTasks.filter((t) => t.timestamp >= thirtySecondsAgo);\n    return recentTasks.length > 5;\n  }, [longTasks]);\n\n  // Get last task\n  const lastTask = useMemo((): LongTaskEntry | null => {\n    return longTasks.length > 0 ? (longTasks[longTasks.length - 1] ?? null) : null;\n  }, [longTasks]);\n\n  // Register callback\n  const registerCallback = useCallback((callback: (task: LongTaskEntry) => void): (() => void) => {\n    callbacksRef.current.add(callback);\n    return () => {\n      callbacksRef.current.delete(callback);\n    };\n  }, []);\n\n  // Clear history\n  const clearHistory = useCallback(() => {\n    setLongTasks([]);\n    setLastTaskTime(null);\n  }, []);\n\n  // Should defer rendering\n  const shouldDefer = useCallback((): boolean => {\n    // Defer if currently blocked or in high blocking period\n    return isBlocked || isHighBlocking;\n  }, [isBlocked, isHighBlocking]);\n\n  // Get attribution for last task\n  const getLastTaskAttribution = useCallback((): string | null => {\n    if (lastTask === null || lastTask.attribution.length === 0) {\n      return null;\n    }\n\n    const [attr] = lastTask.attribution;\n    if (\n      attr?.containerSrc !== undefined &&\n      attr.containerSrc !== null &&\n      attr.containerSrc !== ''\n    ) {\n      return attr.containerSrc;\n    }\n    if (\n      attr?.containerName !== undefined &&\n      attr.containerName !== null &&\n      attr.containerName !== ''\n    ) {\n      return attr.containerName;\n    }\n    return attr?.name ?? null;\n  }, [lastTask]);\n\n  return {\n    longTasks,\n    stats,\n    isBlocked,\n    isHighBlocking,\n    totalBlockingTime: stats.totalBlockingTime,\n    lastTask,\n    onLongTask: registerCallback,\n    clearHistory,\n    shouldDefer,\n    getLastTaskAttribution,\n  };\n}\n\n// ============================================================================\n// Utility Hooks\n// ============================================================================\n\n/**\n * Hook to defer rendering during long tasks\n */\nexport function useDeferredRender<T>(value: T, options: UseLongTaskDetectorOptions = {}): T {\n  const { shouldDefer } = useLongTaskDetector(options);\n  const [deferredValue, setDeferredValue] = useState(value);\n\n  useEffect(() => {\n    if (!shouldDefer()) {\n      setTimeout(() => {\n        setDeferredValue(value);\n      }, 0);\n      return;\n    } else {\n      // Use requestIdleCallback to update when idle\n      const id = requestIdleCallback(() => {\n        setDeferredValue(value);\n      }) as unknown as number;\n      return () => cancelIdleCallback(id);\n    }\n  }, [value, shouldDefer]);\n\n  return deferredValue;\n}\n\n/**\n * Hook to track blocking time for a specific operation\n */\nexport function useBlockingTimeTracker(): {\n  startTracking: () => void;\n  stopTracking: () => number;\n  blockingTime: number;\n} {\n  const [blockingTime, setBlockingTime] = useState(0);\n  const startTimeRef = useRef<number | null>(null);\n  const tasksDuringOperationRef = useRef<LongTaskEntry[]>([]);\n\n  const { onLongTask } = useLongTaskDetector();\n\n  useEffect(() => {\n\n    return onLongTask((task) => {\n      if (startTimeRef.current !== null) {\n        tasksDuringOperationRef.current.push(task);\n      }\n    });\n  }, [onLongTask]);\n\n  const startTracking = useCallback(() => {\n    startTimeRef.current = performance.now();\n    tasksDuringOperationRef.current = [];\n  }, []);\n\n  const stopTracking = useCallback(() => {\n    if (startTimeRef.current === null) return 0;\n\n    const totalBlocking = tasksDuringOperationRef.current.reduce(\n      (sum, task) => sum + Math.max(0, task.duration - 50),\n      0\n    );\n\n    setBlockingTime(totalBlocking);\n    startTimeRef.current = null;\n    tasksDuringOperationRef.current = [];\n\n    return totalBlocking;\n  }, []);\n\n  return { startTracking, stopTracking, blockingTime };\n}\n\n/**\n * Hook that yields to main thread during long operations\n */\n/**\n * Type for the experimental Scheduler API\n */\ninterface SchedulerWithYield {\n  scheduler: {\n    yield: () => Promise<void>;\n  };\n}\n\n/**\n * Type guard for checking if globalThis has the scheduler.yield API\n */\nfunction hasSchedulerYield(obj: typeof globalThis): obj is typeof globalThis & SchedulerWithYield {\n  return (\n    'scheduler' in obj &&\n    typeof (obj as SchedulerWithYield).scheduler === 'object' &&\n    (obj as SchedulerWithYield).scheduler !== null &&\n    'yield' in (obj as SchedulerWithYield).scheduler\n  );\n}\n\nexport function useYieldToMain(): {\n  yieldToMain: () => Promise<void>;\n  yieldIfNeeded: (elapsedMs: number) => Promise<void>;\n} {\n  const yieldToMain = useCallback(async (): Promise<void> => {\n    return new Promise((resolve) => {\n      if (hasSchedulerYield(globalThis)) {\n        const global = globalThis as unknown as SchedulerWithYield;\n        void global.scheduler.yield().then(resolve);\n      } else {\n        setTimeout(resolve, 0);\n      }\n    });\n  }, []);\n\n  const yieldIfNeeded = useCallback(\n    async (elapsedMs: number): Promise<void> => {\n      // Yield if we've been running for more than 50ms\n      if (elapsedMs > 50) {\n        await yieldToMain();\n      }\n    },\n    [yieldToMain]\n  );\n\n  return { yieldToMain, yieldIfNeeded };\n}\n\n// ============================================================================\n// Polyfill for requestIdleCallback\n// ============================================================================\n\nconst requestIdleCallback =\n  typeof window !== 'undefined' && window.requestIdleCallback !== undefined\n    ? window.requestIdleCallback\n    : (callback: () => void) => setTimeout(callback, 1);\n\nconst cancelIdleCallback =\n  typeof window !== 'undefined' && window.cancelIdleCallback !== undefined\n    ? window.cancelIdleCallback\n    : (id: number) => clearTimeout(id);\n"],"names":["useLongTaskDetector","options","threshold","LONG_TASK_CONFIG","maxHistory","onLongTask","onCriticalTask","blockDetectionWindow","debug","monitorRef","useRef","getPerformanceMonitor","monitor","longTasks","setLongTasks","useState","isBlocked","setIsBlocked","lastTaskTime","setLastTaskTime","callbacksRef","blockTimerRef","useEffect","unsubscribe","task","prev","cb","stats","useMemo","durations","t","criticalTasks","totalBlocking","sum","d","oneMinuteAgo","recentTasks","a","b","isHighBlocking","thirtySecondsAgo","lastTask","registerCallback","useCallback","callback","clearHistory","shouldDefer","getLastTaskAttribution","attr","useDeferredRender","value","deferredValue","setDeferredValue","id","requestIdleCallback","cancelIdleCallback","useBlockingTimeTracker","blockingTime","setBlockingTime","startTimeRef","tasksDuringOperationRef","startTracking","stopTracking","hasSchedulerYield","obj","useYieldToMain","yieldToMain","resolve","yieldIfNeeded","elapsedMs"],"mappings":"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"}