@incodetech/core 2.0.1 → 2.1.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 (218) hide show
  1. package/dist/{BrowserStorageProvider-CuOW1Er2.esm.js → BrowserStorageProvider-BpJM-gIl.esm.js} +8 -1
  2. package/dist/{IpifyProvider-D7jx52AL.esm.js → IpifyProvider-D4LWD15E.esm.js} +28 -0
  3. package/dist/{MotionSensorProvider-4v7xkqAp.esm.js → MotionSensorProvider-Bx7Mpzt0.esm.js} +63 -13
  4. package/dist/{OpenViduRecordingProvider-CMu6XVdc.esm.js → OpenViduRecordingProvider-O4GjBseO.esm.js} +1 -1
  5. package/dist/StateMachine-BC_nGvrc.d.ts +2 -0
  6. package/dist/StreamCanvasCapture-ImiDQdVA.esm.js +118 -0
  7. package/dist/StreamCanvasCapture-yyl20qd9.d.ts +152 -0
  8. package/dist/{BaseWasmProvider-C_DLEI40.esm.js → WasmUtilProvider-CiEN7Gjn.esm.js} +183 -11
  9. package/dist/{addressSearch-BpTbTWCa.esm.js → addressSearch-DvmWXKZg.esm.js} +63 -57
  10. package/dist/{ae-signature-DDDZmWXj.esm.js → ae-signature-BFZta3TZ.esm.js} +1 -1
  11. package/dist/ae-signature.d.ts +3 -3
  12. package/dist/ae-signature.esm.js +6 -5
  13. package/dist/antifraud.d.ts +5 -46
  14. package/dist/antifraud.esm.js +6 -43
  15. package/dist/antifraudManager-CkV4u-LE.esm.js +55 -0
  16. package/dist/antifraudManager-CznnhyvD.d.ts +63 -0
  17. package/dist/{antifraudStateMachine-O0TMf6yc.esm.js → antifraudStateMachine-Ccrb-Jxc.esm.js} +2 -2
  18. package/dist/apiError-B-j-gyDx.esm.js +51 -0
  19. package/dist/authentication.d.ts +13 -11
  20. package/dist/authentication.esm.js +26 -22
  21. package/dist/{authenticationManager-C83GNIhl.d.ts → authenticationManager-CIVY80H9.d.ts} +4 -4
  22. package/dist/{authenticationManager-5M-fKzXx.esm.js → authenticationManager-ZNotsWnC.esm.js} +6 -6
  23. package/dist/{authenticationStateMachine-BMZqatiF.esm.js → authenticationStateMachine-DksVbF_H.esm.js} +21 -9
  24. package/dist/{backCameraStream-DMdMeGk2.esm.js → backCameraStream-D7Wo4Nbx.esm.js} +95 -7
  25. package/dist/{session-CrkWAs-q.esm.js → browserSimulation-B1dWiXp7.esm.js} +61 -476
  26. package/dist/camera.d.ts +4 -3
  27. package/dist/camera.esm.js +4 -3
  28. package/dist/canvas-SKcRBxsk.esm.js +230 -0
  29. package/dist/consent.d.ts +4 -398
  30. package/dist/consent.esm.js +6 -77
  31. package/dist/consentManager-BLd51QiW.d.ts +419 -0
  32. package/dist/consentManager-BYo9Nu1r.esm.js +90 -0
  33. package/dist/{consentStateMachine-CCT-B60O.esm.js → consentStateMachine-BG3yL8aC.esm.js} +9 -6
  34. package/dist/cpf-ocr.d.ts +4 -199
  35. package/dist/cpf-ocr.esm.js +8 -177
  36. package/dist/cpfOcrManager-BnieFXuG.d.ts +216 -0
  37. package/dist/cpfOcrManager-sSKegxox.esm.js +190 -0
  38. package/dist/cross-document-data-match.d.ts +1 -1
  39. package/dist/cross-document-data-match.esm.js +4 -4
  40. package/dist/curp-validation.d.ts +8 -158
  41. package/dist/curp-validation.esm.js +6 -108
  42. package/dist/curpValidationManager-CFem6zP9.esm.js +122 -0
  43. package/dist/curpValidationManager-RttixpIc.d.ts +184 -0
  44. package/dist/{curpValidationStateMachine-CitWLr2c.esm.js → curpValidationStateMachine-B7V_qp66.esm.js} +20 -13
  45. package/dist/custom-fields.d.ts +2 -2
  46. package/dist/custom-fields.esm.js +4 -4
  47. package/dist/custom-watchlist.d.ts +1 -1
  48. package/dist/custom-watchlist.esm.js +4 -41
  49. package/dist/customWatchlistStateMachine-HmFybXLX.esm.js +50 -0
  50. package/dist/{deepsightLoader-Cm4JIT_z.esm.js → deepsightLoader-65k1Appi.esm.js} +19 -10
  51. package/dist/{deepsightService-CEVxzehb.d.ts → deepsightService-B7ShOkWL.d.ts} +8 -160
  52. package/dist/deepsightService-CrHmvx8X.esm.js +276 -0
  53. package/dist/device.esm.js +4 -3
  54. package/dist/document-capture.d.ts +995 -86
  55. package/dist/document-capture.esm.js +34 -8
  56. package/dist/document-upload.d.ts +47 -47
  57. package/dist/document-upload.esm.js +7 -7
  58. package/dist/{documentCaptureStateMachine-BqzTDy9k.esm.js → documentCaptureStateMachine-WYV1r9le.esm.js} +90 -6
  59. package/dist/dynamic-forms.d.ts +20 -5
  60. package/dist/dynamic-forms.esm.js +150 -61
  61. package/dist/ekyb.d.ts +32 -13
  62. package/dist/ekyb.esm.js +25 -15
  63. package/dist/{ekybStateMachine-CyMx_kg-.esm.js → ekybStateMachine-aYixw2sL.esm.js} +319 -207
  64. package/dist/ekyc.d.ts +10 -78
  65. package/dist/ekyc.esm.js +17 -12
  66. package/dist/{ekycStateMachine-oeO0Iekd.esm.js → ekycStateMachine-CXbpaJJn.esm.js} +201 -113
  67. package/dist/electronic-signature.d.ts +3 -3
  68. package/dist/electronic-signature.esm.js +5 -4
  69. package/dist/{electronicSignatureManager-D9OHzTpG.esm.js → electronicSignatureManager-BaECdJ1u.esm.js} +91 -23
  70. package/dist/email.d.ts +4 -3
  71. package/dist/email.esm.js +6 -5
  72. package/dist/{emailManager-wAV0LE-H.esm.js → emailManager--D5G3ChB.esm.js} +30 -7
  73. package/dist/{emailManager-DIfnS5g1.d.ts → emailManager-lAzDoQOs.d.ts} +66 -8
  74. package/dist/{emailStateMachine-DOf4j58N.esm.js → emailStateMachine-CxTOMAjC.esm.js} +46 -11
  75. package/dist/{endpoints-CnN3SyDa.esm.js → endpoints-BeTK0Mlt.esm.js} +6 -3
  76. package/dist/{events-D6-e4vok.esm.js → events-Dvvriq9l.esm.js} +3 -1
  77. package/dist/events.d.ts +2 -0
  78. package/dist/events.esm.js +1 -1
  79. package/dist/extensibility.d.ts +32 -16
  80. package/dist/extensibility.esm.js +55 -33
  81. package/dist/face-match.d.ts +32 -2
  82. package/dist/face-match.esm.js +5 -5
  83. package/dist/{faceCaptureManagerFactory-yqtpxjnN.d.ts → faceCaptureManagerFactory-C_hRHx8a.d.ts} +35 -11
  84. package/dist/{faceCaptureManagerFactory-Dh2PdGlF.esm.js → faceCaptureManagerFactory-kqbUqtrr.esm.js} +21 -5
  85. package/dist/{faceCaptureSetup-B3faSpYA.esm.js → faceCaptureSetup-CtvHWd3x.esm.js} +68 -183
  86. package/dist/{faceMatchStateMachine-DNFrxTFS.esm.js → faceMatchStateMachine-DdGXUBnx.esm.js} +60 -6
  87. package/dist/field-comparison.d.ts +4 -0
  88. package/dist/field-comparison.esm.js +7 -0
  89. package/dist/fieldComparisonManager-Bu5TaSr3.d.ts +76 -0
  90. package/dist/fieldComparisonManager-COGI2ARD.esm.js +162 -0
  91. package/dist/fiscal-qr.d.ts +59 -0
  92. package/dist/fiscal-qr.esm.js +323 -0
  93. package/dist/flow-events.d.ts +6 -5
  94. package/dist/flow.d.ts +23 -15
  95. package/dist/flow.esm.js +63 -17
  96. package/dist/flowCompletionService-BdR2cGgB.d.ts +19 -0
  97. package/dist/flowCompletionService-DdGojV9K.esm.js +20 -0
  98. package/dist/{flowServices-PiNsxLfK.esm.js → flowServices-BTuHLHVr.esm.js} +10 -5
  99. package/dist/geolocation.d.ts +4 -4
  100. package/dist/geolocation.esm.js +6 -6
  101. package/dist/{geolocationStateMachine-asasuHY2.esm.js → geolocationStateMachine-Dvh7X0wF.esm.js} +5 -5
  102. package/dist/getBrowser-C8DP7oTB.esm.js +8 -0
  103. package/dist/{getBrowser-BSXUTWXw.esm.js → getDeviceClass-C0olyNFS.esm.js} +1 -8
  104. package/dist/{getDeviceClass-BSntT9_j.esm.js → getDeviceClass-C8Do2qYu.esm.js} +1 -1
  105. package/dist/government-validation.d.ts +28 -8
  106. package/dist/government-validation.esm.js +19 -8
  107. package/dist/{governmentValidationStateMachine-BDDYrJTo.esm.js → governmentValidationStateMachine-DcJ-BfsC.esm.js} +35 -77
  108. package/dist/home.d.ts +15 -14
  109. package/dist/home.esm.js +2 -2
  110. package/dist/http-Cai3IoLS.esm.js +0 -0
  111. package/dist/http.esm.js +1 -0
  112. package/dist/id-ocr.d.ts +54 -54
  113. package/dist/id-ocr.esm.js +5 -5
  114. package/dist/id-verification.d.ts +27 -27
  115. package/dist/id-verification.esm.js +4 -4
  116. package/dist/id.d.ts +12 -10
  117. package/dist/id.esm.js +36 -26
  118. package/dist/{idCaptureManager-Fyd0eam-.d.ts → idCaptureManager-D-QYESvF.d.ts} +28 -14
  119. package/dist/{idCaptureManager-D0ktk7Hh.esm.js → idCaptureManager-DGVv5l1_.esm.js} +22 -7
  120. package/dist/{idCaptureStateMachine-dwlBUjbC.esm.js → idCaptureStateMachine-DHi7HydI.esm.js} +172 -123
  121. package/dist/{idOcrStateMachine-YbjjC_Gg.esm.js → idOcrStateMachine-CDQ5d_VM.esm.js} +4 -4
  122. package/dist/{idVerificationStateMachine-xbw9HP1Z.esm.js → idVerificationStateMachine-kRxwImzO.esm.js} +2 -2
  123. package/dist/identity-reuse.d.ts +4 -530
  124. package/dist/identity-reuse.esm.js +8 -274
  125. package/dist/identityReuseManager-C6n_97dw.esm.js +95 -0
  126. package/dist/identityReuseManager-DwLtVzUn.d.ts +428 -0
  127. package/dist/identityReuseStateMachine-BfE5YiEr.esm.js +148 -0
  128. package/dist/{index-BcRG8rtJ.d.ts → index-B5hPA0Bg.d.ts} +2 -2
  129. package/dist/{index-ChHWNH48.d.ts → index-B9NysVDB.d.ts} +469 -195
  130. package/dist/index.d.ts +2 -2
  131. package/dist/index.esm.js +10 -8
  132. package/dist/{invokeOnCaptureCallback-rc6kBHo5.esm.js → invokeOnCaptureCallback-ygByVdnn.esm.js} +1 -1
  133. package/dist/{lib-BB0B_qQX.esm.js → lib-BY67lgbq.esm.js} +1 -1
  134. package/dist/mandatory-consent.d.ts +8 -412
  135. package/dist/mandatory-consent.esm.js +6 -76
  136. package/dist/mandatoryConsentManager-H6D18cZB.esm.js +89 -0
  137. package/dist/mandatoryConsentManager-KfIlURRY.d.ts +429 -0
  138. package/dist/{mandatoryConsentStateMachine-Cnco1jvn.esm.js → mandatoryConsentStateMachine-DtQNW1ji.esm.js} +6 -6
  139. package/dist/openviduLazy-B8L--0oe.esm.js +3 -0
  140. package/dist/{openviduLazy-Cok70ZSg.esm.js → openviduLazy-Dh14JNJc.esm.js} +2 -2
  141. package/dist/otp-CGMdUzBC.esm.js +33 -0
  142. package/dist/otp-DF5A0sFx.d.ts +8 -0
  143. package/dist/permissionGuards-C1ispV96.esm.js +23 -0
  144. package/dist/permissionServices-CG3bMSfG.esm.js +130 -0
  145. package/dist/phone.d.ts +4 -3
  146. package/dist/phone.esm.js +6 -5
  147. package/dist/{phoneManager-DAJbGhlY.esm.js → phoneManager-BmF-0Ez4.esm.js} +30 -7
  148. package/dist/{phoneManager-B6M30hKE.d.ts → phoneManager-fPmIBYQK.d.ts} +65 -7
  149. package/dist/{phoneStateMachine-CuPARRaT.esm.js → phoneStateMachine-BiV0yoEx.esm.js} +46 -11
  150. package/dist/{qe-signature-DFo_Cc-I.esm.js → qe-signature-CUYPcHVo.esm.js} +1 -1
  151. package/dist/qe-signature.d.ts +3 -3
  152. package/dist/qe-signature.esm.js +6 -5
  153. package/dist/{recordingService-Ig2UgbLv.esm.js → recordingService-Bn9EdCmz.esm.js} +197 -179
  154. package/dist/redirect-to-mobile.d.ts +6 -104
  155. package/dist/redirect-to-mobile.esm.js +6 -99
  156. package/dist/redirectToMobileManager-BNe3IzC_.d.ts +178 -0
  157. package/dist/redirectToMobileManager-Dy3t7o0C.esm.js +159 -0
  158. package/dist/{redirectToMobileStateMachine-BOEqe46A.esm.js → redirectToMobileStateMachine-DyAdRxfP.esm.js} +28 -19
  159. package/dist/{runChildModule-CqqwqAkW.esm.js → runChildModule-CuoHZ1cx.esm.js} +35 -3
  160. package/dist/selfie.d.ts +13 -11
  161. package/dist/selfie.esm.js +27 -23
  162. package/dist/{selfieManager-Duisl7qN.esm.js → selfieManager-BjCoKRy0.esm.js} +6 -6
  163. package/dist/{selfieManager-D0lSgd-J.d.ts → selfieManager-dUbKRzOh.d.ts} +4 -4
  164. package/dist/{selfieStateMachine-D76whWEf.esm.js → selfieStateMachine-b4F2q9zw.esm.js} +5 -3
  165. package/dist/session-DoVb-OcB.esm.js +152 -0
  166. package/dist/session.d.ts +37 -5
  167. package/dist/session.esm.js +12 -7
  168. package/dist/sessionInitializer-B8H5MsXM.esm.js +366 -0
  169. package/dist/{setup-C5AITV8m.d.ts → setup-BbkprdVv.d.ts} +57 -6
  170. package/dist/{setup-DPPAxmXf.esm.js → setup-BqEfrdja.esm.js} +162 -24
  171. package/dist/signature.d.ts +2 -2
  172. package/dist/signature.esm.js +4 -4
  173. package/dist/{signatureStateMachine-B5-QVUve.esm.js → signatureStateMachine-C5qqYLRz.esm.js} +3 -3
  174. package/dist/stats-BMNUG1AU.esm.js +41 -0
  175. package/dist/stats.d.ts +13 -2
  176. package/dist/stats.esm.js +3 -2
  177. package/dist/trust-graph.d.ts +33 -4
  178. package/dist/trust-graph.esm.js +21 -15
  179. package/dist/{types-CFV9G_7j.d.ts → types-Bj9hdFjU.d.ts} +1 -1
  180. package/dist/{types-BP1m8VRw.d.ts → types-DOUhndhT.d.ts} +14 -2
  181. package/dist/types-DsnEVMhr.esm.js +34 -0
  182. package/dist/types-DvGZI7BF.d.ts +131 -0
  183. package/dist/{types-B06Ypu2F.d.ts → types-NuT8ftBV.d.ts} +1 -1
  184. package/dist/types-ya0LN_MX.d.ts +5 -0
  185. package/dist/{warmup-CEcppFiS.d.ts → warmup-Dg8Lh-50.d.ts} +8 -0
  186. package/dist/wasm.d.ts +6 -4
  187. package/dist/wasm.esm.js +11 -9
  188. package/dist/watchlist-for-business.d.ts +1 -1
  189. package/dist/watchlist-for-business.esm.js +5 -73
  190. package/dist/watchlist.d.ts +1 -1
  191. package/dist/watchlist.esm.js +4 -41
  192. package/dist/watchlistForBusinessStateMachine-DMl8j2Ov.esm.js +74 -0
  193. package/dist/watchlistStateMachine-DmQlqI6L.esm.js +50 -0
  194. package/dist/workflow.d.ts +150 -97
  195. package/dist/workflow.esm.js +156 -80
  196. package/package.json +19 -1
  197. package/dist/StateMachine-BCQrZJhf.d.ts +0 -2
  198. package/dist/WasmUtilProvider-j98OJf-S.esm.js +0 -114
  199. package/dist/browserSimulation-gxD8cSpM.esm.js +0 -20
  200. package/dist/deepsightService-O74l4Y__.esm.js +0 -489
  201. package/dist/displayErrors-DqJ_IbsG.d.ts +0 -39
  202. package/dist/flowCompletionService-DhkT4SRY.d.ts +0 -10
  203. package/dist/flowCompletionService-P54yzGvA.esm.js +0 -13
  204. package/dist/openviduLazy-Cm0XFh_v.esm.js +0 -3
  205. package/dist/permissionServices-D_i6nzEw.esm.js +0 -50
  206. package/dist/stats-CIfiPzb1.esm.js +0 -16
  207. package/dist/types-CAD4va6a.d.ts +0 -5
  208. package/dist/watchlistServices-DMbUhkBX.esm.js +0 -12
  209. /package/dist/{Actor-CI32dTbG.d.ts → Actor-Y0_Fj-KL.d.ts} +0 -0
  210. /package/dist/{ITimerCapability-C67ZRskg.esm.js → ITimerCapability-CB0I1Uf2.esm.js} +0 -0
  211. /package/dist/{Manager-C8PrhBOx.d.ts → Manager-BHn8wH8K.d.ts} +0 -0
  212. /package/dist/{camera-PA2Ljri3.esm.js → camera-DJWm3V4g.esm.js} +0 -0
  213. /package/dist/{camera-DBSxa6ML.d.ts → camera-SRBpPq2X.d.ts} +0 -0
  214. /package/dist/{chunk-CRF6K_H_.esm.js → chunk-CMUKZ2uL.esm.js} +0 -0
  215. /package/dist/{cpf-PPz2Njto.esm.js → cpf-BRzggV8G.esm.js} +0 -0
  216. /package/dist/{dateUtils-UoN5xswP.esm.js → dateUtils-AksLQmgV.esm.js} +0 -0
  217. /package/dist/{platform-CfrjKhmi.esm.js → platform-SKvEfCBh.esm.js} +0 -0
  218. /package/dist/{xstate.esm-B70JrNqo.esm.js → xstate.esm-C9wncMQa.esm.js} +0 -0
