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

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 (32) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/{capture-session-v3-CAoWM8iT.d.cts → capture-session-v3-DEInCOUg.d.cts} +37 -7
  3. package/dist/{capture-session-v3-BJ8ciaWl.d.ts → capture-session-v3-uXJr1Wlm.d.ts} +37 -7
  4. package/dist/{chunk-LOTAJDRE.js → chunk-EWRNPKTR.js} +38 -9
  5. package/dist/chunk-EWRNPKTR.js.map +1 -0
  6. package/dist/{chunk-BPYVZUJA.js → chunk-TBANUT3X.js} +39 -6
  7. package/dist/chunk-TBANUT3X.js.map +1 -0
  8. package/dist/client/index.cjs.map +1 -1
  9. package/dist/client/index.d.cts +1 -1
  10. package/dist/client/index.d.ts +1 -1
  11. package/dist/core/index.cjs +37 -8
  12. package/dist/core/index.cjs.map +1 -1
  13. package/dist/core/index.d.cts +2 -2
  14. package/dist/core/index.d.ts +2 -2
  15. package/dist/core/index.js +1 -1
  16. package/dist/{create-verification-EnZ13uY4.d.cts → create-verification-Ce1y5kJR.d.ts} +26 -3
  17. package/dist/{create-verification-CjLnJ0w6.d.ts → create-verification-Dkb2tXuY.d.cts} +26 -3
  18. package/dist/{hosted-client-BpvBqu9f.d.cts → hosted-client-DWzCRYJK.d.cts} +14 -1
  19. package/dist/{hosted-client-BpvBqu9f.d.ts → hosted-client-DWzCRYJK.d.ts} +14 -1
  20. package/dist/index.cjs +74 -12
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +3 -3
  23. package/dist/index.d.ts +3 -3
  24. package/dist/index.js +2 -2
  25. package/dist/internal/index.cjs +74 -12
  26. package/dist/internal/index.cjs.map +1 -1
  27. package/dist/internal/index.d.cts +4 -4
  28. package/dist/internal/index.d.ts +4 -4
  29. package/dist/internal/index.js +2 -2
  30. package/package.json +1 -1
  31. package/dist/chunk-BPYVZUJA.js.map +0 -1
  32. package/dist/chunk-LOTAJDRE.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { C as CameraErrorKind } from '../capture-session-v3-CAoWM8iT.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 ClipError, j as ClipErrorKind, k as ClipRecorder, l as ClipResult, D as DEFAULT_CLIP_MIME, m as DEVICE_PROFILES, n as DeviceClass, o as DeviceProbe, p as DeviceProfile, q as DeviceProfiler, E as EscalationClipArtifact, r as EscalationHook, F as FaceGateV3, G as GateChecks, K as KEYFRAME_CANDIDATES, s as KEYFRAME_WINDOW_MS, M as MAX_CLIP_BYTES, t as MIME_CANDIDATES, S as STOP_GRACE_MS, T as TIMESLICE_MS, V as V3ChecksPayload, u as V3GateFactor, v as V3GateQuality, w as V3GateThresholds, x as V3GateTick, y as V3GateTickInput, z as V3TelemetryEvent, A as V3_GATE_DEFAULTS, B as VIDEO_BPS, H as buildLivenessV2FormData, I as cameraPreflight, J as classifyDevice, L as extForMime, N as isClipTooLarge, O as isMediaRecorderSupported, P as mapGetUserMediaError, Q as pickMimeType, R as probeDevice } from '../capture-session-v3-CAoWM8iT.cjs';
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';
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-BJ8ciaWl.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 ClipError, j as ClipErrorKind, k as ClipRecorder, l as ClipResult, D as DEFAULT_CLIP_MIME, m as DEVICE_PROFILES, n as DeviceClass, o as DeviceProbe, p as DeviceProfile, q as DeviceProfiler, E as EscalationClipArtifact, r as EscalationHook, F as FaceGateV3, G as GateChecks, K as KEYFRAME_CANDIDATES, s as KEYFRAME_WINDOW_MS, M as MAX_CLIP_BYTES, t as MIME_CANDIDATES, S as STOP_GRACE_MS, T as TIMESLICE_MS, V as V3ChecksPayload, u as V3GateFactor, v as V3GateQuality, w as V3GateThresholds, x as V3GateTick, y as V3GateTickInput, z as V3TelemetryEvent, A as V3_GATE_DEFAULTS, B as VIDEO_BPS, H as buildLivenessV2FormData, I as cameraPreflight, J as classifyDevice, L as extForMime, N as isClipTooLarge, O as isMediaRecorderSupported, P as mapGetUserMediaError, Q as pickMimeType, R as probeDevice } from '../capture-session-v3-BJ8ciaWl.js';
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';
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-LOTAJDRE.js";
34
+ } from "../chunk-EWRNPKTR.js";
35
35
  import {
36
36
  DEFAULT_TIER_ORDER,
37
37
  DEFAULT_V3_ASSET_BASE_URL,
@@ -1,5 +1,5 @@
1
- import { h as CaptureState$1, f as CaptureSessionV3Events, g as CaptureSessionV3Options, c as CaptureErrorKind$1 } from './capture-session-v3-CAoWM8iT.cjs';
2
- import { C as CheckReason, c as HostedSessionView, g as HostedClient, A as AttestationInput, h as SessionView, b as CheckType } from './hosted-client-BpvBqu9f.cjs';
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';
3
3
 
4
4
  /** Gate guidance code. `'hold'` is emitted while the clip records. */
5
5
  type GateHint = "center" | "closer" | "farther" | "light" | "still" | "hold";
@@ -47,7 +47,30 @@ interface CapturedArtifacts {
47
47
  captureChannel: CaptureChannel;
48
48
  /** Set when the browser has no MediaRecorder: a keyframe-only capture. */
49
49
  degraded?: "NO_RECORDER";
50
+ /** The capture engine that produced the artifacts (`'v3'` for this SDK). Always set by the SDK; optional in the type so host-built fixtures stay valid. */
51
+ engine?: CaptureEngineId;
52
+ /**
53
+ * Camera request (`getUserMedia`) → the preview is live, in whole
54
+ * milliseconds measured with `performance.now()`. Part of the face-capture
55
+ * timing the SDK forwards to the backend as `input.capture` on the liveness
56
+ * submission; absent when the phase was not observed.
57
+ */
58
+ cameraReadyMs?: number;
59
+ /**
60
+ * Camera ready → the first face ACCEPTED by the gate (present and with
61
+ * size, centering and quality good enough to make progress — not merely
62
+ * detected), whole ms. Absent when no face was ever accepted.
63
+ */
64
+ faceAcquireMs?: number;
65
+ /**
66
+ * Face-capture duration: FIRST accepted face → gate progress 100 % (capture
67
+ * complete, before the clip window and any upload), whole ms. A face lost
68
+ * and re-acquired keeps the first acceptance as its start.
69
+ */
70
+ captureMs?: number;
50
71
  }
72
+ /** Capture engine identifier carried on {@link CapturedArtifacts.engine}. */
73
+ type CaptureEngineId = "v1" | "v3";
51
74
  /** Camera / engine failure kinds — collapsed to the public six. */
52
75
  type CaptureErrorKind = "permission" | "notfound" | "inuse" | "insecure" | "unsupported" | "generic";
53
76
  /** Camera / engine failure payload (`on('error')`). */
@@ -345,4 +368,4 @@ declare function createVerification(options: VerificationOptions): Verification;
345
368
  /** {@link createVerification} with construction seams (tests / Sekyro-internal hosts). */
346
369
  declare function createVerificationInternal(options: VerificationOptions, internals: VerificationInternals): Verification;
347
370
 
348
- export { AttestationError as A, createLivenessCaptureInternal as B, type CaptureChannel as C, DEFAULT_API_ORIGIN as D, createVerificationInternal as E, mapEngineState as F, type GateHint as G, type HostedClientLike as H, mapErrorKind as I, mapGuidanceHint as J, randomUuid as K, type LivenessCaptureEvents as L, runLivenessFlow as M, runSubmission as N, PROCESSING_POLL_DELAY_MS as P, type ReasonCode as R, type SdkFailureReason as S, TRANSPORT_REPLAY_ATTEMPTS as T, type Verification as V, type CaptureError as a, type CaptureErrorKind as b, type CaptureState as c, type CapturedArtifacts as d, type GateUpdate as e, type LivenessCaptureHandle as f, type LivenessCaptureOptions as g, type VerificationEvents as h, type VerificationLocale as i, type VerificationOptions as j, type VerificationResult as k, type VerificationStatus as l, createLivenessCapture as m, createVerification as n, CLIP_MIME_ALLOWLIST as o, type CaptureEngine as p, type LivenessCaptureInternalHandle as q, type LivenessCaptureInternals as r, type LivenessFlowDeps as s, type LivenessFlowOutcome as t, PROCESSING_POLL_MAX as u, REGISTRY_RETRY_DELAY_MS as v, type SubmitExecutor as w, type SubmitRuntime as x, TRANSPORT_REPLAY_DELAY_MS as y, type VerificationInternals as z };
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 };
@@ -1,5 +1,5 @@
1
- import { h as CaptureState$1, f as CaptureSessionV3Events, g as CaptureSessionV3Options, c as CaptureErrorKind$1 } from './capture-session-v3-BJ8ciaWl.js';
2
- import { C as CheckReason, c as HostedSessionView, g as HostedClient, A as AttestationInput, h as SessionView, b as CheckType } from './hosted-client-BpvBqu9f.js';
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';
3
3
 
