{"version":3,"file":"use-torch.cjs","names":[],"sources":["../../src/capture/use-torch.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from \"react\";\n\n/**\n * `torch` is a real constrainable property in the Media Capture spec, but\n * TypeScript's `MediaTrackConstraintSet` does not list it, so the literal has to be\n * widened before `applyConstraints` will take it.\n */\ntype TorchConstraints = MediaTrackConstraints & {\n    advanced?: Array<MediaTrackConstraintSet & { torch?: boolean }>;\n};\n\n/** `getCapabilities()` reports `torch` as a list of the values the lamp accepts. */\ntype TorchCapabilities = MediaTrackCapabilities & { torch?: readonly boolean[] };\n\n/** Value returned by {@link useTorch}. */\nexport interface UseTorchResult {\n    /** Whether this track has a controllable lamp. `false` on every desktop webcam. */\n    supported: boolean;\n    /** Whether the lamp is on, as far as this hook knows. */\n    on: boolean;\n    /**\n     * Turn the lamp on or off.\n     *\n     * @param next - `true` to light it up.\n     * @returns `false` when the track refused — treat that as \"no torch\".\n     */\n    set: (next: boolean) => Promise<boolean>;\n    /** Flip it. Same return contract as {@link UseTorchResult.set}. */\n    toggle: () => Promise<boolean>;\n}\n\n/**\n * Drive the camera's LED torch on the video track of a stream.\n *\n * The lamp is not a device you can open — it is a **constraint on a live video\n * track**, so there is nothing to control until a camera stream exists, and it\n * disappears when that stream is released. That is also why `supported` can only be\n * answered after the track is live: the same code is `true` on an Android rear camera\n * and `false` on the front one of the same phone.\n *\n * Capability detection prefers `getCapabilities()` and falls back to\n * `getSettings()`, because Firefox implements neither the torch nor\n * `getCapabilities()` and Safari reports the setting without the capability. When\n * neither mentions `torch`, the hook reports `supported: false` instead of offering a\n * button that silently does nothing.\n *\n * @param stream - A live camera stream, or `null` before permission lands.\n * @returns Whether a lamp exists, its state, and setters.\n *\n * @example\n * const camera = useBarcodeScanner();\n * {camera.torch.supported && (\n *     <button onClick={() => void camera.torch.toggle()}>Lanterna</button>\n * )}\n */\nexport function useTorch(stream: MediaStream | null): UseTorchResult {\n    const [supported, setSupported] = useState(false);\n    const [on, setOn] = useState(false);\n\n    useEffect(() => {\n        const track = stream?.getVideoTracks()[0] ?? null;\n        if (!track) {\n            setSupported(false);\n            setOn(false);\n            return;\n        }\n        const capabilities = (track.getCapabilities?.() ?? {}) as TorchCapabilities;\n        const settings = track.getSettings();\n        setSupported(capabilities.torch !== undefined || settings.torch !== undefined);\n        setOn(settings.torch === true);\n    }, [stream]);\n\n    const set = useCallback(\n        async (next: boolean): Promise<boolean> => {\n            const track = stream?.getVideoTracks()[0] ?? null;\n            if (!track) return false;\n            try {\n                await track.applyConstraints({\n                    advanced: [{ torch: next }],\n                } as TorchConstraints);\n                setOn(next);\n                return true;\n            } catch {\n                // A track without a lamp rejects with `OverconstrainedError`. There is\n                // nothing for the user to fix, and the honest report is \"no torch\".\n                setSupported(false);\n                setOn(false);\n                return false;\n            }\n        },\n        [stream],\n    );\n\n    const toggle = useCallback((): Promise<boolean> => set(!on), [set, on]);\n\n    return { supported, on, set, toggle };\n}\n"],"mappings":"uBAuDA,SAAgB,EAAS,EAA4C,CACjE,GAAM,CAAC,EAAW,IAAA,EAAgB,EAAA,SAAA,CAAS,EAAK,EAC1C,CAAC,EAAI,IAAA,EAAS,EAAA,SAAA,CAAS,EAAK,GAElC,EAAA,EAAA,UAAA,KAAgB,CACZ,IAAM,EAAQ,GAAQ,eAAe,CAAC,CAAC,IAAM,KAC7C,GAAI,CAAC,EAAO,CACR,EAAa,EAAK,EAClB,EAAM,EAAK,EACX,MACJ,CACA,IAAM,EAAgB,EAAM,kBAAkB,GAAK,CAAC,EAC9C,EAAW,EAAM,YAAY,EACnC,EAAa,EAAa,QAAU,IAAA,IAAa,EAAS,QAAU,IAAA,EAAS,EAC7E,EAAM,EAAS,QAAU,EAAI,CACjC,EAAG,CAAC,CAAM,CAAC,EAEX,IAAM,GAAA,EAAM,EAAA,YAAA,CACR,KAAO,IAAoC,CACvC,IAAM,EAAQ,GAAQ,eAAe,CAAC,CAAC,IAAM,KAC7C,GAAI,CAAC,EAAO,MAAO,GACnB,GAAI,CAKA,OAJA,MAAM,EAAM,iBAAiB,CACzB,SAAU,CAAC,CAAE,MAAO,CAAK,CAAC,CAC9B,CAAqB,EACrB,EAAM,CAAI,EACH,EACX,MAAQ,CAKJ,OAFA,EAAa,EAAK,EAClB,EAAM,EAAK,EACJ,EACX,CACJ,EACA,CAAC,CAAM,CACX,EAIA,MAAO,CAAE,YAAW,KAAI,MAAK,QAAA,EAFd,EAAA,YAAA,KAAoC,EAAI,CAAC,CAAE,EAAG,CAAC,EAAK,CAAE,CAExC,CAAO,CACxC"}