@incodetech/core 2.0.0-alpha.8 → 2.0.0-rc.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.
Files changed (184) hide show
  1. package/dist/Actor-CI32dTbG.d.ts +2 -0
  2. package/dist/BaseWasmProvider-C_DLEI40.esm.js +1118 -0
  3. package/dist/BrowserStorageProvider-CuOW1Er2.esm.js +55 -0
  4. package/dist/BrowserTimerProvider-DhNc_x02.esm.js +22 -0
  5. package/dist/ITimerCapability-C67ZRskg.esm.js +7 -0
  6. package/dist/IpifyProvider-D7jx52AL.esm.js +139 -0
  7. package/dist/MotionSensorProvider-4v7xkqAp.esm.js +254 -0
  8. package/dist/OpenViduRecordingProvider-CMu6XVdc.esm.js +87 -0
  9. package/dist/StateMachine-BCQrZJhf.d.ts +2 -0
  10. package/dist/WasmUtilProvider-j98OJf-S.esm.js +114 -0
  11. package/dist/addressSearch-BpTbTWCa.esm.js +430 -0
  12. package/dist/ae-signature-DDDZmWXj.esm.js +12 -0
  13. package/dist/ae-signature.d.ts +25 -0
  14. package/dist/ae-signature.esm.js +8 -0
  15. package/dist/antifraud.d.ts +57 -0
  16. package/dist/antifraud.esm.js +45 -0
  17. package/dist/antifraudStateMachine-O0TMf6yc.esm.js +39 -0
  18. package/dist/api-CESGtpbH.esm.js +53 -0
  19. package/dist/authentication.d.ts +12 -0
  20. package/dist/authentication.esm.js +25 -0
  21. package/dist/authenticationManager-5M-fKzXx.esm.js +67 -0
  22. package/dist/authenticationManager-C83GNIhl.d.ts +66 -0
  23. package/dist/authenticationStateMachine-BMZqatiF.esm.js +139 -0
  24. package/dist/backCameraStream-DMdMeGk2.esm.js +346 -0
  25. package/dist/browserSimulation-gxD8cSpM.esm.js +20 -0
  26. package/dist/camera-DBSxa6ML.d.ts +4 -0
  27. package/dist/camera-PA2Ljri3.esm.js +22 -0
  28. package/dist/camera.d.ts +15 -0
  29. package/dist/camera.esm.js +5 -0
  30. package/dist/consent.d.ts +398 -0
  31. package/dist/consent.esm.js +79 -0
  32. package/dist/consentStateMachine-CCT-B60O.esm.js +151 -0
  33. package/dist/cpf-PPz2Njto.esm.js +38 -0
  34. package/dist/cpf-ocr.d.ts +204 -0
  35. package/dist/cpf-ocr.esm.js +177 -0
  36. package/dist/cross-document-data-match.d.ts +34 -0
  37. package/dist/cross-document-data-match.esm.js +71 -0
  38. package/dist/curp-validation.d.ts +188 -0
  39. package/dist/curp-validation.esm.js +110 -0
  40. package/dist/curpValidationStateMachine-CitWLr2c.esm.js +595 -0
  41. package/dist/custom-fields.d.ts +115 -0
  42. package/dist/custom-fields.esm.js +177 -0
  43. package/dist/custom-watchlist.d.ts +66 -0
  44. package/dist/custom-watchlist.esm.js +86 -0
  45. package/dist/dateUtils-UoN5xswP.esm.js +23 -0
  46. package/dist/deepsightLoader-Cm4JIT_z.esm.js +52 -0
  47. package/dist/deepsightService-CEVxzehb.d.ts +412 -0
  48. package/dist/deepsightService-O74l4Y__.esm.js +489 -0
  49. package/dist/device.d.ts +46 -0
  50. package/dist/device.esm.js +106 -0
  51. package/dist/displayErrors-DqJ_IbsG.d.ts +39 -0
  52. package/dist/document-capture.d.ts +906 -0
  53. package/dist/document-capture.esm.js +156 -0
  54. package/dist/document-upload.d.ts +331 -0
  55. package/dist/document-upload.esm.js +203 -0
  56. package/dist/documentCaptureStateMachine-BqzTDy9k.esm.js +394 -0
  57. package/dist/dynamic-forms.d.ts +178 -0
  58. package/dist/dynamic-forms.esm.js +323 -0
  59. package/dist/ekyb.d.ts +148 -0
  60. package/dist/ekyb.esm.js +127 -0
  61. package/dist/ekybStateMachine-B59rQjgj.esm.js +674 -0
  62. package/dist/ekyc.d.ts +164 -0
  63. package/dist/ekyc.esm.js +104 -0
  64. package/dist/ekycStateMachine-oeO0Iekd.esm.js +10626 -0
  65. package/dist/electronic-signature.d.ts +4 -0
  66. package/dist/electronic-signature.esm.js +7 -0
  67. package/dist/electronicSignatureManager-D9OHzTpG.esm.js +428 -0
  68. package/dist/email.d.ts +3 -263
  69. package/dist/email.esm.js +7 -477
  70. package/dist/emailManager-DIfnS5g1.d.ts +352 -0
  71. package/dist/emailManager-wAV0LE-H.esm.js +238 -0
  72. package/dist/emailStateMachine-DOf4j58N.esm.js +292 -0
  73. package/dist/endpoints-CnN3SyDa.esm.js +87 -0
  74. package/dist/events-D6-e4vok.esm.js +596 -0
  75. package/dist/events.d.ts +265 -0
  76. package/dist/events.esm.js +4 -0
  77. package/dist/extensibility.d.ts +122 -0
  78. package/dist/extensibility.esm.js +43 -0
  79. package/dist/face-match.d.ts +228 -0
  80. package/dist/face-match.esm.js +173 -0
  81. package/dist/faceCaptureManagerFactory-Dh2PdGlF.esm.js +290 -0
  82. package/dist/faceCaptureManagerFactory-yqtpxjnN.d.ts +690 -0
  83. package/dist/faceCaptureSetup-B3faSpYA.esm.js +873 -0
  84. package/dist/faceMatchStateMachine-DNFrxTFS.esm.js +127 -0
  85. package/dist/flow-events.d.ts +6 -0
  86. package/dist/flow-events.esm.js +0 -0
  87. package/dist/flow.d.ts +101 -321
  88. package/dist/flow.esm.js +370 -173
  89. package/dist/flowCompletionService-DhkT4SRY.d.ts +10 -0
  90. package/dist/flowCompletionService-P54yzGvA.esm.js +13 -0
  91. package/dist/flowServices-DTsm-Vf1.esm.js +188 -0
  92. package/dist/geolocation.d.ts +127 -0
  93. package/dist/geolocation.esm.js +89 -0
  94. package/dist/geolocationStateMachine-asasuHY2.esm.js +105 -0
  95. package/dist/getBrowser-BSXUTWXw.esm.js +41 -0
  96. package/dist/getDeviceClass-BSntT9_j.esm.js +14 -0
  97. package/dist/government-validation.d.ts +67 -0
  98. package/dist/government-validation.esm.js +81 -0
  99. package/dist/governmentValidationStateMachine-BDDYrJTo.esm.js +271 -0
  100. package/dist/home.d.ts +99 -0
  101. package/dist/home.esm.js +61 -0
  102. package/dist/http.d.ts +68 -0
  103. package/dist/http.esm.js +3 -0
  104. package/dist/id-ocr.d.ts +635 -0
  105. package/dist/id-ocr.esm.js +86 -0
  106. package/dist/id-verification.d.ts +190 -0
  107. package/dist/id-verification.esm.js +43 -0
  108. package/dist/id.d.ts +24 -0
  109. package/dist/id.esm.js +164 -0
  110. package/dist/idCaptureManager-B9TGA5dq.d.ts +956 -0
  111. package/dist/idCaptureManager-DMK0GIt3.esm.js +581 -0
  112. package/dist/idCaptureStateMachine-Bq0fVZXl.esm.js +2954 -0
  113. package/dist/idOcrStateMachine-YbjjC_Gg.esm.js +388 -0
  114. package/dist/idVerificationStateMachine-xbw9HP1Z.esm.js +71 -0
  115. package/dist/identity-reuse.d.ts +530 -0
  116. package/dist/identity-reuse.esm.js +274 -0
  117. package/dist/index-BLKtMA0g.d.ts +1177 -0
  118. package/dist/index-BcRG8rtJ.d.ts +97 -0
  119. package/dist/index.d.ts +3 -226
  120. package/dist/index.esm.js +11 -154
  121. package/dist/invokeOnCaptureCallback-rc6kBHo5.esm.js +30 -0
  122. package/dist/{lib-Bu9XGMBW.esm.js → lib-BB0B_qQX.esm.js} +801 -2
  123. package/dist/mandatory-consent.d.ts +412 -0
  124. package/dist/mandatory-consent.esm.js +78 -0
  125. package/dist/mandatoryConsentStateMachine-Cnco1jvn.esm.js +126 -0
  126. package/dist/openviduLazy-Cm0XFh_v.esm.js +3 -0
  127. package/dist/openviduLazy-Cok70ZSg.esm.js +12 -0
  128. package/dist/permissionServices-D_i6nzEw.esm.js +50 -0
  129. package/dist/phone.d.ts +3 -291
  130. package/dist/phone.esm.js +7 -548
  131. package/dist/phoneManager-B6M30hKE.d.ts +397 -0
  132. package/dist/phoneManager-DAJbGhlY.esm.js +256 -0
  133. package/dist/phoneStateMachine-CuPARRaT.esm.js +351 -0
  134. package/dist/platform-CfrjKhmi.esm.js +83 -0
  135. package/dist/qe-signature-DFo_Cc-I.esm.js +12 -0
  136. package/dist/qe-signature.d.ts +25 -0
  137. package/dist/qe-signature.esm.js +8 -0
  138. package/dist/recordingService-Ig2UgbLv.esm.js +1003 -0
  139. package/dist/redirect-to-mobile.d.ts +107 -0
  140. package/dist/redirect-to-mobile.esm.js +102 -0
  141. package/dist/redirectToMobileStateMachine-BOEqe46A.esm.js +249 -0
  142. package/dist/runChildModule-CqqwqAkW.esm.js +219 -0
  143. package/dist/selfie.d.ts +21 -754
  144. package/dist/selfie.esm.js +113 -962
  145. package/dist/selfieManager-D0lSgd-J.d.ts +68 -0
  146. package/dist/selfieManager-Duisl7qN.esm.js +60 -0
  147. package/dist/selfieStateMachine-D76whWEf.esm.js +68 -0
  148. package/dist/session-BS-d_vuE.esm.js +3206 -0
  149. package/dist/session.d.ts +217 -0
  150. package/dist/session.esm.js +9 -0
  151. package/dist/setup-Buy-hyj4.esm.js +887 -0
  152. package/dist/setup-C5AITV8m.d.ts +254 -0
  153. package/dist/signature.d.ts +94 -0
  154. package/dist/signature.esm.js +66 -0
  155. package/dist/signatureStateMachine-B5-QVUve.esm.js +132 -0
  156. package/dist/stats-CIfiPzb1.esm.js +16 -0
  157. package/dist/stats.d.ts +16 -0
  158. package/dist/stats.esm.js +4 -0
  159. package/dist/trust-graph.d.ts +54 -0
  160. package/dist/trust-graph.esm.js +56 -0
  161. package/dist/types-B06Ypu2F.d.ts +49 -0
  162. package/dist/types-BP1m8VRw.d.ts +340 -0
  163. package/dist/types-CFV9G_7j.d.ts +24 -0
  164. package/dist/{warmup-CEJTfxQr.d.ts → warmup-CEcppFiS.d.ts} +11 -3
  165. package/dist/wasm.d.ts +15 -0
  166. package/dist/wasm.esm.js +12 -0
  167. package/dist/watchlist-for-business.d.ts +79 -0
  168. package/dist/watchlist-for-business.esm.js +148 -0
  169. package/dist/watchlist.d.ts +62 -0
  170. package/dist/watchlist.esm.js +86 -0
  171. package/dist/watchlistServices-DMbUhkBX.esm.js +12 -0
  172. package/dist/workflow.d.ts +907 -0
  173. package/dist/workflow.esm.js +702 -0
  174. package/dist/{xstate.esm-B_rda9yU.esm.js → xstate.esm-B70JrNqo.esm.js} +144 -1
  175. package/package.json +203 -6
  176. package/dist/OpenViduLogger-BdPfiZO6.esm.js +0 -3
  177. package/dist/OpenViduLogger-CQyDxBvM.esm.js +0 -803
  178. package/dist/StateMachine-DRE1oH2B.d.ts +0 -2
  179. package/dist/addEvent-W0ORK0jT.esm.js +0 -16
  180. package/dist/endpoints-BSTFaHYo.esm.js +0 -1706
  181. package/dist/permissionServices-I6vX6DBy.esm.js +0 -72
  182. /package/dist/{Manager-BGfxEmyv.d.ts → Manager-C8PrhBOx.d.ts} +0 -0
  183. /package/dist/{chunk-C_Yo44FK.esm.js → chunk-CRF6K_H_.esm.js} +0 -0
  184. /package/dist/{types-iZi2rawo.d.ts → types-CAD4va6a.d.ts} +0 -0
