1import * as React from 'react';
2import { captureImageData } from './WebCameraUtils';
3const qrWorkerMethod = ({ data, width, height }) => {
4    // eslint-disable-next-line no-undef
5    const decoded = self.jsQR(data, width, height, {
6        inversionAttempts: 'attemptBoth',
7    });
8    let parsed;
9    try {
10        parsed = JSON.parse(decoded);
11    }
12    catch {
13        parsed = decoded;
14    }
15    if (parsed?.data) {
16        const nativeEvent = {
17            type: 'qr',
18            data: parsed.data,
19            cornerPoints: [],
20            bounds: { origin: { x: 0, y: 0 }, size: { width: 0, height: 0 } },
21        };
22        if (parsed.location) {
23            nativeEvent.cornerPoints = [
24                parsed.location.topLeftCorner,
25                parsed.location.bottomLeftCorner,
26                parsed.location.topRightCorner,
27                parsed.location.bottomRightCorner,
28            ];
29        }
30        return nativeEvent;
31    }
32    return parsed;
33};
34const createWorkerAsyncFunction = (fn, deps) => {
35    const stringifiedFn = [
36        `self.func = ${fn.toString()};`,
37        'self.onmessage = (e) => {',
38        '  const result = self.func(e.data);',
39        '  self.postMessage(result);',
40        '};',
41    ];
42    if (deps.length > 0) {
43        stringifiedFn.unshift(`importScripts(${deps.map((dep) => `'${dep}'`).join(', ')});`);
44    }
45    const blob = new Blob(stringifiedFn, { type: 'text/javascript' });
46    const worker = new Worker(URL.createObjectURL(blob));
47    // First-In First-Out queue of promises
48    const promises = [];
49    worker.onmessage = (e) => promises.shift()?.resolve(e.data);
50    return (data) => {
51        return new Promise((resolve, reject) => {
52            promises.push({ resolve, reject });
53            worker.postMessage(data);
54        });
55    };
56};
57const decode = createWorkerAsyncFunction(qrWorkerMethod, [
58    'https://cdn.jsdelivr.net/npm/[email protected]/dist/jsQR.min.js',
59]);
60export function useWebQRScanner(video, { isEnabled, captureOptions, interval, onScanned, onError, }) {
61    const isRunning = React.useRef(false);
62    const timeout = React.useRef(undefined);
63    async function scanAsync() {
64        // If interval is 0 then only scan once.
65        if (!isRunning.current || !onScanned) {
66            stop();
67            return;
68        }
69        try {
70            const data = captureImageData(video.current, captureOptions);
71            if (data) {
72                const nativeEvent = await decode(data);
73                if (nativeEvent?.data) {
74                    onScanned({
75                        nativeEvent,
76                    });
77                }
78            }
79        }
80        catch (error) {
81            if (onError) {
82                onError({ nativeEvent: error });
83            }
84        }
85        finally {
86            // If interval is 0 then only scan once.
87            if (interval === 0) {
88                stop();
89                return;
90            }
91            const intervalToUse = !interval || interval < 0 ? 16 : interval;
92            // @ts-ignore: Type 'Timeout' is not assignable to type 'number'
93            timeout.current = setTimeout(() => {
94                scanAsync();
95            }, intervalToUse);
96        }
97    }
98    function stop() {
99        isRunning.current = false;
100        clearTimeout(timeout.current);
101    }
102    React.useEffect(() => {
103        if (isEnabled) {
104            isRunning.current = true;
105            scanAsync();
106        }
107        return () => {
108            if (isEnabled) {
109                stop();
110            }
111        };
112    }, [isEnabled]);
113}
114//# sourceMappingURL=useWebQRScanner.js.map