@sekyro/web 0.1.0-rc.4 → 0.1.0-rc.6

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 (34) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +44 -0
  3. package/dist/{capture-session-v3-uXJr1Wlm.d.ts → capture-session-v3-Okq0EQHG.d.ts} +9 -2
  4. package/dist/{capture-session-v3-DEInCOUg.d.cts → capture-session-v3-UQU_WjO2.d.cts} +9 -2
  5. package/dist/{chunk-TBANUT3X.js → chunk-R3SJQHYU.js} +296 -8
  6. package/dist/chunk-R3SJQHYU.js.map +1 -0
  7. package/dist/{chunk-EWRNPKTR.js → chunk-TG5IE552.js} +7 -2
  8. package/dist/{chunk-EWRNPKTR.js.map → chunk-TG5IE552.js.map} +1 -1
  9. package/dist/client/index.cjs.map +1 -1
  10. package/dist/client/index.d.cts +1 -1
  11. package/dist/client/index.d.ts +1 -1
  12. package/dist/core/index.cjs +6 -1
  13. package/dist/core/index.cjs.map +1 -1
  14. package/dist/core/index.d.cts +2 -2
  15. package/dist/core/index.d.ts +2 -2
  16. package/dist/core/index.js +1 -1
  17. package/dist/{create-verification-Dkb2tXuY.d.cts → create-verification-BKc9NFQj.d.cts} +92 -8
  18. package/dist/{create-verification-Ce1y5kJR.d.ts → create-verification-DjcMZHAQ.d.ts} +92 -8
  19. package/dist/{hosted-client-DWzCRYJK.d.cts → hosted-client-DJXq_CB9.d.cts} +29 -1
  20. package/dist/{hosted-client-DWzCRYJK.d.ts → hosted-client-DJXq_CB9.d.ts} +29 -1
  21. package/dist/index.cjs +341 -9
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +25 -3
  24. package/dist/index.d.ts +25 -3
  25. package/dist/index.js +61 -4
  26. package/dist/index.js.map +1 -1
  27. package/dist/internal/index.cjs +218 -7
  28. package/dist/internal/index.cjs.map +1 -1
  29. package/dist/internal/index.d.cts +4 -4
  30. package/dist/internal/index.d.ts +4 -4
  31. package/dist/internal/index.js +12 -2
  32. package/dist/internal/index.js.map +1 -1
  33. package/package.json +1 -1
  34. package/dist/chunk-TBANUT3X.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { C as CameraErrorKind } from '../capture-session-v3-DEInCOUg.cjs';
2
- export { a as CLIP_MS, b as CaptureArtifacts, c as CaptureErrorKind, d as CaptureSessionEvents, e as CaptureSessionV3, f as CaptureSessionV3Events, g as CaptureSessionV3Options, h as CaptureState, i as CaptureTiming, j as ClipError, k as ClipErrorKind, l as ClipRecorder, m as ClipResult, D as DEFAULT_CLIP_MIME, n as DEVICE_PROFILES, o as DeviceClass, p as DeviceProbe, q as DeviceProfile, r as DeviceProfiler, E as EscalationClipArtifact, s as EscalationHook, F as FaceGateV3, G as GateChecks, K as KEYFRAME_CANDIDATES, t as KEYFRAME_WINDOW_MS, M as MAX_CLIP_BYTES, u as MIME_CANDIDATES, S as STOP_GRACE_MS, T as TIMESLICE_MS, V as V3ChecksPayload, v as V3GateFactor, w as V3GateQuality, x as V3GateThresholds, y as V3GateTick, z as V3GateTickInput, A as V3TelemetryEvent, B as V3_GATE_DEFAULTS, H as VIDEO_BPS, I as buildLivenessV2FormData, J as cameraPreflight, L as classifyDevice, N as extForMime, O as isClipTooLarge, P as isMediaRecorderSupported, Q as mapGetUserMediaError, R as pickMimeType, U as probeDevice } from '../capture-session-v3-DEInCOUg.cjs';
1
+ import { C as CameraErrorKind } from '../capture-session-v3-UQU_WjO2.cjs';
2
+ export { a as CLIP_MS, b as CaptureArtifacts, c as CaptureErrorKind, d as CaptureSessionEvents, e as CaptureSessionV3, f as CaptureSessionV3Events, g as CaptureSessionV3Options, h as CaptureSessionV3StartOptions, i as CaptureState, j as CaptureTiming, k as ClipError, l as ClipErrorKind, m as ClipRecorder, n as ClipResult, D as DEFAULT_CLIP_MIME, o as DEVICE_PROFILES, p as DeviceClass, q as DeviceProbe, r as DeviceProfile, s as DeviceProfiler, E as EscalationClipArtifact, t as EscalationHook, F as FaceGateV3, G as GateChecks, K as KEYFRAME_CANDIDATES, u as KEYFRAME_WINDOW_MS, M as MAX_CLIP_BYTES, v as MIME_CANDIDATES, S as STOP_GRACE_MS, T as TIMESLICE_MS, V as V3ChecksPayload, w as V3GateFactor, x as V3GateQuality, y as V3GateThresholds, z as V3GateTick, A as V3GateTickInput, B as V3TelemetryEvent, H as V3_GATE_DEFAULTS, I as VIDEO_BPS, J as buildLivenessV2FormData, L as cameraPreflight, N as classifyDevice, O as extForMime, P as isClipTooLarge, Q as isMediaRecorderSupported, R as mapGetUserMediaError, U as pickMimeType, W as probeDevice } from '../capture-session-v3-UQU_WjO2.cjs';
3
3
  export { C as CENTERED_FACTOR, a as CIRCLE_RADIUS_FACTOR, I as IN_CIRCLE_FACTOR, b as buildCaptureConstraints, d as detectIsMobile } from '../capture-constraints-BujkZcfb.cjs';
