@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,4 +1,4 @@
1
1
  import "./Manager-D9pehGyp.js";
2
2
  import "./Actor-YjWTo26u.js";
3
- import { a as AE_CONSENT_KEYS, c as ConsentKey, d as ElectronicSignatureVariant, f as QE_CONSENT_KEYS, g as getDefaultConsentChecks, h as getConsentKeys, i as electronicSignatureMachine, l as ElectronicSignatureConfig, m as areAllConsented, n as ElectronicSignatureState, o as AeConsentKey, p as QeConsentKey, r as createElectronicSignatureManager, s as ConsentChecks, t as ElectronicSignatureManager, u as ElectronicSignatureDocument } from "./index-BRdxM5zm.js";
3
+ import { a as AE_CONSENT_KEYS, c as ConsentKey, d as ElectronicSignatureVariant, f as QE_CONSENT_KEYS, g as getDefaultConsentChecks, h as getConsentKeys, i as electronicSignatureMachine, l as ElectronicSignatureConfig, m as areAllConsented, n as ElectronicSignatureState, o as AeConsentKey, p as QeConsentKey, r as createElectronicSignatureManager, s as ConsentChecks, t as ElectronicSignatureManager, u as ElectronicSignatureDocument } from "./index-DXB9aRs0.js";
4
4
  export { AE_CONSENT_KEYS, AeConsentKey, ConsentChecks, ConsentKey, ElectronicSignatureConfig, ElectronicSignatureDocument, ElectronicSignatureManager, ElectronicSignatureState, ElectronicSignatureVariant, QE_CONSENT_KEYS, QeConsentKey, areAllConsented, createElectronicSignatureManager, electronicSignatureMachine, getConsentKeys, getDefaultConsentChecks };
@@ -1,17 +1,17 @@
1
- import "./warmup-DHGg8wQZ.js";
1
+ import "./warmup-C6O7yhfX.js";
2
2
  import "./Manager-D9pehGyp.js";
3
3
  import { n as createActor } from "./Actor-YjWTo26u.js";
4
4
  import { r as fromPromise } from "./StateMachine-CJG7thvx.js";
5
- import { c as FaceCaptureEvent, f as SendFaceImageResponse, l as FaceCaptureInput, n as FaceCaptureManagerState, p as BaseWasmProvider, s as FaceCaptureContext, t as FaceCaptureManager, u as faceCaptureMachine } from "./faceCaptureManagerFactory-FX5Lw2Q5.js";
5
+ import { c as FaceCaptureEvent, f as SendFaceImageResponse, l as FaceCaptureInput, n as FaceCaptureManagerState, p as BaseWasmProvider, s as FaceCaptureContext, t as FaceCaptureManager, u as faceCaptureMachine } from "./faceCaptureManagerFactory-DmHbKbyC.js";
6
6
  import "./camera-B6UAKpM1.js";
7
7
  import "./types-DJSt3Ovt.js";
8
- import "./types-BA181GDD.js";
9
- import { a as IWasmUtilCapability, o as VirtualCameraCheckOutput, s as WasmUtilConfig, u as IStorageCapability } from "./deepsightService-CGSDjjBz.js";
8
+ import "./types-DkXZpS0R.js";
9
+ import { a as IWasmUtilCapability, o as VirtualCameraCheckOutput, s as WasmUtilConfig, u as IStorageCapability } from "./deepsightService-Kuw9roIJ.js";
10
10
  import "./types-CarMMtoz.js";
11
- import { a as ProcessFaceResponse, i as createSelfieManagerFromActor, n as SelfieState, t as SelfieManager } from "./selfieManager-DPQzO4ua.js";
12
- import { i as createAuthenticationManagerFromActor, n as AuthenticationState, t as AuthenticationManager } from "./authenticationManager-BuChl5GH.js";
11
+ import { a as ProcessFaceResponse, i as createSelfieManagerFromActor, n as SelfieState, t as SelfieManager } from "./selfieManager-CQtRqcjI.js";
12
+ import { i as createAuthenticationManagerFromActor, n as AuthenticationState, t as AuthenticationManager } from "./authenticationManager-BnltMEfq.js";
13
13
  import { i as createEmailManagerFromActor, n as EmailState, t as EmailManager } from "./emailManager-DsYl45qf.js";
14
- import { T as CaptureIdResponse, i as createIdCaptureManagerFromActor, n as IdCaptureState, t as IdCaptureManager } from "./idCaptureManager-DiFBYm7h.js";
14
+ import { T as CaptureIdResponse, i as createIdCaptureManagerFromActor, n as IdCaptureState, t as IdCaptureManager } from "./idCaptureManager-Bg2va24b.js";
15
15
  import { i as createPhoneManagerFromActor, n as PhoneState, t as PhoneManager } from "./phoneManager-CeAs-QB1.js";
16
16
 
17
17
  //#region src/modules/authentication/authenticationUploadService.d.ts
@@ -1,35 +1,35 @@
1
- import "./BaseWasmProvider-IiHnsP8E.esm.js";
2
- import { t as WasmUtilProvider } from "./WasmUtilProvider-BrEYcdhY.esm.js";
1
+ import "./BaseWasmProvider-CVktpSfA.esm.js";
2
+ import { t as WasmUtilProvider } from "./WasmUtilProvider-BEQWy5_K.esm.js";
3
3
  import "./BrowserTimerProvider-BZGH3sYJ.esm.js";
