{"version":3,"file":"networkUtils.mjs","sources":["../../../../src/lib/hooks/shared/networkUtils.ts"],"sourcesContent":["/**\n * @file Network Utilities\n * @description Shared utilities for network information and quality detection\n *\n * This module provides cross-browser network information access and quality\n * assessment utilities. It's used by network-aware hooks and prefetching logic.\n */\n\n/**\n * Connection quality type based on Network Information API\n */\nexport type ConnectionType = '4g' | '3g' | '2g' | 'slow-2g' | 'unknown';\n\n/**\n * Network information from the Navigator.connection API\n */\nexport interface NetworkInformation {\n  /** Effective connection type (4g, 3g, etc.) */\n  effectiveType?: ConnectionType;\n  /** Estimated downlink speed in Mbps */\n  downlink?: number;\n  /** Estimated round-trip time in ms */\n  rtt?: number;\n  /** Whether user has enabled data saver mode */\n  saveData?: boolean;\n}\n\n/**\n * Navigator with connection property (non-standard API)\n */\ninterface NavigatorWithConnection extends Navigator {\n  connection?: EventTarget & NetworkInformation;\n}\n\n/**\n * Connection quality ranking for comparison\n * Higher numbers indicate better quality\n */\nconst CONNECTION_QUALITY_RANK: Record<ConnectionType, number> = {\n  '4g': 4,\n  '3g': 3,\n  '2g': 2,\n  'slow-2g': 1,\n  unknown: 3, // Assume decent connection if unknown\n};\n\n/**\n * Get current network information from browser\n *\n * Uses the Network Information API if available. Falls back to safe defaults\n * if the API is not supported (e.g., Firefox, Safari).\n *\n * @returns Current network information\n *\n * @example\n * ```ts\n * const network = getNetworkInfo();\n * console.log(`Connection: ${network.effectiveType}, RTT: ${network.rtt}ms`);\n * ```\n */\nexport function getNetworkInfo(): NetworkInformation {\n  if (typeof globalThis.navigator === 'undefined') {\n    return {\n      effectiveType: 'unknown',\n      downlink: Infinity,\n      rtt: 0,\n      saveData: false,\n    };\n  }\n\n  const navigator = globalThis.navigator as NavigatorWithConnection | undefined;\n  const connection = navigator?.connection;\n\n  return {\n    effectiveType: connection?.effectiveType ?? 'unknown',\n    downlink: connection?.downlink ?? Infinity,\n    rtt: connection?.rtt ?? 0,\n    saveData: connection?.saveData ?? false,\n  };\n}\n\n/**\n * Check if current connection meets minimum quality requirement\n *\n * @param current - Current connection type\n * @param minimum - Minimum required connection type\n * @returns True if current meets or exceeds minimum quality\n *\n * @example\n * ```ts\n * if (meetsMinimumQuality(network.effectiveType, '3g')) {\n *   // Load high-quality assets\n * }\n * ```\n */\nexport function meetsMinimumQuality(current: ConnectionType, minimum: ConnectionType): boolean {\n  return CONNECTION_QUALITY_RANK[current] >= CONNECTION_QUALITY_RANK[minimum];\n}\n\n/**\n * Check if prefetching should be allowed based on network conditions\n *\n * @param options - Prefetch configuration options\n * @param options.respectDataSaver - Skip prefetch if data saver is enabled\n * @param options.minConnectionQuality - Minimum connection quality required\n * @returns True if prefetching should proceed\n *\n * @example\n * ```ts\n * if (shouldAllowPrefetch({ minConnectionQuality: '3g' })) {\n *   prefetchData();\n * }\n * ```\n */\nexport function shouldAllowPrefetch(\n  options: {\n    respectDataSaver?: boolean;\n    minConnectionQuality?: ConnectionType;\n  } = {}\n): boolean {\n  const { respectDataSaver = true, minConnectionQuality = '2g' } = options;\n\n  const networkInfo = getNetworkInfo();\n\n  // Respect data saver mode\n  if (respectDataSaver && networkInfo.saveData === true) {\n    return false;\n  }\n\n  // Check minimum connection quality\n  return meetsMinimumQuality(networkInfo.effectiveType ?? 'unknown', minConnectionQuality);\n}\n\n/**\n * Monitor network quality changes\n *\n * Sets up an event listener for network quality changes. Returns a cleanup\n * function to remove the listener.\n *\n * @param callback - Function called when network quality changes\n * @returns Cleanup function to remove the listener\n *\n * @example\n * ```ts\n * const unsubscribe = monitorNetworkQuality((info) => {\n *   console.log('Network changed:', info.effectiveType);\n * });\n *\n * // Later, cleanup\n * unsubscribe();\n * ```\n */\nexport function monitorNetworkQuality(callback: (info: NetworkInformation) => void): () => void {\n  if (typeof globalThis.navigator === 'undefined') {\n    return () => {};\n  }\n\n  const navigator = globalThis.navigator as NavigatorWithConnection | undefined;\n  const connection = navigator?.connection;\n\n  if (!connection) {\n    // Return no-op cleanup function if API not available\n    return () => {};\n  }\n\n  const handleChange = (): void => {\n    callback(getNetworkInfo());\n  };\n\n  connection.addEventListener('change', handleChange);\n\n  return () => {\n    connection.removeEventListener('change', handleChange);\n  };\n}\n\n/**\n * Check if connection is considered slow\n *\n * A connection is slow if it's 2G/slow-2G, has low downlink speed,\n * high RTT, or data saver mode is enabled.\n *\n * @param threshold - Optional custom thresholds\n * @returns True if connection is slow\n */\nexport function isSlowConnection(threshold?: { maxDownlink?: number; maxRtt?: number }): boolean {\n  const info = getNetworkInfo();\n  const { maxDownlink = 1.5, maxRtt = 300 } = threshold ?? {};\n\n  return (\n    info.saveData === true ||\n    info.effectiveType === '2g' ||\n    info.effectiveType === 'slow-2g' ||\n    (info.downlink !== undefined && info.downlink < maxDownlink) ||\n    (info.rtt !== undefined && info.rtt > maxRtt)\n  );\n}\n\n/**\n * Get descriptive quality label for connection\n *\n * @returns Human-readable quality label\n */\nexport function getConnectionQualityLabel(type?: ConnectionType): string {\n  const effectiveType = type ?? getNetworkInfo().effectiveType ?? 'unknown';\n\n  const labels: Record<ConnectionType, string> = {\n    '4g': 'Excellent',\n    '3g': 'Good',\n    '2g': 'Fair',\n    'slow-2g': 'Poor',\n    unknown: 'Unknown',\n  };\n\n  return labels[effectiveType];\n}\n"],"names":["CONNECTION_QUALITY_RANK","getNetworkInfo","connection","meetsMinimumQuality","current","minimum","shouldAllowPrefetch","options","respectDataSaver","minConnectionQuality","networkInfo","monitorNetworkQuality","callback","handleChange","isSlowConnection","threshold","info","maxDownlink","maxRtt","getConnectionQualityLabel","type","effectiveType"],"mappings":"AAsCA,MAAMA,IAA0D;AAAA,EAC9D,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,WAAW;AAAA,EACX,SAAS;AAAA;AACX;AAgBO,SAASC,IAAqC;AACnD,MAAI,OAAO,WAAW,YAAc;AAClC,WAAO;AAAA,MACL,eAAe;AAAA,MACf,UAAU;AAAA,MACV,KAAK;AAAA,MACL,UAAU;AAAA,IAAA;AAKd,QAAMC,IADY,WAAW,WACC;AAE9B,SAAO;AAAA,IACL,eAAeA,GAAY,iBAAiB;AAAA,IAC5C,UAAUA,GAAY,YAAY;AAAA,IAClC,KAAKA,GAAY,OAAO;AAAA,IACxB,UAAUA,GAAY,YAAY;AAAA,EAAA;AAEtC;AAgBO,SAASC,EAAoBC,GAAyBC,GAAkC;AAC7F,SAAOL,EAAwBI,CAAO,KAAKJ,EAAwBK,CAAO;AAC5E;AAiBO,SAASC,EACdC,IAGI,IACK;AACT,QAAM,EAAE,kBAAAC,IAAmB,IAAM,sBAAAC,IAAuB,SAASF,GAE3DG,IAAcT,EAAA;AAGpB,SAAIO,KAAoBE,EAAY,aAAa,KACxC,KAIFP,EAAoBO,EAAY,iBAAiB,WAAWD,CAAoB;AACzF;AAqBO,SAASE,EAAsBC,GAA0D;AAC9F,MAAI,OAAO,WAAW,YAAc;AAClC,WAAO,MAAM;AAAA,IAAC;AAIhB,QAAMV,IADY,WAAW,WACC;AAE9B,MAAI,CAACA;AAEH,WAAO,MAAM;AAAA,IAAC;AAGhB,QAAMW,IAAe,MAAY;AAC/B,IAAAD,EAASX,GAAgB;AAAA,EAC3B;AAEA,SAAAC,EAAW,iBAAiB,UAAUW,CAAY,GAE3C,MAAM;AACX,IAAAX,EAAW,oBAAoB,UAAUW,CAAY;AAAA,EACvD;AACF;AAWO,SAASC,EAAiBC,GAAgE;AAC/F,QAAMC,IAAOf,EAAA,GACP,EAAE,aAAAgB,IAAc,KAAK,QAAAC,IAAS,IAAA,IAAQH,KAAa,CAAA;AAEzD,SACEC,EAAK,aAAa,MAClBA,EAAK,kBAAkB,QACvBA,EAAK,kBAAkB,aACtBA,EAAK,aAAa,UAAaA,EAAK,WAAWC,KAC/CD,EAAK,QAAQ,UAAaA,EAAK,MAAME;AAE1C;AAOO,SAASC,EAA0BC,GAA+B;AACvE,QAAMC,IAAgBD,KAAQnB,EAAA,EAAiB,iBAAiB;AAUhE,SAR+C;AAAA,IAC7C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,EAAA,EAGGoB,CAAa;AAC7B;"}