4
4
  /** Gate guidance code. `'hold'` is emitted while the clip records. */
5
5
  type GateHint = "center" | "closer" | "farther" | "light" | "still" | "hold";
@@ -47,7 +47,30 @@ interface CapturedArtifacts {
47
47
  captureChannel: CaptureChannel;
48
48
  /** Set when the browser has no MediaRecorder: a keyframe-only capture. */
49
49
  degraded?: "NO_RECORDER";
50
+ /** The capture engine that produced the artifacts (`'v3'` for this SDK). Always set by the SDK; optional in the type so host-built fixtures stay valid. */
51
+ engine?: CaptureEngineId;
52
+ /**
53
+ * Camera request (`getUserMedia`) → the preview is live, in whole
54
+ * milliseconds measured with `performance.now()`. Part of the face-capture
55
+ * timing the SDK forwards to the backend as `input.capture` on the liveness
56
+ * submission; absent when the phase was not observed.
57
+ */
58
+ cameraReadyMs?: number;
59
+ /**
60
+ * Camera ready → the first face ACCEPTED by the gate (present and with
61
+ * size, centering and quality good enough to make progress — not merely
62
+ * detected), whole ms. Absent when no face was ever accepted.
63
+ */
64
+ faceAcquireMs?: number;
65
+ /**
66
+ * Face-capture duration: FIRST accepted face → gate progress 100 % (capture
67
+ * complete, before the clip window and any upload), whole ms. A face lost
68
+ * and re-acquired keeps the first acceptance as its start.
69
+ */
70
+ captureMs?: number;
50
71
  }