4
4
  import "./api-eqRXuVG-.esm.js";
5
5
  import "./events-Bt1azl2B.esm.js";
6
6
  import "./endpoints-B3V1U9Dg.esm.js";
7
- import { a as FingerprintProvider, o as getDeviceFingerprintInfo, t as getDisableIpify } from "./session-DAspZUCj.esm.js";
7
+ import { a as FingerprintProvider, o as getDeviceFingerprintInfo, t as getDisableIpify } from "./session-BxtuBDwz.esm.js";
8
8
  import { t as IpifyProvider } from "./IpifyProvider-ByL6JYxg.esm.js";
9
9
  import "./browserSimulation-CAH-V_iE.esm.js";
10
10
  import { a as fromPromise, o as createActor } from "./xstate.esm-7GmmAwg6.esm.js";
11
- import "./faceCaptureManagerFactory-ByAGjOLF.esm.js";
11
+ import "./faceCaptureManagerFactory-fu-9hWf5.esm.js";
12
12
  import { t as BrowserStorageProvider } from "./BrowserStorageProvider-CoUfuy0u.esm.js";
13
- import "./recordingService-DMaVUhWY.esm.js";
14
- import "./deepsightService-IxmrmdKl.esm.js";
13
+ import { t as faceCaptureMachine } from "./faceCaptureSetup-D607PhdL.esm.js";
14
+ import "./ITimerCapability-3xSd36bT.esm.js";
15
15
  import "./camera-Bm3wb89Z.esm.js";
16
- import "./getBrowser-Y88tNVud.esm.js";
17
- import "./stats-Bqq9IKre.esm.js";
18
- import "./MotionSensorProvider-DJMsPght.esm.js";
19
- import "./permissionServices-ACBX6sNZ.esm.js";
20
- import "./platform-Dpzd9p3X.esm.js";
21
- import "./ITimerCapability-2pw-S97e.esm.js";
22
- import "./backCameraStream-DWZ1cNVA.esm.js";
23
- import "./getDeviceClass-DmoqR7G2.esm.js";
24
- import { t as faceCaptureMachine } from "./faceCaptureSetup-CUzqUwkP.esm.js";
25
- import "./authenticationStateMachine-BNs4VCxh.esm.js";
26
- import { n as createAuthenticationManagerFromActor } from "./authenticationManager-CKDxnLtG.esm.js";
16
+ import "./deepsightService-Dv6kvzph.esm.js";
17
+ import "./recordingService-Dp-3nA-h.esm.js";
18
+ import "./platform-CDh4uv5Y.esm.js";
19
+ import "./backCameraStream-BKC7QXRJ.esm.js";
20
+ import "./getBrowser-Bl0PlyDu.esm.js";
21
+ import "./stats-qUsejORa.esm.js";
22
+ import "./getDeviceClass-C1ZS2XJL.esm.js";
23
+ import "./MotionSensorProvider-Dt_lF3Z8.esm.js";
24
+ import "./permissionServices-Cdxqlwqz.esm.js";
25
+ import "./authenticationStateMachine-B4FQ52zK.esm.js";
26
+ import { n as createAuthenticationManagerFromActor } from "./authenticationManager-DsauZR1g.esm.js";
27
27
  import "./emailStateMachine-BW4tiYqt.esm.js";
28
28
  import { n as createEmailManagerFromActor } from "./emailManager-CJAgi4be.esm.js";
29
- import "./selfieStateMachine-DvOTE42w.esm.js";
30
- import { n as createSelfieManagerFromActor } from "./selfieManager-DC9hKgt7.esm.js";
31
- import "./idCaptureStateMachine-BuX1-VlB.esm.js";
32
- import { n as createIdCaptureManagerFromActor } from "./idCaptureManager-ZtfBOR6V.esm.js";
29
+ import "./selfieStateMachine-D0rrAFIs.esm.js";
30
+ import { n as createSelfieManagerFromActor } from "./selfieManager-5AG9bMT1.esm.js";
31
+ import "./idCaptureStateMachine-g5cYnHGD.esm.js";
32
+ import { n as createIdCaptureManagerFromActor } from "./idCaptureManager-DbP4E8PO.esm.js";
33
33
  import "./phoneStateMachine-dDqWuk_Q.esm.js";
34
34
  import { n as createPhoneManagerFromActor } from "./phoneManager-BgAfR0DQ.esm.js";
35
35
 
@@ -1,10 +1,10 @@
1
- import { n as WasmPipeline } from "./warmup-DHGg8wQZ.js";
1
+ import { n as WasmPipeline } from "./warmup-C6O7yhfX.js";
2
2
  import { t as Manager } from "./Manager-D9pehGyp.js";
3
3
  import { t as ActorRefFrom } from "./Actor-YjWTo26u.js";
4
4
  import { n as StateMachine, t as AnyStateMachine } from "./StateMachine-CJG7thvx.js";
5
5
  import { t as CameraStream } from "./camera-B6UAKpM1.js";
