@incodetech/core 2.3.0-rc.1 → 2.3.0-rc.2

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 (54) hide show
  1. package/dist/{BrowserDiagnosticsCryptoProvider-CU6kBvqv.esm.js → BrowserDiagnosticsCryptoProvider-Crg8fwBl.esm.js} +1 -1
  2. package/dist/{FaceDetectionProvider-BfhWkK90.esm.js → FaceDetectionProvider-i55W_Jkj.esm.js} +4 -4
  3. package/dist/ae-signature.esm.js +1 -1
  4. package/dist/{apiError-Budb6m6w.esm.js → apiError-DcnaKSwk.esm.js} +1 -1
  5. package/dist/authentication.esm.js +2 -2
  6. package/dist/{authenticationManager-cMXhG70r.esm.js → authenticationManager-D-UWdyhr.esm.js} +3 -3
  7. package/dist/{authenticationStateMachine-MOYz4HCf.esm.js → authenticationStateMachine-Cklrmjfo.esm.js} +2 -2
  8. package/dist/{deepsightLoader-DDv3vhXU.esm.js → deepsightLoader-BNDIPbEK.esm.js} +3 -3
  9. package/dist/dynamic-forms.esm.js +2 -2
  10. package/dist/{dynamicFormsManager-BbS-XMFc.esm.js → dynamicFormsManager-DOu0Xgs0.esm.js} +1 -1
  11. package/dist/{dynamicFormsStateMachine-D8zHBCh4.esm.js → dynamicFormsStateMachine-DehYndAZ.esm.js} +1 -1
  12. package/dist/ekyb.esm.js +3 -3
  13. package/dist/{ekybManager-5aiac8wL.esm.js → ekybManager-CCcz4-FC.esm.js} +1 -1
  14. package/dist/{ekybStateMachine-Bn2IE9rx.esm.js → ekybStateMachine-xesYf5pK.esm.js} +1 -1
  15. package/dist/electronic-signature.esm.js +1 -1
  16. package/dist/{electronicSignatureManager-BJJH0Tvi.esm.js → electronicSignatureManager-8VGN2aKU.esm.js} +1 -1
  17. package/dist/extensibility.d.ts +1 -1
  18. package/dist/extensibility.esm.js +10 -10
  19. package/dist/{faceCaptureManagerFactory-B7Ms6pSs.esm.js → faceCaptureManagerFactory-Bl6EffXD.esm.js} +1 -1
  20. package/dist/{faceCaptureSetup-bkAlr5d8.esm.js → faceCaptureSetup-CDGmqC8J.esm.js} +24 -3
  21. package/dist/{feature-management-E0mq0pMs.esm.js → feature-management-J3rr-HDW.esm.js} +1 -1
  22. package/dist/feature-management.esm.js +1 -1
  23. package/dist/flow.esm.js +3 -3
  24. package/dist/{flowCompletionService-DJp1odGN.esm.js → flowCompletionService-CayNS1FR.esm.js} +1 -1
  25. package/dist/{flowServices-DjPFGs_D.esm.js → flowServices-DX5ygAyn.esm.js} +4 -4
  26. package/dist/geolocation.esm.js +2 -2
  27. package/dist/{geolocationManager-D5906YXx.esm.js → geolocationManager-DYXuNsN2.esm.js} +1 -1
  28. package/dist/{geolocationStateMachine-BVOduc3y.esm.js → geolocationStateMachine-C-37vSiR.esm.js} +1 -1
  29. package/dist/id-selfie-flow.esm.js +7 -7
  30. package/dist/id.d.ts +2 -2
  31. package/dist/id.esm.js +4 -4
  32. package/dist/{idCaptureDefaults-CbPA-Auz.esm.js → idCaptureDefaults-CxOh31Xf.esm.js} +1 -1
  33. package/dist/{idCaptureManager-rfV9dIXy.esm.js → idCaptureManager-BFtpmjsP.esm.js} +3 -3
  34. package/dist/{idCaptureManager-DKESug0R.d.ts → idCaptureManager-De7O0TOD.d.ts} +23 -4
  35. package/dist/{idCaptureServices-i1KxugN7.esm.js → idCaptureServices-C7aPT72E.esm.js} +57 -10
  36. package/dist/{idCaptureStateMachine-Ne_PXth_.esm.js → idCaptureStateMachine-BEbzg_R1.esm.js} +210 -66
  37. package/dist/index.esm.js +1 -1
  38. package/dist/personhood.esm.js +4 -4
  39. package/dist/qe-signature.esm.js +1 -1
  40. package/dist/{runChildModule-CI1gGWN1.esm.js → runChildModule-CT0aKjFV.esm.js} +1 -1
  41. package/dist/{sdkVersion-BZh6dj53.esm.js → sdkVersion-DTrl2Jm7.esm.js} +1 -1
  42. package/dist/selfie.esm.js +5 -5
  43. package/dist/{selfieManager-B-2c1n_x.esm.js → selfieManager-0gvnAH1m.esm.js} +3 -3
  44. package/dist/{selfieStateMachine-Bzx41R8d.esm.js → selfieStateMachine-rfneTd9x.esm.js} +2 -2
  45. package/dist/{session-3LmvAU4S.esm.js → session-ZAdron5D.esm.js} +3 -3
  46. package/dist/session.esm.js +4 -4
  47. package/dist/{sessionInitializer-BFk33E67.esm.js → sessionInitializer-C1A6s33W.esm.js} +3 -3
  48. package/dist/{setup-BWG-hivt.esm.js → setup-6e71xCI7.esm.js} +4 -4
  49. package/dist/{trueSightService-BN-Hzw82.esm.js → trueSightService-DJ1kSDlH.esm.js} +2 -2
  50. package/dist/video-selfie.esm.js +4 -4
  51. package/dist/{videoSelfieCameraWarmer-B8PcYqmz.esm.js → videoSelfieCameraWarmer-BqXupt3L.esm.js} +3 -3
  52. package/dist/wasm.esm.js +1 -1
  53. package/dist/workflow.esm.js +14 -14
  54. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- import { t as ensureWasmPipelines } from "./setup-BWG-hivt.esm.js";
