@incodetech/core 0.0.0-dev-20260512-cffbe28 → 0.0.0-dev-20260512-20def2c

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.
Files changed (77) hide show
  1. package/dist/{BaseWasmProvider-IiHnsP8E.esm.js → BaseWasmProvider-CVktpSfA.esm.js} +230 -5
  2. package/dist/{WasmUtilProvider-BrEYcdhY.esm.js → WasmUtilProvider-BEQWy5_K.esm.js} +1 -1
  3. package/dist/ae-signature.d.ts +1 -1
  4. package/dist/authentication.d.ts +5 -5
  5. package/dist/authentication.esm.js +16 -16
  6. package/dist/{authenticationManager-BuChl5GH.d.ts → authenticationManager-BnltMEfq.d.ts} +1 -1
  7. package/dist/{authenticationManager-CKDxnLtG.esm.js → authenticationManager-DsauZR1g.esm.js} +3 -3
  8. package/dist/{authenticationStateMachine-BNs4VCxh.esm.js → authenticationStateMachine-B4FQ52zK.esm.js} +11 -3
  9. package/dist/{backCameraStream-DWZ1cNVA.esm.js → backCameraStream-BKC7QXRJ.esm.js} +2 -2
  10. package/dist/camera.esm.js +2 -2
  11. package/dist/consent.d.ts +50 -50
  12. package/dist/cpf-ocr.d.ts +17 -17
  13. package/dist/cross-document-data-match.esm.js +1 -1
  14. package/dist/curp-validation.d.ts +1 -1
  15. package/dist/{deepsightLoader-BMeAmiNh.esm.js → deepsightLoader-VJ3nFjie.esm.js} +6 -6
  16. package/dist/{deepsightService-IxmrmdKl.esm.js → deepsightService-Dv6kvzph.esm.js} +2 -2
  17. package/dist/{deepsightService-CGSDjjBz.d.ts → deepsightService-Kuw9roIJ.d.ts} +1 -1
  18. package/dist/device.esm.js +3 -3
  19. package/dist/document-capture.d.ts +71 -71
  20. package/dist/document-capture.esm.js +4 -4
  21. package/dist/document-upload.d.ts +46 -46
  22. package/dist/document-upload.esm.js +3 -3
  23. package/dist/{documentCaptureStateMachine-CuanhXvs.esm.js → documentCaptureStateMachine-CEm-9zrh.esm.js} +1 -1
  24. package/dist/ekyb.esm.js +3 -3
  25. package/dist/{ekybStateMachine-tZ1_L9vE.esm.js → ekybStateMachine-DqzhMm0r.esm.js} +1 -1
  26. package/dist/electronic-signature.d.ts +1 -1
  27. package/dist/extensibility.d.ts +7 -7
  28. package/dist/extensibility.esm.js +21 -21
  29. package/dist/{faceCaptureManagerFactory-FX5Lw2Q5.d.ts → faceCaptureManagerFactory-DmHbKbyC.d.ts} +66 -3
  30. package/dist/{faceCaptureManagerFactory-ByAGjOLF.esm.js → faceCaptureManagerFactory-fu-9hWf5.esm.js} +2 -0
  31. package/dist/{faceCaptureSetup-CUzqUwkP.esm.js → faceCaptureSetup-D607PhdL.esm.js} +141 -19
  32. package/dist/flow-events.d.ts +2 -2
  33. package/dist/flow.d.ts +7 -3
  34. package/dist/flow.esm.js +2 -2
  35. package/dist/{flowServices-CLo2qihS.esm.js → flowServices-BVVnH_Fn.esm.js} +14 -1
  36. package/dist/geolocation.esm.js +2 -2
  37. package/dist/{geolocationStateMachine-15aagr2_.esm.js → geolocationStateMachine-BYWUPbNs.esm.js} +1 -1
  38. package/dist/{getDeviceClass-DmoqR7G2.esm.js → getDeviceClass-C1ZS2XJL.esm.js} +1 -1
  39. package/dist/home.d.ts +11 -11
  40. package/dist/http.d.ts +9 -0
  41. package/dist/id-ocr.d.ts +52 -52
  42. package/dist/id.d.ts +4 -4
  43. package/dist/id.esm.js +14 -14
  44. package/dist/{idCaptureManager-DiFBYm7h.d.ts → idCaptureManager-Bg2va24b.d.ts} +2 -2
  45. package/dist/{idCaptureManager-ZtfBOR6V.esm.js → idCaptureManager-DbP4E8PO.esm.js} +1 -1
  46. package/dist/{idCaptureStateMachine-BuX1-VlB.esm.js → idCaptureStateMachine-g5cYnHGD.esm.js} +11 -11
  47. package/dist/identity-reuse.d.ts +40 -40
  48. package/dist/{index-BRdxM5zm.d.ts → index-DXB9aRs0.d.ts} +119 -119
  49. package/dist/{index-CmFkidgy.d.ts → index-UH-vOq3x.d.ts} +1 -1
  50. package/dist/index.d.ts +2 -2
  51. package/dist/index.esm.js +4 -4
  52. package/dist/mandatory-consent.d.ts +51 -51
  53. package/dist/{permissionServices-ACBX6sNZ.esm.js → permissionServices-Cdxqlwqz.esm.js} +1 -1
  54. package/dist/qe-signature.d.ts +1 -1
  55. package/dist/{recordingService-DMaVUhWY.esm.js → recordingService-Dp-3nA-h.esm.js} +204 -174
  56. package/dist/selfie.d.ts +5 -5
  57. package/dist/selfie.esm.js +16 -16
  58. package/dist/{selfieManager-DC9hKgt7.esm.js → selfieManager-5AG9bMT1.esm.js} +3 -3
  59. package/dist/{selfieManager-DPQzO4ua.d.ts → selfieManager-CQtRqcjI.d.ts} +1 -1
  60. package/dist/{selfieStateMachine-DvOTE42w.esm.js → selfieStateMachine-D0rrAFIs.esm.js} +22 -10
  61. package/dist/{session-DAspZUCj.esm.js → session-BxtuBDwz.esm.js} +1 -1
  62. package/dist/session.esm.js +1 -1
  63. package/dist/{setup-DyspWyTY.esm.js → setup-B2Van3Nc.esm.js} +38 -183
  64. package/dist/{setup-DM301Lyz.d.ts → setup-CsJ6FYyF.d.ts} +1 -1
  65. package/dist/stats.esm.js +1 -1
  66. package/dist/{types-BA181GDD.d.ts → types-DkXZpS0R.d.ts} +14 -0
  67. package/dist/{warmup-DHGg8wQZ.d.ts → warmup-C6O7yhfX.d.ts} +5 -2
  68. package/dist/wasm.d.ts +3 -3
  69. package/dist/wasm.esm.js +4 -4
  70. package/dist/workflow.d.ts +2 -2
  71. package/dist/workflow.esm.js +20 -20
  72. package/package.json +1 -1
  73. /package/dist/{ITimerCapability-2pw-S97e.esm.js → ITimerCapability-3xSd36bT.esm.js} +0 -0
  74. /package/dist/{MotionSensorProvider-DJMsPght.esm.js → MotionSensorProvider-Dt_lF3Z8.esm.js} +0 -0
  75. /package/dist/{getBrowser-Y88tNVud.esm.js → getBrowser-Bl0PlyDu.esm.js} +0 -0
  76. /package/dist/{platform-Dpzd9p3X.esm.js → platform-CDh4uv5Y.esm.js} +0 -0
  77. /package/dist/{stats-Bqq9IKre.esm.js → stats-qUsejORa.esm.js} +0 -0
