{"version":3,"file":"useNetworkQuality.mjs","sources":["../../../../src/lib/performance/hooks/useNetworkQuality.ts"],"sourcesContent":["/**\n * @file useNetworkQuality Hook\n * @description React hook for monitoring network quality and adapting behavior.\n *\n * Provides components with real-time network quality information, enabling\n * adaptive loading strategies based on connection speed and type.\n *\n * @example\n * ```tsx\n * function MyComponent() {\n *   const {\n *     quality,\n *     isSlowConnection,\n *     loadingStrategy,\n *     shouldPrefetch\n *   } = useNetworkQuality();\n *\n *   // Adapt image loading based on network\n *   const imageQuality = loadingStrategy.imageQuality;\n *\n *   return (\n *     <Image\n *       src={getImageUrl(imageQuality)}\n *       loading={isSlowConnection ? 'lazy' : 'eager'}\n *     />\n *   );\n * }\n * ```\n */\n\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport {\n  type ConnectionType,\n  type EffectiveConnectionType,\n  getNetworkAnalyzer,\n  type NetworkPerformanceAnalyzer,\n  type NetworkQuality,\n  type NetworkStats,\n  type RequestTiming,\n} from '../network-performance';\nimport { type NetworkTierConfig } from '../../../config/performance.config';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Adaptive loading strategy\n */\nexport interface AdaptiveLoadingStrategy {\n  /** Recommended image quality */\n  readonly imageQuality: 'high' | 'medium' | 'low' | 'placeholder';\n  /** Prefetch strategy */\n  readonly prefetchStrategy: 'aggressive' | 'moderate' | 'conservative' | 'none';\n  /** Should reduce motion/animations */\n  readonly shouldReduceMotion: boolean;\n  /** Should defer non-critical resources */\n  readonly shouldDeferNonCritical: boolean;\n  /** Maximum concurrent requests */\n  readonly maxConcurrentRequests: number;\n}\n\n/**\n * Hook options\n */\nexport interface UseNetworkQualityOptions {\n  /** Callback on quality change */\n  readonly onQualityChange?: (quality: NetworkQuality) => void;\n  /** Callback on slow request */\n  readonly onSlowRequest?: (request: RequestTiming) => void;\n  /** Slow connection threshold (score 0-100) */\n  readonly slowConnectionThreshold?: number;\n  /** Enable debug logging */\n  readonly debug?: boolean;\n}\n\n/**\n * Hook return value\n */\nexport interface UseNetworkQualityReturn {\n  /** Current network quality */\n  readonly quality: NetworkQuality | null;\n  /** Effective connection type */\n  readonly effectiveType: EffectiveConnectionType;\n  /** Connection type */\n  readonly connectionType: ConnectionType;\n  /** Estimated downlink speed (Mbps) */\n  readonly downlink: number;\n  /** Round-trip time (ms) */\n  readonly rtt: number;\n  /** Data saver enabled */\n  readonly saveData: boolean;\n  /** Overall quality score (0-100) */\n  readonly score: number;\n  /** Network tier configuration */\n  readonly tier: NetworkTierConfig | null;\n  /** Whether on slow connection */\n  readonly isSlowConnection: boolean;\n  /** Whether connection is metered */\n  readonly isMetered: boolean;\n  /** Whether offline */\n  readonly isOffline: boolean;\n  /** Adaptive loading strategy */\n  readonly loadingStrategy: AdaptiveLoadingStrategy;\n  /** Whether should prefetch */\n  readonly shouldPrefetch: boolean;\n  /** Network statistics */\n  readonly stats: NetworkStats | null;\n  /** Estimated bandwidth (bytes/sec) */\n  readonly estimatedBandwidth: number;\n  /** Force refresh quality */\n  readonly refresh: () => void;\n  /** Get priority recommendation for a resource */\n  readonly getPriority: (url: string, type: string, options?: {\n    isAboveFold?: boolean;\n    isLCP?: boolean;\n    isInteractive?: boolean;\n  }) => 'highest' | 'high' | 'normal' | 'low' | 'lowest';\n}\n\n// ============================================================================\n// Hook Implementation\n// ============================================================================\n\n/**\n * Hook for network quality monitoring\n */\nexport function useNetworkQuality(\n  options: UseNetworkQualityOptions = {}\n): UseNetworkQualityReturn {\n  const {\n    onQualityChange,\n    onSlowRequest,\n    slowConnectionThreshold = 50,\n    debug = false,\n  } = options;\n\n  // State\n  const [quality, setQuality] = useState<NetworkQuality | null>(null);\n\n  // Get analyzer instance (lazy initialization)\n  const [analyzer] = useState<NetworkPerformanceAnalyzer>(() => getNetworkAnalyzer({\n    debug,\n    onQualityChange: (quality) => {\n      setQuality(quality);\n      onQualityChange?.(quality);\n    },\n    onSlowRequest: (request) => {\n      onSlowRequest?.(request);\n    },\n  }));\n  const [isOffline, setIsOffline] = useState(\n    typeof navigator !== 'undefined' ? !navigator.onLine : false\n  );\n  const [stats, setStats] = useState<NetworkStats | null>(null);\n\n  // Initialize quality\n  useEffect(() => {\n    const initialQuality = analyzer.getQuality();\n    // eslint-disable-next-line react-hooks/set-state-in-effect\n    setQuality(initialQuality);\n    setStats(analyzer.getStats());\n\n    // Poll for stats updates\n    const intervalId = setInterval(() => {\n      setQuality(analyzer.getQuality());\n      setStats(analyzer.getStats());\n    }, 5000);\n\n    return () => clearInterval(intervalId);\n  }, [analyzer]);\n\n  // Online/offline detection\n  useEffect(() => {\n    const handleOnline = (): void => {\n      setIsOffline(false);\n      if (debug) {\n        console.info('[useNetworkQuality] Connection restored');\n      }\n    };\n\n    const handleOffline = (): void => {\n      setIsOffline(true);\n      if (debug) {\n        console.info('[useNetworkQuality] Connection lost');\n      }\n    };\n\n    window.addEventListener('online', handleOnline);\n    window.addEventListener('offline', handleOffline);\n\n    return () => {\n      window.removeEventListener('online', handleOnline);\n      window.removeEventListener('offline', handleOffline);\n    };\n  }, [debug]);\n\n  // Refresh quality\n  const refresh = useCallback(() => {\n    const newQuality = analyzer.getQuality();\n    setQuality(newQuality);\n    setStats(analyzer.getStats());\n  }, [analyzer]);\n\n  // Get loading strategy\n  const loadingStrategy = useMemo<AdaptiveLoadingStrategy>(() => {\n    return analyzer.getLoadingStrategy();\n  }, [analyzer]); // Re-compute when analyzer changes\n\n  // Get priority recommendation\n  const getPriority = useCallback(\n    (\n      url: string,\n      type: string,\n      options?: {\n        isAboveFold?: boolean;\n        isLCP?: boolean;\n        isInteractive?: boolean;\n      }\n    ) => {\n      const recommendation = analyzer.getPriorityRecommendation(url, type, options);\n      return recommendation.recommendedPriority;\n    },\n    [analyzer]\n  );\n\n  // Derived values\n  const effectiveType: EffectiveConnectionType = quality?.effectiveType ?? '4g';\n  const connectionType: ConnectionType = quality?.type ?? 'unknown';\n  const downlink = quality?.downlink ?? 10;\n  const rtt = quality?.rtt ?? 50;\n  const saveData = quality?.saveData ?? false;\n  const score = quality?.score ?? 100;\n  const tier = quality?.tier ?? null;\n  const isSlowConnection = score < slowConnectionThreshold || effectiveType === 'slow-2g' || effectiveType === '2g';\n  const isMetered = quality?.isMetered ?? false;\n  const shouldPrefetch = loadingStrategy.prefetchStrategy !== 'none' && !isOffline && !saveData;\n  const estimatedBandwidth = analyzer.getEstimatedBandwidth();\n\n  return {\n    quality,\n    effectiveType,\n    connectionType,\n    downlink,\n    rtt,\n    saveData,\n    score,\n    tier,\n    isSlowConnection,\n    isMetered,\n    isOffline,\n    loadingStrategy,\n    shouldPrefetch,\n    stats,\n    estimatedBandwidth,\n    refresh,\n    getPriority,\n  };\n}\n\n// ============================================================================\n// Utility Hooks\n// ============================================================================\n\n/**\n * Hook that returns image quality based on network\n */\nexport function useAdaptiveImageQuality(): 'high' | 'medium' | 'low' | 'placeholder' {\n  const { loadingStrategy } = useNetworkQuality();\n  return loadingStrategy.imageQuality;\n}\n\n/**\n * Hook that conditionally loads based on network\n */\nexport function useNetworkConditional<T>(\n  fullValue: T,\n  reducedValue: T,\n  placeholderValue: T\n): T {\n  const { loadingStrategy, isOffline } = useNetworkQuality();\n\n  if (isOffline) {\n    return placeholderValue;\n  }\n\n  switch (loadingStrategy.imageQuality) {\n    case 'high':\n    case 'medium':\n      return fullValue;\n    case 'low':\n      return reducedValue;\n    case 'placeholder':\n      return placeholderValue;\n    default:\n      return fullValue;\n  }\n}\n\n/**\n * Hook for network-aware lazy loading\n */\nexport function useNetworkAwareLazyLoad(): {\n  shouldLazyLoad: boolean;\n  intersectionThreshold: number;\n  rootMargin: string;\n} {\n  const { isSlowConnection, loadingStrategy } = useNetworkQuality();\n\n  return useMemo(() => {\n    if (isSlowConnection) {\n      return {\n        shouldLazyLoad: true,\n        intersectionThreshold: 0,\n        rootMargin: '50px', // Start loading earlier on slow connections\n      };\n    }\n\n    if (loadingStrategy.prefetchStrategy === 'aggressive') {\n      return {\n        shouldLazyLoad: false,\n        intersectionThreshold: 0,\n        rootMargin: '200px',\n      };\n    }\n\n    return {\n      shouldLazyLoad: true,\n      intersectionThreshold: 0.1,\n      rootMargin: '100px',\n    };\n  }, [isSlowConnection, loadingStrategy]);\n}\n\n/**\n * Hook for tracking request performance\n */\nexport function useRequestPerformance(url: string): {\n  timing: RequestTiming | null;\n  isLoading: boolean;\n  error: Error | null;\n} {\n  const [timing, setTiming] = useState<RequestTiming | null>(null);\n  const [isLoading, setIsLoading] = useState(true);\n  const [error, setError] = useState<Error | null>(null);\n\n  const analyzer = getNetworkAnalyzer();\n\n  useEffect(() => {\n    queueMicrotask(() => {\n      setIsLoading(true);\n      setError(null);\n    });\n\n    // Wait for the request to complete and then analyze it\n    const checkForTiming = (): void => {\n      const requestTiming = analyzer.analyzeRequest(url);\n      if (requestTiming) {\n        setTiming(requestTiming);\n        setIsLoading(false);\n      }\n    };\n\n    // Check periodically for the request timing\n    const intervalId = setInterval(checkForTiming, 100);\n    const timeoutId = setTimeout(() => {\n      clearInterval(intervalId);\n      setIsLoading(false);\n\n      if (timing === null) {\n        setError(new Error('Request timing not found'));\n      }\n    }, 10000);\n\n    return () => {\n      clearInterval(intervalId);\n      clearTimeout(timeoutId);\n    };\n  }, [url, analyzer, timing]);\n\n  return { timing, isLoading, error };\n}\n\n/**\n * Hook that provides network status indicator data\n */\nexport function useNetworkStatusIndicator(): {\n  status: 'excellent' | 'good' | 'fair' | 'poor' | 'offline';\n  label: string;\n  color: string;\n  icon: string;\n} {\n  const { score, isOffline } = useNetworkQuality();\n\n  return useMemo(() => {\n    if (isOffline) {\n      return {\n        status: 'offline' as const,\n        label: 'Offline',\n        color: '#6b7280', // gray\n        icon: 'wifi-off',\n      };\n    }\n\n    if (score >= 80) {\n      return {\n        status: 'excellent' as const,\n        label: 'Excellent',\n        color: '#22c55e', // green\n        icon: 'wifi',\n      };\n    }\n\n    if (score >= 60) {\n      return {\n        status: 'good' as const,\n        label: 'Good',\n        color: '#84cc16', // lime\n        icon: 'wifi',\n      };\n    }\n\n    if (score >= 40) {\n      return {\n        status: 'fair' as const,\n        label: 'Fair',\n        color: '#f59e0b', // amber\n        icon: 'wifi-low',\n      };\n    }\n\n    return {\n      status: 'poor' as const,\n      label: 'Poor',\n      color: '#ef4444', // red\n      icon: 'wifi-low',\n    };\n  }, [score, isOffline]);\n}\n\n/**\n * Hook for preconnect management\n */\nexport function usePreconnect(origins: string[]): void {\n  const { shouldPrefetch } = useNetworkQuality();\n\n  useEffect(() => {\n    if (!shouldPrefetch) return;\n\n    const links: HTMLLinkElement[] = [];\n\n    origins.forEach((origin) => {\n      // Check if preconnect already exists\n      const existing = document.querySelector(`link[rel=\"preconnect\"][href=\"${origin}\"]`);\n      if (existing) return;\n\n      const link = document.createElement('link');\n      link.rel = 'preconnect';\n      link.href = origin;\n      link.crossOrigin = 'anonymous';\n      document.head.appendChild(link);\n      links.push(link);\n    });\n\n    return () => {\n      links.forEach((link) => {\n        if (link.parentNode) {\n          link.parentNode.removeChild(link);\n        }\n      });\n    };\n  }, [origins, shouldPrefetch]);\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n// Types are already exported at their declaration sites\n"],"names":["useNetworkQuality","options","onQualityChange","onSlowRequest","slowConnectionThreshold","debug","quality","setQuality","useState","analyzer","getNetworkAnalyzer","request","isOffline","setIsOffline","stats","setStats","useEffect","initialQuality","intervalId","handleOnline","handleOffline","refresh","useCallback","newQuality","loadingStrategy","useMemo","getPriority","url","type","effectiveType","connectionType","downlink","rtt","saveData","score","tier","isSlowConnection","isMetered","shouldPrefetch","estimatedBandwidth","useAdaptiveImageQuality","useNetworkConditional","fullValue","reducedValue","placeholderValue","useNetworkAwareLazyLoad","useRequestPerformance","timing","setTiming","isLoading","setIsLoading","error","setError","requestTiming","timeoutId","useNetworkStatusIndicator","usePreconnect","origins","links","origin","link"],"mappings":"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"}