{"version":3,"sources":["../../src/use-bluetooth/index.ts"],"sourcesContent":["import { useLatest } from '../use-latest'\nimport { useSetState } from '../use-set-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { useSupported } from '../use-supported'\nimport { useUnmount } from '../use-unmount'\nimport { useUpdateEffect } from '../use-update-effect'\n\nexport interface BluetoothRequestDeviceOptions {\n  /**\n   * An array of filter objects indicating the properties of devices that will be matched.\n   *\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/requestDevice#filters | requestDevice#filters - MDN}\n   */\n  filters?: BluetoothLEScanFilter[] | undefined\n  /**\n   * A list of services that the application wishes to access on the remote device.\n   *\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/BluetoothRemoteGATTService/uuid | BluetoothRemoteGATTService/uuid - MDN}\n   */\n  optionalServices?: BluetoothServiceUUID[] | undefined\n}\n\nexport interface UseBluetoothOptions extends BluetoothRequestDeviceOptions {\n  /**\n   * Whether to accept all devices\n   *\n   * @defaultValue false\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/requestDevice#acceptAllDevices | requestDevice#acceptAllDevices - MDN}\n   */\n  acceptAllDevices?: boolean\n  /**\n   * Whether to connect immediately\n   *\n   * @defaultValue true\n   */\n  immediate?: boolean\n}\n\nexport interface UseBlueToothReturns {\n  /**\n   * Whether the device is connected\n   */\n  isConnected: boolean\n  /**\n   * Whether the device is connecting\n   */\n  isConnecting: boolean\n  /**\n   * The error that occurred while connecting\n   */\n  error: unknown | null\n  /**\n   * The GATT server\n   */\n  server: BluetoothRemoteGATTServer | undefined\n  /**\n   * The device\n   */\n  device: BluetoothDevice | undefined\n  /**\n   * Connect to the Bluetooth GATT server\n   *\n   * @returns {Promise<BluetoothRemoteGATTServer | undefined>} The GATT server, see {@link BluetoothRemoteGATTServer}\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/BluetoothRemoteGATTServer | BluetoothRemoteGATTServer - MDN}\n   */\n  connect(): Promise<BluetoothRemoteGATTServer | undefined>\n  /**\n   * Disconnect from the Bluetooth GATT server\n   *\n   * @returns {void} `void`\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/BluetoothRemoteGATTServer/disconnect | BluetoothRemoteGATTServer.disconnect - MDN}\n   */\n  disconnect(): void\n  /**\n   * Whether the browser supports the Web Bluetooth API\n   */\n  isSupported: boolean\n  /**\n   * Request a Bluetooth device\n   *\n   * @returns {Promise<BluetoothDevice | undefined>} The Bluetooth device, see {@link BluetoothDevice}\n   * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/requestDevice | Bluetooth.requestDevice - MDN}\n   */\n  requestDevice(): Promise<BluetoothDevice | undefined>\n}\n\n/**\n * A React Hook that provides a simple API to interact with the Web [Bluetooth API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API).\n *\n * @param {UseBluetoothOptions} [options={}] - `UseBluetoothOptions`, options to configure the hook, see {@link UseBluetoothOptions}\n * @returns {UseBlueToothReturns} `UseBlueToothReturns`, see {@link UseBlueToothReturns}\n */\nexport function useBluetooth(options?: UseBluetoothOptions): UseBlueToothReturns {\n  const { filters, immediate = true, optionalServices, acceptAllDevices = false } = options || {}\n\n  const isSupported = useSupported(() => 'bluetooth' in navigator)\n\n  const [state, setState] = useSetState(\n    {\n      isConnected: false,\n      isConnecting: false,\n      error: null as unknown | null,\n      server: undefined as BluetoothRemoteGATTServer | undefined,\n      device: undefined as BluetoothDevice | undefined,\n    },\n    { deep: true },\n  )\n\n  const latest = useLatest({ ...state, isSupported, immediate, acceptAllDevices, filters, optionalServices })\n\n  const requestDevice = useStableFn(async () => {\n    const { filters, isSupported, optionalServices, acceptAllDevices } = latest.current\n\n    if (!isSupported) return\n\n    let error: unknown | null = null\n    let device = undefined\n\n    const findAll = filters && filters.length > 0 ? false : acceptAllDevices\n\n    setState({ error })\n\n    try {\n      device = await navigator.bluetooth.requestDevice({\n        acceptAllDevices: findAll,\n        filters,\n        optionalServices,\n      })\n    } catch (err) {\n      error = err\n    } finally {\n      setState({ error, device })\n    }\n\n    return device\n  })\n\n  const connectToBluetoothGATTServer = useStableFn(async () => {\n    const { device } = latest.current\n\n    if (!device || !device.gatt) return\n\n    let error = null\n    let server = undefined\n\n    setState({ error, isConnecting: true })\n\n    try {\n      server = await device.gatt.connect()\n    } catch (err) {\n      error = err\n    } finally {\n      setState({\n        server,\n        error,\n        isConnecting: false,\n        isConnected: !!server?.connected,\n      })\n    }\n\n    return server\n  })\n\n  const disconnect = useStableFn(() => {\n    latest.current.server?.disconnect()\n    setState({ isConnected: false, server: undefined })\n  })\n\n  useUnmount(disconnect)\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: effect need to re-run when state.device changes\n  useUpdateEffect(() => {\n    immediate && connectToBluetoothGATTServer()\n\n    return disconnect\n  }, [state.device, immediate])\n\n  return {\n    ...state,\n    connect: connectToBluetoothGATTServer,\n    disconnect,\n    isSupported,\n    requestDevice,\n  }\n}\n"],"names":["useBluetooth","options","filters","immediate","optionalServices","acceptAllDevices","isSupported","useSupported","navigator","useSetState","isConnected","isConnecting","error","server","undefined","device","deep","state","setState","latest","useLatest","requestDevice","useStableFn","findAll","err","current","length","bluetooth","connectToBluetoothGATTServer","gatt","connect","connected","disconnect","useUnmount","useUpdateEffect"],"mappings":"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"}