2
- import { i as numberParam, n as defineExperimentParams, t as booleanParam, u as resolveExperimentOnce } from "./feature-management-E0mq0pMs.esm.js";
1
+ import { t as ensureWasmPipelines } from "./setup-6e71xCI7.esm.js";
2
+ import { i as numberParam, n as defineExperimentParams, t as booleanParam, u as resolveExperimentOnce } from "./feature-management-J3rr-HDW.esm.js";
3
3
  import { t as api } from "./api-Bx3gKW_y.esm.js";
4
4
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
5
5
  import { i as isDesktop } from "./platform-DkcRc9JV.esm.js";
@@ -9,7 +9,7 @@ import { s as queryCameraPermission } from "./permissionServices-Bj_fyWtv.esm.js
9
9
  import { a as isBackFacingTrack, n as getBackCameraStream } from "./backCameraStream-BOtyQowf.esm.js";
10
10
  import { t as getDeviceClass } from "./getDeviceClass-5NYZg9s6.esm.js";
11
11
  import { t as MultipartRecordingService } from "./multipartRecordingService-OEgIRvqC.esm.js";
12
- import { i as CameraCompositor, n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider } from "./idCaptureDefaults-CbPA-Auz.esm.js";
12
+ import { i as CameraCompositor, n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider } from "./idCaptureDefaults-CxOh31Xf.esm.js";
13
13
  //#region src/internal/camera/cameraServices.ts
