{"version":3,"file":"useNetworkStatus.mjs","sources":["../../../src/lib/hooks/useNetworkStatus.ts"],"sourcesContent":["/**\n * @file Network Status Hooks\n * @description React hooks for network status monitoring and online/offline handling\n */\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n  getSuggestedAction,\n  networkMonitor,\n  type NetworkQuality,\n  type NetworkStatus,\n} from '../utils/networkStatus';\nimport { isSlowConnection as checkSlowConnection } from './shared/networkUtils';\n\n/**\n * Hook to monitor network online/offline status\n */\nexport function useOnlineStatus(): boolean {\n  const [isOnline, setIsOnline] = useState(() => networkMonitor.isOnline());\n\n  useEffect(() => {\n    return networkMonitor.onStatusChange((status) => {\n      setIsOnline(status.online);\n    });\n  }, []);\n\n  return isOnline;\n}\n\n/**\n * Hook to get full network status\n */\nexport function useNetworkStatus(): NetworkStatus {\n  const [status, setStatus] = useState(() => networkMonitor.getStatus());\n\n  useEffect(() => {\n    return networkMonitor.onStatusChange(setStatus);\n  }, []);\n\n  return status;\n}\n\n/**\n * Hook to monitor network quality\n */\nexport function useNetworkQuality(): NetworkQuality {\n  const [quality, setQuality] = useState(() => networkMonitor.getQuality());\n\n  useEffect(() => {\n    return networkMonitor.onQualityChange(setQuality);\n  }, []);\n\n  return quality;\n}\n\n/**\n * Hook to get suggested actions based on network quality\n */\nexport function useNetworkSuggestions(): ReturnType<typeof getSuggestedAction> {\n  const quality = useNetworkQuality();\n  return useMemo(() => getSuggestedAction(quality), [quality]);\n}\n\n/**\n * Hook to check if connection is slow\n */\nexport function useSlowConnection(): boolean {\n  const status = useNetworkStatus();\n\n  return useMemo(() => {\n    return checkSlowConnection();\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [status]);\n}\n\n/**\n * Hook options for offline behavior\n */\nexport interface UseOfflineFallbackOptions<T> {\n  /** Fallback value when offline */\n  fallbackValue: T;\n  /** Whether to show notification when offline */\n  showNotification?: boolean;\n  /** Custom offline message */\n  offlineMessage?: string;\n}\n\n/**\n * Hook to provide fallback values when offline\n */\nexport function useOfflineFallback<T>(\n  value: T,\n  options: UseOfflineFallbackOptions<T>\n): {\n  value: T;\n  isOffline: boolean;\n  isFallback: boolean;\n} {\n  const isOnline = useOnlineStatus();\n  const [cachedValue, setCachedValue] = useState<T>(value);\n\n  // Update cached value when online\n  useEffect(() => {\n    if (isOnline) {\n      // Use microtask to avoid setState in effect\n      Promise.resolve()\n        .then(() => {\n          setCachedValue(value);\n        })\n        .catch(() => {\n          // Ignore errors in cleanup\n        });\n    }\n  }, [isOnline, value]);\n\n  const effectiveValue = isOnline ? value : cachedValue;\n  const isFallback = !isOnline && effectiveValue === options.fallbackValue;\n\n  return {\n    value: effectiveValue,\n    isOffline: !isOnline,\n    isFallback,\n  };\n}\n\n/**\n * Hook to execute callback when coming back online\n */\nexport function useOnReconnect(callback: () => void): void {\n  const isOnline = useOnlineStatus();\n  const wasOffline = useRef(false);\n\n  useEffect(() => {\n    if (!isOnline) {\n      wasOffline.current = true;\n    } else if (wasOffline.current) {\n      wasOffline.current = false;\n      callback();\n    }\n  }, [isOnline, callback]);\n}\n\n/**\n * Hook to wait for online status\n */\nexport function useWaitForOnline(): {\n  isOnline: boolean;\n  waitForOnline: (timeout?: number) => Promise<boolean>;\n} {\n  const isOnline = useOnlineStatus();\n\n  const waitForOnline = useCallback(async (timeout?: number) => {\n    return networkMonitor.waitForOnline(timeout);\n  }, []);\n\n  return { isOnline, waitForOnline };\n}\n\n/**\n * Hook for network-aware data fetching\n */\nexport interface UseNetworkAwareFetchOptions {\n  /** Minimum quality required to fetch */\n  minQuality?: NetworkQuality;\n  /** Whether to retry on reconnect */\n  retryOnReconnect?: boolean;\n  /** Custom fetch function */\n  fetchFn?: () => Promise<unknown>;\n}\n\n/**\n * Hook result for network-aware fetch\n */\nexport interface UseNetworkAwareFetchResult {\n  canFetch: boolean;\n  quality: NetworkQuality;\n  isOnline: boolean;\n  suggestions: ReturnType<typeof getSuggestedAction>;\n  refetchOnReconnect: () => void;\n}\n\n/**\n * Hook to manage network-aware fetching\n */\nexport function useNetworkAwareFetch(\n  options: UseNetworkAwareFetchOptions = {}\n): UseNetworkAwareFetchResult {\n  const isOnline = useOnlineStatus();\n  const quality = useNetworkQuality();\n  const suggestions = useNetworkSuggestions();\n  const { minQuality = 'poor', retryOnReconnect = true, fetchFn } = options;\n\n  const qualityOrder: NetworkQuality[] = ['offline', 'poor', 'fair', 'good', 'excellent'];\n  const canFetch = isOnline && qualityOrder.indexOf(quality) >= qualityOrder.indexOf(minQuality);\n\n  // Retry on reconnect\n  useOnReconnect(\n    useCallback(() => {\n      if (retryOnReconnect && fetchFn != null) {\n        void fetchFn();\n      }\n    }, [retryOnReconnect, fetchFn])\n  );\n\n  const refetchOnReconnect = useCallback(() => {\n    if (fetchFn != null) {\n      void fetchFn();\n    }\n  }, [fetchFn]);\n\n  return {\n    canFetch,\n    quality,\n    isOnline,\n    suggestions,\n    refetchOnReconnect,\n  };\n}\n\n/**\n * Hook to show offline indicator\n */\nexport function useOfflineIndicator(): {\n  showIndicator: boolean;\n  message: string;\n  quality: NetworkQuality;\n} {\n  const isOnline = useOnlineStatus();\n  const quality = useNetworkQuality();\n  const [showIndicator, setShowIndicator] = useState(false);\n\n  useEffect(() => {\n    if (!isOnline) {\n      // Use microtask to avoid synchronous setState in effect\n      Promise.resolve()\n        .then(() => {\n          setShowIndicator(true);\n        })\n        .catch(() => {\n          // Ignore errors in cleanup\n        });\n    } else {\n      // Delay hiding indicator to allow for brief disconnections\n      const timer = setTimeout(() => {\n        setShowIndicator(false);\n      }, 2000);\n      return () => clearTimeout(timer);\n    }\n    return undefined;\n  }, [isOnline]);\n\n  const message = useMemo(() => {\n    if (!isOnline) return 'You are offline';\n    if (quality === 'poor') return 'Slow connection detected';\n    return '';\n  }, [isOnline, quality]);\n\n  return {\n    showIndicator: showIndicator || quality === 'poor',\n    message,\n    quality,\n  };\n}\n\n/**\n * Hook to track connection changes\n */\nexport function useConnectionTracker(): {\n  changes: Array<{ online: boolean; timestamp: number }>;\n  disconnectCount: number;\n  lastDisconnect: number | null;\n  avgOfflineDuration: number;\n} {\n  const isOnline = useOnlineStatus();\n  const [changes, setChanges] = useState<Array<{ online: boolean; timestamp: number }>>([]);\n\n  useEffect(() => {\n    // Use microtask to avoid setState in effect\n    Promise.resolve()\n      .then(() => {\n        setChanges((prev) => [...prev.slice(-19), { online: isOnline, timestamp: Date.now() }]);\n      })\n      .catch(() => {\n        // Ignore errors in cleanup\n      });\n  }, [isOnline]);\n\n  return useMemo(() => {\n    const disconnects = changes.filter((c) => !c.online);\n    const reconnects = changes.filter((c) => c.online);\n\n    let totalOffline = 0;\n    for (let i = 0; i < disconnects.length; i++) {\n      const disconnect = disconnects[i];\n      if (disconnect == null) continue;\n\n      const reconnect = reconnects.find((r) => r.timestamp > disconnect.timestamp);\n      if (reconnect != null) {\n        totalOffline += reconnect.timestamp - disconnect.timestamp;\n      }\n    }\n\n    return {\n      changes,\n      disconnectCount: disconnects.length,\n      lastDisconnect:\n        disconnects.length > 0 ? (disconnects[disconnects.length - 1]?.timestamp ?? null) : null,\n      avgOfflineDuration: disconnects.length > 0 ? totalOffline / disconnects.length : 0,\n    };\n  }, [changes]);\n}\n"],"names":["useOnlineStatus","isOnline","setIsOnline","useState","networkMonitor","useEffect","status","useNetworkStatus","setStatus","useNetworkQuality","quality","setQuality","useNetworkSuggestions","useMemo","getSuggestedAction","useSlowConnection","checkSlowConnection","useOfflineFallback","value","options","cachedValue","setCachedValue","effectiveValue","isFallback","useOnReconnect","callback","wasOffline","useRef","useWaitForOnline","waitForOnline","useCallback","timeout","useNetworkAwareFetch","suggestions","minQuality","retryOnReconnect","fetchFn","qualityOrder","canFetch","refetchOnReconnect","useOfflineIndicator","showIndicator","setShowIndicator","timer","message","useConnectionTracker","changes","setChanges","prev","disconnects","c","reconnects","totalOffline","disconnect","reconnect","r"],"mappings":"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"}