@incodetech/core 2.3.0-rc.9 → 2.3.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 (86) hide show
  1. package/dist/{BrowserDiagnosticsCryptoProvider-HO8YXP4h.esm.js → BrowserDiagnosticsCryptoProvider-BuzqvbhN.esm.js} +6 -24
  2. package/dist/{FaceDetectionProvider-C7bUZsH9.esm.js → FaceDetectionProvider-Lb6i4Ilt.esm.js} +7 -7
  3. package/dist/{MotionSensorProvider-BgTYwg9L.esm.js → MotionSensorProvider-DyhbM4Si.esm.js} +1 -1
  4. package/dist/ae-signature.esm.js +1 -1
  5. package/dist/{apiError-BWlcyGbw.esm.js → apiError-Dkl9_HOx.esm.js} +1 -1
  6. package/dist/authentication.d.ts +2 -2
  7. package/dist/authentication.esm.js +2 -2
  8. package/dist/{authenticationManager-DcTHmYmL.d.ts → authenticationManager-B23V74p7.d.ts} +1 -1
  9. package/dist/{authenticationManager-B321A87w.esm.js → authenticationManager-C7BaQC99.esm.js} +4 -4
  10. package/dist/{authenticationStateMachine-CSJtf13E.esm.js → authenticationStateMachine-CW7a9qpV.esm.js} +3 -3
  11. package/dist/camera.esm.js +1 -1
  12. package/dist/{createCameraCycleOwnership-CX3hJGKc.esm.js → createCameraCycleOwnership-DnwTl1ad.esm.js} +6 -1
  13. package/dist/{deepsightLoader-FOktaF-9.esm.js → deepsightLoader-DgaaacGJ.esm.js} +6 -6
  14. package/dist/document-capture.esm.js +2 -2
  15. package/dist/{documentCaptureManager-pprJUhsN.esm.js → documentCaptureManager-BRPxqYD2.esm.js} +1 -1
  16. package/dist/{documentCaptureStateMachine-DN2YOxdu.esm.js → documentCaptureStateMachine-D312sSIu.esm.js} +2 -2
  17. package/dist/dynamic-forms.esm.js +2 -2
  18. package/dist/{dynamicFormsManager-Pj67RmHb.esm.js → dynamicFormsManager-Cm33oGqC.esm.js} +1 -1
  19. package/dist/{dynamicFormsStateMachine-B00MVHEa.esm.js → dynamicFormsStateMachine-4EVsg15i.esm.js} +1 -1
  20. package/dist/ekyb.esm.js +3 -3
  21. package/dist/{ekybManager-CovxKSIS.esm.js → ekybManager-CgjQ2Thl.esm.js} +1 -1
  22. package/dist/{ekybStateMachine-DHCg1B5d.esm.js → ekybStateMachine-Dwgt5Dqa.esm.js} +1 -1
  23. package/dist/electronic-signature.esm.js +1 -1
  24. package/dist/{electronicSignatureManager-BnlLBzH6.esm.js → electronicSignatureManager-DGEUq9nY.esm.js} +1 -1
  25. package/dist/extensibility.d.ts +6 -6
  26. package/dist/extensibility.esm.js +12 -12
  27. package/dist/{faceCaptureManagerFactory-DTqP1t1a.esm.js → faceCaptureManagerFactory-3x7qaM76.esm.js} +3 -3
  28. package/dist/{faceCaptureManagerFactory-Cx-8SqRy.d.ts → faceCaptureManagerFactory-DMLstvui.d.ts} +35 -3
  29. package/dist/{faceCaptureSetup-DfetEHJm.esm.js → faceCaptureSetup-CJzsvv1I.esm.js} +10 -9
  30. package/dist/{feature-management-BjROP6fF.esm.js → feature-management-BG6sf4O4.esm.js} +1 -1
  31. package/dist/feature-management.esm.js +1 -1
  32. package/dist/flow.esm.js +3 -3
  33. package/dist/{flowCompletionService-iyH7fw8r.esm.js → flowCompletionService-BusrkMdp.esm.js} +1 -1
  34. package/dist/{flowServices-C8CBt9j3.esm.js → flowServices-pIc1cq8q.esm.js} +5 -5
  35. package/dist/geolocation.esm.js +2 -2
  36. package/dist/{geolocationManager-DQ5tHq5k.esm.js → geolocationManager-BbgMboZ-.esm.js} +1 -1
  37. package/dist/{geolocationStateMachine-BfNIvTHA.esm.js → geolocationStateMachine-Bixn87pI.esm.js} +1 -1
  38. package/dist/id-selfie-flow.d.ts +1 -1
  39. package/dist/id-selfie-flow.esm.js +9 -10
  40. package/dist/id.d.ts +1 -1
  41. package/dist/id.esm.js +3 -3
  42. package/dist/{idCaptureDefaults-DCmwAxkz.esm.js → idCaptureDefaults-BmnsDgZZ.esm.js} +3 -3
  43. package/dist/{idCaptureManager-De7O0TOD.d.ts → idCaptureManager-BaHEyQyr.d.ts} +0 -1
  44. package/dist/{idCaptureManager-C4gJNe18.esm.js → idCaptureManager-BpdRLyqZ.esm.js} +5 -5
  45. package/dist/{idCaptureServices-CPh--aZR.esm.js → idCaptureServices-Di_APvz_.esm.js} +9 -8
  46. package/dist/{idCaptureStateMachine-Du4Q40uJ.esm.js → idCaptureStateMachine-hY-RpDH_.esm.js} +14 -14
  47. package/dist/identity-reuse.d.ts +1 -1
  48. package/dist/{identityReuseManager-v2TH5g7e.d.ts → identityReuseManager-BFDI7iFK.d.ts} +4 -4
  49. package/dist/index.d.ts +1 -1
  50. package/dist/index.esm.js +1 -1
  51. package/dist/mandatory-consent.d.ts +1 -1
  52. package/dist/{mandatoryConsentManager-2O5wztkg.d.ts → mandatoryConsentManager-Csfl7_XQ.d.ts} +4 -4
  53. package/dist/{multipartRecordingService-DDAOXQKm.esm.js → multipartRecordingService-mwKFTlhR.esm.js} +730 -8
  54. package/dist/{permissionGuards-uYZYFu4J.esm.js → permissionGuards-D6TfVop2.esm.js} +1 -1
  55. package/dist/{permissionServices-Bj_fyWtv.esm.js → permissionServices-EY3_Vx6c.esm.js} +2 -2
  56. package/dist/qe-signature.esm.js +1 -1
  57. package/dist/{runChildModule-CHjWYSMf.esm.js → runChildModule-kZQwHJ21.esm.js} +1 -1
  58. package/dist/{safeStorage-B-trhxg6.esm.js → safeStorage-BdU9_m2E.esm.js} +1 -1
  59. package/dist/{sdkVersion-DCLQtexS.esm.js → sdkVersion-KY79FtZx.esm.js} +1 -1
  60. package/dist/selfie.d.ts +2 -2
  61. package/dist/selfie.esm.js +7 -7
  62. package/dist/{selfieManager-ys-X4hkv.esm.js → selfieManager-Bjane9c3.esm.js} +4 -4
  63. package/dist/{selfieManager-jXqwqosi.d.ts → selfieManager-CDCTOrcg.d.ts} +1 -1
  64. package/dist/{selfieStateMachine-BhzbXmKN.esm.js → selfieStateMachine-OsbjyRR6.esm.js} +3 -3
  65. package/dist/{session-oKiwoHdR.esm.js → session-D4EAR74k.esm.js} +3 -3
  66. package/dist/session.esm.js +4 -4
  67. package/dist/{sessionInitializer-DSf0jyab.esm.js → sessionInitializer-BqGb0lFN.esm.js} +3 -3
  68. package/dist/{setup-BttZ27hw.esm.js → setup-Cc6MzR5Q.esm.js} +7 -57
  69. package/dist/{setup-CLfBztP0.d.ts → setup-Cyko6cAn.d.ts} +4 -17
  70. package/dist/{trueSightService-C1JG8gAU.esm.js → trueSightService-Di5RGIls.esm.js} +16 -554
  71. package/dist/video-selfie.d.ts +61 -3
  72. package/dist/video-selfie.esm.js +60 -14
  73. package/dist/{videoSelfieCameraWarmer-BpaLtLvD.esm.js → videoSelfieCameraWarmer-PV8PLwmD.esm.js} +5 -5
  74. package/dist/{videoSelfieStepDetector-Co0Gu2k2.d.ts → videoSelfieStepDetector-CAqAG2G3.d.ts} +49 -0
  75. package/dist/{warmup-CUUnwYxe.esm.js → warmup-ChDwHSel.esm.js} +5 -0
  76. package/dist/wasm.d.ts +1 -1
  77. package/dist/wasm.esm.js +3 -3
  78. package/dist/{wasmDsFlagSync-B2e8p268.esm.js → wasmDsFlagSync-DYrLUEII.esm.js} +1 -1
  79. package/dist/workflow.d.ts +4 -4
  80. package/dist/workflow.esm.js +15 -15
  81. package/package.json +2 -7
  82. package/dist/FaceDetectionProvider-LdZ47bWy.d.ts +0 -36
  83. package/dist/StreamCanvasProcessingSession-CBnbTnOr.esm.js +0 -42
  84. package/dist/personhood.d.ts +0 -538
  85. package/dist/personhood.esm.js +0 -1574
  86. package/dist/types-BT_Oalip.d.ts +0 -1