6
- import { i as FlowModuleConfig, n as Flow } from "./types-BA181GDD.js";
7
- import { a as IWasmUtilCapability, c as IMLProviderCapability, d as IRecordingCapability, i as IncodeCanvas, l as MLProviderConfig, r as StreamCanvasCapture, t as DeepsightService, u as IStorageCapability } from "./deepsightService-CGSDjjBz.js";
6
+ import { i as FlowModuleConfig, n as Flow } from "./types-DkXZpS0R.js";
7
+ import { a as IWasmUtilCapability, c as IMLProviderCapability, d as IRecordingCapability, i as IncodeCanvas, l as MLProviderConfig, r as StreamCanvasCapture, t as DeepsightService, u as IStorageCapability } from "./deepsightService-Kuw9roIJ.js";
8
8
  import { n as PermissionStatus, t as PermissionResult } from "./types-CarMMtoz.js";
9
9
 
10
10
  //#region src/modules/authentication/authenticationStateMachine.d.ts
@@ -37,6 +37,13 @@ type BaseFaceCaptureConfig = {
37
37
  capability?: IRecordingCapability;
38
38
  };
39
39
  ds?: Flow['ds'];
40
+ /**
41
+ * When true, face analysis runs on-device via the OnDevice WASM workflow
42
+ * (6 models) and only the results JSON is submitted to the backend
43
+ * (`/omni/add/face-results`). Recording is skipped entirely. Used by both
44
+ * SELFIE and AUTHENTICATION modules.
45
+ */
46
+ onDeviceFaceResultsSubmissionEnabled?: boolean;
40
47
  };
