{"version":3,"sources":["../../src/use-device-list/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useAsyncEffect } from '../use-async-effect'\nimport { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { usePermission } from '../use-permission'\nimport { useSetState } from '../use-set-state'\nimport { useStableFn } from '../use-stable-fn'\nimport { useSupported } from '../use-supported'\n\nexport interface UseDeviceListOptions {\n  /**\n   * Callback when devices are updated\n   */\n  onUpdated?: (devices: MediaDeviceInfo[]) => void\n  /**\n   * Request for permissions immediately if it's not granted,\n   * otherwise label and deviceIds could be empty\n   *\n   * @defaultValue false\n   */\n  requestPermissions?: boolean\n  /**\n   * Request for types of media permissions\n   *\n   * @defaultValue { audio: true, video: true }\n   */\n  constraints?: MediaStreamConstraints\n}\n\nexport interface UseDeviceListReturns {\n  /**\n   * List of all devices\n   */\n  devices: MediaDeviceInfo[]\n  /**\n   * a getter to get all video inputs\n   */\n  videoInputs: MediaDeviceInfo[]\n  /**\n   * a getter to get all audio inputs\n   */\n  audioInputs: MediaDeviceInfo[]\n  /**\n   * a getter to get all audio outputs\n   */\n  audioOutputs: MediaDeviceInfo[]\n  /**\n   * a boolean to check if permission is granted\n   */\n  isPermissionGranted: boolean\n  /**\n   * a function to check if the browser supports the API\n   */\n  isSupported: boolean\n  /**\n   * a function to request for permissions to access the media devices\n   */\n  ensurePermission(): Promise<boolean>\n  /**\n   * a function to update the list of devices\n   */\n  update(): Promise<void>\n}\n\n/**\n * A React Hook that returns a list of devices that are currently connected.\n */\nexport function useDeviceList(options: UseDeviceListOptions = {}): UseDeviceListReturns {\n  const { requestPermissions = false, constraints = { audio: true, video: true }, onUpdated } = options\n\n  const [state, setState] = useSetState({\n    devices: [] as MediaDeviceInfo[],\n    isPermissionGranted: false as boolean,\n  })\n\n  // https://developer.mozilla.org/en-US/docs/Web/API/Navigator/mediaDevices#browser_compatibility\n  const isSupported = useSupported(() => 'mediaDevices' in navigator && 'enumerateDevices' in navigator.mediaDevices)\n  const latest = useLatest({ ...state, isSupported, onUpdated, constraints })\n  const streamRef = useRef<MediaStream | null>(null)\n\n  const update = useStableFn(async () => {\n    if (!latest.current.isSupported) return\n\n    const devices = (await navigator.mediaDevices.enumerateDevices()) || []\n\n    setState({ devices })\n\n    latest.current.onUpdated?.(devices)\n\n    if (streamRef.current) {\n      for (const track of streamRef.current.getTracks()) {\n        track.stop()\n      }\n      streamRef.current = null\n    }\n  })\n\n  const permission = usePermission('camera', { immediate: false, controls: true })\n\n  const ensurePermission = useStableFn(async () => {\n    const { isSupported, isPermissionGranted, constraints } = latest.current\n\n    if (!isSupported) return false\n    if (isPermissionGranted) return true\n\n    await permission.query()\n\n    if (permission.stateRef.current !== 'granted') {\n      streamRef.current = await navigator.mediaDevices.getUserMedia(constraints)\n    }\n\n    setState({ isPermissionGranted: true })\n\n    await update()\n\n    return true\n  })\n\n  useEventListener(isSupported ? () => navigator.mediaDevices : null, 'devicechange', update)\n\n  useAsyncEffect(async () => {\n    if (isSupported && requestPermissions) {\n      await ensurePermission()\n    }\n  }, [isSupported, requestPermissions])\n\n  return {\n    ...state,\n    videoInputs: filterDevice(state.devices, 'videoinput'),\n    audioInputs: filterDevice(state.devices, 'audioinput'),\n    audioOutputs: filterDevice(state.devices, 'audiooutput'),\n    ensurePermission,\n    isSupported,\n    update,\n  }\n}\n\nfunction filterDevice(devices: MediaDeviceInfo[], type: string) {\n  return devices.filter((i) => i.kind === type)\n}\n"],"names":["useDeviceList","options","requestPermissions","constraints","audio","video","onUpdated","useSetState","devices","isPermissionGranted","state","setState","isSupported","useSupported","navigator","mediaDevices","latest","useLatest","streamRef","useRef","update","useStableFn","track","current","enumerateDevices","getTracks","stop","permission","usePermission","immediate","controls","ensurePermission","query","stateRef","getUserMedia","useEventListener","useAsyncEffect","videoInputs","filterDevice","audioInputs","audioOutputs","type","filter","i","kind"],"mappings":"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"}