@@ -5,7 +5,7 @@ import "./Actor-iTq7YY48.js";
5
5
  import { t as IVisibilityObserverCapability } from "./IVisibilityObserverCapability-D4tvIB5v.js";
6
6
  import { t as CameraStream } from "./camera-9wWD-pwg.js";
7
7
  import { t as DetectionOrientation } from "./IIdCaptureCapability-RNiFhvXR.js";
8
- import { a as FacingMode, i as CameraCompositor, n as VideoSelfieDetectionStatus, o as VideoSelfieConfig, r as VideoSelfieValidationFailure, s as VideoSelfieStep, t as StepDetector } from "./videoSelfieStepDetector-Co0Gu2k2.js";
8
+ import { a as FacingMode, i as CameraCompositor, n as VideoSelfieDetectionStatus, o as VideoSelfieConfig, r as VideoSelfieValidationFailure, s as VideoSelfieStep, t as StepDetector } from "./videoSelfieStepDetector-CAqAG2G3.js";
9
9
  //#region ../infra/src/capabilities/ITimerCapability.d.ts
10
10
  type TimerHandle = ReturnType<typeof setTimeout>;
11
11
  type ITimerCapability = {
@@ -15,6 +15,62 @@ type ITimerCapability = {
15
15
  clearInterval(handle: TimerHandle): void;
16
16
  };
17
17
  //#endregion
18
+ //#region ../infra/src/capabilities/IMultipartRecordingCapability.d.ts
19
+ /**
20
+ * A single chunk of a recording, ready to be uploaded as one S3 multipart
21
+ * part. `partNumber` is 1-based and strictly increasing across a recording.
22
+ */
23
+ type MultipartRecordingPart = {
24
+ partNumber: number;
25
+ chunk: Blob;
26
+ };
27
+ /**
28
+ * Records a `MediaStream` and emits it as a sequence of size-bounded parts
29
+ * (suitable for S3 multipart upload) instead of one blob at the end. Every
30
+ * part except the last is guaranteed to be at least the S3 minimum part size;
31
+ * the final part (flushed on stop) may be smaller.
32
+ *
33
+ * The capability owns only the recording/buffering mechanics — it has no
34
+ * knowledge of HTTP. Callers upload each emitted part themselves via `onPart`.
35
+ */
36
+ type IMultipartRecordingCapability = {
37
+ readonly isRecording: boolean;
38
+ readonly hasError: boolean;
39
+ readonly error: string | null;
40
+ /**
41
+ * Start recording `stream`. `onPart` fires once per part: whenever the
42
+ * internal buffer crosses the part-size threshold during recording, and once
43
+ * more for the remaining buffer when `stopRecording` is called.
44
+ */
45
+ startRecording(stream: MediaStream, onPart: (part: MultipartRecordingPart) => void): void;
46
+ /**
47
+ * Temporarily stop gathering media into the current recording without
48
+ * finalizing its container. Returns whether the recorder is paused.
49
+ * Video Selfie requires this operation; omission is treated as a failed
50
+ * pause. It remains optional for compatibility with other consumers.
51
+ */
52
+ pauseRecording?(): boolean;
53
+ /**
54
+ * Continue gathering media into a recording previously paused with
55
+ * `pauseRecording`. Returns whether the recorder is recording again.
56
+ * Video Selfie requires this operation; omission is treated as a failed
57
+ * resume. It remains optional for compatibility with other consumers.
58
+ */
59
+ resumeRecording?(): boolean;
60
+ /**
61
+ * Stop recording, flush the remaining buffer as the final part (via the
62
+ * `onPart` callback passed to `startRecording`), and resolve once the
63
+ * recorder has fully stopped and that final part has been emitted.
64
+ */
65
+ stopRecording(): Promise<void>;
66
+ /**
67
+ * Discard an in-progress recording without flushing: stops the recorder and
68
+ * releases its (cloned) stream tracks, drops buffered data, and clears error
69
+ * state. Idempotent — safe after `stopRecording` or when never started.
70
+ */
71
+ reset(): void;
72
+ };
73
+ //#endregion
18
74
  //#region src/internal/recordings/videoSelfieUploadService.d.ts
19
75
  /** What the multipart upload records. Must be sent on every protocol call. */
20
76
  type VideoUploadScope = 'videoselfie' | 'selfie' | 'frontId' | 'backId';
@@ -46,14 +102,16 @@ type MultipartRecordingResult = {
46
102
  */
47
103
  declare class MultipartRecordingService {
48
104
  private readonly scope;
49
- private recorder;
105
+ private readonly recorder;
50
106
  private timer;
51
107
  private session;
52
108
  private uploader;
53
109
  private chunksEmitted;
54
110
  private stopPromise;
55
111
  private abandonRequested;
56
- constructor(scope?: VideoUploadScope);
112
+ constructor(scope?: VideoUploadScope,
113
+ /** Recordings encoded in the compositor worker pass their own recorder. */
114
+ recorder?: IMultipartRecordingCapability);
57
115
  get isRecording(): boolean;
58
116
  start(stream: MediaStream): Promise<void>;
59
117
  /** Pause the current media container without finalizing its upload. */
@@ -1,15 +1,15 @@
1
- import { r as WasmUtilProvider } from "./safeStorage-B-trhxg6.esm.js";
2
- import { t as ensureWasmPipelines } from "./setup-BttZ27hw.esm.js";
1
+ import { r as WasmUtilProvider } from "./safeStorage-BdU9_m2E.esm.js";
2
+ import { t as ensureWasmPipelines } from "./setup-Cc6MzR5Q.esm.js";
3
3
  import { t as BrowserTimerProvider } from "./BrowserTimerProvider-BXhgNxLt.esm.js";
4
4
  import { t as api } from "./api-Bx3gKW_y.esm.js";
5
5
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
6
- import { d as facingModeForStep, f as resolveVideoSelfieSteps, p as videoSelfieWasmPipelines } from "./flowServices-C8CBt9j3.esm.js";
6
+ import { d as facingModeForStep, f as resolveVideoSelfieSteps, p as videoSelfieWasmPipelines } from "./flowServices-pIc1cq8q.esm.js";
7
7
  import { i as assign, r as sendTo, s as createActor, t as setup, u as createManager } from "./xstate.esm-BuFLFuzz.esm.js";
8
8
  import { n as fromPromise, t as fromCallback } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
9
9
  import { t as BrowserVisibilityObserverProvider } from "./BrowserVisibilityObserverProvider-BrJN1B8A.esm.js";
10
- import { n as CameraCompositor, t as MultipartRecordingService } from "./multipartRecordingService-DDAOXQKm.esm.js";
10
+ import { i as createRecordingCompositor, n as WorkerEncoderRecordingProvider, t as MultipartRecordingService } from "./multipartRecordingService-mwKFTlhR.esm.js";
11
11
  import { t as VIDEO_SELFIE_VALIDATION_ATTEMPTS_EXHAUSTED_CODE } from "./advanceableErrors-CpF2cBy6.esm.js";
12
- import { a as isConnectionError, n as defaultAcquireCamera, r as createDefaultStepDetector, t as createVideoSelfieCameraWarmer } from "./videoSelfieCameraWarmer-BpaLtLvD.esm.js";
12
+ import { a as isConnectionError, n as defaultAcquireCamera, r as createDefaultStepDetector, t as createVideoSelfieCameraWarmer } from "./videoSelfieCameraWarmer-PV8PLwmD.esm.js";
13
13
  import { t as videoSelfieFlowModuleMachine } from "./videoSelfieFlowModuleMachine-BUe2uACW.esm.js";
14
14
  //#region src/modules/video-selfie/videoSelfieWasm.ts
15
15
  function warmupVideoSelfieWasm(config, steps = resolveVideoSelfieSteps(config)) {
@@ -28,6 +28,17 @@ function recordingIdFromEvent(event) {
28
28
  function errorFromEvent(event) {
29
29
  return String(event.error);
30
30
  }
31
+ /**
32
+ * Chromium reports a camera the device cannot open right now as
33
+ * `NotReadableError` ("Could not start video source") or `AbortError`
34
+ * ("Starting videoinput failed") — the same pair the rear-camera acquire
35
+ * retries on. Anything else (permission, no device) will not clear by
36
+ * releasing our own camera.
37
+ */
38
+ function isCameraBusyError(error) {
39
+ const name = typeof error === "object" && error !== null && "name" in error ? error.name : void 0;
40
+ return name === "NotReadableError" || name === "AbortError";
41
+ }
31
42
  function detectionStatusFromEvent(event) {
32
43
  return event.status;
33
44
  }
@@ -47,6 +58,12 @@ function orientationFromEvent(event) {
47
58
  return event.orientation;
48
59
  }
49
60
  const SWITCHING_CAMERA_MIN_DWELL_MS = 3e3;
61
+ /**
62
+ * How long a just-stopped camera gets to release before another one is
63
+ * opened (see `releasingCamera`). Same settle the rear-camera acquire uses
64
+ * on a busy device; a hardware knob, not a protocol value.
65
+ */
66
+ const CAMERA_RELEASE_SETTLE_MS = 300;
50
67
  const ID_FLIP_DWELL_MS = 4e3;
51
68
  const FINAL_SUCCESS_DWELL_MS = 3e3;
52
69
  const MAX_VIDEO_LENGTH_ERROR_DWELL_MS = 3e3;
@@ -86,6 +103,9 @@ function waitForDwell(ms, signal) {
86
103
  * │
87
104
  * ▼
88
105
  * recording ⇄ switchingCamera
106
+ * │ │ busy camera (ENG-57332)
107
+ * │ ▼
108
+ * │ releasingCamera ─settle▶ retry once
89
109
  * │ (capture validated → DETECTION_DONE,
90
110
  * │ or manual NEXT_STEP)
91
111
  * last step ─▶ finalizing ─▶ finished
@@ -110,7 +130,8 @@ const videoSelfieRecordingSetup = setup({
110
130
  ID_FLIP_DWELL: ID_FLIP_DWELL_MS,
111
131
  FINAL_SUCCESS_DWELL: FINAL_SUCCESS_DWELL_MS,
112
132
  MAX_VIDEO_LENGTH_ERROR_DWELL: MAX_VIDEO_LENGTH_ERROR_DWELL_MS,
113
- VALIDATION_FEEDBACK_DWELL: VALIDATION_FEEDBACK_DWELL_MS
133
+ VALIDATION_FEEDBACK_DWELL: VALIDATION_FEEDBACK_DWELL_MS,
134
+ CAMERA_RELEASE_SETTLE: CAMERA_RELEASE_SETTLE_MS
114
135
  },
115
136
  actors: {
116
137
  prepareWasm: fromPromise(async ({ input }) => input.ensure()),
@@ -219,7 +240,8 @@ const videoSelfieRecordingSetup = setup({
219
240
  advanceStep: assign({
220
241
  stepIndex: ({ context }) => context.stepIndex + 1,
221
242
  attemptsRemaining: ({ context }) => context.attemptsPerStep,
222
- validationFailure: () => void 0
243
+ validationFailure: () => void 0,
244
+ cameraSwitchRetried: () => false
223
245
  }),
224
246
  setDetectionStatus: assign({ detectionStatus: ({ event }) => detectionStatusFromEvent(event) }),
225
247
  setOrientation: assign({ orientation: ({ event }) => orientationFromEvent(event) }),
@@ -263,6 +285,7 @@ const videoSelfieRecordingSetup = setup({
263
285
  }),
264
286
  resetSession: assign(({ context }) => ({
265
287
  stepIndex: 0,
288
+ cameraSwitchRetried: false,
266
289
  stream: void 0,
267
290
  composite: void 0,
268
291
  detectionStatus: void 0,
@@ -299,7 +322,10 @@ const videoSelfieRecordingSetup = setup({
299
322
  setPauseError: assign({
300
323
  error: () => "Recording could not be paused before backgrounding",
301
324
  errorKind: () => "technical"
302
- })
325
+ }),
326
+ releaseCurrentVideo: ({ context }) => {
327
+ context.stream?.getVideoTracks().forEach((track) => track.stop());
328
+ }
303
329
  },
304
330
  guards: {
305
331
  shouldEnterWasmGate: ({ context }) => context.ensureWasmReady !== void 0 && context.errorKind !== "maxVideoLengthReached" && context.errorKind !== "validationAttemptsExhausted",
@@ -311,6 +337,7 @@ const videoSelfieRecordingSetup = setup({
311
337
  maxVideoLengthWasReached: ({ context }) => context.errorKind === "maxVideoLengthReached",
312
338
  validationAttemptsWereExhausted: ({ context }) => context.errorKind === "validationAttemptsExhausted",
313
339
  errorIsRetryable: ({ context }) => context.errorKind !== "maxVideoLengthReached" && context.errorKind !== "validationAttemptsExhausted",
340
+ canRetryCameraSwitchAfterRelease: ({ context, event }) => !context.cameraSwitchRetried && isCameraBusyError(event.error),
314
341
  pageIsHidden: ({ context }) => !context.isPageVisible,
315
342
  pauseFailed: ({ event }) => !event.output,
316
343
  pauseSucceededWhileVisible: ({ context, event }) => context.isPageVisible && event.output,
@@ -347,9 +374,10 @@ const videoSelfieRecordingMachine = videoSelfieRecordingSetup.createMachine({
347
374
  initial: "idle",
348
375
  context: ({ input }) => {
349
376
  const visibilityObserver = input.visibilityObserver;
377
+ const compositor = input.dependencies?.createCompositor?.() ?? createRecordingCompositor();
350
378
  return {
351
- service: input.dependencies?.createRecordingService?.() ?? new MultipartRecordingService(),
352
- compositor: input.dependencies?.createCompositor?.() ?? new CameraCompositor(),
379
+ service: input.dependencies?.createRecordingService?.() ?? new MultipartRecordingService("videoselfie", new WorkerEncoderRecordingProvider(compositor)),
380
+ compositor,
353
381
  acquireCamera: input.dependencies?.acquireCamera ?? defaultAcquireCamera,
354
382
  ensureWasmReady: input.ensureWasmReady,
355
383
  detect: input.dependencies?.detect ?? manualStepDetector,
@@ -371,7 +399,8 @@ const videoSelfieRecordingMachine = videoSelfieRecordingSetup.createMachine({
371
399
  recordingId: null,
372
400
  error: void 0,
373
401
  errorKind: void 0,
374
- switchingCameraMinDwellMs: input.dependencies?.switchingCameraMinDwellMs ?? SWITCHING_CAMERA_MIN_DWELL_MS
402
+ switchingCameraMinDwellMs: input.dependencies?.switchingCameraMinDwellMs ?? SWITCHING_CAMERA_MIN_DWELL_MS,
403
+ cameraSwitchRetried: false
375
404
  };
376
405
  },
377
406
  invoke: [{
@@ -542,12 +571,29 @@ const videoSelfieRecordingMachine = videoSelfieRecordingSetup.createMachine({
542
571
  context.compositor.switchVideo(eventOutputStream(event));
543
572
  }, assign({ stream: ({ event }) => eventOutputStream(event) })]
544
573
  },
545
- onError: {
574
+ onError: [{
575
+ target: "releasingCamera",
576
+ guard: "canRetryCameraSwitchAfterRelease"
577
+ }, {
546
578
  target: "error",
547
579
  actions: assign({ error: ({ event }) => errorFromEvent(event) })
548
- }
580
+ }]
549
581
  }
550
582
  },
583
+ releasingCamera: {
584
+ entry: ["releaseCurrentVideo", assign({ cameraSwitchRetried: () => true })],
585
+ on: {
586
+ BACKGROUND: {
587
+ target: "pausing",
588
+ actions: ["markPageHidden", assign({ resumeState: () => "switchingCamera" })]
589
+ },
590
+ MAX_VIDEO_LENGTH_REACHED: {
591
+ target: "finalizing",
592
+ actions: "setMaxVideoLengthReached"
593
+ }
594
+ },
595
+ after: { CAMERA_RELEASE_SETTLE: { target: "switchingCamera" } }
596
+ },
551
597
  pausing: {
552
598
  on: { MAX_VIDEO_LENGTH_REACHED: { actions: "setMaxVideoLengthReached" } },
553
599
  invoke: {
@@ -838,7 +884,7 @@ function createVideoSelfieRecordingActor(visibilityObserver, options = {}) {
838
884
  function mapState(snapshot) {
839
885
  const value = typeof snapshot.value === "string" ? snapshot.value : "idle";
840
886
  const { context } = snapshot;
841
- const status = value === "preparingWasm" || value === "acquiringCamera" ? "starting" : value === "pausing" || value === "suspended" || value === "resumingCompositor" || value === "reacquiringCamera" || value === "validatingRecoveredCamera" || value === "resumingRecorder" ? "recording" : value;
887
+ const status = value === "preparingWasm" || value === "acquiringCamera" ? "starting" : value === "pausing" || value === "suspended" || value === "resumingCompositor" || value === "reacquiringCamera" || value === "validatingRecoveredCamera" || value === "resumingRecorder" ? "recording" : value === "releasingCamera" ? "switchingCamera" : value;
842
888
  const steps = context.steps;
843
889
  const stepIndex = context.stepIndex;
844
890
  return {
@@ -1,16 +1,16 @@
1
1
  import { t as BrowserTimerProvider } from "./BrowserTimerProvider-BXhgNxLt.esm.js";
2
2
  import { t as api } from "./api-Bx3gKW_y.esm.js";
3
3
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
4
- import { d as facingModeForStep, f as resolveVideoSelfieSteps } from "./flowServices-C8CBt9j3.esm.js";
4
+ import { d as facingModeForStep, f as resolveVideoSelfieSteps } from "./flowServices-pIc1cq8q.esm.js";
5
5
  import { a as requestCameraWithFallback, i as requestCameraAccess } from "./camera-sIa9ceW2.esm.js";
6
- import { t as checkPermission } from "./permissionServices-Bj_fyWtv.esm.js";
7
- import { n as encryptSelfieImage, o as startDetection, t as FaceDetectionProvider } from "./FaceDetectionProvider-C7bUZsH9.esm.js";
6
+ import { t as checkPermission } from "./permissionServices-EY3_Vx6c.esm.js";
7
+ import { n as encryptSelfieImage, o as startDetection, t as FaceDetectionProvider } from "./FaceDetectionProvider-Lb6i4Ilt.esm.js";
8
8
  import { t as FACE_ERROR_CODES } from "./types-BN5RPPIZ.esm.js";
9
- import { t as StreamCanvasProcessingSession } from "./StreamCanvasProcessingSession-CBnbTnOr.esm.js";
9
+ import { o as StreamCanvasProcessingSession } from "./multipartRecordingService-mwKFTlhR.esm.js";
10
10
  import { n as getBackCameraStream } from "./backCameraStream-B0-YgP_y.esm.js";
11
11
  import { n as getWindowDimensions } from "./getDeviceClass-CeBiEayS.esm.js";
12
12
  import { a as uploadSelfie, r as processFace, t as getFaceErrorCodeFromUnknown } from "./selfieErrorUtils-UiQ46EBa.esm.js";
13
- import { n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider, t as DEFAULT_ID_CAPTURE_GEOMETRY } from "./idCaptureDefaults-DCmwAxkz.esm.js";
13
+ import { n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider, t as DEFAULT_ID_CAPTURE_GEOMETRY } from "./idCaptureDefaults-BmnsDgZZ.esm.js";
14
14
  import { t as StreamCanvasCapture } from "./StreamCanvasCapture-C9jtgBdT.esm.js";
15
15
  //#region src/modules/video-selfie/videoSelfieCompareService.ts
16
16
  async function postVideoSelfieCompare(endpoint, base64Image) {
@@ -29,6 +29,19 @@ type FacingMode = 'user' | 'environment';
29
29
  //#region ../infra/src/media/CameraCompositor.d.ts
30
30
  type CameraCompositorOptions = {
31
31
  fps?: number;
32
+ maxLongEdge?: number;
33
+ maxShortEdge?: number;
34
+ /** Worker transport: drop frames to hold the output at `fps`. */
35
+ paceWorkerFrames?: boolean;
36
+ /**
37
+ * Worker transport: record by encoding inside the worker (see
38
+ * {@link CameraCompositor.startWorkerRecording}) instead of handing the
39
+ * composite stream to a `MediaRecorder`.
40
+ */
41
+ encodeInWorker?: {
42
+ bitrate: number;
43
+ timesliceMs: number;
44
+ };
32
45
  resumeTimeoutMs?: number;
33
46
  };
34
47
  type CameraCompositorResumeResult = 'resumed' | 'video-ended' | 'audio-ended' | 'timed-out';
@@ -50,6 +63,10 @@ type CameraCompositorResumeResult = 'resumed' | 'video-ended' | 'audio-ended' |
50
63
  * `captureStream`, for Safari, Firefox and strict-CSP hosts that block blob
51
64
  * workers.
52
65
  *
66
+ * With `encodeInWorker`, the worker transport also records: it encodes and
67
+ * muxes the WebM itself (see `startWorkerRecording`), so no `MediaRecorder`
68
+ * — which needs the main thread for every frame — is involved.
69
+ *
53
70
  * A worker that dies mid-recording (GPU-process crash, OOM) is released at
54
71
  * once; the composite track stays valid but receives no further frames, and
55
72
  * the next `resume()` reports `timed-out` so the caller reacquires the camera
@@ -62,6 +79,14 @@ declare class CameraCompositor {
62
79
  private readonly fps;
63
80
  private readonly frameIntervalMs;
64
81
  private readonly resumeTimeoutMs;
82
+ private readonly maxLongEdge;
83
+ private readonly maxShortEdge;
84
+ private readonly paceWorkerFrames;
85
+ private readonly encodeInWorker;
86
+ private workerEncoding;
87
+ private onWorkerPart;
88
+ private workerRecordingError;
89
+ private workerRecordingStopped;
65
90
  private canvas;
66
91
  private ctx;
67
92
  private video;
@@ -90,6 +115,30 @@ declare class CameraCompositor {
90
115
  * video track is stopped.
91
116
  */
92
117
  switchVideo(stream: CameraStream): void;
118
+ /**
119
+ * True when this compositor records by itself: the worker transport started
120
+ * with `encodeInWorker` and the browser has `VideoEncoder`. Use the
121
+ * `*WorkerRecording` methods instead of a `MediaRecorder` then; the
122
+ * composite stream receives no frames.
123
+ */
124
+ get encodesInWorker(): boolean;
125
+ /** Last in-worker encoder error, if any. */
126
+ get workerRecordingErrorMessage(): string | null;
127
+ /**
128
+ * Start a new WebM recording inside the worker. `onPart` receives whole
129
+ * WebM clusters (~`timesliceMs` each, keyframe first; the first part also
130
+ * carries the header), in order. Returns false when not encoding in-worker.
131
+ */
132
+ startWorkerRecording(onPart: (chunk: Blob) => void): boolean;
133
+ pauseWorkerRecording(): boolean;
134
+ resumeWorkerRecording(): boolean;
135
+ /**
136
+ * Flush the encoder and resolve once every part has reached `onPart`.
137
+ * Resolves at once if the worker is gone (its buffered frames are lost).
138
+ */
139
+ stopWorkerRecording(): Promise<void>;
140
+ /** Stop in-worker recording and drop whatever it still emits. */
141
+ cancelWorkerRecording(): void;
93
142
  /** The composite stream being recorded, if compositing is active. */
94
143
  get stream(): MediaStream | undefined;
95
144
  /** Pause source playback and drawing while the page is backgrounded. */
@@ -363,6 +363,11 @@ var WasmRuntime = class WasmRuntime {
363
363
  captureProtectedFrame(target) {
364
364
  return this.requireCameraCycleApi("Unable to capture protected frame, cpp API hasn't been initialized").mcp(target);
365
365
  }
366
+ /**
367
+ * @deprecated Unused by SDK 2 production flows.
368
+ * Retained for compatibility; avoid new uses.
369
+ * Candidate for removal after a compatibility review.
370
+ */
366
371
  paintFrameToCanvas(canvas, options) {
367
372
  return this.requireCameraCycleApi("Unable to paint frame, cpp API hasn't been initialized").pfc(canvas, options);
368
373
  }
package/dist/wasm.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as WASM_MODEL_FILES, c as WasmPipeline, l as WasmSource, o as WasmGlueLoader, r as warmupWasm, s as WasmModelName, t as WarmupConfig } from "./warmup-Cis2p6O0.js";
2
- import { c as setWasmConfig, i as initializeWasmUtil, n as WasmConfig, r as ensureWasmPipelines, s as resolveWasmConfigForPipelines, u as upgradeToWasmHttpClient } from "./setup-CLfBztP0.js";
2
+ import { c as setWasmConfig, i as initializeWasmUtil, n as WasmConfig, r as ensureWasmPipelines, s as resolveWasmConfigForPipelines, u as upgradeToWasmHttpClient } from "./setup-Cyko6cAn.js";
3
3
  //#region ../infra/src/wasm/wasmDefaults.d.ts
4
4
  /** The WASM version bundled and tested with this SDK release. */
5
5
  declare const DEFAULT_WASM_VERSION = "v2.14.50-post1";
package/dist/wasm.esm.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { g as WASM_PIPELINE_MODEL_NAMES, m as WASM_PIPELINE_LAZY_MODEL_NAMES, p as WASM_MODEL_FILES } from "./wasmWebClient-B7baE-Wf.esm.js";
2
- import { D as buildWasmConfigFromBasePath, E as buildDefaultWasmConfig, T as DEFAULT_WASM_VERSION, k as resolveWasmConfig } from "./trueSightService-C1JG8gAU.esm.js";
3
- import { o as warmupWasm } from "./warmup-CUUnwYxe.esm.js";
4
- import { a as resolveWasmConfigForPipelines, c as upgradeToWasmHttpClient, n as initializeWasmUtil, o as setWasmConfig, t as ensureWasmPipelines } from "./setup-BttZ27hw.esm.js";
2
+ import { C as DEFAULT_WASM_VERSION, D as resolveWasmConfig, T as buildWasmConfigFromBasePath, w as buildDefaultWasmConfig } from "./trueSightService-Di5RGIls.esm.js";
3
+ import { o as warmupWasm } from "./warmup-ChDwHSel.esm.js";
4
+ import { a as resolveWasmConfigForPipelines, c as upgradeToWasmHttpClient, n as initializeWasmUtil, o as setWasmConfig, t as ensureWasmPipelines } from "./setup-Cc6MzR5Q.esm.js";
5
5
  //#region src/defineWasm.ts
6
6
  function requiredModels(pipelines) {
7
7
  const models = /* @__PURE__ */ new Set();
@@ -1,4 +1,4 @@
1
- import { a as utilityWasmApi } from "./safeStorage-B-trhxg6.esm.js";
1
+ import { a as utilityWasmApi } from "./safeStorage-BdU9_m2E.esm.js";
2
2
  //#region ../infra/src/wasm/wasmDsFlagSync.ts
3
3
  /**
4
4
  * Sets the Deepsight (ds) flag that the WASM utility API receives on every
@@ -334,10 +334,6 @@ declare const workflowMachine: StateMachine<WorkflowContext, {
334
334
  id: string | undefined;
335
335
  };
336
336
  }>, Values<{
337
- setError: {
338
- type: "setError";
339
- params: NonReducibleUnknown;
340
- };
341
337
  setLoadingResult: {
342
338
  type: "setLoadingResult";
343
339
  params: NonReducibleUnknown;
@@ -370,6 +366,10 @@ declare const workflowMachine: StateMachine<WorkflowContext, {
370
366
  type: "setFinishStatusFailed";
371
367
  params: NonReducibleUnknown;
372
368
  };
369
+ setError: {
370
+ type: "setError";
371
+ params: NonReducibleUnknown;
372
+ };
373
373
  setModuleError: {
374
374
  type: "setModuleError";
375
375
  params: NonReducibleUnknown;
@@ -1,29 +1,29 @@
1
- import { l as trueSightLog } from "./trueSightService-C1JG8gAU.esm.js";
2
- import { E as updateFeatureManagementUser } from "./feature-management-BjROP6fF.esm.js";
1
+ import { l as trueSightLog } from "./trueSightService-Di5RGIls.esm.js";
2
+ import { E as updateFeatureManagementUser } from "./feature-management-BG6sf4O4.esm.js";
3
3
  import { t as api } from "./api-Bx3gKW_y.esm.js";
4
4
  import { n as eventModuleNames, o as createManagerInstrumentation, v as addEvent } from "./events-ijlbX_Wx.esm.js";
5
- import { i as initializeSession, r as getSessionFingerprintResult } from "./sessionInitializer-DSf0jyab.esm.js";
5
+ import { i as initializeSession, r as getSessionFingerprintResult } from "./sessionInitializer-BqGb0lFN.esm.js";
6
6
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
7
- import { i as toIncodeApiError } from "./apiError-BWlcyGbw.esm.js";
8
- import { v as toEkybConfig } from "./flowServices-C8CBt9j3.esm.js";
7
+ import { i as toIncodeApiError } from "./apiError-Dkl9_HOx.esm.js";
8
+ import { v as toEkybConfig } from "./flowServices-pIc1cq8q.esm.js";
9
9
  import { i as toEkycConfig } from "./ekycUtils-Dew1rBG0.esm.js";
10
10
  import { i as assign, s as createActor, t as setup, u as createManager } from "./xstate.esm-BuFLFuzz.esm.js";
11
11
  import { n as fromPromise } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
12
- import { r as electronicSignatureMachine } from "./electronicSignatureManager-BnlLBzH6.esm.js";
12
+ import { r as electronicSignatureMachine } from "./electronicSignatureManager-DGEUq9nY.esm.js";
13
13
  import "./ae-signature.esm.js";
14
14
  import { t as antifraudMachine } from "./antifraudStateMachine-DBeq47D2.esm.js";
15
- import { t as authenticationMachine } from "./authenticationStateMachine-CSJtf13E.esm.js";
15
+ import { t as authenticationMachine } from "./authenticationStateMachine-CW7a9qpV.esm.js";
16
16
  import { t as certificateIssuanceMachine } from "./certificateIssuanceStateMachine-CxqS_nD-.esm.js";
17
17
  import { t as consentMachine } from "./consentStateMachine-DTSfdGiW.esm.js";
18
18
  import { t as curpValidationMachine } from "./curpValidationStateMachine-g5kMfuLj.esm.js";
19
19
  import { t as customWatchlistMachine } from "./customWatchlistStateMachine-DOQou6TW.esm.js";
20
- import { t as documentCaptureMachine } from "./documentCaptureStateMachine-DN2YOxdu.esm.js";
21
- import { t as dynamicFormsMachine } from "./dynamicFormsStateMachine-B00MVHEa.esm.js";
22
- import { t as ekybMachine } from "./ekybStateMachine-DHCg1B5d.esm.js";
20
+ import { t as documentCaptureMachine } from "./documentCaptureStateMachine-D312sSIu.esm.js";
21
+ import { t as dynamicFormsMachine } from "./dynamicFormsStateMachine-4EVsg15i.esm.js";
22
+ import { t as ekybMachine } from "./ekybStateMachine-Dwgt5Dqa.esm.js";
23
23
  import { t as ekycMachine } from "./ekycStateMachine-CshSNJhh.esm.js";
24
24
  import { t as emailMachine } from "./emailStateMachine-Bc_6oIYw.esm.js";
25
- import { t as selfieMachine } from "./selfieStateMachine-BhzbXmKN.esm.js";
26
- import { t as idCaptureMachine } from "./idCaptureStateMachine-Du4Q40uJ.esm.js";
25
+ import { t as selfieMachine } from "./selfieStateMachine-OsbjyRR6.esm.js";
26
+ import { t as idCaptureMachine } from "./idCaptureStateMachine-hY-RpDH_.esm.js";
27
27
  import { t as phoneMachine } from "./phoneStateMachine-CXdXufKg.esm.js";
28
28
  import { t as watchlistMachine } from "./watchlistStateMachine-CBqk2w-h.esm.js";
29
29
  import { t as watchlistForBusinessMachine } from "./watchlistForBusinessStateMachine-CJ-MvUre.esm.js";
@@ -32,12 +32,12 @@ import { t as mandatoryConsentMachine } from "./mandatoryConsentStateMachine-DC5
32
32
  import { t as idOcrStateMachine } from "./idOcrStateMachine-ClDEP-VI.esm.js";
33
33
  import { n as redirectToMobileMachine } from "./redirectToMobileStateMachine-CSWWgUTO.esm.js";
34
34
  import { t as signatureMachine } from "./signatureStateMachine-ce_XMA3l.esm.js";
35
- import { t as geolocationMachine } from "./geolocationStateMachine-BfNIvTHA.esm.js";
35
+ import { t as geolocationMachine } from "./geolocationStateMachine-Bixn87pI.esm.js";
36
36
  import { t as governmentValidationMachine } from "./governmentValidationStateMachine-CoaZOSTP.esm.js";
37
37
  import { t as idVerificationMachine } from "./idVerificationStateMachine-DbDVIh9t.esm.js";
38
38
  import { t as faceMatchMachine } from "./faceMatchStateMachine-mRIHQ3dA.esm.js";
39
- import { n as getFinishStatus, r as getTotalScoreStatus } from "./flowCompletionService-iyH7fw8r.esm.js";
40
- import { n as attachFlowEventEmitter, t as runChildModule } from "./runChildModule-CHjWYSMf.esm.js";
39
+ import { n as getFinishStatus, r as getTotalScoreStatus } from "./flowCompletionService-BusrkMdp.esm.js";
40
+ import { n as attachFlowEventEmitter, t as runChildModule } from "./runChildModule-kZQwHJ21.esm.js";
41
41
  import { n as isAdvanceableError } from "./advanceableErrors-CpF2cBy6.esm.js";
42
42
  import "./qe-signature.esm.js";
43
43
  import { t as videoSelfieFlowModuleMachine } from "./videoSelfieFlowModuleMachine-BUe2uACW.esm.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@incodetech/core",
3
- "version": "2.3.0-rc.9",
3
+ "version": "2.3.0",
4
4
  "license": "ISC",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,11 +50,6 @@
50
50
  "types": "./dist/id-selfie-flow.d.ts",
51
51
  "import": "./dist/id-selfie-flow.esm.js"
52
52
  },
53
- "./personhood": {
54
- "source": "./src/modules/personhood/index.ts",
55
- "types": "./dist/personhood.d.ts",
56
- "import": "./dist/personhood.esm.js"
57
- },
58
53
  "./authentication": {
59
54
  "source": "./src/modules/authentication/index.ts",
60
55
  "types": "./dist/authentication.d.ts",
@@ -277,7 +272,7 @@
277
272
  "typescript": "^5.9.3",
278
273
  "vitest": "4.1.10",
279
274
  "@incodetech/config": "1.0.2",
280
- "@incodetech/infra": "1.3.0"
275
+ "@incodetech/infra": "1.4.0"
281
276
  },
282
277
  "scripts": {
283
278
  "build": "tsdown -c tsdown.config.ts",
@@ -1,36 +0,0 @@
1
- import { c as FaceAttributesThresholds, d as FaceDetectionCallbacks, f as FaceDetectionConfig, h as IFaceDetectionCapability, l as FaceChecksConfig, m as FacePositionConstraints, p as FaceDetectionThresholds, v as WebApiHostRequestConfig } from "./createFaceAvatar-BlcTYgJv.js";
2
- import { t as BaseWasmProvider } from "./BaseWasmProvider-Dyi6dKp1.js";
3
- //#region ../infra/src/providers/wasm/FaceDetectionProvider.d.ts
4
- declare class FaceDetectionProvider extends BaseWasmProvider implements IFaceDetectionCapability {
5
- private defaultThresholds;
6
- private currentThresholds;
7
- private currentFrame;
8
- private onFaceDataCallback;
9
- constructor();
10
- processFrame(image: ImageData): Promise<void>;
11
- initialize(config: FaceDetectionConfig): Promise<void>;
12
- /**
13
- * Last-registered onCapture callback — captured into a private
14
- * field so `forceCapture()` (called from outside the WASM-callback
15
- * lifecycle) can re-fire the same wrapper. `setCallbacks` rebinds
16
- * this on each invocation, so the field always reflects the
17
- * current consumer.
18
- */
19
- private currentOnCaptureWrapper;
20
- processPhoto(canvas: HTMLCanvasElement): void;
21
- postFaceResults(config?: WebApiHostRequestConfig): Promise<unknown>;
22
- setCallbacks(callbacks: FaceDetectionCallbacks): void;
23
- setPositionConstraints(constraints: FacePositionConstraints): void;
24
- applyDefaults(autocaptureInterval?: number): void;
25
- setAutocaptureInterval(interval: number): void;
26
- setThresholds(thresholds: FaceDetectionThresholds): void;
27
- setAttributesThresholds(thresholds: FaceAttributesThresholds): void;
28
- setChecksEnabled(config: FaceChecksConfig): void;
29
- setVideoSelfieMode(enabled: boolean): void;
30
- forceCapture(): void;
31
- reset(): void;
32
- private createDefaultFaceCoordinates;
33
- private formatFaceCoordinates;
34
- }
35
- //#endregion
36
- export { FaceDetectionProvider as t };
@@ -1,42 +0,0 @@
1
- //#region ../infra/src/media/StreamCanvasProcessingSession.ts
2
- var StreamCanvasProcessingSession = class {
3
- /**
4
- * Creates a processing session that reacts to `StreamCanvasCapture` frame events
5
- * and drives a provider's `processFrame()` method with backpressure.
6
- */
7
- constructor(params) {
8
- this.disposed = false;
9
- this.isProcessing = false;
10
- this.onFrameEvent = () => {
11
- if (this.disposed || this.isProcessing) return;
12
- const frame = this.capturer.getLatestFrame();
13
- if (!frame) return;
14
- this.onFrame?.(frame);
15
- this.isProcessing = true;
16
- this.provider.processFrame(frame).catch(() => {}).finally(() => {
17
- this.isProcessing = false;
18
- });
19
- };
20
- this.capturer = params.capturer;
21
- this.provider = params.provider;
22
- this.onFrame = params.onFrame;
23
- this.capturer.addEventListener("frame", this.onFrameEvent);
24
- }
25
- /**
26
- * Unsubscribes from frame events and resets the provider.
27
- */
28
- dispose() {
29
- if (this.disposed) return;
30
- this.disposed = true;
31
- this.capturer.removeEventListener("frame", this.onFrameEvent);
32
- this.provider.reset();
33
- }
34
- /**
35
- * Returns whether the session has been disposed.
36
- */
37
- isDisposed() {
38
- return this.disposed;
39
- }
40
- };
41
- //#endregion
42
- export { StreamCanvasProcessingSession as t };