@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
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
- export { C as CaptureChannel, a as CaptureError, b as CaptureErrorKind, c as CaptureState, d as CapturedArtifacts, D as DEFAULT_API_ORIGIN, G as GateHint, e as GateUpdate, L as LivenessCaptureEvents, f as LivenessCaptureHandle, g as LivenessCaptureOptions, R as ReasonCode, S as SdkFailureReason, V as Verification, h as VerificationEvents, i as VerificationLocale, j as VerificationOptions, k as VerificationResult, l as VerificationStatus, m as createLivenessCapture, n as createVerification } from './create-verification-EnZ13uY4.cjs';
1
+ export { C as CaptureChannel, a as CaptureEngineId, b as CaptureError, c as CaptureErrorKind, d as CaptureState, e as CapturedArtifacts, D as DEFAULT_API_ORIGIN, G as GateHint, f as GateUpdate, L as LivenessCaptureEvents, g as LivenessCaptureHandle, h as LivenessCaptureOptions, R as ReasonCode, S as SdkFailureReason, V as Verification, i as VerificationEvents, j as VerificationLocale, k as VerificationOptions, l as VerificationResult, m as VerificationStatus, n as createLivenessCapture, o as createVerification } from './create-verification-Dkb2tXuY.cjs';
2
2
  export { OpenHostedOptions, PopupBlocked, PopupHandle, SEKYRO_EVENTS, SekyroEvent, SekyroEventName, openHosted } from './popup/index.cjs';
3
3
  export { HostedApiError, KNOWN_CODES, KnownCode, isKnownCode } from './client/index.cjs';
4
- export { C as CheckReason, a as CheckState, b as CheckType, D as DocReason, F as FaceMatchReason, H as HostedOtpView, c as HostedSessionView, d as HostedStepView, L as LivenessReason, P as PhoneOtpReason, e as PopulationReason, S as SessionOutcome, f as SessionStatus } from './hosted-client-BpvBqu9f.cjs';
5
- import './capture-session-v3-CAoWM8iT.cjs';
4
+ export { C as CheckReason, a as CheckState, b as CheckType, D as DocReason, F as FaceMatchReason, H as HostedOtpView, c as HostedSessionView, d as HostedStepView, L as LivenessReason, P as PhoneOtpReason, e as PopulationReason, S as SessionOutcome, f as SessionStatus } from './hosted-client-DWzCRYJK.cjs';
5
+ import './capture-session-v3-DEInCOUg.cjs';
6
6
  import './detect-worker-CKXHlXx9.cjs';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { C as CaptureChannel, a as CaptureError, b as CaptureErrorKind, c as CaptureState, d as CapturedArtifacts, D as DEFAULT_API_ORIGIN, G as GateHint, e as GateUpdate, L as LivenessCaptureEvents, f as LivenessCaptureHandle, g as LivenessCaptureOptions, R as ReasonCode, S as SdkFailureReason, V as Verification, h as VerificationEvents, i as VerificationLocale, j as VerificationOptions, k as VerificationResult, l as VerificationStatus, m as createLivenessCapture, n as createVerification } from './create-verification-CjLnJ0w6.js';
1
+ export { C as CaptureChannel, a as CaptureEngineId, b as CaptureError, c as CaptureErrorKind, d as CaptureState, e as CapturedArtifacts, D as DEFAULT_API_ORIGIN, G as GateHint, f as GateUpdate, L as LivenessCaptureEvents, g as LivenessCaptureHandle, h as LivenessCaptureOptions, R as ReasonCode, S as SdkFailureReason, V as Verification, i as VerificationEvents, j as VerificationLocale, k as VerificationOptions, l as VerificationResult, m as VerificationStatus, n as createLivenessCapture, o as createVerification } from './create-verification-Ce1y5kJR.js';
2
2
  export { OpenHostedOptions, PopupBlocked, PopupHandle, SEKYRO_EVENTS, SekyroEvent, SekyroEventName, openHosted } from './popup/index.js';
3
3
  export { HostedApiError, KNOWN_CODES, KnownCode, isKnownCode } from './client/index.js';
