{"version":3,"sources":["../../../../src/sensors/useNetwork/core.ts"],"sourcesContent":["import { observable, ObservableHint } from \"@legendapp/state\";\nimport { createSupported, onMount } from \"@usels/core\";\nimport type { DeepMaybeObservable, ReadonlyObservable, Supportable } from \"@usels/core\";\nimport { type ConfigurableWindow, defaultNavigator, defaultWindow } from \"@shared/configurable\";\nimport type { MaybeEventTarget } from \"../../types\";\nimport { createEventListener } from \"../../browser/useEventListener/core\";\nimport { createWhenMounted } from \"@usels/core/utilities/useWhenMounted/core\";\n\nexport type NetworkType =\n  | \"bluetooth\"\n  | \"cellular\"\n  | \"ethernet\"\n  | \"none\"\n  | \"wifi\"\n  | \"wimax\"\n  | \"other\"\n  | \"unknown\";\n\nexport type NetworkEffectiveType = \"slow-2g\" | \"2g\" | \"3g\" | \"4g\";\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface UseNetworkOptions extends ConfigurableWindow {}\n\nexport interface UseNetworkReturn extends Supportable {\n  /** Whether the browser is online */\n  isOnline$: ReadonlyObservable<boolean>;\n  /** Timestamp of last offline transition */\n  offlineAt$: ReadonlyObservable<number | undefined>;\n  /** Timestamp of last online transition */\n  onlineAt$: ReadonlyObservable<number | undefined>;\n  /** Downlink speed in Mbps */\n  downlink$: ReadonlyObservable<number | undefined>;\n  /** Max reachable downlink speed in Mbps */\n  downlinkMax$: ReadonlyObservable<number | undefined>;\n  /** Effective connection type */\n  effectiveType$: ReadonlyObservable<NetworkEffectiveType | undefined>;\n  /** Estimated round-trip time in ms */\n  rtt$: ReadonlyObservable<number | undefined>;\n  /** Whether data-saver mode is active */\n  saveData$: ReadonlyObservable<boolean | undefined>;\n  /** Connection type */\n  type$: ReadonlyObservable<NetworkType>;\n}\n\ninterface NetworkInformation extends EventTarget {\n  readonly downlink?: number;\n  readonly downlinkMax?: number;\n  readonly effectiveType?: NetworkEffectiveType;\n  readonly rtt?: number;\n  readonly saveData?: boolean;\n  readonly type?: NetworkType;\n}\n\n/*@__NO_SIDE_EFFECTS__*/\nexport function createNetwork(_options?: DeepMaybeObservable<UseNetworkOptions>): UseNetworkReturn {\n  const isSupported$ = createSupported(\n    () => !!defaultNavigator && \"connection\" in defaultNavigator\n  );\n\n  const isOnline$ = observable(true);\n  const offlineAt$ = observable<number | undefined>(undefined);\n  const onlineAt$ = observable<number | undefined>(undefined);\n  const downlink$ = observable<number | undefined>(undefined);\n  const downlinkMax$ = observable<number | undefined>(undefined);\n  const effectiveType$ = observable<NetworkEffectiveType | undefined>(undefined);\n  const rtt$ = observable<number | undefined>(undefined);\n  const saveData$ = observable<boolean | undefined>(undefined);\n  const type$ = observable<NetworkType>(\"unknown\");\n\n  const updateConnectionInfo = () => {\n    if (!defaultNavigator || !(\"connection\" in defaultNavigator)) return;\n    const conn = (defaultNavigator as { connection?: NetworkInformation }).connection;\n    if (!conn) return;\n    downlink$.set(conn.downlink);\n    downlinkMax$.set(conn.downlinkMax);\n    effectiveType$.set(conn.effectiveType);\n    rtt$.set(conn.rtt);\n    saveData$.set(conn.saveData);\n    type$.set(conn.type ?? \"unknown\");\n  };\n  const _conn$ = createWhenMounted(() => {\n    const con =\n      isSupported$.get() && defaultNavigator\n        ? (defaultNavigator as { connection?: NetworkInformation }).connection\n        : null;\n    return con ? ObservableHint.opaque(con) : null;\n  });\n\n  onMount(() => {\n    if (!defaultWindow) return;\n    isOnline$.set(defaultNavigator?.onLine ?? true);\n    updateConnectionInfo();\n  });\n\n  createEventListener(_conn$, \"change\", updateConnectionInfo);\n\n  createEventListener(\n    (defaultWindow as MaybeEventTarget) ?? null,\n    \"online\",\n    () => {\n      isOnline$.set(true);\n      onlineAt$.set(Date.now());\n      offlineAt$.set(undefined);\n      updateConnectionInfo();\n    },\n    { passive: true }\n  );\n\n  createEventListener(\n    (defaultWindow as MaybeEventTarget) ?? null,\n    \"offline\",\n    () => {\n      isOnline$.set(false);\n      offlineAt$.set(Date.now());\n      onlineAt$.set(undefined);\n      updateConnectionInfo();\n    },\n    { passive: true }\n  );\n\n  return {\n    isSupported$,\n    isOnline$,\n    offlineAt$,\n    onlineAt$,\n    downlink$,\n    downlinkMax$,\n    effectiveType$,\n    rtt$,\n    saveData$,\n    type$,\n  };\n}\n"],"mappings":"AAAA,SAAS,YAAY,sBAAsB;AAC3C,SAAS,iBAAiB,eAAe;AAEzC,SAAkC,kBAAkB,qBAAqB;AAEzE,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAAA;AAgD3B,SAAS,cAAc,UAAqE;AACjG,QAAM,eAAe;AAAA,IACnB,MAAM,CAAC,CAAC,oBAAoB,gBAAgB;AAAA,EAC9C;AAEA,QAAM,YAAY,WAAW,IAAI;AACjC,QAAM,aAAa,WAA+B,MAAS;AAC3D,QAAM,YAAY,WAA+B,MAAS;AAC1D,QAAM,YAAY,WAA+B,MAAS;AAC1D,QAAM,eAAe,WAA+B,MAAS;AAC7D,QAAM,iBAAiB,WAA6C,MAAS;AAC7E,QAAM,OAAO,WAA+B,MAAS;AACrD,QAAM,YAAY,WAAgC,MAAS;AAC3D,QAAM,QAAQ,WAAwB,SAAS;AAE/C,QAAM,uBAAuB,MAAM;AACjC,QAAI,CAAC,oBAAoB,EAAE,gBAAgB,kBAAmB;AAC9D,UAAM,OAAQ,iBAAyD;AACvE,QAAI,CAAC,KAAM;AACX,cAAU,IAAI,KAAK,QAAQ;AAC3B,iBAAa,IAAI,KAAK,WAAW;AACjC,mBAAe,IAAI,KAAK,aAAa;AACrC,SAAK,IAAI,KAAK,GAAG;AACjB,cAAU,IAAI,KAAK,QAAQ;AAC3B,UAAM,IAAI,KAAK,QAAQ,SAAS;AAAA,EAClC;AACA,QAAM,SAAS,kBAAkB,MAAM;AACrC,UAAM,MACJ,aAAa,IAAI,KAAK,mBACjB,iBAAyD,aAC1D;AACN,WAAO,MAAM,eAAe,OAAO,GAAG,IAAI;AAAA,EAC5C,CAAC;AAED,UAAQ,MAAM;AACZ,QAAI,CAAC,cAAe;AACpB,cAAU,IAAI,kBAAkB,UAAU,IAAI;AAC9C,yBAAqB;AAAA,EACvB,CAAC;AAED,sBAAoB,QAAQ,UAAU,oBAAoB;AAE1D;AAAA,IACG,iBAAsC;AAAA,IACvC;AAAA,IACA,MAAM;AACJ,gBAAU,IAAI,IAAI;AAClB,gBAAU,IAAI,KAAK,IAAI,CAAC;AACxB,iBAAW,IAAI,MAAS;AACxB,2BAAqB;AAAA,IACvB;AAAA,IACA,EAAE,SAAS,KAAK;AAAA,EAClB;AAEA;AAAA,IACG,iBAAsC;AAAA,IACvC;AAAA,IACA,MAAM;AACJ,gBAAU,IAAI,KAAK;AACnB,iBAAW,IAAI,KAAK,IAAI,CAAC;AACzB,gBAAU,IAAI,MAAS;AACvB,2BAAqB;AAAA,IACvB;AAAA,IACA,EAAE,SAAS,KAAK;AAAA,EAClB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}