@@ -1,174 +1,13 @@
1
- import { a as WasmPipelineType, r as mlWasmJSApi_default, t as BaseWasmProvider } from "./BaseWasmProvider-IiHnsP8E.esm.js";
1
+ import { r as mlWasmJSApi_default, t as BaseWasmProvider, u as WasmPipelineType } from "./BaseWasmProvider-CVktpSfA.esm.js";
2
2
  import { t as api } from "./api-eqRXuVG-.esm.js";
3
3
  import { t as endpoints } from "./endpoints-B3V1U9Dg.esm.js";
4
- import { n as IncodeCanvas } from "./deepsightService-IxmrmdKl.esm.js";
5
4
  import { i as stopCameraStream, r as requestCameraAccess } from "./camera-Bm3wb89Z.esm.js";
6
- import { t as addDeviceStats } from "./stats-Bqq9IKre.esm.js";
7
- import { a as isIPhone14OrHigher, n as isDesktop, r as isIOS, t as isAndroid } from "./platform-Dpzd9p3X.esm.js";
8
- import { n as getDesktopCameraStream, t as getBackCameraStream } from "./backCameraStream-DWZ1cNVA.esm.js";
9
- import { t as getDeviceClass } from "./getDeviceClass-DmoqR7G2.esm.js";
5
+ import { n as IncodeCanvas } from "./deepsightService-Dv6kvzph.esm.js";
6
+ import { a as isIPhone14OrHigher, n as isDesktop, r as isIOS, t as isAndroid } from "./platform-CDh4uv5Y.esm.js";
7
+ import { n as getDesktopCameraStream, t as getBackCameraStream } from "./backCameraStream-BKC7QXRJ.esm.js";
8
+ import { t as addDeviceStats } from "./stats-qUsejORa.esm.js";
9
+ import { t as getDeviceClass } from "./getDeviceClass-C1ZS2XJL.esm.js";
10
10
 