72
+ /** Capture engine identifier carried on {@link CapturedArtifacts.engine}. */
73
+ type CaptureEngineId = "v1" | "v3";
51
74
  /** Camera / engine failure kinds — collapsed to the public six. */
52
75
  type CaptureErrorKind = "permission" | "notfound" | "inuse" | "insecure" | "unsupported" | "generic";
53
76
  /** Camera / engine failure payload (`on('error')`). */
@@ -345,4 +368,4 @@ declare function createVerification(options: VerificationOptions): Verification;
345
368
  /** {@link createVerification} with construction seams (tests / Sekyro-internal hosts). */
346
369
  declare function createVerificationInternal(options: VerificationOptions, internals: VerificationInternals): Verification;
347
370
 
348
- export { AttestationError as A, createLivenessCaptureInternal as B, type CaptureChannel as C, DEFAULT_API_ORIGIN as D, createVerificationInternal as E, mapEngineState as F, type GateHint as G, type HostedClientLike as H, mapErrorKind as I, mapGuidanceHint as J, randomUuid as K, type LivenessCaptureEvents as L, runLivenessFlow as M, runSubmission as N, PROCESSING_POLL_DELAY_MS as P, type ReasonCode as R, type SdkFailureReason as S, TRANSPORT_REPLAY_ATTEMPTS as T, type Verification as V, type CaptureError as a, type CaptureErrorKind as b, type CaptureState as c, type CapturedArtifacts as d, type GateUpdate as e, type LivenessCaptureHandle as f, type LivenessCaptureOptions as g, type VerificationEvents as h, type VerificationLocale as i, type VerificationOptions as j, type VerificationResult as k, type VerificationStatus as l, createLivenessCapture as m, createVerification as n, CLIP_MIME_ALLOWLIST as o, type CaptureEngine as p, type LivenessCaptureInternalHandle as q, type LivenessCaptureInternals as r, type LivenessFlowDeps as s, type LivenessFlowOutcome as t, PROCESSING_POLL_MAX as u, REGISTRY_RETRY_DELAY_MS as v, type SubmitExecutor as w, type SubmitRuntime as x, TRANSPORT_REPLAY_DELAY_MS as y, type VerificationInternals as z };
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 };
@@ -190,6 +190,19 @@ interface LivenessInput {
190
190
  * Client-declared by design (not a security boundary); absent = legacy
191
191
  * clients, treated as mobile server-side during the rollout window. */
192
192
  captureChannel?: 'mobile' | 'desktop';
193
+ /** Capture metadata (engine, dimensions, clip length, face-capture timing)
194
+ * — the backend's allowlisted, non-PII `capture` block (session insights). */
195
+ capture?: LivenessCaptureInput;
196
+ }
197
+ /** `LivenessInput.capture`: what the SDK's `captured` event measured. All ms are whole, ≥ 0. */
198
+ interface LivenessCaptureInput {
199
+ engine?: 'v1' | 'v3';
200
+ width?: number;
201
+ height?: number;
202
+ clipMs?: number;
203
+ cameraReadyMs?: number;
204
+ faceAcquireMs?: number;
205
+ captureMs?: number;
193
206
  }
