quadqr-js 0.7.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.
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Optional QuadQR WASM acceleration.
3
+ *
4
+ * The library does not require WASM. Calling initWasm() installs the bundled
5
+ * CRC-32 helper into the normal synchronous codec path; failure leaves the
6
+ * JavaScript fallback untouched.
7
+ */
8
+
9
+ import { installCrc32Accelerator } from "./quadqr.js";
10
+
11
+ let state = null;
12
+ let loading = null;
13
+
14
+ function toUint8Array(input) {
15
+ if (input instanceof Uint8Array) return input;
16
+ if (ArrayBuffer.isView(input)) return new Uint8Array(input.buffer, input.byteOffset, input.byteLength);
17
+ if (input instanceof ArrayBuffer) return new Uint8Array(input);
18
+ return new Uint8Array(input);
19
+ }
20
+
21
+ async function loadBytes(url) {
22
+ if (url.protocol === "file:" && typeof process !== "undefined" && process.versions?.node) {
23
+ const [{ readFile }, { fileURLToPath }] = await Promise.all([
24
+ import("node:fs/promises"),
25
+ import("node:url")
26
+ ]);
27
+ return new Uint8Array(await readFile(fileURLToPath(url)));
28
+ }
29
+
30
+ const response = await fetch(url);
31
+ if (!response.ok) throw new Error(`Unable to load QuadQR WASM (${response.status}).`);
32
+ return new Uint8Array(await response.arrayBuffer());
33
+ }
34
+
35
+ function makeCrc32(instance) {
36
+ const { memory, crc32_bytes: crc32Bytes } = instance.exports;
37
+ if (!(memory instanceof WebAssembly.Memory) || typeof crc32Bytes !== "function") {
38
+ throw new Error("QuadQR WASM exports are invalid.");
39
+ }
40
+
41
+ const rawHeapBase = instance.exports.__heap_base;
42
+ const heapBase = Number(rawHeapBase?.value ?? rawHeapBase ?? 65536);
43
+
44
+ return (input) => {
45
+ const bytes = toUint8Array(input);
46
+ const required = heapBase + bytes.length;
47
+ if (required > memory.buffer.byteLength) {
48
+ const pages = Math.ceil((required - memory.buffer.byteLength) / 65536);
49
+ memory.grow(pages);
50
+ }
51
+ new Uint8Array(memory.buffer, heapBase, bytes.length).set(bytes);
52
+ return crc32Bytes(heapBase, bytes.length) >>> 0;
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Load QuadQR's bundled WebAssembly helper and install it into the codec.
58
+ * @param {{url?: string|URL, bytes?: Uint8Array|ArrayBuffer}} options
59
+ */
60
+ export async function initWasm(options = {}) {
61
+ if (state) return state;
62
+ if (loading) return loading;
63
+
64
+ loading = (async () => {
65
+ const bytes = options.bytes
66
+ ? toUint8Array(options.bytes)
67
+ : await loadBytes(options.url ? new URL(options.url, import.meta.url) : new URL("../wasm/quadqr-core.wasm", import.meta.url));
68
+
69
+ const { instance } = await WebAssembly.instantiate(bytes, {});
70
+ const crc32 = makeCrc32(instance);
71
+ installCrc32Accelerator(crc32);
72
+
73
+ state = Object.freeze({
74
+ enabled: true,
75
+ module: "quadqr-core",
76
+ accelerators: Object.freeze(["crc32"]),
77
+ bytes: bytes.length
78
+ });
79
+ return state;
80
+ })();
81
+
82
+ try {
83
+ return await loading;
84
+ } catch (error) {
85
+ loading = null;
86
+ throw error;
87
+ }
88
+ }
89
+
90
+ export function getWasmState() {
91
+ return state;
92
+ }
93
+
94
+ export function disableWasm() {
95
+ installCrc32Accelerator(null);
96
+ state = null;
97
+ loading = null;
98
+ }
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ module.exports = require("./index.js");
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./esm/quadqr.js";
2
+ export { initWasm, getWasmState, disableWasm } from "./esm/wasm.js";
package/dist/node.cjs ADDED
@@ -0,0 +1 @@
1
+ module.exports = require("./node.js");
package/dist/node.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./esm/node.js";