tempest-react-sdk 0.35.0 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -70
- package/dist/audio/audio-output.cjs +2 -0
- package/dist/audio/audio-output.cjs.map +1 -0
- package/dist/audio/audio-output.js +17 -0
- package/dist/audio/audio-output.js.map +1 -0
- package/dist/audio/audio-player.cjs +1 -1
- package/dist/audio/audio-player.cjs.map +1 -1
- package/dist/audio/audio-player.js +21 -20
- package/dist/audio/audio-player.js.map +1 -1
- package/dist/audio/audio-recorder.cjs +2 -0
- package/dist/audio/audio-recorder.cjs.map +1 -0
- package/dist/audio/audio-recorder.js +30 -0
- package/dist/audio/audio-recorder.js.map +1 -0
- package/dist/audio/duration.cjs +2 -0
- package/dist/audio/duration.cjs.map +1 -0
- package/dist/audio/duration.js +10 -0
- package/dist/audio/duration.js.map +1 -0
- package/dist/audio/level-meter.cjs +2 -0
- package/dist/audio/level-meter.cjs.map +1 -0
- package/dist/audio/level-meter.js +34 -0
- package/dist/audio/level-meter.js.map +1 -0
- package/dist/audio/media-access.cjs +2 -0
- package/dist/audio/media-access.cjs.map +1 -0
- package/dist/audio/media-access.js +51 -0
- package/dist/audio/media-access.js.map +1 -0
- package/dist/audio/use-audio-recorder.cjs +2 -0
- package/dist/audio/use-audio-recorder.cjs.map +1 -0
- package/dist/audio/use-audio-recorder.js +94 -0
- package/dist/audio/use-audio-recorder.js.map +1 -0
- package/dist/audio/use-audio.cjs.map +1 -1
- package/dist/audio/use-audio.js.map +1 -1
- package/dist/audio/use-microphone.cjs +2 -0
- package/dist/audio/use-microphone.cjs.map +1 -0
- package/dist/audio/use-microphone.js +54 -0
- package/dist/audio/use-microphone.js.map +1 -0
- package/dist/audio/wav.cjs +2 -0
- package/dist/audio/wav.cjs.map +1 -0
- package/dist/audio/wav.js +49 -0
- package/dist/audio/wav.js.map +1 -0
- package/dist/auth/passkey.cjs +2 -0
- package/dist/auth/passkey.cjs.map +1 -0
- package/dist/auth/passkey.js +171 -0
- package/dist/auth/passkey.js.map +1 -0
- package/dist/auth/use-passkey.cjs +2 -0
- package/dist/auth/use-passkey.cjs.map +1 -0
- package/dist/auth/use-passkey.js +120 -0
- package/dist/auth/use-passkey.js.map +1 -0
- package/dist/br/PixQRCode.cjs +2 -0
- package/dist/br/PixQRCode.cjs.map +1 -0
- package/dist/br/PixQRCode.js +70 -0
- package/dist/br/PixQRCode.js.map +1 -0
- package/dist/br/PixQRCode.module.cjs +2 -0
- package/dist/br/PixQRCode.module.cjs.map +1 -0
- package/dist/br/PixQRCode.module.js +15 -0
- package/dist/br/PixQRCode.module.js.map +1 -0
- package/dist/br/boleto.cjs +2 -0
- package/dist/br/boleto.cjs.map +1 -0
- package/dist/br/boleto.js +225 -0
- package/dist/br/boleto.js.map +1 -0
- package/dist/br/holidays.cjs +2 -0
- package/dist/br/holidays.cjs.map +1 -0
- package/dist/br/holidays.js +148 -0
- package/dist/br/holidays.js.map +1 -0
- package/dist/br/nfe.cjs +2 -0
- package/dist/br/nfe.cjs.map +1 -0
- package/dist/br/nfe.js +104 -0
- package/dist/br/nfe.js.map +1 -0
- package/dist/br/pix.cjs +2 -0
- package/dist/br/pix.cjs.map +1 -0
- package/dist/br/pix.js +148 -0
- package/dist/br/pix.js.map +1 -0
- package/dist/br.cjs +1 -1
- package/dist/br.cjs.map +1 -1
- package/dist/br.d.ts +878 -0
- package/dist/br.js +7 -2
- package/dist/br.js.map +1 -1
- package/dist/capture/barcode.cjs +2 -0
- package/dist/capture/barcode.cjs.map +1 -0
- package/dist/capture/barcode.js +59 -0
- package/dist/capture/barcode.js.map +1 -0
- package/dist/capture/media-recorder.cjs +2 -0
- package/dist/capture/media-recorder.cjs.map +1 -0
- package/dist/capture/media-recorder.js +64 -0
- package/dist/capture/media-recorder.js.map +1 -0
- package/dist/capture/use-barcode-scanner.cjs +2 -0
- package/dist/capture/use-barcode-scanner.cjs.map +1 -0
- package/dist/capture/use-barcode-scanner.js +86 -0
- package/dist/capture/use-barcode-scanner.js.map +1 -0
- package/dist/capture/use-screen-capture.cjs +2 -0
- package/dist/capture/use-screen-capture.cjs.map +1 -0
- package/dist/capture/use-screen-capture.js +79 -0
- package/dist/capture/use-screen-capture.js.map +1 -0
- package/dist/capture/use-speech-recognition.cjs +2 -0
- package/dist/capture/use-speech-recognition.cjs.map +1 -0
- package/dist/capture/use-speech-recognition.js +118 -0
- package/dist/capture/use-speech-recognition.js.map +1 -0
- package/dist/capture/use-torch.cjs +2 -0
- package/dist/capture/use-torch.cjs.map +1 -0
- package/dist/capture/use-torch.js +33 -0
- package/dist/capture/use-torch.js.map +1 -0
- package/dist/capture/use-video-recorder.cjs +2 -0
- package/dist/capture/use-video-recorder.cjs.map +1 -0
- package/dist/capture/use-video-recorder.js +90 -0
- package/dist/capture/use-video-recorder.js.map +1 -0
- package/dist/capture/video-recorder.cjs +2 -0
- package/dist/capture/video-recorder.cjs.map +1 -0
- package/dist/capture/video-recorder.js +31 -0
- package/dist/capture/video-recorder.js.map +1 -0
- package/dist/components/AIChat/AIChat.cjs +1 -1
- package/dist/components/AIChat/AIChat.cjs.map +1 -1
- package/dist/components/AIChat/AIChat.js +93 -97
- package/dist/components/AIChat/AIChat.js.map +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs +1 -1
- package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
- package/dist/components/AIChat/AIChatComposer.js +2 -1
- package/dist/components/AIChat/AIChatComposer.js.map +1 -1
- package/dist/components/AIChat/AIChatTurn.cjs +2 -2
- package/dist/components/AIChat/AIChatTurn.js +6 -6
- package/dist/components/AIChat/AIChatTurn.js.map +1 -1
- package/dist/components/Alert/Alert.module.cjs.map +1 -1
- package/dist/components/Alert/Alert.module.js.map +1 -1
- package/dist/components/AudioPlayer/AudioPlayer.cjs +2 -0
- package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.js +123 -0
- package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.cjs +2 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.js +12 -0
- package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.cjs +2 -0
- package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.js +179 -0
- package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.cjs +2 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.js +19 -0
- package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -0
- package/dist/components/Badge/Badge.module.cjs.map +1 -1
- package/dist/components/Badge/Badge.module.js.map +1 -1
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs +2 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.js +123 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs +2 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.js +22 -0
- package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -0
- package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
- package/dist/components/Button/Button.module.cjs.map +1 -1
- package/dist/components/Button/Button.module.js.map +1 -1
- package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
- package/dist/components/Combobox/Combobox.module.js.map +1 -1
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +203 -66
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/DataTable.module.cjs +1 -1
- package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.module.js +9 -3
- package/dist/components/DataTable/DataTable.module.js.map +1 -1
- package/dist/components/DataTable/EditableCell.cjs +2 -0
- package/dist/components/DataTable/EditableCell.cjs.map +1 -0
- package/dist/components/DataTable/EditableCell.js +77 -0
- package/dist/components/DataTable/EditableCell.js.map +1 -0
- package/dist/components/DataTable/edit-labels.cjs +2 -0
- package/dist/components/DataTable/edit-labels.cjs.map +1 -0
- package/dist/components/DataTable/edit-labels.js +11 -0
- package/dist/components/DataTable/edit-labels.js.map +1 -0
- package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
- package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
- package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
- package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs.map +1 -1
- package/dist/components/SyncStatusBadge/SyncStatusBadge.js +33 -32
- package/dist/components/SyncStatusBadge/SyncStatusBadge.js.map +1 -1
- package/dist/components/Toast/ToastProvider.cjs +1 -1
- package/dist/components/Toast/ToastProvider.cjs.map +1 -1
- package/dist/components/Toast/ToastProvider.js +1 -2
- package/dist/components/Toast/ToastProvider.js.map +1 -1
- package/dist/hooks/use-announce.cjs +2 -0
- package/dist/hooks/use-announce.cjs.map +1 -0
- package/dist/hooks/use-announce.js +50 -0
- package/dist/hooks/use-announce.js.map +1 -0
- package/dist/hooks/use-media-devices.cjs +2 -0
- package/dist/hooks/use-media-devices.cjs.map +1 -0
- package/dist/hooks/use-media-devices.js +46 -0
- package/dist/hooks/use-media-devices.js.map +1 -0
- package/dist/hooks/use-media-permission.cjs +2 -0
- package/dist/hooks/use-media-permission.cjs.map +1 -0
- package/dist/hooks/use-media-permission.js +33 -0
- package/dist/hooks/use-media-permission.js.map +1 -0
- package/dist/http/resumable-upload.cjs +2 -0
- package/dist/http/resumable-upload.cjs.map +1 -0
- package/dist/http/resumable-upload.js +249 -0
- package/dist/http/resumable-upload.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +2485 -29
- package/dist/tempest-react-sdk.js +268 -244
- package/dist/vision/core/graph.cjs +2 -0
- package/dist/vision/core/graph.cjs.map +1 -0
- package/dist/vision/core/graph.js +17 -0
- package/dist/vision/core/graph.js.map +1 -0
- package/dist/vision/core/session.cjs +1 -1
- package/dist/vision/core/session.cjs.map +1 -1
- package/dist/vision/core/session.js +19 -9
- package/dist/vision/core/session.js.map +1 -1
- package/dist/vision/index.cjs +1 -1
- package/dist/vision/index.cjs.map +1 -1
- package/dist/vision/index.js +14 -13
- package/dist/vision/index.js.map +1 -1
- package/dist/vision/tasks/classifier.cjs +1 -1
- package/dist/vision/tasks/classifier.cjs.map +1 -1
- package/dist/vision/tasks/classifier.js +33 -25
- package/dist/vision/tasks/classifier.js.map +1 -1
- package/dist/vision/tasks/detector.cjs +1 -1
- package/dist/vision/tasks/detector.cjs.map +1 -1
- package/dist/vision/tasks/detector.js +28 -20
- package/dist/vision/tasks/detector.js.map +1 -1
- package/dist/vision/tasks/segmenter.cjs +1 -1
- package/dist/vision/tasks/segmenter.cjs.map +1 -1
- package/dist/vision/tasks/segmenter.js +23 -15
- package/dist/vision/tasks/segmenter.js.map +1 -1
- package/dist/vision/use-camera-stream.cjs +1 -1
- package/dist/vision/use-camera-stream.cjs.map +1 -1
- package/dist/vision/use-camera-stream.js +40 -57
- package/dist/vision/use-camera-stream.js.map +1 -1
- package/dist/vision.cjs +1 -1
- package/dist/vision.d.ts +149 -8
- package/dist/vision.js +22 -21
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-camera-stream.cjs","names":[],"sources":["../../src/vision/use-camera-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\n\n/** Lifecycle status of the camera stream. */\nexport type CameraStreamStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/** Classified reason a camera stream could not be acquired. */\nexport type CameraStreamErrorKind =\n \"unsupported\" | \"permission-denied\" | \"no-camera\" | \"in-use\" | \"insecure\" | \"unknown\";\n\n/** A classified camera error with a human-readable, English message. */\nexport interface CameraStreamError {\n kind: CameraStreamErrorKind;\n message: string;\n}\n\n/** Options for {@link useCameraStream}. */\nexport interface UseCameraStreamOptions {\n /**\n * Constraints passed to `getUserMedia`. Defaults to the rear\n * (\"environment\") camera at Full-HD ideal resolution with audio off.\n * Read when the stream (re)starts — change it and call `retry()` to apply.\n */\n constraints?: MediaStreamConstraints;\n}\n\n/** Value returned by {@link useCameraStream}. */\nexport interface UseCameraStreamApi {\n /** Current lifecycle status. */\n status: CameraStreamStatus;\n /** The classified error, or `null` while not in the `error` status. */\n error: CameraStreamError | null;\n /** Attach to a `<video ref={…} />`. The stream is wired to it once ready. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /** Manually re-attempt after an error (e.g. the user changed permissions). */\n retry: () => void;\n}\n\n/** Rear-camera Full-HD defaults used when no `constraints` are supplied. */\nconst DEFAULT_CONSTRAINTS: MediaStreamConstraints = {\n video: {\n facingMode: { ideal: \"environment\" },\n width: { ideal: 1920 },\n height: { ideal: 1080 },\n },\n audio: false,\n};\n\n/**\n * Map an unknown failure into a {@link CameraStreamError}. Secure-context and\n * environment checks run first (they are the reason `getUserMedia` is missing\n * or rejects), then the `DOMException.name` is mapped to a stable `kind`.\n */\nfunction classifyError(err: unknown): CameraStreamError {\n if (typeof window === \"undefined\") {\n return { kind: \"unsupported\", message: \"Camera is unavailable in this environment.\" };\n }\n if (!window.isSecureContext) {\n return {\n kind: \"insecure\",\n message: \"Camera access requires a secure (HTTPS) connection.\",\n };\n }\n if (err instanceof DOMException) {\n switch (err.name) {\n case \"NotAllowedError\":\n case \"SecurityError\":\n return {\n kind: \"permission-denied\",\n message: \"Camera permission denied. Enable access in your browser settings.\",\n };\n case \"NotFoundError\":\n case \"OverconstrainedError\":\n return {\n kind: \"no-camera\",\n message: \"No camera available on this device.\",\n };\n case \"NotReadableError\":\n case \"AbortError\":\n return {\n kind: \"in-use\",\n message: \"The camera is in use by another app. Close it and try again.\",\n };\n }\n }\n return {\n kind: \"unknown\",\n message:\n err instanceof Error ? err.message : \"Unexpected error while accessing the camera.\",\n };\n}\n\n/**\n * Acquire a `MediaStream` via `getUserMedia`, attach it to a `<video>` element,\n * and expose status/error so the page can render permission and error states.\n * The stream is automatically released on unmount or retry.\n *\n * Defaults to the rear (\"environment\") camera; desktops fall back to whatever\n * single camera they expose. Pass `options.constraints` to override.\n *\n * Implementation notes:\n * - Cleanup detaches the stream from a *snapshotted* video node, so it releases\n * the same element it attached to even if the page remounts the `<video>`.\n * - When `getUserMedia` is missing, an insecure context is the usual cause, so\n * the hook prefers that (actionable) error; otherwise it reports `unsupported`.\n * - `video.play()` rejections are swallowed: autoplay may be blocked, but the\n * user gesture that opened the camera usually counts and playback resumes on\n * the next interaction.\n *\n * @param options - optional configuration (see {@link UseCameraStreamOptions}).\n * @returns The stream status, classified error, a `videoRef` to attach, and a\n * `retry()` to re-attempt acquisition.\n */\nexport function useCameraStream(options: UseCameraStreamOptions = {}): UseCameraStreamApi {\n const [status, setStatus] = useState<CameraStreamStatus>(\"loading\");\n const [error, setError] = useState<CameraStreamError | null>(null);\n const [retryToken, setRetryToken] = useState(0);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const constraintsRef = useRef<MediaStreamConstraints>(\n options.constraints ?? DEFAULT_CONSTRAINTS,\n );\n useEffect(() => {\n constraintsRef.current = options.constraints ?? DEFAULT_CONSTRAINTS;\n }, [options.constraints]);\n\n useEffect(() => {\n let cancelled = false;\n let stream: MediaStream | null = null;\n let attachedVideo: HTMLVideoElement | null = null;\n\n async function start(): Promise<void> {\n setStatus(\"loading\");\n setError(null);\n\n if (\n typeof navigator === \"undefined\" ||\n !navigator.mediaDevices ||\n typeof navigator.mediaDevices.getUserMedia !== \"function\"\n ) {\n if (!cancelled) {\n setError(\n typeof window !== \"undefined\" && !window.isSecureContext\n ? classifyError(null)\n : {\n kind: \"unsupported\",\n message: \"Camera capture is not supported in this browser.\",\n },\n );\n setStatus(\"error\");\n }\n return;\n }\n\n try {\n stream = await navigator.mediaDevices.getUserMedia(constraintsRef.current);\n if (cancelled) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n const video = videoRef.current;\n if (!video) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n attachedVideo = video;\n video.srcObject = stream;\n await video.play().catch(() => undefined);\n if (!cancelled) setStatus(\"ready\");\n } catch (err) {\n if (!cancelled) {\n setError(classifyError(err));\n setStatus(\"error\");\n }\n }\n }\n\n void start();\n\n return () => {\n cancelled = true;\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (attachedVideo) {\n attachedVideo.srcObject = null;\n }\n };\n }, [retryToken]);\n\n return {\n status,\n error,\n videoRef,\n retry: () => setRetryToken((n) => n + 1),\n };\n}\n"],"mappings":"uBAsCA,IAAM,EAA8C,CAChD,MAAO,CACH,WAAY,CAAE,MAAO,aAAc,EACnC,MAAO,CAAE,MAAO,IAAK,EACrB,OAAQ,CAAE,MAAO,IAAK,CAC1B,EACA,MAAO,EACX,EAOA,SAAS,EAAc,EAAiC,CACpD,GAAI,OAAO,OAAW,IAClB,MAAO,CAAE,KAAM,cAAe,QAAS,4CAA6C,EAExF,GAAI,CAAC,OAAO,gBACR,MAAO,CACH,KAAM,WACN,QAAS,qDACb,EAEJ,GAAI,aAAe,aACf,OAAQ,EAAI,KAAZ,CACI,IAAK,kBACL,IAAK,gBACD,MAAO,CACH,KAAM,oBACN,QAAS,mEACb,EACJ,IAAK,gBACL,IAAK,uBACD,MAAO,CACH,KAAM,YACN,QAAS,qCACb,EACJ,IAAK,mBACL,IAAK,aACD,MAAO,CACH,KAAM,SACN,QAAS,8DACb,CACR,CAEJ,MAAO,CACH,KAAM,UACN,QACI,aAAe,MAAQ,EAAI,QAAU,8CAC7C,CACJ,CAuBA,SAAgB,EAAgB,EAAkC,CAAC,EAAuB,CACtF,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAA0C,SAAS,EAC5D,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,CAA+C,IAAI,EAC3D,CAAC,EAAY,IAAA,EAAA,EAAA,SAAA,CAA0B,CAAC,EACxC,GAAA,EAAA,EAAA,OAAA,CAA2C,IAAI,EAC/C,GAAA,EAAA,EAAA,OAAA,CACF,EAAQ,aAAe,CAC3B,EAqEA,OApEA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAe,QAAU,EAAQ,aAAe,CACpD,EAAG,CAAC,EAAQ,WAAW,CAAC,GAExB,EAAA,EAAA,UAAA,KAAgB,CACZ,IAAI,EAAY,GACZ,EAA6B,KAC7B,EAAyC,KAE7C,eAAe,GAAuB,CAIlC,GAHA,EAAU,SAAS,EACnB,EAAS,IAAI,EAGT,OAAO,UAAc,KACrB,CAAC,UAAU,cACX,OAAO,UAAU,aAAa,cAAiB,WACjD,CACO,IACD,EACI,OAAO,OAAW,KAAe,CAAC,OAAO,gBACnC,EAAc,IAAI,EAClB,CACI,KAAM,cACN,QAAS,kDACb,CACV,EACA,EAAU,OAAO,GAErB,MACJ,CAEA,GAAI,CAEA,GADA,EAAS,MAAM,UAAU,aAAa,aAAa,EAAe,OAAO,EACrE,EAAW,CACX,EAAO,UAAU,CAAC,CAAC,QAAS,GAAU,EAAM,KAAK,CAAC,EAClD,MACJ,CACA,IAAM,EAAQ,EAAS,QACvB,GAAI,CAAC,EAAO,CACR,EAAO,UAAU,CAAC,CAAC,QAAS,GAAU,EAAM,KAAK,CAAC,EAClD,MACJ,CACA,EAAgB,EAChB,EAAM,UAAY,EAClB,MAAM,EAAM,KAAK,CAAC,CAAC,UAAY,IAAA,EAAS,EACnC,GAAW,EAAU,OAAO,CACrC,OAAS,EAAK,CACL,IACD,EAAS,EAAc,CAAG,CAAC,EAC3B,EAAU,OAAO,EAEzB,CACJ,CAIA,OAFA,EAAW,MAEE,CACT,EAAY,GACR,GACA,EAAO,UAAU,CAAC,CAAC,QAAS,GAAU,EAAM,KAAK,CAAC,EAElD,IACA,EAAc,UAAY,KAElC,CACJ,EAAG,CAAC,CAAU,CAAC,EAER,CACH,SACA,QACA,WACA,UAAa,EAAe,GAAM,EAAI,CAAC,CAC3C,CACJ"}
|
|
1
|
+
{"version":3,"file":"use-camera-stream.cjs","names":[],"sources":["../../src/vision/use-camera-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\n\nimport {\n classifyMediaError,\n missingCaptureApiError,\n type MediaAccessError,\n} from \"@/audio/media-access\";\n\n/** Lifecycle status of the camera stream. */\nexport type CameraStreamStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/** Classified reason a camera stream could not be acquired. */\nexport type CameraStreamErrorKind =\n \"unsupported\" | \"permission-denied\" | \"no-camera\" | \"in-use\" | \"insecure\" | \"unknown\";\n\n/** A classified camera error with a human-readable, English message. */\nexport interface CameraStreamError {\n kind: CameraStreamErrorKind;\n message: string;\n}\n\n/** Options for {@link useCameraStream}. */\nexport interface UseCameraStreamOptions {\n /**\n * Constraints passed to `getUserMedia`. Defaults to the rear\n * (\"environment\") camera at Full-HD ideal resolution with audio off.\n * Read when the stream (re)starts — change it and call `retry()` to apply.\n */\n constraints?: MediaStreamConstraints;\n /**\n * Hold off acquiring the camera until this is `true`. Default `true`.\n *\n * The point is to be able to *not* prompt. A permission prompt costs the user a\n * decision and, if they refuse, costs the app the feature permanently — so a\n * surface that already knows it cannot do its job (a barcode scanner in a browser\n * with no decoder) must not open the camera to then say so. Flipping this to `false`\n * also releases a stream that is already live.\n */\n enabled?: boolean;\n}\n\n/** Value returned by {@link useCameraStream}. */\nexport interface UseCameraStreamApi {\n /** Current lifecycle status. */\n status: CameraStreamStatus;\n /** The classified error, or `null` while not in the `error` status. */\n error: CameraStreamError | null;\n /** Attach to a `<video ref={…} />`. The stream is wired to it once ready. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /**\n * The live stream, or `null`.\n *\n * Exposed for the things that need the **track** rather than the picture — the LED\n * torch (`useTorch`), the real frame size from `getSettings()`, recording it with\n * `useVideoRecorder`. Do not stop it yourself: the hook owns its lifetime and\n * releases it on unmount and on `retry()`.\n */\n stream: MediaStream | null;\n /** Manually re-attempt after an error (e.g. the user changed permissions). */\n retry: () => void;\n}\n\n/** Rear-camera Full-HD defaults used when no `constraints` are supplied. */\nconst DEFAULT_CONSTRAINTS: MediaStreamConstraints = {\n video: {\n facingMode: { ideal: \"environment\" },\n width: { ideal: 1920 },\n height: { ideal: 1080 },\n },\n audio: false,\n};\n\n/**\n * Re-label a {@link MediaAccessError} as a {@link CameraStreamError}.\n *\n * The classification itself lives in one place for the whole SDK\n * (`classifyMediaError`), so a microphone and a camera failure are never explained\n * two different ways. Only the name of one kind differs: this surface shipped\n * `\"no-camera\"` where the shared taxonomy says `\"not-found\"`, and renaming a\n * published union member would break every consumer switching on it.\n *\n * @param error - The shared classification.\n * @returns The same error under this module's kind names.\n */\nfunction toCameraError({ kind, message }: MediaAccessError): CameraStreamError {\n return { kind: kind === \"not-found\" ? \"no-camera\" : kind, message };\n}\n\n/**\n * Map an unknown `getUserMedia` failure into a {@link CameraStreamError}. Secure-context\n * and environment checks run first (they are the reason `getUserMedia` is missing or\n * rejects), then the `DOMException.name` is mapped to a stable `kind`.\n */\nfunction classifyError(err: unknown): CameraStreamError {\n return toCameraError(classifyMediaError(err, \"camera\"));\n}\n\n/**\n * Acquire a `MediaStream` via `getUserMedia`, attach it to a `<video>` element,\n * and expose status/error so the page can render permission and error states.\n * The stream is automatically released on unmount or retry.\n *\n * Defaults to the rear (\"environment\") camera; desktops fall back to whatever\n * single camera they expose. Pass `options.constraints` to override, or\n * `options.enabled: false` to render the surface without prompting for the camera\n * at all.\n *\n * Implementation notes:\n * - Cleanup detaches the stream from a *snapshotted* video node, so it releases\n * the same element it attached to even if the page remounts the `<video>`.\n * - When `getUserMedia` is missing, an insecure context is the usual cause, so\n * the hook prefers that (actionable) error; otherwise it reports `unsupported`.\n * - `video.play()` rejections are swallowed: autoplay may be blocked, but the\n * user gesture that opened the camera usually counts and playback resumes on\n * the next interaction.\n *\n * @param options - optional configuration (see {@link UseCameraStreamOptions}).\n * @returns The stream status, classified error, a `videoRef` to attach, the live\n * `stream` for whatever needs the track itself, and a `retry()` to re-attempt\n * acquisition.\n */\nexport function useCameraStream(options: UseCameraStreamOptions = {}): UseCameraStreamApi {\n const [status, setStatus] = useState<CameraStreamStatus>(\"loading\");\n const [error, setError] = useState<CameraStreamError | null>(null);\n const [live, setLive] = useState<MediaStream | null>(null);\n const [retryToken, setRetryToken] = useState(0);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const constraintsRef = useRef<MediaStreamConstraints>(\n options.constraints ?? DEFAULT_CONSTRAINTS,\n );\n useEffect(() => {\n constraintsRef.current = options.constraints ?? DEFAULT_CONSTRAINTS;\n }, [options.constraints]);\n\n const enabled = options.enabled ?? true;\n\n useEffect(() => {\n let cancelled = false;\n let stream: MediaStream | null = null;\n let attachedVideo: HTMLVideoElement | null = null;\n\n async function start(): Promise<void> {\n if (!enabled) {\n setStatus(\"idle\");\n setError(null);\n return;\n }\n setStatus(\"loading\");\n setError(null);\n\n if (\n typeof navigator === \"undefined\" ||\n !navigator.mediaDevices ||\n typeof navigator.mediaDevices.getUserMedia !== \"function\"\n ) {\n if (!cancelled) {\n setError(toCameraError(missingCaptureApiError(\"camera\")));\n setStatus(\"error\");\n }\n return;\n }\n\n try {\n stream = await navigator.mediaDevices.getUserMedia(constraintsRef.current);\n if (cancelled) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n const video = videoRef.current;\n if (!video) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n attachedVideo = video;\n video.srcObject = stream;\n setLive(stream);\n await video.play().catch(() => undefined);\n if (!cancelled) setStatus(\"ready\");\n } catch (err) {\n if (!cancelled) {\n setError(classifyError(err));\n setStatus(\"error\");\n }\n }\n }\n\n void start();\n\n return () => {\n cancelled = true;\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (attachedVideo) {\n attachedVideo.srcObject = null;\n }\n setLive(null);\n };\n }, [retryToken, enabled]);\n\n return {\n status,\n error,\n videoRef,\n stream: live,\n retry: () => setRetryToken((n) => n + 1),\n };\n}\n"],"mappings":"oEA+DA,IAAM,EAA8C,CAChD,MAAO,CACH,WAAY,CAAE,MAAO,aAAc,EACnC,MAAO,CAAE,MAAO,IAAK,EACrB,OAAQ,CAAE,MAAO,IAAK,CAC1B,EACA,MAAO,EACX,EAcA,SAAS,EAAc,CAAE,OAAM,WAAgD,CAC3E,MAAO,CAAE,KAAM,IAAS,YAAc,YAAc,EAAM,SAAQ,CACtE,CAOA,SAAS,EAAc,EAAiC,CACpD,OAAO,EAAc,EAAA,mBAAmB,EAAK,QAAQ,CAAC,CAC1D,CA0BA,SAAgB,EAAgB,EAAkC,CAAC,EAAuB,CACtF,GAAM,CAAC,EAAQ,IAAA,EAAA,EAAA,SAAA,CAA0C,SAAS,EAC5D,CAAC,EAAO,IAAA,EAAA,EAAA,SAAA,CAA+C,IAAI,EAC3D,CAAC,EAAM,IAAA,EAAA,EAAA,SAAA,CAAwC,IAAI,EACnD,CAAC,EAAY,IAAA,EAAA,EAAA,SAAA,CAA0B,CAAC,EACxC,GAAA,EAAA,EAAA,OAAA,CAA2C,IAAI,EAC/C,GAAA,EAAA,EAAA,OAAA,CACF,EAAQ,aAAe,CAC3B,GACA,EAAA,EAAA,UAAA,KAAgB,CACZ,EAAe,QAAU,EAAQ,aAAe,CACpD,EAAG,CAAC,EAAQ,WAAW,CAAC,EAExB,IAAM,EAAU,EAAQ,SAAW,GAkEnC,OAhEA,EAAA,EAAA,UAAA,KAAgB,CACZ,IAAI,EAAY,GACZ,EAA6B,KAC7B,EAAyC,KAE7C,eAAe,GAAuB,CAClC,GAAI,CAAC,EAAS,CACV,EAAU,MAAM,EAChB,EAAS,IAAI,EACb,MACJ,CAIA,GAHA,EAAU,SAAS,EACnB,EAAS,IAAI,EAGT,OAAO,UAAc,KACrB,CAAC,UAAU,cACX,OAAO,UAAU,aAAa,cAAiB,WACjD,CACO,IACD,EAAS,EAAc,EAAA,uBAAuB,QAAQ,CAAC,CAAC,EACxD,EAAU,OAAO,GAErB,MACJ,CAEA,GAAI,CAEA,GADA,EAAS,MAAM,UAAU,aAAa,aAAa,EAAe,OAAO,EACrE,EAAW,CACX,EAAO,UAAU,CAAC,CAAC,QAAS,GAAU,EAAM,KAAK,CAAC,EAClD,MACJ,CACA,IAAM,EAAQ,EAAS,QACvB,GAAI,CAAC,EAAO,CACR,EAAO,UAAU,CAAC,CAAC,QAAS,GAAU,EAAM,KAAK,CAAC,EAClD,MACJ,CACA,EAAgB,EAChB,EAAM,UAAY,EAClB,EAAQ,CAAM,EACd,MAAM,EAAM,KAAK,CAAC,CAAC,UAAY,IAAA,EAAS,EACnC,GAAW,EAAU,OAAO,CACrC,OAAS,EAAK,CACL,IACD,EAAS,EAAc,CAAG,CAAC,EAC3B,EAAU,OAAO,EAEzB,CACJ,CAIA,OAFA,EAAW,MAEE,CACT,EAAY,GACR,GACA,EAAO,UAAU,CAAC,CAAC,QAAS,GAAU,EAAM,KAAK,CAAC,EAElD,IACA,EAAc,UAAY,MAE9B,EAAQ,IAAI,CAChB,CACJ,EAAG,CAAC,EAAY,CAAO,CAAC,EAEjB,CACH,SACA,QACA,WACA,OAAQ,EACR,UAAa,EAAe,GAAM,EAAI,CAAC,CAC3C,CACJ"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { classifyMediaError as e, missingCaptureApiError as t } from "../audio/media-access.js";
|
|
2
|
+
import { useEffect as n, useRef as r, useState as i } from "react";
|
|
2
3
|
//#region src/vision/use-camera-stream.ts
|
|
3
|
-
var
|
|
4
|
+
var a = {
|
|
4
5
|
video: {
|
|
5
6
|
facingMode: { ideal: "environment" },
|
|
6
7
|
width: { ideal: 1920 },
|
|
@@ -8,77 +9,59 @@ var r = {
|
|
|
8
9
|
},
|
|
9
10
|
audio: !1
|
|
10
11
|
};
|
|
11
|
-
function
|
|
12
|
-
if (typeof window > "u") return {
|
|
13
|
-
kind: "unsupported",
|
|
14
|
-
message: "Camera is unavailable in this environment."
|
|
15
|
-
};
|
|
16
|
-
if (!window.isSecureContext) return {
|
|
17
|
-
kind: "insecure",
|
|
18
|
-
message: "Camera access requires a secure (HTTPS) connection."
|
|
19
|
-
};
|
|
20
|
-
if (e instanceof DOMException) switch (e.name) {
|
|
21
|
-
case "NotAllowedError":
|
|
22
|
-
case "SecurityError": return {
|
|
23
|
-
kind: "permission-denied",
|
|
24
|
-
message: "Camera permission denied. Enable access in your browser settings."
|
|
25
|
-
};
|
|
26
|
-
case "NotFoundError":
|
|
27
|
-
case "OverconstrainedError": return {
|
|
28
|
-
kind: "no-camera",
|
|
29
|
-
message: "No camera available on this device."
|
|
30
|
-
};
|
|
31
|
-
case "NotReadableError":
|
|
32
|
-
case "AbortError": return {
|
|
33
|
-
kind: "in-use",
|
|
34
|
-
message: "The camera is in use by another app. Close it and try again."
|
|
35
|
-
};
|
|
36
|
-
}
|
|
12
|
+
function o({ kind: e, message: t }) {
|
|
37
13
|
return {
|
|
38
|
-
kind: "
|
|
39
|
-
message:
|
|
14
|
+
kind: e === "not-found" ? "no-camera" : e,
|
|
15
|
+
message: t
|
|
40
16
|
};
|
|
41
17
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
18
|
+
function s(t) {
|
|
19
|
+
return o(e(t, "camera"));
|
|
20
|
+
}
|
|
21
|
+
function c(e = {}) {
|
|
22
|
+
let [c, l] = i("loading"), [u, d] = i(null), [f, p] = i(null), [m, h] = i(0), g = r(null), _ = r(e.constraints ?? a);
|
|
23
|
+
n(() => {
|
|
24
|
+
_.current = e.constraints ?? a;
|
|
25
|
+
}, [e.constraints]);
|
|
26
|
+
let v = e.enabled ?? !0;
|
|
27
|
+
return n(() => {
|
|
28
|
+
let e = !1, n = null, r = null;
|
|
29
|
+
async function i() {
|
|
30
|
+
if (!v) {
|
|
31
|
+
l("idle"), d(null);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (l("loading"), d(null), typeof navigator > "u" || !navigator.mediaDevices || typeof navigator.mediaDevices.getUserMedia != "function") {
|
|
35
|
+
e || (d(o(t("camera"))), l("error"));
|
|
54
36
|
return;
|
|
55
37
|
}
|
|
56
38
|
try {
|
|
57
|
-
if (
|
|
58
|
-
|
|
39
|
+
if (n = await navigator.mediaDevices.getUserMedia(_.current), e) {
|
|
40
|
+
n.getTracks().forEach((e) => e.stop());
|
|
59
41
|
return;
|
|
60
42
|
}
|
|
61
|
-
let
|
|
62
|
-
if (!
|
|
63
|
-
|
|
43
|
+
let t = g.current;
|
|
44
|
+
if (!t) {
|
|
45
|
+
n.getTracks().forEach((e) => e.stop());
|
|
64
46
|
return;
|
|
65
47
|
}
|
|
66
|
-
|
|
48
|
+
r = t, t.srcObject = n, p(n), await t.play().catch(() => void 0), e || l("ready");
|
|
67
49
|
} catch (t) {
|
|
68
|
-
e || (
|
|
50
|
+
e || (d(s(t)), l("error"));
|
|
69
51
|
}
|
|
70
52
|
}
|
|
71
|
-
return
|
|
72
|
-
e = !0,
|
|
53
|
+
return i(), () => {
|
|
54
|
+
e = !0, n && n.getTracks().forEach((e) => e.stop()), r && (r.srcObject = null), p(null);
|
|
73
55
|
};
|
|
74
|
-
}, [
|
|
75
|
-
status:
|
|
76
|
-
error:
|
|
77
|
-
videoRef:
|
|
78
|
-
|
|
56
|
+
}, [m, v]), {
|
|
57
|
+
status: c,
|
|
58
|
+
error: u,
|
|
59
|
+
videoRef: g,
|
|
60
|
+
stream: f,
|
|
61
|
+
retry: () => h((e) => e + 1)
|
|
79
62
|
};
|
|
80
63
|
}
|
|
81
64
|
//#endregion
|
|
82
|
-
export {
|
|
65
|
+
export { c as useCameraStream };
|
|
83
66
|
|
|
84
67
|
//# sourceMappingURL=use-camera-stream.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-camera-stream.js","names":[],"sources":["../../src/vision/use-camera-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\n\n/** Lifecycle status of the camera stream. */\nexport type CameraStreamStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/** Classified reason a camera stream could not be acquired. */\nexport type CameraStreamErrorKind =\n \"unsupported\" | \"permission-denied\" | \"no-camera\" | \"in-use\" | \"insecure\" | \"unknown\";\n\n/** A classified camera error with a human-readable, English message. */\nexport interface CameraStreamError {\n kind: CameraStreamErrorKind;\n message: string;\n}\n\n/** Options for {@link useCameraStream}. */\nexport interface UseCameraStreamOptions {\n /**\n * Constraints passed to `getUserMedia`. Defaults to the rear\n * (\"environment\") camera at Full-HD ideal resolution with audio off.\n * Read when the stream (re)starts — change it and call `retry()` to apply.\n */\n constraints?: MediaStreamConstraints;\n}\n\n/** Value returned by {@link useCameraStream}. */\nexport interface UseCameraStreamApi {\n /** Current lifecycle status. */\n status: CameraStreamStatus;\n /** The classified error, or `null` while not in the `error` status. */\n error: CameraStreamError | null;\n /** Attach to a `<video ref={…} />`. The stream is wired to it once ready. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /** Manually re-attempt after an error (e.g. the user changed permissions). */\n retry: () => void;\n}\n\n/** Rear-camera Full-HD defaults used when no `constraints` are supplied. */\nconst DEFAULT_CONSTRAINTS: MediaStreamConstraints = {\n video: {\n facingMode: { ideal: \"environment\" },\n width: { ideal: 1920 },\n height: { ideal: 1080 },\n },\n audio: false,\n};\n\n/**\n *
|
|
1
|
+
{"version":3,"file":"use-camera-stream.js","names":[],"sources":["../../src/vision/use-camera-stream.ts"],"sourcesContent":["import { useEffect, useRef, useState, type RefObject } from \"react\";\n\nimport {\n classifyMediaError,\n missingCaptureApiError,\n type MediaAccessError,\n} from \"@/audio/media-access\";\n\n/** Lifecycle status of the camera stream. */\nexport type CameraStreamStatus = \"idle\" | \"loading\" | \"ready\" | \"error\";\n\n/** Classified reason a camera stream could not be acquired. */\nexport type CameraStreamErrorKind =\n \"unsupported\" | \"permission-denied\" | \"no-camera\" | \"in-use\" | \"insecure\" | \"unknown\";\n\n/** A classified camera error with a human-readable, English message. */\nexport interface CameraStreamError {\n kind: CameraStreamErrorKind;\n message: string;\n}\n\n/** Options for {@link useCameraStream}. */\nexport interface UseCameraStreamOptions {\n /**\n * Constraints passed to `getUserMedia`. Defaults to the rear\n * (\"environment\") camera at Full-HD ideal resolution with audio off.\n * Read when the stream (re)starts — change it and call `retry()` to apply.\n */\n constraints?: MediaStreamConstraints;\n /**\n * Hold off acquiring the camera until this is `true`. Default `true`.\n *\n * The point is to be able to *not* prompt. A permission prompt costs the user a\n * decision and, if they refuse, costs the app the feature permanently — so a\n * surface that already knows it cannot do its job (a barcode scanner in a browser\n * with no decoder) must not open the camera to then say so. Flipping this to `false`\n * also releases a stream that is already live.\n */\n enabled?: boolean;\n}\n\n/** Value returned by {@link useCameraStream}. */\nexport interface UseCameraStreamApi {\n /** Current lifecycle status. */\n status: CameraStreamStatus;\n /** The classified error, or `null` while not in the `error` status. */\n error: CameraStreamError | null;\n /** Attach to a `<video ref={…} />`. The stream is wired to it once ready. */\n videoRef: RefObject<HTMLVideoElement | null>;\n /**\n * The live stream, or `null`.\n *\n * Exposed for the things that need the **track** rather than the picture — the LED\n * torch (`useTorch`), the real frame size from `getSettings()`, recording it with\n * `useVideoRecorder`. Do not stop it yourself: the hook owns its lifetime and\n * releases it on unmount and on `retry()`.\n */\n stream: MediaStream | null;\n /** Manually re-attempt after an error (e.g. the user changed permissions). */\n retry: () => void;\n}\n\n/** Rear-camera Full-HD defaults used when no `constraints` are supplied. */\nconst DEFAULT_CONSTRAINTS: MediaStreamConstraints = {\n video: {\n facingMode: { ideal: \"environment\" },\n width: { ideal: 1920 },\n height: { ideal: 1080 },\n },\n audio: false,\n};\n\n/**\n * Re-label a {@link MediaAccessError} as a {@link CameraStreamError}.\n *\n * The classification itself lives in one place for the whole SDK\n * (`classifyMediaError`), so a microphone and a camera failure are never explained\n * two different ways. Only the name of one kind differs: this surface shipped\n * `\"no-camera\"` where the shared taxonomy says `\"not-found\"`, and renaming a\n * published union member would break every consumer switching on it.\n *\n * @param error - The shared classification.\n * @returns The same error under this module's kind names.\n */\nfunction toCameraError({ kind, message }: MediaAccessError): CameraStreamError {\n return { kind: kind === \"not-found\" ? \"no-camera\" : kind, message };\n}\n\n/**\n * Map an unknown `getUserMedia` failure into a {@link CameraStreamError}. Secure-context\n * and environment checks run first (they are the reason `getUserMedia` is missing or\n * rejects), then the `DOMException.name` is mapped to a stable `kind`.\n */\nfunction classifyError(err: unknown): CameraStreamError {\n return toCameraError(classifyMediaError(err, \"camera\"));\n}\n\n/**\n * Acquire a `MediaStream` via `getUserMedia`, attach it to a `<video>` element,\n * and expose status/error so the page can render permission and error states.\n * The stream is automatically released on unmount or retry.\n *\n * Defaults to the rear (\"environment\") camera; desktops fall back to whatever\n * single camera they expose. Pass `options.constraints` to override, or\n * `options.enabled: false` to render the surface without prompting for the camera\n * at all.\n *\n * Implementation notes:\n * - Cleanup detaches the stream from a *snapshotted* video node, so it releases\n * the same element it attached to even if the page remounts the `<video>`.\n * - When `getUserMedia` is missing, an insecure context is the usual cause, so\n * the hook prefers that (actionable) error; otherwise it reports `unsupported`.\n * - `video.play()` rejections are swallowed: autoplay may be blocked, but the\n * user gesture that opened the camera usually counts and playback resumes on\n * the next interaction.\n *\n * @param options - optional configuration (see {@link UseCameraStreamOptions}).\n * @returns The stream status, classified error, a `videoRef` to attach, the live\n * `stream` for whatever needs the track itself, and a `retry()` to re-attempt\n * acquisition.\n */\nexport function useCameraStream(options: UseCameraStreamOptions = {}): UseCameraStreamApi {\n const [status, setStatus] = useState<CameraStreamStatus>(\"loading\");\n const [error, setError] = useState<CameraStreamError | null>(null);\n const [live, setLive] = useState<MediaStream | null>(null);\n const [retryToken, setRetryToken] = useState(0);\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const constraintsRef = useRef<MediaStreamConstraints>(\n options.constraints ?? DEFAULT_CONSTRAINTS,\n );\n useEffect(() => {\n constraintsRef.current = options.constraints ?? DEFAULT_CONSTRAINTS;\n }, [options.constraints]);\n\n const enabled = options.enabled ?? true;\n\n useEffect(() => {\n let cancelled = false;\n let stream: MediaStream | null = null;\n let attachedVideo: HTMLVideoElement | null = null;\n\n async function start(): Promise<void> {\n if (!enabled) {\n setStatus(\"idle\");\n setError(null);\n return;\n }\n setStatus(\"loading\");\n setError(null);\n\n if (\n typeof navigator === \"undefined\" ||\n !navigator.mediaDevices ||\n typeof navigator.mediaDevices.getUserMedia !== \"function\"\n ) {\n if (!cancelled) {\n setError(toCameraError(missingCaptureApiError(\"camera\")));\n setStatus(\"error\");\n }\n return;\n }\n\n try {\n stream = await navigator.mediaDevices.getUserMedia(constraintsRef.current);\n if (cancelled) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n const video = videoRef.current;\n if (!video) {\n stream.getTracks().forEach((track) => track.stop());\n return;\n }\n attachedVideo = video;\n video.srcObject = stream;\n setLive(stream);\n await video.play().catch(() => undefined);\n if (!cancelled) setStatus(\"ready\");\n } catch (err) {\n if (!cancelled) {\n setError(classifyError(err));\n setStatus(\"error\");\n }\n }\n }\n\n void start();\n\n return () => {\n cancelled = true;\n if (stream) {\n stream.getTracks().forEach((track) => track.stop());\n }\n if (attachedVideo) {\n attachedVideo.srcObject = null;\n }\n setLive(null);\n };\n }, [retryToken, enabled]);\n\n return {\n status,\n error,\n videoRef,\n stream: live,\n retry: () => setRetryToken((n) => n + 1),\n };\n}\n"],"mappings":";;;AA+DA,IAAM,IAA8C;CAChD,OAAO;EACH,YAAY,EAAE,OAAO,cAAc;EACnC,OAAO,EAAE,OAAO,KAAK;EACrB,QAAQ,EAAE,OAAO,KAAK;CAC1B;CACA,OAAO;AACX;AAcA,SAAS,EAAc,EAAE,SAAM,cAAgD;CAC3E,OAAO;EAAE,MAAM,MAAS,cAAc,cAAc;EAAM;CAAQ;AACtE;AAOA,SAAS,EAAc,GAAiC;CACpD,OAAO,EAAc,EAAmB,GAAK,QAAQ,CAAC;AAC1D;AA0BA,SAAgB,EAAgB,IAAkC,CAAC,GAAuB;CACtF,IAAM,CAAC,GAAQ,KAAa,EAA6B,SAAS,GAC5D,CAAC,GAAO,KAAY,EAAmC,IAAI,GAC3D,CAAC,GAAM,KAAW,EAA6B,IAAI,GACnD,CAAC,GAAY,KAAiB,EAAS,CAAC,GACxC,IAAW,EAAgC,IAAI,GAC/C,IAAiB,EACnB,EAAQ,eAAe,CAC3B;CACA,QAAgB;EACZ,EAAe,UAAU,EAAQ,eAAe;CACpD,GAAG,CAAC,EAAQ,WAAW,CAAC;CAExB,IAAM,IAAU,EAAQ,WAAW;CAkEnC,OAhEA,QAAgB;EACZ,IAAI,IAAY,IACZ,IAA6B,MAC7B,IAAyC;EAE7C,eAAe,IAAuB;GAClC,IAAI,CAAC,GAAS;IAEV,AADA,EAAU,MAAM,GAChB,EAAS,IAAI;IACb;GACJ;GAIA,IAHA,EAAU,SAAS,GACnB,EAAS,IAAI,GAGT,OAAO,YAAc,OACrB,CAAC,UAAU,gBACX,OAAO,UAAU,aAAa,gBAAiB,YACjD;IACE,AAAK,MACD,EAAS,EAAc,EAAuB,QAAQ,CAAC,CAAC,GACxD,EAAU,OAAO;IAErB;GACJ;GAEA,IAAI;IAEA,IADA,IAAS,MAAM,UAAU,aAAa,aAAa,EAAe,OAAO,GACrE,GAAW;KACX,EAAO,UAAU,CAAC,CAAC,SAAS,MAAU,EAAM,KAAK,CAAC;KAClD;IACJ;IACA,IAAM,IAAQ,EAAS;IACvB,IAAI,CAAC,GAAO;KACR,EAAO,UAAU,CAAC,CAAC,SAAS,MAAU,EAAM,KAAK,CAAC;KAClD;IACJ;IAKA,AAJA,IAAgB,GAChB,EAAM,YAAY,GAClB,EAAQ,CAAM,GACd,MAAM,EAAM,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS,GACnC,KAAW,EAAU,OAAO;GACrC,SAAS,GAAK;IACV,AAAK,MACD,EAAS,EAAc,CAAG,CAAC,GAC3B,EAAU,OAAO;GAEzB;EACJ;EAIA,OAFA,EAAW,SAEE;GAQT,AAPA,IAAY,IACR,KACA,EAAO,UAAU,CAAC,CAAC,SAAS,MAAU,EAAM,KAAK,CAAC,GAElD,MACA,EAAc,YAAY,OAE9B,EAAQ,IAAI;EAChB;CACJ,GAAG,CAAC,GAAY,CAAO,CAAC,GAEjB;EACH;EACA;EACA;EACA,QAAQ;EACR,aAAa,GAAe,MAAM,IAAI,CAAC;CAC3C;AACJ"}
|
package/dist/vision.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./vision/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./vision/use-camera-stream.cjs"),t=require("./vision/core/exceptions.cjs"),n=require("./vision/types.cjs"),r=require("./vision/core/timing.cjs"),i=require("./vision/results.cjs"),a=require("./vision/labels.cjs"),o=require("./vision/core/graph.cjs"),s=require("./vision/core/providers.cjs"),c=require("./vision/core/session.cjs"),l=require("./vision/io/image.cjs"),u=require("./vision/preprocess/image.cjs"),d=require("./vision/postprocess/classification.cjs"),f=require("./vision/postprocess/detection.cjs"),p=require("./vision/postprocess/segmentation.cjs"),m=require("./vision/tasks/base.cjs"),h=require("./vision/tasks/classifier.cjs"),g=require("./vision/tasks/detector.cjs"),_=require("./vision/tasks/segmenter.cjs"),v=require("./vision/index.cjs"),y=require("./vision/luminance.cjs"),b=require("./vision/use-live-luminance.cjs");exports.BoundingBox=n.BoundingBox,exports.Boxes=i.Boxes,exports.COCO_CLASSES=a.COCO_CLASSES,exports.ClassificationResults=i.ClassificationResults,exports.Classifier=h.Classifier,exports.DEFAULT_PROVIDERS=s.DEFAULT_PROVIDERS,exports.DetectionResults=i.DetectionResults,exports.Detector=g.Detector,exports.ImageLoadError=t.ImageLoadError,exports.InferenceError=t.InferenceError,exports.LUMINANCE_SAMPLE_MAX_EDGE=y.LUMINANCE_SAMPLE_MAX_EDGE,exports.LabelMapError=t.LabelMapError,exports.LowLuminanceError=y.LowLuminanceError,exports.Mask=n.Mask,exports.Masks=i.Masks,exports.ModelLoadError=t.ModelLoadError,exports.OrtSession=c.OrtSession,exports.OrtVisionError=t.OrtVisionError,exports.Probs=i.Probs,exports.ProviderNotAvailableError=t.ProviderNotAvailableError,exports.RGBImage=n.RGBImage,exports.SegmentationResults=i.SegmentationResults,exports.Segmenter=_.Segmenter,exports.SpeedTimer=r.SpeedTimer,exports.VERSION=v.VERSION,exports.VisionTask=m.VisionTask,exports.batchedNms=f.batchedNms,exports.computeImageLuminance=y.computeImageLuminance,exports.declaredShapesFrom=o.declaredShapesFrom,exports.decodeYolo=f.decodeYolo,exports.decodeYoloAnchors=f.decodeYoloAnchors,exports.decodeYoloSeg=p.decodeYoloSeg,exports.decodeYoloV8=f.decodeYoloV8,exports.decodeYoloV8Anchors=f.decodeYoloV8Anchors,exports.decodeYoloV8Seg=p.decodeYoloV8Seg,exports.fromCv2=u.fromCv2,exports.isLuminanceAcceptable=y.isLuminanceAcceptable,exports.letterbox=u.letterbox,exports.loadImage=l.loadImage,exports.nms=f.nms,exports.normalize=u.normalize,exports.resize=u.resize,exports.resolveInputSize=o.resolveInputSize,exports.resolveLabels=a.resolveLabels,exports.resolveProviders=s.resolveProviders,exports.softmax=d.softmax,exports.spatialInputSize=o.spatialInputSize,exports.toCHW=u.toCHW,exports.toCv2=u.toCv2,exports.toFloat32=u.toFloat32,exports.toFloat32Tensor=u.toFloat32Tensor,exports.toTensor=u.toTensor,exports.topK=d.topK,exports.useCameraStream=e.useCameraStream,exports.useLiveLuminance=b.useLiveLuminance;
|
package/dist/vision.d.ts
CHANGED
|
@@ -196,6 +196,14 @@ export declare class Classifier extends VisionTask {
|
|
|
196
196
|
get labels(): readonly string[];
|
|
197
197
|
/** Class id → class name dict (matches Ultralytics' `model.names`). */
|
|
198
198
|
get names(): Readonly<Record<number, string>>;
|
|
199
|
+
/**
|
|
200
|
+
* The `[width, height]` this task preprocesses to.
|
|
201
|
+
*
|
|
202
|
+
* Resolved at creation time from the model's graph when it declares a static
|
|
203
|
+
* input, so reading it back tells you the resolution inference really runs at
|
|
204
|
+
* — not merely what was requested.
|
|
205
|
+
*/
|
|
206
|
+
get inputSize(): readonly [number, number];
|
|
199
207
|
/** Number of classes the model can predict. */
|
|
200
208
|
get numClasses(): number;
|
|
201
209
|
/** Alias for {@link predict} (parity with PyTorch `nn.Module.__call__`). */
|
|
@@ -214,7 +222,13 @@ export declare interface ClassifierOptions extends OrtSessionOptions {
|
|
|
214
222
|
* or when you want to validate that the supplied labels match the model.
|
|
215
223
|
*/
|
|
216
224
|
readonly numClasses?: number;
|
|
217
|
-
/**
|
|
225
|
+
/**
|
|
226
|
+
* Model input `[width, height]` in pixels.
|
|
227
|
+
*
|
|
228
|
+
* Only used when the model's graph leaves its spatial axes dynamic: a graph
|
|
229
|
+
* that declares a static size always wins, since that is the only shape ONNX
|
|
230
|
+
* Runtime will accept. Defaults to `[224, 224]`.
|
|
231
|
+
*/
|
|
218
232
|
readonly inputSize?: readonly [number, number];
|
|
219
233
|
/** Per-channel RGB mean used for normalization. Defaults to ImageNet. */
|
|
220
234
|
readonly mean?: readonly [number, number, number];
|
|
@@ -277,6 +291,26 @@ export declare const COCO_CLASSES: readonly string[];
|
|
|
277
291
|
*/
|
|
278
292
|
export declare function computeImageLuminance(source: LuminanceSource, reusableCanvas?: HTMLCanvasElement): number;
|
|
279
293
|
|
|
294
|
+
/**
|
|
295
|
+
* One declared dimension: a number when the graph pins it, `null` when the
|
|
296
|
+
* dimension is symbolic (dynamic).
|
|
297
|
+
*/
|
|
298
|
+
export declare type DeclaredDim = number | null;
|
|
299
|
+
|
|
300
|
+
/** A declared input/output shape, dynamic axes appearing as `null`. */
|
|
301
|
+
export declare type DeclaredShape = readonly DeclaredDim[];
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Convert ORT value metadata into declared shapes.
|
|
305
|
+
*
|
|
306
|
+
* @param metadata Metadata as reported by `InferenceSession.inputMetadata`, or
|
|
307
|
+
* `undefined` on ORT builds that predate it (added in onnxruntime 1.21).
|
|
308
|
+
* @returns One shape per value, in declaration order. Non-tensor values and
|
|
309
|
+
* builds without metadata yield empty shapes, which read as "nothing
|
|
310
|
+
* declared" everywhere downstream.
|
|
311
|
+
*/
|
|
312
|
+
export declare function declaredShapesFrom(metadata: readonly ort.InferenceSession.ValueMetadata[] | undefined): readonly DeclaredShape[];
|
|
313
|
+
|
|
280
314
|
export declare interface DecodedAnchors {
|
|
281
315
|
/** Indices into the original `numAnchors` axis, in descending confidence order. */
|
|
282
316
|
readonly anchorIndices: Int32Array;
|
|
@@ -504,6 +538,14 @@ export declare class Detector extends VisionTask {
|
|
|
504
538
|
get labels(): readonly string[];
|
|
505
539
|
/** Class id → class name dict (matches Ultralytics' `model.names`). */
|
|
506
540
|
get names(): Readonly<Record<number, string>>;
|
|
541
|
+
/**
|
|
542
|
+
* The `[width, height]` this task preprocesses to.
|
|
543
|
+
*
|
|
544
|
+
* Resolved at creation time from the model's graph when it declares a static
|
|
545
|
+
* input, so reading it back tells you the resolution inference really runs at
|
|
546
|
+
* — not merely what was requested.
|
|
547
|
+
*/
|
|
548
|
+
get inputSize(): readonly [number, number];
|
|
507
549
|
/** Number of classes the model predicts. */
|
|
508
550
|
get numClasses(): number;
|
|
509
551
|
/**
|
|
@@ -548,7 +590,13 @@ export declare interface DetectorOptions extends OrtSessionOptions {
|
|
|
548
590
|
readonly labels?: LabelSpec;
|
|
549
591
|
/** Number of classes — used to validate the supplied labels. */
|
|
550
592
|
readonly numClasses?: number;
|
|
551
|
-
/**
|
|
593
|
+
/**
|
|
594
|
+
* Model input `[width, height]` in pixels for letterboxing.
|
|
595
|
+
*
|
|
596
|
+
* Only used when the model's graph leaves its spatial axes dynamic: a graph
|
|
597
|
+
* that declares a static size always wins, since that is the only shape ONNX
|
|
598
|
+
* Runtime will accept. Defaults to `[640, 640]`.
|
|
599
|
+
*/
|
|
552
600
|
readonly inputSize?: readonly [number, number];
|
|
553
601
|
/** Default minimum class score to keep a candidate. */
|
|
554
602
|
readonly confThreshold?: number;
|
|
@@ -763,8 +811,9 @@ export declare interface LetterboxResult {
|
|
|
763
811
|
/**
|
|
764
812
|
* Wrap an ONNX Runtime Web `InferenceSession` with convenient metadata access.
|
|
765
813
|
*
|
|
766
|
-
* The wrapper exposes input/output names
|
|
767
|
-
* selection,
|
|
814
|
+
* The wrapper exposes input/output names and the shapes the graph declares,
|
|
815
|
+
* manages execution-provider selection, provides a typed {@link OrtSession.run}
|
|
816
|
+
* method, and releases the native session through {@link OrtSession.release}.
|
|
768
817
|
*/
|
|
769
818
|
export declare class OrtSession {
|
|
770
819
|
private readonly _session;
|
|
@@ -784,6 +833,29 @@ export declare interface LetterboxResult {
|
|
|
784
833
|
get inputName(): string;
|
|
785
834
|
/** Names of the model's outputs, in declaration order. */
|
|
786
835
|
get outputNames(): readonly string[];
|
|
836
|
+
/**
|
|
837
|
+
* Shapes the graph declares for its inputs, in declaration order.
|
|
838
|
+
*
|
|
839
|
+
* Dynamic (symbolic) axes appear as `null`. Empty shapes mean the runtime
|
|
840
|
+
* reported no metadata — either a non-tensor input, or an `onnxruntime-web`
|
|
841
|
+
* older than 1.21, which predates input metadata.
|
|
842
|
+
*/
|
|
843
|
+
get inputShapes(): readonly DeclaredShape[];
|
|
844
|
+
/**
|
|
845
|
+
* Shape the graph declares for its first input, dynamic axes as `null`.
|
|
846
|
+
*
|
|
847
|
+
* Empty when the runtime reports no metadata for it.
|
|
848
|
+
*/
|
|
849
|
+
get inputShape(): DeclaredShape;
|
|
850
|
+
/**
|
|
851
|
+
* Release the native session and free its memory.
|
|
852
|
+
*
|
|
853
|
+
* Call it when a session is discarded while the page lives on — rebuilding a
|
|
854
|
+
* task at a different input size, swapping in a newer model. A failure from
|
|
855
|
+
* the runtime is ignored: a session being torn down has nothing left to fail
|
|
856
|
+
* at, and the caller is already moving on.
|
|
857
|
+
*/
|
|
858
|
+
release(): Promise<void>;
|
|
787
859
|
/** The underlying `onnxruntime-web` session, for advanced use cases. */
|
|
788
860
|
get raw(): ort.InferenceSession;
|
|
789
861
|
/**
|
|
@@ -843,6 +915,29 @@ export declare interface LetterboxResult {
|
|
|
843
915
|
/** Resize an image to `(targetWidth, targetHeight)` using high-quality canvas resampling. */
|
|
844
916
|
export declare function resize(image: RGBImage, targetWidth: number, targetHeight: number): RGBImage;
|
|
845
917
|
|
|
918
|
+
/**
|
|
919
|
+
* Decide the input size a task will preprocess to.
|
|
920
|
+
*
|
|
921
|
+
* Precedence is graph → caller → fallback. The graph wins over an explicit
|
|
922
|
+
* `inputSize` because a static shape is not a preference, it is what ORT will
|
|
923
|
+
* accept: honoring the caller there would only turn a fixable mismatch into a
|
|
924
|
+
* failed run. A disagreement is a configuration bug in the caller, so it is
|
|
925
|
+
* reported through `console.warn` instead of being swallowed.
|
|
926
|
+
*
|
|
927
|
+
* @param options Graph shape, requested size and per-task fallback.
|
|
928
|
+
* @returns The `[width, height]` to preprocess to.
|
|
929
|
+
*/
|
|
930
|
+
export declare function resolveInputSize(options: ResolveInputSizeOptions): readonly [number, number];
|
|
931
|
+
|
|
932
|
+
export declare interface ResolveInputSizeOptions {
|
|
933
|
+
/** Declared shape of the model's image input, from {@link declaredShapesFrom}. */
|
|
934
|
+
readonly graphShape?: DeclaredShape;
|
|
935
|
+
/** Size the caller asked for, if any. */
|
|
936
|
+
readonly requested?: readonly [number, number];
|
|
937
|
+
/** Size to use when neither the graph nor the caller pins one. */
|
|
938
|
+
readonly fallback: readonly [number, number];
|
|
939
|
+
}
|
|
940
|
+
|
|
846
941
|
/**
|
|
847
942
|
* Resolve a labels specification into an ordered array of class names.
|
|
848
943
|
*
|
|
@@ -991,6 +1086,14 @@ export declare interface LetterboxResult {
|
|
|
991
1086
|
get labels(): readonly string[];
|
|
992
1087
|
/** Class id → class name dict (matches Ultralytics' `model.names`). */
|
|
993
1088
|
get names(): Readonly<Record<number, string>>;
|
|
1089
|
+
/**
|
|
1090
|
+
* The `[width, height]` this task preprocesses to.
|
|
1091
|
+
*
|
|
1092
|
+
* Resolved at creation time from the model's graph when it declares a static
|
|
1093
|
+
* input, so reading it back tells you the resolution inference really runs at
|
|
1094
|
+
* — not merely what was requested.
|
|
1095
|
+
*/
|
|
1096
|
+
get inputSize(): readonly [number, number];
|
|
994
1097
|
/** Number of classes the model predicts. */
|
|
995
1098
|
get numClasses(): number;
|
|
996
1099
|
/** Alias for {@link predict} (parity with PyTorch `nn.Module.__call__`). */
|
|
@@ -1026,7 +1129,13 @@ export declare interface LetterboxResult {
|
|
|
1026
1129
|
readonly labels?: LabelSpec;
|
|
1027
1130
|
/** Number of classes — used to validate the supplied labels. */
|
|
1028
1131
|
readonly numClasses?: number;
|
|
1029
|
-
/**
|
|
1132
|
+
/**
|
|
1133
|
+
* Model input `[width, height]` in pixels for letterboxing.
|
|
1134
|
+
*
|
|
1135
|
+
* Only used when the model's graph leaves its spatial axes dynamic: a graph
|
|
1136
|
+
* that declares a static size always wins, since that is the only shape ONNX
|
|
1137
|
+
* Runtime will accept. Defaults to `[640, 640]`.
|
|
1138
|
+
*/
|
|
1030
1139
|
readonly inputSize?: readonly [number, number];
|
|
1031
1140
|
/** Default minimum class score to keep a candidate. */
|
|
1032
1141
|
readonly confThreshold?: number;
|
|
@@ -1054,6 +1163,16 @@ export declare interface LetterboxResult {
|
|
|
1054
1163
|
/** Apply numerically-stable softmax to a 1-D vector of logits. */
|
|
1055
1164
|
export declare function softmax(logits: Float32Array | readonly number[]): Float32Array;
|
|
1056
1165
|
|
|
1166
|
+
/**
|
|
1167
|
+
* Read the spatial input size out of a declared NCHW shape.
|
|
1168
|
+
*
|
|
1169
|
+
* @param shape The declared shape of the model's image input.
|
|
1170
|
+
* @returns `[width, height]` in pixels, or `null` when the shape is not 4D or
|
|
1171
|
+
* leaves either spatial axis dynamic — in which case the model accepts more
|
|
1172
|
+
* than one resolution and there is nothing to correct.
|
|
1173
|
+
*/
|
|
1174
|
+
export declare function spatialInputSize(shape: DeclaredShape): readonly [number, number] | null;
|
|
1175
|
+
|
|
1057
1176
|
/**
|
|
1058
1177
|
* Per-stage timing for a single `predict()` call.
|
|
1059
1178
|
*
|
|
@@ -1156,7 +1275,9 @@ export declare interface LetterboxResult {
|
|
|
1156
1275
|
* The stream is automatically released on unmount or retry.
|
|
1157
1276
|
*
|
|
1158
1277
|
* Defaults to the rear ("environment") camera; desktops fall back to whatever
|
|
1159
|
-
* single camera they expose. Pass `options.constraints` to override
|
|
1278
|
+
* single camera they expose. Pass `options.constraints` to override, or
|
|
1279
|
+
* `options.enabled: false` to render the surface without prompting for the camera
|
|
1280
|
+
* at all.
|
|
1160
1281
|
*
|
|
1161
1282
|
* Implementation notes:
|
|
1162
1283
|
* - Cleanup detaches the stream from a *snapshotted* video node, so it releases
|
|
@@ -1168,8 +1289,9 @@ export declare interface LetterboxResult {
|
|
|
1168
1289
|
* the next interaction.
|
|
1169
1290
|
*
|
|
1170
1291
|
* @param options - optional configuration (see {@link UseCameraStreamOptions}).
|
|
1171
|
-
* @returns The stream status, classified error, a `videoRef` to attach,
|
|
1172
|
-
* `retry()` to re-attempt
|
|
1292
|
+
* @returns The stream status, classified error, a `videoRef` to attach, the live
|
|
1293
|
+
* `stream` for whatever needs the track itself, and a `retry()` to re-attempt
|
|
1294
|
+
* acquisition.
|
|
1173
1295
|
*/
|
|
1174
1296
|
export declare function useCameraStream(options?: UseCameraStreamOptions): UseCameraStreamApi;
|
|
1175
1297
|
|
|
@@ -1181,6 +1303,15 @@ export declare interface LetterboxResult {
|
|
|
1181
1303
|
error: CameraStreamError | null;
|
|
1182
1304
|
/** Attach to a `<video ref={…} />`. The stream is wired to it once ready. */
|
|
1183
1305
|
videoRef: RefObject<HTMLVideoElement | null>;
|
|
1306
|
+
/**
|
|
1307
|
+
* The live stream, or `null`.
|
|
1308
|
+
*
|
|
1309
|
+
* Exposed for the things that need the **track** rather than the picture — the LED
|
|
1310
|
+
* torch (`useTorch`), the real frame size from `getSettings()`, recording it with
|
|
1311
|
+
* `useVideoRecorder`. Do not stop it yourself: the hook owns its lifetime and
|
|
1312
|
+
* releases it on unmount and on `retry()`.
|
|
1313
|
+
*/
|
|
1314
|
+
stream: MediaStream | null;
|
|
1184
1315
|
/** Manually re-attempt after an error (e.g. the user changed permissions). */
|
|
1185
1316
|
retry: () => void;
|
|
1186
1317
|
}
|
|
@@ -1193,6 +1324,16 @@ export declare interface LetterboxResult {
|
|
|
1193
1324
|
* Read when the stream (re)starts — change it and call `retry()` to apply.
|
|
1194
1325
|
*/
|
|
1195
1326
|
constraints?: MediaStreamConstraints;
|
|
1327
|
+
/**
|
|
1328
|
+
* Hold off acquiring the camera until this is `true`. Default `true`.
|
|
1329
|
+
*
|
|
1330
|
+
* The point is to be able to *not* prompt. A permission prompt costs the user a
|
|
1331
|
+
* decision and, if they refuse, costs the app the feature permanently — so a
|
|
1332
|
+
* surface that already knows it cannot do its job (a barcode scanner in a browser
|
|
1333
|
+
* with no decoder) must not open the camera to then say so. Flipping this to `false`
|
|
1334
|
+
* also releases a stream that is already live.
|
|
1335
|
+
*/
|
|
1336
|
+
enabled?: boolean;
|
|
1196
1337
|
}
|
|
1197
1338
|
|
|
1198
1339
|
/**
|
package/dist/vision.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
|
|
1
|
+
import { useCameraStream as e } from "./vision/use-camera-stream.js";
|
|
2
|
+
import { ImageLoadError as t, InferenceError as n, LabelMapError as r, ModelLoadError as i, OrtVisionError as a, ProviderNotAvailableError as o } from "./vision/core/exceptions.js";
|
|
3
|
+
import { BoundingBox as s, Mask as c, RGBImage as l } from "./vision/types.js";
|
|
4
|
+
import { SpeedTimer as u } from "./vision/core/timing.js";
|
|
5
|
+
import { Boxes as d, ClassificationResults as f, DetectionResults as p, Masks as m, Probs as h, SegmentationResults as g } from "./vision/results.js";
|
|
6
|
+
import { COCO_CLASSES as _, resolveLabels as v } from "./vision/labels.js";
|
|
7
|
+
import { declaredShapesFrom as y, resolveInputSize as b, spatialInputSize as x } from "./vision/core/graph.js";
|
|
8
|
+
import { DEFAULT_PROVIDERS as S, resolveProviders as C } from "./vision/core/providers.js";
|
|
9
|
+
import { OrtSession as w } from "./vision/core/session.js";
|
|
10
|
+
import { loadImage as T } from "./vision/io/image.js";
|
|
11
|
+
import { fromCv2 as E, letterbox as D, normalize as O, resize as k, toCHW as A, toCv2 as j, toFloat32 as M, toFloat32Tensor as N, toTensor as P } from "./vision/preprocess/image.js";
|
|
12
|
+
import { softmax as F, topK as I } from "./vision/postprocess/classification.js";
|
|
13
|
+
import { batchedNms as L, decodeYolo as R, decodeYoloAnchors as z, decodeYoloV8 as B, decodeYoloV8Anchors as V, nms as H } from "./vision/postprocess/detection.js";
|
|
14
|
+
import { decodeYoloSeg as U, decodeYoloV8Seg as W } from "./vision/postprocess/segmentation.js";
|
|
15
|
+
import { VisionTask as G } from "./vision/tasks/base.js";
|
|
16
|
+
import { Classifier as K } from "./vision/tasks/classifier.js";
|
|
17
|
+
import { Detector as q } from "./vision/tasks/detector.js";
|
|
18
|
+
import { Segmenter as J } from "./vision/tasks/segmenter.js";
|
|
19
|
+
import { VERSION as Y } from "./vision/index.js";
|
|
20
|
+
import { LUMINANCE_SAMPLE_MAX_EDGE as X, LowLuminanceError as Z, computeImageLuminance as Q, isLuminanceAcceptable as $ } from "./vision/luminance.js";
|
|
21
|
+
import { useLiveLuminance as ee } from "./vision/use-live-luminance.js";
|
|
22
|
+
export { s as BoundingBox, d as Boxes, _ as COCO_CLASSES, f as ClassificationResults, K as Classifier, S as DEFAULT_PROVIDERS, p as DetectionResults, q as Detector, t as ImageLoadError, n as InferenceError, X as LUMINANCE_SAMPLE_MAX_EDGE, r as LabelMapError, Z as LowLuminanceError, c as Mask, m as Masks, i as ModelLoadError, w as OrtSession, a as OrtVisionError, h as Probs, o as ProviderNotAvailableError, l as RGBImage, g as SegmentationResults, J as Segmenter, u as SpeedTimer, Y as VERSION, G as VisionTask, L as batchedNms, Q as computeImageLuminance, y as declaredShapesFrom, R as decodeYolo, z as decodeYoloAnchors, U as decodeYoloSeg, B as decodeYoloV8, V as decodeYoloV8Anchors, W as decodeYoloV8Seg, E as fromCv2, $ as isLuminanceAcceptable, D as letterbox, T as loadImage, H as nms, O as normalize, k as resize, b as resolveInputSize, v as resolveLabels, C as resolveProviders, F as softmax, x as spatialInputSize, A as toCHW, j as toCv2, M as toFloat32, N as toFloat32Tensor, P as toTensor, I as topK, e as useCameraStream, ee as useLiveLuminance };
|