{"version":3,"file":"useOptimizedHooks.mjs","sources":["../../../../src/lib/performance/hooks/useOptimizedHooks.ts"],"sourcesContent":["/**\n * @file Optimized Performance Hooks\n * @description PhD-level performance hooks for intelligent rendering, lazy feature\n * loading, and progressive content loading with network awareness.\n *\n * Hooks:\n * - useOptimizedRender - Intelligent component rendering with scheduling\n * - useLazyFeature - Lazy loading features with progressive enhancement\n * - useProgressiveLoad - Network-aware progressive loading\n */\n\nimport {\n  type DependencyList,\n  useCallback,\n  useDeferredValue,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n  useTransition,\n} from 'react';\n\n// ============================================================================\n// Utility Hook for Dynamic Dependencies\n// ============================================================================\n\n/**\n * Custom hook to track dependency array changes with a stable version number.\n * This allows proper ESLint compliance when using dynamic dependency arrays.\n *\n * Uses shallow comparison for better performance (avoids JSON.stringify overhead).\n * Only increments version when React's shallow comparison detects changes.\n *\n * @param deps - The dependency array to track\n * @returns A stable version number that increments when any dependency changes\n */\nfunction useDepsVersion(deps: DependencyList): number {\n  const versionRef = useRef(0);\n  const prevDepsRef = useRef<DependencyList>(deps);\n\n  // Use useMemo with deps to detect changes via React's shallow comparison\n  // This is more efficient than JSON.stringify\n\n\n  return useMemo(() => {\n    // React's shallow comparison already ran to trigger this memo\n    // We just need to check if this is a new computation\n    const prevDeps = prevDepsRef.current;\n\n    // Quick length check\n    if (prevDeps.length !== deps.length) {\n      versionRef.current++;\n      prevDepsRef.current = deps;\n      return versionRef.current;\n    }\n\n    // Shallow compare each dependency using Object.is\n    let hasChanged = false;\n    for (let i = 0; i < deps.length; i++) {\n      if (!Object.is(prevDeps[i], deps[i])) {\n        hasChanged = true;\n        break;\n      }\n    }\n\n    if (hasChanged) {\n      versionRef.current++;\n      prevDepsRef.current = deps;\n    }\n\n    return versionRef.current;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, deps);\n}\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Render priority levels\n */\nexport type RenderPriority = 'critical' | 'high' | 'normal' | 'low' | 'idle';\n\n/**\n * Lazy feature status\n */\nexport type LazyFeatureStatus = 'idle' | 'loading' | 'loaded' | 'error';\n\n/**\n * Progressive load phase\n */\nexport type ProgressiveLoadPhase = 'skeleton' | 'low-quality' | 'medium-quality' | 'full';\n\n/**\n * Network quality\n */\nexport type NetworkQuality = 'fast' | 'moderate' | 'slow' | 'offline';\n\n/**\n * Options for useOptimizedRender\n */\nexport interface UseOptimizedRenderOptions<T> {\n  /** Render priority */\n  priority?: RenderPriority;\n  /** Initial value */\n  initialValue?: T;\n  /** Defer initial render */\n  defer?: boolean;\n  /** Use React 18 transitions */\n  useTransition?: boolean;\n  /** Use deferred value */\n  useDeferredValue?: boolean;\n  /** Debounce delay in ms */\n  debounceMs?: number;\n  /** Skip render condition */\n  skipWhen?: (value: T) => boolean;\n}\n\n/**\n * Return type for useOptimizedRender\n */\nexport interface UseOptimizedRenderReturn<T> {\n  /** Current value */\n  value: T;\n  /** Is computation pending */\n  isPending: boolean;\n  /** Is initial render */\n  isInitial: boolean;\n  /** Force immediate computation */\n  forceCompute: () => void;\n}\n\n/**\n * Options for useLazyFeature\n */\nexport interface UseLazyFeatureOptions<T> {\n  /** Auto load on mount */\n  autoLoad?: boolean;\n  /** Preload on hover/focus */\n  preloadOnInteraction?: boolean;\n  /** Fallback value */\n  fallback?: T;\n  /** Retry on error */\n  retryOnError?: boolean;\n  /** Max retries */\n  maxRetries?: number;\n  /** Retry delay in ms */\n  retryDelay?: number;\n  /** Minimum loading time for UX */\n  minLoadingTime?: number;\n  /** Cache the loaded module */\n  cache?: boolean;\n}\n\n/**\n * Return type for useLazyFeature\n */\nexport interface UseLazyFeatureReturn<T> {\n  /** Loaded feature */\n  feature: T | null;\n  /** Loading status */\n  status: LazyFeatureStatus;\n  /** Load error */\n  error: Error | null;\n  /** Load the feature */\n  load: () => Promise<T>;\n  /** Preload handler for events */\n  preloadHandlers: {\n    onMouseEnter: () => void;\n    onFocus: () => void;\n  };\n  /** Is loaded */\n  isLoaded: boolean;\n  /** Is loading */\n  isLoading: boolean;\n}\n\n/**\n * Options for useProgressiveLoad\n */\nexport interface UseProgressiveLoadOptions {\n  /** Enable network awareness */\n  networkAware?: boolean;\n  /** Phases to skip on slow networks */\n  skipPhasesOnSlow?: ProgressiveLoadPhase[];\n  /** Custom phase durations */\n  phaseDurations?: Partial<Record<ProgressiveLoadPhase, number>>;\n  /** Start with placeholder */\n  startWithPlaceholder?: boolean;\n  /** Minimum phase duration */\n  minPhaseDuration?: number;\n}\n\n/**\n * Return type for useProgressiveLoad\n */\nexport interface UseProgressiveLoadReturn<T> {\n  /** Current phase */\n  phase: ProgressiveLoadPhase;\n  /** Current data for phase */\n  data: T | null;\n  /** Network quality */\n  networkQuality: NetworkQuality;\n  /** Is loading */\n  isLoading: boolean;\n  /** Is complete */\n  isComplete: boolean;\n  /** Progress percentage */\n  progress: number;\n  /** Advance to next phase */\n  advancePhase: () => void;\n  /** Set data for current phase */\n  setPhaseData: (data: T) => void;\n  /** Reset to initial state */\n  reset: () => void;\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Get network quality\n */\nfunction getNetworkQuality(): NetworkQuality {\n  if (typeof navigator === 'undefined') return 'fast';\n\n  if (!navigator.onLine) return 'offline';\n\n  const { connection } = navigator as Navigator & {\n    connection?: {\n      effectiveType?: string;\n      saveData?: boolean;\n    };\n  };\n\n  if (connection === null || connection === undefined) return 'fast';\n  if (connection.saveData === true) return 'slow';\n\n  const { effectiveType } = connection;\n  if (effectiveType === '4g') return 'fast';\n  if (effectiveType === '3g') return 'moderate';\n  return 'slow';\n}\n\n/**\n * Schedule based on priority\n */\nfunction scheduleByPriority(callback: () => void, priority: RenderPriority): () => void {\n  let cancelled = false;\n  let timeoutId: ReturnType<typeof setTimeout> | undefined;\n  let idleId: number | undefined;\n\n  const run = (): void => {\n    if (!cancelled) callback();\n  };\n\n  switch (priority) {\n    case 'critical':\n      // Run synchronously\n      callback();\n      break;\n    case 'high':\n      // Run on next microtask\n      void Promise.resolve().then(run);\n      break;\n    case 'normal':\n      // Run on next frame\n      requestAnimationFrame(run);\n      break;\n    case 'low':\n      // Run after small delay\n      timeoutId = setTimeout(run, 50);\n      break;\n    case 'idle':\n      // Run when idle\n      if (typeof requestIdleCallback !== 'undefined') {\n        idleId = requestIdleCallback(run);\n      } else {\n        timeoutId = setTimeout(run, 100);\n      }\n      break;\n  }\n\n  return () => {\n    cancelled = true;\n    if (timeoutId !== undefined) clearTimeout(timeoutId);\n    if (idleId !== undefined && typeof cancelIdleCallback !== 'undefined') {\n      cancelIdleCallback(idleId);\n    }\n  };\n}\n\n// ============================================================================\n// useOptimizedRender Hook\n// ============================================================================\n\n/**\n * Hook for optimized rendering with scheduling and React 18 features\n */\nexport function useOptimizedRender<T>(\n  computeFn: () => T,\n  deps: DependencyList,\n  options: UseOptimizedRenderOptions<T> = {}\n): UseOptimizedRenderReturn<T> {\n  const {\n    priority = 'normal',\n    initialValue,\n    defer = false,\n    useTransition: useTransitionOpt = false,\n    useDeferredValue: useDeferredOpt = false,\n    debounceMs,\n    skipWhen,\n  } = options;\n\n  const [value, setValue] = useState<T>(() => {\n    if (defer && initialValue !== undefined) {\n      return initialValue;\n    }\n    return computeFn();\n  });\n\n  const [isInitial, setIsInitial] = useState(defer);\n  const [isPending, startTransition] = useTransition();\n  const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n  const cancelScheduleRef = useRef<(() => void) | null>(null);\n\n  // Track dependency changes with stable version number\n  const depsVersion = useDepsVersion(deps);\n\n  // Use deferred value if requested\n  const deferredValue = useDeferredValue(value);\n  const outputValue = useDeferredOpt ? deferredValue : value;\n\n  // Force compute function\n  const forceCompute = useCallback(() => {\n    const newValue = computeFn();\n\n    if (skipWhen?.(newValue) === true) {\n      return;\n    }\n\n    if (useTransitionOpt) {\n      startTransition(() => {\n        setValue(newValue);\n      });\n    } else {\n      setValue(newValue);\n    }\n\n    setIsInitial(false);\n  }, [computeFn, skipWhen, useTransitionOpt, startTransition]);\n\n  // Effect to compute on dependency change\n  useEffect(() => {\n    // Clear previous schedule\n    cancelScheduleRef.current?.();\n    if (debounceTimerRef.current) {\n      clearTimeout(debounceTimerRef.current);\n    }\n\n    const compute = (): void => {\n      cancelScheduleRef.current = scheduleByPriority(forceCompute, priority);\n    };\n\n    if (debounceMs !== undefined && debounceMs !== null && debounceMs > 0) {\n      debounceTimerRef.current = setTimeout(compute, debounceMs);\n    } else {\n      compute();\n    }\n\n    return () => {\n      cancelScheduleRef.current?.();\n      if (debounceTimerRef.current) {\n        clearTimeout(debounceTimerRef.current);\n      }\n    };\n  }, [depsVersion, forceCompute, priority, debounceMs]);\n\n  return {\n    value: outputValue,\n    isPending,\n    isInitial,\n    forceCompute,\n  };\n}\n\n// ============================================================================\n// useLazyFeature Hook\n// ============================================================================\n\n// Module cache for lazy features with size limit\nconst MAX_CACHE_SIZE = 50;\nconst featureCache = new Map<string, unknown>();\n\n/**\n * Evict oldest cache entries when size limit is exceeded\n */\nfunction evictOldestCacheEntries(): void {\n  if (featureCache.size <= MAX_CACHE_SIZE) return;\n\n  // Get iterator and delete oldest entries (Maps maintain insertion order)\n  const iterator = featureCache.keys();\n  const entriesToRemove = featureCache.size - MAX_CACHE_SIZE;\n\n  for (let i = 0; i < entriesToRemove; i++) {\n    const oldestKey = iterator.next().value;\n    if (oldestKey !== undefined) {\n      featureCache.delete(oldestKey);\n    }\n  }\n}\n\n/**\n * Hook for lazy loading features with progressive enhancement\n */\nexport function useLazyFeature<T>(\n  featureId: string,\n  loader: () => Promise<T>,\n  options: UseLazyFeatureOptions<T> = {}\n): UseLazyFeatureReturn<T> {\n  const {\n    autoLoad = true,\n    preloadOnInteraction = true,\n    fallback,\n    retryOnError = true,\n    maxRetries = 3,\n    retryDelay = 1000,\n    minLoadingTime = 100,\n    cache = true,\n  } = options;\n\n  const [feature, setFeature] = useState<T | null>(() => {\n    if (cache && featureCache.has(featureId)) {\n      return featureCache.get(featureId) as T;\n    }\n    return fallback ?? null;\n  });\n\n  const [status, setStatus] = useState<LazyFeatureStatus>(() => {\n    if (cache && featureCache.has(featureId)) {\n      return 'loaded';\n    }\n    return 'idle';\n  });\n\n  const [error, setError] = useState<Error | null>(null);\n  const retryCountRef = useRef(0);\n  const loadPromiseRef = useRef<Promise<T> | null>(null);\n\n  // Load the feature\n  const load = useCallback(async (): Promise<T> => {\n    // Return cached\n    if (cache && featureCache.has(featureId)) {\n      const cached = featureCache.get(featureId) as T;\n      setFeature(cached);\n      setStatus('loaded');\n      return cached;\n    }\n\n    // Return existing load promise if loading\n    if (loadPromiseRef.current) {\n      return loadPromiseRef.current;\n    }\n\n    setStatus('loading');\n    setError(null);\n    const startTime = Date.now();\n\n    loadPromiseRef.current = (async () => {\n      try {\n        const result = await loader();\n\n        // Ensure minimum loading time\n        const elapsed = Date.now() - startTime;\n        if (elapsed < minLoadingTime) {\n          await new Promise((r) => setTimeout(r, minLoadingTime - elapsed));\n        }\n\n        // Cache result\n        if (cache) {\n          featureCache.set(featureId, result);\n          evictOldestCacheEntries();\n        }\n\n        setFeature(result);\n        setStatus('loaded');\n        retryCountRef.current = 0;\n        return result;\n      } catch (err) {\n        const loadError = err instanceof Error ? err : new Error(String(err));\n\n        // Retry logic\n        if (retryOnError && retryCountRef.current < maxRetries) {\n          retryCountRef.current++;\n          await new Promise((r) => setTimeout(r, retryDelay * retryCountRef.current));\n          loadPromiseRef.current = null;\n          return load();\n        }\n\n        setError(loadError);\n        setStatus('error');\n        throw loadError;\n      } finally {\n        loadPromiseRef.current = null;\n      }\n    })();\n\n    return loadPromiseRef.current;\n  }, [featureId, loader, cache, minLoadingTime, retryOnError, maxRetries, retryDelay]);\n\n  // Auto load on mount\n  useEffect(() => {\n    if (autoLoad && status === 'idle') {\n      load().catch(() => {\n        // Error handled in state\n      });\n    }\n  }, [autoLoad, load, status]);\n\n  // Preload handlers\n  const preloadHandlers = useMemo(() => {\n    if (!preloadOnInteraction) {\n      return {\n        onMouseEnter: () => {},\n        onFocus: () => {},\n      };\n    }\n\n    const preload = (): void => {\n      if (status === 'idle') {\n        load().catch(() => {\n          // Silently fail preload\n        });\n      }\n    };\n\n    return {\n      onMouseEnter: preload,\n      onFocus: preload,\n    };\n  }, [preloadOnInteraction, status, load]);\n\n  return {\n    feature,\n    status,\n    error,\n    load,\n    preloadHandlers,\n    isLoaded: status === 'loaded',\n    isLoading: status === 'loading',\n  };\n}\n\n// ============================================================================\n// useProgressiveLoad Hook\n// ============================================================================\n\nconst PHASE_ORDER: ProgressiveLoadPhase[] = ['skeleton', 'low-quality', 'medium-quality', 'full'];\nconst DEFAULT_PHASE_DURATIONS: Record<ProgressiveLoadPhase, number> = {\n  skeleton: 0,\n  'low-quality': 200,\n  'medium-quality': 500,\n  full: 1000,\n};\n\n/**\n * Hook for network-aware progressive content loading\n */\nexport function useProgressiveLoad<T>(\n  options: UseProgressiveLoadOptions = {}\n): UseProgressiveLoadReturn<T> {\n  const {\n    networkAware = true,\n    skipPhasesOnSlow = ['medium-quality'],\n    phaseDurations = {},\n    startWithPlaceholder = true,\n    minPhaseDuration = 100,\n  } = options;\n\n  const [phase, setPhase] = useState<ProgressiveLoadPhase>(\n    startWithPlaceholder ? 'skeleton' : 'full'\n  );\n  const [data, setData] = useState<T | null>(null);\n  const [networkQuality, setNetworkQuality] = useState<NetworkQuality>(getNetworkQuality);\n  // eslint-disable-next-line react-hooks/purity\n  const phaseStartTimeRef = useRef(Date.now());\n\n  // Monitor network quality\n  useEffect(() => {\n    if (!networkAware) return;\n\n    const updateNetwork = (): void => setNetworkQuality(getNetworkQuality());\n\n    window.addEventListener('online', updateNetwork);\n    window.addEventListener('offline', updateNetwork);\n\n    const { connection } = navigator as Navigator & {\n      connection?: EventTarget & { addEventListener: (type: string, handler: () => void) => void };\n    };\n    connection?.addEventListener('change', updateNetwork);\n\n    return () => {\n      window.removeEventListener('online', updateNetwork);\n      window.removeEventListener('offline', updateNetwork);\n    };\n  }, [networkAware]);\n\n  // Calculate effective phases\n  const effectivePhases = useMemo(() => {\n    if (!networkAware || networkQuality === 'fast') {\n      return PHASE_ORDER;\n    }\n\n    if (networkQuality === 'slow' || networkQuality === 'offline') {\n      return PHASE_ORDER.filter((p) => !skipPhasesOnSlow.includes(p));\n    }\n\n    return PHASE_ORDER;\n  }, [networkAware, networkQuality, skipPhasesOnSlow]);\n\n  // Get current phase index\n  const currentPhaseIndex = effectivePhases.indexOf(phase);\n  const progress = ((currentPhaseIndex + 1) / effectivePhases.length) * 100;\n  const isComplete = phase === 'full';\n  const isLoading = phase !== 'full';\n\n  // Advance to next phase\n  const advancePhase = useCallback(() => {\n    const currentIndex = effectivePhases.indexOf(phase);\n    const nextPhase = effectivePhases[currentIndex + 1];\n\n    if (nextPhase) {\n      // Ensure minimum phase duration\n      const elapsed = Date.now() - phaseStartTimeRef.current;\n      const duration = phaseDurations[phase] ?? DEFAULT_PHASE_DURATIONS[phase];\n      const effectiveDuration = Math.max(duration, minPhaseDuration);\n\n      if (elapsed < effectiveDuration) {\n        setTimeout(() => {\n          phaseStartTimeRef.current = Date.now();\n          setPhase(nextPhase);\n        }, effectiveDuration - elapsed);\n      } else {\n        phaseStartTimeRef.current = Date.now();\n        setPhase(nextPhase);\n      }\n    }\n  }, [effectivePhases, phase, phaseDurations, minPhaseDuration]);\n\n  // Set data for current phase\n  const setPhaseData = useCallback(\n    (newData: T) => {\n      setData(newData);\n      advancePhase();\n    },\n    [advancePhase]\n  );\n\n  // Reset to initial state\n  const reset = useCallback(() => {\n    setPhase(startWithPlaceholder ? 'skeleton' : 'full');\n    setData(null);\n    phaseStartTimeRef.current = Date.now();\n  }, [startWithPlaceholder]);\n\n  return {\n    phase,\n    data,\n    networkQuality,\n    isLoading,\n    isComplete,\n    progress,\n    advancePhase,\n    setPhaseData,\n    reset,\n  };\n}\n\n// ============================================================================\n// Utility Export Functions\n// ============================================================================\n\n/**\n * Clear feature cache\n */\nexport function clearFeatureCache(featureId?: string): void {\n  if (featureId !== undefined && featureId !== null && featureId !== '') {\n    featureCache.delete(featureId);\n  } else {\n    featureCache.clear();\n  }\n}\n\n/**\n * Preload a feature\n */\nexport async function preloadFeature<T>(featureId: string, loader: () => Promise<T>): Promise<T> {\n  if (featureCache.has(featureId)) {\n    return featureCache.get(featureId) as T;\n  }\n\n  const result = await loader();\n  featureCache.set(featureId, result);\n  evictOldestCacheEntries();\n  return result;\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport default {\n  useOptimizedRender,\n  useLazyFeature,\n  useProgressiveLoad,\n  clearFeatureCache,\n  preloadFeature,\n};\n"],"names":["getNetworkQuality","connection","effectiveType","MAX_CACHE_SIZE","featureCache","evictOldestCacheEntries","iterator","entriesToRemove","i","oldestKey","useLazyFeature","featureId","loader","options","autoLoad","preloadOnInteraction","fallback","retryOnError","maxRetries","retryDelay","minLoadingTime","cache","feature","setFeature","useState","status","setStatus","error","setError","retryCountRef","useRef","loadPromiseRef","load","useCallback","cached","startTime","result","elapsed","r","err","loadError","useEffect","preloadHandlers","useMemo","preload","PHASE_ORDER","DEFAULT_PHASE_DURATIONS","useProgressiveLoad","networkAware","skipPhasesOnSlow","phaseDurations","startWithPlaceholder","minPhaseDuration","phase","setPhase","data","setData","networkQuality","setNetworkQuality","phaseStartTimeRef","updateNetwork","effectivePhases","p","progress","isComplete","isLoading","advancePhase","currentIndex","nextPhase","duration","effectiveDuration","setPhaseData","newData","reset","clearFeatureCache","preloadFeature"],"mappings":"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"}