Viewing is open to everyone. Downloading and starring need a GitHub sign-in. Sign in with GitHub

ckey.mjs

v0.1.0-build.85 Latest Commit ede38f5

Size
2.9 KB
Lines
68
Language
javascript
SHA-256
f65fbcaa5f80…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1// CKey Web SDK entry point (npm package `openckey`).
2//
3// import { loadCKey } from 'openckey';
4// const ckey = await loadCKey();
5//
6// loadCKey fetches ckey.wasm from next to this module unless told otherwise.
7// The Emscripten glue (ckey-core.mjs) and the WebAssembly binary are built
8// from the C core by scripts/build.sh.
9
10import { createCKey } from './api.mjs';
11
12export { classifyPayload, readableText, toHex } from './payload.mjs';
13export { CKEY_TELEMETRY_ENDPOINT } from './telemetry.mjs';
14export { SAME_DEVICE, CROSS_DEVICE, isSafeAction, SafeActions, SafeActionRequest } from './safe-actions.mjs';
15
16/** Telemetry modes (canonical numeric values shared by every CKey SDK). */
17export const TELEMETRY_OFF = 0;
18export const TELEMETRY_ON = 1;
19export const TELEMETRY_LOCAL = 2;
20
21let shared = null;
22
23/**
24 * Loads the WebAssembly core and returns the CKey API object.
25 *
26 * options:
27 * wasmUrl URL or string of ckey.wasm (default: next to this module)
28 * wasmBinary ArrayBuffer/Uint8Array of ckey.wasm (skips fetching)
29 * telemetry initial mode 0 | 1 | 2 (applied before anything is counted)
30 * fetch fetch function used for telemetry; null never sends
31 * telemetryEndpoint override of CKEY_TELEMETRY_ENDPOINT (tests, self-hosting)
32 * moduleFactory Emscripten factory to use instead of ./ckey-core.mjs
33 *
34 * Called with no options, every call returns the same instance.
35 */
36export function loadCKey(options) {
37 if (options === undefined) return (shared ??= instantiate({}).catch((e) => ((shared = null), Promise.reject(e))));
38 if (options === null || typeof options !== 'object') throw new TypeError('loadCKey options must be an object');
39 return instantiate(options);
40}
41
42async function instantiate(options) {
43 const factory = options.moduleFactory ?? (await import('./ckey-core.mjs')).default;
44 const wasmUrl = options.wasmUrl !== undefined ? new URL(String(options.wasmUrl), baseUrl()) : new URL('./ckey.wasm', import.meta.url);
45 let wasmBinary = options.wasmBinary;
46 if (wasmBinary === undefined) wasmBinary = readLocalWasm(wasmUrl);
47 const moduleArgs = {
48 locateFile: (path) => (path.endsWith('.wasm') ? wasmUrl.href : path),
49 print: () => {},
50 printErr: () => {},
51 };
52 if (wasmBinary !== undefined) moduleArgs.wasmBinary = wasmBinary instanceof Uint8Array ? wasmBinary : new Uint8Array(wasmBinary);
53 const M = await factory(moduleArgs);
54 return createCKey(M, options);
55}
56
57function baseUrl() {
58 return typeof location !== 'undefined' && location.href ? location.href : import.meta.url;
59}
60
61// In Node (tests, server-side rendering) a file: URL is read directly; the
62// browser path fetches and streams the binary instead.
63function readLocalWasm(url) {
64 if (url.protocol !== 'file:') return undefined;
65 const getBuiltin = globalThis.process?.getBuiltinModule;
66 if (typeof getBuiltin !== 'function') return undefined; // the glue's own loader handles it
67 return getBuiltin('node:fs').readFileSync(url);
68}