{"version":3,"sources":["../../../../src/sensors/useUserMedia/core.ts"],"sourcesContent":["import { batch, observable, ObservableHint } from \"@legendapp/state\";\nimport type { OpaqueObject } from \"@legendapp/state\";\nimport {\n  createSupported,\n  onMount,\n  type DeepMaybeObservable,\n  type ReadonlyObservable,\n  type Supportable,\n} from \"@usels/core\";\nimport { defaultNavigator } from \"@shared/configurable\";\n\nexport interface UseUserMediaOptions {\n  /** Media constraints for getUserMedia. Default: { audio: false, video: true } */\n  constraints?: MediaStreamConstraints;\n  /** Auto-start stream on mount. Default: false */\n  immediate?: boolean;\n}\n\nexport interface UseUserMediaReturn extends Supportable {\n  /** Current media stream */\n  stream$: ReadonlyObservable<OpaqueObject<MediaStream> | null>;\n  /** Whether stream is currently active */\n  enabled$: ReadonlyObservable<boolean>;\n  /** Start the media stream. Throws if getUserMedia fails. */\n  start: () => Promise<MediaStream>;\n  /** Stop the media stream */\n  stop: () => void;\n  /** Restart the media stream. Throws if getUserMedia fails. */\n  restart: () => Promise<MediaStream>;\n}\n\n/**\n * Framework-agnostic reactive wrapper around\n * [MediaDevices.getUserMedia()](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia).\n *\n * Exposes the active `MediaStream` as an observable with `start()` / `stop()` /\n * `restart()` controls. Constraints are read at each `start()` call, so\n * reactive updates take effect on the next stream acquisition. Cleanup\n * (stopping all tracks) is registered via `onMount` so it fires on unmount.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function createUserMedia(\n  options?: DeepMaybeObservable<UseUserMediaOptions>\n): UseUserMediaReturn {\n  const opts$ = observable(options);\n\n  const isSupported$ = createSupported(() => !!defaultNavigator?.mediaDevices?.getUserMedia);\n\n  const stream$ = observable<OpaqueObject<MediaStream> | null>(null);\n  const enabled$ = observable(false);\n\n  const stop = (): void => {\n    const currentStream = stream$.peek();\n    if (currentStream) {\n      currentStream.getTracks().forEach((t) => t.stop());\n    }\n    batch(() => {\n      stream$.set(null);\n      enabled$.set(false);\n    });\n  };\n\n  const start = async (): Promise<MediaStream> => {\n    if (!isSupported$.peek() || !defaultNavigator?.mediaDevices?.getUserMedia) {\n      throw new Error(\"getUserMedia is not supported\");\n    }\n\n    stop();\n\n    try {\n      const constraints = (opts$.peek()?.constraints as MediaStreamConstraints | undefined) ?? {\n        audio: false,\n        video: true,\n      };\n      const mediaStream = await defaultNavigator.mediaDevices.getUserMedia(constraints);\n      batch(() => {\n        stream$.set(ObservableHint.opaque(mediaStream));\n        enabled$.set(true);\n      });\n      return mediaStream;\n    } catch (err) {\n      batch(() => {\n        stream$.set(null);\n        enabled$.set(false);\n      });\n      throw err;\n    }\n  };\n\n  const restart = async (): Promise<MediaStream> => {\n    stop();\n    return start();\n  };\n\n  onMount(() => {\n    if (opts$.peek()?.immediate) {\n      // Swallow rejection from auto-start — callers who care about errors\n      // should invoke start() explicitly.\n      start().catch(() => {});\n    }\n    return () => {\n      stop();\n    };\n  });\n\n  return {\n    isSupported$,\n    stream$: stream$ as ReadonlyObservable<OpaqueObject<MediaStream> | null>,\n    enabled$: enabled$ as ReadonlyObservable<boolean>,\n    start,\n    stop,\n    restart,\n  };\n}\n"],"mappings":"AAAA,SAAS,OAAO,YAAY,sBAAsB;AAElD;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AACP,SAAS,wBAAwB;AAAA;AAgC1B,SAAS,gBACd,SACoB;AACpB,QAAM,QAAQ,WAAW,OAAO;AAEhC,QAAM,eAAe,gBAAgB,MAAM,CAAC,CAAC,kBAAkB,cAAc,YAAY;AAEzF,QAAM,UAAU,WAA6C,IAAI;AACjE,QAAM,WAAW,WAAW,KAAK;AAEjC,QAAM,OAAO,MAAY;AACvB,UAAM,gBAAgB,QAAQ,KAAK;AACnC,QAAI,eAAe;AACjB,oBAAc,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,IACnD;AACA,UAAM,MAAM;AACV,cAAQ,IAAI,IAAI;AAChB,eAAS,IAAI,KAAK;AAAA,IACpB,CAAC;AAAA,EACH;AAEA,QAAM,QAAQ,YAAkC;AAC9C,QAAI,CAAC,aAAa,KAAK,KAAK,CAAC,kBAAkB,cAAc,cAAc;AACzE,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AAEA,SAAK;AAEL,QAAI;AACF,YAAM,cAAe,MAAM,KAAK,GAAG,eAAsD;AAAA,QACvF,OAAO;AAAA,QACP,OAAO;AAAA,MACT;AACA,YAAM,cAAc,MAAM,iBAAiB,aAAa,aAAa,WAAW;AAChF,YAAM,MAAM;AACV,gBAAQ,IAAI,eAAe,OAAO,WAAW,CAAC;AAC9C,iBAAS,IAAI,IAAI;AAAA,MACnB,CAAC;AACD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,YAAM,MAAM;AACV,gBAAQ,IAAI,IAAI;AAChB,iBAAS,IAAI,KAAK;AAAA,MACpB,CAAC;AACD,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,UAAU,YAAkC;AAChD,SAAK;AACL,WAAO,MAAM;AAAA,EACf;AAEA,UAAQ,MAAM;AACZ,QAAI,MAAM,KAAK,GAAG,WAAW;AAG3B,YAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IACxB;AACA,WAAO,MAAM;AACX,WAAK;AAAA,IACP;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}