{"version":3,"sources":["../../src/use-web-socket/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useGetterRef } from '../use-getter-ref'\nimport { useIntervalFn } from '../use-interval-fn'\nimport { useLatest } from '../use-latest'\nimport { useMount } from '../use-mount'\nimport { useSafeState } from '../use-safe-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { useTimeoutFn } from '../use-timeout-fn'\nimport { useUnmount } from '../use-unmount'\nimport { useUpdateEffect } from '../use-update-effect'\nimport { useVersionedAction } from '../use-versioned-action'\nimport { isDev, isFunction, isString, noop } from '../utils/basic'\n\nexport type UseWebSocketSendable = string | ArrayBufferLike | Blob | ArrayBufferView\n\nexport interface UseWebSocketOptionsHeartbeat {\n  /**\n   * The heartbeat message to send to the server.\n   *\n   * @defaultValue 'ping'\n   */\n  message?: UseWebSocketSendable\n  /**\n   * The interval at which to send a heartbeat message to the server, disabled when set to `0`.\n   *\n   * @defaultValue 1_000\n   */\n  interval?: number\n  /**\n   * The timeout for the server to respond to the heartbeat message, set false to disable.\n   *\n   * @defaultValue 1_000\n   */\n  responseTimeout?: number\n  /**\n   * The expected response heartbeat message from the server, `true` means any message.\n   *\n   * @defaultValue true\n   */\n  responseMessage?: true | UseWebSocketSendable | ((data: UseWebSocketSendable) => boolean)\n}\n\nexport interface UseWebSocketOptionsReconnect {\n  /**\n   * The number of times to reconnect, default is `() => true`, reconnect indefinitely.\n   */\n  count?: number | (() => boolean)\n  /**\n   * The interval at which to reconnect.\n   */\n  interval?: number\n  /**\n   * A callback function that is called when the WebSocket connection is closed and the reconnection limit is reached.\n   */\n  onFailed?: (event: CloseEvent, ws: WebSocket) => void\n}\n\nexport interface UseWebSocketOptions {\n  /**\n   * A callback function that is called when the WebSocket connection is opened.\n   *\n   * @defaultValue undefined\n   */\n  onOpen?: (event: Event, ws: WebSocket) => void\n  /**\n   * A callback function that is called when the WebSocket connection is closed.\n   *\n   * @defaultValue undefined\n   */\n  onClose?: (event: CloseEvent, ws: WebSocket) => void\n  /**\n   * A callback function that is called when an error occurs.\n   *\n   * @defaultValue undefined\n   */\n  onError?: (event: Event, ws: WebSocket) => void\n  /**\n   * A callback function that is called when a message is received from the server.\n   *\n   * @defaultValue undefined\n   */\n  onMessage?: (event: MessageEvent, ws: WebSocket) => void\n  /**\n   * A callback function that is called when the WebSocket connection fails to open,\n   * such as an error or an invalid URL, which will cause the ws to fail to create a connection and close the connection.\n   *\n   * @defaultValue undefined\n   */\n  onOpenFailed?: (event: CloseEvent, ws: WebSocket) => void\n  /**\n   * Whether to send a heartbeat message to the server.\n   *\n   * @defaultValue false\n   */\n  heartbeat?: boolean | UseWebSocketOptionsHeartbeat\n  /**\n   * Whether to reconnect when the connection is closed. Count can be a number or a function that returns a boolean.\n   *\n   * @defaultValue true => { count: () => true, interval: 1_000 }\n   */\n  reconnect?: boolean | UseWebSocketOptionsReconnect\n  /**\n   * Whether to connect to the server immediately.\n   *\n   * @defaultValue true when `wsUrl` is provided, otherwise false\n   */\n  immediate?: boolean\n  /**\n   * Whether to close the WebSocket connection when the component is unmounted.\n   *\n   * @defaultValue true\n   */\n  closeOnUnmount?: boolean\n  /**\n   * The WebSocket subprotocols to use.\n   *\n   * @defaultValue []\n   */\n  protocols?: string | string[]\n  /**\n   * Filter the message to `onMessage` callback, return `true` to ignore the message.\n   *\n   * Useful for filtering out heartbeat messages.\n   *\n   * @defaultValue undefined\n   */\n  filter?: (event: MessageEvent, ws: WebSocket) => boolean\n}\n\nexport interface UseWebSocketReturns<HasURL extends boolean> {\n  /**\n   * The WebSocket instance.\n   */\n  ws: WebSocket | null\n  /**\n   * A function to send data to the server.\n   */\n  send: (data: UseWebSocketSendable) => void\n  /**\n   * The current ready state of the WebSocket connection.\n   */\n  readyState: UseWebSocketReturnsReadyState\n  /**\n   * Close the WebSocket connection.\n   */\n  close: () => Promise<void>\n  /**\n   * Open the WebSocket connection.\n   */\n  open: HasURL extends true ? () => Promise<void> : (wsUrl?: string, protocols?: string | string[]) => Promise<void>\n}\n\n// export type UseWebSocketReturnsReadyState = (typeof WebSocket)[keyof Omit<typeof WebSocket, 'prototype'>]\n\nexport type UseWebSocketReturnsReadyState =\n  | typeof WebSocket.CONNECTING\n  | typeof WebSocket.OPEN\n  | typeof WebSocket.CLOSING\n  | typeof WebSocket.CLOSED\n\nconst defaultHeartbeatMessage = 'ping'\nconst defaultResponseTimeout = 1_000\nconst defaultHeartbeatInterval = 1_000\nconst defaultReconnectOptions = { count: () => true, interval: 1_000 }\n\n/**\n * A simplified React Hook for using WebSockets, wrapping the native WebSocket API. It supports features such as automatic reconnection and heartbeat.\n *\n * @since 1.7.0\n */\nexport function useWebSocket(wsUrl?: string, options?: UseWebSocketOptions): UseWebSocketReturns<true>\nexport function useWebSocket(options?: Omit<UseWebSocketOptions, 'immediate'>): UseWebSocketReturns<false>\nexport function useWebSocket(\n  wsUrl?: string | UseWebSocketOptions,\n  options: UseWebSocketOptions = {},\n): UseWebSocketReturns<boolean> {\n  const [_url, _options = {}] = isString(wsUrl) ? [wsUrl, options] : [undefined, wsUrl]\n\n  const { immediate = !!_url, closeOnUnmount = true } = _options\n\n  const [wsRef, ws] = useGetterRef<WebSocket | null>(null)\n  const retriesRef = useRef(0)\n  const messageQueue = useRef<UseWebSocketSendable[]>([])\n  const isClosedIntentionally = useRef<boolean>(false)\n  const hasBeenOnlineBeforeRef = useRef(false)\n  const [incVersion, runVersionedAction] = useVersionedAction()\n  const [readyState, setReadyState] = useSafeState<UseWebSocketReturnsReadyState>(WebSocket.CLOSED)\n\n  const latest = useLatest({\n    wsUrl: _url,\n    heartbeat: _options.heartbeat,\n    reconnect: resolveReconnectOptions(_options.reconnect ?? true),\n    onOpen: _options.onOpen ?? noop,\n    onClose: _options.onClose ?? noop,\n    onError: _options.onError ?? noop,\n    onMessage: _options.onMessage ?? noop,\n    onOpenFailed: _options.onOpenFailed ?? noop,\n    protocols: _options.protocols ?? [],\n    filter: _options.filter ?? (() => false),\n  })\n\n  const initWebSocket = useStableFn(\n    (\n      wsUrl: string | undefined = latest.current.wsUrl,\n      protocols: string | string[] | undefined = latest.current.protocols,\n    ) => {\n      const url = latest.current.wsUrl || wsUrl\n\n      if (!url) {\n        if (isDev) console.error('The WebSocket URL is required.')\n        return\n      }\n\n      const version = incVersion()\n      setReadyState(WebSocket.CONNECTING)\n\n      hasBeenOnlineBeforeRef.current = false\n      isClosedIntentionally.current = false\n\n      wsRef.current = new WebSocket(url, protocols)\n\n      wsRef.current.onopen = (event) => {\n        runVersionedAction(version, () => {\n          retriesRef.current = 0\n          hasBeenOnlineBeforeRef.current = true\n          setReadyState(WebSocket.OPEN)\n          latest.current.onOpen(event, ws() as WebSocket)\n        })\n      }\n\n      wsRef.current.onclose = (event) => {\n        runVersionedAction(version, () => {\n          setReadyState(WebSocket.CLOSED)\n\n          const notOpen = !hasBeenOnlineBeforeRef.current\n          const reconnect = latest.current.reconnect\n\n          if (notOpen) {\n            latest.current.onOpenFailed(event, ws() as WebSocket)\n            return\n          }\n\n          latest.current.onClose(event, ws() as WebSocket)\n\n          if (!reconnect || isClosedIntentionally.current) return\n\n          const {\n            count = defaultReconnectOptions.count,\n            interval = defaultReconnectOptions.interval,\n            onFailed,\n          } = reconnect\n\n          if (isFunction(count) ? count() : retriesRef.current < count) {\n            retriesRef.current++\n            setTimeout(() => initWebSocket(wsUrl, protocols), interval)\n          } else if (onFailed) {\n            onFailed(event, wsRef.current as WebSocket)\n          }\n        })\n      }\n\n      wsRef.current.onerror = (event) => {\n        runVersionedAction(version, () => {\n          setReadyState(WebSocket.CLOSED)\n\n          const notOpen = !hasBeenOnlineBeforeRef.current\n          if (notOpen) return\n\n          latest.current?.onError?.(event, ws() as WebSocket)\n        })\n      }\n\n      wsRef.current.onmessage = (event) => {\n        runVersionedAction(version, () => {\n          const { heartbeat } = latest.current\n\n          if (heartbeat) {\n            const checkHeartbeatResponse = resolveCheckHeartbeatResponse(heartbeat)\n            checkHeartbeatResponse(event.data) && responseTimeout.pause()\n          }\n\n          if (latest.current.filter(event, ws() as WebSocket)) return\n\n          latest.current.onMessage(event, ws() as WebSocket)\n        })\n      }\n    },\n  )\n\n  const open = useStableFn(\n    async (\n      wsUrl: string | undefined = latest.current.wsUrl,\n      protocols: string | string[] | undefined = latest.current.protocols,\n    ) => {\n      // `reason` will be send to the ws server, not on client's CloseEvent\n      await close(1000, 'Opening a new connection')\n      retriesRef.current = 0\n      initWebSocket(wsUrl, protocols)\n    },\n  )\n\n  const responseTimeout = useTimeoutFn(\n    () => {\n      conditionClose(1000, 'Server did not respond to the heartbeat message', false)\n    },\n    resolveTimeout(latest.current.heartbeat),\n    { immediate: false },\n  )\n\n  useIntervalFn(() => {\n    if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN && latest.current.heartbeat) {\n      const message =\n        latest.current.heartbeat === true\n          ? defaultHeartbeatMessage\n          : (latest.current.heartbeat.message ?? defaultHeartbeatMessage)\n\n      wsRef.current.send(message)\n\n      if (latest.current.heartbeat && !responseTimeout.isActive()) {\n        responseTimeout.resume()\n      }\n    }\n  }, resolveInterval(latest.current.heartbeat))\n\n  const send = useStableFn((data: UseWebSocketSendable) => {\n    if (wsRef.current) {\n      if (wsRef.current.readyState === WebSocket.OPEN) {\n        wsRef.current.send(data)\n      } else {\n        messageQueue.current.push(data)\n      }\n    }\n  })\n\n  async function conditionClose(code?: number, reason?: string, intentional = true) {\n    if (wsRef.current && wsRef.current.readyState !== WebSocket.CLOSED) {\n      responseTimeout.pause()\n      setReadyState(WebSocket.CLOSING)\n      isClosedIntentionally.current = intentional\n\n      // wait for the close action to complete\n      await new Promise<void>((resolve) => {\n        if (!wsRef.current) return resolve()\n        wsRef.current.addEventListener('close', () => {\n          wsRef.current = null\n          resolve()\n        })\n        wsRef.current.close(code, reason)\n      })\n    }\n  }\n\n  /**\n   * `1000` is the code for normal closure\n   *\n   * @see https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code#value\n   */\n  const close = useStableFn(async (code: number = 1000, reason?: string) => {\n    await conditionClose(code, reason, true)\n  })\n\n  useMount(immediate && open)\n\n  useUnmount(closeOnUnmount && close)\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: handle url change\n  useUpdateEffect(() => {\n    open()\n  }, [_url])\n\n  useUpdateEffect(() => {\n    if (readyState === WebSocket.OPEN) {\n      if (messageQueue.current.length) {\n        for (const message of messageQueue.current) send(message)\n        messageQueue.current = []\n      }\n    }\n  }, [readyState])\n\n  return {\n    get ws() {\n      return wsRef.current\n    },\n    readyState,\n    send,\n    close,\n    open,\n  }\n}\n\nfunction isWebSocketSendable(data: unknown): data is UseWebSocketSendable {\n  return isString(data) || ArrayBuffer.isView(data) || data instanceof ArrayBuffer || data instanceof Blob\n}\n\nfunction resolveCheckHeartbeatResponse(heartbeat: Exclude<UseWebSocketOptions['heartbeat'], undefined | false>) {\n  return heartbeat === true\n    ? () => true\n    : heartbeat.responseMessage === true\n      ? () => true\n      : isWebSocketSendable(heartbeat.responseMessage)\n        ? (data: UseWebSocketSendable) => data === heartbeat.responseMessage\n        : (heartbeat.responseMessage ?? (() => true))\n}\n\nfunction resolveReconnectOptions(\n  reconnect?: UseWebSocketOptions['reconnect'],\n): Exclude<UseWebSocketOptions['reconnect'], true> {\n  return reconnect\n    ? reconnect === true\n      ? defaultReconnectOptions\n      : typeof reconnect === 'object'\n        ? { ...defaultReconnectOptions, ...reconnect }\n        : (false as const)\n    : (false as const)\n}\n\nfunction resolveTimeout(heartbeat?: UseWebSocketOptions['heartbeat']) {\n  return heartbeat\n    ? heartbeat === true\n      ? defaultResponseTimeout\n      : (heartbeat.responseTimeout ?? defaultResponseTimeout)\n    : 0\n}\n\nfunction resolveInterval(heartbeat?: UseWebSocketOptions['heartbeat']) {\n  return heartbeat\n    ? heartbeat === true\n      ? defaultHeartbeatInterval\n      : (heartbeat.interval ?? defaultHeartbeatInterval)\n    : 0\n}\n"],"names":["useWebSocket","defaultHeartbeatMessage","defaultResponseTimeout","defaultHeartbeatInterval","defaultReconnectOptions","count","interval","wsUrl","options","isString","undefined","_url","_options","immediate","closeOnUnmount","useGetterRef","wsRef","ws","retriesRef","useRef","messageQueue","isClosedIntentionally","hasBeenOnlineBeforeRef","useVersionedAction","incVersion","runVersionedAction","useSafeState","WebSocket","CLOSED","readyState","setReadyState","latest","useLatest","heartbeat","reconnect","resolveReconnectOptions","onOpen","noop","onClose","onError","onMessage","onOpenFailed","protocols","filter","initWebSocket","useStableFn","current","url","isDev","console","error","version","CONNECTING","onopen","event","OPEN","onclose","notOpen","onFailed","isFunction","setTimeout","onerror","onmessage","checkHeartbeatResponse","resolveCheckHeartbeatResponse","data","responseTimeout","pause","open","close","useTimeoutFn","conditionClose","resolveTimeout","useIntervalFn","message","send","isActive","resume","resolveInterval","push","code","reason","intentional","CLOSING","Promise","resolve","addEventListener","useMount","useUnmount","useUpdateEffect","length","isWebSocketSendable","ArrayBuffer","isView","Blob","responseMessage"],"mappings":"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"}