194
207
  /**
195
208
  * population_registry adapter input. `nni` is the 10-digit NNI for an UNBOUND
@@ -405,4 +418,4 @@ declare class HostedClient {
405
418
  private api;
406
419
  }
407
420
 
408
- 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 LivenessInput as p, type MediaKind as q, type PhoneOtpInput as r, type PopulationInput as s, type PresignRequest as t, type PresignUploadResult as u, type SessionStepView as v, type SubmitCheckBody as w, type SubmitOptions as x, stripMimeParams as y };
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 };
@@ -190,6 +190,19 @@ interface LivenessInput {
190
190
  * Client-declared by design (not a security boundary); absent = legacy
191
191
  * clients, treated as mobile server-side during the rollout window. */
192
192
  captureChannel?: 'mobile' | 'desktop';
193
+ /** Capture metadata (engine, dimensions, clip length, face-capture timing)
194
+ * — the backend's allowlisted, non-PII `capture` block (session insights). */
195
+ capture?: LivenessCaptureInput;
196
+ }
197
+ /** `LivenessInput.capture`: what the SDK's `captured` event measured. All ms are whole, ≥ 0. */
198
+ interface LivenessCaptureInput {
199
+ engine?: 'v1' | 'v3';
200
+ width?: number;
201
+ height?: number;
202
+ clipMs?: number;
203
+ cameraReadyMs?: number;
204
+ faceAcquireMs?: number;
205
+ captureMs?: number;
193
206
  }