11
- //#region src/internal/faceCapture/types.ts
12
- const FACE_ERROR_CODES = {
13
- FACE_OCCLUDED: "FACE_OCCLUDED",
14
- LIVENESS: "LIVENESS_ERROR",
15
- BRIGHTNESS: "BRIGHTNESS_ERROR",
16
- LENSES: "LENSES_ERROR",
17
- MASK: "MASK_ERROR",
18
- CLOSED_EYES: "CLOSED_EYES_ERROR",
19
- HEAD_COVER: "HEAD_COVER_ERROR",
20
- SERVER: "SERVER_ERROR",
21
- FACE_NOT_FOUND: "FACE_NOT_FOUND",
22
- MULTIPLE_FACES: "MULTIPLE_FACES",
23
- TOO_BLURRY: "TOO_BLURRY_ERROR",
24
- TOO_DARK: "TOO_DARK_ERROR",
25
- USER_IS_NOT_RECOGNIZED: "USER_IS_NOT_RECOGNIZED",
26
- SPOOF_ATTEMPT_DETECTED: "SPOOF_ATTEMPT_DETECTED",
27
- FACE_TOO_DARK: "FACE_TOO_DARK",
28
- LENSES_DETECTED: "LENSES_DETECTED",
29
- FACE_MASK_DETECTED: "FACE_MASK_DETECTED",
30
- CLOSED_EYES_DETECTED: "CLOSED_EYES_DETECTED",
31
- HEAD_COVER_DETECTED: "HEAD_COVER_DETECTED",
32
- FACE_CROPPING_FAILED: "FACE_CROPPING_FAILED",
33
- FACE_TOO_SMALL: "FACE_TOO_SMALL",
34
- FACE_TOO_BLURRY: "FACE_TOO_BLURRY",
35
- BAD_PHOTO_QUALITY: "BAD_PHOTO_QUALITY",
36
- PROCESSING_ERROR: "PROCESSING_ERROR",
37
- BAD_REQUEST: "BAD_REQUEST",
38
- NONEXISTENT_CUSTOMER: "NONEXISTENT_CUSTOMER",
39
- HINT_NOT_PROVIDED: "HINT_NOT_PROVIDED",
40
- SELFIE_IMAGE_LOW_QUALITY: "SELFIE_IMAGE_LOW_QUALITY"
41
- };
42
-
43
- //#endregion
44
- //#region ../infra/src/media/StreamCanvasCapture.ts
45
- var StreamCanvasCapture = class {
46
- constructor(stream, options) {
47
- this.hasFrame = false;
48
- this.disposed = false;
49
- this.eventTarget = new EventTarget();
50
- this.video = document.createElement("video");
51
- this.video.srcObject = stream;
52
- this.video.autoplay = true;
53
- this.video.playsInline = true;
54
- this.video.muted = true;
55
- const settings = stream.getVideoTracks()[0]?.getSettings();
56
- const initialWidth = options?.width ?? settings?.width ?? 1280;
57
- const initialHeight = options?.height ?? settings?.height ?? 720;
58
- this.canvas = document.createElement("canvas");
59
- this.canvas.width = initialWidth;
60
- this.canvas.height = initialHeight;
61
- this.ctx = this.canvas.getContext("2d", { willReadFrequently: true });
62
- const fps = options?.fps ?? 10;
63
- const intervalMs = fps > 0 ? Math.max(16, Math.floor(1e3 / fps)) : 0;
64
- this.video.addEventListener("loadedmetadata", () => {
65
- if (this.video.videoWidth > 0 && this.video.videoHeight > 0) {
66
- this.canvas.width = this.video.videoWidth;
67
- this.canvas.height = this.video.videoHeight;
68
- }
69
- });
70
- try {
71
- this.video.play();
72
- } catch {}
73
- this.rafLoop(intervalMs);
74
- }
75
- addEventListener(type, listener, options) {
76
- this.eventTarget.addEventListener(type, listener, options);
77
- }
78
- removeEventListener(type, listener, options) {
79
- this.eventTarget.removeEventListener(type, listener, options);
80
- }
81
- /**
82
- * Returns the latest cached frame as an {@link IncodeCanvas}.
83
- */
84
- getLatestCanvas() {
85
- if (!this.hasFrame) this.tick();
86
- if (!this.hasFrame) return null;
87
- return new IncodeCanvas(this.canvas);
88
- }
89
- /**
90
- * Returns the latest cached frame as raw {@link ImageData}.
91
- */
92
- getLatestFrame() {
93
- if (!this.ctx) return null;
94
- if (!this.hasFrame) this.tick();
95
- if (!this.hasFrame) return null;
96
- try {
97
- return this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
98
- } catch {
99
- return null;
100
- }
101
- }
102
- /**
103
- * Disposes internal resources and stops the capture loop.
104
- */
105
- dispose() {
106
- if (this.disposed) return;
107
- this.disposed = true;
108
- if (this.rafId !== void 0) {
109
- window.cancelAnimationFrame(this.rafId);
110
- this.rafId = void 0;
111
- }
112
- this.video.srcObject = null;
113
- this.canvas.width = 0;
114
- this.canvas.height = 0;
115
- this.hasFrame = false;
116
- }
117
- rafLoop(intervalMs) {
118
- const loop = (timeMs) => {
119
- if (this.disposed) return;
120
- if (intervalMs <= 0 || this.lastTickTimeMs === void 0 || timeMs - this.lastTickTimeMs >= intervalMs) {
121
- this.lastTickTimeMs = timeMs;
122
- const previousFrameTimeSeconds = this.lastFrameTimeSeconds;
123
- this.tick();
124
- const currentFrameTimeSeconds = this.video.currentTime;
125
- if (previousFrameTimeSeconds === void 0) {
126
- if (this.hasFrame) {
127
- this.lastFrameTimeSeconds = currentFrameTimeSeconds;
128
- this.eventTarget.dispatchEvent(new Event("frame"));
129
- }
130
- } else if (this.hasFrame && currentFrameTimeSeconds !== previousFrameTimeSeconds) {
131
- this.lastFrameTimeSeconds = currentFrameTimeSeconds;
132
- this.eventTarget.dispatchEvent(new Event("frame"));
133
- }
134
- }
135
- this.rafId = window.requestAnimationFrame(loop);
136
- };
137
- this.rafId = window.requestAnimationFrame(loop);
138
- }
139
- tick() {
140
- if (!this.ctx) return;
141
- if (this.video.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) return;
142
- const videoWidth = this.video.videoWidth;
143
- const videoHeight = this.video.videoHeight;
144
- if (videoWidth === 0 || videoHeight === 0) return;
145
- if (this.canvas.width !== videoWidth || this.canvas.height !== videoHeight) {
146
- this.canvas.width = videoWidth;
147
- this.canvas.height = videoHeight;
148
- }
149
- try {
150
- this.ctx.drawImage(this.video, 0, 0);
151
- this.hasFrame = true;
152
- } catch {
153
- this.hasFrame = false;
154
- }
155
- }
156
- };
157
-
158
- //#endregion
159
- //#region src/internal/manualReview/manualReviewService.ts
160
- async function flagFaceManualReview() {
161
- try {
162
- await api.put(endpoints.updateSession, { manualSelfieCheckNeeded: true });
163
- } catch {}
164
- }
165
- async function flagIdManualReview() {
166
- try {
167
- await api.put(endpoints.updateSession, { manualIdCheckNeeded: true });
168
- } catch {}
169
- }
170
-
171
- //#endregion
172
11
  //#region ../infra/src/providers/wasm/FaceDetectionProvider.ts