14
14
  function createCameraServices(camera) {
15
15
  return {
@@ -577,6 +577,7 @@ function createMultipartSessionHandle(service, compositor, recordingSource) {
577
577
  needsVideoSourceReplacement: false,
578
578
  recorderPaused: false,
579
579
  recordingSource,
580
+ audioSource: recordingSource.getAudioTracks(),
580
581
  service
581
582
  });
582
583
  return session;
@@ -620,21 +621,62 @@ function prepareRecordingForCameraRetry(session) {
620
621
  const multipartSession = multipartIdSessions.get(session);
621
622
  if (!multipartSession) return;
622
623
  if (!multipartSession.recorderPaused) multipartSession.recorderPaused = multipartSession.service.pause();
623
- multipartSession.compositor.pause();
624
- multipartSession.recordingSource.getVideoTracks().forEach((track) => track.stop());
624
+ releaseCameraClone(multipartSession, { keepAudio: true });
625
625
  multipartSession.needsVideoSourceReplacement = true;
626
626
  }
627
627
  /**
628
- * Fully drains an ID recording before the protected camera cycle runs POC.
629
- * Every recorder clone is stopped before this promise settles.
628
+ * Resumes a recording paused with `pauseRecordingForAttempt` while its camera
629
+ * clone is still attached (no source replacement pending). Returns whether the
630
+ * recorder is recording again.
631
+ */
632
+ function resumeRecordingAfterPause(session) {
633
+ const multipartSession = multipartIdSessions.get(session);
634
+ if (!multipartSession || multipartSession.needsVideoSourceReplacement) return false;
635
+ if (!multipartSession.recorderPaused) return true;
636
+ if (!multipartSession.service.resume()) return false;
637
+ multipartSession.recorderPaused = false;
638
+ return true;
639
+ }
640
+ /**
641
+ * True only for a live SDK-managed multipart session. A session that has
642
+ * already been finalized or disposed is no longer in the registry, so callers
643
+ * use this to avoid resuming or re-pausing a torn-down recording.
644
+ */
645
+ function isSuspendableRecordingSession(session) {
646
+ return multipartIdSessions.has(session);
647
+ }
648
+ /**
649
+ * Ends the compositor's camera clone on the calling thread. The composite
650
+ * stream and its upload stay alive; only the tracks that pin the physical
651
+ * camera end. `keepAudio` preserves the compositor's audio track across a
652
+ * video-source swap. Every release path must call this before any async work
653
+ * so no camera clone can overlap a PRC or POC camera switch (ENG-47407) or pin
654
+ * the device for the next module (ENG-56648).
655
+ */
656
+ function releaseCameraClone(multipartSession, options) {
657
+ try {
658
+ multipartSession.compositor.pause();
659
+ } catch {}
660
+ const tracks = options.keepAudio ? multipartSession.recordingSource.getVideoTracks() : /* @__PURE__ */ new Set([...multipartSession.recordingSource.getTracks(), ...multipartSession.audioSource]);
661
+ for (const track of tracks) try {
662
+ track.stop();
663
+ } catch {}
664
+ }
665
+ /**
666
+ * Completes an ID recording: drains the multipart upload and releases the
667
+ * compositor. The camera clone ends synchronously, before this function
668
+ * returns its promise, so a step that ends mid-attempt never pins the camera
669
+ * while the upload finishes (ENG-56648). The composite canvas stays alive until
670
+ * the recorder has emitted its final chunk.
630
671
  */
631
672
  async function finalizeRecordingSession(session) {
632
673
  const existing = idRecordingFinalizations.get(session);
633
674
  if (existing) return existing;
634
675
  const multipartSession = multipartIdSessions.get(session);
635
676
  if (!multipartSession) return {};
677
+ multipartIdSessions.delete(session);
678
+ releaseCameraClone(multipartSession, { keepAudio: false });
636
679
  const finalization = (async () => {
637
- multipartIdSessions.delete(session);
638
680
  try {
639
681
  return await multipartSession.service.stop();
640
682
  } finally {
@@ -644,11 +686,16 @@ async function finalizeRecordingSession(session) {
644
686
  idRecordingFinalizations.set(session, finalization);
645
687
  return finalization;
646
688
  }
647
- /** Synchronous teardown used when an attempt is cancelled before finalization. */
689
+ /**
690
+ * Teardown for an attempt released before finalization. The camera clone ends
691
+ * synchronously, before this function returns; the upload completes in the
692
+ * background with whatever was recorded.
693
+ */
648
694
  function disposeRecordingSession(session) {
649
695
  const multipartSession = multipartIdSessions.get(session);
650
696
  if (multipartSession) {
651
697
  multipartIdSessions.delete(session);
698
+ releaseCameraClone(multipartSession, { keepAudio: false });
652
699
  const finalization = multipartSession.service.stop().finally(() => multipartSession.compositor.stop());
653
700
  idRecordingFinalizations.set(session, finalization);
654
701
  finalization.catch(() => {});
@@ -732,4 +779,4 @@ async function addBarcode(params) {
732
779
  return res.data;
733
780
  }
734
781
  //#endregion
735
- export { resolveCaptureOptimizingTreatment as _, getRealQualityValue as a, OPTIMIZING_WATCHDOG_MARGIN_MS as b, prepareRecordingForCameraRetry as c, stopRecording as d, stopStream as f, ID_ERROR_CODES as g, validateUploadResponse as h, finalizeRecordingSession as i, processId as l, uploadManualIdFile as m, barcodeToBase64 as n, initializeIdCapture as o, uploadIdImage as p, disposeRecordingSession as r, pauseRecordingForAttempt as s, addBarcode as t, startRecordingSession as u, resolveIdCaptureThresholds as v, getIdCameraStream as x, CAPTURE_OPTIMIZING as y };
782
+ export { getIdCameraStream as C, OPTIMIZING_WATCHDOG_MARGIN_MS as S, validateUploadResponse as _, getRealQualityValue as a, resolveIdCaptureThresholds as b, pauseRecordingForAttempt as c, resumeRecordingAfterPause as d, startRecordingSession as f, uploadManualIdFile as g, uploadIdImage as h, finalizeRecordingSession as i, prepareRecordingForCameraRetry as l, stopStream as m, barcodeToBase64 as n, initializeIdCapture as o, stopRecording as p, disposeRecordingSession as r, isSuspendableRecordingSession as s, addBarcode as t, processId as u, ID_ERROR_CODES as v, CAPTURE_OPTIMIZING as x, resolveCaptureOptimizingTreatment as y };
@@ -1,16 +1,16 @@
1
- import { l as BrowserStorageProvider } from "./setup-BWG-hivt.esm.js";
1
+ import { l as BrowserStorageProvider } from "./setup-6e71xCI7.esm.js";
2
2
  import { r as WasmUtilProvider } from "./safeStorage-B-trhxg6.esm.js";
3
3
  import { t as BrowserTimerProvider } from "./BrowserTimerProvider-BXhgNxLt.esm.js";
4
- import { s as exposeExperimentOnce } from "./feature-management-E0mq0pMs.esm.js";
4
+ import { s as exposeExperimentOnce } from "./feature-management-J3rr-HDW.esm.js";
5
5
  import { n as revokeObjectURL, t as getTimestamp } from "./IBrowserEnvironmentCapability-DEaRRk-R.esm.js";
6
6
  import { r as getToken, t as api } from "./api-Bx3gKW_y.esm.js";
7
- import { c as trueSightHintTransition, l as trueSightLog, m as isTrueSightTesting, r as noteTrueSightCaptureActivity } from "./trueSightService-BN-Hzw82.esm.js";
7
+ import { c as trueSightHintTransition, l as trueSightLog, m as isTrueSightTesting, r as noteTrueSightCaptureActivity } from "./trueSightService-DJ1kSDlH.esm.js";
8
8
  import { n as eventModuleNames, s as recordExperimentAssignmentOnce } from "./events-ijlbX_Wx.esm.js";
9
- import { t as getDisableIpify } from "./sessionInitializer-BFk33E67.esm.js";
9
+ import { t as getDisableIpify } from "./sessionInitializer-C1A6s33W.esm.js";
10
10
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
11
11
  import { t as addDeviceStats } from "./stats-CZcy2J53.esm.js";
12
12
  import { a as isIOS, s as isIPad, t as isAndroid, u as isMacOsSafari } from "./platform-DkcRc9JV.esm.js";
13
- import "./session-3LmvAU4S.esm.js";
13
+ import "./session-ZAdron5D.esm.js";
14
14
  import { c as not, i as assign, l as raise, n as enqueueActions, o as and, r as sendTo, t as setup } from "./xstate.esm-BuFLFuzz.esm.js";
15
15
  import { n as fromPromise, t as fromCallback } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
16
16
  import { n as getUrlSearchParam, t as buildUrlWithSearchParams } from "./urlUtils-D6phjq1-.esm.js";
@@ -24,8 +24,8 @@ import { t as sleep } from "./ITimerCapability-DgdDzp8G.esm.js";
24
24
  import { t as getBrowser } from "./getBrowser-Cbe1C4Tn.esm.js";
25
25
  import { n as getWindowDimensions } from "./getDeviceClass-CeBiEayS.esm.js";
26
26
  import { n as runVirtualCameraCheck, t as frameSources } from "./virtualCameraCheck-Cjab7FTI.esm.js";
27
- import { n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider } from "./idCaptureDefaults-CbPA-Auz.esm.js";
28
- import { a as getRealQualityValue, b as OPTIMIZING_WATCHDOG_MARGIN_MS, c as prepareRecordingForCameraRetry, d as stopRecording, f as stopStream, g as ID_ERROR_CODES, h as validateUploadResponse, i as finalizeRecordingSession, l as processId, m as uploadManualIdFile, o as initializeIdCapture, p as uploadIdImage, r as disposeRecordingSession, t as addBarcode, u as startRecordingSession, v as resolveIdCaptureThresholds, x as getIdCameraStream, y as CAPTURE_OPTIMIZING } from "./idCaptureServices-i1KxugN7.esm.js";
27
+ import { n as DEFAULT_ID_CAPTURE_THRESHOLDS, r as IdCaptureProvider } from "./idCaptureDefaults-CxOh31Xf.esm.js";
28
+ import { C as getIdCameraStream, S as OPTIMIZING_WATCHDOG_MARGIN_MS, _ as validateUploadResponse, a as getRealQualityValue, b as resolveIdCaptureThresholds, c as pauseRecordingForAttempt, d as resumeRecordingAfterPause, f as startRecordingSession, g as uploadManualIdFile, h as uploadIdImage, i as finalizeRecordingSession, l as prepareRecordingForCameraRetry, m as stopStream, o as initializeIdCapture, p as stopRecording, r as disposeRecordingSession, s as isSuspendableRecordingSession, t as addBarcode, u as processId, v as ID_ERROR_CODES, x as CAPTURE_OPTIMIZING } from "./idCaptureServices-C7aPT72E.esm.js";
29
29
  import { t as StreamCanvasCapture } from "./StreamCanvasCapture-C9jtgBdT.esm.js";
30
30
  //#region src/modules/id/digitalUpload/digitalUploadErrors.ts
31
31
  const TERMINAL_FAIL_REASONS = /* @__PURE__ */ new Set(["DIGITAL_ID_REQUESTED_BUT_OTHER_PROVIDED", "ID_TYPE_UNACCEPTABLE"]);
@@ -1781,7 +1781,7 @@ fromPromise(async ({ input }) => {
1781
1781
  });
1782
1782
  fromPromise(async ({ input }) => {
1783
1783
  if (!input.dependencies) return;
1784
- const { loadDeepsightSession } = await import("./deepsightLoader-DDv3vhXU.esm.js");
1784
+ const { loadDeepsightSession } = await import("./deepsightLoader-BNDIPbEK.esm.js");
1785
1785
  return loadDeepsightSession({
1786
1786
  ds: input.ds,
1787
1787
  storage: input.dependencies.storage,
@@ -2224,7 +2224,7 @@ function cleanup(service) {
2224
2224
  service.cleanup();
2225
2225
  } catch {}
2226
2226
  }
2227
- function createIdMetadataPreparationCoordinator(load = async (input) => (await import("./deepsightLoader-DDv3vhXU.esm.js")).loadDeepsightSession(input)) {
2227
+ function createIdMetadataPreparationCoordinator(load = async (input) => (await import("./deepsightLoader-BNDIPbEK.esm.js")).loadDeepsightSession(input)) {
2228
2228
  let disposed = false;
2229
2229
  let preparation;
2230
2230
  let service;
@@ -2325,6 +2325,16 @@ function createIdProtectedCaptureController(dependencies = {}) {
2325
2325
  let attemptContext;
2326
2326
  let attemptSend;
2327
2327
  let diagnosticAttempt;
2328
+ const stepRecording = { retryPending: false };
2329
+ const recordingScopeFor = (context) => context.currentMode === "back" ? "backId" : "frontId";
2330
+ const completeStepRecording = () => {
2331
+ const session = stepRecording.session;
2332
+ stepRecording.session = void 0;
2333
+ stepRecording.scope = void 0;
2334
+ stepRecording.retryPending = false;
2335
+ if (!session) return;
2336
+ finalizeRecordingSession(session).catch(() => {});
2337
+ };
2328
2338
  const logDiagnostic = (event, fields = {}) => {
2329
2339
  if (!diagnosticAttempt) return;
2330
2340
  logIdCameraDiagnostic(event, {
@@ -2455,6 +2465,7 @@ function createIdProtectedCaptureController(dependencies = {}) {
2455
2465
  beginAttempt(context, send) {
2456
2466
  if (disposed) throw new Error("ID protected capture controller is disposed");
2457
2467
  clearAttempt();
2468
+ if (stepRecording.session && stepRecording.scope !== recordingScopeFor(context)) completeStepRecording();
2458
2469
  diagnosticAttempt = {
2459
2470
  attempt: ++protectedIdAttemptSequence,
2460
2471
  side: context.currentMode === "back" ? "back" : "front",
@@ -2492,6 +2503,27 @@ function createIdProtectedCaptureController(dependencies = {}) {
2492
2503
  metadataCoordinator.dispose();
2493
2504
  releasePreAcquired();
2494
2505
  clearAttempt();
2506
+ completeStepRecording();
2507
+ },
2508
+ getStepRecording() {
2509
+ return stepRecording;
2510
+ },
2511
+ keepRecordingForRetry() {
2512
+ stepRecording.retryPending = true;
2513
+ },
2514
+ completeStepRecording,
2515
+ endRecordingStep() {
2516
+ if (stepRecording.retryPending) {
2517
+ stepRecording.retryPending = false;
2518
+ return;
2519
+ }
2520
+ completeStepRecording();
2521
+ },
2522
+ pauseStepRecording() {
2523
+ if (stepRecording.session) pauseRecordingForAttempt(stepRecording.session);
2524
+ },
2525
+ resumeStepRecording() {
2526
+ if (stepRecording.session) resumeRecordingAfterPause(stepRecording.session);
2495
2527
  },
2496
2528
  preAcquire,
2497
2529
  setVisible(nextVisible) {
@@ -2738,33 +2770,118 @@ function createProtectedIdProvider(config) {
2738
2770
  const workflow = resolveProtectedIdWorkflow(config);
2739
2771
  return workflow === 0 ? new IdCaptureProvider() : new IdCaptureProvider(workflow);
2740
2772
  }
2773
+ /**
2774
+ * Recorder hooks for one protected ID attempt over a step-scoped recording.
2775
+ *
2776
+ * The attempt never completes the scoped upload. It starts or resumes the held
2777
+ * session after PRC, pauses it and ends its camera clone synchronously when the
2778
+ * capture is committed (before POC), and suspends it the same way on release.
2779
+ * The controller completes the upload when the backend accepts the capture or
2780
+ * when the step ends without a retry (ENG-56648). A session that is no longer
2781
+ * live — already finalized or disposed — cannot be paused, so it is dropped and
2782
+ * torn down instead.
2783
+ */
2741
2784
  function createProtectedIdRecorderHooks(input) {
2742
- let session;
2785
+ const holder = input.stepRecording ?? { retryPending: false };
2786
+ const scope = input.currentMode === "back" ? "backId" : "frontId";
2743
2787
  const enabled = input.enabled !== false && input.config.enableIdRecording === true;
2788
+ let disposed = false;
2789
+ const dropHeldSession = () => {
2790
+ const session = holder.session;
2791
+ holder.session = void 0;
2792
+ holder.scope = void 0;
2793
+ return session;
2794
+ };
2795
+ /**
2796
+ * Ends the camera clone on the calling thread and keeps the paused upload for
2797
+ * the next attempt. Idempotent; never finalizes a multipart session.
2798
+ */
2799
+ const suspend = () => {
2800
+ const session = holder.session;
2801
+ if (!session) return;
2802
+ if (!isSuspendableRecordingSession(session)) {
2803
+ dropHeldSession();
2804
+ disposeRecordingSession(session);
2805
+ return;
2806
+ }
2807
+ try {
2808
+ prepareRecordingForCameraRetry(session);
2809
+ } catch {}
2810
+ };
2811
+ const warn = (message) => {
2812
+ trueSightLog("warning", "recording", "idScan", message);
2813
+ };
2744
2814
  return {
2745
2815
  mode: enabled ? "finalizeBeforePoc" : "none",
2746
2816
  async start(stream) {
2747
2817
  if (!enabled) return;
2748
- session = await startRecordingSession({
2749
- config: input.config,
2750
- stream,
2751
- type: input.currentMode === "back" ? "backId" : "frontId"
2752
- });
2818
+ if (holder.session && holder.scope !== scope) {
2819
+ const stale = dropHeldSession();
2820
+ if (stale) disposeRecordingSession(stale);
2821
+ }
2822
+ const existing = holder.session;
2823
+ let session;
2824
+ try {
2825
+ session = await startRecordingSession({
2826
+ config: input.config,
2827
+ stream,
2828
+ type: scope,
2829
+ existing
2830
+ });
2831
+ } catch (error) {
2832
+ if (existing) {
2833
+ suspend();
2834
+ warn("ID recording did not resume for this attempt");
2835
+ return;
2836
+ }
2837
+ throw error;
2838
+ }
2839
+ if (disposed) {
2840
+ if (session && session !== existing) disposeRecordingSession(session);
2841
+ else suspend();
2842
+ return;
2843
+ }
2844
+ if (session) {
2845
+ holder.session = session;
2846
+ holder.scope = scope;
2847
+ }
2753
2848
  },
2754
2849
  async prepareForPoc() {
2850
+ const session = holder.session;
2755
2851
  if (!session) return {};
2756
- const currentSession = session;
2757
- session = void 0;
2758
- return finalizeRecordingSession(currentSession);
2852
+ if (!isSuspendableRecordingSession(session)) {
2853
+ dropHeldSession();
2854
+ return finalizeRecordingSession(session);
2855
+ }
2856
+ suspend();
2857
+ return {};
2759
2858
  },
2760
2859
  async resumeAfterPoc() {},
2761
- pauseForBackground() {},
2762
- async resumeFromBackground() {},
2860
+ pauseForBackground() {
2861
+ suspend();
2862
+ },
2863
+ async resumeFromBackground(stream) {
2864
+ const existing = holder.session;
2865
+ if (!enabled || disposed || !existing || holder.scope !== scope || !isSuspendableRecordingSession(existing)) return;
2866
+ try {
2867
+ await startRecordingSession({
2868
+ config: input.config,
2869
+ stream,
2870
+ type: scope,
2871
+ existing
2872
+ });
2873
+ } catch {
2874
+ suspend();
2875
+ warn("ID recording did not resume after foreground");
2876
+ }
2877
+ },
2763
2878
  dispose() {
2764
- input.disposeCaptureCallbacks();
2765
- if (!session) return;
2766
- disposeRecordingSession(session);
2767
- session = void 0;
2879
+ disposed = true;
2880
+ try {
2881
+ input.disposeCaptureCallbacks();
2882
+ } finally {
2883
+ suspend();
2884
+ }
2768
2885
  }
2769
2886
  };
2770
2887
  }
@@ -2995,7 +3112,8 @@ function createProtectedIdAttemptInput(input) {
2995
3112
  config: context.config,
2996
3113
  currentMode: context.currentMode,
2997
3114
  disposeCaptureCallbacks: callbackSession.dispose,
2998
- enabled: !captureOnly
3115
+ enabled: !captureOnly,
3116
+ stepRecording: controller.getStepRecording()
2999
3117
  }),
3000
3118
  releaseUnadoptedStream: stopStream,
3001
3119
  beforeAdopt: captureOnly ? void 0 : async (stream) => {
@@ -3788,6 +3906,21 @@ const idCaptureMachine = setup({
3788
3906
  clearProtectedAttempt: ({ self }) => {
3789
3907
  getIdProtectedCaptureController(self).clearAttempt();
3790
3908
  },
3909
+ keepProtectedRecordingForRetry: ({ self }) => {
3910
+ getIdProtectedCaptureController(self).keepRecordingForRetry();
3911
+ },
3912
+ completeProtectedRecording: ({ self }) => {
3913
+ getIdProtectedCaptureController(self).completeStepRecording();
3914
+ },
3915
+ endProtectedRecordingStep: ({ self }) => {
3916
+ getIdProtectedCaptureController(self).endRecordingStep();
3917
+ },
3918
+ pauseProtectedRecording: ({ self }) => {
3919
+ getIdProtectedCaptureController(self).pauseStepRecording();
3920
+ },
3921
+ resumeProtectedRecording: ({ self }) => {
3922
+ getIdProtectedCaptureController(self).resumeStepRecording();
3923
+ },
3791
3924
  disposeProvider: ({ context }) => {
3792
3925
  performDisposeProvider(context);
3793
3926
  },
@@ -4553,6 +4686,7 @@ const idCaptureMachine = setup({
4553
4686
  exit: [
4554
4687
  "stopMediaRecording",
4555
4688
  "clearRecordingSession",
4689
+ "endProtectedRecordingStep",
4556
4690
  "clearProtectedAttempt"
4557
4691
  ],
4558
4692
  invoke: {
@@ -4592,7 +4726,7 @@ const idCaptureMachine = setup({
4592
4726
  always: "#idCapture.closed"
4593
4727
  },
4594
4728
  releasingForRetry: {
4595
- entry: "releaseProtectedForRetry",
4729
+ entry: ["keepProtectedRecordingForRetry", "releaseProtectedForRetry"],
4596
4730
  always: {
4597
4731
  target: "#idCapture.capture",
4598
4732
  reenter: true
@@ -4760,21 +4894,27 @@ const idCaptureMachine = setup({
4760
4894
  onError: { target: "uploading" }
4761
4895
  } },
4762
4896
  capturingBarcode: { always: [{ target: "submittingBarcodePreCapture" }] },
4763
- submittingBarcodePreCapture: { invoke: {
4764
- id: "submitBarcode",
4765
- src: "submitBarcode",
4766
- input: ({ context }) => ({
4767
- rawBarcode: context.decodedBarcode?.text ?? "",
4768
- metrics: context.decodedBarcode,
4769
- processId: context.config.skipProcessId !== true,
4770
- minDurationMs: 1e3
4771
- }),
4772
- onDone: {
4773
- target: "success",
4774
- actions: ["storeBarcodeResponse", "markBarcodeFastPathCaptured"]
4775
- },
4776
- onError: { target: "choosingDetectionStrategy" }
4777
- } },
4897
+ submittingBarcodePreCapture: {
4898
+ entry: "pauseProtectedRecording",
4899
+ invoke: {
4900
+ id: "submitBarcode",
4901
+ src: "submitBarcode",
4902
+ input: ({ context }) => ({
4903
+ rawBarcode: context.decodedBarcode?.text ?? "",
4904
+ metrics: context.decodedBarcode,
4905
+ processId: context.config.skipProcessId !== true,
4906
+ minDurationMs: 1e3
4907
+ }),
4908
+ onDone: {
4909
+ target: "success",
4910
+ actions: ["storeBarcodeResponse", "markBarcodeFastPathCaptured"]
4911
+ },
4912
+ onError: {
4913
+ target: "choosingDetectionStrategy",
4914
+ actions: "resumeProtectedRecording"
4915
+ }
4916
+ }
4917
+ },
4778
4918
  capturingManual: {
4779
4919
  entry: "finalizeProtectedAttempt",
4780
4920
  on: { PROTECTED_ATTEMPT_FINALIZED_SIGNAL: [
@@ -4888,32 +5028,36 @@ const idCaptureMachine = setup({
4888
5028
  },
4889
5029
  { target: "success" }
4890
5030
  ] },
4891
- uploadError: { on: { CONTINUE_FROM_ERROR: [
4892
- {
4893
- target: "releasingForRetry",
4894
- guard: "hasAttemptsRemaining",
4895
- actions: [
4896
- "resetDetection",
4897
- "clearUploadFailure",
4898
- "clearStreamForRetry"
4899
- ]
4900
- },
4901
- {
4902
- target: "#idCapture.frontFinished",
4903
- guard: "shouldContinueToBack",
4904
- actions: ["flagIdManualReview"]
4905
- },
4906
- {
4907
- target: "#idCapture.backFinished",
4908
- guard: "shouldContinueToFront",
4909
- actions: ["flagIdManualReview"]
4910
- },
4911
- {
4912
- target: "#idCapture.processing",
4913
- actions: ["flagIdManualReview"]
4914
- }
4915
- ] } },
5031
+ uploadError: {
5032
+ entry: "pauseProtectedRecording",
5033
+ on: { CONTINUE_FROM_ERROR: [
5034
+ {
5035
+ target: "releasingForRetry",
5036
+ guard: "hasAttemptsRemaining",
5037
+ actions: [
5038
+ "resetDetection",
5039
+ "clearUploadFailure",
5040
+ "clearStreamForRetry"
5041
+ ]
5042
+ },
5043
+ {
5044
+ target: "#idCapture.frontFinished",
5045
+ guard: "shouldContinueToBack",
5046
+ actions: ["flagIdManualReview"]
5047
+ },
5048
+ {
5049
+ target: "#idCapture.backFinished",
5050
+ guard: "shouldContinueToFront",
5051
+ actions: ["flagIdManualReview"]
5052
+ },
5053
+ {
5054
+ target: "#idCapture.processing",
5055
+ actions: ["flagIdManualReview"]
5056
+ }
5057
+ ] }
5058
+ },
4916
5059
  success: {
5060
+ entry: "completeProtectedRecording",
4917
5061
  exit: "clearBarcodeFastPathCaptured",
4918
5062
  on: { NEXT_STEP: [
4919
5063
  {
package/dist/index.esm.js CHANGED
@@ -1,2 +1,2 @@
1
- import { i as reset, r as isConfigured, s as setup } from "./setup-BWG-hivt.esm.js";
1
+ import { i as reset, r as isConfigured, s as setup } from "./setup-6e71xCI7.esm.js";
2
2
  export { isConfigured, reset, setup };
@@ -1,16 +1,16 @@
1
- import { l as BrowserStorageProvider } from "./setup-BWG-hivt.esm.js";
1
+ import { l as BrowserStorageProvider } from "./setup-6e71xCI7.esm.js";
2
2
  import { r as WasmUtilProvider } from "./safeStorage-B-trhxg6.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
- import { b as getStoredHttpConfig, w as createApi$1, y as randomUUID } from "./trueSightService-BN-Hzw82.esm.js";
5
+ import { b as getStoredHttpConfig, w as createApi$1, y as randomUUID } from "./trueSightService-DJ1kSDlH.esm.js";
6
6
  import { n as eventModuleNames } from "./events-ijlbX_Wx.esm.js";
7
- import { b as BrowserEnvironmentProvider, h as isBrowserSimulation, n as getFingerprintEnabled, v as getThumbmarkId, y as getDeviceFingerprintInfo } from "./sessionInitializer-BFk33E67.esm.js";
7
+ import { b as BrowserEnvironmentProvider, h as isBrowserSimulation, n as getFingerprintEnabled, v as getThumbmarkId, y as getDeviceFingerprintInfo } from "./sessionInitializer-C1A6s33W.esm.js";
8
8
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
9
9
  import { i as assign, s as createActor, t as setup, u as createManager } from "./xstate.esm-BuFLFuzz.esm.js";
10
10
  import { n as fromPromise, t as fromCallback } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
11
11
  import { i as requestCameraAccess, o as stopCameraStream } from "./camera-sIa9ceW2.esm.js";
12
12
  import { i as requestPermission, t as checkPermission } from "./permissionServices-Bj_fyWtv.esm.js";
13
- import { i as initializeDeepsightSession, o as startDetection, s as stopStream, t as FaceDetectionProvider } from "./FaceDetectionProvider-BfhWkK90.esm.js";
13
+ import { i as initializeDeepsightSession, o as startDetection, s as stopStream, t as FaceDetectionProvider } from "./FaceDetectionProvider-i55W_Jkj.esm.js";
14
14
  import { t as sleep } from "./ITimerCapability-DgdDzp8G.esm.js";
15
15
  import { t as StreamCanvasCapture } from "./StreamCanvasCapture-C9jtgBdT.esm.js";
16
16
  //#region src/modules/personhood/personhoodServices.ts
@@ -1,4 +1,4 @@
1
- import { a as NAMIRIAL_QES_CONSENT_KEYS, c as areAllConsented, o as NAMIRIAL_QES_PROVIDER_CODE, r as electronicSignatureMachine, s as QE_CONSENT_KEYS, t as createElectronicSignatureManager, u as getDefaultConsentChecks } from "./electronicSignatureManager-BJJH0Tvi.esm.js";
1
+ import { a as NAMIRIAL_QES_CONSENT_KEYS, c as areAllConsented, o as NAMIRIAL_QES_PROVIDER_CODE, r as electronicSignatureMachine, s as QE_CONSENT_KEYS, t as createElectronicSignatureManager, u as getDefaultConsentChecks } from "./electronicSignatureManager-8VGN2aKU.esm.js";
2
2
  //#region src/modules/qe-signature/index.ts
3
3
  function createQeSignatureManager(options) {
4
4
  return createElectronicSignatureManager({ config: {
@@ -1,5 +1,5 @@
1
1
  import { t as getTimestamp } from "./IBrowserEnvironmentCapability-DEaRRk-R.esm.js";
2
- import { a as notifyTrueSightManagerStopped, i as notifyTrueSightFlowEvent } from "./trueSightService-BN-Hzw82.esm.js";
2
+ import { a as notifyTrueSightManagerStopped, i as notifyTrueSightFlowEvent } from "./trueSightService-DJ1kSDlH.esm.js";
3
3
  import { C as createEventBus } from "./events-ijlbX_Wx.esm.js";
4
4
  import { s as createActor } from "./xstate.esm-BuFLFuzz.esm.js";
5
5
  import { t as fromCallback } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
@@ -1,4 +1,4 @@
1
1
  //#region src/internal/version/sdkVersion.ts
2
- const SDK_VERSION = "2.3.0-rc.1+c6c04ca";
2
+ const SDK_VERSION = "2.3.0-rc.2+aecc086";
3
3
  //#endregion
4
4
  export { SDK_VERSION as t };
@@ -1,14 +1,14 @@
1
- import { l as BrowserStorageProvider } from "./setup-BWG-hivt.esm.js";
1
+ import { l as BrowserStorageProvider } from "./setup-6e71xCI7.esm.js";
2
2
  import { r as WasmUtilProvider } from "./safeStorage-B-trhxg6.esm.js";
3
3
  import { n as eventModuleNames } from "./events-ijlbX_Wx.esm.js";
4
4
  import { s as createActor } from "./xstate.esm-BuFLFuzz.esm.js";
5
5
  import { n as fromPromise } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
6
- import { n as createDefaultProtectedFaceControllerActor, t as faceCaptureMachine } from "./faceCaptureSetup-bkAlr5d8.esm.js";
7
- import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-B7Ms6pSs.esm.js";
6
+ import { n as createDefaultProtectedFaceControllerActor, t as faceCaptureMachine } from "./faceCaptureSetup-CDGmqC8J.esm.js";
7
+ import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-Bl6EffXD.esm.js";
8
8
  import { s as PROTECTED_CAPTURE_TARGET } from "./createCameraCycleOwnership-CX3hJGKc.esm.js";
9
9
  import { r as processFace } from "./selfieErrorUtils-UiQ46EBa.esm.js";
10
- import { t as selfieMachine } from "./selfieStateMachine-Bzx41R8d.esm.js";
11
- import { n as createSelfieManagerFromActor, t as createSelfieManager } from "./selfieManager-B-2c1n_x.esm.js";
10
+ import { t as selfieMachine } from "./selfieStateMachine-rfneTd9x.esm.js";
11
+ import { n as createSelfieManagerFromActor, t as createSelfieManager } from "./selfieManager-0gvnAH1m.esm.js";
12
12
  import { t as invokeOnCaptureCallback } from "./invokeOnCaptureCallback-BjzPjJ_p.esm.js";
13
13
  /**
14
14
  * Selfie state machine variant for the captureOnly flow. Shares the full base
@@ -1,9 +1,9 @@
1
- import { l as BrowserStorageProvider } from "./setup-BWG-hivt.esm.js";
1
+ import { l as BrowserStorageProvider } from "./setup-6e71xCI7.esm.js";
2
2
  import { r as WasmUtilProvider } from "./safeStorage-B-trhxg6.esm.js";
3
3
  import { n as eventModuleNames } from "./events-ijlbX_Wx.esm.js";
4
4
  import { s as createActor } from "./xstate.esm-BuFLFuzz.esm.js";
5
- import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-B7Ms6pSs.esm.js";
6
- import { t as selfieMachine } from "./selfieStateMachine-Bzx41R8d.esm.js";
5
+ import { t as createFaceCaptureManagerFromActor } from "./faceCaptureManagerFactory-Bl6EffXD.esm.js";
6
+ import { t as selfieMachine } from "./selfieStateMachine-rfneTd9x.esm.js";
7
7
  //#region src/modules/selfie/selfieActor.ts
8
8
  function createSelfieActor(options) {
9
9
  const dependencies = options.dependencies ?? {
@@ -1,7 +1,7 @@
1
1
  import { i as assign } from "./xstate.esm-BuFLFuzz.esm.js";
2
2
  import { n as fromPromise } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
3
- import { n as createDefaultProtectedFaceControllerActor, r as manualFaceUploadMachine, t as faceCaptureMachine } from "./faceCaptureSetup-bkAlr5d8.esm.js";
4
- import { c as isOnDeviceMode } from "./FaceDetectionProvider-BfhWkK90.esm.js";
3
+ import { n as createDefaultProtectedFaceControllerActor, r as manualFaceUploadMachine, t as faceCaptureMachine } from "./faceCaptureSetup-CDGmqC8J.esm.js";
4
+ import { c as isOnDeviceMode } from "./FaceDetectionProvider-i55W_Jkj.esm.js";
5
5
  import { t as FACE_ERROR_CODES } from "./types-BN5RPPIZ.esm.js";
6
6
  import { s as PROTECTED_CAPTURE_TARGET } from "./createCameraCycleOwnership-CX3hJGKc.esm.js";
7
7
  import { i as uploadManualSelfie, n as validateUploadResponse, r as processFace } from "./selfieErrorUtils-UiQ46EBa.esm.js";
@@ -1,8 +1,8 @@
1
1
  import { n as getApi } from "./api-Bx3gKW_y.esm.js";
2
- import { g as noteSessionCreated, l as trueSightLog } from "./trueSightService-BN-Hzw82.esm.js";
3
- import "./sessionInitializer-BFk33E67.esm.js";
2
+ import { g as noteSessionCreated, l as trueSightLog } from "./trueSightService-DJ1kSDlH.esm.js";
3
+ import "./sessionInitializer-C1A6s33W.esm.js";
4
4
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
5
- import { i as toIncodeApiError } from "./apiError-Budb6m6w.esm.js";
5
+ import { i as toIncodeApiError } from "./apiError-DcnaKSwk.esm.js";
6
6
  //#region src/internal/session/sessionService.ts
7
7
  /**
8
8
  * HTTP status codes the QR validation endpoint emits, keyed by their semantic
@@ -1,5 +1,5 @@
1
- import { i as initializeSession, l as whenSessionFingerprintSettled } from "./sessionInitializer-BFk33E67.esm.js";
2
- import { t as IncodeApiError } from "./apiError-Budb6m6w.esm.js";
3
- import { a as refreshQrUrlUuid, i as createSession, n as QrValidationError, o as validateQrUuid, r as bootstrapSession, t as QR_VALIDATION_ERROR_CODES } from "./session-3LmvAU4S.esm.js";
4
- import { n as getFinishStatus } from "./flowCompletionService-DJp1odGN.esm.js";
1
+ import { i as initializeSession, l as whenSessionFingerprintSettled } from "./sessionInitializer-C1A6s33W.esm.js";
2
+ import { t as IncodeApiError } from "./apiError-DcnaKSwk.esm.js";
3
+ import { a as refreshQrUrlUuid, i as createSession, n as QrValidationError, o as validateQrUuid, r as bootstrapSession, t as QR_VALIDATION_ERROR_CODES } from "./session-ZAdron5D.esm.js";
4
+ import { n as getFinishStatus } from "./flowCompletionService-CayNS1FR.esm.js";
5
5
  export { IncodeApiError, QR_VALIDATION_ERROR_CODES, QrValidationError, bootstrapSession, createSession, getFinishStatus, initializeSession, refreshQrUrlUuid, validateQrUuid, whenSessionFingerprintSettled };
@@ -1,8 +1,8 @@
1
- import { E as updateFeatureManagementUser } from "./feature-management-E0mq0pMs.esm.js";
1
+ import { E as updateFeatureManagementUser } from "./feature-management-J3rr-HDW.esm.js";
2
2
  import { c as setToken, r as getToken, t as api } from "./api-Bx3gKW_y.esm.js";
3
- import { d as fetchFeatureConfig, f as isFeatureEnabled, h as noteEnvironment, l as trueSightLog, p as resetFeatureConfigCache, s as startTrueSightCollection, v as noteTokenActivated } from "./trueSightService-BN-Hzw82.esm.js";
3
+ import { d as fetchFeatureConfig, f as isFeatureEnabled, h as noteEnvironment, l as trueSightLog, p as resetFeatureConfigCache, s as startTrueSightCollection, v as noteTokenActivated } from "./trueSightService-DJ1kSDlH.esm.js";
4
4
  import { v as addEvent, y as getAnalyticsBatcher } from "./events-ijlbX_Wx.esm.js";
5
- import { t as SDK_VERSION } from "./sdkVersion-BZh6dj53.esm.js";
5
+ import { t as SDK_VERSION } from "./sdkVersion-DTrl2Jm7.esm.js";
6
6
  import { t as endpoints } from "./endpoints-B-3Q-LUw.esm.js";
7
7
  import { n as flushDeviceStatsQueue, r as resetDeviceStatsQueue } from "./stats-CZcy2J53.esm.js";
8
8
  import { t as getParsedUserAgent } from "./getParsedUserAgent-B2iFDql1.esm.js";