194
207
  /**
195
208
  * population_registry adapter input. `nni` is the 10-digit NNI for an UNBOUND
@@ -405,4 +418,4 @@ declare class HostedClient {
405
418
  private api;
406
419
  }
407
420
 
408
- 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 LivenessInput as p, type MediaKind as q, type PhoneOtpInput as r, type PopulationInput as s, type PresignRequest as t, type PresignUploadResult as u, type SessionStepView as v, type SubmitCheckBody as w, type SubmitOptions as x, stripMimeParams as y };
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 };
package/dist/index.cjs CHANGED
@@ -862,10 +862,12 @@ var V3_GATE_DEFAULTS = Object.freeze({
862
862
  MOTION_TAU_S: 0.4,
863
863
  MOTION_DEADBAND_IOD_PER_S: 0.1,
864
864
  READY_WINDOW_MS: 500,
865
- // 0.7→0.75 with the trimmed window: trimming forgives exactly ONE flaky
866
- // tick; the raised mean keeps a SECOND bad tick (a real sustained wobble)
867
- // from diluting through at 10 Hz cadences.
868
- READY_MEAN_Q: 0.75,
865
+ // (READY_MEAN_Q, the former 0.75 window MEAN, is gone — 2026-10-17 field
866
+ // bug: a steady q anywhere in [Q_GOOD, 0.75) saturated p at 1, passed every
867
+ // guide ("hold still") and could never reach the mean, so the ring sat full
868
+ // and green with nothing recording. Readiness now checks the window against
869
+ // Q_GOOD, which keeps the one-flaky-tick forgiveness and the second-bad-tick
870
+ // block without a dead band above the rise threshold.)
869
871
  GUIDE_SIZE: 0.6,
870
872
  GUIDE_CENTERING: 0.6,
871
873
  GUIDE_POSE: 0.6,
@@ -943,15 +945,15 @@ var FaceGateV3 = class {
943
945
  const worstIndex = windowSamples.indexOf(worst);
944
946
  windowSamples = windowSamples.filter((_, index) => index !== worstIndex);
945
947
  }
946
- const windowMean = windowSamples.reduce((sum, value) => sum + value, 0) / Math.max(1, windowSamples.length);
947
- const ready = this.p >= 1 && windowMean >= this.t.READY_MEAN_Q;
948
+ const ready = this.p >= 1 && windowSamples.every((sample) => sample >= this.t.Q_GOOD);
948
949
  return {
949
950
  at: timestampMs,
950
951
  q,
951
952
  p: this.p,
952
953
  factors,
953
954
  guidanceKey: this.guidanceOf(factors, quality, q),
954
- ready
955
+ ready,
956
+ accepted: q >= this.t.Q_GOOD
955
957
  };
956
958
  }
957
959
  geometryOf(observation, input) {
@@ -1069,6 +1071,11 @@ var CaptureSessionV3 = class {
1069
1071
  this.profiler = null;
1070
1072
  this.lastGuidanceKey = null;
1071
1073
  this.positioningStartedAt = 0;
1074
+ // Face-capture timing marks of the CURRENT attempt (engine clock; reset per run).
1075
+ this.cameraRequestedAt = null;
1076
+ this.cameraReadyAt = null;
1077
+ this.faceAcquiredAt = null;
1078
+ this.captureCompleteAt = null;
1072
1079
  this.fired = false;
1073
1080
  this.carriedDegrade = 0;
1074
1081
  this.carriedMeans = [];
@@ -1123,6 +1130,10 @@ var CaptureSessionV3 = class {
1123
1130
  this.lastGuidanceKey = null;
1124
1131
  this.carriedDegrade = 0;
1125
1132
  this.carriedMeans = [];
1133
+ this.cameraRequestedAt = null;
1134
+ this.cameraReadyAt = null;
1135
+ this.faceAcquiredAt = null;
1136
+ this.captureCompleteAt = null;
1126
1137
  this.setState("preflight");
1127
1138
  const preflight = cameraPreflight();
1128
1139
  if (preflight !== "OK") {
@@ -1132,6 +1143,7 @@ var CaptureSessionV3 = class {
1132
1143
  this.setState("acquiring");
1133
1144
  const getUserMedia = options.getUserMedia ?? ((constraints) => navigator.mediaDevices.getUserMedia(constraints));
1134
1145
  let stream;
1146
+ this.cameraRequestedAt = this.now();
1135
1147
  try {
1136
1148
  stream = await getUserMedia(buildCaptureConstraints(detectIsMobile(), this.facing));
1137
1149
  } catch (err) {
@@ -1147,6 +1159,7 @@ var CaptureSessionV3 = class {
1147
1159
  options.video.srcObject = stream;
1148
1160
  await options.video.play().catch(() => void 0);
1149
1161
  if (attempt !== this.attempt) return;
1162
+ this.cameraReadyAt = this.now();
1150
1163
  if (this.detector === null) {
1151
1164
  const ladderOptions = {
1152
1165
  ...options.v3AssetBaseUrl !== void 0 ? { v3AssetBaseUrl: options.v3AssetBaseUrl } : {}
@@ -1246,6 +1259,7 @@ var CaptureSessionV3 = class {
1246
1259
  frameWidth: video.videoWidth,
1247
1260
  frameHeight: video.videoHeight
1248
1261
  });
1262
+ if (tick.accepted && this.faceAcquiredAt === null) this.faceAcquiredAt = tick.at;
1249
1263
  this.emit("checks", {
1250
1264
  engine: "v3",
1251
1265
  progress: tick.p,
@@ -1259,6 +1273,7 @@ var CaptureSessionV3 = class {
1259
1273
  }
1260
1274
  if (tick.ready && this.stateValue === "positioning") {
1261
1275
  this.fired = true;
1276
+ this.captureCompleteAt = tick.at;
1262
1277
  void this.fire(attempt);
1263
1278
  }
1264
1279
  }
@@ -1353,7 +1368,21 @@ var CaptureSessionV3 = class {
1353
1368
  finishCapture(artifacts) {
1354
1369
  this.stopTracks();
1355
1370
  this.setState("captured");
1356
- this.emit("artifacts", artifacts);
1371
+ const timing = this.captureTiming();
1372
+ this.emit("artifacts", timing === void 0 ? artifacts : { ...artifacts, timing });
1373
+ }
1374
+ /** The attempt's capture-phase timing (whole ms, ≥ 0); undefined when no mark landed. */
1375
+ captureTiming() {
1376
+ const span = (from, to) => from !== null && to !== null ? Math.max(0, Math.round(to - from)) : void 0;
1377
+ const cameraReadyMs = span(this.cameraRequestedAt, this.cameraReadyAt);
1378
+ const faceAcquireMs = span(this.cameraReadyAt, this.faceAcquiredAt);
1379
+ const captureMs = span(this.faceAcquiredAt, this.captureCompleteAt);
1380
+ const timing = {
1381
+ ...cameraReadyMs !== void 0 ? { cameraReadyMs } : {},
1382
+ ...faceAcquireMs !== void 0 ? { faceAcquireMs } : {},
1383
+ ...captureMs !== void 0 ? { captureMs } : {}
1384
+ };
1385
+ return Object.keys(timing).length > 0 ? timing : void 0;
1357
1386
  }
