@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.
- package/CHANGELOG.md +30 -0
- package/README.md +44 -0
- package/dist/{capture-session-v3-uXJr1Wlm.d.ts → capture-session-v3-Okq0EQHG.d.ts} +9 -2
- package/dist/{capture-session-v3-DEInCOUg.d.cts → capture-session-v3-UQU_WjO2.d.cts} +9 -2
- package/dist/{chunk-TBANUT3X.js → chunk-R3SJQHYU.js} +296 -8
- package/dist/chunk-R3SJQHYU.js.map +1 -0
- package/dist/{chunk-EWRNPKTR.js → chunk-TG5IE552.js} +7 -2
- package/dist/{chunk-EWRNPKTR.js.map → chunk-TG5IE552.js.map} +1 -1
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/core/index.cjs +6 -1
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +1 -1
- package/dist/{create-verification-Dkb2tXuY.d.cts → create-verification-BKc9NFQj.d.cts} +92 -8
- package/dist/{create-verification-Ce1y5kJR.d.ts → create-verification-DjcMZHAQ.d.ts} +92 -8
- package/dist/{hosted-client-DWzCRYJK.d.cts → hosted-client-DJXq_CB9.d.cts} +29 -1
- package/dist/{hosted-client-DWzCRYJK.d.ts → hosted-client-DJXq_CB9.d.ts} +29 -1
- package/dist/index.cjs +341 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +61 -4
- package/dist/index.js.map +1 -1
- package/dist/internal/index.cjs +218 -7
- package/dist/internal/index.cjs.map +1 -1
- package/dist/internal/index.d.cts +4 -4
- package/dist/internal/index.d.ts +4 -4
- package/dist/internal/index.js +12 -2
- package/dist/internal/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-TBANUT3X.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -36,8 +36,15 @@ __export(src_exports, {
|
|
|
36
36
|
SEKYRO_EVENTS: () => SEKYRO_EVENTS,
|
|
37
37
|
createLivenessCapture: () => createLivenessCapture,
|
|
38
38
|
createVerification: () => createVerification,
|
|
39
|
+
getLivenessAssetsStatus: () => getLivenessAssetsStatus,
|
|
40
|
+
hasMultipleCameras: () => hasMultipleCameras,
|
|
39
41
|
isKnownCode: () => isKnownCode,
|
|
40
|
-
openHosted: () => openHosted
|
|
42
|
+
openHosted: () => openHosted,
|
|
43
|
+
preloadLivenessAssets: () => preloadLivenessAssets,
|
|
44
|
+
queryCameraPermission: () => queryCameraPermission,
|
|
45
|
+
releaseLivenessAssets: () => releaseLivenessAssets,
|
|
46
|
+
subscribeCameraPermission: () => subscribeCameraPermission,
|
|
47
|
+
subscribeLivenessAssets: () => subscribeLivenessAssets
|
|
41
48
|
});
|
|
42
49
|
module.exports = __toCommonJS(src_exports);
|
|
43
50
|
|
|
@@ -1102,10 +1109,15 @@ var CaptureSessionV3 = class {
|
|
|
1102
1109
|
handler(payload);
|
|
1103
1110
|
}
|
|
1104
1111
|
}
|
|
1105
|
-
async start() {
|
|
1112
|
+
async start(options = {}) {
|
|
1113
|
+
if (options.facingMode !== void 0) this.facing = options.facingMode;
|
|
1106
1114
|
this.attempt += 1;
|
|
1107
1115
|
await this.run(this.attempt);
|
|
1108
1116
|
}
|
|
1117
|
+
/** The camera the current/next attempt requests (start option, switchCamera toggles). */
|
|
1118
|
+
get facingMode() {
|
|
1119
|
+
return this.facing;
|
|
1120
|
+
}
|
|
1109
1121
|
/** Full reset + camera restart — the documented recovery path (v1 parity). */
|
|
1110
1122
|
retry() {
|
|
1111
1123
|
this.teardownAttempt();
|
|
@@ -1513,6 +1525,250 @@ function createEmitter() {
|
|
|
1513
1525
|
};
|
|
1514
1526
|
}
|
|
1515
1527
|
|
|
1528
|
+
// src/capture/preload.ts
|
|
1529
|
+
var PRELOAD_BLAZE_INIT_TIMEOUT_MS = 12e4;
|
|
1530
|
+
var PRELOAD_BUDGET_MS = 13e4;
|
|
1531
|
+
var IDLE_TIMEOUT_MS = 3e3;
|
|
1532
|
+
var IDLE_FALLBACK_MS = 1200;
|
|
1533
|
+
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("@sekyro/web.preload.v1");
|
|
1534
|
+
function registry() {
|
|
1535
|
+
const host = globalThis;
|
|
1536
|
+
host[REGISTRY_KEY] ?? (host[REGISTRY_KEY] = /* @__PURE__ */ new Map());
|
|
1537
|
+
return host[REGISTRY_KEY];
|
|
1538
|
+
}
|
|
1539
|
+
function normalizeBase(assetBaseUrl) {
|
|
1540
|
+
const base = (assetBaseUrl ?? DEFAULT_V3_ASSET_BASE_URL).replace(/\/+$/, "");
|
|
1541
|
+
return base === "" ? "/" : base;
|
|
1542
|
+
}
|
|
1543
|
+
function entryFor(base) {
|
|
1544
|
+
const map = registry();
|
|
1545
|
+
let entry = map.get(base);
|
|
1546
|
+
if (entry === void 0) {
|
|
1547
|
+
entry = { status: "idle", promise: null, scheduled: null, detectorPromise: null, detector: null, listeners: /* @__PURE__ */ new Set() };
|
|
1548
|
+
map.set(base, entry);
|
|
1549
|
+
}
|
|
1550
|
+
return entry;
|
|
1551
|
+
}
|
|
1552
|
+
function setStatus(entry, next) {
|
|
1553
|
+
if (entry.status === next) return;
|
|
1554
|
+
entry.status = next;
|
|
1555
|
+
for (const listener of [...entry.listeners]) listener(next);
|
|
1556
|
+
}
|
|
1557
|
+
var defaultLoader = (base) => createDetector({ preferred: ["blaze"], v3AssetBaseUrl: base, blazeInitTimeoutMs: PRELOAD_BLAZE_INIT_TIMEOUT_MS });
|
|
1558
|
+
var loader = defaultLoader;
|
|
1559
|
+
function canCapture() {
|
|
1560
|
+
return typeof window !== "undefined" && typeof navigator !== "undefined" && typeof navigator.mediaDevices?.getUserMedia === "function";
|
|
1561
|
+
}
|
|
1562
|
+
function saveDataOn() {
|
|
1563
|
+
return navigator.connection?.saveData === true;
|
|
1564
|
+
}
|
|
1565
|
+
function scheduleIdle(run) {
|
|
1566
|
+
const w = window;
|
|
1567
|
+
if (typeof w.requestIdleCallback === "function") {
|
|
1568
|
+
const handle = w.requestIdleCallback(run, { timeout: IDLE_TIMEOUT_MS });
|
|
1569
|
+
return () => w.cancelIdleCallback?.(handle);
|
|
1570
|
+
}
|
|
1571
|
+
const timer = setTimeout(run, IDLE_FALLBACK_MS);
|
|
1572
|
+
return () => clearTimeout(timer);
|
|
1573
|
+
}
|
|
1574
|
+
function schedule(entry, base) {
|
|
1575
|
+
let resolve;
|
|
1576
|
+
const promise = new Promise((res) => {
|
|
1577
|
+
resolve = res;
|
|
1578
|
+
});
|
|
1579
|
+
let done = false;
|
|
1580
|
+
let cancel = () => void 0;
|
|
1581
|
+
const scheduled = {
|
|
1582
|
+
promise,
|
|
1583
|
+
settle: (outcome) => {
|
|
1584
|
+
if (done) return;
|
|
1585
|
+
done = true;
|
|
1586
|
+
cancel();
|
|
1587
|
+
if (entry.scheduled === scheduled) entry.scheduled = null;
|
|
1588
|
+
resolve(outcome);
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
entry.scheduled = scheduled;
|
|
1592
|
+
cancel = scheduleIdle(() => {
|
|
1593
|
+
if (done) return;
|
|
1594
|
+
scheduled.settle(begin(entry, base));
|
|
1595
|
+
});
|
|
1596
|
+
return promise;
|
|
1597
|
+
}
|
|
1598
|
+
function begin(entry, base) {
|
|
1599
|
+
if ((entry.status === "loading" || entry.status === "ready") && entry.promise !== null) return entry.promise;
|
|
1600
|
+
setStatus(entry, "loading");
|
|
1601
|
+
const detectorPromise = new Promise((resolve) => resolve(loader(base)));
|
|
1602
|
+
entry.detectorPromise = detectorPromise;
|
|
1603
|
+
let timer;
|
|
1604
|
+
const budget = new Promise((_, reject) => {
|
|
1605
|
+
timer = setTimeout(() => {
|
|
1606
|
+
detectorPromise.then((late) => late.destroy(), () => void 0);
|
|
1607
|
+
reject(new Error(`detector preload exceeded ${PRELOAD_BUDGET_MS} ms`));
|
|
1608
|
+
}, PRELOAD_BUDGET_MS);
|
|
1609
|
+
});
|
|
1610
|
+
const settled = Promise.race([detectorPromise, budget]).then(
|
|
1611
|
+
(detector) => {
|
|
1612
|
+
if (entry.detectorPromise !== detectorPromise) {
|
|
1613
|
+
detector.destroy();
|
|
1614
|
+
return entry.status;
|
|
1615
|
+
}
|
|
1616
|
+
entry.detector = detector;
|
|
1617
|
+
setStatus(entry, "ready");
|
|
1618
|
+
return "ready";
|
|
1619
|
+
},
|
|
1620
|
+
(err) => {
|
|
1621
|
+
if (entry.detectorPromise === detectorPromise) {
|
|
1622
|
+
entry.detectorPromise = null;
|
|
1623
|
+
entry.detector = null;
|
|
1624
|
+
setStatus(entry, "failed");
|
|
1625
|
+
console.warn("[@sekyro/web] face-detector preload failed:", err);
|
|
1626
|
+
}
|
|
1627
|
+
return entry.status;
|
|
1628
|
+
}
|
|
1629
|
+
);
|
|
1630
|
+
const promise = settled.finally(() => clearTimeout(timer));
|
|
1631
|
+
entry.promise = promise;
|
|
1632
|
+
entry.scheduled?.settle(promise);
|
|
1633
|
+
return promise;
|
|
1634
|
+
}
|
|
1635
|
+
function preloadLivenessAssets(options = {}) {
|
|
1636
|
+
if (!canCapture()) return Promise.resolve("idle");
|
|
1637
|
+
const base = normalizeBase(options.assetBaseUrl);
|
|
1638
|
+
const entry = entryFor(base);
|
|
1639
|
+
if (options.respectSaveData === true && saveDataOn()) return Promise.resolve(entry.status);
|
|
1640
|
+
if ((entry.status === "loading" || entry.status === "ready") && entry.promise !== null) return entry.promise;
|
|
1641
|
+
if (options.idle === true) return entry.scheduled?.promise ?? schedule(entry, base);
|
|
1642
|
+
return begin(entry, base);
|
|
1643
|
+
}
|
|
1644
|
+
function getLivenessAssetsStatus(assetBaseUrl) {
|
|
1645
|
+
return registry().get(normalizeBase(assetBaseUrl))?.status ?? "idle";
|
|
1646
|
+
}
|
|
1647
|
+
function subscribeLivenessAssets(listener, assetBaseUrl) {
|
|
1648
|
+
const entry = entryFor(normalizeBase(assetBaseUrl));
|
|
1649
|
+
entry.listeners.add(listener);
|
|
1650
|
+
return () => {
|
|
1651
|
+
entry.listeners.delete(listener);
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
function releaseLivenessAssets(assetBaseUrl) {
|
|
1655
|
+
const entry = registry().get(normalizeBase(assetBaseUrl));
|
|
1656
|
+
if (entry === void 0) return;
|
|
1657
|
+
entry.scheduled?.settle("idle");
|
|
1658
|
+
entry.detector?.destroy();
|
|
1659
|
+
entry.detector = null;
|
|
1660
|
+
entry.detectorPromise = null;
|
|
1661
|
+
entry.promise = null;
|
|
1662
|
+
setStatus(entry, "idle");
|
|
1663
|
+
}
|
|
1664
|
+
function nonOwningView(shared) {
|
|
1665
|
+
return {
|
|
1666
|
+
get tier() {
|
|
1667
|
+
return shared.tier;
|
|
1668
|
+
},
|
|
1669
|
+
get fallbackReason() {
|
|
1670
|
+
return shared.fallbackReason;
|
|
1671
|
+
},
|
|
1672
|
+
detect: (...args) => shared.detect(...args),
|
|
1673
|
+
destroy: () => {
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
function preloadedDetectorFactory(assetBaseUrl) {
|
|
1678
|
+
const base = normalizeBase(assetBaseUrl);
|
|
1679
|
+
const entry = registry().get(base);
|
|
1680
|
+
if (entry === void 0 || entry.detector === null && entry.detectorPromise === null && entry.scheduled === null) {
|
|
1681
|
+
return void 0;
|
|
1682
|
+
}
|
|
1683
|
+
return async () => {
|
|
1684
|
+
if (entry.scheduled !== null) void begin(entry, base);
|
|
1685
|
+
let waitingOn = entry.promise;
|
|
1686
|
+
while (entry.detector === null && waitingOn !== null) {
|
|
1687
|
+
await waitingOn;
|
|
1688
|
+
if (entry.promise === waitingOn) break;
|
|
1689
|
+
waitingOn = entry.promise;
|
|
1690
|
+
}
|
|
1691
|
+
return entry.detector !== null ? nonOwningView(entry.detector) : createDetector({ v3AssetBaseUrl: base });
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
// src/capture/wake-lock.ts
|
|
1696
|
+
function wakeLockApi() {
|
|
1697
|
+
if (typeof navigator === "undefined" || !("wakeLock" in navigator)) return null;
|
|
1698
|
+
const api = navigator.wakeLock;
|
|
1699
|
+
return typeof api?.request === "function" ? api : null;
|
|
1700
|
+
}
|
|
1701
|
+
function isVisible() {
|
|
1702
|
+
return typeof document === "undefined" || document.visibilityState === "visible";
|
|
1703
|
+
}
|
|
1704
|
+
function releaseQuietly(sentinel) {
|
|
1705
|
+
try {
|
|
1706
|
+
void sentinel.release().catch(() => void 0);
|
|
1707
|
+
} catch {
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
function createScreenWakeLock(options = {}) {
|
|
1711
|
+
if (options.enabled === false) return { setActive: () => void 0 };
|
|
1712
|
+
let wanted = false;
|
|
1713
|
+
let sentinel = null;
|
|
1714
|
+
let inFlight = false;
|
|
1715
|
+
let listening = false;
|
|
1716
|
+
const acquire = () => {
|
|
1717
|
+
if (!wanted || inFlight || sentinel !== null && !sentinel.released) return;
|
|
1718
|
+
const api = wakeLockApi();
|
|
1719
|
+
if (api === null || !isVisible()) return;
|
|
1720
|
+
let request;
|
|
1721
|
+
try {
|
|
1722
|
+
request = api.request("screen");
|
|
1723
|
+
} catch {
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
inFlight = true;
|
|
1727
|
+
request.then(
|
|
1728
|
+
(granted) => {
|
|
1729
|
+
inFlight = false;
|
|
1730
|
+
if (!wanted) {
|
|
1731
|
+
releaseQuietly(granted);
|
|
1732
|
+
return;
|
|
1733
|
+
}
|
|
1734
|
+
sentinel = granted;
|
|
1735
|
+
granted.addEventListener?.("release", () => {
|
|
1736
|
+
if (sentinel === granted) sentinel = null;
|
|
1737
|
+
});
|
|
1738
|
+
},
|
|
1739
|
+
() => {
|
|
1740
|
+
inFlight = false;
|
|
1741
|
+
}
|
|
1742
|
+
);
|
|
1743
|
+
};
|
|
1744
|
+
const onVisibilityChange = () => {
|
|
1745
|
+
if (isVisible()) acquire();
|
|
1746
|
+
};
|
|
1747
|
+
const listen = (on) => {
|
|
1748
|
+
if (typeof document === "undefined" || on === listening) return;
|
|
1749
|
+
listening = on;
|
|
1750
|
+
if (on) document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1751
|
+
else document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1752
|
+
};
|
|
1753
|
+
return {
|
|
1754
|
+
setActive: (active) => {
|
|
1755
|
+
wanted = active;
|
|
1756
|
+
if (active) {
|
|
1757
|
+
if (wakeLockApi() === null) return;
|
|
1758
|
+
listen(true);
|
|
1759
|
+
acquire();
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
listen(false);
|
|
1763
|
+
if (sentinel !== null) {
|
|
1764
|
+
const held = sentinel;
|
|
1765
|
+
sentinel = null;
|
|
1766
|
+
releaseQuietly(held);
|
|
1767
|
+
}
|
|
1768
|
+
}
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1516
1772
|
// src/capture/create-liveness-capture.ts
|
|
1517
1773
|
function mapGuidanceHint(key) {
|
|
1518
1774
|
switch (key) {
|
|
@@ -1576,12 +1832,22 @@ function createLivenessCaptureInternal(options, internals = {}) {
|
|
|
1576
1832
|
const now = internals.now ?? (() => performance.now());
|
|
1577
1833
|
const emitter = createEmitter();
|
|
1578
1834
|
const degraded = !isMediaRecorderSupported();
|
|
1835
|
+
const hostSeams = internals.engineOptions;
|
|
1836
|
+
const preloadAware = hostSeams?.createDetector === void 0 && hostSeams?.createWorker === void 0 ? {
|
|
1837
|
+
createDetector: () => {
|
|
1838
|
+
const warmed = preloadedDetectorFactory(options.assetBaseUrl);
|
|
1839
|
+
return warmed !== void 0 ? warmed() : createDetector(
|
|
1840
|
+
options.assetBaseUrl !== void 0 ? { v3AssetBaseUrl: options.assetBaseUrl } : {}
|
|
1841
|
+
);
|
|
1842
|
+
}
|
|
1843
|
+
} : {};
|
|
1579
1844
|
const engineOptions = {
|
|
1580
1845
|
video: options.video,
|
|
1581
1846
|
mode: degraded ? "photo" : "clip",
|
|
1582
1847
|
...options.facing !== void 0 ? { facingMode: options.facing } : {},
|
|
1583
1848
|
...options.assetBaseUrl !== void 0 ? { v3AssetBaseUrl: options.assetBaseUrl } : {},
|
|
1584
|
-
...internals.engineOptions ?? {}
|
|
1849
|
+
...internals.engineOptions ?? {},
|
|
1850
|
+
...preloadAware
|
|
1585
1851
|
};
|
|
1586
1852
|
const engine = internals.createEngine?.(engineOptions) ?? new CaptureSessionV3(engineOptions);
|
|
1587
1853
|
let state = "idle";
|
|
@@ -1599,8 +1865,10 @@ function createLivenessCaptureInternal(options, internals = {}) {
|
|
|
1599
1865
|
frameHeight = options.video.videoHeight;
|
|
1600
1866
|
}
|
|
1601
1867
|
};
|
|
1868
|
+
const wakeLock = createScreenWakeLock({ enabled: options.keepScreenAwake !== false });
|
|
1602
1869
|
const setState = (next) => {
|
|
1603
1870
|
state = next;
|
|
1871
|
+
wakeLock.setActive(next === "starting" || next === "gating" || next === "recording");
|
|
1604
1872
|
emitter.emit("state", next);
|
|
1605
1873
|
};
|
|
1606
1874
|
const emitGate = () => emitter.emit("gate", { progress, hint, faceDetected });
|
|
@@ -1674,11 +1942,12 @@ function createLivenessCaptureInternal(options, internals = {}) {
|
|
|
1674
1942
|
return state;
|
|
1675
1943
|
},
|
|
1676
1944
|
on: (event, handler) => emitter.on(event, handler),
|
|
1677
|
-
start: () => engine.start(),
|
|
1945
|
+
start: (startOptions) => engine.start(startOptions?.facing !== void 0 ? { facingMode: startOptions.facing } : {}),
|
|
1678
1946
|
retry: () => engine.retry(),
|
|
1679
1947
|
switchCamera: () => engine.switchCamera(),
|
|
1680
1948
|
destroy: () => {
|
|
1681
1949
|
for (const unsubscribe of unsubscribes) unsubscribe();
|
|
1950
|
+
wakeLock.setActive(false);
|
|
1682
1951
|
engine.destroy();
|
|
1683
1952
|
emitter.clear();
|
|
1684
1953
|
}
|
|
@@ -1694,6 +1963,52 @@ function createLivenessCapture(options) {
|
|
|
1694
1963
|
return createLivenessCaptureInternal(options).handle;
|
|
1695
1964
|
}
|
|
1696
1965
|
|
|
1966
|
+
// src/capture/camera-probe.ts
|
|
1967
|
+
async function permissionStatus() {
|
|
1968
|
+
try {
|
|
1969
|
+
if (typeof navigator === "undefined" || typeof navigator.permissions?.query !== "function") return null;
|
|
1970
|
+
return await navigator.permissions.query({ name: "camera" });
|
|
1971
|
+
} catch {
|
|
1972
|
+
return null;
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
function asState(state) {
|
|
1976
|
+
return state === "granted" || state === "prompt" || state === "denied" ? state : "unknown";
|
|
1977
|
+
}
|
|
1978
|
+
async function queryCameraPermission() {
|
|
1979
|
+
const status = await permissionStatus();
|
|
1980
|
+
return status === null ? "unknown" : asState(status.state);
|
|
1981
|
+
}
|
|
1982
|
+
function subscribeCameraPermission(listener) {
|
|
1983
|
+
let stopped = false;
|
|
1984
|
+
let status = null;
|
|
1985
|
+
const onChange = () => {
|
|
1986
|
+
if (!stopped && status !== null) listener(asState(status.state));
|
|
1987
|
+
};
|
|
1988
|
+
void permissionStatus().then((resolved) => {
|
|
1989
|
+
if (stopped) return;
|
|
1990
|
+
status = resolved;
|
|
1991
|
+
listener(resolved === null ? "unknown" : asState(resolved.state));
|
|
1992
|
+
resolved?.addEventListener?.("change", onChange);
|
|
1993
|
+
});
|
|
1994
|
+
return () => {
|
|
1995
|
+
stopped = true;
|
|
1996
|
+
status?.removeEventListener?.("change", onChange);
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
async function hasMultipleCameras() {
|
|
2000
|
+
if (typeof navigator === "undefined") return false;
|
|
2001
|
+
const ua = String(navigator.userAgent ?? "");
|
|
2002
|
+
if (/Android|iPhone|iPad|iPod/i.test(ua)) return true;
|
|
2003
|
+
if (/Macintosh/.test(ua) && (navigator.maxTouchPoints ?? 0) > 1) return true;
|
|
2004
|
+
try {
|
|
2005
|
+
const devices = await navigator.mediaDevices?.enumerateDevices?.() ?? [];
|
|
2006
|
+
return devices.filter((device) => device.kind === "videoinput").length >= 2;
|
|
2007
|
+
} catch {
|
|
2008
|
+
return false;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
|
|
1697
2012
|
// src/client/errors.ts
|
|
1698
2013
|
var KNOWN_CODES = [
|
|
1699
2014
|
// auth / addressing (session-token.guard, controllers' own-session guards)
|
|
@@ -2462,7 +2777,7 @@ function createVerificationInternal(options, internals) {
|
|
|
2462
2777
|
}
|
|
2463
2778
|
emitter.emit("result", result);
|
|
2464
2779
|
};
|
|
2465
|
-
let
|
|
2780
|
+
let registry2 = null;
|
|
2466
2781
|
let registryFailed = false;
|
|
2467
2782
|
let registryUnbound = false;
|
|
2468
2783
|
const submitRegistry = () => runSubmission(
|
|
@@ -2497,8 +2812,8 @@ function createVerificationInternal(options, internals) {
|
|
|
2497
2812
|
if (view !== null && isTerminalView(view)) emitResult(mapSessionResult(view, { autoRetry }));
|
|
2498
2813
|
};
|
|
2499
2814
|
const startRegistry = () => {
|
|
2500
|
-
|
|
2501
|
-
return
|
|
2815
|
+
registry2 ?? (registry2 = runRegistry());
|
|
2816
|
+
return registry2;
|
|
2502
2817
|
};
|
|
2503
2818
|
const getAttestation = async () => {
|
|
2504
2819
|
const current = await ensureView();
|
|
@@ -2613,7 +2928,7 @@ function createVerificationInternal(options, internals) {
|
|
|
2613
2928
|
return inner.state;
|
|
2614
2929
|
},
|
|
2615
2930
|
on: (event, handler) => inner.on(event, handler),
|
|
2616
|
-
start: () => inner.start(),
|
|
2931
|
+
start: (startOptions) => inner.start(startOptions),
|
|
2617
2932
|
retry: () => inner.retry(),
|
|
2618
2933
|
switchCamera: () => inner.switchCamera(),
|
|
2619
2934
|
destroy: () => {
|
|
@@ -2627,6 +2942,16 @@ function createVerificationInternal(options, internals) {
|
|
|
2627
2942
|
consent: () => ensureConsent(),
|
|
2628
2943
|
startRegistry,
|
|
2629
2944
|
liveness,
|
|
2945
|
+
voiceClips: async () => {
|
|
2946
|
+
if (destroyed) return null;
|
|
2947
|
+
try {
|
|
2948
|
+
const current = await ensureView();
|
|
2949
|
+
if (destroyed) return null;
|
|
2950
|
+
return current.voice ?? null;
|
|
2951
|
+
} catch {
|
|
2952
|
+
return null;
|
|
2953
|
+
}
|
|
2954
|
+
},
|
|
2630
2955
|
on: (event, handler) => emitter.on(event, handler),
|
|
2631
2956
|
destroy: () => {
|
|
2632
2957
|
destroyed = true;
|
|
@@ -2692,7 +3017,14 @@ function openHosted(hostedUrl, opts) {
|
|
|
2692
3017
|
SEKYRO_EVENTS,
|
|
2693
3018
|
createLivenessCapture,
|
|
2694
3019
|
createVerification,
|
|
3020
|
+
getLivenessAssetsStatus,
|
|
3021
|
+
hasMultipleCameras,
|
|
2695
3022
|
isKnownCode,
|
|
2696
|
-
openHosted
|
|
3023
|
+
openHosted,
|
|
3024
|
+
preloadLivenessAssets,
|
|
3025
|
+
queryCameraPermission,
|
|
3026
|
+
releaseLivenessAssets,
|
|
3027
|
+
subscribeCameraPermission,
|
|
3028
|
+
subscribeLivenessAssets
|
|
2697
3029
|
});
|
|
2698
3030
|
//# sourceMappingURL=index.cjs.map
|