41
48
  type FaceCaptureDependencies = {
42
49
  storage: IStorageCapability;
@@ -90,6 +97,20 @@ type CreateAuthenticationActorOptions = {
90
97
  type AuthenticationActor = ActorRefFrom<AuthenticationMachine>;
91
98
  declare function createAuthenticationActor(options: CreateAuthenticationActorOptions): AuthenticationActor;
92
99
  //#endregion
100
+ //#region ../infra/src/wasm/wasmWebClient.d.ts
101
+
102
+ /**
103
+ * Configuration shape that the C++ `WebApi` passes when calling `.post(...)`
104
+ * on its host JS adapter. Mirrors the upstream `ml-wasm-kit/WebClient`
105
+ * `RequestConfig` for the subset of fields actually set by `WebApi`.
106
+ */
107
+ type WebApiHostRequestConfig = {
108
+ ie?: boolean;
109
+ headers?: Record<string, string>;
110
+ params?: Record<string, string | number | boolean | undefined>;
111
+ timeout?: number;
112
+ };
113
+ //#endregion
93
114
  //#region ../infra/src/capabilities/IFaceDetectionCapability.d.ts
94
115
  /**
95
116
  * Configuration for face detection provider.
@@ -97,6 +118,12 @@ declare function createAuthenticationActor(options: CreateAuthenticationActorOpt
97
118
  */
98
119
  interface FaceDetectionConfig extends MLProviderConfig {
99
120
  autocaptureInterval?: number;
121
+ /**
122
+ * Load the on-device selfie workflow (6 models including liveness + age
123
+ * estimation) instead of the default selfie workflow (4 models). Required
124
+ * when SELFIE/AUTHENTICATION has `onDeviceFaceResultsSubmissionEnabled`.
125
+ */
126
+ useOnDeviceWorkflow?: boolean;
100
127
  }
101
128
  interface FacePositionConstraints {
102
129
  minX: number;
@@ -112,6 +139,24 @@ interface FaceDetectionThresholds {
112
139
  autocaptureInterval: number;
113
140
  minFaceQualityScore: number;
114
141
  faceOcclusionThreshold: number;
142
+ /**
143
+ * Milliseconds the C++ workflow waits after `onGetReady` fires before
144
+ * triggering autocapture. Mirrors V1's `getReadyDelay` (2000 ms) — without
145
+ * it, autocapture can fire on the first quality-passing frame, before the
146
+ * front camera has finished locking focus, producing blurry captures that
147
+ * the on-device quality model rejects.
148
+ */
149
+ getReadyDelay: number;
150
+ /**
151
+ * Milliseconds over which face-detection results are aggregated before the
152
+ * autocapture decision. Mirrors V1's `framesAggregationInterval` (2000 ms).
153
+ */
154
+ framesAggregationInterval: number;
155
+ /**
156
+ * Minimum consecutive frames with a detected face required before
157
+ * autocapture can trigger. Mirrors V1's `minFramesWithFace` (3).
158
+ */
159
+ minFramesWithFace: number;
115
160
  }
116
161
  interface FaceAttributesThresholds {
117
162
  headwearThreshold: number;
@@ -196,6 +241,21 @@ interface IFaceDetectionCapability extends IMLProviderCapability<FaceDetectionCo
196
241
  * @param enabled - Whether to enable video selfie mode
197
242
  */
198
243
  setVideoSelfieMode(enabled: boolean): void;
244
+ /**
245
+ * Synchronous manual-capture entry point for the on-device selfie workflow.
246
+ * Runs the full on-device pipeline on a single canvas image and stages the
247
+ * results inside WASM for the next {@link postFaceResults} call. No-op for
248
+ * default (non-on-device) configurations; callers should guard with the
249
+ * `onDeviceFaceResultsSubmissionEnabled` flag.
250
+ */
251
+ processPhoto(canvas: HTMLCanvasElement): void;
252
+ /**
253
+ * POSTs the staged on-device face-results JSON to `/omni/add/face-results`.
254
+ * The C++ side encrypts the body via `SessionEncryptor` and routes through
255
+ * the WASM `WebClient`, so the SDK's WebClient must be initialized first
256
+ * (consumers calling this must configure `setup({ apiURL, wasm })`).
257
+ */
258
+ postFaceResults(config?: WebApiHostRequestConfig): Promise<unknown>;
199
259
  }
200
260
  //#endregion
201
261
  //#region ../infra/src/wasm/WasmPipelineType.d.ts
@@ -205,6 +265,7 @@ declare enum WasmPipelineType {
205
265
  IdVideoSelfiePipeline = 2,
206
266
  SelfieWithAggregationMetrics = 3,
207
267
  SelfieWithQualityMetrics = 4,
268
+ OnDeviceSelfieWorkflow = 5,
208
269
  }
209
270
  //#endregion
210
271
  //#region ../infra/src/providers/wasm/BaseWasmProvider.d.ts
@@ -282,6 +343,8 @@ declare class FaceDetectionProvider extends BaseWasmProvider implements IFaceDet
282
343
  constructor();
283
344
  processFrame(image: ImageData): Promise<void>;
284
345
  initialize(config: FaceDetectionConfig): Promise<void>;
346
+ processPhoto(canvas: HTMLCanvasElement): void;
347
+ postFaceResults(config?: WebApiHostRequestConfig): Promise<unknown>;
285
348
  setCallbacks(callbacks: FaceDetectionCallbacks): void;
286
349
  setPositionConstraints(constraints: FacePositionConstraints): void;
287
350
  applyDefaults(autocaptureInterval?: number): void;
@@ -14,7 +14,9 @@ function getCaptureStatus(snapshot) {
14
14
  if (snapshot.matches({ capture: "detecting" })) return "detecting";
15
15
  if (snapshot.matches({ capture: "capturing" })) return "capturing";
16
16
  if (snapshot.matches({ capture: "capturingManual" })) return "capturing";
17
+ if (snapshot.matches({ capture: "preparingUpload" })) return "uploading";
17
18
  if (snapshot.matches({ capture: "uploading" })) return "uploading";
19
+ if (snapshot.matches({ capture: "validatingUpload" })) return "uploading";
18
20
  if (snapshot.matches({ capture: "uploadError" })) return "uploadError";
19
21
  if (snapshot.matches({ capture: "success" })) return "success";
20
22
  }
@@ -1,8 +1,143 @@
1
1
  import { r as getToken } from "./api-eqRXuVG-.esm.js";
2
2
  import { a as fromPromise, i as fromCallback, r as assign, t as setup } from "./xstate.esm-7GmmAwg6.esm.js";
3
- import { _ as StreamCanvasCapture, a as initializeDeepsightSession, c as stopStream, h as flagFaceManualReview, i as initializeCamera, n as preloadOpenViduProvider, o as sendLabelInspectionEvent, r as encryptSelfieImage, s as startDetection, t as createRecordingService, v as FACE_ERROR_CODES } from "./recordingService-DMaVUhWY.esm.js";
4
- import { n as requestPermission, t as checkPermission } from "./permissionServices-ACBX6sNZ.esm.js";
3
+ import { t as sleep } from "./ITimerCapability-3xSd36bT.esm.js";
4
+ import { a as StreamCanvasCapture, c as initializeDeepsightSession, d as stopStream, l as sendLabelInspectionEvent, m as FACE_ERROR_CODES, n as preloadOpenViduProvider, o as encryptSelfieImage, r as flagFaceManualReview, s as initializeCamera, t as createRecordingService, u as startDetection } from "./recordingService-Dp-3nA-h.esm.js";
5
+ import { n as requestPermission, t as checkPermission } from "./permissionServices-Cdxqlwqz.esm.js";
5
6
 
7
+ //#region ../infra/src/scheduling/yieldUntilNextPaint.ts
8
+ /**
9
+ * Resolves after the browser has had a chance to commit and paint a queued
10
+ * render.
11
+ *
12
+ * Strategy:
13
+ * - `requestAnimationFrame` callbacks fire BEFORE the paint of the frame
14
+ * they belong to (per the HTML5 "update the rendering" step). If we
15
+ * resolve the promise inside a rAF callback, the await-continuation
16
+ * runs as a microtask immediately after the callback returns — still
17
+ * before the paint phase of that frame. A caller that then blocks the
18
+ * main thread (e.g. synchronous WASM `processPhoto`) starves the paint.
19
+ * - We therefore chain rAF → setTimeout: the rAF fires before frame N's
20
+ * paint, the setTimeout runs as a macrotask scheduled after frame N's
21
+ * "update the rendering" step, which the browser will only get to once
22
+ * the paint actually lands. By the time setTimeout fires, the paint
23
+ * for the queued render is on screen.
24
+ * - In environments where rAF never ticks (jsdom, happy-dom, backgrounded
25
+ * tabs), a parallel `setTimeout` fallback at 100 ms resolves instead.
26
+ * 100 ms is comfortably longer than two real-browser frames so rAF +
27
+ * setTimeout wins reliably in any foregrounded browser. (An earlier
28
+ * implementation raced rAF against a `MessageChannel` macrotask, but
29
+ * MessageChannel drains immediately after the current task's
30
+ * microtasks — before the next paint — so it resolved the promise too
31
+ * early and defeated the whole point of the helper.)
32
+ *
33
+ * Lives in infra because it touches browser APIs (`requestAnimationFrame`,
34
+ * `setTimeout`) that the architecture rules forbid from core. Core modules
35
+ * that need to yield to the browser render loop should import this helper
36
+ * directly via its file path.
37
+ */
38
+ function yieldUntilNextPaint() {
39
+ return new Promise((resolve) => {
40
+ let resolved = false;
41
+ const done = () => {
42
+ if (resolved) return;
43
+ resolved = true;
44
+ resolve();
45
+ };
46
+ if (typeof requestAnimationFrame === "function") requestAnimationFrame(() => {
47
+ requestAnimationFrame(() => {
48
+ setTimeout(done, 0);
49
+ });
50
+ });
51
+ setTimeout(done, 100);
52
+ });
53
+ }
54
+
55
+ //#endregion
56
+ //#region src/internal/faceCapture/onDeviceFaceResults.ts
57
+ /**
58
+ * On-device face-results submission helpers.
59
+ *
60
+ * When a SELFIE or AUTHENTICATION module has
61
+ * `onDeviceFaceResultsSubmissionEnabled: true`, face analysis runs entirely
62
+ * inside the WASM `OnDeviceSelfieWorkflow` pipeline. Captured images are
63
+ * never uploaded — only the staged face-results JSON is POSTed via the WASM
64
+ * `WebApi` to `/omni/add/face-results`. The C++ side encrypts that JSON via
65
+ * `SessionEncryptor`, so this path does NOT require WebClient E2EE.
66
+ *
67
+ * These helpers are deliberately variant-agnostic: both the selfie and auth
68
+ * state machine variants delegate their `prepareFaceUpload`, `uploadFace`,
69
+ * and `processFace` actors here to share behavior. See the "Runtime modes
70
+ * within a module" section of `docs/patterns/XSTATE.md` for the broader
71
+ * pattern.
72
+ */
73
+ const isOnDeviceMode = (config) => config.onDeviceFaceResultsSubmissionEnabled === true;
74
+ /**
75
+ * The default (non-on-device) prepare-upload body shared by selfie and auth.
76
+ * Stops any active recording, runs deepsight virtual-camera + frame checks,
77
+ * tracks the capture attempt, and encrypts the captured image.
78
+ *
79
+ * Lifted out of `faceCaptureSetup.ts`'s base `prepareFaceUpload` actor so the
80
+ * default path can be reused by both variants while leaving room for an
81
+ * on-device branch alongside it.
82
+ */
83
+ async function defaultPrepareFaceUpload(ctx) {
84
+ const sessionToken = getToken();
85
+ const recordingId = (await ctx.recordingService?.stop())?.recordingId ?? null;
86
+ try {
87
+ if (ctx.deepsightService) await Promise.all([ctx.deepsightService.performVirtualCameraCheck(sessionToken, "SELFIE"), ctx.deepsightService.analyzeFrame(ctx.capturedImage.getImageData())]);
88
+ } catch (error) {}
89
+ const logs = ctx.deepsightService?.getPipelineState() ?? "";
90
+ ctx.dependencies.trackCaptureAttemptFinished?.({ logs });
91
+ return {
92
+ encryptedBase64Image: await encryptSelfieImage({
93
+ canvas: ctx.capturedImage,
94
+ dependencies: ctx.dependencies
95
+ }),
96
+ recordingId
97
+ };
98
+ }
99
+ /**
100
+ * On-device prepare-upload. No recording to stop (the recording service is
101
+ * never created when the flag is on), no image encryption needed — instead,
102
+ * we hand the captured canvas to the WASM provider's `processPhoto` which
103
+ * runs the full on-device pipeline and stages results inside `WebApi` for
104
+ * the subsequent `postFaceResults` call.
105
+ *
106
+ * Returns sentinel values for `encryptedBase64Image` and `recordingId` so
107
+ * the existing FaceCaptureContext shape remains stable; downstream actors
108
+ * for the on-device path simply ignore them.
109
+ */
110
+ async function prepareOnDeviceFaceUpload(ctx) {
111
+ if (!ctx.capturedImage) throw new Error("On-device capture requires a captured image canvas");
112
+ if (!ctx.provider) throw new Error("On-device capture requires the FaceDetectionProvider to be initialized");
113
+ await yieldUntilNextPaint();
114
+ await sleep(350);
115
+ ctx.provider.processPhoto(ctx.capturedImage.canvas);
116
+ return {
117
+ encryptedBase64Image: "",
118
+ recordingId: null
119
+ };
120
+ }
121
+ /**
122
+ * POSTs the staged on-device face-results JSON to `/omni/add/face-results`
123
+ * through the WASM `WebApi`. Used as the `uploadFace` actor body for both
124
+ * selfie and auth variants when on-device mode is enabled.
125
+ *
126
+ * The C++ `WebApi` handles `SessionEncryptor` encryption and the actual
127
+ * HTTP via the WASM `WebClient` — so callers don't need to thread the
128
+ * session-encryption details through JS.
129
+ */
130
+ async function postOnDeviceFaceResults(ctx, signal) {
131
+ const provider = ctx.provider;
132
+ if (!provider) throw new Error("On-device upload requires the FaceDetectionProvider to be initialized");
133
+ const sessionToken = getToken();
134
+ return await provider.postFaceResults({
135
+ headers: sessionToken ? { "X-Incode-Hardware-Id": sessionToken } : void 0,
136
+ timeout: 3e4
137
+ }) ?? {};
138
+ }
139
+
140
+ //#endregion
6
141
  //#region src/internal/faceCapture/faceCaptureSetup.ts
7
142
  const getAttemptsFromConfig = (config) => {
8
143
  return config.captureAttempts ?? config.numberOfAttempts ?? 3;
@@ -89,22 +224,8 @@ const _faceCaptureMachine = setup({
89
224
  if (!videoTrack) return false;
90
225
  return input.deepsightService.checkVirtualCamera(videoTrack);
91
226
  }),
92
- prepareFaceUpload: fromPromise(async ({ input }) => {
93
- const ctx = input;
94
- const sessionToken = getToken();
95
- const recordingId = (await ctx.recordingService?.stop())?.recordingId ?? null;
96
- try {
97
- if (ctx.deepsightService) await Promise.all([ctx.deepsightService.performVirtualCameraCheck(sessionToken, "SELFIE"), ctx.deepsightService.analyzeFrame(ctx.capturedImage.getImageData())]);
98
- } catch (error) {}
99
- const logs = ctx.deepsightService?.getPipelineState() ?? "";
100
- ctx.dependencies.trackCaptureAttemptFinished?.({ logs });
101
- return {
102
- encryptedBase64Image: await encryptSelfieImage({
103
- canvas: ctx.capturedImage,
104
- dependencies: ctx.dependencies
105
- }),
106
- recordingId
107
- };
227
+ prepareFaceUpload: fromPromise(async () => {
228
+ throw new Error("prepareFaceUpload must be provided by variant");
108
229
  }),
109
230
  uploadFace: fromPromise(async () => {
110
231
  throw new Error("uploadFace must be provided by variant");
@@ -686,6 +807,7 @@ const _faceCaptureMachine = setup({
686
807
  processing: { invoke: {
687
808
  id: "processFace",
688
809
  src: "processFace",
810
+ input: ({ context }) => context,
689
811
  onDone: {
690
812
  target: "finished",
691
813
  actions: "setProcessResponseFromEvent"
@@ -712,4 +834,4 @@ const _faceCaptureMachine = setup({
712
834
  const faceCaptureMachine = _faceCaptureMachine;
713
835
 
714
836
  //#endregion
715
- export { faceCaptureMachine as t };
837
+ export { prepareOnDeviceFaceUpload as a, postOnDeviceFaceResults as i, defaultPrepareFaceUpload as n, isOnDeviceMode as r, faceCaptureMachine as t };
@@ -1,6 +1,6 @@
1
1
  import "./camera-B6UAKpM1.js";
2
2
  import "./types-DJSt3Ovt.js";
3
- import "./types-BA181GDD.js";
3
+ import "./types-DkXZpS0R.js";
4
4
  import "./flowCompletionService-C376JZwA.js";
5
- import { a as FlowEventListener, c as FlowModuleStartedEvent, i as FlowEvent, l as FlowReadyEvent, n as FlowCompletedEvent, o as FlowEventSubscribable, r as FlowErrorEvent, s as FlowModuleCompletedEvent, t as FlowClosedEvent, u as FlowStartedEvent } from "./index-CmFkidgy.js";
5
+ import { a as FlowEventListener, c as FlowModuleStartedEvent, i as FlowEvent, l as FlowReadyEvent, n as FlowCompletedEvent, o as FlowEventSubscribable, r as FlowErrorEvent, s as FlowModuleCompletedEvent, t as FlowClosedEvent, u as FlowStartedEvent } from "./index-UH-vOq3x.js";
6
6
  export { FlowClosedEvent, FlowCompletedEvent, FlowErrorEvent, FlowEvent, FlowEventListener, FlowEventSubscribable, FlowModuleCompletedEvent, FlowModuleStartedEvent, FlowReadyEvent, FlowStartedEvent };
package/dist/flow.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { n as WasmPipeline } from "./warmup-DHGg8wQZ.js";
1
+ import { n as WasmPipeline } from "./warmup-C6O7yhfX.js";
2
2
  import { t as Manager } from "./Manager-D9pehGyp.js";
3
3
  import { t as AnyStateMachine } from "./StateMachine-CJG7thvx.js";
4
4
  import "./camera-B6UAKpM1.js";
5
5
  import "./types-DJSt3Ovt.js";
6
- import { i as FlowModuleConfig, n as Flow, r as FlowModule } from "./types-BA181GDD.js";
6
+ import { i as FlowModuleConfig, n as Flow, r as FlowModule } from "./types-DkXZpS0R.js";
7
7
  import { n as GetFinishStatusFn, t as FinishStatus } from "./flowCompletionService-C376JZwA.js";
8
- import { o as FlowEventSubscribable } from "./index-CmFkidgy.js";
8
+ import { o as FlowEventSubscribable } from "./index-UH-vOq3x.js";
9
9
  import { t as ModuleRegistry } from "./types-WKAQ7Ai4.js";
10
10
  import * as xstate963 from "xstate";
11
11
 
@@ -21,6 +21,10 @@ type FlowForNormalization = Pick<Flow, 'flowId' | 'flowModules' | 'redirectDeskt
21
21
  * Analyzes a flow configuration and returns the WASM pipelines needed.
22
22
  * Use this to conditionally warmup WASM only when required by the flow.
23
23
  *
24
+ * Modules with `onDeviceFaceResultsSubmissionEnabled: true` (currently SELFIE
25
+ * and AUTHENTICATION) select the 6-model `'onDeviceSelfie'` bundle instead of
26
+ * the default 4-model `'selfie'` bundle.
27
+ *
24
28
  * @param flow - The flow configuration from /omni/onboarding/flow
25
29
  * @returns Array of WASM pipelines needed (e.g., ['selfie', 'idCapture'])
26
30
  *
package/dist/flow.esm.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import "./api-eqRXuVG-.esm.js";
2
2
  import "./events-Bt1azl2B.esm.js";
3
3
  import "./endpoints-B3V1U9Dg.esm.js";
4
- import "./session-DAspZUCj.esm.js";
4
+ import "./session-BxtuBDwz.esm.js";
5
5
  import "./IpifyProvider-ByL6JYxg.esm.js";
6
6
  import "./browserSimulation-CAH-V_iE.esm.js";
7
7
  import { a as fromPromise, o as createActor, r as assign, s as createManager, t as setup } from "./xstate.esm-7GmmAwg6.esm.js";
8
- import { n as getRequiredWasmPipelines, r as normalizeFlowModules, t as getFlow } from "./flowServices-CLo2qihS.esm.js";
8
+ import { n as getRequiredWasmPipelines, r as normalizeFlowModules, t as getFlow } from "./flowServices-BVVnH_Fn.esm.js";
9
9
  import { n as attachFlowEventEmitter, t as runChildModule } from "./runChildModule-B16ocpd4.esm.js";
10
10
  import { t as getFinishStatus } from "./flowCompletionService-BuVIVPT_.esm.js";
11
11
 
@@ -1,6 +1,6 @@
1
1
  import { t as api } from "./api-eqRXuVG-.esm.js";
2
2
  import { t as endpoints } from "./endpoints-B3V1U9Dg.esm.js";
3
- import { n as getSessionFingerprintResult, r as initializeSession } from "./session-DAspZUCj.esm.js";
3
+ import { n as getSessionFingerprintResult, r as initializeSession } from "./session-BxtuBDwz.esm.js";
4
4
 
5
5
  //#region src/modules/flow/flowUtils.ts
6
6
  const WASM_MODULE_PIPELINES = {
@@ -12,10 +12,19 @@ const WASM_MODULE_PIPELINES = {
12
12
  TUTORIAL_ID: "idCapture",
13
13
  SECOND_ID: "idCapture"
14
14
  };
15
+ const FACE_MODULES_WITH_ON_DEVICE_VARIANT = new Set(["SELFIE", "AUTHENTICATION"]);
16
+ function isOnDeviceFaceModule(module) {
17
+ if (!FACE_MODULES_WITH_ON_DEVICE_VARIANT.has(module.key)) return false;
18
+ return module.configuration?.onDeviceFaceResultsSubmissionEnabled === true;
19
+ }
15
20
  /**
16
21
  * Analyzes a flow configuration and returns the WASM pipelines needed.
17
22
  * Use this to conditionally warmup WASM only when required by the flow.
18
23
  *
24
+ * Modules with `onDeviceFaceResultsSubmissionEnabled: true` (currently SELFIE
25
+ * and AUTHENTICATION) select the 6-model `'onDeviceSelfie'` bundle instead of
26
+ * the default 4-model `'selfie'` bundle.
27
+ *
19
28
  * @param flow - The flow configuration from /omni/onboarding/flow
20
29
  * @returns Array of WASM pipelines needed (e.g., ['selfie', 'idCapture'])
21
30
  *
@@ -30,6 +39,10 @@ const WASM_MODULE_PIPELINES = {
30
39
  function getRequiredWasmPipelines(flow) {
31
40
  const pipelines = /* @__PURE__ */ new Set();
32
41
  for (const module of flow.flowModules) {
42
+ if (isOnDeviceFaceModule(module)) {
43
+ pipelines.add("onDeviceSelfie");
44
+ continue;
45
+ }
33
46
  const pipeline = WASM_MODULE_PIPELINES[module.key];
34
47
  if (pipeline) pipelines.add(pipeline);
35
48
  }
@@ -2,8 +2,8 @@ import "./api-eqRXuVG-.esm.js";
2
2
  import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-Bt1azl2B.esm.js";
3
3
  import "./endpoints-B3V1U9Dg.esm.js";
4
4
  import { o as createActor, s as createManager } from "./xstate.esm-7GmmAwg6.esm.js";
5
- import "./platform-Dpzd9p3X.esm.js";
6
- import { t as geolocationMachine } from "./geolocationStateMachine-15aagr2_.esm.js";
5
+ import "./platform-CDh4uv5Y.esm.js";
6
+ import { t as geolocationMachine } from "./geolocationStateMachine-BYWUPbNs.esm.js";
7
7
 
8
8
  //#region ../infra/src/providers/browser/BrowserGeolocationProvider.ts
9
9
  var BrowserGeolocationProvider = class {
@@ -1,7 +1,7 @@
1
1
  import { t as api } from "./api-eqRXuVG-.esm.js";
2
2
  import { t as endpoints } from "./endpoints-B3V1U9Dg.esm.js";
3
3
  import { a as fromPromise, r as assign, t as setup } from "./xstate.esm-7GmmAwg6.esm.js";
4
- import { r as isIOS, t as isAndroid } from "./platform-Dpzd9p3X.esm.js";
4
+ import { r as isIOS, t as isAndroid } from "./platform-CDh4uv5Y.esm.js";
5
5
 
6
6
  //#region src/modules/geolocation/geolocationServices.ts
7
7
  async function addGeolocation(params, signal) {
@@ -1,4 +1,4 @@
1
- import { n as getDeviceInfo } from "./getBrowser-Y88tNVud.esm.js";
1
+ import { n as getDeviceInfo } from "./getBrowser-Bl0PlyDu.esm.js";
2
2
 
3
3
  //#region src/internal/device/getDeviceClass.ts
4
4
  function getDeviceClass() {
package/dist/home.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { t as Manager } from "./Manager-D9pehGyp.js";
2
2
  import "./camera-B6UAKpM1.js";
3
3
  import "./types-DJSt3Ovt.js";
4
- import { t as EmptyConfig } from "./types-BA181GDD.js";
5
- import * as xstate468 from "xstate";
4
+ import { t as EmptyConfig } from "./types-DkXZpS0R.js";
5
+ import * as xstate726 from "xstate";
6
6
 
7
7
  //#region src/modules/home/types.d.ts
8
8
  type HomeConfig = EmptyConfig;
@@ -34,41 +34,41 @@ type HomeContext = {
34
34
  type HomeInput = {
35
35
  config: EmptyConfig;
36
36
  };
37
- declare const homeMachine: xstate468.StateMachine<HomeContext, {
37
+ declare const homeMachine: xstate726.StateMachine<HomeContext, {
38
38
  type: "LOAD";
39
39
  } | {
40
40
  type: "COMPLETE";
41
41
  } | {
42
42
  type: "RESET";
43
- }, {}, never, never, never, never, "idle" | "finished" | "main", string, HomeInput, xstate468.NonReducibleUnknown, xstate468.EventObject, xstate468.MetaObject, {
43
+ }, {}, never, never, never, never, "idle" | "finished" | "main", string, HomeInput, xstate726.NonReducibleUnknown, xstate726.EventObject, xstate726.MetaObject, {
44
44
  readonly id: "home";
45
45
  readonly initial: "idle";
46
46
  readonly context: ({
47
47
  input
48
48
  }: {
49
49
  spawn: {
50
- <TSrc extends never>(logic: TSrc, ...[options]: never): xstate468.ActorRefFromLogic<never>;
51
- <TLogic extends xstate468.AnyActorLogic>(src: TLogic, ...[options]: xstate468.ConditionalRequired<[options?: ({
50
+ <TSrc extends never>(logic: TSrc, ...[options]: never): xstate726.ActorRefFromLogic<never>;
51
+ <TLogic extends xstate726.AnyActorLogic>(src: TLogic, ...[options]: xstate726.ConditionalRequired<[options?: ({
52
52
  id?: never;
53
53
  systemId?: string;
54
- input?: xstate468.InputFrom<TLogic> | undefined;
54
+ input?: xstate726.InputFrom<TLogic> | undefined;
55
55
  syncSnapshot?: boolean;
56
- } & { [K in xstate468.RequiredLogicInput<TLogic>]: unknown }) | undefined], xstate468.IsNotNever<xstate468.RequiredLogicInput<TLogic>>>): xstate468.ActorRefFromLogic<TLogic>;
56
+ } & { [K in xstate726.RequiredLogicInput<TLogic>]: unknown }) | undefined], xstate726.IsNotNever<xstate726.RequiredLogicInput<TLogic>>>): xstate726.ActorRefFromLogic<TLogic>;
57
57
  };
58
58
  input: HomeInput;
59
- self: xstate468.ActorRef<xstate468.MachineSnapshot<HomeContext, {
59
+ self: xstate726.ActorRef<xstate726.MachineSnapshot<HomeContext, {
60
60
  type: "LOAD";
61
61
  } | {
62
62
  type: "COMPLETE";
63
63
  } | {
64
64
  type: "RESET";
65
- }, Record<string, xstate468.AnyActorRef | undefined>, xstate468.StateValue, string, unknown, any, any>, {
65
+ }, Record<string, xstate726.AnyActorRef | undefined>, xstate726.StateValue, string, unknown, any, any>, {
66
66
  type: "LOAD";
67
67
  } | {
68
68
  type: "COMPLETE";
69
69
  } | {
70
70
  type: "RESET";
71
- }, xstate468.AnyEventObject>;
71
+ }, xstate726.AnyEventObject>;
72
72
  }) => {
73
73
  config: EmptyConfig;
74
74
  };
package/dist/http.d.ts CHANGED
@@ -12,6 +12,15 @@ type RequestConfig = {
12
12
  parse?: 'json' | 'text' | 'blob' | 'arrayBuffer' | 'response';
13
13
  onUploadProgress?: (progress: number) => void;
14
14
  keepalive?: boolean;
15
+ /**
16
+ * Transport-internal flag: the request body has already been inline-
17
+ * encrypted by C++ `SessionEncryptor` (used only by the on-device face-
18
+ * results path). When true, `createWasmApi` attaches the SHA-256 OAEP
19
+ * scheme header so the server can unwrap the embedded AES key, and
20
+ * forwards the flag to the WASM WebClient so it does not double-encrypt.
21
+ * Ignored by non-WASM transports.
22
+ */
23
+ ie?: boolean;
15
24
  };
16
25
  type HttpResponse<T = unknown> = {
17
26
  ok: boolean;