@nddeps/barcode-scanner 0.1.0 → 0.3.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.
@@ -0,0 +1,34 @@
1
+ import { type ScanArea } from './utils';
2
+ declare function createBarcodeScanner(video: HTMLVideoElement, { calcScanArea, }?: {
3
+ calcScanArea?: (video: HTMLVideoElement) => ScanArea;
4
+ }): {
5
+ destroy: () => Promise<void>;
6
+ pause: () => void;
7
+ start: ({ facingMode }: {
8
+ facingMode?: "environment" | "user";
9
+ } | undefined, onDecodeSuccess: (data: string, area: ScanArea) => void, onDecodeFailure?: () => void) => Promise<void>;
10
+ state: {
11
+ calcScanArea: (video: HTMLVideoElement) => ScanArea;
12
+ canvas: HTMLCanvasElement;
13
+ canvasContext: CanvasRenderingContext2D;
14
+ debug: boolean;
15
+ decodeFrameRequestTimestamp: number;
16
+ facingMode: "environment" | "user";
17
+ isDecodeFrameProcessed: boolean;
18
+ isDestroyed: boolean;
19
+ isReady: boolean;
20
+ isVideoActive: boolean;
21
+ isVideoPaused: boolean;
22
+ onDecodeFailure: () => void;
23
+ onDecodeSuccess: (data: string, area: ScanArea) => void;
24
+ requestFrame: (callback: () => void) => number;
25
+ resumeOnVisibilityChange: boolean;
26
+ scanArea: ScanArea;
27
+ scanRate: number;
28
+ video: HTMLVideoElement;
29
+ worker: null | Worker;
30
+ };
31
+ stop: () => void;
32
+ watch: <T>(source: () => T, callback: (newValue: T) => void) => () => void;
33
+ };
34
+ export { createBarcodeScanner };
@@ -0,0 +1,5 @@
1
+ declare function createWatchable<T extends object>(init: T): {
2
+ state: T;
3
+ watch: <T_1>(source: () => T_1, callback: (newValue: T_1) => void) => () => void;
4
+ };
5
+ export { createWatchable };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { default as BarcodeScanner } from './barcode-scanner';
2
- export type * from './barcode-detector.type';
3
- export type * from './barcode-scanner.types';
4
- export { BarcodeScanner };
5
- export default BarcodeScanner;
1
+ import { createBarcodeScanner } from './create-barcode-scanner';
2
+ export * from './utils';
3
+ export { createBarcodeScanner };
4
+ export default createBarcodeScanner;
package/dist/index.js CHANGED
@@ -1,147 +1,289 @@
1
- var barcode_scanner_default = class {
2
- canvas;
3
- canvasContext;
4
- debug;
5
- decodeFrameRequestTimestamp;
6
- decodeTimeout;
7
- isDecodeFrameProcessed;
8
- isDestroyed;
9
- onDecode;
10
- onDecodeError;
11
- onVisibilityChange;
12
- requestFrame;
13
- resizeObserver;
14
- resumeOnVisibilityChange;
15
- scanArea;
16
- scanRate;
17
- video;
18
- videoActive;
19
- videoPaused;
20
- worker;
21
- constructor({ onDecode: e, onDecodeError: t, options: n, video: r }) {
22
- if (r && !(r instanceof HTMLVideoElement)) throw Error("video is not a HTMLVideoElement");
23
- if (e && !(e instanceof Function)) throw Error("onDecode is not a function");
24
- if (t && !(t instanceof Function)) throw Error("onDecodeError is not a function");
25
- this.canvas = document.createElement("canvas");
26
- let i = this.canvas.getContext("2d", { willReadFrequently: !0 });
27
- if (!i) throw Error("Failed to get canvas context");
28
- this.canvasContext = i, this.debug = n?.debug, this.decodeTimeout = n?.decodeTimeout ?? 1e3, this.isDecodeFrameProcessed = !1, this.isDestroyed = !1, this.onDecode = e, this.onDecodeError = t, this.requestFrame = r.requestVideoFrameCallback ? r.requestVideoFrameCallback.bind(r) : requestAnimationFrame, this.decodeFrameRequestTimestamp = performance.now(), this.resumeOnVisibilityChange = !1, this.scanArea = this.getScanArea(r), this.scanRate = n?.scanRate ?? 24, this.video = r, this.video.autoplay = !0, this.video.disablePictureInPicture = !0, this.video.hidden = !1, this.video.muted = !0, this.video.playsInline = !0, this.videoActive = !1, this.videoPaused = !1, this.resizeObserver = new ResizeObserver(() => {
29
- this.scanArea = this.getScanArea(this.video);
30
- }), this.resizeObserver.observe(this.video), this.onVisibilityChange = () => {
31
- document.visibilityState === "hidden" ? (this.videoActive && this.videoPaused === !1 && (this.resumeOnVisibilityChange = !0), this.pause()) : this.resumeOnVisibilityChange && (this.resumeOnVisibilityChange = !1, this.start());
32
- }, document.addEventListener("visibilitychange", this.onVisibilityChange), this.worker = new Worker(new URL(
33
- /* @vite-ignore */
34
- "" + new URL("barcode-scanner.worker.js", import.meta.url).href,
35
- "" + import.meta.url
36
- ), { type: "module" });
37
- }
38
- decode(e) {
39
- if (!(e instanceof ImageData)) throw Error("Invalid decode data");
40
- let t = `${performance.now()}-${Math.random().toString(36).slice(2)}`;
41
- return new Promise((n, r) => {
42
- let i = 0, a = ({ data: { data: e, uuid: r } }) => {
43
- r === t && (clearTimeout(i), this.worker.removeEventListener("message", a), n(e));
44
- };
45
- i = setTimeout(() => {
46
- this.worker.removeEventListener("message", a), r(null);
47
- }, this.decodeTimeout), this.worker.addEventListener("message", a), this.worker.postMessage({
48
- data: e,
49
- uuid: t
50
- });
51
- });
52
- }
53
- async destroy() {
54
- this.isDestroyed ||= (await this.stop(), document.removeEventListener("visibilitychange", this.onVisibilityChange), this.resizeObserver.disconnect(), this.worker.terminate(), !0);
55
- }
56
- async getCameraAccess() {
57
- if (await this.hasCameraAccess()) return !0;
58
- try {
59
- let e = (await navigator.mediaDevices.getUserMedia({ video: !0 })).getTracks();
60
- for (let t of e) t.stop();
61
- return !0;
62
- } catch {
63
- return !1;
1
+ function createWatchable(e) {
2
+ let r = new EventTarget(), i = new Proxy(e, {
3
+ get(e, r, i) {
4
+ return Reflect.get(e, r, i);
5
+ },
6
+ set(e, i, a, o) {
7
+ let s = Reflect.set(e, i, a, o);
8
+ return r.dispatchEvent(new CustomEvent("change")), s;
64
9
  }
65
- }
66
- getScanArea(e) {
67
- let t = Math.round(2 / 3 * Math.min(e.videoWidth, e.videoHeight));
68
- return {
69
- height: t,
70
- width: t,
71
- x: Math.round((e.videoWidth - t) / 2),
72
- y: Math.round((e.videoHeight - t) / 2)
73
- };
74
- }
75
- getScanAreaPosition(e = this.scanArea) {
76
- let t = window.getComputedStyle(this.video), n = /scaleX\(-1\)/.test(this.video.style.transform), r = t.objectFit, i = t.objectPosition, a = this.video.offsetLeft, o = this.video.offsetTop, s = this.video.offsetHeight, c = this.video.offsetWidth, l = c / s, u = this.video.videoHeight, d = this.video.videoWidth, f = d / u, p = e.width || d, m = e.height || u, h = e.x || 0, g = e.y || 0, _, v;
77
- switch (r) {
78
- case "contain":
79
- case "cover": {
80
- let e = r === "contain" ? f < l : f > l;
81
- _ = e ? s : c / f, v = e ? s * f : c;
82
- break;
83
- }
84
- case "none":
85
- _ = u, v = d;
86
- break;
87
- case "scale-down": {
88
- let e = f < l;
89
- _ = Math.min(e ? c / f : s, u), v = Math.min(e ? s * f : c, d);
90
- break;
91
- }
92
- default:
93
- _ = s, v = c;
94
- break;
10
+ });
11
+ function a(e, i) {
12
+ let a = e();
13
+ function o() {
14
+ let r = e();
15
+ JSON.stringify(r) !== JSON.stringify(a) && (a = r, i(r));
95
16
  }
96
- let [y, b] = i.split(" ").map((e, t) => e.endsWith("%") ? (t === 0 ? c - v : s - _) * parseFloat(e) / 100 : parseFloat(e)), x = (n ? h : d - h - p) / d * v, S = g / u * _, C = v / d;
97
- return {
98
- height: _ / u * m,
99
- width: p * C,
100
- x: a + (n ? y : c - y - v) + x,
101
- y: o + b + S
102
- };
17
+ return r.addEventListener("change", o), () => r.removeEventListener("change", o);
103
18
  }
104
- async hasCameraAccess() {
105
- try {
106
- return (await navigator.permissions.query({ name: "camera" })).state === "granted";
107
- } catch {
108
- return (await navigator.mediaDevices.enumerateDevices()).filter((e) => e.deviceId && e.kind === "videoinput").length > 0;
109
- }
19
+ return {
20
+ state: i,
21
+ watch: a
22
+ };
23
+ }
24
+ async function hasCameraAccess() {
25
+ try {
26
+ return (await navigator.permissions.query({ name: "camera" })).state === "granted";
27
+ } catch {
28
+ return (await navigator.mediaDevices.enumerateDevices()).filter((e) => e.deviceId && e.kind === "videoinput").length > 0;
110
29
  }
111
- pause() {
112
- this.canvas.height = this.video.videoHeight, this.canvas.width = this.video.videoWidth, this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height), this.canvasContext.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height, 0, 0, this.canvas.width, this.canvas.height), this.video.poster = this.canvas.toDataURL(), this.video.srcObject instanceof MediaStream && this.video.srcObject.getTracks().forEach((e) => e.stop()), this.video.srcObject = null, this.videoPaused = !0;
30
+ }
31
+ async function getCameraAccess() {
32
+ if (await hasCameraAccess()) return !0;
33
+ try {
34
+ let e = (await navigator.mediaDevices.getUserMedia({ video: !0 })).getTracks();
35
+ for (let r of e) r.stop();
36
+ return !0;
37
+ } catch {
38
+ return !1;
113
39
  }
114
- async start({ facingMode: e = "environment" } = {}) {
115
- if (!await this.getCameraAccess()) throw Error("No camera access");
116
- this.video.srcObject instanceof MediaStream && this.videoActive && this.videoPaused === !1 || (this.video.srcObject instanceof MediaStream || (this.video.srcObject = await navigator.mediaDevices.getUserMedia({ video: { facingMode: e } })), await this.video.play(), this.scanArea = this.getScanArea(this.video), this.video.style.transform = e === "user" ? "scaleX(-1)" : "none", this.videoActive = !0, this.videoPaused = !1, this.decodeFrame());
40
+ }
41
+ function getScanArea(e) {
42
+ let r = Math.round(2 / 3 * Math.min(e.videoWidth, e.videoHeight));
43
+ return {
44
+ height: r,
45
+ width: r,
46
+ x: Math.round((e.videoWidth - r) / 2),
47
+ y: Math.round((e.videoHeight - r) / 2)
48
+ };
49
+ }
50
+ function getVideoRenderOffset(e, r) {
51
+ let [i, a] = window.getComputedStyle(e).objectPosition.split(" ").map((i, a) => i.endsWith("%") ? (a === 0 ? e.offsetWidth - r.width : e.offsetHeight - r.height) * parseFloat(i) / 100 : parseFloat(i));
52
+ return {
53
+ x: i,
54
+ y: a
55
+ };
56
+ }
57
+ function getVideoRenderSize(e) {
58
+ let r = window.getComputedStyle(e), i = {
59
+ height: e.offsetHeight,
60
+ width: e.offsetWidth
61
+ }, a = i.width / i.height, o = {
62
+ height: e.videoHeight,
63
+ width: e.videoWidth
64
+ }, s = o.width / o.height;
65
+ switch (r.objectFit) {
66
+ case "contain": return {
67
+ height: s < a ? e.offsetHeight : e.offsetWidth / s,
68
+ width: s < a ? e.offsetHeight * s : e.offsetWidth
69
+ };
70
+ case "cover": return {
71
+ height: s > a ? e.offsetHeight : e.offsetWidth / s,
72
+ width: s > a ? e.offsetHeight * s : e.offsetWidth
73
+ };
74
+ case "fill": return i;
75
+ case "none": return o;
76
+ case "scale-down": return {
77
+ height: Math.min(s < a ? e.offsetHeight : e.offsetWidth / s, e.videoHeight),
78
+ width: Math.min(s < a ? e.offsetHeight * s : e.offsetWidth, e.videoWidth)
79
+ };
80
+ default: return o;
117
81
  }
118
- async stop() {
119
- this.video.srcObject instanceof MediaStream && this.video.srcObject.getTracks().forEach((e) => e.stop()), this.video.poster = "", this.video.srcObject = null, this.videoActive = !1, this.videoPaused = !1;
82
+ }
83
+ function isBarcodeDetectorAvailable(e) {
84
+ return "BarcodeDetector" in e;
85
+ }
86
+ function translateAreaToVideoRender(e, r) {
87
+ let i = /scaleX\(-1\)/.test(e.style.transform), a = getVideoRenderSize(e), c = getVideoRenderOffset(e, a), l = i ? e.videoWidth - r.x - r.width : r.x, u = r.y;
88
+ return {
89
+ height: r.height / e.videoHeight * a.height,
90
+ width: r.width / e.videoWidth * a.width,
91
+ x: l / e.videoWidth * a.width + c.x,
92
+ y: u / e.videoHeight * a.height + c.y
93
+ };
94
+ }
95
+ function translateAreaToVideoSource(e, r) {
96
+ let i = /scaleX\(-1\)/.test(e.style.transform), a = getVideoRenderSize(e), c = getVideoRenderOffset(e, a), l = i ? a.width - (r.x - c.x) - r.width : r.x - c.x, u = r.y - c.y, d = e.videoHeight / a.height, f = e.videoWidth / a.width;
97
+ return {
98
+ height: r.height * d,
99
+ width: r.width * f,
100
+ x: l * f,
101
+ y: u * d
102
+ };
103
+ }
104
+ function wait(e) {
105
+ return new Promise((r) => setTimeout(r, e));
106
+ }
107
+ var Dt = [
108
+ ["Aztec", "M"],
109
+ ["Codabar", "L"],
110
+ ["Code39", "L"],
111
+ ["Code93", "L"],
112
+ ["Code128", "L"],
113
+ ["DataBar", "L"],
114
+ ["DataBarExpanded", "L"],
115
+ ["DataMatrix", "M"],
116
+ ["EAN-8", "L"],
117
+ ["EAN-13", "L"],
118
+ ["ITF", "L"],
119
+ ["MaxiCode", "M"],
120
+ ["PDF417", "M"],
121
+ ["QRCode", "M"],
122
+ ["UPC-A", "L"],
123
+ ["UPC-E", "L"],
124
+ ["MicroQRCode", "M"],
125
+ ["rMQRCode", "M"],
126
+ ["DXFilmEdge", "L"],
127
+ ["DataBarLimited", "L"]
128
+ ], Mt = Dt.map(([e]) => e);
129
+ Mt.filter((e, r) => Dt[r][1] === "L"), Mt.filter((e, r) => Dt[r][1] === "M");
130
+ var It = {
131
+ formats: [],
132
+ tryHarder: !0,
133
+ tryRotate: !0,
134
+ tryInvert: !0,
135
+ tryDownscale: !0,
136
+ tryDenoise: !1,
137
+ binarizer: "LocalAverage",
138
+ isPure: !1,
139
+ downscaleFactor: 3,
140
+ downscaleThreshold: 500,
141
+ minLineCount: 2,
142
+ maxNumberOfSymbols: 255,
143
+ tryCode39ExtendedMode: !0,
144
+ returnErrors: !1,
145
+ eanAddOnSymbol: "Ignore",
146
+ textMode: "HRI",
147
+ characterSet: "Unknown"
148
+ };
149
+ ({ ...It }), [...It.formats], [...[
150
+ ["aztec", "Aztec"],
151
+ ["code_128", "Code128"],
152
+ ["code_39", "Code39"],
153
+ ["code_93", "Code93"],
154
+ ["codabar", "Codabar"],
155
+ ["databar", "DataBar"],
156
+ ["databar_expanded", "DataBarExpanded"],
157
+ ["databar_limited", "DataBarLimited"],
158
+ ["data_matrix", "DataMatrix"],
159
+ ["dx_film_edge", "DXFilmEdge"],
160
+ ["ean_13", "EAN-13"],
161
+ ["ean_8", "EAN-8"],
162
+ ["itf", "ITF"],
163
+ ["maxi_code", "MaxiCode"],
164
+ ["micro_qr_code", "MicroQRCode"],
165
+ ["pdf417", "PDF417"],
166
+ ["qr_code", "QRCode"],
167
+ ["rm_qr_code", "rMQRCode"],
168
+ ["upc_a", "UPC-A"],
169
+ ["upc_e", "UPC-E"],
170
+ ["linear_codes", "Linear-Codes"],
171
+ ["matrix_codes", "Matrix-Codes"],
172
+ ["any", "Any"]
173
+ ], ["unknown"]].map((e) => e[0]);
174
+ var instance = { value: null };
175
+ async function decode(e) {
176
+ let r = instance.value;
177
+ if (!r) throw Error("Worker not installed");
178
+ let i = `${performance.now()}-${Math.random().toString(36).slice(2)}`;
179
+ return new Promise((a, o) => {
180
+ let s = 0, c = ({ data: { payload: e, type: o } }) => {
181
+ o !== "decode" || e.uuid !== i || (clearTimeout(s), r.removeEventListener("message", c), a(e.data));
182
+ };
183
+ s = setTimeout(() => {
184
+ r.removeEventListener("message", c), o(null);
185
+ }, 1e3), r.addEventListener("message", c), r.postMessage({
186
+ payload: {
187
+ data: e,
188
+ uuid: i
189
+ },
190
+ type: "decode"
191
+ });
192
+ });
193
+ }
194
+ function install() {
195
+ if (instance.value) return Promise.resolve(instance.value);
196
+ let e = new Worker(new URL(
197
+ /* @vite-ignore */
198
+ "" + new URL("worker.js", import.meta.url).href,
199
+ "" + import.meta.url
200
+ ), { type: "module" });
201
+ return new Promise((r, i) => {
202
+ e.addEventListener("message", ({ data: { type: a } }) => {
203
+ a === "init" ? r(e) : i(/* @__PURE__ */ Error("Worker load failed"));
204
+ }, { once: !0 }), instance.value = e;
205
+ });
206
+ }
207
+ function createBarcodeScanner(r, { calcScanArea: o } = {}) {
208
+ if (!(r instanceof HTMLVideoElement)) throw Error("video is not a HTMLVideoElement");
209
+ let s = document.createElement("canvas"), c = s.getContext("2d", { willReadFrequently: !0 });
210
+ if (!c) throw Error("Failed to get canvas context");
211
+ let { state: u, watch: d } = createWatchable({
212
+ calcScanArea: o ?? getScanArea,
213
+ canvas: s,
214
+ canvasContext: c,
215
+ debug: !0,
216
+ decodeFrameRequestTimestamp: performance.now(),
217
+ facingMode: "environment",
218
+ isDecodeFrameProcessed: !1,
219
+ isDestroyed: !1,
220
+ isReady: !1,
221
+ isVideoActive: !1,
222
+ isVideoPaused: !1,
223
+ onDecodeFailure: () => {},
224
+ onDecodeSuccess: () => {},
225
+ requestFrame: r.requestVideoFrameCallback ? r.requestVideoFrameCallback.bind(r) : requestAnimationFrame,
226
+ resumeOnVisibilityChange: !1,
227
+ scanArea: {
228
+ height: 0,
229
+ width: 0,
230
+ x: 0,
231
+ y: 0
232
+ },
233
+ scanRate: 24,
234
+ video: r,
235
+ worker: null
236
+ });
237
+ install().then((e) => u.worker = e).then(() => Promise.resolve()).then(() => u.isReady = !0), u.video.autoplay = !0, u.video.disablePictureInPicture = !0, u.video.hidden = !1, u.video.muted = !0, u.video.playsInline = !0, document.addEventListener("visibilitychange", f);
238
+ function f() {
239
+ document.visibilityState === "hidden" ? u.isVideoActive && u.isVideoPaused === !1 && (u.resumeOnVisibilityChange = !0, h()) : u.resumeOnVisibilityChange && (u.resumeOnVisibilityChange = !1, g({ facingMode: u.facingMode }, u.onDecodeSuccess, u.onDecodeFailure));
120
240
  }
121
- decodeFrame() {
122
- this.isDestroyed || this.videoActive === !1 || this.videoPaused || this.requestFrame(() => {
123
- if (performance.now() - this.decodeFrameRequestTimestamp < 1e3 / this.scanRate || this.isDecodeFrameProcessed || this.video.ended || this.video.paused || this.video.readyState <= 1) {
124
- this.decodeFrameRequestTimestamp = performance.now(), this.decodeFrame();
241
+ function p(e, r) {
242
+ u.isDestroyed || u.isVideoActive === !1 || u.isVideoPaused || u.requestFrame(() => {
243
+ if (performance.now() - u.decodeFrameRequestTimestamp < 1e3 / u.scanRate || u.isDecodeFrameProcessed || u.video.ended || u.video.paused || u.video.readyState <= 1) {
244
+ u.decodeFrameRequestTimestamp = performance.now(), p(e, r);
125
245
  return;
126
246
  }
127
- this.isDecodeFrameProcessed = !0, this.canvas.height = this.scanArea.height, this.canvas.width = this.scanArea.width, this.canvasContext.clearRect(0, 0, this.canvas.width, this.canvas.height), this.canvasContext.drawImage(this.video, this.scanArea.x, this.scanArea.y, this.scanArea.width, this.scanArea.height, 0, 0, this.canvas.width, this.canvas.height);
128
- let e = this.canvasContext.getImageData(0, 0, this.canvas.width, this.canvas.height);
129
- this.debug && window.dispatchEvent(new CustomEvent("barcode-scanner:decode-frame", { detail: { imageData: e } })), this.decode(e).then((e) => {
130
- if (e) {
131
- let t = e.cornerPoints.map((e) => e.x), n = e.cornerPoints.map((e) => e.y);
132
- this.onDecode(e.rawValue, this.getScanAreaPosition({
133
- height: Math.max(...n) - Math.min(...n),
134
- width: Math.max(...t) - Math.min(...t),
135
- x: Math.min(...t) + this.scanArea.x,
136
- y: Math.min(...n) + this.scanArea.y
247
+ u.isDecodeFrameProcessed = !0, u.scanArea = u.calcScanArea(u.video), u.canvas.height = u.scanArea.height, u.canvas.width = u.scanArea.width, u.canvasContext.clearRect(0, 0, u.canvas.width, u.canvas.height), u.canvasContext.drawImage(u.video, u.scanArea.x, u.scanArea.y, u.scanArea.width, u.scanArea.height, 0, 0, u.canvas.width, u.canvas.height);
248
+ let i = u.canvasContext.getImageData(0, 0, u.canvas.width, u.canvas.height);
249
+ u.debug && window.dispatchEvent(new CustomEvent("barcode-scanner:decode-frame", { detail: { imageData: i } })), decode(i).then((i) => {
250
+ if (i) {
251
+ let r = i.cornerPoints.map((e) => e.x), a = i.cornerPoints.map((e) => e.y);
252
+ e(i.rawValue, translateAreaToVideoRender(u.video, {
253
+ height: Math.max(...a) - Math.min(...a),
254
+ width: Math.max(...r) - Math.min(...r),
255
+ x: Math.min(...r) + u.scanArea.x,
256
+ y: Math.min(...a) + u.scanArea.y
137
257
  }));
138
- } else this.onDecode(null);
258
+ } else r();
139
259
  }).catch(() => {
140
- this.onDecodeError?.();
260
+ console.error("Failed to decode barcode");
141
261
  }).finally(() => {
142
- this.isDecodeFrameProcessed = !1, this.decodeFrameRequestTimestamp = performance.now(), this.decodeFrame();
262
+ u.isDecodeFrameProcessed = !1, u.decodeFrameRequestTimestamp = performance.now(), p(e, r);
143
263
  });
144
264
  });
145
265
  }
146
- }, lib_default = barcode_scanner_default;
147
- export { barcode_scanner_default as BarcodeScanner, lib_default as default };
266
+ async function m() {
267
+ u.isDestroyed || (_(), document.removeEventListener("visibilitychange", f), u.worker?.terminate(), u.worker = null, u.isDestroyed = !0, u.isReady = !1);
268
+ }
269
+ function h() {
270
+ u.canvas.height = u.video.videoHeight, u.canvas.width = u.video.videoWidth, u.canvasContext.clearRect(0, 0, u.canvas.width, u.canvas.height), u.canvasContext.drawImage(u.video, 0, 0, u.canvas.width, u.canvas.height, 0, 0, u.canvas.width, u.canvas.height), u.video.poster = u.canvas.toDataURL(), u.video.srcObject instanceof MediaStream && u.video.srcObject.getTracks().forEach((e) => e.stop()), u.video.srcObject = null, u.isVideoPaused = !0;
271
+ }
272
+ async function g({ facingMode: e = "environment" } = {}, r, a = () => {}) {
273
+ if (!await getCameraAccess()) throw Error("No camera access");
274
+ u.video.srcObject instanceof MediaStream && u.isVideoActive && u.isVideoPaused === !1 || (u.video.srcObject instanceof MediaStream || (u.video.srcObject = await navigator.mediaDevices.getUserMedia({ video: { facingMode: e } })), await u.video.play(), u.facingMode = e, u.isVideoActive = !0, u.isVideoPaused = !1, u.onDecodeFailure = a, u.onDecodeSuccess = r, u.scanArea = u.calcScanArea(u.video), u.video.style.transform = e === "user" ? "scaleX(-1)" : "none", p(r, a));
275
+ }
276
+ function _() {
277
+ u.video.srcObject instanceof MediaStream && u.video.srcObject.getTracks().forEach((e) => e.stop()), u.video.poster = "", u.video.srcObject = null, u.isVideoActive = !1, u.isVideoPaused = !1;
278
+ }
279
+ return {
280
+ destroy: m,
281
+ pause: h,
282
+ start: g,
283
+ state: u,
284
+ stop: _,
285
+ watch: d
286
+ };
287
+ }
288
+ var lib_default = createBarcodeScanner;
289
+ export { createBarcodeScanner, lib_default as default, getCameraAccess, getScanArea, getVideoRenderOffset, getVideoRenderSize, hasCameraAccess, isBarcodeDetectorAvailable, translateAreaToVideoRender, translateAreaToVideoSource, wait };
@@ -0,0 +1,2 @@
1
+ declare function getCameraAccess(): Promise<boolean>;
2
+ export { getCameraAccess };
@@ -0,0 +1,9 @@
1
+ type ScanArea = {
2
+ height: number;
3
+ width: number;
4
+ x: number;
5
+ y: number;
6
+ };
7
+ declare function getScanArea(video: HTMLVideoElement): ScanArea;
8
+ export type { ScanArea };
9
+ export { getScanArea };
@@ -0,0 +1,8 @@
1
+ import type { RenderSize } from './get-video-render-size';
2
+ type RenderOffset = {
3
+ x: number;
4
+ y: number;
5
+ };
6
+ declare function getVideoRenderOffset(video: HTMLVideoElement, renderSize: RenderSize): RenderOffset;
7
+ export type { RenderOffset };
8
+ export { getVideoRenderOffset };
@@ -0,0 +1,7 @@
1
+ type RenderSize = {
2
+ height: number;
3
+ width: number;
4
+ };
5
+ declare function getVideoRenderSize(video: HTMLVideoElement): RenderSize;
6
+ export type { RenderSize };
7
+ export { getVideoRenderSize };
@@ -0,0 +1,2 @@
1
+ declare function hasCameraAccess(): Promise<boolean>;
2
+ export { hasCameraAccess };
@@ -0,0 +1,9 @@
1
+ export * from './get-camera-access';
2
+ export * from './get-scan-area';
3
+ export * from './get-video-render-offset';
4
+ export * from './get-video-render-size';
5
+ export * from './has-camera-access';
6
+ export * from './is-barcode-detector-available';
7
+ export * from './translate-area-to-video-render';
8
+ export * from './translate-area-to-video-source';
9
+ export * from './wait';
@@ -0,0 +1,7 @@
1
+ import type { BarcodeDetector, BarcodeDetectorOptions } from 'barcode-detector/ponyfill';
2
+ declare function isBarcodeDetectorAvailable<T extends object>(value: T): value is {
3
+ BarcodeDetector: {
4
+ new (barcodeDetectorOptions?: BarcodeDetectorOptions): BarcodeDetector;
5
+ } & BarcodeDetector;
6
+ } & T;
7
+ export { isBarcodeDetectorAvailable };
@@ -0,0 +1,3 @@
1
+ import type { ScanArea } from './get-scan-area';
2
+ declare function translateAreaToVideoRender(video: HTMLVideoElement, area: ScanArea): ScanArea;
3
+ export { translateAreaToVideoRender };
@@ -0,0 +1,3 @@
1
+ import type { ScanArea } from './get-scan-area';
2
+ declare function translateAreaToVideoSource(video: HTMLVideoElement, area: ScanArea): ScanArea;
3
+ export { translateAreaToVideoSource };
@@ -0,0 +1,2 @@
1
+ declare function wait(ms: number): Promise<unknown>;
2
+ export { wait };
@@ -0,0 +1,3 @@
1
+ export * from './worker.decode';
2
+ export * from './worker.install';
3
+ export * from './worker.instance';
@@ -0,0 +1,3 @@
1
+ import { type DetectedBarcode } from 'barcode-detector/ponyfill';
2
+ declare function decode(imageData: ImageData): Promise<DetectedBarcode | null>;
3
+ export { decode };
@@ -0,0 +1,2 @@
1
+ declare function install(): Promise<Worker>;
2
+ export { install };
@@ -0,0 +1,4 @@
1
+ declare const instance: {
2
+ value: null | Worker;
3
+ };
4
+ export { instance };
@@ -0,0 +1,16 @@
1
+ import type { DetectedBarcode } from 'barcode-detector/ponyfill';
2
+ type DecodeReq = {
3
+ payload: {
4
+ data: ImageData;
5
+ uuid: string;
6
+ };
7
+ type: 'decode';
8
+ };
9
+ type DecodeRes = {
10
+ payload: {
11
+ data: DetectedBarcode | null;
12
+ uuid: string;
13
+ };
14
+ type: 'decode';
15
+ };
16
+ export type { DecodeReq, DecodeRes };