@arkyc/widget 1.2.11 → 2.1.0
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/dist/ArkycWidget.d.mts +1 -3
- package/dist/ArkycWidget.d.mts.map +1 -1
- package/dist/WidgetHandler.d.mts +5 -6
- package/dist/WidgetHandler.d.mts.map +1 -1
- package/dist/WidgetHandler.mjs +2 -1
- package/dist/WidgetHandler.mjs.map +1 -1
- package/dist/arkyc-widget.iife.global.js +13 -3
- package/dist/arkyc-widget.iife.global.js.map +1 -1
- package/dist/capture.d.mts +2 -3
- package/dist/capture.d.mts.map +1 -1
- package/dist/client.d.mts +51 -23
- package/dist/client.d.mts.map +1 -1
- package/dist/client.mjs +67 -2
- package/dist/client.mjs.map +1 -1
- package/dist/controller.d.mts +10 -9
- package/dist/controller.d.mts.map +1 -1
- package/dist/controller.mjs +23 -12
- package/dist/controller.mjs.map +1 -1
- package/dist/document.d.mts +9 -10
- package/dist/document.d.mts.map +1 -1
- package/dist/face.d.mts +8 -10
- package/dist/face.d.mts.map +1 -1
- package/dist/flow.d.mts +2 -4
- package/dist/flow.d.mts.map +1 -1
- package/dist/flow.mjs +2 -1
- package/dist/flow.mjs.map +1 -1
- package/dist/index.d.mts +4 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/realtime.d.mts +15 -13
- package/dist/realtime.d.mts.map +1 -1
- package/dist/realtime.mjs +58 -76
- package/dist/realtime.mjs.map +1 -1
- package/dist/theme.d.mts +1 -3
- package/dist/theme.d.mts.map +1 -1
- package/dist/types.d.mts +65 -23
- package/dist/types.d.mts.map +1 -1
- package/dist/ui.d.mts +4 -3
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +4 -3
- package/dist/ui.mjs.map +1 -1
- package/package.json +3 -2
package/dist/realtime.mjs
CHANGED
|
@@ -1,107 +1,89 @@
|
|
|
1
|
+
import { createRealtime } from "@arkstack/realtime";
|
|
2
|
+
import { REALTIME_EVENT } from "@arkyc/types";
|
|
1
3
|
//#region src/realtime.ts
|
|
2
4
|
/** CDN that serves any npm package as ESM (`…/pkg@ver/+esm`). */
|
|
3
5
|
const CDN = "https://cdn.jsdelivr.net/npm/";
|
|
6
|
+
/** CDN paths for the SDK modules the realtime transports load. */
|
|
7
|
+
const CDN_PATHS = {
|
|
8
|
+
"pusher-js": "pusher-js@8/+esm",
|
|
9
|
+
"firebase/app": "firebase@11/app/+esm",
|
|
10
|
+
"firebase/auth": "firebase@11/auth/+esm",
|
|
11
|
+
"firebase/database": "firebase@11/database/+esm",
|
|
12
|
+
"firebase/messaging": "firebase@11/messaging/+esm"
|
|
13
|
+
};
|
|
14
|
+
/** The domain events the widget watches its session for. */
|
|
15
|
+
const SESSION_EVENTS = [REALTIME_EVENT.sessionTransition];
|
|
4
16
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* trying to resolve these (they aren't hard dependencies) and avoid needing their
|
|
11
|
-
* type declarations.
|
|
17
|
+
* Load a transport SDK by its package name (resolved by a bundler, import map or
|
|
18
|
+
* Node), falling back to jsDelivr so a plain `<script>` embed still gets it.
|
|
19
|
+
*
|
|
20
|
+
* @param specifier
|
|
21
|
+
* @returns
|
|
12
22
|
*/
|
|
13
|
-
async
|
|
23
|
+
const importWithCdnFallback = async (specifier) => {
|
|
14
24
|
try {
|
|
15
25
|
return await import(
|
|
16
26
|
/* @vite-ignore */
|
|
17
27
|
/* webpackIgnore: true */
|
|
18
|
-
|
|
28
|
+
specifier
|
|
19
29
|
);
|
|
20
|
-
} catch {
|
|
30
|
+
} catch (error) {
|
|
31
|
+
const path = CDN_PATHS[specifier];
|
|
32
|
+
if (!path) throw error;
|
|
21
33
|
return await import(
|
|
22
34
|
/* @vite-ignore */
|
|
23
35
|
/* webpackIgnore: true */
|
|
24
|
-
`${CDN}${
|
|
36
|
+
`${CDN}${path}`
|
|
25
37
|
);
|
|
26
38
|
}
|
|
27
|
-
}
|
|
39
|
+
};
|
|
28
40
|
/**
|
|
29
|
-
* Connect to
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
41
|
+
* Connect to the session's push transport. Returns null for transports the
|
|
42
|
+
* widget does not stream over (polling, and Firebase Cloud Messaging, which
|
|
43
|
+
* would prompt the end user for notification permission), and rejects when the
|
|
44
|
+
* transport SDK cannot load, so the caller polls instead.
|
|
45
|
+
*
|
|
46
|
+
* @param config
|
|
47
|
+
* @param options
|
|
48
|
+
* @returns
|
|
34
49
|
*/
|
|
35
50
|
async function createWidgetRealtimeClient(config, options) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
} : {},
|
|
55
|
-
channelAuthorization: {
|
|
56
|
-
transport: "ajax",
|
|
57
|
-
endpoint: options.authEndpoint,
|
|
58
|
-
headers: { "X-Client-Token": options.token }
|
|
59
|
-
}
|
|
51
|
+
if (config.transport !== "pusher" && config.transport !== "firebase-database") return null;
|
|
52
|
+
const authEndpoint = options.authEndpoint;
|
|
53
|
+
const auth = { headers: { "X-Client-Token": options.token } };
|
|
54
|
+
const pusher = config.pusher;
|
|
55
|
+
const firebaseDatabase = config["firebase-database"];
|
|
56
|
+
const client = createRealtime({
|
|
57
|
+
transport: config.transport,
|
|
58
|
+
pusher: pusher && {
|
|
59
|
+
...pusher,
|
|
60
|
+
authEndpoint,
|
|
61
|
+
auth
|
|
62
|
+
},
|
|
63
|
+
"firebase-database": firebaseDatabase && {
|
|
64
|
+
...firebaseDatabase,
|
|
65
|
+
authEndpoint,
|
|
66
|
+
auth
|
|
67
|
+
},
|
|
68
|
+
importModule: importWithCdnFallback
|
|
60
69
|
});
|
|
70
|
+
await client.onPoll(() => {});
|
|
61
71
|
return {
|
|
62
72
|
subscribe(channel, handler) {
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
73
|
+
let active = true;
|
|
74
|
+
const stops = [];
|
|
75
|
+
for (const event of SESSION_EVENTS) client.listen(channel, event, (data) => handler(event, data)).then((stop) => active ? stops.push(stop) : stop()).catch(() => {});
|
|
66
76
|
return () => {
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
active = false;
|
|
78
|
+
stops.forEach((stop) => stop());
|
|
69
79
|
};
|
|
70
80
|
},
|
|
71
81
|
disconnect() {
|
|
72
|
-
|
|
82
|
+
client.disconnect();
|
|
73
83
|
}
|
|
74
84
|
};
|
|
75
85
|
}
|
|
76
|
-
async function createFirebaseClient(config) {
|
|
77
|
-
const [app, auth, database] = await Promise.all([
|
|
78
|
-
loadOptional("firebase/app", "firebase@11/app/+esm"),
|
|
79
|
-
loadOptional("firebase/auth", "firebase@11/auth/+esm"),
|
|
80
|
-
loadOptional("firebase/database", "firebase@11/database/+esm")
|
|
81
|
-
]);
|
|
82
|
-
const name = "arkyc-widget-realtime";
|
|
83
|
-
const fbApp = app.getApps().some((a) => a.name === name) ? app.getApp(name) : app.initializeApp({
|
|
84
|
-
apiKey: String(config.apiKey ?? ""),
|
|
85
|
-
authDomain: String(config.authDomain ?? ""),
|
|
86
|
-
projectId: String(config.projectId ?? ""),
|
|
87
|
-
databaseURL: String(config.databaseURL ?? "")
|
|
88
|
-
}, name);
|
|
89
|
-
if (config.token) await auth.signInWithCustomToken(auth.getAuth(fbApp), config.token);
|
|
90
|
-
const db = database.getDatabase(fbApp);
|
|
91
|
-
const since = Date.now();
|
|
92
|
-
return {
|
|
93
|
-
subscribe(channel, handler) {
|
|
94
|
-
const q = database.query(database.ref(db, `realtime/${channel}`), database.orderByChild("at"), database.startAt(since));
|
|
95
|
-
const unsubscribe = database.onChildAdded(q, (snap) => {
|
|
96
|
-
const value = snap.val();
|
|
97
|
-
if (value) handler(value.event, value.payload);
|
|
98
|
-
});
|
|
99
|
-
return () => unsubscribe();
|
|
100
|
-
},
|
|
101
|
-
disconnect() {}
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
86
|
//#endregion
|
|
105
|
-
export { createWidgetRealtimeClient };
|
|
87
|
+
export { createWidgetRealtimeClient, importWithCdnFallback };
|
|
106
88
|
|
|
107
89
|
//# sourceMappingURL=realtime.mjs.map
|
package/dist/realtime.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"realtime.mjs","names":[],"sources":["../src/realtime.ts"],"sourcesContent":["import type { ClientRealtime } from './client'\n\n/** Fires for every event received on a subscribed channel. */\nexport type WidgetRealtimeHandler = (event: string, data: unknown) => void\n\n/** A connected push transport. `subscribe` returns an unsubscribe function. */\nexport interface WidgetRealtimeClient {\n subscribe(channel: string, handler: WidgetRealtimeHandler): () => void\n disconnect(): void\n}\n\n/** A factory that builds a push client from the session's realtime config. */\nexport type WidgetRealtimeFactory = (\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n) => Promise<WidgetRealtimeClient | null>\n\nexport interface WidgetRealtimeOptions {\n /** The client-token channel-auth endpoint
|
|
1
|
+
{"version":3,"file":"realtime.mjs","names":[],"sources":["../src/realtime.ts"],"sourcesContent":["import { createRealtime, type ModuleImporter, type RealtimeConfig } from '@arkstack/realtime'\nimport { REALTIME_EVENT } from '@arkyc/types'\nimport type { ClientRealtime } from './client'\n\n/** Fires for every event received on a subscribed channel. */\nexport type WidgetRealtimeHandler = (event: string, data: unknown) => void\n\n/** A connected push transport. `subscribe` returns an unsubscribe function. */\nexport interface WidgetRealtimeClient {\n subscribe(channel: string, handler: WidgetRealtimeHandler): () => void\n disconnect(): void\n}\n\n/** A factory that builds a push client from the session's realtime config. */\nexport type WidgetRealtimeFactory = (\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n) => Promise<WidgetRealtimeClient | null>\n\nexport interface WidgetRealtimeOptions {\n /** The client-token channel-auth endpoint. */\n authEndpoint: string\n /** The session's client token (sent as `X-Client-Token` to the authorizer). */\n token: string\n}\n\n/** CDN that serves any npm package as ESM (`…/pkg@ver/+esm`). */\nconst CDN = 'https://cdn.jsdelivr.net/npm/'\n\n/** CDN paths for the SDK modules the realtime transports load. */\nconst CDN_PATHS: Record<string, string> = {\n 'pusher-js': 'pusher-js@8/+esm',\n 'firebase/app': 'firebase@11/app/+esm',\n 'firebase/auth': 'firebase@11/auth/+esm',\n 'firebase/database': 'firebase@11/database/+esm',\n 'firebase/messaging': 'firebase@11/messaging/+esm',\n}\n\n/** The domain events the widget watches its session for. */\nconst SESSION_EVENTS = [REALTIME_EVENT.sessionTransition]\n\n/**\n * Load a transport SDK by its package name (resolved by a bundler, import map or\n * Node), falling back to jsDelivr so a plain `<script>` embed still gets it.\n *\n * @param specifier\n * @returns\n */\nexport const importWithCdnFallback: ModuleImporter = async (specifier) => {\n try {\n return await import(/* @vite-ignore */ /* webpackIgnore: true */ specifier)\n } catch (error) {\n const path = CDN_PATHS[specifier]\n if (!path) throw error\n\n return await import(/* @vite-ignore */ /* webpackIgnore: true */ `${CDN}${path}`)\n }\n}\n\n/**\n * Connect to the session's push transport. Returns null for transports the\n * widget does not stream over (polling, and Firebase Cloud Messaging, which\n * would prompt the end user for notification permission), and rejects when the\n * transport SDK cannot load, so the caller polls instead.\n *\n * @param config\n * @param options\n * @returns\n */\nexport async function createWidgetRealtimeClient(\n config: ClientRealtime,\n options: WidgetRealtimeOptions,\n): Promise<WidgetRealtimeClient | null> {\n if (config.transport !== 'pusher' && config.transport !== 'firebase-database') return null\n\n const authEndpoint = options.authEndpoint\n const auth = { headers: { 'X-Client-Token': options.token } }\n const pusher = config.pusher as RealtimeConfig['pusher']\n const firebaseDatabase = config['firebase-database'] as RealtimeConfig['firebase-database']\n\n const client = createRealtime({\n transport: config.transport,\n pusher: pusher && { ...pusher, authEndpoint, auth },\n 'firebase-database': firebaseDatabase && { ...firebaseDatabase, authEndpoint, auth },\n importModule: importWithCdnFallback,\n })\n\n // Connect now, so a transport that cannot load falls back to polling.\n await client.onPoll(() => {})\n\n return {\n subscribe(channel, handler) {\n let active = true\n const stops: Array<() => void> = []\n\n for (const event of SESSION_EVENTS) {\n client\n .listen(channel, event, (data) => handler(event, data))\n .then((stop) => (active ? stops.push(stop) : stop()))\n .catch(() => {\n // An unauthorized or unavailable channel leaves the session to the poll budget.\n })\n }\n\n return () => {\n active = false\n stops.forEach((stop) => stop())\n }\n },\n disconnect() {\n void client.disconnect()\n },\n }\n}\n"],"mappings":";;;;AA2BA,MAAM,MAAM;;AAGZ,MAAM,YAAoC;CACxC,aAAa;CACb,gBAAgB;CAChB,iBAAiB;CACjB,qBAAqB;CACrB,sBAAsB;AACxB;;AAGA,MAAM,iBAAiB,CAAC,eAAe,iBAAiB;;;;;;;;AASxD,MAAa,wBAAwC,OAAO,cAAc;CACxE,IAAI;EACF,OAAO,MAAM;;;GAAoD;;CACnE,SAAS,OAAO;EACd,MAAM,OAAO,UAAU;EACvB,IAAI,CAAC,MAAM,MAAM;EAEjB,OAAO,MAAM;;;GAAoD,GAAG,MAAM;;CAC5E;AACF;;;;;;;;;;;AAYA,eAAsB,2BACpB,QACA,SACsC;CACtC,IAAI,OAAO,cAAc,YAAY,OAAO,cAAc,qBAAqB,OAAO;CAEtF,MAAM,eAAe,QAAQ;CAC7B,MAAM,OAAO,EAAE,SAAS,EAAE,kBAAkB,QAAQ,MAAM,EAAE;CAC5D,MAAM,SAAS,OAAO;CACtB,MAAM,mBAAmB,OAAO;CAEhC,MAAM,SAAS,eAAe;EAC5B,WAAW,OAAO;EAClB,QAAQ,UAAU;GAAE,GAAG;GAAQ;GAAc;EAAK;EAClD,qBAAqB,oBAAoB;GAAE,GAAG;GAAkB;GAAc;EAAK;EACnF,cAAc;CAChB,CAAC;CAGD,MAAM,OAAO,aAAa,CAAC,CAAC;CAE5B,OAAO;EACL,UAAU,SAAS,SAAS;GAC1B,IAAI,SAAS;GACb,MAAM,QAA2B,CAAC;GAElC,KAAK,MAAM,SAAS,gBAClB,OACG,OAAO,SAAS,QAAQ,SAAS,QAAQ,OAAO,IAAI,CAAC,CAAC,CACtD,MAAM,SAAU,SAAS,MAAM,KAAK,IAAI,IAAI,KAAK,CAAE,CAAC,CACpD,YAAY,CAEb,CAAC;GAGL,aAAa;IACX,SAAS;IACT,MAAM,SAAS,SAAS,KAAK,CAAC;GAChC;EACF;EACA,aAAa;GACX,OAAY,WAAW;EACzB;CACF;AACF"}
|
package/dist/theme.d.mts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { RgbData } from "./types.mjs";
|
|
2
2
|
import { ProjectBranding } from "@arkyc/types";
|
|
3
|
-
|
|
4
3
|
//#region src/theme.d.ts
|
|
5
4
|
/**
|
|
6
5
|
* Resolves project branding into a concrete theme and renders its CSS. One class
|
|
7
6
|
* owns the whole "theme" concern: defaulted colour/logo/radius values plus the
|
|
8
7
|
* CSS-variable block and stylesheet derived from them.
|
|
9
8
|
*/
|
|
10
|
-
declare class Theme {
|
|
9
|
+
export declare class Theme {
|
|
11
10
|
readonly primaryColor: string;
|
|
12
11
|
readonly borderRadius: number;
|
|
13
12
|
readonly mode: 'light' | 'dark';
|
|
@@ -45,5 +44,4 @@ declare class Theme {
|
|
|
45
44
|
}): RgbData;
|
|
46
45
|
}
|
|
47
46
|
//#endregion
|
|
48
|
-
export { Theme };
|
|
49
47
|
//# sourceMappingURL=theme.d.mts.map
|
package/dist/theme.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.mts","names":[],"sources":["../src/theme.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"theme.d.mts","names":[],"sources":["../src/theme.ts"],"mappings":";;;;;;;;qBAuBa;WACF;WACA;WACA;WACA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;;WAEA;EAEG,YAAA,WAAW;;;;;;EAmBvB;;;;;;EAgBA;SAIO,IAAI;IAAK;MAAyB;EAWzC,IAAI;IAAK;MAAyB"}
|
package/dist/types.d.mts
CHANGED
|
@@ -3,10 +3,9 @@ import { FaceAnalyzer, FaceTuning } from "./face.mjs";
|
|
|
3
3
|
import { AddressFormData } from "./ui.mjs";
|
|
4
4
|
import { ProviderSignalHints } from "./client.mjs";
|
|
5
5
|
import { WidgetRealtimeFactory } from "./realtime.mjs";
|
|
6
|
-
import { DocumentType, LivenessChallenge, ProjectBranding, WidgetResult } from "@arkyc/types";
|
|
7
|
-
|
|
6
|
+
import { DocumentType, LivenessChallenge, ProjectBranding, SessionTransitionEvent, WidgetResult } from "@arkyc/types";
|
|
8
7
|
//#region src/types.d.ts
|
|
9
|
-
interface RgbData {
|
|
8
|
+
export interface RgbData {
|
|
10
9
|
obj: {
|
|
11
10
|
r: number;
|
|
12
11
|
g: number;
|
|
@@ -15,20 +14,62 @@ interface RgbData {
|
|
|
15
14
|
str: string;
|
|
16
15
|
}
|
|
17
16
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* Payload for `session.transition` — a live verification status change relayed
|
|
18
|
+
* from the configured transport (pusher/firebase/polling). A widget-scoped
|
|
19
|
+
* subset of the server's {@link SessionTransitionEvent} (no org/project ids).
|
|
21
20
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
export type WidgetSessionTransitionData = Pick<SessionTransitionEvent, 'session_id' | 'status' | 'previous_status'>;
|
|
22
|
+
/**
|
|
23
|
+
* Payload for `error` — a non-terminal failure surfaced as it happens (an
|
|
24
|
+
* expired session/token becomes knowable without waiting for the user to
|
|
25
|
+
* dismiss the screen). `status`/`error` are present only for typed API errors.
|
|
26
|
+
*/
|
|
27
|
+
export interface WidgetErrorData {
|
|
28
|
+
/** Human-readable failure message. */
|
|
29
|
+
message: string;
|
|
30
|
+
/** HTTP status code, when the failure came from a typed API error. */
|
|
31
|
+
status?: number;
|
|
32
|
+
/** Stable machine-readable error key, when the failure came from a typed API error. */
|
|
33
|
+
error?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The set of widget events and the payload each delivers. This is the single
|
|
37
|
+
* source of truth for event names and their `data` shapes: `onEvent`,
|
|
38
|
+
* {@link WidgetEvent}, {@link WidgetEventListener}, and {@link WidgetHandle.on}
|
|
39
|
+
* are all derived from it, so a listener's `data` is typed from the name.
|
|
40
|
+
*/
|
|
41
|
+
export interface WidgetEventMap {
|
|
42
|
+
/** Live status change (fires on every real transition, once per change). */
|
|
43
|
+
'session.transition': WidgetSessionTransitionData;
|
|
44
|
+
/** The flow settled successfully; carries the final verification result. */
|
|
45
|
+
complete: WidgetResult;
|
|
46
|
+
/** A failure occurred (may be recoverable; the flow has not necessarily ended). */
|
|
47
|
+
error: WidgetErrorData;
|
|
48
|
+
/** The widget was closed (camera released). No payload. */
|
|
49
|
+
close: undefined;
|
|
27
50
|
}
|
|
28
|
-
/**
|
|
29
|
-
type
|
|
51
|
+
/** A widget event name — one of the keys of {@link WidgetEventMap}. */
|
|
52
|
+
export type WidgetEventName = keyof WidgetEventMap;
|
|
53
|
+
/**
|
|
54
|
+
* An event surfaced to consumers through `onEvent`. Discriminated on `name`, so
|
|
55
|
+
* a `switch (event.name)` narrows `event.data` to the matching payload. The
|
|
56
|
+
* stream is a firehose: `session.transition` (live status changes) plus the
|
|
57
|
+
* lifecycle events `complete` / `error` / `close`.
|
|
58
|
+
*/
|
|
59
|
+
export type WidgetEvent = { [K in WidgetEventName]: {
|
|
60
|
+
/** Event name (discriminant). */
|
|
61
|
+
name: K;
|
|
62
|
+
/** Event payload for this `name` (see {@link WidgetEventMap}). */
|
|
63
|
+
data: WidgetEventMap[K];
|
|
64
|
+
}; }[WidgetEventName];
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe callback for a single named widget event; receives that event's
|
|
67
|
+
* payload (typed from the name via {@link WidgetEventMap}). Defaults to the
|
|
68
|
+
* union of all payloads when the name isn't fixed.
|
|
69
|
+
*/
|
|
70
|
+
export type WidgetEventListener<K extends WidgetEventName = WidgetEventName> = (data: WidgetEventMap[K]) => void;
|
|
30
71
|
/** Configuration for a {@link WidgetController}. */
|
|
31
|
-
interface WidgetControllerConfig {
|
|
72
|
+
export interface WidgetControllerConfig {
|
|
32
73
|
/** Short-lived client token for this session. */
|
|
33
74
|
token: string;
|
|
34
75
|
/** API origin (defaults to the widget's own origin). */
|
|
@@ -93,7 +134,7 @@ interface WidgetControllerConfig {
|
|
|
93
134
|
maxHandoffPolls?: number;
|
|
94
135
|
}
|
|
95
136
|
/** Common options shared by every launch mode. */
|
|
96
|
-
interface BaseWidgetOptions {
|
|
137
|
+
export interface BaseWidgetOptions {
|
|
97
138
|
/** Short-lived client token minted by the integrator's backend. */
|
|
98
139
|
token: string;
|
|
99
140
|
/** API origin (defaults to the page's own origin). */
|
|
@@ -142,23 +183,25 @@ interface BaseWidgetOptions {
|
|
|
142
183
|
documentTuning?: DocumentTuning;
|
|
143
184
|
}
|
|
144
185
|
/** Options for {@link ArkycWidget.mount} (inline mode). */
|
|
145
|
-
interface MountWidgetOptions extends BaseWidgetOptions {
|
|
186
|
+
export interface MountWidgetOptions extends BaseWidgetOptions {
|
|
146
187
|
/** Element (or selector) to mount the widget into. */
|
|
147
188
|
container: string | HTMLElement;
|
|
148
189
|
}
|
|
149
190
|
/** A handle to an open/mounted widget. */
|
|
150
|
-
interface WidgetHandle {
|
|
191
|
+
export interface WidgetHandle {
|
|
151
192
|
/** Close the widget and release the camera (fires `onClose`). */
|
|
152
193
|
close: () => void;
|
|
153
194
|
/**
|
|
154
|
-
* Subscribe to a named widget event (
|
|
155
|
-
*
|
|
156
|
-
*
|
|
195
|
+
* Subscribe to a named widget event (`session.transition`, `complete`,
|
|
196
|
+
* `error`, `close`). The `listener`'s `data` is typed from the `event` name
|
|
197
|
+
* via {@link WidgetEventMap}. Returns an unsubscribe function. Registering a
|
|
198
|
+
* listener activates the event stream (events are only delivered while at
|
|
199
|
+
* least one listener is active).
|
|
157
200
|
*/
|
|
158
|
-
on: (event:
|
|
201
|
+
on: <K extends WidgetEventName>(event: K, listener: WidgetEventListener<K>) => () => void;
|
|
159
202
|
}
|
|
160
203
|
/** High-level events the view raises back to the controller. */
|
|
161
|
-
interface ViewHandlers {
|
|
204
|
+
export interface ViewHandlers {
|
|
162
205
|
onClose(): void;
|
|
163
206
|
onStart(): void;
|
|
164
207
|
onDocumentSelected(type: DocumentType, country: string): void;
|
|
@@ -181,5 +224,4 @@ interface ViewHandlers {
|
|
|
181
224
|
onShareLocation(): boolean | Promise<boolean>;
|
|
182
225
|
}
|
|
183
226
|
//#endregion
|
|
184
|
-
export { BaseWidgetOptions, MountWidgetOptions, RgbData, ViewHandlers, WidgetControllerConfig, WidgetEvent, WidgetEventListener, WidgetHandle };
|
|
185
227
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;;;;iBAciB;EACf;IAAO;IAAW;IAAW;;EAC7B;;;;;;;YAQU,8BAA8B,KAAK;;;;;;iBAO9B;;EAEf;;EAEA;;EAEA;;;;;;;;iBASe;;EAEf,sBAAsB;;EAEtB,UAAU;;EAEV,OAAO;;EAEP;;;YAIU,wBAAwB;;;;;;;YAQxB,iBACT,KAAK;;EAEJ,MAAM;;EAEN,MAAM,eAAe;KAEvB;;;;;;YAOU,oBAAoB,UAAU,kBAAkB,oBAAoB,MAAM,eAAe;;iBAGpF;;EAEf;;EAEA;;EAEA;;EAEA;EACA,WAAW;;;;;EAKX,UAAU;EACV,cAAc,QAAQ;EACtB,WAAW,OAAO;EAClB;;;;;;EAMA,WAAW,OAAO;;EAElB;;EAEA;EAGA,eAAe;EACf,MAAM;EACN,MAAM;EACN,MAAM;;;;;;EAMN,eAAe;;EAEf,aAAa;;;;;;EAMb,mBAAmB;;EAEnB,iBAAiB;;;;;EAKjB,kBAAkB;;EAElB,aAAa,gBAAgB;;EAE7B;;EAEA;;EAEA;;EAEA;;;iBAIe;;EAEf;;EAEA;;;;;;EAMA;;;;;EAKA;;EAEA,WAAW;;;;;EAKX;;EAEA,UAAU;EACV,cAAc,QAAQ;EACtB,WAAW,OAAO;EAClB;;;;;;;EAOA,WAAW,OAAO;EAGlB,eAAe;EACf,MAAM;EACN,MAAM;EACN,MAAM;;EAEN,eAAe;;EAEf,aAAa;;EAEb,mBAAmB;;EAEnB,iBAAiB;;;iBAIF,2BAA2B;;EAE1C,oBAAoB;;;iBAIL;;EAEf;;;;;;;;EAQA,KAAK,UAAU,iBAAiB,OAAO,GAAG,UAAU,oBAAoB;;;iBAIzD;EACf;EACA;EACA,mBAAmB,MAAM,cAAc;;EAEvC,QAAQ,MAAM;;;;;EAKd,iBAAiB,OAAO,aAAa,WAAW,qBAAqB,SAAS;;EAE9E;;EAEA;;EAEA;;EAEA,UAAU,MAAM;;EAEhB,6BAA6B"}
|
package/dist/ui.d.mts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import "./face.mjs";
|
|
2
|
+
import "./theme.mjs";
|
|
3
|
+
import "./types.mjs";
|
|
1
4
|
import { DocumentType, LivenessChallenge, ProjectBranding, VerificationDecision, VerificationStatus, WidgetStep } from "@arkyc/types";
|
|
2
|
-
|
|
3
5
|
//#region src/ui.d.ts
|
|
4
6
|
/** The data the address-entry screen collects before submission. */
|
|
5
|
-
interface AddressFormData {
|
|
7
|
+
export interface AddressFormData {
|
|
6
8
|
line1: string | null;
|
|
7
9
|
line2: string | null;
|
|
8
10
|
city: string | null;
|
|
@@ -15,5 +17,4 @@ interface AddressFormData {
|
|
|
15
17
|
useLocation: boolean;
|
|
16
18
|
}
|
|
17
19
|
//#endregion
|
|
18
|
-
export { AddressFormData };
|
|
19
20
|
//# sourceMappingURL=ui.d.mts.map
|
package/dist/ui.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.d.mts","names":[],"sources":["../src/ui.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ui.d.mts","names":[],"sources":["../src/ui.ts"],"mappings":";;;;;;iBAWiB;EACf;EACA;EACA;EACA;EACA;EACA;;EAEA,KAAK;;EAEL"}
|
package/dist/ui.mjs
CHANGED
|
@@ -137,7 +137,7 @@ var WidgetView = class {
|
|
|
137
137
|
*/
|
|
138
138
|
fillBrand() {
|
|
139
139
|
this.clear(this.brandEl);
|
|
140
|
-
const lastTenMins = Date.now() - Math.floor(Math.random() *
|
|
140
|
+
const lastTenMins = Date.now() - Math.floor(Math.random() * 6e5);
|
|
141
141
|
const branded = this.theme.showBranding && (this.theme.logoUrl || this.theme.name);
|
|
142
142
|
this.dom.append(this.brandEl, branded ? [this.theme.logoUrl && this.dom.h("img", {
|
|
143
143
|
class: "arkyc-logo",
|
|
@@ -446,11 +446,12 @@ var WidgetView = class {
|
|
|
446
446
|
if (!sample) return;
|
|
447
447
|
fillEma = ema(fillEma, sample.fill);
|
|
448
448
|
edgeEma = ema(edgeEma, sample.edgeStrength);
|
|
449
|
-
const
|
|
449
|
+
const smoothed = {
|
|
450
450
|
...sample,
|
|
451
451
|
fill: fillEma,
|
|
452
452
|
edgeStrength: edgeEma
|
|
453
|
-
}
|
|
453
|
+
};
|
|
454
|
+
const { ready, hint: message } = documentGuidance(smoothed, this.docTuning);
|
|
454
455
|
hint.textContent = message;
|
|
455
456
|
doc.setFrame(sample.present ? sample.rect : null);
|
|
456
457
|
doc.setQuality(ready ? "good" : sample.present ? "wait" : "bad");
|