@@ -1,164 +1,11 @@
1
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";
2
+ import { a as fromPromise, i as fromCallback, r as assign, t as setup } from "./xstate.esm-C9wncMQa.esm.js";
3
+ import { n as invokeRequestPermissionActor, t as checkPermission } from "./permissionServices-CG3bMSfG.esm.js";
4
+ import { d as sendLabelInspectionEvent, f as startDetection, l as initializeCamera, n as preloadOpenViduProvider, p as stopStream, r as flagFaceManualReview, t as createRecordingService, u as initializeDeepsightSession } from "./recordingService-Bn9EdCmz.esm.js";
5
+ import { t as FACE_ERROR_CODES } from "./types-DsnEVMhr.esm.js";
6
+ import { t as StreamCanvasCapture } from "./StreamCanvasCapture-ImiDQdVA.esm.js";
7
+ import { n as needsMotionPrimeOnlyFromPermission, r as resolveStoredPermissionResult, t as isReadyForCaptureFromPermission } from "./permissionGuards-C1ispV96.esm.js";
6
8
 
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
9
  //#region src/internal/faceCapture/faceCaptureSetup.ts
163
10
  const getAttemptsFromConfig = (config) => {
164
11
  return config.captureAttempts ?? config.numberOfAttempts ?? 3;
@@ -174,7 +21,7 @@ const _faceCaptureMachine = setup({
174
21
  return checkPermission();
175
22
  }),
176
23
  requestPermission: fromPromise(async ({ input }) => {
177
- return requestPermission({ requestMotion: input.requestMotionPermission });
24
+ return invokeRequestPermissionActor(input);
178
25
  }),
179
26
  initializeCamera: fromPromise(async ({ input }) => {
180
27
  return initializeCamera({
@@ -379,6 +226,12 @@ const _faceCaptureMachine = setup({
379
226
  if ("output" in event) return event.output === "granted";
380
227
  return false;
381
228
  },
229
+ isReadyForCapture: ({ context, event }) => {
230
+ return isReadyForCaptureFromPermission(resolveStoredPermissionResult("output" in event ? event.output : void 0, context.permissionResult), context.config.ds);
231
+ },
232
+ needsMotionPrimeOnly: ({ context, event }) => {
233
+ return needsMotionPrimeOnlyFromPermission(resolveStoredPermissionResult("output" in event ? event.output : void 0, context.permissionResult), context.config.ds);
234
+ },
382
235
  isPermissionDeniedError: ({ event }) => {
383
236
  if ("error" in event) {
384
237
  const error = event.error;
@@ -435,7 +288,7 @@ const _faceCaptureMachine = setup({
435
288
  src: "checkPermission",
436
289
  onDone: [{
437
290
  target: "capture",
438
- guard: "isPermissionGranted",
291
+ guard: "isReadyForCapture",
439
292
  actions: "setPermissionResultFromEvent"
440
293
  }, {
441
294
  target: "permissions",
@@ -461,7 +314,7 @@ const _faceCaptureMachine = setup({
461
314
  src: "checkPermission",
462
315
  onDone: [{
463
316
  target: "initializingCamera",
464
- guard: "isPermissionGranted",
317
+ guard: "isReadyForCapture",
465
318
  actions: "setPermissionResultFromEvent"
466
319
  }, {
467
320
  target: "ready",
@@ -553,14 +406,22 @@ const _faceCaptureMachine = setup({
553
406
  waitingForPermission: { invoke: {
554
407
  id: "checkPermissionWaiting",
555
408
  src: "checkPermission",
556
- onDone: [{
557
- target: "#faceCapture.capture",
558
- guard: "isPermissionGranted",
559
- actions: "setPermissionResultFromEvent"
560
- }, {
561
- target: "#faceCapture.permissions",
562
- actions: "setPermissionResultFromEvent"
563
- }]
409
+ onDone: [
410
+ {
411
+ target: "#faceCapture.capture",
412
+ guard: "isReadyForCapture",
413
+ actions: "setPermissionResultFromEvent"
414
+ },
415
+ {
416
+ target: "#faceCapture.permissions.requesting",
417
+ guard: "needsMotionPrimeOnly",
418
+ actions: "setPermissionResultFromEvent"
419
+ },
420
+ {
421
+ target: "#faceCapture.permissions",
422
+ actions: "setPermissionResultFromEvent"
423
+ }
424
+ ]
564
425
  } }
565
426
  }
566
427
  },
@@ -589,21 +450,42 @@ const _faceCaptureMachine = setup({
589
450
  invoke: {
590
451
  id: "checkPermissionIdle",
591
452
  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
- }]
453
+ onDone: [
454
+ {
455
+ target: "#faceCapture.capture",
456
+ guard: "isReadyForCapture",
457
+ actions: "setPermissionResultFromEvent"
458
+ },
459
+ {
460
+ target: "denied",
461
+ guard: ({ event }) => event.output === "denied",
462
+ actions: "setPermissionResultFromEvent"
463
+ },
464
+ {
465
+ target: "motionOnly",
466
+ guard: "needsMotionPrimeOnly",
467
+ actions: "setPermissionResultFromEvent"
468
+ },
469
+ {
470
+ target: "waitingForUser",
471
+ actions: "setPermissionResultFromEvent"
472
+ }
473
+ ],
474
+ onError: {
475
+ target: "waitingForUser",
476
+ actions: assign({ permissionResult: () => "prompt" })
477
+ }
601
478
  },
602
479
  on: {
603
480
  REQUEST_PERMISSION: "requesting",
604
481
  GO_TO_LEARN_MORE: "learnMore"
605
482
  }
606
483
  },
484
+ waitingForUser: { on: {
485
+ REQUEST_PERMISSION: "requesting",
486
+ GO_TO_LEARN_MORE: "learnMore"
487
+ } },
488
+ motionOnly: { on: { REQUEST_PERMISSION: "requesting" } },
607
489
  learnMore: { on: {
608
490
  BACK: "idle",
609
491
  REQUEST_PERMISSION: "requesting"
@@ -611,11 +493,14 @@ const _faceCaptureMachine = setup({
611
493
  requesting: { invoke: {
612
494
  id: "requestPermission",
613
495
  src: "requestPermission",
614
- input: ({ context }) => ({ requestMotionPermission: context.config.ds === true }),
496
+ input: ({ context }) => ({
497
+ permissionResult: context.permissionResult === "refresh" ? void 0 : context.permissionResult,
498
+ requestMotionPermission: context.config.ds === true
499
+ }),
615
500
  onDone: [
616
501
  {
617
502
  target: "#faceCapture.capture",
618
- guard: "isPermissionGranted",
503
+ guard: "isReadyForCapture",
619
504
  actions: "setPermissionResultFromEvent"
620
505
  },
621
506
  {
@@ -624,7 +509,7 @@ const _faceCaptureMachine = setup({
624
509
  actions: "setPermissionResultFromEvent"
625
510
  },
626
511
  {
627
- target: "idle",
512
+ target: "waitingForUser",
628
513
  actions: "setPermissionResultFromEvent"
629
514
  }
630
515
  ],
@@ -870,4 +755,4 @@ const _faceCaptureMachine = setup({
870
755
  const faceCaptureMachine = _faceCaptureMachine;
871
756
 
872
757
  //#endregion
873
- export { prepareOnDeviceFaceUpload as a, postOnDeviceFaceResults as i, defaultPrepareFaceUpload as n, isOnDeviceMode as r, faceCaptureMachine as t };
758
+ export { faceCaptureMachine as t };
@@ -1,7 +1,31 @@
1
1
  import { t as api } from "./api-CESGtpbH.esm.js";
2
- import { t as endpoints } from "./endpoints-CnN3SyDa.esm.js";
3
- import { a as fromPromise, r as assign, t as setup } from "./xstate.esm-B70JrNqo.esm.js";
2
+ import { t as endpoints } from "./endpoints-BeTK0Mlt.esm.js";
3
+ import { a as fromPromise, r as assign, t as setup } from "./xstate.esm-C9wncMQa.esm.js";
4
4
 
5
+ //#region src/modules/face-match/constants.ts
6
+ /**
7
+ * Backend error code returned by face-match endpoints (e.g. `/omni/process/face`,
8
+ * `/omni/get/score`) when the session was captured with `extractIdFace: false`.
9
+ * No biometric ID template exists, so face-match cannot run and should be
10
+ * skipped on the client (continue to the next step instead of erroring).
11
+ */
12
+ const ID_FACE_EXTRACTION_SKIPPED_CODE = 4084;
13
+ /**
14
+ * Determines whether a thrown HTTP error represents the "ID face extraction
15
+ * skipped" case (backend status `4084`).
16
+ *
17
+ * The backend exposes the code either as the top-level `status` field of the
18
+ * rejected value or nested inside the response body (`data.status`), depending
19
+ * on the transport. The HTTP client surfaces non-2xx responses as a
20
+ * `FetchHttpError` whose `data` holds the parsed error body.
21
+ */
22
+ function isFaceExtractionSkippedError(error) {
23
+ if (!error || typeof error !== "object") return false;
24
+ const err = error;
25
+ return err.status === ID_FACE_EXTRACTION_SKIPPED_CODE || err.data?.status === ID_FACE_EXTRACTION_SKIPPED_CODE;
26
+ }
27
+
28
+ //#endregion
5
29
  //#region src/modules/face-match/faceMatchServices.ts
6
30
  /**
7
31
  * Fetches cropped face images from the backend.
@@ -41,9 +65,33 @@ async function fetchSecondIdImages(signal) {
41
65
  return { secondIdFace: res.data.croppedIDFace ?? null };
42
66
  }
43
67
  /**
68
+ * Triggers server-side face processing/matching for the captured selfie.
69
+ *
70
+ * Used when an AUTHENTICATION module is present in the flow (`processFaceBeforeMatch`):
71
+ * the auth capture step skips server-side processing, so the match must be triggered here
72
+ * before `GET /omni/get/score` reflects it. Mirrors SDK 1's FaceMatch module.
73
+ *
74
+ * The response body is intentionally ignored — face-match re-reads the result via
75
+ * `fetchScore`. A non-ok response throws an Error carrying the backend `status`/`data` so
76
+ * the state machine's `onError` can both produce a readable message and detect the
77
+ * "ID face extraction skipped" case (status 4084) via `isFaceExtractionSkippedError`.
78
+ */
79
+ async function processFaceForMatch(matchingType, signal) {
80
+ const endpoint = matchingType === "secondId" ? endpoints.processFaceSecondId : endpoints.processFace;
81
+ const res = await api.post(endpoint, {}, {
82
+ query: { imageType: "selfie" },
83
+ signal
84
+ });
85
+ if (!res.ok) throw Object.assign(/* @__PURE__ */ new Error(`POST ${endpoint} failed: ${res.status} ${res.statusText}`), {
86
+ status: res.status,
87
+ data: res.data
88
+ });
89
+ }
90
+ /**
44
91
  * Fetches all face match data in parallel (images, score, and optionally second ID images).
45
92
  */
46
93
  async function fetchFaceMatchData(config, signal) {
94
+ if (config.processFaceBeforeMatch) await processFaceForMatch(config.matchingType, signal);
47
95
  const promises = [fetchFaceMatchImages(signal), fetchScore(signal)];
48
96
  if (config.matchingType === "secondId") promises.push(fetchSecondIdImages(signal));
49
97
  const [imagesRes, resultRes, secondIdRes] = await Promise.all(promises);
@@ -84,7 +132,10 @@ const faceMatchMachine = setup({
84
132
  error: void 0
85
133
  }))
86
134
  },
87
- guards: { isAnimationDisabled: ({ context }) => context.config.disableFaceMatchAnimation === true }
135
+ guards: {
136
+ isAnimationDisabled: ({ context }) => context.config.disableFaceMatchAnimation === true,
137
+ isFaceExtractionSkipped: ({ event }) => isFaceExtractionSkippedError(event.error)
138
+ }
88
139
  }).createMachine({
89
140
  id: "faceMatch",
90
141
  initial: "idle",
@@ -108,10 +159,13 @@ const faceMatchMachine = setup({
108
159
  target: "animating",
109
160
  actions: "setData"
110
161
  }],
111
- onError: {
162
+ onError: [{
163
+ target: "finished",
164
+ guard: "isFaceExtractionSkipped"
165
+ }, {
112
166
  target: "error",
113
167
  actions: "setError"
114
- }
168
+ }]
115
169
  } },
116
170
  animating: { on: { ANIMATION_COMPLETE: { target: "result" } } },
117
171
  result: { on: { CONTINUE: { target: "finished" } } },
@@ -124,4 +178,4 @@ const faceMatchMachine = setup({
124
178
  });
125
179
 
126
180
  //#endregion
127
- export { faceMatchMachine as t };
181
+ export { ID_FACE_EXTRACTION_SKIPPED_CODE as n, isFaceExtractionSkippedError as r, faceMatchMachine as t };
@@ -0,0 +1,4 @@
1
+ import "./Manager-BHn8wH8K.js";
2
+ import "./Actor-Y0_Fj-KL.js";
3
+ import { a as FieldComparisonActor, c as FieldComparisonFields, i as createFieldComparisonManagerFromActor, n as FieldComparisonState, o as fieldComparisonMachine, r as createFieldComparisonManager, s as FieldComparisonConfig, t as FieldComparisonManager } from "./fieldComparisonManager-Bu5TaSr3.js";
4
+ export { type FieldComparisonActor, type FieldComparisonConfig, type FieldComparisonFields, type FieldComparisonManager, type FieldComparisonState, createFieldComparisonManager, createFieldComparisonManagerFromActor, fieldComparisonMachine };
@@ -0,0 +1,7 @@
1
+ import "./api-CESGtpbH.esm.js";
2
+ import "./events-Dvvriq9l.esm.js";
3
+ import "./endpoints-BeTK0Mlt.esm.js";
4
+ import "./xstate.esm-C9wncMQa.esm.js";
5
+ import { n as createFieldComparisonManagerFromActor, r as fieldComparisonMachine, t as createFieldComparisonManager } from "./fieldComparisonManager-COGI2ARD.esm.js";
6
+
7
+ export { createFieldComparisonManager, createFieldComparisonManagerFromActor, fieldComparisonMachine };
@@ -0,0 +1,76 @@
1
+ import { t as Manager } from "./Manager-BHn8wH8K.js";
2
+ import { t as ActorRefFrom } from "./Actor-Y0_Fj-KL.js";
3
+
4
+ //#region src/modules/field-comparison/types.d.ts
5
+
6
+ /**
7
+ * Configuration options for the field comparison module.
8
+ *
9
+ * The backend currently sends an empty module configuration for this step.
10
+ */
11
+ type FieldComparisonConfig = Record<string, never>;
12
+ /** First and last name collected for backend field comparison. */
13
+ type FieldComparisonFields = {
14
+ firstName: string;
15
+ lastName: string;
16
+ };
17
+ //#endregion
18
+ //#region src/modules/field-comparison/fieldComparisonStateMachine.d.ts
19
+
20
+ declare const fieldComparisonMachine: any;
21
+ type FieldComparisonMachine = typeof fieldComparisonMachine;
22
+ //#endregion
23
+ //#region src/modules/field-comparison/fieldComparisonActor.d.ts
24
+ /** Options for {@link createFieldComparisonActor}. */
25
+ type CreateFieldComparisonActorOptions = {
26
+ /** Module configuration from the flow (currently always empty). */
27
+ config?: FieldComparisonConfig;
28
+ };
29
+ /** Started actor ref for the field comparison state machine. */
30
+ type FieldComparisonActor = ActorRefFrom<FieldComparisonMachine>;
31
+ //#endregion
32
+ //#region src/modules/field-comparison/fieldComparisonManager.d.ts
33
+ type FieldComparisonIdleState = {
34
+ status: 'idle';
35
+ };
36
+ type FieldComparisonInputtingState = {
37
+ status: 'inputting';
38
+ fields: FieldComparisonFields;
39
+ canSubmit: boolean;
40
+ };
41
+ type FieldComparisonSubmittingState = {
42
+ status: 'submitting';
43
+ fields: FieldComparisonFields;
44
+ };
45
+ type FieldComparisonSuccessState = {
46
+ status: 'success';
47
+ };
48
+ type FieldComparisonErrorState = {
49
+ status: 'error';
50
+ };
51
+ type FieldComparisonFinishedState = {
52
+ status: 'finished';
53
+ };
54
+ type FieldComparisonState = FieldComparisonIdleState | FieldComparisonInputtingState | FieldComparisonSubmittingState | FieldComparisonFinishedState | FieldComparisonSuccessState | FieldComparisonErrorState;
55
+ declare function createFieldComparisonManager(options?: CreateFieldComparisonActorOptions): Manager<FieldComparisonState> & {
56
+ load(): void;
57
+ setField(field: keyof FieldComparisonFields, value: string): void;
58
+ submit(): void;
59
+ retry(): void;
60
+ skip(): void;
61
+ };
62
+ /**
63
+ * Creates a field-comparison manager from a pre-built actor.
64
+ * Use this when overriding the machine via `.provide()` for custom backends
65
+ * or for story-isolation testing.
66
+ */
67
+ declare function createFieldComparisonManagerFromActor(actor: FieldComparisonActor): Manager<FieldComparisonState> & {
68
+ load(): void;
69
+ setField(field: keyof FieldComparisonFields, value: string): void;
70
+ submit(): void;
71
+ retry(): void;
72
+ skip(): void;
73
+ };
74
+ type FieldComparisonManager = ReturnType<typeof createFieldComparisonManager>;
75
+ //#endregion
76
+ export { FieldComparisonActor as a, FieldComparisonFields as c, createFieldComparisonManagerFromActor as i, FieldComparisonState as n, fieldComparisonMachine as o, createFieldComparisonManager as r, FieldComparisonConfig as s, FieldComparisonManager as t };
@@ -0,0 +1,162 @@
1
+ import { t as api } from "./api-CESGtpbH.esm.js";
2
+ import { n as eventModuleNames, o as createManagerInstrumentation } from "./events-Dvvriq9l.esm.js";
3
+ import { t as endpoints } from "./endpoints-BeTK0Mlt.esm.js";
4
+ import { a as fromPromise, c as createManager, r as assign, s as createActor, t as setup } from "./xstate.esm-C9wncMQa.esm.js";
5
+
6
+ //#region src/modules/field-comparison/fieldComparisonServices.ts
7
+ /** Submit first and last name for backend field comparison. Throws on failure. */
8
+ async function submitFieldComparison(params, signal) {
9
+ const res = await api.post(endpoints.addCustomFields, params, { signal });
10
+ if (!res.ok) throw new Error(`POST ${endpoints.addCustomFields} failed: ${res.status} ${res.statusText}`);
11
+ return res.data;
12
+ }
13
+
14
+ //#endregion
15
+ //#region src/modules/field-comparison/fieldComparisonUtils.ts
16
+ /** Returns true when both first and last name are non-empty after trimming. */
17
+ function isFormComplete(fields) {
18
+ return fields.firstName.trim() !== "" && fields.lastName.trim() !== "";
19
+ }
20
+
21
+ //#endregion
22
+ //#region src/modules/field-comparison/fieldComparisonStateMachine.ts
23
+ const emptyFields = () => ({
24
+ firstName: "",
25
+ lastName: ""
26
+ });
27
+ const fieldComparisonMachine = setup({
28
+ types: {
29
+ context: {},
30
+ events: {},
31
+ input: {}
32
+ },
33
+ actors: { submitFields: fromPromise(async ({ input, signal }) => {
34
+ return submitFieldComparison({ customFields: input }, signal);
35
+ }) },
36
+ actions: { setField: assign(({ context, event }) => {
37
+ const e = event;
38
+ return { fields: {
39
+ ...context.fields,
40
+ [e.field]: e.value
41
+ } };
42
+ }) },
43
+ guards: {
44
+ canSubmit: ({ context }) => isFormComplete(context.fields),
45
+ apiSucceeded: ({ event }) => event.output.success
46
+ }
47
+ }).createMachine({
48
+ id: "fieldComparison",
49
+ initial: "idle",
50
+ context: ({ input }) => ({
51
+ config: input.config,
52
+ fields: emptyFields()
53
+ }),
54
+ states: {
55
+ idle: { on: { LOAD: "inputting" } },
56
+ inputting: { on: {
57
+ FIELD_CHANGED: { actions: "setField" },
58
+ SUBMIT: {
59
+ target: "submitting",
60
+ guard: "canSubmit"
61
+ }
62
+ } },
63
+ submitting: { invoke: {
64
+ id: "submitFields",
65
+ src: "submitFields",
66
+ input: ({ context }) => context.fields,
67
+ onDone: [{
68
+ target: "success",
69
+ guard: "apiSucceeded"
70
+ }, { target: "error" }],
71
+ onError: { target: "error" }
72
+ } },
73
+ success: { after: { 3e3: { target: "finished" } } },
74
+ error: { on: {
75
+ RETRY: { target: "inputting" },
76
+ SKIP: { target: "finished" }
77
+ } },
78
+ finished: { type: "final" }
79
+ }
80
+ });
81
+
82
+ //#endregion
83
+ //#region src/modules/field-comparison/fieldComparisonActor.ts
84
+ /**
85
+ * Creates and starts the field comparison state machine actor.
86
+ *
87
+ * @param options - Optional actor configuration
88
+ */
89
+ function createFieldComparisonActor(options = {}) {
90
+ return createActor(fieldComparisonMachine, { input: { config: options.config ?? {} } }).start();
91
+ }
92
+
93
+ //#endregion
94
+ //#region src/modules/field-comparison/fieldComparisonManager.ts
95
+ function mapState(snapshot) {
96
+ const typedSnapshot = snapshot;
97
+ const { fields } = typedSnapshot.context;
98
+ if (typedSnapshot.matches("idle")) return { status: "idle" };
99
+ if (typedSnapshot.matches("inputting")) return {
100
+ status: "inputting",
101
+ canSubmit: isFormComplete(fields),
102
+ fields
103
+ };
104
+ if (typedSnapshot.matches("submitting")) return {
105
+ status: "submitting",
106
+ fields
107
+ };
108
+ if (typedSnapshot.matches("finished")) return { status: "finished" };
109
+ if (typedSnapshot.matches("success")) return { status: "success" };
110
+ if (typedSnapshot.matches("error")) return { status: "error" };
111
+ return { status: "idle" };
112
+ }
113
+ function createApi({ actor, trackElementClicked }) {
114
+ return {
115
+ load() {
116
+ actor.send({ type: "LOAD" });
117
+ },
118
+ setField(field, value) {
119
+ actor.send({
120
+ type: "FIELD_CHANGED",
121
+ field,
122
+ value
123
+ });
124
+ },
125
+ submit() {
126
+ trackElementClicked?.("submit");
127
+ actor.send({ type: "SUBMIT" });
128
+ },
129
+ retry() {
130
+ trackElementClicked?.("retry");
131
+ actor.send({ type: "RETRY" });
132
+ },
133
+ skip() {
134
+ trackElementClicked?.("skip");
135
+ actor.send({ type: "SKIP" });
136
+ }
137
+ };
138
+ }
139
+ function createFieldComparisonManager(options = {}) {
140
+ return createManager({
141
+ actor: createFieldComparisonActor(options),
142
+ mapState,
143
+ createApi,
144
+ instrumentation: createManagerInstrumentation(eventModuleNames.fieldComparison)
145
+ });
146
+ }
147
+ /**
148
+ * Creates a field-comparison manager from a pre-built actor.
149
+ * Use this when overriding the machine via `.provide()` for custom backends
150
+ * or for story-isolation testing.
151
+ */
152
+ function createFieldComparisonManagerFromActor(actor) {
153
+ return createManager({
154
+ actor,
155
+ mapState,
156
+ createApi,
157
+ instrumentation: createManagerInstrumentation(eventModuleNames.fieldComparison)
158
+ });
159
+ }
160
+
161
+ //#endregion
162
+ export { createFieldComparisonManagerFromActor as n, fieldComparisonMachine as r, createFieldComparisonManager as t };