@scanly/browser 2.0.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 +3 -0
- package/dist/batch/batch-controller.d.ts +71 -0
- package/dist/batch/batch-controller.d.ts.map +1 -0
- package/dist/batch/batch-controller.js +422 -0
- package/dist/batch/batch-controller.js.map +1 -0
- package/dist/batch/batch-session.d.ts +53 -0
- package/dist/batch/batch-session.d.ts.map +1 -0
- package/dist/batch/batch-session.js +267 -0
- package/dist/batch/batch-session.js.map +1 -0
- package/dist/batch/index.d.ts +4 -0
- package/dist/batch/index.d.ts.map +1 -0
- package/dist/batch/index.js +4 -0
- package/dist/batch/index.js.map +1 -0
- package/dist/batch/types.d.ts +101 -0
- package/dist/batch/types.d.ts.map +1 -0
- package/dist/batch/types.js +2 -0
- package/dist/batch/types.js.map +1 -0
- package/dist/browser-session.d.ts +51 -0
- package/dist/browser-session.d.ts.map +1 -0
- package/dist/browser-session.js +168 -0
- package/dist/browser-session.js.map +1 -0
- package/dist/camera-source.d.ts +89 -0
- package/dist/camera-source.d.ts.map +1 -0
- package/dist/camera-source.js +366 -0
- package/dist/camera-source.js.map +1 -0
- package/dist/camera-strategy.d.ts +36 -0
- package/dist/camera-strategy.d.ts.map +1 -0
- package/dist/camera-strategy.js +94 -0
- package/dist/camera-strategy.js.map +1 -0
- package/dist/decode-upload.d.ts +13 -0
- package/dist/decode-upload.d.ts.map +1 -0
- package/dist/decode-upload.js +23 -0
- package/dist/decode-upload.js.map +1 -0
- package/dist/image-loader.d.ts +11 -0
- package/dist/image-loader.d.ts.map +1 -0
- package/dist/image-loader.js +63 -0
- package/dist/image-loader.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime.d.ts +8 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +14 -0
- package/dist/runtime.js.map +1 -0
- package/dist/scanner/camera-capabilities.d.ts +20 -0
- package/dist/scanner/camera-capabilities.d.ts.map +1 -0
- package/dist/scanner/camera-capabilities.js +181 -0
- package/dist/scanner/camera-capabilities.js.map +1 -0
- package/dist/scanner/camera-platform.d.ts +75 -0
- package/dist/scanner/camera-platform.d.ts.map +1 -0
- package/dist/scanner/camera-platform.js +145 -0
- package/dist/scanner/camera-platform.js.map +1 -0
- package/dist/scanner/decode-escalation.d.ts +20 -0
- package/dist/scanner/decode-escalation.d.ts.map +1 -0
- package/dist/scanner/decode-escalation.js +40 -0
- package/dist/scanner/decode-escalation.js.map +1 -0
- package/dist/scanner/frame-quality.d.ts +24 -0
- package/dist/scanner/frame-quality.d.ts.map +1 -0
- package/dist/scanner/frame-quality.js +90 -0
- package/dist/scanner/frame-quality.js.map +1 -0
- package/dist/scanner/frame-scheduler.d.ts +59 -0
- package/dist/scanner/frame-scheduler.d.ts.map +1 -0
- package/dist/scanner/frame-scheduler.js +148 -0
- package/dist/scanner/frame-scheduler.js.map +1 -0
- package/dist/scanner/frame-source.d.ts +70 -0
- package/dist/scanner/frame-source.d.ts.map +1 -0
- package/dist/scanner/frame-source.js +263 -0
- package/dist/scanner/frame-source.js.map +1 -0
- package/dist/scanner/index.d.ts +12 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +12 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/repeat-suppressor.d.ts +23 -0
- package/dist/scanner/repeat-suppressor.d.ts.map +1 -0
- package/dist/scanner/repeat-suppressor.js +69 -0
- package/dist/scanner/repeat-suppressor.js.map +1 -0
- package/dist/scanner/scanner-session.d.ts +160 -0
- package/dist/scanner/scanner-session.d.ts.map +1 -0
- package/dist/scanner/scanner-session.js +766 -0
- package/dist/scanner/scanner-session.js.map +1 -0
- package/dist/scanner/temporal-confirmation.d.ts +30 -0
- package/dist/scanner/temporal-confirmation.d.ts.map +1 -0
- package/dist/scanner/temporal-confirmation.js +71 -0
- package/dist/scanner/temporal-confirmation.js.map +1 -0
- package/dist/scanner/temporal-roi.d.ts +27 -0
- package/dist/scanner/temporal-roi.d.ts.map +1 -0
- package/dist/scanner/temporal-roi.js +50 -0
- package/dist/scanner/temporal-roi.js.map +1 -0
- package/dist/scanner/types.d.ts +232 -0
- package/dist/scanner/types.d.ts.map +1 -0
- package/dist/scanner/types.js +2 -0
- package/dist/scanner/types.js.map +1 -0
- package/dist/tracking/barcode-tracker.d.ts +28 -0
- package/dist/tracking/barcode-tracker.d.ts.map +1 -0
- package/dist/tracking/barcode-tracker.js +279 -0
- package/dist/tracking/barcode-tracker.js.map +1 -0
- package/dist/tracking/geometry.d.ts +13 -0
- package/dist/tracking/geometry.d.ts.map +1 -0
- package/dist/tracking/geometry.js +51 -0
- package/dist/tracking/geometry.js.map +1 -0
- package/dist/tracking/index.d.ts +8 -0
- package/dist/tracking/index.d.ts.map +1 -0
- package/dist/tracking/index.js +8 -0
- package/dist/tracking/index.js.map +1 -0
- package/dist/tracking/scanner-tracking-runtime.d.ts +45 -0
- package/dist/tracking/scanner-tracking-runtime.d.ts.map +1 -0
- package/dist/tracking/scanner-tracking-runtime.js +93 -0
- package/dist/tracking/scanner-tracking-runtime.js.map +1 -0
- package/dist/tracking/track-association.d.ts +19 -0
- package/dist/tracking/track-association.d.ts.map +1 -0
- package/dist/tracking/track-association.js +191 -0
- package/dist/tracking/track-association.js.map +1 -0
- package/dist/tracking/track-overlay.d.ts +4 -0
- package/dist/tracking/track-overlay.d.ts.map +1 -0
- package/dist/tracking/track-overlay.js +16 -0
- package/dist/tracking/track-overlay.js.map +1 -0
- package/dist/tracking/track-roi-set.d.ts +17 -0
- package/dist/tracking/track-roi-set.d.ts.map +1 -0
- package/dist/tracking/track-roi-set.js +119 -0
- package/dist/tracking/track-roi-set.js.map +1 -0
- package/dist/tracking/types.d.ts +154 -0
- package/dist/tracking/types.d.ts.map +1 -0
- package/dist/tracking/types.js +2 -0
- package/dist/tracking/types.js.map +1 -0
- package/dist/worker/decode-worker.d.ts +2 -0
- package/dist/worker/decode-worker.d.ts.map +1 -0
- package/dist/worker/decode-worker.js +84 -0
- package/dist/worker/decode-worker.js.map +1 -0
- package/dist/worker/transferable-buffer.d.ts +18 -0
- package/dist/worker/transferable-buffer.d.ts.map +1 -0
- package/dist/worker/transferable-buffer.js +24 -0
- package/dist/worker/transferable-buffer.js.map +1 -0
- package/dist/worker/worker-client.d.ts +86 -0
- package/dist/worker/worker-client.d.ts.map +1 -0
- package/dist/worker/worker-client.js +286 -0
- package/dist/worker/worker-client.js.map +1 -0
- package/dist/worker/worker-messages.d.ts +75 -0
- package/dist/worker/worker-messages.d.ts.map +1 -0
- package/dist/worker/worker-messages.js +244 -0
- package/dist/worker/worker-messages.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { getBuiltinScenario } from "@scanly/scenario-schema";
|
|
2
|
+
export class CameraEscalationController {
|
|
3
|
+
options;
|
|
4
|
+
misses = 0;
|
|
5
|
+
escalationRemaining = 0;
|
|
6
|
+
track = null;
|
|
7
|
+
sequence = 0;
|
|
8
|
+
constructor(options = {}) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
}
|
|
11
|
+
nextScenario(base, frame, now = Date.now()) {
|
|
12
|
+
if (this.track && now - this.track.lastSeenMs > (this.options.resetTimeoutMs ?? 2_500))
|
|
13
|
+
this.track = null;
|
|
14
|
+
const baseScenario = JSON.parse(JSON.stringify(base ?? getBuiltinScenario("fast")));
|
|
15
|
+
let scenario = baseScenario;
|
|
16
|
+
if (this.escalationRemaining > 0) {
|
|
17
|
+
if (this.options.escalationScenario) {
|
|
18
|
+
scenario = JSON.parse(JSON.stringify(this.options.escalationScenario));
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const balanced = getBuiltinScenario("balanced");
|
|
22
|
+
scenario = {
|
|
23
|
+
...baseScenario,
|
|
24
|
+
id: `${baseScenario.id}.camera-escalated`,
|
|
25
|
+
revision: baseScenario.revision + 1,
|
|
26
|
+
localization: {
|
|
27
|
+
...baseScenario.localization,
|
|
28
|
+
maxCandidates: Math.max(baseScenario.localization.maxCandidates, balanced.localization.maxCandidates),
|
|
29
|
+
cropPaddings: [...new Set([...baseScenario.localization.cropPaddings, ...balanced.localization.cropPaddings])],
|
|
30
|
+
scales: [...new Set([...baseScenario.localization.scales, ...balanced.localization.scales])],
|
|
31
|
+
},
|
|
32
|
+
enhancement: {
|
|
33
|
+
operators: [...new Set([...baseScenario.enhancement.operators, ...balanced.enhancement.operators])],
|
|
34
|
+
rotations: [...new Set([...baseScenario.enhancement.rotations, ...balanced.enhancement.rotations])],
|
|
35
|
+
},
|
|
36
|
+
budgets: {
|
|
37
|
+
...baseScenario.budgets,
|
|
38
|
+
maxCandidates: Math.max(baseScenario.budgets.maxCandidates, balanced.budgets.maxCandidates),
|
|
39
|
+
maxAttempts: Math.max(baseScenario.budgets.maxAttempts, balanced.budgets.maxAttempts),
|
|
40
|
+
maxIntermediateAllocations: Math.max(baseScenario.budgets.maxIntermediateAllocations, balanced.budgets.maxIntermediateAllocations),
|
|
41
|
+
maxIntermediateBytes: Math.max(baseScenario.budgets.maxIntermediateBytes, balanced.budgets.maxIntermediateBytes),
|
|
42
|
+
maxExecutionMs: Math.max(baseScenario.budgets.maxExecutionMs, balanced.budgets.maxExecutionMs),
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (this.track?.corners.length && frame) {
|
|
48
|
+
const xs = this.track.corners.map((point) => point.x);
|
|
49
|
+
const ys = this.track.corners.map((point) => point.y);
|
|
50
|
+
const expansion = Math.max(0, Math.min(1, this.options.roiExpansion ?? 0.35));
|
|
51
|
+
const left = Math.max(0, Math.min(...xs));
|
|
52
|
+
const right = Math.min(frame.width, Math.max(...xs));
|
|
53
|
+
const top = Math.max(0, Math.min(...ys));
|
|
54
|
+
const bottom = Math.min(frame.height, Math.max(...ys));
|
|
55
|
+
const dx = (right - left) * expansion;
|
|
56
|
+
const dy = (bottom - top) * expansion;
|
|
57
|
+
const x = Math.max(0, left - dx) / frame.width;
|
|
58
|
+
const y = Math.max(0, top - dy) / frame.height;
|
|
59
|
+
const width = (Math.min(frame.width, right + dx) - Math.max(0, left - dx)) / frame.width;
|
|
60
|
+
const height = (Math.min(frame.height, bottom + dy) - Math.max(0, top - dy)) / frame.height;
|
|
61
|
+
scenario.input.roi = { mode: "relative", x, y, width, height };
|
|
62
|
+
}
|
|
63
|
+
return scenario;
|
|
64
|
+
}
|
|
65
|
+
observe(outcome, now = Date.now()) {
|
|
66
|
+
if (outcome.ok) {
|
|
67
|
+
const result = outcome.primary;
|
|
68
|
+
this.misses = 0;
|
|
69
|
+
this.escalationRemaining = 0;
|
|
70
|
+
if (result.cornerPoints?.length) {
|
|
71
|
+
if (this.track && this.track.payload === result.rawText && this.track.format === result.format) {
|
|
72
|
+
this.track = { ...this.track, corners: result.cornerPoints, lastSeenMs: now, consecutiveFrames: this.track.consecutiveFrames + 1, missedFrames: 0 };
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.track = { id: `internal-track-${++this.sequence}`, payload: result.rawText, format: result.format, corners: result.cornerPoints, firstSeenMs: now, lastSeenMs: now, consecutiveFrames: 1, missedFrames: 0 };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.misses += 1;
|
|
81
|
+
if (this.track)
|
|
82
|
+
this.track = { ...this.track, missedFrames: this.track.missedFrames + 1 };
|
|
83
|
+
if (this.escalationRemaining > 0)
|
|
84
|
+
this.escalationRemaining -= 1;
|
|
85
|
+
if (this.misses >= Math.max(1, this.options.fastMissThreshold ?? 4)) {
|
|
86
|
+
this.escalationRemaining = Math.max(1, this.options.maximumEscalationAttempts ?? 3);
|
|
87
|
+
this.misses = 0;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
reset() { this.misses = 0; this.escalationRemaining = 0; this.track = null; }
|
|
91
|
+
get activeTrack() { return this.track; }
|
|
92
|
+
get escalated() { return this.escalationRemaining > 0; }
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=camera-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-strategy.js","sourceRoot":"","sources":["../src/camera-strategy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ScanOutcome } from "@scanly/core";
|
|
2
|
+
import type { ScenarioDefinition } from "@scanly/scenario-schema";
|
|
3
|
+
import { type BrowserScanFileOptions } from "./browser-session.js";
|
|
4
|
+
/**
|
|
5
|
+
* @deprecated Prefer BrowserCaptureSession. This compatibility wrapper executes
|
|
6
|
+
* the same CaptureRouter path and no longer owns a separate decode pipeline.
|
|
7
|
+
*/
|
|
8
|
+
export declare function decodeUploadedFile(file: File, options?: BrowserScanFileOptions & {
|
|
9
|
+
scenario?: ScenarioDefinition;
|
|
10
|
+
}): Promise<ScanOutcome>;
|
|
11
|
+
export declare function cancelUploadedDecode(): void;
|
|
12
|
+
export declare function disposeUploadedDecodeWorker(): Promise<void>;
|
|
13
|
+
//# sourceMappingURL=decode-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode-upload.d.ts","sourceRoot":"","sources":["../src/decode-upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAyB,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAI1F;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,sBAAsB,GAAG;IAAE,QAAQ,CAAC,EAAE,kBAAkB,CAAA;CAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAQnJ;AAED,wBAAgB,oBAAoB,IAAI,IAAI,CAAoC;AAChF,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BrowserCaptureSession } from "./browser-session.js";
|
|
2
|
+
let compatibilitySession = null;
|
|
3
|
+
/**
|
|
4
|
+
* @deprecated Prefer BrowserCaptureSession. This compatibility wrapper executes
|
|
5
|
+
* the same CaptureRouter path and no longer owns a separate decode pipeline.
|
|
6
|
+
*/
|
|
7
|
+
export async function decodeUploadedFile(file, options = {}) {
|
|
8
|
+
if (!compatibilitySession) {
|
|
9
|
+
compatibilitySession = new BrowserCaptureSession({ scenario: options.scenario });
|
|
10
|
+
compatibilitySession.start();
|
|
11
|
+
}
|
|
12
|
+
else if (options.scenario) {
|
|
13
|
+
compatibilitySession.updateConfiguration(options.scenario);
|
|
14
|
+
}
|
|
15
|
+
return compatibilitySession.scanFile(file, options);
|
|
16
|
+
}
|
|
17
|
+
export function cancelUploadedDecode() { compatibilitySession?.cancel(); }
|
|
18
|
+
export async function disposeUploadedDecodeWorker() {
|
|
19
|
+
const session = compatibilitySession;
|
|
20
|
+
compatibilitySession = null;
|
|
21
|
+
await session?.dispose();
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=decode-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decode-upload.js","sourceRoot":"","sources":["../src/decode-upload.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAA+B,MAAM,sBAAsB,CAAC;AAE1F,IAAI,oBAAoB,GAAiC,IAAI,CAAC;AAE9D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAU,EAAE,UAAsE,EAAE;IAC3H,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,oBAAoB,GAAG,IAAI,qBAAqB,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACjF,oBAAoB,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QAC5B,oBAAoB,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,oBAAoB,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,oBAAoB,KAAW,oBAAoB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAChF,MAAM,CAAC,KAAK,UAAU,2BAA2B;IAC/C,MAAM,OAAO,GAAG,oBAAoB,CAAC;IACrC,oBAAoB,GAAG,IAAI,CAAC;IAC5B,MAAM,OAAO,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PixelBuffer } from "@scanly/core/qr";
|
|
2
|
+
export declare const MAX_UPLOAD_BYTES: number;
|
|
3
|
+
export declare const MAX_IMAGE_PIXELS = 24000000;
|
|
4
|
+
export declare const MAX_IMAGE_SIDE = 12000;
|
|
5
|
+
/** Load image file bytes into a PixelBuffer via browser createImageBitmap + canvas. */
|
|
6
|
+
export declare function loadPixelBufferFromBlob(blob: Blob): Promise<PixelBuffer>;
|
|
7
|
+
/** Decode a File through the same path (revokes nothing — blob from File is owned by browser). */
|
|
8
|
+
export declare function loadPixelBufferFromFile(file: File): Promise<PixelBuffer>;
|
|
9
|
+
/** Convert browser ImageData to PixelBuffer. */
|
|
10
|
+
export declare function pixelBufferFromImageData(imageData: ImageData): PixelBuffer;
|
|
11
|
+
//# sourceMappingURL=image-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-loader.d.ts","sourceRoot":"","sources":["../src/image-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,eAAO,MAAM,gBAAgB,QAAmB,CAAC;AACjD,eAAO,MAAM,gBAAgB,WAAa,CAAC;AAC3C,eAAO,MAAM,cAAc,QAAS,CAAC;AAErC,uFAAuF;AACvF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAuD9E;AAED,kGAAkG;AAClG,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAE9E;AAED,gDAAgD;AAChD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG,WAAW,CAE1E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createPixelBuffer, flattenAlphaOntoWhite } from "@scanly/core/qr";
|
|
2
|
+
export const MAX_UPLOAD_BYTES = 25 * 1024 * 1024;
|
|
3
|
+
export const MAX_IMAGE_PIXELS = 24_000_000;
|
|
4
|
+
export const MAX_IMAGE_SIDE = 12_000;
|
|
5
|
+
/** Load image file bytes into a PixelBuffer via browser createImageBitmap + canvas. */
|
|
6
|
+
export async function loadPixelBufferFromBlob(blob) {
|
|
7
|
+
if (!blob || blob.size === 0) {
|
|
8
|
+
throw Object.assign(new Error("Empty or missing image file."), { code: "empty_image" });
|
|
9
|
+
}
|
|
10
|
+
if (blob.size > MAX_UPLOAD_BYTES) {
|
|
11
|
+
throw Object.assign(new Error("Image is larger than the 25 MiB upload limit."), {
|
|
12
|
+
code: "image_too_large",
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (blob.type && !blob.type.startsWith("image/")) {
|
|
16
|
+
throw Object.assign(new Error("Please select a valid image file."), { code: "invalid_file" });
|
|
17
|
+
}
|
|
18
|
+
let bitmap;
|
|
19
|
+
try {
|
|
20
|
+
bitmap = await createImageBitmap(blob);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
throw Object.assign(new Error("Unsupported or corrupted image."), {
|
|
24
|
+
code: "unsupported_image",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
if (bitmap.width < 1 ||
|
|
29
|
+
bitmap.height < 1 ||
|
|
30
|
+
bitmap.width > MAX_IMAGE_SIDE ||
|
|
31
|
+
bitmap.height > MAX_IMAGE_SIDE ||
|
|
32
|
+
bitmap.width * bitmap.height > MAX_IMAGE_PIXELS) {
|
|
33
|
+
throw Object.assign(new Error("Image dimensions exceed the 24 megapixel processing limit."), { code: "image_too_large" });
|
|
34
|
+
}
|
|
35
|
+
const canvas = document.createElement("canvas");
|
|
36
|
+
canvas.width = bitmap.width;
|
|
37
|
+
canvas.height = bitmap.height;
|
|
38
|
+
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
39
|
+
if (!ctx) {
|
|
40
|
+
throw Object.assign(new Error("Canvas is not supported in this browser."), {
|
|
41
|
+
code: "unsupported_image",
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// White underlay so transparent PNG modules remain decodable
|
|
45
|
+
ctx.fillStyle = "#ffffff";
|
|
46
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
47
|
+
ctx.drawImage(bitmap, 0, 0);
|
|
48
|
+
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
49
|
+
return flattenAlphaOntoWhite(createPixelBuffer(imageData.data, imageData.width, imageData.height));
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
bitmap.close();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Decode a File through the same path (revokes nothing — blob from File is owned by browser). */
|
|
56
|
+
export async function loadPixelBufferFromFile(file) {
|
|
57
|
+
return loadPixelBufferFromBlob(file);
|
|
58
|
+
}
|
|
59
|
+
/** Convert browser ImageData to PixelBuffer. */
|
|
60
|
+
export function pixelBufferFromImageData(imageData) {
|
|
61
|
+
return createPixelBuffer(imageData.data, imageData.width, imageData.height);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=image-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-loader.js","sourceRoot":"","sources":["../src/image-loader.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const BROWSER_SDK_VERSION: "2.0.0";
|
|
2
|
+
export * from "./browser-session.js";
|
|
3
|
+
export * from "./camera-source.js";
|
|
4
|
+
export * from "./image-loader.js";
|
|
5
|
+
export * from "./decode-upload.js";
|
|
6
|
+
export * from "./runtime.js";
|
|
7
|
+
export * from "./worker/worker-client.js";
|
|
8
|
+
export * from "./worker/worker-messages.js";
|
|
9
|
+
export * from "./worker/transferable-buffer.js";
|
|
10
|
+
export * from "./scanner/index.js";
|
|
11
|
+
export * from "./tracking/index.js";
|
|
12
|
+
export * from "./batch/index.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,EAAG,OAAgB,CAAC;AACpD,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const BROWSER_SDK_VERSION = "2.0.0";
|
|
2
|
+
export * from "./browser-session.js";
|
|
3
|
+
export * from "./camera-source.js";
|
|
4
|
+
export * from "./image-loader.js";
|
|
5
|
+
export * from "./decode-upload.js";
|
|
6
|
+
export * from "./runtime.js";
|
|
7
|
+
export * from "./worker/worker-client.js";
|
|
8
|
+
export * from "./worker/worker-messages.js";
|
|
9
|
+
export * from "./worker/transferable-buffer.js";
|
|
10
|
+
export * from "./scanner/index.js";
|
|
11
|
+
export * from "./tracking/index.js";
|
|
12
|
+
export * from "./batch/index.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,OAAgB,CAAC;AACpD,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC;AAC7B,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CaptureRouter, type CaptureRouterOptions } from "@scanly/core";
|
|
2
|
+
import { type ZxingCppWasmEngineOptions } from "@scanly/engine-zxing-cpp-wasm";
|
|
3
|
+
/** Explicit browser composition root; core never imports concrete decoders. */
|
|
4
|
+
export interface BrowserCaptureRouterOptions extends Omit<CaptureRouterOptions, "engines"> {
|
|
5
|
+
zxingCppWasm?: ZxingCppWasmEngineOptions | false;
|
|
6
|
+
}
|
|
7
|
+
export declare function createBrowserCaptureRouter(options?: BrowserCaptureRouterOptions): CaptureRouter;
|
|
8
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAkB,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGxF,OAAO,EAA4B,KAAK,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAEzG,+EAA+E;AAC/E,MAAM,WAAW,2BAA4B,SAAQ,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC;IACxF,YAAY,CAAC,EAAE,yBAAyB,GAAG,KAAK,CAAC;CAClD;AAED,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,2BAAgC,GAAG,aAAa,CAOnG"}
|
package/dist/runtime.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CaptureRouter, EngineRegistry } from "@scanly/core";
|
|
2
|
+
import { JsQrEngine } from "@scanly/engine-jsqr";
|
|
3
|
+
import { ZxingJsEngine } from "@scanly/engine-zxing-js";
|
|
4
|
+
import { createZxingCppWasmEngine } from "@scanly/engine-zxing-cpp-wasm";
|
|
5
|
+
export function createBrowserCaptureRouter(options = {}) {
|
|
6
|
+
const { zxingCppWasm, ...routerOptions } = options;
|
|
7
|
+
const engines = new EngineRegistry();
|
|
8
|
+
engines.register(new JsQrEngine());
|
|
9
|
+
if (zxingCppWasm !== false)
|
|
10
|
+
engines.register(createZxingCppWasmEngine(zxingCppWasm));
|
|
11
|
+
engines.register(new ZxingJsEngine());
|
|
12
|
+
return new CaptureRouter({ ...routerOptions, engines });
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAA6B,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAkC,MAAM,+BAA+B,CAAC;AAOzG,MAAM,UAAU,0BAA0B,CAAC,UAAuC,EAAE;IAClF,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,EAAE,GAAG,OAAO,CAAC;IACnD,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAC;IACrC,OAAO,CAAC,QAAQ,CAAC,IAAI,UAAU,EAAE,CAAC,CAAC;IACnC,IAAI,YAAY,KAAK,KAAK;QAAE,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC,YAAY,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,QAAQ,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;IACtC,OAAO,IAAI,aAAa,CAAC,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AutoZoomOptions, BarcodeGeometry, CameraCapabilities, CapabilityResult } from "./types.js";
|
|
2
|
+
export declare class CameraCapabilityController {
|
|
3
|
+
private readonly track;
|
|
4
|
+
private readonly autoZoom;
|
|
5
|
+
private lastAutoZoomAt;
|
|
6
|
+
private manualZoomOverride;
|
|
7
|
+
private autoZoomOperation;
|
|
8
|
+
constructor(track: () => MediaStreamTrack | undefined, autoZoom?: AutoZoomOptions);
|
|
9
|
+
getCapabilities(): CameraCapabilities;
|
|
10
|
+
setTorch(enabled: boolean): Promise<CapabilityResult<boolean>>;
|
|
11
|
+
setZoom(value: number, manual?: boolean): Promise<CapabilityResult<number>>;
|
|
12
|
+
requestFocus(): Promise<CapabilityResult<boolean>>;
|
|
13
|
+
considerAutoZoom(geometry: BarcodeGeometry, frame: {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
}, now?: number): Promise<CapabilityResult<number> | undefined>;
|
|
17
|
+
clearManualZoomOverride(): void;
|
|
18
|
+
private unsupported;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=camera-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-capabilities.d.ts","sourceRoot":"","sources":["../../src/scanner/camera-capabilities.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAqEzG,qBAAa,0BAA0B;IAMnC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAN3B,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,iBAAiB,CAAqB;gBAG3B,KAAK,EAAE,MAAM,gBAAgB,GAAG,SAAS,EACzC,QAAQ,GAAE,eAAoB;IAGjD,eAAe,IAAI,kBAAkB;IAS/B,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAiB9D,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,UAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IA2BxE,YAAY,IAAI,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAiBlD,gBAAgB,CACpB,QAAQ,EAAE,eAAe,EACzB,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EACxC,GAAG,SAAa,GACf,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC;IA2ChD,uBAAuB,IAAI,IAAI;IAI/B,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { sdkError } from "@scanly/core";
|
|
2
|
+
import { cameraError } from "./camera-platform.js";
|
|
3
|
+
const controllerStates = new WeakMap();
|
|
4
|
+
function resolveTrack(owner, provider, onSourceChanged) {
|
|
5
|
+
const track = provider();
|
|
6
|
+
const state = controllerStates.get(owner);
|
|
7
|
+
if (!state) {
|
|
8
|
+
controllerStates.set(owner, { activeTrack: track });
|
|
9
|
+
}
|
|
10
|
+
else if (state.activeTrack !== track) {
|
|
11
|
+
state.activeTrack = track;
|
|
12
|
+
state.lastAppliedZoom = undefined;
|
|
13
|
+
onSourceChanged();
|
|
14
|
+
}
|
|
15
|
+
return track;
|
|
16
|
+
}
|
|
17
|
+
function stateFor(owner) {
|
|
18
|
+
const state = controllerStates.get(owner);
|
|
19
|
+
if (!state)
|
|
20
|
+
throw new Error("Camera capability state was not initialized.");
|
|
21
|
+
return state;
|
|
22
|
+
}
|
|
23
|
+
function capabilitiesFor(track) {
|
|
24
|
+
const capabilities = track?.getCapabilities?.();
|
|
25
|
+
const settings = track?.getSettings?.();
|
|
26
|
+
const min = capabilities?.zoom?.min;
|
|
27
|
+
const max = capabilities?.zoom?.max;
|
|
28
|
+
const rawFocusMode = capabilities?.focusMode;
|
|
29
|
+
const continuousFocus = rawFocusMode === true || (Array.isArray(rawFocusMode) && rawFocusMode.includes("continuous"));
|
|
30
|
+
return {
|
|
31
|
+
torch: Boolean(capabilities?.torch),
|
|
32
|
+
...(min !== undefined && max !== undefined
|
|
33
|
+
? {
|
|
34
|
+
zoom: {
|
|
35
|
+
min,
|
|
36
|
+
max,
|
|
37
|
+
...(capabilities?.zoom?.step === undefined ? {} : { step: capabilities.zoom.step }),
|
|
38
|
+
...(settings?.zoom === undefined ? {} : { current: settings.zoom }),
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
: {}),
|
|
42
|
+
// The public boolean means requestFocus() can make the exact request it
|
|
43
|
+
// promises. Other modes (for example "manual") do not imply that the
|
|
44
|
+
// continuous-focus constraint is supported.
|
|
45
|
+
focusMode: continuousFocus,
|
|
46
|
+
...(settings?.width === undefined ? {} : { width: settings.width }),
|
|
47
|
+
...(settings?.height === undefined ? {} : { height: settings.height }),
|
|
48
|
+
...(settings?.deviceId === undefined ? {} : { deviceId: settings.deviceId }),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export class CameraCapabilityController {
|
|
52
|
+
track;
|
|
53
|
+
autoZoom;
|
|
54
|
+
lastAutoZoomAt = Number.NEGATIVE_INFINITY;
|
|
55
|
+
manualZoomOverride = false;
|
|
56
|
+
autoZoomOperation;
|
|
57
|
+
constructor(track, autoZoom = {}) {
|
|
58
|
+
this.track = track;
|
|
59
|
+
this.autoZoom = autoZoom;
|
|
60
|
+
}
|
|
61
|
+
getCapabilities() {
|
|
62
|
+
const track = resolveTrack(this, this.track, () => {
|
|
63
|
+
this.lastAutoZoomAt = Number.NEGATIVE_INFINITY;
|
|
64
|
+
this.manualZoomOverride = false;
|
|
65
|
+
this.autoZoomOperation = undefined;
|
|
66
|
+
});
|
|
67
|
+
return capabilitiesFor(track);
|
|
68
|
+
}
|
|
69
|
+
async setTorch(enabled) {
|
|
70
|
+
const track = resolveTrack(this, this.track, () => {
|
|
71
|
+
this.lastAutoZoomAt = Number.NEGATIVE_INFINITY;
|
|
72
|
+
this.manualZoomOverride = false;
|
|
73
|
+
this.autoZoomOperation = undefined;
|
|
74
|
+
});
|
|
75
|
+
if (!track || !capabilitiesFor(track).torch) {
|
|
76
|
+
return this.unsupported("Torch is not supported by the active camera track.");
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
await track.applyConstraints({ advanced: [{ torch: enabled }] });
|
|
80
|
+
return { ok: true, value: enabled };
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
return { ok: false, error: cameraError(error, "Unable to update camera torch.") };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async setZoom(value, manual = true) {
|
|
87
|
+
const track = resolveTrack(this, this.track, () => {
|
|
88
|
+
this.lastAutoZoomAt = Number.NEGATIVE_INFINITY;
|
|
89
|
+
this.manualZoomOverride = false;
|
|
90
|
+
this.autoZoomOperation = undefined;
|
|
91
|
+
});
|
|
92
|
+
const zoom = capabilitiesFor(track).zoom;
|
|
93
|
+
if (!track || !zoom) {
|
|
94
|
+
return this.unsupported("Zoom is not supported by the active camera track.");
|
|
95
|
+
}
|
|
96
|
+
if (!Number.isFinite(value) || value < zoom.min || value > zoom.max) {
|
|
97
|
+
return { ok: false, error: sdkError("invalid_configuration", `Zoom must be between ${zoom.min} and ${zoom.max}.`) };
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
await track.applyConstraints({ advanced: [{ zoom: value }] });
|
|
101
|
+
// A track can be switched while applyConstraints() is pending. Do not
|
|
102
|
+
// carry an old track's zoom state or manual override into the new source.
|
|
103
|
+
if (stateFor(this).activeTrack === track) {
|
|
104
|
+
stateFor(this).lastAppliedZoom = value;
|
|
105
|
+
this.manualZoomOverride = manual;
|
|
106
|
+
}
|
|
107
|
+
return { ok: true, value };
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return { ok: false, error: cameraError(error, "Unable to update camera zoom.") };
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async requestFocus() {
|
|
114
|
+
const track = resolveTrack(this, this.track, () => {
|
|
115
|
+
this.lastAutoZoomAt = Number.NEGATIVE_INFINITY;
|
|
116
|
+
this.manualZoomOverride = false;
|
|
117
|
+
this.autoZoomOperation = undefined;
|
|
118
|
+
});
|
|
119
|
+
if (!track || !capabilitiesFor(track).focusMode) {
|
|
120
|
+
return this.unsupported("Focus control is not supported by the active camera track.");
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
await track.applyConstraints({ advanced: [{ focusMode: "continuous" }] });
|
|
124
|
+
return { ok: true, value: true };
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
return { ok: false, error: cameraError(error, "Unable to request camera focus.") };
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async considerAutoZoom(geometry, frame, now = Date.now()) {
|
|
131
|
+
const track = resolveTrack(this, this.track, () => {
|
|
132
|
+
this.lastAutoZoomAt = Number.NEGATIVE_INFINITY;
|
|
133
|
+
this.manualZoomOverride = false;
|
|
134
|
+
this.autoZoomOperation = undefined;
|
|
135
|
+
});
|
|
136
|
+
const cooldownMs = Math.max(0, this.autoZoom.cooldownMs ?? 1_500);
|
|
137
|
+
if (this.autoZoom.enabled === false
|
|
138
|
+
|| this.manualZoomOverride
|
|
139
|
+
|| this.autoZoomOperation !== undefined
|
|
140
|
+
|| now - this.lastAutoZoomAt < cooldownMs)
|
|
141
|
+
return undefined;
|
|
142
|
+
const zoom = capabilitiesFor(track).zoom;
|
|
143
|
+
if (!track || !zoom)
|
|
144
|
+
return undefined;
|
|
145
|
+
const frameArea = Math.max(1, frame.width * frame.height);
|
|
146
|
+
const barcodeArea = Math.max(0, geometry.boundingBox.width) * Math.max(0, geometry.boundingBox.height);
|
|
147
|
+
if (barcodeArea / frameArea >= (this.autoZoom.minimumBarcodeAreaRatio ?? 0.04))
|
|
148
|
+
return undefined;
|
|
149
|
+
// Some browsers update getSettings().zoom asynchronously. Remembering the
|
|
150
|
+
// last successful constraint prevents repeated requests for the same value.
|
|
151
|
+
const current = Math.min(zoom.max, Math.max(zoom.min, stateFor(this).lastAppliedZoom ?? zoom.current ?? zoom.min));
|
|
152
|
+
const configuredDelta = this.autoZoom.maximumZoomDelta ?? 0.5;
|
|
153
|
+
const delta = Number.isFinite(configuredDelta) ? Math.max(0, configuredDelta) : 0;
|
|
154
|
+
const next = Math.min(zoom.max, current + delta);
|
|
155
|
+
if (next <= current)
|
|
156
|
+
return undefined;
|
|
157
|
+
// Reserve the cooldown before awaiting applyConstraints so concurrent frame
|
|
158
|
+
// observations cannot issue duplicate zoom requests.
|
|
159
|
+
const previousAutoZoomAt = this.lastAutoZoomAt;
|
|
160
|
+
const operation = {};
|
|
161
|
+
this.lastAutoZoomAt = now;
|
|
162
|
+
this.autoZoomOperation = operation;
|
|
163
|
+
try {
|
|
164
|
+
const result = await this.setZoom(next, false);
|
|
165
|
+
if (!result.ok && this.autoZoomOperation === operation)
|
|
166
|
+
this.lastAutoZoomAt = previousAutoZoomAt;
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
finally {
|
|
170
|
+
if (this.autoZoomOperation === operation)
|
|
171
|
+
this.autoZoomOperation = undefined;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
clearManualZoomOverride() {
|
|
175
|
+
this.manualZoomOverride = false;
|
|
176
|
+
}
|
|
177
|
+
unsupported(message) {
|
|
178
|
+
return { ok: false, error: sdkError("camera_capability_unsupported", message) };
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=camera-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-capabilities.js","sourceRoot":"","sources":["../../src/scanner/camera-capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type SdkError, type SdkErrorCode } from "@scanly/core";
|
|
2
|
+
export type CameraLifecycleReason = "orientation-change" | "resolution-change" | "constraints-renegotiated" | "background-suspended" | "foreground-resumed";
|
|
3
|
+
export interface CameraLifecycleEvent {
|
|
4
|
+
reason: CameraLifecycleReason;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
detail?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface CameraConstraintPolicy {
|
|
9
|
+
deviceId?: string;
|
|
10
|
+
facingMode?: "user" | "environment";
|
|
11
|
+
preferredWidth?: number;
|
|
12
|
+
preferredHeight?: number;
|
|
13
|
+
preferredFrameRate?: number;
|
|
14
|
+
/** Device selection is exact only when a caller explicitly supplies a device id. */
|
|
15
|
+
exactDevice?: boolean;
|
|
16
|
+
/** Bounded acquisition attempts. Defaults to three and is capped at four. */
|
|
17
|
+
maximumAttempts?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface CameraConstraintAttempt {
|
|
20
|
+
index: number;
|
|
21
|
+
constraints: MediaTrackConstraints | true;
|
|
22
|
+
result: "negotiated" | "failed";
|
|
23
|
+
errorCode?: SdkErrorCode;
|
|
24
|
+
errorMessage?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface DeviceDiagnostics {
|
|
27
|
+
requestedConstraints: CameraConstraintPolicy;
|
|
28
|
+
supportedConstraints: Record<string, boolean> | "unavailable";
|
|
29
|
+
attempts: readonly CameraConstraintAttempt[];
|
|
30
|
+
negotiatedSettings: Record<string, unknown> | "unavailable";
|
|
31
|
+
trackCapabilities: Record<string, unknown> | "unavailable";
|
|
32
|
+
trackConstraints: Record<string, unknown> | "unavailable";
|
|
33
|
+
}
|
|
34
|
+
export interface CameraRecoveryPolicy {
|
|
35
|
+
maximumRetries?: number;
|
|
36
|
+
baseDelayMs?: number;
|
|
37
|
+
maximumDelayMs?: number;
|
|
38
|
+
wait?: (delayMs: number) => Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export interface CameraRecoveryDecision {
|
|
41
|
+
retry: boolean;
|
|
42
|
+
attempt: number;
|
|
43
|
+
delayMs: number;
|
|
44
|
+
reason: string;
|
|
45
|
+
}
|
|
46
|
+
export interface CameraRecoveryStatistics {
|
|
47
|
+
attempts: number;
|
|
48
|
+
restarts: number;
|
|
49
|
+
failures: number;
|
|
50
|
+
exhausted: boolean;
|
|
51
|
+
}
|
|
52
|
+
export declare function cameraError(error: unknown, fallback?: string): SdkError;
|
|
53
|
+
export declare function negotiateCameraStream(policy: CameraConstraintPolicy): Promise<{
|
|
54
|
+
stream: MediaStream;
|
|
55
|
+
diagnostics: DeviceDiagnostics;
|
|
56
|
+
}>;
|
|
57
|
+
export declare function diagnosticsForTrack(policy: CameraConstraintPolicy, track: MediaStreamTrack | undefined, attempts?: readonly CameraConstraintAttempt[]): DeviceDiagnostics;
|
|
58
|
+
export declare class CameraRecoveryController {
|
|
59
|
+
private attempts;
|
|
60
|
+
private restarts;
|
|
61
|
+
private failures;
|
|
62
|
+
private exhausted;
|
|
63
|
+
private readonly maximumRetries;
|
|
64
|
+
private readonly baseDelayMs;
|
|
65
|
+
private readonly maximumDelayMs;
|
|
66
|
+
private readonly waiter;
|
|
67
|
+
constructor(policy?: CameraRecoveryPolicy);
|
|
68
|
+
next(reason: string): CameraRecoveryDecision;
|
|
69
|
+
wait(decision: CameraRecoveryDecision): Promise<void>;
|
|
70
|
+
markRestarted(): void;
|
|
71
|
+
markFailed(): void;
|
|
72
|
+
reset(): void;
|
|
73
|
+
getStatistics(): CameraRecoveryStatistics;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=camera-platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera-platform.d.ts","sourceRoot":"","sources":["../../src/scanner/camera-platform.ts"],"names":[],"mappings":"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"}
|