4
4
  export { C as CreateDetectorOptions, D as DEFAULT_TIER_ORDER, a as DEFAULT_V3_ASSET_BASE_URL, b as Detector, c as DetectorLadderError, F as FaceObservation, d as createDetector, i as intrinsicSize, t as toStreamPixels } from '../detect-worker-CKXHlXx9.cjs';
5
5
 
@@ -1,5 +1,5 @@
1
- import { C as CameraErrorKind } from '../capture-session-v3-uXJr1Wlm.js';
2
- export { a as CLIP_MS, b as CaptureArtifacts, c as CaptureErrorKind, d as CaptureSessionEvents, e as CaptureSessionV3, f as CaptureSessionV3Events, g as CaptureSessionV3Options, h as CaptureState, i as CaptureTiming, j as ClipError, k as ClipErrorKind, l as ClipRecorder, m as ClipResult, D as DEFAULT_CLIP_MIME, n as DEVICE_PROFILES, o as DeviceClass, p as DeviceProbe, q as DeviceProfile, r as DeviceProfiler, E as EscalationClipArtifact, s as EscalationHook, F as FaceGateV3, G as GateChecks, K as KEYFRAME_CANDIDATES, t as KEYFRAME_WINDOW_MS, M as MAX_CLIP_BYTES, u as MIME_CANDIDATES, S as STOP_GRACE_MS, T as TIMESLICE_MS, V as V3ChecksPayload, v as V3GateFactor, w as V3GateQuality, x as V3GateThresholds, y as V3GateTick, z as V3GateTickInput, A as V3TelemetryEvent, B as V3_GATE_DEFAULTS, H as VIDEO_BPS, I as buildLivenessV2FormData, J as cameraPreflight, L as classifyDevice, N as extForMime, O as isClipTooLarge, P as isMediaRecorderSupported, Q as mapGetUserMediaError, R as pickMimeType, U as probeDevice } from '../capture-session-v3-uXJr1Wlm.js';
1
+ import { C as CameraErrorKind } from '../capture-session-v3-Okq0EQHG.js';
2
+ export { a as CLIP_MS, b as CaptureArtifacts, c as CaptureErrorKind, d as CaptureSessionEvents, e as CaptureSessionV3, f as CaptureSessionV3Events, g as CaptureSessionV3Options, h as CaptureSessionV3StartOptions, i as CaptureState, j as CaptureTiming, k as ClipError, l as ClipErrorKind, m as ClipRecorder, n as ClipResult, D as DEFAULT_CLIP_MIME, o as DEVICE_PROFILES, p as DeviceClass, q as DeviceProbe, r as DeviceProfile, s as DeviceProfiler, E as EscalationClipArtifact, t as EscalationHook, F as FaceGateV3, G as GateChecks, K as KEYFRAME_CANDIDATES, u as KEYFRAME_WINDOW_MS, M as MAX_CLIP_BYTES, v as MIME_CANDIDATES, S as STOP_GRACE_MS, T as TIMESLICE_MS, V as V3ChecksPayload, w as V3GateFactor, x as V3GateQuality, y as V3GateThresholds, z as V3GateTick, A as V3GateTickInput, B as V3TelemetryEvent, H as V3_GATE_DEFAULTS, I as VIDEO_BPS, J as buildLivenessV2FormData, L as cameraPreflight, N as classifyDevice, O as extForMime, P as isClipTooLarge, Q as isMediaRecorderSupported, R as mapGetUserMediaError, U as pickMimeType, W as probeDevice } from '../capture-session-v3-Okq0EQHG.js';
3
3
  export { C as CENTERED_FACTOR, a as CIRCLE_RADIUS_FACTOR, I as IN_CIRCLE_FACTOR, b as buildCaptureConstraints, d as detectIsMobile } from '../capture-constraints-BujkZcfb.js';
4
4
  export { C as CreateDetectorOptions, D as DEFAULT_TIER_ORDER, a as DEFAULT_V3_ASSET_BASE_URL, b as Detector, c as DetectorLadderError, F as FaceObservation, d as createDetector, i as intrinsicSize, t as toStreamPixels } from '../detect-worker-CKXHlXx9.js';
5
5
 
@@ -31,7 +31,7 @@ import {
31
31
  mapGetUserMediaError,
32
32
  pickMimeType,
33
33
  probeDevice
34
- } from "../chunk-EWRNPKTR.js";
34
+ } from "../chunk-TG5IE552.js";
35
35
  import {
36
36
  DEFAULT_TIER_ORDER,
37
37
  DEFAULT_V3_ASSET_BASE_URL,
@@ -1,5 +1,6 @@
1
- import { h as CaptureState$1, f as CaptureSessionV3Events, g as CaptureSessionV3Options, c as CaptureErrorKind$1 } from './capture-session-v3-DEInCOUg.cjs';
2
- import { C as CheckReason, c as HostedSessionView, g as HostedClient, A as AttestationInput, h as SessionView, b as CheckType } from './hosted-client-DWzCRYJK.cjs';
1
+ import { b as Detector } from './detect-worker-CKXHlXx9.cjs';
2
+ import { i as CaptureState$1, f as CaptureSessionV3Events, g as CaptureSessionV3Options, c as CaptureErrorKind$1 } from './capture-session-v3-UQU_WjO2.cjs';
3
+ import { C as CheckReason, f as HostedVoiceView, c as HostedSessionView, i as HostedClient, A as AttestationInput, j as SessionView, b as CheckType } from './hosted-client-DJXq_CB9.cjs';
3
4
 
4
5
  /** Gate guidance code. `'hold'` is emitted while the clip records. */
5
6
  type GateHint = "center" | "closer" | "farther" | "light" | "still" | "hold";
@@ -110,14 +111,28 @@ interface LivenessCaptureEvents {
110
111
  animations: "full" | "reduced";
111
112
  };
112
113
  }