173
12
  var FaceDetectionProvider = class extends BaseWasmProvider {
174
13
  constructor() {
@@ -187,7 +26,10 @@ var FaceDetectionProvider = class extends BaseWasmProvider {
187
26
  closedEyesThreshold: .9,
188
27
  maskThreshold: .85,
189
28
  minFaceQualityScore: .63,
190
- faceOcclusionThreshold: .3
29
+ faceOcclusionThreshold: .3,
30
+ getReadyDelay: 2e3,
31
+ framesAggregationInterval: 2e3,
32
+ minFramesWithFace: 3
191
33
  };
192
34
  this.currentFrame = null;
193
35
  }
@@ -196,9 +38,20 @@ var FaceDetectionProvider = class extends BaseWasmProvider {
196
38
  await this.processFrameWasm(image);
197
39
  }
198
40
  async initialize(config) {
199
- await this.initializeBase(config, "selfie");
41
+ if (config.useOnDeviceWorkflow === true) {
42
+ this.pipelineType = WasmPipelineType.OnDeviceSelfieWorkflow;
43
+ await this.initializeBase(config, "onDeviceSelfie");
44
+ } else await this.initializeBase(config, "selfie");
200
45
  this.applyDefaults(config.autocaptureInterval ?? 0);
201
46
  }
47
+ processPhoto(canvas) {
48
+ this.ensureInitialized();
49
+ mlWasmJSApi_default.processPhoto(canvas);
50
+ }
51
+ async postFaceResults(config) {
52
+ this.ensureInitialized();
53
+ return mlWasmJSApi_default.postFaceResults(config);
54
+ }
202
55
  setCallbacks(callbacks) {
203
56
  this.ensureInitialized();
204
57
  const onCaptureWrapper = (wasmCanvas, face) => {
@@ -228,7 +81,10 @@ var FaceDetectionProvider = class extends BaseWasmProvider {
228
81
  minMagicCropSize: this.defaultThresholds.minMagicCropSize,
229
82
  autocaptureInterval,
230
83
  minFaceQualityScore: this.defaultThresholds.minFaceQualityScore,
231
- faceOcclusionThreshold: this.defaultThresholds.faceOcclusionThreshold
84
+ faceOcclusionThreshold: this.defaultThresholds.faceOcclusionThreshold,
85
+ getReadyDelay: this.defaultThresholds.getReadyDelay,
86
+ framesAggregationInterval: this.defaultThresholds.framesAggregationInterval,
87
+ minFramesWithFace: this.defaultThresholds.minFramesWithFace
232
88
  });
233
89
  this.setPositionConstraints({
234
90
  minX: this.defaultThresholds.frameMinX,
@@ -257,7 +113,7 @@ var FaceDetectionProvider = class extends BaseWasmProvider {
257
113
  setThresholds(thresholds) {
258
114
  this.ensureInitialized();
259
115
  this.currentThresholds = { ...thresholds };
260
- mlWasmJSApi_default.setFaceDetectionThresholds(this.getPipelineType(), thresholds.brightnessThreshold, thresholds.blurrinessThreshold, thresholds.tiltRotationAngleThreshold, thresholds.minMagicCropSize, thresholds.autocaptureInterval, thresholds.minFaceQualityScore, thresholds.faceOcclusionThreshold);
116
+ mlWasmJSApi_default.setFaceDetectionThresholds(this.getPipelineType(), thresholds.brightnessThreshold, thresholds.blurrinessThreshold, thresholds.tiltRotationAngleThreshold, thresholds.minMagicCropSize, thresholds.autocaptureInterval, thresholds.minFaceQualityScore, thresholds.faceOcclusionThreshold, thresholds.getReadyDelay, thresholds.framesAggregationInterval, thresholds.minFramesWithFace);
261
117
  }
262
118
  setAttributesThresholds(thresholds) {
263
119
  this.ensureInitialized();
@@ -384,6 +240,39 @@ async function uploadDeepsightVideo(encryptedVideo, token) {
384
240
  }
385
241
  }
386
242
 
243
+ //#endregion
244
+ //#region src/internal/faceCapture/types.ts
245
+ const FACE_ERROR_CODES = {
246
+ FACE_OCCLUDED: "FACE_OCCLUDED",
247
+ LIVENESS: "LIVENESS_ERROR",
248
+ BRIGHTNESS: "BRIGHTNESS_ERROR",
249
+ LENSES: "LENSES_ERROR",
250
+ MASK: "MASK_ERROR",
251
+ CLOSED_EYES: "CLOSED_EYES_ERROR",
252
+ HEAD_COVER: "HEAD_COVER_ERROR",
253
+ SERVER: "SERVER_ERROR",
254
+ FACE_NOT_FOUND: "FACE_NOT_FOUND",
255
+ MULTIPLE_FACES: "MULTIPLE_FACES",
256
+ TOO_BLURRY: "TOO_BLURRY_ERROR",
257
+ TOO_DARK: "TOO_DARK_ERROR",
258
+ USER_IS_NOT_RECOGNIZED: "USER_IS_NOT_RECOGNIZED",
259
+ SPOOF_ATTEMPT_DETECTED: "SPOOF_ATTEMPT_DETECTED",
260
+ FACE_TOO_DARK: "FACE_TOO_DARK",
261
+ LENSES_DETECTED: "LENSES_DETECTED",
262
+ FACE_MASK_DETECTED: "FACE_MASK_DETECTED",
263
+ CLOSED_EYES_DETECTED: "CLOSED_EYES_DETECTED",
264
+ HEAD_COVER_DETECTED: "HEAD_COVER_DETECTED",
265
+ FACE_CROPPING_FAILED: "FACE_CROPPING_FAILED",
266
+ FACE_TOO_SMALL: "FACE_TOO_SMALL",
267
+ FACE_TOO_BLURRY: "FACE_TOO_BLURRY",
268
+ BAD_PHOTO_QUALITY: "BAD_PHOTO_QUALITY",
269
+ PROCESSING_ERROR: "PROCESSING_ERROR",
270
+ BAD_REQUEST: "BAD_REQUEST",
271
+ NONEXISTENT_CUSTOMER: "NONEXISTENT_CUSTOMER",
272
+ HINT_NOT_PROVIDED: "HINT_NOT_PROVIDED",
273
+ SELFIE_IMAGE_LOW_QUALITY: "SELFIE_IMAGE_LOW_QUALITY"
274
+ };
275
+
387
276
  //#endregion
388
277
  //#region src/modules/selfie/selfieUploadService.ts
389
278
  /**
@@ -476,7 +365,10 @@ async function initializeCamera(params) {
476
365
  const { config } = params;
477
366
  const prcConstraints = buildCameraConstraints(config.cameraResolution);
478
367
  const provider = new FaceDetectionProvider();
479
- await provider.initialize({ autocaptureInterval: config.autoCaptureTimeout * 1e3 });
368
+ await provider.initialize({
369
+ autocaptureInterval: config.autoCaptureTimeout * 1e3,
370
+ useOnDeviceWorkflow: config.onDeviceFaceResultsSubmissionEnabled === true
371
+ });
480
372
  provider.setChecksEnabled({
481
373
  lenses: config.validateLenses ?? false,
482
374
  mask: config.validateFaceMask ?? false,
@@ -620,13 +512,141 @@ async function stopRecording(session) {
620
512
  }
621
513
  }
622
514
  async function initializeDeepsightSession(options) {
623
- const { loadDeepsightSession } = await import("./deepsightLoader-BMeAmiNh.esm.js");
515
+ const { loadDeepsightSession } = await import("./deepsightLoader-VJ3nFjie.esm.js");
624
516
  return loadDeepsightSession({
625
517
  ds: options.ds,
626
518
  storage: options.storage
627
519
  });
628
520
  }
629
521
 
522
+ //#endregion
523
+ //#region ../infra/src/media/StreamCanvasCapture.ts
524
+ var StreamCanvasCapture = class {
525
+ constructor(stream, options) {
526
+ this.hasFrame = false;
527
+ this.disposed = false;
528
+ this.eventTarget = new EventTarget();
529
+ this.video = document.createElement("video");
530
+ this.video.srcObject = stream;
531
+ this.video.autoplay = true;
532
+ this.video.playsInline = true;
533
+ this.video.muted = true;
534
+ const settings = stream.getVideoTracks()[0]?.getSettings();
535
+ const initialWidth = options?.width ?? settings?.width ?? 1280;
536
+ const initialHeight = options?.height ?? settings?.height ?? 720;
537
+ this.canvas = document.createElement("canvas");
538
+ this.canvas.width = initialWidth;
539
+ this.canvas.height = initialHeight;
540
+ this.ctx = this.canvas.getContext("2d", { willReadFrequently: true });
541
+ const fps = options?.fps ?? 10;
542
+ const intervalMs = fps > 0 ? Math.max(16, Math.floor(1e3 / fps)) : 0;
543
+ this.video.addEventListener("loadedmetadata", () => {
544
+ if (this.video.videoWidth > 0 && this.video.videoHeight > 0) {
545
+ this.canvas.width = this.video.videoWidth;
546
+ this.canvas.height = this.video.videoHeight;
547
+ }
548
+ });
549
+ try {
550
+ this.video.play();
551
+ } catch {}
552
+ this.rafLoop(intervalMs);
553
+ }
554
+ addEventListener(type, listener, options) {
555
+ this.eventTarget.addEventListener(type, listener, options);
556
+ }
557
+ removeEventListener(type, listener, options) {
558
+ this.eventTarget.removeEventListener(type, listener, options);
559
+ }
560
+ /**
561
+ * Returns the latest cached frame as an {@link IncodeCanvas}.
562
+ */
563
+ getLatestCanvas() {
564
+ if (!this.hasFrame) this.tick();
565
+ if (!this.hasFrame) return null;
566
+ return new IncodeCanvas(this.canvas);
567
+ }
568
+ /**
569
+ * Returns the latest cached frame as raw {@link ImageData}.
570
+ */
571
+ getLatestFrame() {
572
+ if (!this.ctx) return null;
573
+ if (!this.hasFrame) this.tick();
574
+ if (!this.hasFrame) return null;
575
+ try {
576
+ return this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height);
577
+ } catch {
578
+ return null;
579
+ }
580
+ }
581
+ /**
582
+ * Disposes internal resources and stops the capture loop.
583
+ */
584
+ dispose() {
585
+ if (this.disposed) return;
586
+ this.disposed = true;
587
+ if (this.rafId !== void 0) {
588
+ window.cancelAnimationFrame(this.rafId);
589
+ this.rafId = void 0;
590
+ }
591
+ this.video.srcObject = null;
592
+ this.canvas.width = 0;
593
+ this.canvas.height = 0;
594
+ this.hasFrame = false;
595
+ }
596
+ rafLoop(intervalMs) {
597
+ const loop = (timeMs) => {
598
+ if (this.disposed) return;
599
+ if (intervalMs <= 0 || this.lastTickTimeMs === void 0 || timeMs - this.lastTickTimeMs >= intervalMs) {
600
+ this.lastTickTimeMs = timeMs;
601
+ const previousFrameTimeSeconds = this.lastFrameTimeSeconds;
602
+ this.tick();
603
+ const currentFrameTimeSeconds = this.video.currentTime;
604
+ if (previousFrameTimeSeconds === void 0) {
605
+ if (this.hasFrame) {
606
+ this.lastFrameTimeSeconds = currentFrameTimeSeconds;
607
+ this.eventTarget.dispatchEvent(new Event("frame"));
608
+ }
609
+ } else if (this.hasFrame && currentFrameTimeSeconds !== previousFrameTimeSeconds) {
610
+ this.lastFrameTimeSeconds = currentFrameTimeSeconds;
611
+ this.eventTarget.dispatchEvent(new Event("frame"));
612
+ }
613
+ }
614
+ this.rafId = window.requestAnimationFrame(loop);
615
+ };
616
+ this.rafId = window.requestAnimationFrame(loop);
617
+ }
618
+ tick() {
619
+ if (!this.ctx) return;
620
+ if (this.video.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) return;
621
+ const videoWidth = this.video.videoWidth;
622
+ const videoHeight = this.video.videoHeight;
623
+ if (videoWidth === 0 || videoHeight === 0) return;
624
+ if (this.canvas.width !== videoWidth || this.canvas.height !== videoHeight) {
625
+ this.canvas.width = videoWidth;
626
+ this.canvas.height = videoHeight;
627
+ }
628
+ try {
629
+ this.ctx.drawImage(this.video, 0, 0);
630
+ this.hasFrame = true;
631
+ } catch {
632
+ this.hasFrame = false;
633
+ }
634
+ }
635
+ };
636
+
637
+ //#endregion
638
+ //#region src/internal/manualReview/manualReviewService.ts
639
+ async function flagFaceManualReview() {
640
+ try {
641
+ await api.put(endpoints.updateSession, { manualSelfieCheckNeeded: true });
642
+ } catch {}
643
+ }
644
+ async function flagIdManualReview() {
645
+ try {
646
+ await api.put(endpoints.updateSession, { manualIdCheckNeeded: true });
647
+ } catch {}
648
+ }
649
+
630
650
  //#endregion
631
651
  //#region ../infra/src/media/VideoTrimmer.ts
632
652
  async function getDurationBySeek(videoBlob) {
@@ -947,11 +967,21 @@ var OpenViduRecordingService = class {
947
967
  };
948
968
  /**
949
969
  * Creates the recording service for the current configuration.
970
+ *
971
+ * Order of precedence:
972
+ * 1. `onDeviceFaceResultsSubmissionEnabled === true` → no recording. The
973
+ * on-device workflow never uploads media, only the staged face-results
974
+ * JSON via `WebApi.postFaceResults`. Mirrors V1's
975
+ * `FaceFlowManager.setRecorders()` early return.
976
+ * 2. `deepsightLiveness === 'VIDEOLIVENESS'` → local Deepsight recorder.
977
+ * 3. `enableFaceRecording === true` → server-side OpenVidu recorder.
978
+ * 4. otherwise → no recording.
950
979
  */
951
980
  function createRecordingService(params) {
981
+ if (params.config.onDeviceFaceResultsSubmissionEnabled === true) return;
952
982
  if (params.config.deepsightLiveness === "VIDEOLIVENESS") return new LocalRecordingService(params.wasmUtil, params.sessionToken);
953
983
  if (params.config.enableFaceRecording === true) return new OpenViduRecordingService(params.config);
954
984
  }
955
985
 
956
986
  //#endregion
957
- export { StreamCanvasCapture as _, initializeDeepsightSession as a, stopStream as c, createRecordingSession as d, startRecording as f, flagIdManualReview as g, flagFaceManualReview as h, initializeCamera as i, processFace as l, StreamCanvasProcessingSession as m, preloadOpenViduProvider as n, sendLabelInspectionEvent as o, stopRecording$1 as p, encryptSelfieImage as r, startDetection as s, createRecordingService as t, uploadSelfie as u, FACE_ERROR_CODES as v };
987
+ export { stopRecording$1 as _, StreamCanvasCapture as a, initializeDeepsightSession as c, stopStream as d, processFace as f, startRecording as g, createRecordingSession as h, flagIdManualReview as i, sendLabelInspectionEvent as l, FACE_ERROR_CODES as m, preloadOpenViduProvider as n, encryptSelfieImage as o, uploadSelfie as p, flagFaceManualReview as r, initializeCamera as s, createRecordingService as t, startDetection as u, StreamCanvasProcessingSession as v };
package/dist/selfie.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import "./warmup-DHGg8wQZ.js";
1
+ import "./warmup-C6O7yhfX.js";
2
2
  import "./Manager-D9pehGyp.js";
3
3
  import "./Actor-YjWTo26u.js";
4
4
  import "./StateMachine-CJG7thvx.js";
5
- import { a as SelfieMachine, d as SelfieConfig, o as selfieMachine, v as DetectionStatus, y as FaceErrorCode } from "./faceCaptureManagerFactory-FX5Lw2Q5.js";
5
+ import { a as SelfieMachine, d as SelfieConfig, o as selfieMachine, v as DetectionStatus, y as FaceErrorCode } from "./faceCaptureManagerFactory-DmHbKbyC.js";
6
6
  import { t as CameraStream } from "./camera-B6UAKpM1.js";
7
7
  import "./types-DJSt3Ovt.js";
8
- import "./types-BA181GDD.js";
9
- import { t as DeepsightService } from "./deepsightService-CGSDjjBz.js";
8
+ import "./types-DkXZpS0R.js";
9
+ import { t as DeepsightService } from "./deepsightService-Kuw9roIJ.js";
10
10
  import { n as PermissionStatus, t as PermissionResult } from "./types-CarMMtoz.js";
11
- import { a as ProcessFaceResponse, n as SelfieState, o as processFace, r as createSelfieManager, t as SelfieManager } from "./selfieManager-DPQzO4ua.js";
11
+ import { a as ProcessFaceResponse, n as SelfieState, o as processFace, r as createSelfieManager, t as SelfieManager } from "./selfieManager-CQtRqcjI.js";
12
12
  export { type CameraStream, type DeepsightService, type DetectionStatus, type FaceErrorCode, type PermissionResult, type PermissionStatus, type ProcessFaceResponse, type SelfieConfig, type SelfieMachine, type SelfieManager, type SelfieState, createSelfieManager, processFace, selfieMachine };
@@ -1,25 +1,25 @@
1
- import "./BaseWasmProvider-IiHnsP8E.esm.js";
2
- import "./WasmUtilProvider-BrEYcdhY.esm.js";
1
+ import "./BaseWasmProvider-CVktpSfA.esm.js";
2
+ import "./WasmUtilProvider-BEQWy5_K.esm.js";
3
3
  import "./api-eqRXuVG-.esm.js";
4
4
  import "./events-Bt1azl2B.esm.js";
5
5
  import "./endpoints-B3V1U9Dg.esm.js";
6
6
  import "./browserSimulation-CAH-V_iE.esm.js";
7
7
  import "./xstate.esm-7GmmAwg6.esm.js";
8
- import "./faceCaptureManagerFactory-ByAGjOLF.esm.js";
8
+ import "./faceCaptureManagerFactory-fu-9hWf5.esm.js";
9
9
  import "./BrowserStorageProvider-CoUfuy0u.esm.js";
10
- import { l as processFace } from "./recordingService-DMaVUhWY.esm.js";
11
- import "./deepsightService-IxmrmdKl.esm.js";
10
+ import "./faceCaptureSetup-D607PhdL.esm.js";
11
+ import "./ITimerCapability-3xSd36bT.esm.js";
12
12
  import "./camera-Bm3wb89Z.esm.js";
13
- import "./getBrowser-Y88tNVud.esm.js";
14
- import "./stats-Bqq9IKre.esm.js";
15
- import "./MotionSensorProvider-DJMsPght.esm.js";
16
- import "./permissionServices-ACBX6sNZ.esm.js";
17
- import "./platform-Dpzd9p3X.esm.js";
18
- import "./ITimerCapability-2pw-S97e.esm.js";
19
- import "./backCameraStream-DWZ1cNVA.esm.js";
20
- import "./getDeviceClass-DmoqR7G2.esm.js";
21
- import "./faceCaptureSetup-CUzqUwkP.esm.js";
22
- import { t as selfieMachine } from "./selfieStateMachine-DvOTE42w.esm.js";
23
- import { t as createSelfieManager } from "./selfieManager-DC9hKgt7.esm.js";
13
+ import "./deepsightService-Dv6kvzph.esm.js";
14
+ import { f as processFace } from "./recordingService-Dp-3nA-h.esm.js";
15
+ import "./platform-CDh4uv5Y.esm.js";
16
+ import "./backCameraStream-BKC7QXRJ.esm.js";
17
+ import "./getBrowser-Bl0PlyDu.esm.js";
18
+ import "./stats-qUsejORa.esm.js";
19
+ import "./getDeviceClass-C1ZS2XJL.esm.js";
20
+ import "./MotionSensorProvider-Dt_lF3Z8.esm.js";
21
+ import "./permissionServices-Cdxqlwqz.esm.js";
22
+ import { t as selfieMachine } from "./selfieStateMachine-D0rrAFIs.esm.js";
23
+ import { t as createSelfieManager } from "./selfieManager-5AG9bMT1.esm.js";
24
24
 
25
25
  export { createSelfieManager, processFace, selfieMachine };
@@ -1,9 +1,9 @@
1
- import { t as WasmUtilProvider } from "./WasmUtilProvider-BrEYcdhY.esm.js";
1
+ import { t as WasmUtilProvider } from "./WasmUtilProvider-BEQWy5_K.esm.js";
2
2
  import { n as eventModuleNames } from "./events-Bt1azl2B.esm.js";
3
3
  import { o as createActor } from "./xstate.esm-7GmmAwg6.esm.js";
4
- import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-ByAGjOLF.esm.js";
4
+ import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-fu-9hWf5.esm.js";
5
5
  import { t as BrowserStorageProvider } from "./BrowserStorageProvider-CoUfuy0u.esm.js";
6
- import { t as selfieMachine } from "./selfieStateMachine-DvOTE42w.esm.js";
6
+ import { t as selfieMachine } from "./selfieStateMachine-D0rrAFIs.esm.js";
7
7
 
8
8
  //#region src/modules/selfie/selfieActor.ts
9
9
  function createSelfieActor(options) {
@@ -1,5 +1,5 @@
1
1
  import { t as Manager } from "./Manager-D9pehGyp.js";
2
- import { i as SelfieActor, n as FaceCaptureManagerState, r as CreateSelfieActorOptions, t as FaceCaptureManager } from "./faceCaptureManagerFactory-FX5Lw2Q5.js";
2
+ import { i as SelfieActor, n as FaceCaptureManagerState, r as CreateSelfieActorOptions, t as FaceCaptureManager } from "./faceCaptureManagerFactory-DmHbKbyC.js";
3
3
 
4
4
  //#region src/modules/selfie/selfieUploadService.d.ts
5
5
  type ProcessFaceImageType = 'selfie' | 'videoSelfie';
@@ -1,6 +1,6 @@
1
1
  import { a as fromPromise, r as assign } from "./xstate.esm-7GmmAwg6.esm.js";
2
- import { l as processFace, u as uploadSelfie, v as FACE_ERROR_CODES } from "./recordingService-DMaVUhWY.esm.js";
3
- import { t as faceCaptureMachine } from "./faceCaptureSetup-CUzqUwkP.esm.js";
2
+ import { a as prepareOnDeviceFaceUpload, i as postOnDeviceFaceResults, n as defaultPrepareFaceUpload, r as isOnDeviceMode, t as faceCaptureMachine } from "./faceCaptureSetup-D607PhdL.esm.js";
3
+ import { f as processFace, m as FACE_ERROR_CODES, p as uploadSelfie } from "./recordingService-Dp-3nA-h.esm.js";
4
4
 
5
5
  //#region src/modules/selfie/selfieErrorUtils.ts
6
6
  const FACE_ERROR_CODE_VALUES = Object.values(FACE_ERROR_CODES);
@@ -18,8 +18,13 @@ const validateUploadResponse = ({ config, response }) => {
18
18
  //#region src/modules/selfie/selfieStateMachine.ts
19
19
  const _selfieMachine = faceCaptureMachine.provide({
20
20
  actors: {
21
+ prepareFaceUpload: fromPromise(async ({ input }) => {
22
+ const ctx = input;
23
+ return isOnDeviceMode(ctx.config) ? prepareOnDeviceFaceUpload(ctx) : defaultPrepareFaceUpload(ctx);
24
+ }),
21
25
  uploadFace: fromPromise(async ({ input, signal }) => {
22
26
  const ctx = input;
27
+ if (isOnDeviceMode(ctx.config)) return postOnDeviceFaceResults(ctx, signal);
23
28
  return uploadSelfie({
24
29
  encryptedBase64Image: ctx.encryptedBase64Image,
25
30
  faceCoordinates: ctx.faceCoordinates,
@@ -28,19 +33,26 @@ const _selfieMachine = faceCaptureMachine.provide({
28
33
  signal
29
34
  });
30
35
  }),
31
- processFace: fromPromise(async ({ signal }) => {
36
+ processFace: fromPromise(async ({ input, signal }) => {
37
+ if (isOnDeviceMode(input.config)) return {};
32
38
  return processFace("selfie", signal);
33
39
  })
34
40
  },
35
- actions: { setUploadErrorFromUploadValidation: assign({ uploadError: ({ context }) => validateUploadResponse({
36
- config: context.config,
37
- response: context.uploadResponse
38
- }) ?? FACE_ERROR_CODES.SERVER }) },
39
- guards: {
40
- hasUploadValidationError: ({ context }) => validateUploadResponse({
41
+ actions: { setUploadErrorFromUploadValidation: assign({ uploadError: ({ context }) => {
42
+ if (isOnDeviceMode(context.config)) return;
43
+ return validateUploadResponse({
41
44
  config: context.config,
42
45
  response: context.uploadResponse
43
- }) !== void 0,
46
+ }) ?? FACE_ERROR_CODES.SERVER;
47
+ } }) },
48
+ guards: {
49
+ hasUploadValidationError: ({ context }) => {
50
+ if (isOnDeviceMode(context.config)) return false;
51
+ return validateUploadResponse({
52
+ config: context.config,
53
+ response: context.uploadResponse
54
+ }) !== void 0;
55
+ },
44
56
  isTerminalUploadError: () => false
45
57
  }
46
58
  });
@@ -3036,7 +3036,7 @@ function resetFeatureConfigCache() {
3036
3036
 
3037
3037
  //#endregion
3038
3038
  //#region src/internal/version/sdkVersion.ts
3039
- const SDK_VERSION = "0.0.0-dev-20260512-cffbe28";
3039
+ const SDK_VERSION = "0.0.0-dev-20260512-20def2c";
3040
3040
 
3041
3041
  //#endregion
3042
3042
  //#region src/internal/fingerprint/fingerprintService.ts
@@ -1,7 +1,7 @@
1
1
  import "./api-eqRXuVG-.esm.js";
2
2
  import "./events-Bt1azl2B.esm.js";
3
3
  import "./endpoints-B3V1U9Dg.esm.js";
4
- import { c as QrValidationError, d as refreshQrUrlUuid, f as validateQrUuid, l as bootstrapSession, s as QR_VALIDATION_ERROR_CODES, u as createSession } from "./session-DAspZUCj.esm.js";
4
+ import { c as QrValidationError, d as refreshQrUrlUuid, f as validateQrUuid, l as bootstrapSession, s as QR_VALIDATION_ERROR_CODES, u as createSession } from "./session-BxtuBDwz.esm.js";
5
5
  import "./IpifyProvider-ByL6JYxg.esm.js";
6
6
  import "./browserSimulation-CAH-V_iE.esm.js";
7
7
  import { t as getFinishStatus } from "./flowCompletionService-BuVIVPT_.esm.js";