1358
1387
  // ── defaults for the canvas-bound seams ────────────────────────────────────
1359
1388
  async defaultKeyframe(video) {
@@ -1562,6 +1591,14 @@ function createLivenessCaptureInternal(options, internals = {}) {
1562
1591
  let animations = "full";
1563
1592
  let recordingStartedAt = null;
1564
1593
  let frozenAt = null;
1594
+ let frameWidth = 0;
1595
+ let frameHeight = 0;
1596
+ const latchFrameSize = () => {
1597
+ if (options.video.videoWidth > 0 && options.video.videoHeight > 0) {
1598
+ frameWidth = options.video.videoWidth;
1599
+ frameHeight = options.video.videoHeight;
1600
+ }
1601
+ };
1565
1602
  const setState = (next) => {
1566
1603
  state = next;
1567
1604
  emitter.emit("state", next);
@@ -1582,10 +1619,13 @@ function createLivenessCaptureInternal(options, internals = {}) {
1582
1619
  faceDetected = false;
1583
1620
  recordingStartedAt = null;
1584
1621
  frozenAt = null;
1622
+ frameWidth = 0;
1623
+ frameHeight = 0;
1585
1624
  }
1586
1625
  setState(next);
1587
1626
  syncProfile();
1588
1627
  if (next === "recording") {
1628
+ latchFrameSize();
1589
1629
  recordingStartedAt = now();
1590
1630
  hint = "hold";
1591
1631
  progress = 1;
@@ -1593,6 +1633,7 @@ function createLivenessCaptureInternal(options, internals = {}) {
1593
1633
  }
1594
1634
  }),
1595
1635
  engine.on("checks", (payload) => {
1636
+ latchFrameSize();
1596
1637
  progress = payload.progress;
1597
1638
  faceDetected = payload.factors.presence > 0;
1598
1639
  emitGate();
@@ -1612,11 +1653,16 @@ function createLivenessCaptureInternal(options, internals = {}) {
1612
1653
  keyframe: artifacts.keyframe,
1613
1654
  ...artifacts.clip !== void 0 ? { clip: artifacts.clip } : {},
1614
1655
  ...artifacts.clipMimeType !== void 0 ? { clipMime: artifacts.clipMimeType } : {},
1615
- width: options.video.videoWidth,
1616
- height: options.video.videoHeight,
1656
+ width: options.video.videoWidth || frameWidth,
1657
+ height: options.video.videoHeight || frameHeight,
1617
1658
  ...clipMs !== void 0 ? { clipMs } : {},
1618
1659
  captureChannel: detectIsMobile() ? "mobile" : "desktop",
1619
- ...degraded ? { degraded: "NO_RECORDER" } : {}
1660
+ ...degraded ? { degraded: "NO_RECORDER" } : {},
1661
+ engine: "v3",
1662
+ // Face-capture timing: the engine's marks, forwarded flat (absent → absent).
1663
+ ...artifacts.timing?.cameraReadyMs !== void 0 ? { cameraReadyMs: artifacts.timing.cameraReadyMs } : {},
1664
+ ...artifacts.timing?.faceAcquireMs !== void 0 ? { faceAcquireMs: artifacts.timing.faceAcquireMs } : {},
1665
+ ...artifacts.timing?.captureMs !== void 0 ? { captureMs: artifacts.timing.captureMs } : {}
1620
1666
  });
1621
1667
  }),
1622
1668
  engine.on("error", ({ kind, retryable }) => {
@@ -2191,7 +2237,12 @@ function buildLivenessSubmit(deps, clip, bareMime) {
2191
2237
  deps.onPhase("checking");
2192
2238
  return client.submitCheck(
2193
2239
  "liveness",
2194
- { clipKey, attestation, captureChannel: deps.artifacts.captureChannel },
2240
+ {
2241
+ clipKey,
2242
+ attestation,
2243
+ captureChannel: deps.artifacts.captureChannel,
2244
+ capture: captureInputOf(deps.artifacts)
2245
+ },
2195
2246
  { idempotencyKey }
2196
2247
  );
2197
2248
  },
@@ -2202,6 +2253,17 @@ function buildLivenessSubmit(deps, clip, bareMime) {
2202
2253
  }
2203
2254
  );
2204
2255
  }
2256
+ function captureInputOf(artifacts) {
2257
+ return {
2258
+ ...artifacts.engine !== void 0 ? { engine: artifacts.engine } : {},
2259
+ width: artifacts.width,
2260
+ height: artifacts.height,
2261
+ ...artifacts.clipMs !== void 0 ? { clipMs: artifacts.clipMs } : {},
2262
+ ...artifacts.cameraReadyMs !== void 0 ? { cameraReadyMs: artifacts.cameraReadyMs } : {},
2263
+ ...artifacts.faceAcquireMs !== void 0 ? { faceAcquireMs: artifacts.faceAcquireMs } : {},
2264
+ ...artifacts.captureMs !== void 0 ? { captureMs: artifacts.captureMs } : {}
2265
+ };
2266
+ }
2205
2267
  function buildFaceMatchSubmit(deps, keyframe) {
2206
2268
  let imageKey = null;
2207
2269
  return () => runSubmission(deps, async (client, idempotencyKey) => {