4
- export { C as CheckReason, a as CheckState, b as CheckType, D as DocReason, F as FaceMatchReason, H as HostedOtpView, c as HostedSessionView, d as HostedStepView, L as LivenessReason, P as PhoneOtpReason, e as PopulationReason, S as SessionOutcome, f as SessionStatus } from './hosted-client-BpvBqu9f.js';
5
- import './capture-session-v3-BJ8ciaWl.js';
4
+ export { C as CheckReason, a as CheckState, b as CheckType, D as DocReason, F as FaceMatchReason, H as HostedOtpView, c as HostedSessionView, d as HostedStepView, L as LivenessReason, P as PhoneOtpReason, e as PopulationReason, S as SessionOutcome, f as SessionStatus } from './hosted-client-DWzCRYJK.js';
5
+ import './capture-session-v3-uXJr1Wlm.js';
6
6
  import './detect-worker-CKXHlXx9.js';
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@ import {
6
6
  DEFAULT_API_ORIGIN,
7
7
  createLivenessCapture,
8
8
  createVerification
9
- } from "./chunk-BPYVZUJA.js";
10
- import "./chunk-LOTAJDRE.js";
9
+ } from "./chunk-TBANUT3X.js";
10
+ import "./chunk-EWRNPKTR.js";
11
11
  import {
12
12
  HostedApiError,
13
13
  KNOWN_CODES,
@@ -2466,10 +2466,12 @@ var V3_GATE_DEFAULTS = Object.freeze({
2466
2466
  MOTION_TAU_S: 0.4,
2467
2467
  MOTION_DEADBAND_IOD_PER_S: 0.1,
2468
2468
  READY_WINDOW_MS: 500,
2469
- // 0.7→0.75 with the trimmed window: trimming forgives exactly ONE flaky
2470
- // tick; the raised mean keeps a SECOND bad tick (a real sustained wobble)
2471
- // from diluting through at 10 Hz cadences.
2472
- READY_MEAN_Q: 0.75,
2469
+ // (READY_MEAN_Q, the former 0.75 window MEAN, is gone — 2026-10-17 field
2470
+ // bug: a steady q anywhere in [Q_GOOD, 0.75) saturated p at 1, passed every
2471
+ // guide ("hold still") and could never reach the mean, so the ring sat full
2472
+ // and green with nothing recording. Readiness now checks the window against
2473
+ // Q_GOOD, which keeps the one-flaky-tick forgiveness and the second-bad-tick
2474
+ // block without a dead band above the rise threshold.)
2473
2475
  GUIDE_SIZE: 0.6,
2474
2476
  GUIDE_CENTERING: 0.6,
2475
2477
  GUIDE_POSE: 0.6,
@@ -2547,15 +2549,15 @@ var FaceGateV3 = class {
2547
2549
  const worstIndex = windowSamples.indexOf(worst);
2548
2550
  windowSamples = windowSamples.filter((_2, index) => index !== worstIndex);
2549
2551
  }
2550
- const windowMean = windowSamples.reduce((sum, value) => sum + value, 0) / Math.max(1, windowSamples.length);
2551
- const ready = this.p >= 1 && windowMean >= this.t.READY_MEAN_Q;
2552
+ const ready = this.p >= 1 && windowSamples.every((sample) => sample >= this.t.Q_GOOD);
2552
2553
  return {
2553
2554
  at: timestampMs,
2554
2555
  q,
2555
2556
  p: this.p,
2556
2557
  factors,
2557
2558
  guidanceKey: this.guidanceOf(factors, quality, q),
2558
- ready
2559
+ ready,
2560
+ accepted: q >= this.t.Q_GOOD
2559
2561
  };
2560
2562
  }
2561
2563
  geometryOf(observation, input) {
@@ -2674,6 +2676,11 @@ var CaptureSessionV3 = class {
2674
2676
  this.profiler = null;
2675
2677
  this.lastGuidanceKey = null;
2676
2678
  this.positioningStartedAt = 0;
2679
+ // Face-capture timing marks of the CURRENT attempt (engine clock; reset per run).
2680
+ this.cameraRequestedAt = null;
2681
+ this.cameraReadyAt = null;
2682
+ this.faceAcquiredAt = null;
2683
+ this.captureCompleteAt = null;
2677
2684
  this.fired = false;
2678
2685
  this.carriedDegrade = 0;
2679
2686
  this.carriedMeans = [];
@@ -2728,6 +2735,10 @@ var CaptureSessionV3 = class {
2728
2735
  this.lastGuidanceKey = null;
2729
2736
  this.carriedDegrade = 0;
2730
2737
  this.carriedMeans = [];
2738
+ this.cameraRequestedAt = null;
2739
+ this.cameraReadyAt = null;
2740
+ this.faceAcquiredAt = null;
2741
+ this.captureCompleteAt = null;
2731
2742
  this.setState("preflight");
2732
2743
  const preflight = cameraPreflight();
2733
2744
  if (preflight !== "OK") {
@@ -2737,6 +2748,7 @@ var CaptureSessionV3 = class {
2737
2748
  this.setState("acquiring");
2738
2749
  const getUserMedia = options.getUserMedia ?? ((constraints) => navigator.mediaDevices.getUserMedia(constraints));
2739
2750
  let stream;
2751
+ this.cameraRequestedAt = this.now();
2740
2752
  try {
2741
2753
  stream = await getUserMedia(buildCaptureConstraints(detectIsMobile(), this.facing));
2742
2754
  } catch (err) {
@@ -2752,6 +2764,7 @@ var CaptureSessionV3 = class {
2752
2764
  options.video.srcObject = stream;
2753
2765
  await options.video.play().catch(() => void 0);
2754
2766
  if (attempt !== this.attempt) return;
2767
+ this.cameraReadyAt = this.now();
2755
2768
  if (this.detector === null) {
2756
2769
  const ladderOptions = {
2757
2770
  ...options.v3AssetBaseUrl !== void 0 ? { v3AssetBaseUrl: options.v3AssetBaseUrl } : {}
@@ -2851,6 +2864,7 @@ var CaptureSessionV3 = class {
2851
2864
  frameWidth: video.videoWidth,
2852
2865
  frameHeight: video.videoHeight
2853
2866
  });
2867
+ if (tick.accepted && this.faceAcquiredAt === null) this.faceAcquiredAt = tick.at;
2854
2868
  this.emit("checks", {
2855
2869
  engine: "v3",
2856
2870
  progress: tick.p,
@@ -2864,6 +2878,7 @@ var CaptureSessionV3 = class {
2864
2878
  }
2865
2879
  if (tick.ready && this.stateValue === "positioning") {
2866
2880
  this.fired = true;
2881
+ this.captureCompleteAt = tick.at;
2867
2882
  void this.fire(attempt);
2868
2883
  }
2869
2884
  }
@@ -2958,7 +2973,21 @@ var CaptureSessionV3 = class {
2958
2973
  finishCapture(artifacts) {
2959
2974
  this.stopTracks();
2960
2975
  this.setState("captured");
2961
- this.emit("artifacts", artifacts);
2976
+ const timing = this.captureTiming();
2977
+ this.emit("artifacts", timing === void 0 ? artifacts : { ...artifacts, timing });
2978
+ }
2979
+ /** The attempt's capture-phase timing (whole ms, ≥ 0); undefined when no mark landed. */
2980
+ captureTiming() {
2981
+ const span = (from, to) => from !== null && to !== null ? Math.max(0, Math.round(to - from)) : void 0;
2982
+ const cameraReadyMs = span(this.cameraRequestedAt, this.cameraReadyAt);
2983
+ const faceAcquireMs = span(this.cameraReadyAt, this.faceAcquiredAt);
2984
+ const captureMs = span(this.faceAcquiredAt, this.captureCompleteAt);
2985
+ const timing = {
2986
+ ...cameraReadyMs !== void 0 ? { cameraReadyMs } : {},
2987
+ ...faceAcquireMs !== void 0 ? { faceAcquireMs } : {},
2988
+ ...captureMs !== void 0 ? { captureMs } : {}
2989
+ };
2990
+ return Object.keys(timing).length > 0 ? timing : void 0;
2962
2991
  }
2963
2992
  // ── defaults for the canvas-bound seams ────────────────────────────────────
2964
2993
  async defaultKeyframe(video) {
@@ -3167,6 +3196,14 @@ function createLivenessCaptureInternal(options, internals = {}) {
3167
3196
  let animations = "full";
3168
3197
  let recordingStartedAt = null;
3169
3198
  let frozenAt = null;
3199
+ let frameWidth = 0;
3200
+ let frameHeight = 0;
3201
+ const latchFrameSize = () => {
3202
+ if (options.video.videoWidth > 0 && options.video.videoHeight > 0) {
3203
+ frameWidth = options.video.videoWidth;
3204
+ frameHeight = options.video.videoHeight;
3205
+ }
3206
+ };
3170
3207
  const setState = (next) => {
3171
3208
  state = next;
3172
3209
  emitter.emit("state", next);
@@ -3187,10 +3224,13 @@ function createLivenessCaptureInternal(options, internals = {}) {
3187
3224
  faceDetected = false;
3188
3225
  recordingStartedAt = null;
3189
3226
  frozenAt = null;
3227
+ frameWidth = 0;
3228
+ frameHeight = 0;
3190
3229
  }
3191
3230
  setState(next);
3192
3231
  syncProfile();
3193
3232
  if (next === "recording") {
3233
+ latchFrameSize();
3194
3234
  recordingStartedAt = now();
3195
3235
  hint = "hold";
3196
3236
  progress = 1;
@@ -3198,6 +3238,7 @@ function createLivenessCaptureInternal(options, internals = {}) {
3198
3238
  }
3199
3239
  }),
3200
3240
  engine.on("checks", (payload) => {
3241
+ latchFrameSize();
3201
3242
  progress = payload.progress;
3202
3243
  faceDetected = payload.factors.presence > 0;
3203
3244
  emitGate();
@@ -3217,11 +3258,16 @@ function createLivenessCaptureInternal(options, internals = {}) {
3217
3258
  keyframe: artifacts.keyframe,
3218
3259
  ...artifacts.clip !== void 0 ? { clip: artifacts.clip } : {},
3219
3260
  ...artifacts.clipMimeType !== void 0 ? { clipMime: artifacts.clipMimeType } : {},
3220
- width: options.video.videoWidth,
3221
- height: options.video.videoHeight,
3261
+ width: options.video.videoWidth || frameWidth,
3262
+ height: options.video.videoHeight || frameHeight,
3222
3263
  ...clipMs !== void 0 ? { clipMs } : {},
3223
3264
  captureChannel: detectIsMobile() ? "mobile" : "desktop",
3224
- ...degraded ? { degraded: "NO_RECORDER" } : {}
3265
+ ...degraded ? { degraded: "NO_RECORDER" } : {},
3266
+ engine: "v3",
3267
+ // Face-capture timing: the engine's marks, forwarded flat (absent → absent).
3268
+ ...artifacts.timing?.cameraReadyMs !== void 0 ? { cameraReadyMs: artifacts.timing.cameraReadyMs } : {},
3269
+ ...artifacts.timing?.faceAcquireMs !== void 0 ? { faceAcquireMs: artifacts.timing.faceAcquireMs } : {},
3270
+ ...artifacts.timing?.captureMs !== void 0 ? { captureMs: artifacts.timing.captureMs } : {}
3225
3271
  });
3226
3272
  }),
3227
3273
  engine.on("error", ({ kind, retryable }) => {
@@ -3720,7 +3766,12 @@ function buildLivenessSubmit(deps, clip, bareMime) {
3720
3766
  deps.onPhase("checking");
3721
3767
  return client.submitCheck(
3722
3768
  "liveness",
3723
- { clipKey, attestation, captureChannel: deps.artifacts.captureChannel },
3769
+ {
3770
+ clipKey,
3771
+ attestation,
3772
+ captureChannel: deps.artifacts.captureChannel,
3773
+ capture: captureInputOf(deps.artifacts)
3774
+ },
3724
3775
  { idempotencyKey }
3725
3776
  );
3726
3777
  },
@@ -3731,6 +3782,17 @@ function buildLivenessSubmit(deps, clip, bareMime) {
3731
3782
  }
3732
3783
  );
3733
3784
  }
3785
+ function captureInputOf(artifacts) {
3786
+ return {
3787
+ ...artifacts.engine !== void 0 ? { engine: artifacts.engine } : {},
3788
+ width: artifacts.width,
3789
+ height: artifacts.height,
3790
+ ...artifacts.clipMs !== void 0 ? { clipMs: artifacts.clipMs } : {},
3791
+ ...artifacts.cameraReadyMs !== void 0 ? { cameraReadyMs: artifacts.cameraReadyMs } : {},
3792
+ ...artifacts.faceAcquireMs !== void 0 ? { faceAcquireMs: artifacts.faceAcquireMs } : {},
3793
+ ...artifacts.captureMs !== void 0 ? { captureMs: artifacts.captureMs } : {}
3794
+ };
3795
+ }
3734
3796
  function buildFaceMatchSubmit(deps, keyframe) {
3735
3797
  let imageKey = null;
3736
3798
  return () => runSubmission(deps, async (client, idempotencyKey) => {