@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.
- package/dist/Actor-CI32dTbG.d.ts +2 -0
- package/dist/BaseWasmProvider-C_DLEI40.esm.js +1118 -0
- package/dist/BrowserStorageProvider-CuOW1Er2.esm.js +55 -0
- package/dist/BrowserTimerProvider-DhNc_x02.esm.js +22 -0
- package/dist/ITimerCapability-C67ZRskg.esm.js +7 -0
- package/dist/IpifyProvider-D7jx52AL.esm.js +139 -0
- package/dist/MotionSensorProvider-4v7xkqAp.esm.js +254 -0
- package/dist/OpenViduRecordingProvider-CMu6XVdc.esm.js +87 -0
- package/dist/StateMachine-BCQrZJhf.d.ts +2 -0
- package/dist/WasmUtilProvider-j98OJf-S.esm.js +114 -0
- package/dist/addressSearch-BpTbTWCa.esm.js +430 -0
- package/dist/ae-signature-DDDZmWXj.esm.js +12 -0
- package/dist/ae-signature.d.ts +25 -0
- package/dist/ae-signature.esm.js +8 -0
- package/dist/antifraud.d.ts +57 -0
- package/dist/antifraud.esm.js +45 -0
- package/dist/antifraudStateMachine-O0TMf6yc.esm.js +39 -0
- package/dist/api-CESGtpbH.esm.js +53 -0
- package/dist/authentication.d.ts +12 -0
- package/dist/authentication.esm.js +25 -0
- package/dist/authenticationManager-5M-fKzXx.esm.js +67 -0
- package/dist/authenticationManager-C83GNIhl.d.ts +66 -0
- package/dist/authenticationStateMachine-BMZqatiF.esm.js +139 -0
- package/dist/backCameraStream-DMdMeGk2.esm.js +346 -0
- package/dist/browserSimulation-gxD8cSpM.esm.js +20 -0
- package/dist/camera-DBSxa6ML.d.ts +4 -0
- package/dist/camera-PA2Ljri3.esm.js +22 -0
- package/dist/camera.d.ts +15 -0
- package/dist/camera.esm.js +5 -0
- package/dist/consent.d.ts +398 -0
- package/dist/consent.esm.js +79 -0
- package/dist/consentStateMachine-CCT-B60O.esm.js +151 -0
- package/dist/cpf-PPz2Njto.esm.js +38 -0
- package/dist/cpf-ocr.d.ts +204 -0
- package/dist/cpf-ocr.esm.js +177 -0
- package/dist/cross-document-data-match.d.ts +34 -0
- package/dist/cross-document-data-match.esm.js +71 -0
- package/dist/curp-validation.d.ts +188 -0
- package/dist/curp-validation.esm.js +110 -0
- package/dist/curpValidationStateMachine-CitWLr2c.esm.js +595 -0
- package/dist/custom-fields.d.ts +115 -0
- package/dist/custom-fields.esm.js +177 -0
- package/dist/custom-watchlist.d.ts +66 -0
- package/dist/custom-watchlist.esm.js +86 -0
- package/dist/dateUtils-UoN5xswP.esm.js +23 -0
- package/dist/deepsightLoader-Cm4JIT_z.esm.js +52 -0
- package/dist/deepsightService-CEVxzehb.d.ts +412 -0
- package/dist/deepsightService-O74l4Y__.esm.js +489 -0
- package/dist/device.d.ts +46 -0
- package/dist/device.esm.js +106 -0
- package/dist/displayErrors-DqJ_IbsG.d.ts +39 -0
- package/dist/document-capture.d.ts +906 -0
- package/dist/document-capture.esm.js +156 -0
- package/dist/document-upload.d.ts +331 -0
- package/dist/document-upload.esm.js +203 -0
- package/dist/documentCaptureStateMachine-BqzTDy9k.esm.js +394 -0
- package/dist/dynamic-forms.d.ts +178 -0
- package/dist/dynamic-forms.esm.js +323 -0
- package/dist/ekyb.d.ts +148 -0
- package/dist/ekyb.esm.js +127 -0
- package/dist/ekybStateMachine-B59rQjgj.esm.js +674 -0
- package/dist/ekyc.d.ts +164 -0
- package/dist/ekyc.esm.js +104 -0
- package/dist/ekycStateMachine-oeO0Iekd.esm.js +10626 -0
- package/dist/electronic-signature.d.ts +4 -0
- package/dist/electronic-signature.esm.js +7 -0
- package/dist/electronicSignatureManager-D9OHzTpG.esm.js +428 -0
- package/dist/email.d.ts +3 -263
- package/dist/email.esm.js +7 -477
- package/dist/emailManager-DIfnS5g1.d.ts +352 -0
- package/dist/emailManager-wAV0LE-H.esm.js +238 -0
- package/dist/emailStateMachine-DOf4j58N.esm.js +292 -0
- package/dist/endpoints-CnN3SyDa.esm.js +87 -0
- package/dist/events-D6-e4vok.esm.js +596 -0
- package/dist/events.d.ts +265 -0
- package/dist/events.esm.js +4 -0
- package/dist/extensibility.d.ts +122 -0
- package/dist/extensibility.esm.js +43 -0
- package/dist/face-match.d.ts +228 -0
- package/dist/face-match.esm.js +173 -0
- package/dist/faceCaptureManagerFactory-Dh2PdGlF.esm.js +290 -0
- package/dist/faceCaptureManagerFactory-yqtpxjnN.d.ts +690 -0
- package/dist/faceCaptureSetup-B3faSpYA.esm.js +873 -0
- package/dist/faceMatchStateMachine-DNFrxTFS.esm.js +127 -0
- package/dist/flow-events.d.ts +6 -0
- package/dist/flow-events.esm.js +0 -0
- package/dist/flow.d.ts +101 -321
- package/dist/flow.esm.js +370 -173
- package/dist/flowCompletionService-DhkT4SRY.d.ts +10 -0
- package/dist/flowCompletionService-P54yzGvA.esm.js +13 -0
- package/dist/flowServices-DTsm-Vf1.esm.js +188 -0
- package/dist/geolocation.d.ts +127 -0
- package/dist/geolocation.esm.js +89 -0
- package/dist/geolocationStateMachine-asasuHY2.esm.js +105 -0
- package/dist/getBrowser-BSXUTWXw.esm.js +41 -0
- package/dist/getDeviceClass-BSntT9_j.esm.js +14 -0
- package/dist/government-validation.d.ts +67 -0
- package/dist/government-validation.esm.js +81 -0
- package/dist/governmentValidationStateMachine-BDDYrJTo.esm.js +271 -0
- package/dist/home.d.ts +99 -0
- package/dist/home.esm.js +61 -0
- package/dist/http.d.ts +68 -0
- package/dist/http.esm.js +3 -0
- package/dist/id-ocr.d.ts +635 -0
- package/dist/id-ocr.esm.js +86 -0
- package/dist/id-verification.d.ts +190 -0
- package/dist/id-verification.esm.js +43 -0
- package/dist/id.d.ts +24 -0
- package/dist/id.esm.js +164 -0
- package/dist/idCaptureManager-B9TGA5dq.d.ts +956 -0
- package/dist/idCaptureManager-DMK0GIt3.esm.js +581 -0
- package/dist/idCaptureStateMachine-Bq0fVZXl.esm.js +2954 -0
- package/dist/idOcrStateMachine-YbjjC_Gg.esm.js +388 -0
- package/dist/idVerificationStateMachine-xbw9HP1Z.esm.js +71 -0
- package/dist/identity-reuse.d.ts +530 -0
- package/dist/identity-reuse.esm.js +274 -0
- package/dist/index-BLKtMA0g.d.ts +1177 -0
- package/dist/index-BcRG8rtJ.d.ts +97 -0
- package/dist/index.d.ts +3 -226
- package/dist/index.esm.js +11 -154
- package/dist/invokeOnCaptureCallback-rc6kBHo5.esm.js +30 -0
- package/dist/{lib-Bu9XGMBW.esm.js → lib-BB0B_qQX.esm.js} +801 -2
- package/dist/mandatory-consent.d.ts +412 -0
- package/dist/mandatory-consent.esm.js +78 -0
- package/dist/mandatoryConsentStateMachine-Cnco1jvn.esm.js +126 -0
- package/dist/openviduLazy-Cm0XFh_v.esm.js +3 -0
- package/dist/openviduLazy-Cok70ZSg.esm.js +12 -0
- package/dist/permissionServices-D_i6nzEw.esm.js +50 -0
- package/dist/phone.d.ts +3 -291
- package/dist/phone.esm.js +7 -548
- package/dist/phoneManager-B6M30hKE.d.ts +397 -0
- package/dist/phoneManager-DAJbGhlY.esm.js +256 -0
- package/dist/phoneStateMachine-CuPARRaT.esm.js +351 -0
- package/dist/platform-CfrjKhmi.esm.js +83 -0
- package/dist/qe-signature-DFo_Cc-I.esm.js +12 -0
- package/dist/qe-signature.d.ts +25 -0
- package/dist/qe-signature.esm.js +8 -0
- package/dist/recordingService-Ig2UgbLv.esm.js +1003 -0
- package/dist/redirect-to-mobile.d.ts +107 -0
- package/dist/redirect-to-mobile.esm.js +102 -0
- package/dist/redirectToMobileStateMachine-BOEqe46A.esm.js +249 -0
- package/dist/runChildModule-CqqwqAkW.esm.js +219 -0
- package/dist/selfie.d.ts +21 -754
- package/dist/selfie.esm.js +113 -962
- package/dist/selfieManager-D0lSgd-J.d.ts +68 -0
- package/dist/selfieManager-Duisl7qN.esm.js +60 -0
- package/dist/selfieStateMachine-D76whWEf.esm.js +68 -0
- package/dist/session-BS-d_vuE.esm.js +3206 -0
- package/dist/session.d.ts +217 -0
- package/dist/session.esm.js +9 -0
- package/dist/setup-Buy-hyj4.esm.js +887 -0
- package/dist/setup-C5AITV8m.d.ts +254 -0
- package/dist/signature.d.ts +94 -0
- package/dist/signature.esm.js +66 -0
- package/dist/signatureStateMachine-B5-QVUve.esm.js +132 -0
- package/dist/stats-CIfiPzb1.esm.js +16 -0
- package/dist/stats.d.ts +16 -0
- package/dist/stats.esm.js +4 -0
- package/dist/trust-graph.d.ts +54 -0
- package/dist/trust-graph.esm.js +56 -0
- package/dist/types-B06Ypu2F.d.ts +49 -0
- package/dist/types-BP1m8VRw.d.ts +340 -0
- package/dist/types-CFV9G_7j.d.ts +24 -0
- package/dist/{warmup-CEJTfxQr.d.ts → warmup-CEcppFiS.d.ts} +11 -3
- package/dist/wasm.d.ts +15 -0
- package/dist/wasm.esm.js +12 -0
- package/dist/watchlist-for-business.d.ts +79 -0
- package/dist/watchlist-for-business.esm.js +148 -0
- package/dist/watchlist.d.ts +62 -0
- package/dist/watchlist.esm.js +86 -0
- package/dist/watchlistServices-DMbUhkBX.esm.js +12 -0
- package/dist/workflow.d.ts +907 -0
- package/dist/workflow.esm.js +702 -0
- package/dist/{xstate.esm-B_rda9yU.esm.js → xstate.esm-B70JrNqo.esm.js} +144 -1
- package/package.json +203 -6
- package/dist/OpenViduLogger-BdPfiZO6.esm.js +0 -3
- package/dist/OpenViduLogger-CQyDxBvM.esm.js +0 -803
- package/dist/StateMachine-DRE1oH2B.d.ts +0 -2
- package/dist/addEvent-W0ORK0jT.esm.js +0 -16
- package/dist/endpoints-BSTFaHYo.esm.js +0 -1706
- package/dist/permissionServices-I6vX6DBy.esm.js +0 -72
- /package/dist/{Manager-BGfxEmyv.d.ts → Manager-C8PrhBOx.d.ts} +0 -0
- /package/dist/{chunk-C_Yo44FK.esm.js → chunk-CRF6K_H_.esm.js} +0 -0
- /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 };
|