{"version":3,"file":"useWebcam.cjs","names":[],"sources":["../../../../../src/components/Webcam/hooks/useWebcam.ts"],"sourcesContent":["import type { HookTarget, StateRef, UseMediaStreamOptions } from '@siberiacancode/reactuse';\nimport type { MediaTrackConstraintsOptions } from '@webcam/core';\n\nimport {\n  isTarget,\n  useDidUpdate,\n  useMediaStream,\n  useMount,\n  useRefState,\n  useUnmount\n} from '@siberiacancode/reactuse';\nimport { getMediaStreamConstraints } from '@webcam/core';\nimport { useEffect } from 'react';\n\nexport interface UseWebcamParams extends MediaTrackConstraintsOptions {\n  audioConstraints?: MediaTrackConstraints;\n  requestTimeLimit?: number;\n  stream?: MediaStream;\n  videoConstraints?: MediaTrackConstraints;\n  onError?: (error: Error) => void;\n  onRequest?: () => void;\n  onStart?: (stream: MediaStream) => void;\n  onStop?: (stream?: MediaStream) => void;\n}\n\nexport interface UseWebcamReturn {\n  stream?: MediaStream;\n  apply: (constraints: MediaStreamConstraints) => Promise<boolean>;\n  start: (constraints?: MediaStreamConstraints) => Promise<MediaStream | undefined>;\n  stop: () => void;\n}\n\nexport interface UseWebcam {\n  (target: HookTarget, params?: UseWebcamParams): UseWebcamReturn;\n\n  (params?: UseWebcamParams): UseWebcamReturn & {\n    ref: StateRef<HTMLVideoElement>;\n  };\n}\n\n/**\n * @name useWebcam\n * @description - Hook that manages a webcam media stream for a video element\n *\n * @overload\n * @param {HookTarget} target The target video element the stream will be attached to\n * @param {UseWebcamParams} [params] The webcam parameters\n * @returns {UseWebcamReturn} An object containing the stream and controls\n *\n * @overload\n * @param {UseWebcamParams} [params] The webcam parameters\n * @returns {UseWebcamReturn & { ref: StateRef<HTMLVideoElement> }} An object containing the stream, controls and ref\n */\nexport const useWebcam = ((...params: any[]) => {\n  const target = (isTarget(params[0]) ? params[0] : undefined) as HookTarget | undefined;\n  const options = ((target ? params[1] : params[0]) as UseWebcamParams) ?? {};\n\n  const {\n    stream: externalStream,\n    videoConstraints,\n    audioConstraints,\n    cameraResolutionMode,\n    cameraResolutionType,\n    frontCamera,\n    mainCamera,\n    muted,\n    onRequest,\n    onError,\n    onStart,\n    onStop\n  } = options;\n\n  const internalRef = useRefState<HTMLVideoElement>();\n  const resolvedRef = (target ?? internalRef) as HookTarget;\n\n  const mediaStream = useMediaStream(resolvedRef, {\n    immediately: false,\n    onStart,\n    onStop,\n    onError\n  } satisfies UseMediaStreamOptions);\n\n  const createConstraints = () =>\n    getMediaStreamConstraints({\n      constraints: {\n        video: videoConstraints,\n        audio: audioConstraints\n      },\n      options: {\n        cameraResolutionMode,\n        cameraResolutionType,\n        frontCamera,\n        mainCamera,\n        muted\n      }\n    });\n\n  useMount(() => {\n    if (externalStream) return;\n    const run = async () => {\n      onRequest?.();\n      const constraints = await createConstraints();\n      mediaStream.start(constraints);\n    };\n\n    run();\n  });\n\n  useDidUpdate(() => {\n    if (externalStream) return;\n\n    const run = async () => {\n      onRequest?.();\n      const constraints = await createConstraints();\n\n      if (mediaStream.stream) {\n        const ok = await mediaStream.apply(constraints);\n        if (!ok) mediaStream.start(constraints);\n        return;\n      }\n\n      mediaStream.start(constraints);\n    };\n\n    run();\n  }, [\n    videoConstraints,\n    audioConstraints,\n    cameraResolutionMode,\n    cameraResolutionType,\n    frontCamera,\n    mainCamera,\n    muted\n  ]);\n\n  useEffect(() => {\n    if (!externalStream) return;\n\n    const element = isTarget.getElement(resolvedRef) as HTMLVideoElement | null;\n    if (!element) return;\n\n    element.srcObject = externalStream;\n    onStart?.(externalStream);\n\n    return () => {\n      onStop?.(externalStream);\n    };\n  }, [externalStream, target && isTarget.getRawElement(target), internalRef.state]);\n\n  useUnmount(() => {\n    if (externalStream) return;\n    mediaStream.stop();\n  });\n\n  if (target)\n    return {\n      stream: externalStream ?? mediaStream.stream,\n      start: mediaStream.start,\n      apply: mediaStream.apply,\n      stop: mediaStream.stop\n    };\n  return {\n    stream: externalStream ?? mediaStream.stream,\n    start: mediaStream.start,\n    apply: mediaStream.apply,\n    stop: mediaStream.stop,\n    ref: internalRef\n  };\n}) as UseWebcam;\n"],"mappings":"uFAqDA,IAAa,IAAc,GAAG,IAAkB,CAC9C,IAAM,GAAA,EAAA,EAAA,SAAA,CAAmB,EAAO,EAAE,EAAI,EAAO,GAAK,IAAA,GAG5C,CACJ,OAAQ,EACR,mBACA,mBACA,uBACA,uBACA,cACA,aACA,QACA,YACA,UACA,UACA,WAdgB,EAAS,EAAO,GAAK,EAAO,KAA2B,CAAC,EAiBpE,GAAA,EAAA,EAAA,YAAA,CAA4C,EAC5C,EAAe,GAAU,EAEzB,GAAA,EAAA,EAAA,eAAA,CAA6B,EAAa,CAC9C,YAAa,GACb,UACA,SACA,SACF,CAAiC,EAE3B,OAAA,EAAA,EAAA,0BAAA,CACsB,CACxB,YAAa,CACX,MAAO,EACP,MAAO,CACT,EACA,QAAS,CACP,uBACA,uBACA,cACA,aACA,OACF,CACF,CAAC,EAkEH,OAhEA,EAAA,EAAA,SAAA,KAAe,CACT,IAOJ,SANwB,CACtB,IAAY,EACZ,IAAM,EAAc,MAAM,EAAkB,EAC5C,EAAY,MAAM,CAAW,CAC/B,EAEA,CAAI,CACN,CAAC,GAED,EAAA,EAAA,aAAA,KAAmB,CACb,IAeJ,SAbwB,CACtB,IAAY,EACZ,IAAM,EAAc,MAAM,EAAkB,EAE5C,GAAI,EAAY,OAAQ,CAEjB,MADY,EAAY,MAAM,CAAW,GACrC,EAAY,MAAM,CAAW,EACtC,MACF,CAEA,EAAY,MAAM,CAAW,CAC/B,EAEA,CAAI,CACN,EAAG,CACD,EACA,EACA,EACA,EACA,EACA,EACA,CACF,CAAC,GAED,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,CAAC,EAAgB,OAErB,IAAM,EAAU,EAAA,SAAS,WAAW,CAAW,EAC1C,KAKL,MAHA,GAAQ,UAAY,EACpB,IAAU,CAAc,MAEX,CACX,IAAS,CAAc,CACzB,CACF,EAAG,CAAC,EAAgB,GAAU,EAAA,SAAS,cAAc,CAAM,EAAG,EAAY,KAAK,CAAC,GAEhF,EAAA,EAAA,WAAA,KAAiB,CACX,GACJ,EAAY,KAAK,CACnB,CAAC,EAEG,EACK,CACL,OAAQ,GAAkB,EAAY,OACtC,MAAO,EAAY,MACnB,MAAO,EAAY,MACnB,KAAM,EAAY,IACpB,EACK,CACL,OAAQ,GAAkB,EAAY,OACtC,MAAO,EAAY,MACnB,MAAO,EAAY,MACnB,KAAM,EAAY,KAClB,IAAK,CACP,CACF"}