@@ -0,0 +1,873 @@
1
+ import { r as getToken } from "./api-CESGtpbH.esm.js";
2
+ import { a as fromPromise, i as fromCallback, r as assign, t as setup } from "./xstate.esm-B70JrNqo.esm.js";
3
+ import { t as sleep } from "./ITimerCapability-C67ZRskg.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-Ig2UgbLv.esm.js";
5
+ import { n as requestPermission, t as checkPermission } from "./permissionServices-D_i6nzEw.esm.js";
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.
102
+ *
103
+ * Behavior depends on which capture path got us here:
104
+ *
105
+ * - **Auto-capture path**: the WASM `OnDeviceSelfiePipeline` has been
106
+ * consuming every video frame via `processFrame()` and aggregating
107
+ * results across them. When it picks a best-shot, the C++
108
+ * `OnDeviceSelfieWorkflow::createOnCaptureHandler` calls
109
+ * `WebApi::setFaceResults(...)` automatically — staging strong,
110
+ * aggregated `BestShotData` for the subsequent `postFaceResults` call.
111
+ * We must NOT call `processPhoto` here: `applyFaceResults` would
112
+ * overwrite that staged state with a weaker single-frame analysis of a
113
+ * post-capture snapshot (camera state has already changed: autocapture
114
+ * freeze, stream pause, post-detection latency), and the server then
115
+ * rejects the submission as "image quality too low".
116
+ *
117
+ * - **Manual-capture path**: the auto-capture timer expired without a
118
+ * successful best-shot, so the C++ pipeline has nothing staged. We
119
+ * need to run a single-frame analysis on the manually captured canvas
120
+ * via `processPhoto`, which itself calls
121
+ * `OnDeviceSelfieWorkflow::applyFaceResults` → `WebApi::setFaceResults`
122
+ * to stage results. Mirrors V1 (`packages/incode-welcome/src/camera/useSelfie.ts`)
123
+ * where `processPhoto` is only invoked from `handleManualCapture`.
124
+ *
125
+ * Returns sentinel values for `encryptedBase64Image` and `recordingId` so
126
+ * the existing FaceCaptureContext shape remains stable; downstream actors
127
+ * for the on-device path simply ignore them.
128
+ */
129
+ async function prepareOnDeviceFaceUpload(ctx) {
130
+ if (!ctx.capturedImage) throw new Error("On-device capture requires a captured image canvas");
131
+ if (!ctx.provider) throw new Error("On-device capture requires the FaceDetectionProvider to be initialized");
132
+ if (ctx.manualCaptureTriggered) {
133
+ await yieldUntilNextPaint();
134
+ await sleep(350);
135
+ ctx.provider.processPhoto(ctx.capturedImage.canvas);
136
+ }
137
+ return {
138
+ encryptedBase64Image: "",
139
+ recordingId: null
140
+ };
141
+ }
142
+ /**
143
+ * POSTs the staged on-device face-results JSON to `/omni/add/face-results`
144
+ * through the WASM `WebApi`. Used as the `uploadFace` actor body for both
145
+ * selfie and auth variants when on-device mode is enabled.
146
+ *
147
+ * The C++ `WebApi` handles `SessionEncryptor` encryption and the actual
148
+ * HTTP via the WASM `WebClient` — so callers don't need to thread the
149
+ * session-encryption details through JS.
150
+ */
151
+ async function postOnDeviceFaceResults(ctx, signal) {
152
+ const provider = ctx.provider;
153
+ if (!provider) throw new Error("On-device upload requires the FaceDetectionProvider to be initialized");
154
+ const sessionToken = getToken();
155
+ return await provider.postFaceResults({
156
+ headers: sessionToken ? { "X-Incode-Hardware-Id": sessionToken } : void 0,
157
+ timeout: 3e4
158
+ }) ?? {};
159
+ }
160
+
161
+ //#endregion
162
+ //#region src/internal/faceCapture/faceCaptureSetup.ts
163
+ const getAttemptsFromConfig = (config) => {
164
+ return config.captureAttempts ?? config.numberOfAttempts ?? 3;
165
+ };
166
+ const _faceCaptureMachine = setup({
167
+ types: {
168
+ context: {},
169
+ events: {},
170
+ input: {}
171
+ },
172
+ actors: {
173
+ checkPermission: fromPromise(async () => {
174
+ return checkPermission();
175
+ }),
176
+ requestPermission: fromPromise(async ({ input }) => {
177
+ return requestPermission({ requestMotion: input.requestMotionPermission });
178
+ }),
179
+ initializeCamera: fromPromise(async ({ input }) => {
180
+ return initializeCamera({
181
+ config: input.config,
182
+ deepsightService: input.deepsightService
183
+ });
184
+ }),
185
+ runDetection: fromCallback(({ input, sendBack }) => {
186
+ if (!input.frameCapturer || !input.provider) {
187
+ sendBack({
188
+ type: "DETECTION_UPDATE",
189
+ status: "error"
190
+ });
191
+ return () => {};
192
+ }
193
+ if (input.manualCaptureTriggered) {
194
+ sendBack({
195
+ type: "DETECTION_UPDATE",
196
+ status: "manualCapture"
197
+ });
198
+ return () => {};
199
+ }
200
+ const { cleanup, reset } = startDetection({
201
+ config: input.config,
202
+ capturer: input.frameCapturer,
203
+ onUpdate: (status) => sendBack({
204
+ type: "DETECTION_UPDATE",
205
+ status
206
+ }),
207
+ onFrame: (frame) => sendBack({
208
+ type: "DETECTION_FRAME",
209
+ frame
210
+ }),
211
+ onSuccess: (canvas, faceCoordinates) => sendBack({
212
+ type: "DETECTION_SUCCESS",
213
+ canvas,
214
+ faceCoordinates
215
+ }),
216
+ provider: input.provider
217
+ });
218
+ sendBack({
219
+ type: "DETECTION_RESET_READY",
220
+ reset
221
+ });
222
+ return cleanup;
223
+ }),
224
+ initializeDeepsightSession: fromPromise(async ({ input }) => {
225
+ return await initializeDeepsightSession({
226
+ ds: input.ds,
227
+ storage: input.storage
228
+ });
229
+ }),
230
+ startRecording: fromPromise(async ({ input }) => {
231
+ if (!input.stream) return input.recordingService;
232
+ const wasmUtil = await input.dependencies.getWasmUtil();
233
+ const sessionToken = getToken();
234
+ const service = input.recordingService ?? createRecordingService({
235
+ config: input.config,
236
+ wasmUtil,
237
+ sessionToken
238
+ });
239
+ if (service) await service.start(input.stream);
240
+ return service;
241
+ }),
242
+ checkVirtualCamera: fromPromise(async ({ input }) => {
243
+ if (!input.deepsightService || !input.stream) return false;
244
+ const videoTrack = input.stream.getVideoTracks()[0];
245
+ if (!videoTrack) return false;
246
+ return input.deepsightService.checkVirtualCamera(videoTrack);
247
+ }),
248
+ prepareFaceUpload: fromPromise(async () => {
249
+ throw new Error("prepareFaceUpload must be provided by variant");
250
+ }),
251
+ uploadFace: fromPromise(async () => {
252
+ throw new Error("uploadFace must be provided by variant");
253
+ }),
254
+ processFace: fromPromise(async () => {
255
+ throw new Error("processFace must be provided by variant");
256
+ })
257
+ },
258
+ actions: {
259
+ stopMediaStream: assign(({ context }) => {
260
+ context.frameCapturer?.dispose();
261
+ if (context.stream) stopStream(context.stream);
262
+ context.provider?.dispose();
263
+ return {
264
+ stream: void 0,
265
+ provider: void 0,
266
+ frameCapturer: void 0
267
+ };
268
+ }),
269
+ setStreamAndCapturer: assign({
270
+ stream: ({ event }) => {
271
+ if ("output" in event) return event.output.stream;
272
+ },
273
+ provider: ({ event }) => {
274
+ if ("output" in event) return event.output.provider;
275
+ },
276
+ frameCapturer: ({ event }) => {
277
+ if ("output" in event) return new StreamCanvasCapture(event.output.stream);
278
+ }
279
+ }),
280
+ trackTutorial: () => void 0,
281
+ trackContinue: () => {},
282
+ resetContext: assign(({ context }) => ({
283
+ stream: void 0,
284
+ provider: void 0,
285
+ frameCapturer: void 0,
286
+ error: void 0,
287
+ detectionStatus: "idle",
288
+ debugFrame: void 0,
289
+ capturedImage: void 0,
290
+ faceCoordinates: void 0,
291
+ uploadResponse: void 0,
292
+ processResponse: void 0,
293
+ recordingService: void 0,
294
+ attemptsRemaining: getAttemptsFromConfig(context.config),
295
+ uploadError: void 0,
296
+ permissionResult: void 0,
297
+ resetDetection: void 0,
298
+ deepsightService: void 0,
299
+ manualCaptureTriggered: false,
300
+ captureOnlyResult: void 0
301
+ })),
302
+ resetDetection: ({ context }) => {
303
+ context.resetDetection?.();
304
+ },
305
+ captureImage: assign({ capturedImage: ({ context }) => {
306
+ if (context.capturedImage) return context.capturedImage;
307
+ return context.frameCapturer?.getLatestCanvas() ?? void 0;
308
+ } }),
309
+ captureLatestFrame: assign({ capturedImage: ({ context }) => {
310
+ return context.frameCapturer?.getLatestCanvas() ?? void 0;
311
+ } }),
312
+ clearUploadFailure: assign({
313
+ uploadError: () => void 0,
314
+ detectionStatus: () => "idle",
315
+ capturedImage: () => void 0
316
+ }),
317
+ clearStreamForRetry: assign(({ context }) => {
318
+ context.frameCapturer?.dispose();
319
+ if (context.stream) stopStream(context.stream);
320
+ context.provider?.dispose();
321
+ return {
322
+ stream: void 0,
323
+ provider: void 0,
324
+ frameCapturer: void 0
325
+ };
326
+ }),
327
+ decrementAttemptsRemaining: assign(({ context }) => ({ attemptsRemaining: context.attemptsRemaining - 1 })),
328
+ setUploadErrorFromUploadValidation: assign({ uploadError: () => FACE_ERROR_CODES.SERVER }),
329
+ setTerminalError: assign({ error: () => "Authentication failed" }),
330
+ clearRecordingService: assign({ recordingService: () => void 0 }),
331
+ cleanup: ({ context }) => {
332
+ context.deepsightService?.cleanup();
333
+ context.recordingService?.cleanup();
334
+ },
335
+ setPermissionResultFromEvent: assign({ permissionResult: ({ event }) => event.output }),
336
+ setPermissionDenied: assign({ permissionResult: () => "denied" }),
337
+ setPermissionRefresh: assign({ permissionResult: () => "refresh" }),
338
+ setDeepsightServiceFromEvent: assign({ deepsightService: ({ event }) => event.output }),
339
+ setErrorFromEvent: assign({ error: ({ event }) => String(event.error) }),
340
+ setDetectionStatusDetecting: assign({ detectionStatus: ({ context }) => context.manualCaptureTriggered ? "manualCapture" : "detecting" }),
341
+ setRecordingServiceFromEvent: assign({ recordingService: ({ context, event }) => {
342
+ return event.output ?? context.recordingService;
343
+ } }),
344
+ setDetectionStatusFromEvent: assign({ detectionStatus: ({ event }) => event.status }),
345
+ setManualCaptureTriggered: assign({ manualCaptureTriggered: ({ context, event }) => {
346
+ const status = event.status;
347
+ return context.manualCaptureTriggered || status === "manualCapture";
348
+ } }),
349
+ setDebugFrameFromEvent: assign({ debugFrame: ({ event }) => event.frame }),
350
+ setResetDetectionFromEvent: assign({ resetDetection: ({ event }) => event.reset }),
351
+ setCapturedImageFromEvent: assign({
352
+ capturedImage: ({ event }) => event.canvas,
353
+ faceCoordinates: ({ event }) => event.faceCoordinates
354
+ }),
355
+ setUploadPreparationFromEvent: assign({
356
+ encryptedBase64Image: ({ event }) => event.output.encryptedBase64Image,
357
+ uploadRecordingId: ({ event }) => event.output.recordingId
358
+ }),
359
+ setUploadResponseFromEvent: assign({ uploadResponse: ({ event }) => event.output }),
360
+ setProcessResponseFromEvent: assign({ processResponse: ({ event }) => event.output }),
361
+ setServerErrorAndDecrement: assign(({ context }) => ({
362
+ uploadError: FACE_ERROR_CODES.SERVER,
363
+ attemptsRemaining: context.attemptsRemaining - 1
364
+ })),
365
+ sendLabelInspection: () => {
366
+ sendLabelInspectionEvent();
367
+ },
368
+ flagFaceManualReview: () => {
369
+ flagFaceManualReview();
370
+ },
371
+ preloadRecordingProvider: ({ context }) => {
372
+ if (context.config.enableFaceRecording === true && context.config.deepsightLiveness !== "VIDEOLIVENESS") preloadOpenViduProvider();
373
+ },
374
+ noOp: () => void 0
375
+ },
376
+ guards: {
377
+ hasShowTutorial: ({ context }) => context.config.showTutorial,
378
+ isPermissionGranted: ({ event }) => {
379
+ if ("output" in event) return event.output === "granted";
380
+ return false;
381
+ },
382
+ isPermissionDeniedError: ({ event }) => {
383
+ if ("error" in event) {
384
+ const error = event.error;
385
+ return error?.name === "NotAllowedError" || error?.name === "PermissionDeniedError";
386
+ }
387
+ return false;
388
+ },
389
+ hasStream: ({ context }) => context.stream !== void 0,
390
+ isCameraAndDeepsightReady: ({ context }) => context.stream !== void 0 && context.deepsightService !== void 0,
391
+ hasAttemptsRemaining: ({ context }) => context.attemptsRemaining > 0,
392
+ hasCapturedImage: ({ context }) => context.capturedImage !== void 0,
393
+ hasUploadValidationError: () => false,
394
+ isTerminalUploadError: () => false,
395
+ isNoAttemptsTerminal: () => false
396
+ }
397
+ }).createMachine({
398
+ id: "faceCapture",
399
+ initial: "idle",
400
+ context: ({ input }) => ({
401
+ config: input.config,
402
+ dependencies: input.dependencies,
403
+ authHint: input.authHint,
404
+ stream: void 0,
405
+ provider: void 0,
406
+ frameCapturer: void 0,
407
+ error: void 0,
408
+ detectionStatus: "idle",
409
+ debugFrame: void 0,
410
+ capturedImage: void 0,
411
+ faceCoordinates: void 0,
412
+ uploadResponse: void 0,
413
+ processResponse: void 0,
414
+ recordingService: void 0,
415
+ attemptsRemaining: getAttemptsFromConfig(input.config),
416
+ uploadError: void 0,
417
+ permissionResult: void 0,
418
+ resetDetection: void 0,
419
+ deepsightService: void 0,
420
+ encryptedBase64Image: void 0,
421
+ uploadRecordingId: void 0,
422
+ manualCaptureTriggered: false,
423
+ captureOnlyResult: void 0
424
+ }),
425
+ on: { QUIT: { target: "#faceCapture.closed" } },
426
+ states: {
427
+ idle: { on: { LOAD: [{
428
+ target: "tutorial",
429
+ guard: "hasShowTutorial"
430
+ }, { target: "loading" }] } },
431
+ loading: {
432
+ entry: "preloadRecordingProvider",
433
+ invoke: [{
434
+ id: "checkPermissionLoading",
435
+ src: "checkPermission",
436
+ onDone: [{
437
+ target: "capture",
438
+ guard: "isPermissionGranted",
439
+ actions: "setPermissionResultFromEvent"
440
+ }, {
441
+ target: "permissions",
442
+ actions: "setPermissionResultFromEvent"
443
+ }]
444
+ }, {
445
+ id: "loadingInitDeepsight",
446
+ src: "initializeDeepsightSession",
447
+ input: ({ context }) => ({
448
+ ds: context.config.ds,
449
+ storage: context.dependencies.storage
450
+ }),
451
+ onDone: { actions: "setDeepsightServiceFromEvent" },
452
+ onError: { actions: "noOp" }
453
+ }]
454
+ },
455
+ tutorial: {
456
+ initial: "checkingPermission",
457
+ entry: ["trackTutorial", "preloadRecordingProvider"],
458
+ states: {
459
+ checkingPermission: { invoke: {
460
+ id: "checkPermissionTutorial",
461
+ src: "checkPermission",
462
+ onDone: [{
463
+ target: "initializingCamera",
464
+ guard: "isPermissionGranted",
465
+ actions: "setPermissionResultFromEvent"
466
+ }, {
467
+ target: "ready",
468
+ actions: "setPermissionResultFromEvent"
469
+ }]
470
+ } },
471
+ initializingCamera: {
472
+ type: "parallel",
473
+ states: {
474
+ cameraInit: {
475
+ initial: "initializingDeepsight",
476
+ states: {
477
+ initializingDeepsight: { invoke: {
478
+ id: "tutorialInitDeepsight",
479
+ src: "initializeDeepsightSession",
480
+ input: ({ context }) => ({
481
+ ds: context.config.ds,
482
+ storage: context.dependencies.storage
483
+ }),
484
+ onDone: {
485
+ target: "initializingStream",
486
+ actions: "setDeepsightServiceFromEvent"
487
+ },
488
+ onError: { target: "#faceCapture.tutorial.ready" }
489
+ } },
490
+ initializingStream: { invoke: {
491
+ id: "tutorialInitCamera",
492
+ src: "initializeCamera",
493
+ input: ({ context }) => ({
494
+ config: context.config,
495
+ dependencies: context.dependencies,
496
+ deepsightService: context.deepsightService
497
+ }),
498
+ onDone: {
499
+ target: "ready",
500
+ actions: "setStreamAndCapturer"
501
+ },
502
+ onError: [{
503
+ target: "#faceCapture.tutorial.ready",
504
+ guard: "isPermissionDeniedError",
505
+ actions: "setPermissionDenied"
506
+ }, {
507
+ target: "#faceCapture.tutorial.ready",
508
+ actions: "setErrorFromEvent"
509
+ }]
510
+ } },
511
+ ready: { type: "final" }
512
+ }
513
+ },
514
+ userIntent: {
515
+ initial: "waiting",
516
+ states: {
517
+ waiting: { on: { NEXT_STEP: {
518
+ target: "clicked",
519
+ actions: "trackContinue"
520
+ } } },
521
+ clicked: { type: "final" }
522
+ }
523
+ }
524
+ },
525
+ onDone: { target: "#faceCapture.capture" }
526
+ },
527
+ ready: {
528
+ initial: "idle",
529
+ states: {
530
+ idle: { always: [{
531
+ target: "initializingDeepsight",
532
+ guard: ({ context }) => context.deepsightService === void 0
533
+ }, { target: "readyForNext" }] },
534
+ initializingDeepsight: { invoke: {
535
+ id: "initializeDeepsightTutorial",
536
+ src: "initializeDeepsightSession",
537
+ input: ({ context }) => ({
538
+ ds: context.config.ds,
539
+ storage: context.dependencies.storage
540
+ }),
541
+ onDone: {
542
+ target: "readyForNext",
543
+ actions: "setDeepsightServiceFromEvent"
544
+ },
545
+ onError: { target: "readyForNext" }
546
+ } },
547
+ readyForNext: { on: { NEXT_STEP: {
548
+ target: "#faceCapture.tutorial.waitingForPermission",
549
+ actions: "trackContinue"
550
+ } } }
551
+ }
552
+ },
553
+ waitingForPermission: { invoke: {
554
+ id: "checkPermissionWaiting",
555
+ src: "checkPermission",
556
+ onDone: [{
557
+ target: "#faceCapture.capture",
558
+ guard: "isPermissionGranted",
559
+ actions: "setPermissionResultFromEvent"
560
+ }, {
561
+ target: "#faceCapture.permissions",
562
+ actions: "setPermissionResultFromEvent"
563
+ }]
564
+ } }
565
+ }
566
+ },
567
+ permissions: {
568
+ entry: "preloadRecordingProvider",
569
+ initial: "checkingDeepsight",
570
+ states: {
571
+ checkingDeepsight: { always: [{
572
+ target: "initializingDeepsight",
573
+ guard: ({ context }) => context.deepsightService === void 0
574
+ }, { target: "idle" }] },
575
+ initializingDeepsight: { invoke: {
576
+ id: "initializeDeepsightPerms",
577
+ src: "initializeDeepsightSession",
578
+ input: ({ context }) => ({
579
+ ds: context.config.ds,
580
+ storage: context.dependencies.storage
581
+ }),
582
+ onDone: {
583
+ target: "idle",
584
+ actions: "setDeepsightServiceFromEvent"
585
+ },
586
+ onError: { target: "idle" }
587
+ } },
588
+ idle: {
589
+ invoke: {
590
+ id: "checkPermissionIdle",
591
+ src: "checkPermission",
592
+ onDone: [{
593
+ target: "#faceCapture.capture",
594
+ guard: "isPermissionGranted",
595
+ actions: "setPermissionResultFromEvent"
596
+ }, {
597
+ target: "denied",
598
+ guard: ({ event }) => event.output === "denied",
599
+ actions: "setPermissionResultFromEvent"
600
+ }]
601
+ },
602
+ on: {
603
+ REQUEST_PERMISSION: "requesting",
604
+ GO_TO_LEARN_MORE: "learnMore"
605
+ }
606
+ },
607
+ learnMore: { on: {
608
+ BACK: "idle",
609
+ REQUEST_PERMISSION: "requesting"
610
+ } },
611
+ requesting: { invoke: {
612
+ id: "requestPermission",
613
+ src: "requestPermission",
614
+ input: ({ context }) => ({ requestMotionPermission: context.config.ds === true }),
615
+ onDone: [
616
+ {
617
+ target: "#faceCapture.capture",
618
+ guard: "isPermissionGranted",
619
+ actions: "setPermissionResultFromEvent"
620
+ },
621
+ {
622
+ target: "denied",
623
+ guard: ({ event }) => event.output === "denied",
624
+ actions: "setPermissionResultFromEvent"
625
+ },
626
+ {
627
+ target: "idle",
628
+ actions: "setPermissionResultFromEvent"
629
+ }
630
+ ],
631
+ onError: { target: "denied" }
632
+ } },
633
+ denied: { entry: "setPermissionRefresh" }
634
+ }
635
+ },
636
+ capture: {
637
+ entry: "preloadRecordingProvider",
638
+ initial: "checkingDeepsight",
639
+ exit: [
640
+ "stopMediaStream",
641
+ "cleanup",
642
+ "clearRecordingService"
643
+ ],
644
+ states: {
645
+ checkingDeepsight: { always: [{
646
+ target: "initializingDeepsight",
647
+ guard: ({ context }) => context.deepsightService === void 0
648
+ }, { target: "checkingStream" }] },
649
+ initializingDeepsight: { invoke: {
650
+ id: "initializeDeepsightCapture",
651
+ src: "initializeDeepsightSession",
652
+ input: ({ context }) => ({
653
+ ds: context.config.ds,
654
+ storage: context.dependencies.storage
655
+ }),
656
+ onDone: {
657
+ target: "checkingStream",
658
+ actions: ["setDeepsightServiceFromEvent"]
659
+ },
660
+ onError: { target: "#faceCapture.permissions" }
661
+ } },
662
+ checkingStream: { always: [
663
+ {
664
+ target: "initializingDeepsight",
665
+ guard: ({ context }) => context.deepsightService === void 0
666
+ },
667
+ {
668
+ target: "detecting",
669
+ guard: "hasStream"
670
+ },
671
+ { target: "initializing" }
672
+ ] },
673
+ initializing: { invoke: {
674
+ id: "initializeCamera",
675
+ src: "initializeCamera",
676
+ input: ({ context }) => ({
677
+ config: context.config,
678
+ dependencies: context.dependencies,
679
+ deepsightService: context.deepsightService
680
+ }),
681
+ onDone: {
682
+ target: "detecting",
683
+ actions: ["setStreamAndCapturer"]
684
+ },
685
+ onError: [{
686
+ target: "#faceCapture.permissions",
687
+ guard: "isPermissionDeniedError",
688
+ actions: "setPermissionDenied"
689
+ }, {
690
+ target: "#faceCapture.error",
691
+ actions: "setErrorFromEvent"
692
+ }]
693
+ } },
694
+ detecting: {
695
+ entry: ["setDetectionStatusDetecting"],
696
+ invoke: [
697
+ {
698
+ id: "checkVirtualCamera",
699
+ src: "checkVirtualCamera",
700
+ input: ({ context }) => ({
701
+ stream: context.stream,
702
+ deepsightService: context.deepsightService
703
+ }),
704
+ onDone: [{
705
+ target: "#faceCapture.processing",
706
+ guard: ({ event }) => event.output === true,
707
+ actions: "sendLabelInspection"
708
+ }],
709
+ onError: { actions: "noOp" }
710
+ },
711
+ {
712
+ id: "startRecording",
713
+ src: "startRecording",
714
+ input: ({ context }) => ({
715
+ config: context.config,
716
+ dependencies: context.dependencies,
717
+ recordingService: context.recordingService,
718
+ stream: context.stream
719
+ }),
720
+ onDone: { actions: "setRecordingServiceFromEvent" },
721
+ onError: { actions: "noOp" }
722
+ },
723
+ {
724
+ id: "runDetection",
725
+ src: "runDetection",
726
+ input: ({ context }) => ({
727
+ frameCapturer: context.frameCapturer,
728
+ provider: context.provider,
729
+ config: context.config,
730
+ manualCaptureTriggered: context.manualCaptureTriggered
731
+ })
732
+ }
733
+ ],
734
+ on: {
735
+ DETECTION_UPDATE: { actions: ["setDetectionStatusFromEvent", "setManualCaptureTriggered"] },
736
+ DETECTION_FRAME: { actions: "setDebugFrameFromEvent" },
737
+ DETECTION_RESET_READY: { actions: "setResetDetectionFromEvent" },
738
+ DETECTION_SUCCESS: {
739
+ target: "capturing",
740
+ actions: "setCapturedImageFromEvent"
741
+ },
742
+ MANUAL_CAPTURE: { target: "capturingManual" }
743
+ }
744
+ },
745
+ capturing: {
746
+ entry: ["captureImage"],
747
+ always: [{
748
+ target: "preparingUpload",
749
+ guard: "hasCapturedImage"
750
+ }, {
751
+ target: "uploadError",
752
+ actions: "setServerErrorAndDecrement"
753
+ }]
754
+ },
755
+ capturingManual: {
756
+ entry: ["captureLatestFrame"],
757
+ always: [{
758
+ target: "preparingUpload",
759
+ guard: "hasCapturedImage"
760
+ }, {
761
+ target: "uploadError",
762
+ actions: "setServerErrorAndDecrement"
763
+ }]
764
+ },
765
+ preparingUpload: { invoke: {
766
+ id: "prepareFaceUpload",
767
+ src: "prepareFaceUpload",
768
+ input: ({ context }) => context,
769
+ onDone: {
770
+ target: "uploading",
771
+ actions: "setUploadPreparationFromEvent"
772
+ },
773
+ onError: {
774
+ target: "uploadError",
775
+ actions: "setServerErrorAndDecrement"
776
+ }
777
+ } },
778
+ uploading: { invoke: {
779
+ id: "uploadFace",
780
+ src: "uploadFace",
781
+ input: ({ context }) => context,
782
+ onDone: {
783
+ target: "validatingUpload",
784
+ actions: "setUploadResponseFromEvent"
785
+ },
786
+ onError: {
787
+ target: "uploadError",
788
+ actions: "setServerErrorAndDecrement"
789
+ }
790
+ } },
791
+ validatingUpload: { always: [
792
+ {
793
+ target: "#faceCapture.error",
794
+ guard: "isTerminalUploadError",
795
+ actions: "setTerminalError"
796
+ },
797
+ {
798
+ target: "uploadError",
799
+ guard: "hasUploadValidationError",
800
+ actions: ["setUploadErrorFromUploadValidation", "decrementAttemptsRemaining"]
801
+ },
802
+ { target: "success" }
803
+ ] },
804
+ uploadError: { on: { RETRY_CAPTURE: [
805
+ {
806
+ target: "checkingStream",
807
+ guard: "hasAttemptsRemaining",
808
+ actions: [
809
+ "resetDetection",
810
+ "clearUploadFailure",
811
+ "clearStreamForRetry"
812
+ ]
813
+ },
814
+ {
815
+ target: "#faceCapture.error",
816
+ guard: "isNoAttemptsTerminal",
817
+ actions: ["setTerminalError"]
818
+ },
819
+ {
820
+ target: "#faceCapture.terminalProcessing",
821
+ actions: ["flagFaceManualReview"]
822
+ }
823
+ ] } },
824
+ success: {
825
+ entry: "cleanup",
826
+ after: { 3e3: { target: "#faceCapture.processing" } }
827
+ }
828
+ }
829
+ },
830
+ processing: { invoke: {
831
+ id: "processFace",
832
+ src: "processFace",
833
+ input: ({ context }) => context,
834
+ onDone: {
835
+ target: "finished",
836
+ actions: "setProcessResponseFromEvent"
837
+ },
838
+ onError: { target: "finished" }
839
+ } },
840
+ terminalProcessing: {
841
+ entry: "cleanup",
842
+ invoke: {
843
+ id: "processFace",
844
+ src: "processFace",
845
+ input: ({ context }) => context,
846
+ onDone: {
847
+ target: "finished",
848
+ actions: "setProcessResponseFromEvent"
849
+ },
850
+ onError: { target: "finished" }
851
+ }
852
+ },
853
+ finished: {
854
+ entry: "stopMediaStream",
855
+ type: "final"
856
+ },
857
+ closed: {
858
+ entry: "stopMediaStream",
859
+ type: "final"
860
+ },
861
+ error: {
862
+ entry: "stopMediaStream",
863
+ on: { RESET: {
864
+ target: "idle",
865
+ actions: "resetContext"
866
+ } }
867
+ }
868
+ }
869
+ });
870
+ const faceCaptureMachine = _faceCaptureMachine;
871
+
872
+ //#endregion
873
+ export { prepareOnDeviceFaceUpload as a, postOnDeviceFaceResults as i, defaultPrepareFaceUpload as n, isOnDeviceMode as r, faceCaptureMachine as t };