114
+ /** Which camera to open: the selfie camera (`'user'`) or the rear one (`'environment'`). */
115
+ type CameraFacing = "user" | "environment";
116
+ /** Options of {@link LivenessCaptureHandle.start}. */
117
+ interface LivenessStartOptions {
118
+ /**
119
+ * Camera for this attempt and its retries; default: the current one
120
+ * ({@link LivenessCaptureOptions.facing}, else `'user'`). Use `switchCamera()`
121
+ * to change camera mid-capture.
122
+ */
123
+ facing?: CameraFacing;
124
+ }
113
125
  /** Live capture handle returned by {@link createLivenessCapture} / {@link Verification.liveness}. */
114
126
  interface LivenessCaptureHandle {
115
127
  /** Current {@link CaptureState}. */
116
128
  readonly state: CaptureState;
117
129
  /** Subscribe; returns the unsubscribe function. */
118
130
  on<K extends keyof LivenessCaptureEvents>(event: K, handler: (payload: LivenessCaptureEvents[K]) => void): () => void;
119
- /** Ask for the camera and start gating. Resolves once the attempt is running or failed. */
120
- start(): Promise<void>;
131
+ /**
132
+ * Ask for the camera and start gating. Resolves once the attempt is running or failed.
133
+ * `options.facing` picks the camera for this attempt and later retries.
134
+ */
135
+ start(options?: LivenessStartOptions): Promise<void>;
121
136
  /** Fresh attempt: resets the engine and restarts the camera. */
122
137
  retry(): void;
123
138
  /** Toggle user/environment camera (gate restarts from zero). */
@@ -129,10 +144,18 @@ interface LivenessCaptureHandle {
129
144
  interface LivenessCaptureOptions {
130
145
  /** Host-owned `<video playsInline muted>` element. */
131
146
  video: HTMLVideoElement;
132
- /** Initial camera; default `'user'`. */
133
- facing?: "user" | "environment";
147
+ /** Initial camera; default `'user'`. `start({ facing })` overrides it. */
148
+ facing?: CameraFacing;
134
149
  /** Base URL of the detector assets (tasks-vision wasm + tflite); default `/models-v3`. */
135
150
  assetBaseUrl?: string;
151
+ /**
152
+ * Hold a Screen Wake Lock while the camera is live (`starting` / `gating` /
153
+ * `recording`) so the phone does not dim or lock mid-capture; re-taken when
154
+ * the page becomes visible again. Best-effort: unsupported browsers or a
155
+ * refused request (e.g. an iframe without `allow="screen-wake-lock"`) never
156
+ * affect the capture. Default `true`; `false` never requests the lock.
157
+ */
158
+ keepScreenAwake?: boolean;
136
159
  }
137
160
  /**
138
161
  * SDK-side failure reasons (status `'unavailable'`):
@@ -208,6 +231,13 @@ interface Verification {
208
231
  startRegistry(): Promise<void>;
209
232
  /** Start a liveness capture bound to this verification; the SDK uploads + submits on `captured`. */
210
233
  liveness(options: LivenessCaptureOptions): LivenessCaptureHandle;
234
+ /**
235
+ * The session's Sekyro-hosted voice clips (`view.voice`), bootstrapping the
236
+ * hosted view when it has not been fetched yet. Resolves `null` when the
237
+ * session has no active clip set, the API predates the field, the bootstrap
238
+ * fails, or the verification was destroyed. Never rejects.
239
+ */
240
+ voiceClips(): Promise<HostedVoiceView | null>;
211
241
  /** Subscribe; returns the unsubscribe function. */
212
242
  on<K extends keyof VerificationEvents>(event: K, handler: (payload: VerificationEvents[K]) => void): () => void;
213
243
  /** Destroy the active capture and drop all listeners. */
@@ -218,7 +248,10 @@ interface Verification {
218
248
  interface CaptureEngine {
219
249
  readonly state: CaptureState$1;
220
250
  on<K extends keyof CaptureSessionV3Events>(event: K, handler: (payload: CaptureSessionV3Events[K]) => void): () => void;
221
- start(): Promise<void>;
251
+ /** `facingMode` sets the camera for this attempt and later retries. */
252
+ start(options?: {
253
+ facingMode?: "user" | "environment";
254
+ }): Promise<void>;
222
255
  retry(): void;
223
256
  switchCamera(): void;
224
257
  destroy(): void;
@@ -253,6 +286,57 @@ declare function createLivenessCaptureInternal(options: LivenessCaptureOptions,
253
286
  */
254
287
  declare function createLivenessCapture(options: LivenessCaptureOptions): LivenessCaptureHandle;
255
288
 
289
+ /** Preload state per asset base URL. */
290
+ type LivenessAssetsStatus = "idle" | "loading" | "ready" | "failed";
291
+ /** Options of {@link preloadLivenessAssets}. */
292
+ interface PreloadLivenessAssetsOptions {
293
+ /** Same value as the capture's `assetBaseUrl`; default `/models-v3`. */
294
+ assetBaseUrl?: string;
295
+ /** Defer the load to browser idle time (`requestIdleCallback`, 1.2 s timeout fallback). Default `false`. */
296
+ idle?: boolean;
297
+ /** Skip when the browser asks to save data (`navigator.connection.saveData`). Default `false`. */
298
+ respectSaveData?: boolean;
299
+ }
300
+ /** Blaze init deadline for the preload — generous: a slow ~11 MB wasm download must finish. */
301
+ declare const PRELOAD_BLAZE_INIT_TIMEOUT_MS = 120000;
302
+ /** Outer budget reclaiming only a genuinely hung load (≥ the init deadline + slack). */
303
+ declare const PRELOAD_BUDGET_MS = 130000;
304
+ type Loader = (base: string) => Promise<Detector>;
305
+ /** @internal Test seam: replace the detector loader (null restores the real one). */
306
+ declare function setPreloadLoaderForTests(next: Loader | null): void;
307
+ /** @internal Test seam: drop every entry (destroying warmed detectors). */
308
+ declare function resetLivenessAssetsForTests(): void;
309
+ /**
310
+ * Warm the face detector for `assetBaseUrl` so the capture starts instantly.
311
+ * Idempotent per base URL and never rejects: resolves the settled status.
312
+ * `'idle'` means nothing was preloaded here (SSR, no camera API, Data-Saver
313
+ * skip) — start normally. Calling again after `'failed'` retries the load.
314
+ * With `idle: true` the load is deferred (status stays `'idle'` until it
315
+ * starts); a later non-idle call — or a capture mounting meanwhile — starts it
316
+ * at once, and {@link releaseLivenessAssets} cancels it.
317
+ */
318
+ declare function preloadLivenessAssets(options?: PreloadLivenessAssetsOptions): Promise<LivenessAssetsStatus>;
319
+ /** Current preload status for `assetBaseUrl` (default `/models-v3`). */
320
+ declare function getLivenessAssetsStatus(assetBaseUrl?: string): LivenessAssetsStatus;
321
+ /**
322
+ * Subscribe to status changes for `assetBaseUrl`; returns the unsubscribe
323
+ * function. Does NOT emit the current status on subscribe (read it with
324
+ * {@link getLivenessAssetsStatus}) — the
325
+ * `useSyncExternalStore(subscribe, getSnapshot)` contract, so it plugs into
326
+ * that hook directly.
327
+ */
328
+ declare function subscribeLivenessAssets(listener: (status: LivenessAssetsStatus) => void, assetBaseUrl?: string): () => void;
329
+ /** Free the warmed detector (an SPA leaving the flow). Never call while a capture is mounted. */
330
+ declare function releaseLivenessAssets(assetBaseUrl?: string): void;
331
+ /**
332
+ * @internal The capture engine's detector source when a preload exists for
333
+ * `assetBaseUrl`: a non-owning view of the warm instance (waiting for an
334
+ * in-flight load), or — once that load failed — a cold detector OWNED by the
335
+ * session (default ladder + deadline). `undefined` when nothing was preloaded.
336
+ * Invoking it on an idle-scheduled preload starts that load now and joins it.
337
+ */
338
+ declare function preloadedDetectorFactory(assetBaseUrl?: string): (() => Promise<Detector>) | undefined;
339
+
256
340
  /** The client surface the flow needs — `HostedClient` or a test fake. */
257
341
  type HostedClientLike = Pick<HostedClient, "getSession" | "recordConsent" | "presign" | "uploadToSpaces" | "completeMedia" | "submitCheck">;
258
342
  /** The presign policy allowlist for `kind: 'clip'` (media.policy.ts mirror). */
@@ -368,4 +452,4 @@ declare function createVerification(options: VerificationOptions): Verification;
368
452
  /** {@link createVerification} with construction seams (tests / Sekyro-internal hosts). */
369
453
  declare function createVerificationInternal(options: VerificationOptions, internals: VerificationInternals): Verification;
370
454
 
371
- export { AttestationError as A, type VerificationInternals as B, type CaptureChannel as C, DEFAULT_API_ORIGIN as D, createLivenessCaptureInternal as E, createVerificationInternal as F, type GateHint as G, type HostedClientLike as H, mapEngineState as I, mapErrorKind as J, mapGuidanceHint as K, type LivenessCaptureEvents as L, randomUuid as M, runLivenessFlow as N, runSubmission as O, PROCESSING_POLL_DELAY_MS as P, type ReasonCode as R, type SdkFailureReason as S, TRANSPORT_REPLAY_ATTEMPTS as T, type Verification as V, type CaptureEngineId as a, type CaptureError as b, type CaptureErrorKind as c, type CaptureState as d, type CapturedArtifacts as e, type GateUpdate as f, type LivenessCaptureHandle as g, type LivenessCaptureOptions as h, type VerificationEvents as i, type VerificationLocale as j, type VerificationOptions as k, type VerificationResult as l, type VerificationStatus as m, createLivenessCapture as n, createVerification as o, CLIP_MIME_ALLOWLIST as p, type CaptureEngine as q, type LivenessCaptureInternalHandle as r, type LivenessCaptureInternals as s, type LivenessFlowDeps as t, type LivenessFlowOutcome as u, PROCESSING_POLL_MAX as v, REGISTRY_RETRY_DELAY_MS as w, type SubmitExecutor as x, type SubmitRuntime as y, TRANSPORT_REPLAY_DELAY_MS as z };
455
+ export { preloadedDetectorFactory as $, AttestationError as A, type LivenessFlowDeps as B, type CameraFacing as C, DEFAULT_API_ORIGIN as D, type LivenessFlowOutcome as E, PRELOAD_BLAZE_INIT_TIMEOUT_MS as F, type GateHint as G, type HostedClientLike as H, PRELOAD_BUDGET_MS as I, PROCESSING_POLL_DELAY_MS as J, PROCESSING_POLL_MAX as K, type LivenessAssetsStatus as L, REGISTRY_RETRY_DELAY_MS as M, type SubmitExecutor as N, type SubmitRuntime as O, type PreloadLivenessAssetsOptions as P, TRANSPORT_REPLAY_DELAY_MS as Q, type ReasonCode as R, type SdkFailureReason as S, TRANSPORT_REPLAY_ATTEMPTS as T, type VerificationInternals as U, type Verification as V, createLivenessCaptureInternal as W, createVerificationInternal as X, mapEngineState as Y, mapErrorKind as Z, mapGuidanceHint as _, type CaptureChannel as a, randomUuid as a0, resetLivenessAssetsForTests as a1, runLivenessFlow as a2, runSubmission as a3, setPreloadLoaderForTests as a4, type CaptureEngineId as b, type CaptureError as c, type CaptureErrorKind as d, type CaptureState as e, type CapturedArtifacts as f, type GateUpdate as g, type LivenessCaptureEvents as h, type LivenessCaptureHandle as i, type LivenessCaptureOptions as j, type LivenessStartOptions as k, type VerificationEvents as l, type VerificationLocale as m, type VerificationOptions as n, type VerificationResult as o, type VerificationStatus as p, createLivenessCapture as q, createVerification as r, getLivenessAssetsStatus as s, preloadLivenessAssets as t, releaseLivenessAssets as u, subscribeLivenessAssets as v, CLIP_MIME_ALLOWLIST as w, type CaptureEngine as x, type LivenessCaptureInternalHandle as y, type LivenessCaptureInternals as z };
@@ -1,5 +1,6 @@
1
- import { h as CaptureState$1, f as CaptureSessionV3Events, g as CaptureSessionV3Options, c as CaptureErrorKind$1 } from './capture-session-v3-uXJr1Wlm.js';
2
- import { C as CheckReason, c as HostedSessionView, g as HostedClient, A as AttestationInput, h as SessionView, b as CheckType } from './hosted-client-DWzCRYJK.js';
1
+ import { b as Detector } from './detect-worker-CKXHlXx9.js';
2
+ import { i as CaptureState$1, f as CaptureSessionV3Events, g as CaptureSessionV3Options, c as CaptureErrorKind$1 } from './capture-session-v3-Okq0EQHG.js';
3
+ import { C as CheckReason, f as HostedVoiceView, c as HostedSessionView, i as HostedClient, A as AttestationInput, j as SessionView, b as CheckType } from './hosted-client-DJXq_CB9.js';
3
4
 
4
5
  /** Gate guidance code. `'hold'` is emitted while the clip records. */
5
6
  type GateHint = "center" | "closer" | "farther" | "light" | "still" | "hold";
@@ -110,14 +111,28 @@ interface LivenessCaptureEvents {
110
111
  animations: "full" | "reduced";
111
112
  };
112
113
  }
114
+ /** Which camera to open: the selfie camera (`'user'`) or the rear one (`'environment'`). */
115
+ type CameraFacing = "user" | "environment";
116
+ /** Options of {@link LivenessCaptureHandle.start}. */
117
+ interface LivenessStartOptions {
118
+ /**
119
+ * Camera for this attempt and its retries; default: the current one
120
+ * ({@link LivenessCaptureOptions.facing}, else `'user'`). Use `switchCamera()`
121
+ * to change camera mid-capture.
122
+ */
123
+ facing?: CameraFacing;
124
+ }
113
125
  /** Live capture handle returned by {@link createLivenessCapture} / {@link Verification.liveness}. */
114
126
  interface LivenessCaptureHandle {
115
127
  /** Current {@link CaptureState}. */
116
128
  readonly state: CaptureState;
117
129
  /** Subscribe; returns the unsubscribe function. */
118
130
  on<K extends keyof LivenessCaptureEvents>(event: K, handler: (payload: LivenessCaptureEvents[K]) => void): () => void;
119
- /** Ask for the camera and start gating. Resolves once the attempt is running or failed. */
120
- start(): Promise<void>;
131
+ /**
132
+ * Ask for the camera and start gating. Resolves once the attempt is running or failed.
133
+ * `options.facing` picks the camera for this attempt and later retries.
134
+ */
135
+ start(options?: LivenessStartOptions): Promise<void>;
121
136
  /** Fresh attempt: resets the engine and restarts the camera. */
122
137
  retry(): void;
123
138
  /** Toggle user/environment camera (gate restarts from zero). */
@@ -129,10 +144,18 @@ interface LivenessCaptureHandle {
129
144
  interface LivenessCaptureOptions {
130
145
  /** Host-owned `<video playsInline muted>` element. */
131
146
  video: HTMLVideoElement;
132
- /** Initial camera; default `'user'`. */
133
- facing?: "user" | "environment";
147
+ /** Initial camera; default `'user'`. `start({ facing })` overrides it. */
148
+ facing?: CameraFacing;
134
149
  /** Base URL of the detector assets (tasks-vision wasm + tflite); default `/models-v3`. */
135
150
  assetBaseUrl?: string;
151
+ /**
152
+ * Hold a Screen Wake Lock while the camera is live (`starting` / `gating` /
153
+ * `recording`) so the phone does not dim or lock mid-capture; re-taken when
154
+ * the page becomes visible again. Best-effort: unsupported browsers or a
155
+ * refused request (e.g. an iframe without `allow="screen-wake-lock"`) never
156
+ * affect the capture. Default `true`; `false` never requests the lock.
157
+ */
158
+ keepScreenAwake?: boolean;
136
159
  }
137
160
  /**
138
161
  * SDK-side failure reasons (status `'unavailable'`):
@@ -208,6 +231,13 @@ interface Verification {
208
231
  startRegistry(): Promise<void>;
209
232
  /** Start a liveness capture bound to this verification; the SDK uploads + submits on `captured`. */
210
233
  liveness(options: LivenessCaptureOptions): LivenessCaptureHandle;
234
+ /**
235
+ * The session's Sekyro-hosted voice clips (`view.voice`), bootstrapping the
236
+ * hosted view when it has not been fetched yet. Resolves `null` when the
237
+ * session has no active clip set, the API predates the field, the bootstrap
238
+ * fails, or the verification was destroyed. Never rejects.
239
+ */
240
+ voiceClips(): Promise<HostedVoiceView | null>;
211
241
  /** Subscribe; returns the unsubscribe function. */
212
242
  on<K extends keyof VerificationEvents>(event: K, handler: (payload: VerificationEvents[K]) => void): () => void;
213
243
  /** Destroy the active capture and drop all listeners. */
@@ -218,7 +248,10 @@ interface Verification {
218
248
  interface CaptureEngine {
219
249
  readonly state: CaptureState$1;
220
250
  on<K extends keyof CaptureSessionV3Events>(event: K, handler: (payload: CaptureSessionV3Events[K]) => void): () => void;
221
- start(): Promise<void>;
251
+ /** `facingMode` sets the camera for this attempt and later retries. */
252
+ start(options?: {
253
+ facingMode?: "user" | "environment";
254
+ }): Promise<void>;
222
255
  retry(): void;
223
256
  switchCamera(): void;
224
257
  destroy(): void;
@@ -253,6 +286,57 @@ declare function createLivenessCaptureInternal(options: LivenessCaptureOptions,
253
286
  */
254
287
  declare function createLivenessCapture(options: LivenessCaptureOptions): LivenessCaptureHandle;
255
288
 
289
+ /** Preload state per asset base URL. */
290
+ type LivenessAssetsStatus = "idle" | "loading" | "ready" | "failed";
291
+ /** Options of {@link preloadLivenessAssets}. */
292
+ interface PreloadLivenessAssetsOptions {
293
+ /** Same value as the capture's `assetBaseUrl`; default `/models-v3`. */
294
+ assetBaseUrl?: string;
295
+ /** Defer the load to browser idle time (`requestIdleCallback`, 1.2 s timeout fallback). Default `false`. */
296
+ idle?: boolean;
297
+ /** Skip when the browser asks to save data (`navigator.connection.saveData`). Default `false`. */
298
+ respectSaveData?: boolean;
299
+ }
300
+ /** Blaze init deadline for the preload — generous: a slow ~11 MB wasm download must finish. */
301
+ declare const PRELOAD_BLAZE_INIT_TIMEOUT_MS = 120000;
302
+ /** Outer budget reclaiming only a genuinely hung load (≥ the init deadline + slack). */
303
+ declare const PRELOAD_BUDGET_MS = 130000;
304
+ type Loader = (base: string) => Promise<Detector>;
305
+ /** @internal Test seam: replace the detector loader (null restores the real one). */
306
+ declare function setPreloadLoaderForTests(next: Loader | null): void;
307
+ /** @internal Test seam: drop every entry (destroying warmed detectors). */
308
+ declare function resetLivenessAssetsForTests(): void;
309
+ /**
310
+ * Warm the face detector for `assetBaseUrl` so the capture starts instantly.
311
+ * Idempotent per base URL and never rejects: resolves the settled status.
312
+ * `'idle'` means nothing was preloaded here (SSR, no camera API, Data-Saver
313
+ * skip) — start normally. Calling again after `'failed'` retries the load.
314
+ * With `idle: true` the load is deferred (status stays `'idle'` until it
315
+ * starts); a later non-idle call — or a capture mounting meanwhile — starts it
316
+ * at once, and {@link releaseLivenessAssets} cancels it.
317
+ */
318
+ declare function preloadLivenessAssets(options?: PreloadLivenessAssetsOptions): Promise<LivenessAssetsStatus>;
319
+ /** Current preload status for `assetBaseUrl` (default `/models-v3`). */
320
+ declare function getLivenessAssetsStatus(assetBaseUrl?: string): LivenessAssetsStatus;
321
+ /**
322
+ * Subscribe to status changes for `assetBaseUrl`; returns the unsubscribe
323
+ * function. Does NOT emit the current status on subscribe (read it with
324
+ * {@link getLivenessAssetsStatus}) — the
325
+ * `useSyncExternalStore(subscribe, getSnapshot)` contract, so it plugs into
326
+ * that hook directly.
327
+ */
328
+ declare function subscribeLivenessAssets(listener: (status: LivenessAssetsStatus) => void, assetBaseUrl?: string): () => void;
329
+ /** Free the warmed detector (an SPA leaving the flow). Never call while a capture is mounted. */
330
+ declare function releaseLivenessAssets(assetBaseUrl?: string): void;
331
+ /**
332
+ * @internal The capture engine's detector source when a preload exists for
333
+ * `assetBaseUrl`: a non-owning view of the warm instance (waiting for an
334
+ * in-flight load), or — once that load failed — a cold detector OWNED by the
335
+ * session (default ladder + deadline). `undefined` when nothing was preloaded.
336
+ * Invoking it on an idle-scheduled preload starts that load now and joins it.
337
+ */
338
+ declare function preloadedDetectorFactory(assetBaseUrl?: string): (() => Promise<Detector>) | undefined;
339
+
256
340
  /** The client surface the flow needs — `HostedClient` or a test fake. */
257
341
  type HostedClientLike = Pick<HostedClient, "getSession" | "recordConsent" | "presign" | "uploadToSpaces" | "completeMedia" | "submitCheck">;
258
342
  /** The presign policy allowlist for `kind: 'clip'` (media.policy.ts mirror). */
@@ -368,4 +452,4 @@ declare function createVerification(options: VerificationOptions): Verification;
368
452
  /** {@link createVerification} with construction seams (tests / Sekyro-internal hosts). */
369
453
  declare function createVerificationInternal(options: VerificationOptions, internals: VerificationInternals): Verification;
370
454
 
371
- export { AttestationError as A, type VerificationInternals as B, type CaptureChannel as C, DEFAULT_API_ORIGIN as D, createLivenessCaptureInternal as E, createVerificationInternal as F, type GateHint as G, type HostedClientLike as H, mapEngineState as I, mapErrorKind as J, mapGuidanceHint as K, type LivenessCaptureEvents as L, randomUuid as M, runLivenessFlow as N, runSubmission as O, PROCESSING_POLL_DELAY_MS as P, type ReasonCode as R, type SdkFailureReason as S, TRANSPORT_REPLAY_ATTEMPTS as T, type Verification as V, type CaptureEngineId as a, type CaptureError as b, type CaptureErrorKind as c, type CaptureState as d, type CapturedArtifacts as e, type GateUpdate as f, type LivenessCaptureHandle as g, type LivenessCaptureOptions as h, type VerificationEvents as i, type VerificationLocale as j, type VerificationOptions as k, type VerificationResult as l, type VerificationStatus as m, createLivenessCapture as n, createVerification as o, CLIP_MIME_ALLOWLIST as p, type CaptureEngine as q, type LivenessCaptureInternalHandle as r, type LivenessCaptureInternals as s, type LivenessFlowDeps as t, type LivenessFlowOutcome as u, PROCESSING_POLL_MAX as v, REGISTRY_RETRY_DELAY_MS as w, type SubmitExecutor as x, type SubmitRuntime as y, TRANSPORT_REPLAY_DELAY_MS as z };
455
+ export { preloadedDetectorFactory as $, AttestationError as A, type LivenessFlowDeps as B, type CameraFacing as C, DEFAULT_API_ORIGIN as D, type LivenessFlowOutcome as E, PRELOAD_BLAZE_INIT_TIMEOUT_MS as F, type GateHint as G, type HostedClientLike as H, PRELOAD_BUDGET_MS as I, PROCESSING_POLL_DELAY_MS as J, PROCESSING_POLL_MAX as K, type LivenessAssetsStatus as L, REGISTRY_RETRY_DELAY_MS as M, type SubmitExecutor as N, type SubmitRuntime as O, type PreloadLivenessAssetsOptions as P, TRANSPORT_REPLAY_DELAY_MS as Q, type ReasonCode as R, type SdkFailureReason as S, TRANSPORT_REPLAY_ATTEMPTS as T, type VerificationInternals as U, type Verification as V, createLivenessCaptureInternal as W, createVerificationInternal as X, mapEngineState as Y, mapErrorKind as Z, mapGuidanceHint as _, type CaptureChannel as a, randomUuid as a0, resetLivenessAssetsForTests as a1, runLivenessFlow as a2, runSubmission as a3, setPreloadLoaderForTests as a4, type CaptureEngineId as b, type CaptureError as c, type CaptureErrorKind as d, type CaptureState as e, type CapturedArtifacts as f, type GateUpdate as g, type LivenessCaptureEvents as h, type LivenessCaptureHandle as i, type LivenessCaptureOptions as j, type LivenessStartOptions as k, type VerificationEvents as l, type VerificationLocale as m, type VerificationOptions as n, type VerificationResult as o, type VerificationStatus as p, createLivenessCapture as q, createVerification as r, getLivenessAssetsStatus as s, preloadLivenessAssets as t, releaseLivenessAssets as u, subscribeLivenessAssets as v, CLIP_MIME_ALLOWLIST as w, type CaptureEngine as x, type LivenessCaptureInternalHandle as y, type LivenessCaptureInternals as z };
@@ -67,6 +67,28 @@ interface HostedStepView {
67
67
  /** phone_otp only: the display-safe OTP send/config surface (never the verifToken). */
68
68
  otp?: HostedOtpView;
69
69
  }
70
+ /** A locale the Sekyro-hosted voice clips are recorded in. */
71
+ type HostedVoiceLocale = "ar" | "fr" | "en";
72
+ /**
73
+ * The session's Sekyro-hosted voice-guidance clips (the active clip set).
74
+ *
75
+ * `clips[locale]` maps a voice key (`fcv3.*`, the `@sekyro/react` voice-key
76
+ * namespace) to an ABSOLUTE URL on the Sekyro assets host
77
+ * (`https://assets.sekyro.ai/voice/<setId>/<locale>/<name>.mp3`; staging:
78
+ * `assets-staging.sekyro.ai`). URLs are immutable per `setId`. A locale or key
79
+ * may be missing — the player falls back to the device voice for it.
80
+ *
81
+ * A page with a Content-Security-Policy must allow the assets origin in
82
+ * `media-src` for the clips to play (see the partner web-SDK guide, CSP note).
83
+ */
84
+ interface HostedVoiceView {
85
+ /** Identifier of the active clip set (part of every clip URL). */
86
+ setId: string;
87
+ /** Per-locale map of voice key (`fcv3.*`) → absolute clip URL. */
88
+ clips: {
89
+ readonly [L in HostedVoiceLocale]?: Readonly<Record<string, string>>;
90
+ };
91
+ }
70
92
  /**
71
93
  * Token-addressed hosted-page bootstrap (`GET /hosted/session`). A separate
72
94
  * shape from the partner `SessionView`: `sessionId` instead of `id`,
@@ -110,6 +132,12 @@ interface HostedSessionView {
110
132
  * valid (additive field, always on the wire from Task 8 onward).
111
133
  */
112
134
  nniBound?: boolean;
135
+ /**
136
+ * The Sekyro-hosted voice-guidance clips of this session, or `null` when no
137
+ * clip set is active (the device voice is used). Optional: older APIs omit
138
+ * the field — treat absent like `null`.
139
+ */
140
+ voice?: HostedVoiceView | null;
113
141
  }
114
142
  /** `POST /hosted/consent` result — 201 on first record, 200 `{alreadyRecorded: true}` on replay. */
115
143
  interface RecordConsentResult {
@@ -418,4 +446,4 @@ declare class HostedClient {
418
446
  private api;
419
447
  }
420
448
 
421
- export { type AttestationInput as A, type CheckReason as C, type DocReason as D, type FaceMatchReason as F, type HostedOtpView as H, type LivenessReason as L, type MediaCheckType as M, type PhoneOtpReason as P, type RecordConsentResult as R, type SessionOutcome as S, type UploadMedia as U, type CheckState as a, type CheckType as b, type HostedSessionView as c, type HostedStepView as d, type PopulationReason as e, type SessionStatus as f, HostedClient as g, type SessionView as h, type CheckInputByType as i, type CompleteMediaResult as j, type ConsentLocale as k, type DocOcrInput as l, type DocSide as m, type FaceMatchInput as n, type HostedClientOptions as o, type LivenessCaptureInput as p, type LivenessInput as q, type MediaKind as r, type PhoneOtpInput as s, type PopulationInput as t, type PresignRequest as u, type PresignUploadResult as v, type SessionStepView as w, type SubmitCheckBody as x, type SubmitOptions as y, stripMimeParams as z };
449
+ export { type AttestationInput as A, type SubmitOptions as B, type CheckReason as C, type DocReason as D, stripMimeParams as E, type FaceMatchReason as F, type HostedOtpView as H, type LivenessReason as L, type MediaCheckType as M, type PhoneOtpReason as P, type RecordConsentResult as R, type SessionOutcome as S, type UploadMedia as U, type CheckState as a, type CheckType as b, type HostedSessionView as c, type HostedStepView as d, type HostedVoiceLocale as e, type HostedVoiceView as f, type PopulationReason as g, type SessionStatus as h, HostedClient as i, type SessionView as j, type CheckInputByType as k, type CompleteMediaResult as l, type ConsentLocale as m, type DocOcrInput as n, type DocSide as o, type FaceMatchInput as p, type HostedClientOptions as q, type LivenessCaptureInput as r, type LivenessInput as s, type MediaKind as t, type PhoneOtpInput as u, type PopulationInput as v, type PresignRequest as w, type PresignUploadResult as x, type SessionStepView as y, type SubmitCheckBody as z };
@@ -67,6 +67,28 @@ interface HostedStepView {
67
67
  /** phone_otp only: the display-safe OTP send/config surface (never the verifToken). */
68
68
  otp?: HostedOtpView;
69
69
  }
70
+ /** A locale the Sekyro-hosted voice clips are recorded in. */
71
+ type HostedVoiceLocale = "ar" | "fr" | "en";
72
+ /**
73
+ * The session's Sekyro-hosted voice-guidance clips (the active clip set).
74
+ *
75
+ * `clips[locale]` maps a voice key (`fcv3.*`, the `@sekyro/react` voice-key
76
+ * namespace) to an ABSOLUTE URL on the Sekyro assets host
77
+ * (`https://assets.sekyro.ai/voice/<setId>/<locale>/<name>.mp3`; staging:
78
+ * `assets-staging.sekyro.ai`). URLs are immutable per `setId`. A locale or key
79
+ * may be missing — the player falls back to the device voice for it.
80
+ *
81
+ * A page with a Content-Security-Policy must allow the assets origin in
82
+ * `media-src` for the clips to play (see the partner web-SDK guide, CSP note).
83
+ */
84
+ interface HostedVoiceView {
85
+ /** Identifier of the active clip set (part of every clip URL). */
86
+ setId: string;
87
+ /** Per-locale map of voice key (`fcv3.*`) → absolute clip URL. */
88
+ clips: {
89
+ readonly [L in HostedVoiceLocale]?: Readonly<Record<string, string>>;
90
+ };
91
+ }
70
92
  /**
71
93
  * Token-addressed hosted-page bootstrap (`GET /hosted/session`). A separate
72
94
  * shape from the partner `SessionView`: `sessionId` instead of `id`,
@@ -110,6 +132,12 @@ interface HostedSessionView {
110
132
  * valid (additive field, always on the wire from Task 8 onward).
111
133
  */
112
134
  nniBound?: boolean;
135
+ /**
136
+ * The Sekyro-hosted voice-guidance clips of this session, or `null` when no
137
+ * clip set is active (the device voice is used). Optional: older APIs omit
138
+ * the field — treat absent like `null`.
139
+ */
140
+ voice?: HostedVoiceView | null;
113
141
  }
114
142
  /** `POST /hosted/consent` result — 201 on first record, 200 `{alreadyRecorded: true}` on replay. */
115
143
  interface RecordConsentResult {
@@ -418,4 +446,4 @@ declare class HostedClient {
418
446
  private api;
419
447
  }
420
448
 
421
- export { type AttestationInput as A, type CheckReason as C, type DocReason as D, type FaceMatchReason as F, type HostedOtpView as H, type LivenessReason as L, type MediaCheckType as M, type PhoneOtpReason as P, type RecordConsentResult as R, type SessionOutcome as S, type UploadMedia as U, type CheckState as a, type CheckType as b, type HostedSessionView as c, type HostedStepView as d, type PopulationReason as e, type SessionStatus as f, HostedClient as g, type SessionView as h, type CheckInputByType as i, type CompleteMediaResult as j, type ConsentLocale as k, type DocOcrInput as l, type DocSide as m, type FaceMatchInput as n, type HostedClientOptions as o, type LivenessCaptureInput as p, type LivenessInput as q, type MediaKind as r, type PhoneOtpInput as s, type PopulationInput as t, type PresignRequest as u, type PresignUploadResult as v, type SessionStepView as w, type SubmitCheckBody as x, type SubmitOptions as y, stripMimeParams as z };
449
+ export { type AttestationInput as A, type SubmitOptions as B, type CheckReason as C, type DocReason as D, stripMimeParams as E, type FaceMatchReason as F, type HostedOtpView as H, type LivenessReason as L, type MediaCheckType as M, type PhoneOtpReason as P, type RecordConsentResult as R, type SessionOutcome as S, type UploadMedia as U, type CheckState as a, type CheckType as b, type HostedSessionView as c, type HostedStepView as d, type HostedVoiceLocale as e, type HostedVoiceView as f, type PopulationReason as g, type SessionStatus as h, HostedClient as i, type SessionView as j, type CheckInputByType as k, type CompleteMediaResult as l, type ConsentLocale as m, type DocOcrInput as n, type DocSide as o, type FaceMatchInput as p, type HostedClientOptions as q, type LivenessCaptureInput as r, type LivenessInput as s, type MediaKind as t, type PhoneOtpInput as u, type PopulationInput as v, type PresignRequest as w, type PresignUploadResult as x, type SessionStepView as y, type SubmitCheckBody as z };