@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,267 @@
|
|
|
1
|
+
import { BarcodeTracker } from "../tracking/barcode-tracker.js";
|
|
2
|
+
import { BatchController } from "./batch-controller.js";
|
|
3
|
+
/**
|
|
4
|
+
* ScannerSession + BarcodeTracker + BatchController composition. React and
|
|
5
|
+
* other UI layers only subscribe to the resulting SDK state.
|
|
6
|
+
*/
|
|
7
|
+
export class BatchScanSession {
|
|
8
|
+
scanner;
|
|
9
|
+
tracker;
|
|
10
|
+
controller;
|
|
11
|
+
disposeScanner;
|
|
12
|
+
disposeTracker;
|
|
13
|
+
subscriptions;
|
|
14
|
+
pendingScannerFrames = new Map();
|
|
15
|
+
generation = 0;
|
|
16
|
+
stopRequested = false;
|
|
17
|
+
disposed = false;
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.scanner = options.scanner;
|
|
20
|
+
this.tracker = options.tracker ?? new BarcodeTracker(options.trackerOptions);
|
|
21
|
+
this.controller = new BatchController(options);
|
|
22
|
+
this.disposeScanner = options.disposeScanner ?? true;
|
|
23
|
+
this.disposeTracker = options.disposeTracker ?? true;
|
|
24
|
+
const observationSubscription = typeof this.scanner.onObservations === "function"
|
|
25
|
+
? this.scanner.onObservations((set) => this.observeScannerObservationSet(set))
|
|
26
|
+
: this.scanner.onDiagnostics((diagnostic) => this.observeScannerDiagnostic(diagnostic));
|
|
27
|
+
this.subscriptions = [observationSubscription, this.scanner.onStateChange((state) => this.observeScannerState(state))];
|
|
28
|
+
}
|
|
29
|
+
async start() {
|
|
30
|
+
this.assertUsable();
|
|
31
|
+
const state = this.scanner.getState();
|
|
32
|
+
if (state === "starting" || state === "scanning" || state === "paused")
|
|
33
|
+
return;
|
|
34
|
+
this.generation += 1;
|
|
35
|
+
this.pendingScannerFrames.clear();
|
|
36
|
+
this.tracker.reset();
|
|
37
|
+
this.controller.reset();
|
|
38
|
+
this.stopRequested = false;
|
|
39
|
+
try {
|
|
40
|
+
await this.scanner.start();
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.controller.fail(error);
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
pause() {
|
|
48
|
+
if (this.disposed || this.scanner.getState() !== "scanning")
|
|
49
|
+
return;
|
|
50
|
+
this.invalidatePendingFrames();
|
|
51
|
+
this.scanner.pause();
|
|
52
|
+
}
|
|
53
|
+
resume() {
|
|
54
|
+
if (this.disposed || this.scanner.getState() !== "paused")
|
|
55
|
+
return;
|
|
56
|
+
this.scanner.resume();
|
|
57
|
+
}
|
|
58
|
+
async stop() {
|
|
59
|
+
if (this.disposed)
|
|
60
|
+
return;
|
|
61
|
+
this.stopRequested = true;
|
|
62
|
+
this.invalidatePendingFrames();
|
|
63
|
+
const errors = [];
|
|
64
|
+
try {
|
|
65
|
+
await this.scanner.stop();
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
errors.push(error);
|
|
69
|
+
this.controller.fail(error);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
// A ScannerSession implementation may reject before changing state.
|
|
73
|
+
// Keep the generation closed so late observation callbacks cannot mutate
|
|
74
|
+
// the terminal batch state.
|
|
75
|
+
this.invalidatePendingFrames();
|
|
76
|
+
try {
|
|
77
|
+
this.tracker.reset();
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
errors.push(error);
|
|
81
|
+
this.controller.fail(error);
|
|
82
|
+
}
|
|
83
|
+
if (errors.length === 0 && this.controller.getState().status === "collecting")
|
|
84
|
+
this.controller.cancel();
|
|
85
|
+
try {
|
|
86
|
+
this.controller.releaseRetainedState();
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
errors.push(error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (errors.length === 1)
|
|
93
|
+
throw errors[0];
|
|
94
|
+
if (errors.length > 1)
|
|
95
|
+
throw new AggregateError(errors, "BatchScanSession stop failed after attempting runtime cleanup.");
|
|
96
|
+
}
|
|
97
|
+
async dispose() {
|
|
98
|
+
if (this.disposed)
|
|
99
|
+
return;
|
|
100
|
+
// Close callbacks before awaiting fallible delegated lifecycle methods.
|
|
101
|
+
this.disposed = true;
|
|
102
|
+
this.stopRequested = true;
|
|
103
|
+
this.invalidatePendingFrames();
|
|
104
|
+
const errors = [];
|
|
105
|
+
try {
|
|
106
|
+
await this.scanner.stop();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
errors.push(error);
|
|
110
|
+
}
|
|
111
|
+
finally {
|
|
112
|
+
if (this.controller.getState().status === "collecting")
|
|
113
|
+
this.controller.cancel();
|
|
114
|
+
for (const unsubscribe of this.subscriptions.splice(0)) {
|
|
115
|
+
try {
|
|
116
|
+
unsubscribe();
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
errors.push(error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (this.disposeTracker) {
|
|
123
|
+
// Reset first so an injected/fallible dispose implementation cannot
|
|
124
|
+
// strand live identities owned by this composition.
|
|
125
|
+
try {
|
|
126
|
+
this.tracker.reset();
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
errors.push(error);
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
this.tracker.dispose();
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
errors.push(error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
this.pendingScannerFrames.clear();
|
|
139
|
+
try {
|
|
140
|
+
this.controller.clear();
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
errors.push(error);
|
|
144
|
+
}
|
|
145
|
+
if (this.disposeScanner) {
|
|
146
|
+
try {
|
|
147
|
+
await this.scanner.dispose();
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
errors.push(error);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (errors.length === 1)
|
|
155
|
+
throw errors[0];
|
|
156
|
+
if (errors.length > 1)
|
|
157
|
+
throw new AggregateError(errors, "BatchScanSession disposal failed after completing all cleanup steps.");
|
|
158
|
+
}
|
|
159
|
+
getTracks() {
|
|
160
|
+
return this.tracker.getTracks();
|
|
161
|
+
}
|
|
162
|
+
getBatchState() {
|
|
163
|
+
return this.controller.getState();
|
|
164
|
+
}
|
|
165
|
+
getStatistics() {
|
|
166
|
+
return this.controller.getStatistics();
|
|
167
|
+
}
|
|
168
|
+
onTrack(listener) {
|
|
169
|
+
return this.controller.onTrack(listener);
|
|
170
|
+
}
|
|
171
|
+
onBatchEvent(listener) {
|
|
172
|
+
return this.controller.onEvent(listener);
|
|
173
|
+
}
|
|
174
|
+
/** Explicit frame API used by deterministic runtimes and custom capture adapters. */
|
|
175
|
+
processFrame(observations, frame) {
|
|
176
|
+
this.assertUsable();
|
|
177
|
+
const update = this.tracker.observeFrame(observations, frame);
|
|
178
|
+
this.controller.applyTrackerUpdate(update);
|
|
179
|
+
return update;
|
|
180
|
+
}
|
|
181
|
+
/** Accept an update from an externally-driven instance of the same tracker. */
|
|
182
|
+
applyTrackerUpdate(update) {
|
|
183
|
+
this.assertUsable();
|
|
184
|
+
this.controller.applyTrackerUpdate(update);
|
|
185
|
+
}
|
|
186
|
+
observeScannerDiagnostic(diagnostic) {
|
|
187
|
+
if (this.disposed || this.stopRequested || !diagnostic.event || diagnostic.frameId === undefined)
|
|
188
|
+
return;
|
|
189
|
+
if (diagnostic.event.type !== "detected" && diagnostic.event.type !== "lost")
|
|
190
|
+
return;
|
|
191
|
+
if (this.scanner.getState() !== "starting" && this.scanner.getState() !== "scanning")
|
|
192
|
+
return;
|
|
193
|
+
const frameId = diagnostic.frameId;
|
|
194
|
+
const pending = this.pendingScannerFrames.get(frameId) ?? {
|
|
195
|
+
timestamp: diagnostic.timestamp,
|
|
196
|
+
observations: [],
|
|
197
|
+
generation: this.generation,
|
|
198
|
+
scheduled: false,
|
|
199
|
+
};
|
|
200
|
+
pending.timestamp = Math.max(pending.timestamp, diagnostic.timestamp);
|
|
201
|
+
const event = diagnostic.event;
|
|
202
|
+
if (event.type === "detected" && event.geometry) {
|
|
203
|
+
pending.observations.push({
|
|
204
|
+
payload: event.barcode.text,
|
|
205
|
+
format: event.barcode.format,
|
|
206
|
+
geometry: event.geometry,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
this.pendingScannerFrames.set(frameId, pending);
|
|
210
|
+
if (pending.scheduled)
|
|
211
|
+
return;
|
|
212
|
+
pending.scheduled = true;
|
|
213
|
+
queueMicrotask(() => this.flushScannerFrame(frameId, pending));
|
|
214
|
+
}
|
|
215
|
+
observeScannerObservationSet(set) {
|
|
216
|
+
if (this.disposed || this.stopRequested || (this.scanner.getState() !== "starting" && this.scanner.getState() !== "scanning"))
|
|
217
|
+
return;
|
|
218
|
+
const observations = set.observations.flatMap((observation) => observation.geometry ? [{
|
|
219
|
+
payload: observation.barcode.text,
|
|
220
|
+
format: observation.barcode.format,
|
|
221
|
+
geometry: observation.geometry,
|
|
222
|
+
}] : []);
|
|
223
|
+
try {
|
|
224
|
+
this.processFrame(observations, { frameId: set.frameId, timestamp: set.timestamp });
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
this.controller.fail(error);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
flushScannerFrame(frameId, pending) {
|
|
231
|
+
if (this.pendingScannerFrames.get(frameId) !== pending)
|
|
232
|
+
return;
|
|
233
|
+
this.pendingScannerFrames.delete(frameId);
|
|
234
|
+
if (this.disposed || this.stopRequested || pending.generation !== this.generation)
|
|
235
|
+
return;
|
|
236
|
+
if (this.scanner.getState() !== "starting" && this.scanner.getState() !== "scanning")
|
|
237
|
+
return;
|
|
238
|
+
try {
|
|
239
|
+
this.processFrame(pending.observations, { frameId, timestamp: pending.timestamp });
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
this.controller.fail(error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
observeScannerState(state) {
|
|
246
|
+
if (this.disposed)
|
|
247
|
+
return;
|
|
248
|
+
if (state === "failed") {
|
|
249
|
+
this.invalidatePendingFrames();
|
|
250
|
+
this.controller.fail(new Error("ScannerSession failed while collecting a batch."));
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (state === "stopped" && !this.stopRequested && this.controller.getState().status === "collecting") {
|
|
254
|
+
this.invalidatePendingFrames();
|
|
255
|
+
this.controller.cancel();
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
invalidatePendingFrames() {
|
|
259
|
+
this.generation += 1;
|
|
260
|
+
this.pendingScannerFrames.clear();
|
|
261
|
+
}
|
|
262
|
+
assertUsable() {
|
|
263
|
+
if (this.disposed)
|
|
264
|
+
throw new Error("BatchScanSession has been disposed.");
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=batch-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch-session.js","sourceRoot":"","sources":["../../src/batch/batch-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/batch/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/batch/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { BarcodeFormat } from "@scanly/core";
|
|
2
|
+
import type { BarcodeTrack } from "../tracking/types.js";
|
|
3
|
+
/** Batch behavior is orthogonal to camera capture and frame scheduling. */
|
|
4
|
+
export type BatchMode = "continuous" | "expected-count" | "checklist" | "unique-physical-instance";
|
|
5
|
+
export type BatchStatus = "collecting" | "complete" | "failed" | "cancelled";
|
|
6
|
+
export interface ExpectedBatchItem {
|
|
7
|
+
payload: string;
|
|
8
|
+
format?: BarcodeFormat;
|
|
9
|
+
/** Defaults to one. Quantities are physical instances, not decoder events. */
|
|
10
|
+
quantity?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface BatchMatchedItem {
|
|
13
|
+
item: ExpectedBatchItem;
|
|
14
|
+
track: BarcodeTrack;
|
|
15
|
+
}
|
|
16
|
+
export interface BatchMissingItem {
|
|
17
|
+
item: ExpectedBatchItem;
|
|
18
|
+
quantity: number;
|
|
19
|
+
}
|
|
20
|
+
export interface BatchState {
|
|
21
|
+
mode: BatchMode;
|
|
22
|
+
status: BatchStatus;
|
|
23
|
+
expectedCount?: number;
|
|
24
|
+
confirmedPhysicalInstanceCount: number;
|
|
25
|
+
matched: readonly BatchMatchedItem[];
|
|
26
|
+
missing: readonly BatchMissingItem[];
|
|
27
|
+
unexpected: readonly BarcodeTrack[];
|
|
28
|
+
duplicate: readonly BarcodeTrack[];
|
|
29
|
+
completedAt?: number;
|
|
30
|
+
failureReason?: string;
|
|
31
|
+
}
|
|
32
|
+
export type TrackEvent = {
|
|
33
|
+
type: "track-added";
|
|
34
|
+
track: BarcodeTrack;
|
|
35
|
+
} | {
|
|
36
|
+
type: "track-updated";
|
|
37
|
+
track: BarcodeTrack;
|
|
38
|
+
} | {
|
|
39
|
+
type: "track-lost";
|
|
40
|
+
trackId: string;
|
|
41
|
+
track: BarcodeTrack;
|
|
42
|
+
} | {
|
|
43
|
+
type: "track-restored";
|
|
44
|
+
track: BarcodeTrack;
|
|
45
|
+
} | {
|
|
46
|
+
type: "track-retired";
|
|
47
|
+
trackId: string;
|
|
48
|
+
track: BarcodeTrack;
|
|
49
|
+
};
|
|
50
|
+
export type BatchEvent = TrackEvent | {
|
|
51
|
+
type: "item-matched";
|
|
52
|
+
item: ExpectedBatchItem;
|
|
53
|
+
track: BarcodeTrack;
|
|
54
|
+
} | {
|
|
55
|
+
type: "unexpected-item";
|
|
56
|
+
track: BarcodeTrack;
|
|
57
|
+
} | {
|
|
58
|
+
type: "duplicate-item";
|
|
59
|
+
item: ExpectedBatchItem;
|
|
60
|
+
track: BarcodeTrack;
|
|
61
|
+
} | {
|
|
62
|
+
type: "batch-completed";
|
|
63
|
+
state: BatchState;
|
|
64
|
+
} | {
|
|
65
|
+
type: "batch-cancelled";
|
|
66
|
+
state: BatchState;
|
|
67
|
+
} | {
|
|
68
|
+
type: "batch-failed";
|
|
69
|
+
state: BatchState;
|
|
70
|
+
error: unknown;
|
|
71
|
+
};
|
|
72
|
+
export interface BatchStatistics {
|
|
73
|
+
confirmedPhysicalInstanceCount: number;
|
|
74
|
+
maxRetainedTracks: number;
|
|
75
|
+
maxRetainedPhysicalInstances: number;
|
|
76
|
+
/** Current bounded controller snapshots, exposed for memory evidence. */
|
|
77
|
+
retainedTrackCount: number;
|
|
78
|
+
retainedPhysicalInstanceCount: number;
|
|
79
|
+
peakRetainedTrackCount: number;
|
|
80
|
+
peakRetainedPhysicalInstanceCount: number;
|
|
81
|
+
peakUnexpectedQuantity: number;
|
|
82
|
+
peakDuplicateQuantity: number;
|
|
83
|
+
retentionRejectedTrackCount: number;
|
|
84
|
+
retentionRejectedPhysicalInstanceCount: number;
|
|
85
|
+
retentionEvictedPhysicalInstanceCount: number;
|
|
86
|
+
matchedQuantity: number;
|
|
87
|
+
missingQuantity: number;
|
|
88
|
+
unexpectedQuantity: number;
|
|
89
|
+
duplicateQuantity: number;
|
|
90
|
+
trackAddedEvents: number;
|
|
91
|
+
trackUpdatedEvents: number;
|
|
92
|
+
trackLostEvents: number;
|
|
93
|
+
trackRestoredEvents: number;
|
|
94
|
+
trackRetiredEvents: number;
|
|
95
|
+
batchCompletedEvents: number;
|
|
96
|
+
completionAccuracy: number;
|
|
97
|
+
}
|
|
98
|
+
export type TrackListener = (event: TrackEvent) => void;
|
|
99
|
+
export type BatchEventListener = (event: BatchEvent) => void;
|
|
100
|
+
export type BatchUnsubscribe = () => void;
|
|
101
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/batch/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/batch/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CaptureRouter, type BarcodeFormat, type ConcurrentCallPolicy, type FormatSelection, type RecoveryBudget, type RecoveryProfile, type RecoveryRouteId, type ScanOutcome } from "@scanly/core";
|
|
2
|
+
import { type ScenarioDefinition } from "@scanly/scenario-schema";
|
|
3
|
+
import { type DecodeWorkerFactory, type WorkerScanOptions } from "./worker/worker-client.js";
|
|
4
|
+
export type BrowserCaptureSessionState = "idle" | "initialized" | "running" | "stopped" | "disposed";
|
|
5
|
+
export interface BrowserScanFileOptions extends WorkerScanOptions {
|
|
6
|
+
forceMainThread?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface BrowserCaptureSessionOptions {
|
|
9
|
+
scenario?: ScenarioDefinition;
|
|
10
|
+
formats?: FormatSelection | readonly BarcodeFormat[];
|
|
11
|
+
concurrentCallPolicy?: ConcurrentCallPolicy;
|
|
12
|
+
workerFactory?: DecodeWorkerFactory;
|
|
13
|
+
router?: CaptureRouter;
|
|
14
|
+
disposeRouter?: boolean;
|
|
15
|
+
/** Static industrial recovery is explicit; normal upload behavior is unchanged. */
|
|
16
|
+
recovery?: false | BrowserStaticIndustrialRecoveryOptions;
|
|
17
|
+
}
|
|
18
|
+
export interface BrowserStaticIndustrialRecoveryOptions {
|
|
19
|
+
profile?: RecoveryProfile;
|
|
20
|
+
budget?: RecoveryBudget;
|
|
21
|
+
dpmExperimental?: boolean;
|
|
22
|
+
excludedRoutes?: readonly RecoveryRouteId[];
|
|
23
|
+
}
|
|
24
|
+
export declare class BrowserCaptureSession {
|
|
25
|
+
private state;
|
|
26
|
+
private scenario;
|
|
27
|
+
private readonly concurrentPolicy;
|
|
28
|
+
private readonly worker;
|
|
29
|
+
private readonly router;
|
|
30
|
+
private readonly ownsRouter;
|
|
31
|
+
private controller;
|
|
32
|
+
private owner;
|
|
33
|
+
private recovery;
|
|
34
|
+
private readonly recoveryPipeline;
|
|
35
|
+
constructor(options?: BrowserCaptureSessionOptions);
|
|
36
|
+
getState(): BrowserCaptureSessionState;
|
|
37
|
+
initialize(): void;
|
|
38
|
+
start(): void;
|
|
39
|
+
stop(): void;
|
|
40
|
+
cancel(): void;
|
|
41
|
+
updateConfiguration(scenario: ScenarioDefinition): void;
|
|
42
|
+
updateFormats(selection: FormatSelection | readonly BarcodeFormat[]): void;
|
|
43
|
+
scanFile(file: File, options?: BrowserScanFileOptions): Promise<ScanOutcome>;
|
|
44
|
+
updateRecovery(recovery: false | BrowserStaticIndustrialRecoveryOptions): void;
|
|
45
|
+
private workerRecovery;
|
|
46
|
+
private decodeOnMain;
|
|
47
|
+
dispose(): Promise<void>;
|
|
48
|
+
private assertNotDisposed;
|
|
49
|
+
private failure;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=browser-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-session.d.ts","sourceRoot":"","sources":["../src/browser-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAgH,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAoB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACrU,OAAO,EAAwC,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGxG,OAAO,EAAsC,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAEjI,MAAM,MAAM,0BAA0B,GAAG,MAAM,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AACrG,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAAG,eAAe,CAAC,EAAE,OAAO,CAAA;CAAE;AAC/F,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,aAAa,EAAE,CAAC;IACrD,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,KAAK,GAAG,sCAAsC,CAAC;CAC3D;AAED,MAAM,WAAW,sCAAsC;IACrD,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAID,qBAAa,qBAAqB;IAChC,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;IACrC,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,QAAQ,CAAiD;IACjE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoC;gBAEzD,OAAO,GAAE,4BAAiC;IAatD,QAAQ,IAAI,0BAA0B;IACtC,UAAU,IAAI,IAAI;IAClB,KAAK,IAAI,IAAI;IACb,IAAI,IAAI,IAAI;IACZ,MAAM,IAAI,IAAI;IAEd,mBAAmB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI;IASvD,aAAa,CAAC,SAAS,EAAE,eAAe,GAAG,SAAS,aAAa,EAAE,GAAG,IAAI;IAKpE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,WAAW,CAAC;IAyEtF,cAAc,CAAC,QAAQ,EAAE,KAAK,GAAG,sCAAsC,GAAG,IAAI;IAM9E,OAAO,CAAC,cAAc;YAYR,YAAY;IASpB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,OAAO;CAGhB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { CaptureRouter, IndustrialRecoveryPipeline, createRecoveryProbeScenario, createRgbaFrame, normalizeFormatSelection, sdkError } from "@scanly/core";
|
|
2
|
+
import { getBuiltinScenario, validateScenario } from "@scanly/scenario-schema";
|
|
3
|
+
import { loadPixelBufferFromFile } from "./image-loader.js";
|
|
4
|
+
import { createBrowserCaptureRouter } from "./runtime.js";
|
|
5
|
+
import { DecodeWorkerClient, markDecodePath } from "./worker/worker-client.js";
|
|
6
|
+
let browserFrameSequence = 0;
|
|
7
|
+
export class BrowserCaptureSession {
|
|
8
|
+
state = "idle";
|
|
9
|
+
scenario;
|
|
10
|
+
concurrentPolicy;
|
|
11
|
+
worker;
|
|
12
|
+
router;
|
|
13
|
+
ownsRouter;
|
|
14
|
+
controller = null;
|
|
15
|
+
owner = 0;
|
|
16
|
+
recovery;
|
|
17
|
+
recoveryPipeline = new IndustrialRecoveryPipeline();
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
const initial = options.scenario ?? getBuiltinScenario("balanced");
|
|
20
|
+
const configured = options.formats ? { ...initial, acceptedFormats: [...normalizeFormatSelection(options.formats).formats] } : initial;
|
|
21
|
+
const validation = validateScenario(configured);
|
|
22
|
+
if (!validation.ok)
|
|
23
|
+
throw Object.assign(new Error(validation.message), { code: "malformed_scenario", issues: validation.issues });
|
|
24
|
+
this.scenario = validation.value;
|
|
25
|
+
this.concurrentPolicy = options.concurrentCallPolicy ?? "replace";
|
|
26
|
+
this.worker = new DecodeWorkerClient(options.workerFactory);
|
|
27
|
+
this.router = options.router ?? createBrowserCaptureRouter({ scenario: this.scenario });
|
|
28
|
+
this.ownsRouter = options.disposeRouter ?? !options.router;
|
|
29
|
+
this.recovery = options.recovery ?? false;
|
|
30
|
+
}
|
|
31
|
+
getState() { return this.state; }
|
|
32
|
+
initialize() { this.assertNotDisposed(); if (this.state === "idle" || this.state === "stopped")
|
|
33
|
+
this.state = "initialized"; }
|
|
34
|
+
start() { this.assertNotDisposed(); if (this.state === "idle")
|
|
35
|
+
this.initialize(); this.state = "running"; }
|
|
36
|
+
stop() { if (this.state === "disposed")
|
|
37
|
+
return; this.cancel(); this.state = "stopped"; }
|
|
38
|
+
cancel() { this.owner += 1; this.controller?.abort(); this.controller = null; this.worker.cancel(); }
|
|
39
|
+
updateConfiguration(scenario) {
|
|
40
|
+
this.assertNotDisposed();
|
|
41
|
+
const validation = validateScenario(scenario);
|
|
42
|
+
if (!validation.ok)
|
|
43
|
+
throw Object.assign(new Error(validation.message), { code: "malformed_scenario", issues: validation.issues });
|
|
44
|
+
this.cancel();
|
|
45
|
+
this.router.updateScenario(validation.value);
|
|
46
|
+
this.scenario = validation.value;
|
|
47
|
+
}
|
|
48
|
+
updateFormats(selection) {
|
|
49
|
+
const formats = normalizeFormatSelection(selection).formats;
|
|
50
|
+
this.updateConfiguration({ ...this.scenario, acceptedFormats: [...formats] });
|
|
51
|
+
}
|
|
52
|
+
async scanFile(file, options = {}) {
|
|
53
|
+
const frameId = `browser-frame-${Date.now()}-${++browserFrameSequence}`;
|
|
54
|
+
if (this.state === "disposed")
|
|
55
|
+
return this.failure(frameId, "session_disposed", "Browser capture session has been disposed.");
|
|
56
|
+
if (this.state !== "running")
|
|
57
|
+
return this.failure(frameId, "session_not_running", "Browser capture session must be started before scanFile().");
|
|
58
|
+
if (this.controller && this.concurrentPolicy === "reject")
|
|
59
|
+
return this.failure(frameId, "concurrent_call_rejected", "This session allows one active scan.");
|
|
60
|
+
if (this.controller)
|
|
61
|
+
this.cancel();
|
|
62
|
+
const owner = ++this.owner;
|
|
63
|
+
const controller = new AbortController();
|
|
64
|
+
this.controller = controller;
|
|
65
|
+
const onAbort = () => controller.abort();
|
|
66
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
67
|
+
try {
|
|
68
|
+
options.onStage?.("Loading image...");
|
|
69
|
+
const pixels = await loadPixelBufferFromFile(file);
|
|
70
|
+
if (controller.signal.aborted)
|
|
71
|
+
return this.failure(frameId, "cancelled", "Decode cancelled.");
|
|
72
|
+
const workerPath = !options.forceMainThread && typeof Worker !== "undefined";
|
|
73
|
+
const frame = createRgbaFrame(pixels.data, pixels.width, pixels.height, { id: frameId, sourceType: "upload", ownership: workerPath ? "transferred" : "owned" });
|
|
74
|
+
let outcome;
|
|
75
|
+
if (workerPath) {
|
|
76
|
+
const decodeStartedAt = Date.now();
|
|
77
|
+
const scenario = this.scenario;
|
|
78
|
+
markDecodePath("worker");
|
|
79
|
+
outcome = await this.worker.scan(frame, scenario, { signal: controller.signal, preserveSourceForFallback: true, onStage: options.onStage, onProgress: options.onProgress, ...(this.workerRecovery() ? { recovery: this.workerRecovery() } : {}) });
|
|
80
|
+
if (!outcome.ok && ["worker_initialization_failure", "engine_execution_failure"].includes(outcome.error.code) && !controller.signal.aborted && owner === this.owner) {
|
|
81
|
+
const workerOutcome = outcome;
|
|
82
|
+
const workerElapsedMs = Math.max(Date.now() - decodeStartedAt, workerOutcome.timing.totalMs);
|
|
83
|
+
const remainingExecutionMs = Math.floor(scenario.budgets.maxExecutionMs - workerElapsedMs);
|
|
84
|
+
const remainingAttempts = scenario.budgets.maxAttempts - workerOutcome.attemptCount;
|
|
85
|
+
if (remainingExecutionMs > 0 && remainingAttempts > 0) {
|
|
86
|
+
markDecodePath("main-thread");
|
|
87
|
+
options.onStage?.("Worker unavailable; retrying on main thread within the remaining scan budget...");
|
|
88
|
+
const fallbackScenario = {
|
|
89
|
+
...scenario,
|
|
90
|
+
multiCode: { ...scenario.multiCode, maxResults: Math.min(scenario.multiCode.maxResults, remainingAttempts) },
|
|
91
|
+
budgets: { ...scenario.budgets, maxAttempts: remainingAttempts, maxExecutionMs: remainingExecutionMs },
|
|
92
|
+
};
|
|
93
|
+
const fallback = await this.decodeOnMain(createRgbaFrame(pixels.data, pixels.width, pixels.height, { id: frameId, sourceType: "upload", ownership: "owned" }), fallbackScenario, controller.signal);
|
|
94
|
+
const totalMs = Math.max(Date.now() - decodeStartedAt, workerElapsedMs + fallback.timing.totalMs);
|
|
95
|
+
outcome = {
|
|
96
|
+
...fallback,
|
|
97
|
+
attemptCount: workerOutcome.attemptCount + fallback.attemptCount,
|
|
98
|
+
timing: {
|
|
99
|
+
...fallback.timing,
|
|
100
|
+
totalMs,
|
|
101
|
+
...(workerOutcome.timing.workerSetupMs === undefined ? {} : { workerSetupMs: workerOutcome.timing.workerSetupMs }),
|
|
102
|
+
...(workerOutcome.timing.workerTransferMs === undefined ? {} : { workerTransferMs: workerOutcome.timing.workerTransferMs }),
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
options.onProgress?.({ attemptCount: outcome.attemptCount });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
markDecodePath("main-thread");
|
|
111
|
+
options.onStage?.("Routing normalized frame...");
|
|
112
|
+
outcome = await this.decodeOnMain(frame, this.scenario, controller.signal);
|
|
113
|
+
options.onProgress?.({ attemptCount: outcome.attemptCount });
|
|
114
|
+
}
|
|
115
|
+
if (owner !== this.owner)
|
|
116
|
+
return this.failure(frameId, "cancelled", "Result belongs to a superseded browser job.");
|
|
117
|
+
return outcome;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
const code = error && typeof error === "object" && "code" in error ? String(error.code) : "unsupported_image";
|
|
121
|
+
const mapped = code === "image_too_large" ? "resource_limit_exceeded" : code === "invalid_file" || code === "unsupported_image" || code === "empty_image" || code === "invalid_image" ? "invalid_image" : controller.signal.aborted ? "cancelled" : "engine_execution_failure";
|
|
122
|
+
return this.failure(frameId, mapped, error instanceof Error ? error.message : String(error));
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
126
|
+
if (this.controller === controller)
|
|
127
|
+
this.controller = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
updateRecovery(recovery) {
|
|
131
|
+
this.assertNotDisposed();
|
|
132
|
+
this.cancel();
|
|
133
|
+
this.recovery = recovery;
|
|
134
|
+
}
|
|
135
|
+
workerRecovery() {
|
|
136
|
+
if (this.recovery === false)
|
|
137
|
+
return undefined;
|
|
138
|
+
const profile = this.recovery.profile ?? "industrial";
|
|
139
|
+
return {
|
|
140
|
+
profile,
|
|
141
|
+
sourceMode: "static",
|
|
142
|
+
...(this.recovery.budget ? { budget: this.recovery.budget } : {}),
|
|
143
|
+
dpmExperimental: this.recovery.dpmExperimental === true || profile === "dpm-experimental",
|
|
144
|
+
...(this.recovery.excludedRoutes ? { excludedRoutes: [...this.recovery.excludedRoutes] } : {}),
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
async decodeOnMain(frame, scenario, signal) {
|
|
148
|
+
const recovery = this.workerRecovery();
|
|
149
|
+
if (!recovery)
|
|
150
|
+
return this.router.scan(frame, { signal, scenario });
|
|
151
|
+
return (await this.recoveryPipeline.run(frame, (candidate, request) => this.router.scan({ ...candidate, ownership: "borrowed", dispose: undefined }, { signal: request.signal, scenario: request.routeId === "general" ? scenario : createRecoveryProbeScenario(scenario, request.routeId) }), { profile: recovery.profile, sourceMode: "static", ...(recovery.budget ? { budget: recovery.budget } : {}), signal, dpmExperimental: recovery.dpmExperimental, excludedRoutes: recovery.excludedRoutes })).outcome;
|
|
152
|
+
}
|
|
153
|
+
async dispose() {
|
|
154
|
+
if (this.state === "disposed")
|
|
155
|
+
return;
|
|
156
|
+
this.cancel();
|
|
157
|
+
this.worker.dispose();
|
|
158
|
+
this.state = "disposed";
|
|
159
|
+
if (this.ownsRouter)
|
|
160
|
+
await this.router.dispose();
|
|
161
|
+
}
|
|
162
|
+
assertNotDisposed() { if (this.state === "disposed")
|
|
163
|
+
throw Object.assign(new Error("Browser capture session has been disposed."), { code: "session_disposed" }); }
|
|
164
|
+
failure(frameId, code, message) {
|
|
165
|
+
return { ok: false, error: sdkError(code, message), frameId, scenarioId: this.scenario.id, attemptCount: 0, timing: { totalMs: 0 } };
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=browser-session.js.map
|