quadqr-js 0.7.0 → 1.0.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.
@@ -1,28 +1,87 @@
1
1
  # Getting Started
2
2
 
3
- ## Install from npm
3
+ ## Install
4
4
 
5
5
  ```bash
6
- npm install quadqr
6
+ npm install quadqr-js
7
7
  ```
8
8
 
9
- QuadQR 0.7.x targets Node.js 20.19 or newer for the full ESM/CommonJS distribution behavior.
9
+ Node.js usage targets Node.js 20.19 or newer. Browser use works through a bundler, direct ESM, or the prebuilt CDN/global bundle.
10
10
 
11
- ## Generate and decode a matrix
11
+ ## Encode and decode text
12
12
 
13
13
  ```js
14
- import { encodeText, decodeMatrix } from "quadqr";
14
+ import { encodeText, decodeMatrix } from "quadqr-js";
15
15
 
16
- const code = encodeText("Hello from QuadQR", { ecc: "M" });
17
- const decoded = decodeMatrix(code.matrix);
16
+ const code = encodeText("Hello from QuadQR", {
17
+ ecc: "M"
18
+ });
19
+
20
+ const result = decodeMatrix(code.matrix);
21
+ console.log(result.text);
22
+ ```
23
+
24
+ If no version is supplied, QuadQR automatically chooses the smallest version that fits the payload.
25
+
26
+ ## Render in the browser
27
+
28
+ ```js
29
+ import {
30
+ encodeText,
31
+ renderToCanvas
32
+ } from "quadqr-js/browser";
33
+
34
+ const code = encodeText("Rendered in the browser");
35
+
36
+ renderToCanvas(code, document.querySelector("#qr"), {
37
+ moduleSize: 12,
38
+ quietZone: 4,
39
+ style: "classic"
40
+ });
41
+ ```
18
42
 
19
- console.log(decoded.text);
43
+ Available presentation styles are `classic`, `depth`, `soft`, and `inset`. Styling does not change the encoded matrix.
44
+
45
+ ## Scan an uploaded image
46
+
47
+ ```js
48
+ import { scanFile } from "quadqr-js/browser";
49
+
50
+ const file = document.querySelector("#image").files[0];
51
+ const result = await scanFile(file);
52
+
53
+ console.log(result.text);
20
54
  ```
21
55
 
56
+ ## Scan from the camera
57
+
58
+ ```js
59
+ import { startCameraScanner } from "quadqr-js/browser";
60
+
61
+ let scanner;
62
+ scanner = await startCameraScanner(
63
+ document.querySelector("#video"),
64
+ {
65
+ onDecode(result) {
66
+ console.log(result);
67
+ scanner.stop();
68
+ }
69
+ }
70
+ );
71
+ ```
72
+
73
+ Camera access requires HTTPS or localhost.
74
+
22
75
  ## Secure password mode
23
76
 
77
+ Secure payloads are optional. Password mode is the simplest choice when a person will provide the secret during decryption.
78
+
24
79
  ```js
25
- import { encodeSecureText, decodeMatrix, decryptDecoded } from "quadqr";
80
+ import {
81
+ encodeSecureText,
82
+ decodeMatrix,
83
+ decryptDecoded
84
+ } from "quadqr-js";
26
85
 
27
86
  const code = await encodeSecureText("Private payload", {
28
87
  ecc: "M",
@@ -33,6 +92,7 @@ const code = await encodeSecureText("Private payload", {
33
92
  });
34
93
 
35
94
  const locked = decodeMatrix(code.matrix);
95
+
36
96
  const unlocked = await decryptDecoded(locked, {
37
97
  password: "correct horse battery staple"
38
98
  });
@@ -40,19 +100,21 @@ const unlocked = await decryptDecoded(locked, {
40
100
  console.log(unlocked.text);
41
101
  ```
42
102
 
43
- ## Raw 256-bit key mode
103
+ A secure image or camera scan follows the same pattern: scanning returns a locked result, then `decryptDecoded()` reveals plaintext only after successful authentication.
104
+
105
+ ## Secure raw-key mode
106
+
107
+ Use raw-key mode when an application already manages its own cryptographic keys.
44
108
 
45
109
  ```js
46
110
  import {
47
- bytesToHex,
48
111
  encodeSecureText,
49
112
  generateRaw256Key
50
- } from "quadqr";
113
+ } from "quadqr-js";
51
114
 
52
115
  const key = generateRaw256Key();
53
- console.log(bytesToHex(key));
54
116
 
55
- const code = await encodeSecureText("Machine-readable secret", {
117
+ const code = await encodeSecureText("Application-managed secret", {
56
118
  security: {
57
119
  mode: "raw-key",
58
120
  key
@@ -60,15 +122,16 @@ const code = await encodeSecureText("Machine-readable secret", {
60
122
  });
61
123
  ```
62
124
 
63
- Never place the raw encryption key inside the same QuadQR payload.
125
+ The key must be exactly 32 bytes. Never embed the secret key inside the same QuadQR payload.
64
126
 
65
- ## Node.js PNG
127
+ ## Generate and scan PNG files in Node.js
66
128
 
67
129
  ```js
68
- import { encodeText } from "quadqr";
69
- import { savePNG, scanFile } from "quadqr/node";
130
+ import { encodeText } from "quadqr-js";
131
+ import { savePNG, scanFile } from "quadqr-js/node";
70
132
 
71
133
  const code = encodeText("Generated on Node.js");
134
+
72
135
  await savePNG(code, "quadqr.png", {
73
136
  moduleSize: 12,
74
137
  quietZone: 4
@@ -78,14 +141,33 @@ const result = await scanFile("quadqr.png");
78
141
  console.log(result.text);
79
142
  ```
80
143
 
81
- ## Browser script tag
144
+ PNG generation and decoding are built into the Node.js adapter.
145
+
146
+ ## Use a script tag
82
147
 
83
148
  ```html
84
- <script src="https://cdn.jsdelivr.net/npm/quadqr@0.7.0/dist/quadqr.min.js"></script>
149
+ <canvas id="qr"></canvas>
150
+ <script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.0.0/dist/quadqr.min.js"></script>
85
151
  <script>
86
152
  const code = QuadQR.encodeText("No build step");
87
- console.log(code.version, code.matrix);
153
+ QuadQR.renderToCanvas(code, document.querySelector("#qr"));
88
154
  </script>
89
155
  ```
90
156
 
91
- For production sites, pin the exact package version in the CDN URL.
157
+ Pin an exact package version in production.
158
+
159
+ ## Use the CLI
160
+
161
+ ```bash
162
+ npx quadqr-js encode "Hello QuadQR" -o hello.png
163
+ npx quadqr-js decode hello.png
164
+ ```
165
+
166
+ Password-protected CLI workflow:
167
+
168
+ ```bash
169
+ npx quadqr-js encode "Private data" --password "my-password" -o secure.png
170
+ npx quadqr-js decode secure.png --password "my-password"
171
+ ```
172
+
173
+ See [CLI.md](./CLI.md) for the full command reference.
package/docs/NODE.md CHANGED
@@ -1,78 +1,80 @@
1
1
  # Node.js
2
2
 
3
- QuadQR uses the same matrix codec and image scanner in Node.js and the browser. The `quadqr/node` entry only adds Node-specific file and PNG helpers.
3
+ QuadQR uses the same matrix codec and scanner core in Node.js and the browser. The `quadqr-js/node` entry adds Node-specific PNG, file, and buffer helpers.
4
4
 
5
5
  ## Requirements
6
6
 
7
- The package targets Node.js 20.19 or newer.
7
+ Node.js 20.19 or newer.
8
8
 
9
9
  ## ESM
10
10
 
11
11
  ```js
12
- import { encodeText } from "quadqr";
13
- import { savePNG, scanFile } from "quadqr/node";
12
+ import { encodeText } from "quadqr-js";
13
+ import { savePNG, scanFile } from "quadqr-js/node";
14
14
  ```
15
15
 
16
16
  ## CommonJS
17
17
 
18
- On supported modern Node versions:
19
-
20
18
  ```js
21
- const QuadQR = require("quadqr");
22
- const QuadQRNode = require("quadqr/node");
19
+ const QuadQR = require("quadqr-js");
20
+ const QuadQRNode = require("quadqr-js/node");
23
21
  ```
24
22
 
25
- ## Generate PNG
23
+ ## Generate a PNG
26
24
 
27
25
  ```js
28
26
  const code = QuadQR.encodeText("Server generated");
27
+
29
28
  await QuadQRNode.savePNG(code, "output.png", {
30
29
  moduleSize: 12,
31
30
  quietZone: 4
32
31
  });
33
32
  ```
34
33
 
35
- `toPNG()` returns a `Buffer` instead of writing it:
34
+ Use `toPNG()` when you need an in-memory `Buffer`:
36
35
 
37
36
  ```js
38
37
  const png = QuadQRNode.toPNG(code);
39
38
  ```
40
39
 
41
- This is useful for HTTP responses, object storage, email attachments, or database/blob workflows.
40
+ This works well for HTTP responses, object storage, attachments, and other buffer-based workflows.
42
41
 
43
- ## Scan PNG
42
+ ## Scan a PNG file
44
43
 
45
44
  ```js
46
45
  const result = await QuadQRNode.scanFile("output.png");
47
46
  console.log(result.text);
48
47
  ```
49
48
 
50
- Or scan an in-memory buffer:
49
+ Or scan a buffer:
51
50
 
52
51
  ```js
53
52
  const result = await QuadQRNode.scanBuffer(pngBuffer);
54
53
  ```
55
54
 
56
- PNG decoding is dependency-free and supports normal non-interlaced 8-bit RGB/RGBA PNGs plus indexed PNGs.
55
+ PNG generation and decoding do not require external native dependencies.
57
56
 
58
- ## JPEG, WebP, and AVIF
57
+ ## Other image formats
59
58
 
60
- QuadQR does not force a native image dependency on every user. If your application already uses `sharp`, `scanBuffer()` / `scanFile()` can use it for formats other than PNG.
59
+ For JPEG, WebP, or AVIF input, the Node adapter can use `sharp` when the consuming application has it installed:
61
60
 
62
61
  ```bash
63
62
  npm install sharp
64
63
  ```
65
64
 
66
- If `sharp` is not installed, pass decoded RGBA pixels directly to `scanImageData()` or use PNG input.
65
+ If `sharp` is not installed, decode the image to RGBA in your own image pipeline and pass the pixels to `scanImageData()`.
67
66
 
68
- ## Secure Node workflow
67
+ ## Secure password workflow
69
68
 
70
69
  ```js
71
70
  import {
72
71
  decryptDecoded,
73
72
  encodeSecureText
74
- } from "quadqr";
75
- import { savePNG, scanFile } from "quadqr/node";
73
+ } from "quadqr-js";
74
+ import {
75
+ savePNG,
76
+ scanFile
77
+ } from "quadqr-js/node";
76
78
 
77
79
  const code = await encodeSecureText("private", {
78
80
  security: {
@@ -84,9 +86,38 @@ const code = await encodeSecureText("private", {
84
86
  await savePNG(code, "secure.png");
85
87
 
86
88
  const locked = await scanFile("secure.png");
89
+
87
90
  const unlocked = await decryptDecoded(locked, {
88
91
  password: process.env.QUADQR_PASSWORD
89
92
  });
90
93
 
91
94
  console.log(unlocked.text);
92
95
  ```
96
+
97
+ ## Secure raw-key workflow
98
+
99
+ ```js
100
+ import {
101
+ decryptDecoded,
102
+ encodeSecureText,
103
+ generateRaw256Key
104
+ } from "quadqr-js";
105
+ import { toPNG, scanBuffer } from "quadqr-js/node";
106
+
107
+ const key = generateRaw256Key();
108
+
109
+ const code = await encodeSecureText("machine secret", {
110
+ security: {
111
+ mode: "raw-key",
112
+ key
113
+ }
114
+ });
115
+
116
+ const png = toPNG(code);
117
+ const locked = await scanBuffer(png);
118
+ const unlocked = await decryptDecoded(locked, { key });
119
+
120
+ console.log(unlocked.text);
121
+ ```
122
+
123
+ Keep long-lived application keys in an appropriate secret-management or platform key-storage system.
@@ -1,8 +1,8 @@
1
1
  # Publishing QuadQR to npm
2
2
 
3
- This repository is already configured as a public npm package named `quadqr` at version `0.7.0`.
3
+ QuadQR is published on npm as [`quadqr-js`](https://www.npmjs.com/package/quadqr-js). The repository package name is `quadqr-js`.
4
4
 
5
- Before the first publish, confirm that the package name is available. If it is already owned by somebody else, use a scoped name such as `@akanshsirohi/quadqr` and update the CDN examples accordingly.
5
+ The QuadQR project/brand, browser global (`QuadQR`), CLI executable (`quadqr`), and generated filenames remain unchanged. Only the npm package identifier is `quadqr-js`.
6
6
 
7
7
  ## 1. Create/sign in to npm
8
8
 
@@ -30,13 +30,13 @@ npm install
30
30
 
31
31
  so your local package lock and npm metadata are synchronized.
32
32
 
33
- ## 3. Verify the package name
33
+ ## 3. Verify the package metadata
34
34
 
35
35
  ```bash
36
- npm view quadqr
36
+ npm view quadqr-js
37
37
  ```
38
38
 
39
- If npm returns a package owned by somebody else, do not publish over it. Change `package.json` to a scoped name that you own.
39
+ Confirm the published package and current version before releasing an update.
40
40
 
41
41
  ## 4. Run the full release checks
42
42
 
@@ -56,18 +56,12 @@ npm pack
56
56
 
57
57
  ## 5. Publish
58
58
 
59
- For the current unscoped public package:
59
+ The package is an unscoped public package and `publishConfig.access` is already set to `public`, so publish with:
60
60
 
61
61
  ```bash
62
62
  npm publish
63
63
  ```
64
64
 
65
- For a scoped public package:
66
-
67
- ```bash
68
- npm publish --access public
69
- ```
70
-
71
65
  npm publishing requires an account that satisfies npm's current 2FA/authentication requirements.
72
66
 
73
67
  ## 6. Verify installation from a clean directory
@@ -76,15 +70,15 @@ npm publishing requires an account that satisfies npm's current 2FA/authenticati
76
70
  mkdir quadqr-consumer-test
77
71
  cd quadqr-consumer-test
78
72
  npm init -y
79
- npm install quadqr
73
+ npm install quadqr-js
80
74
  ```
81
75
 
82
76
  Then test ESM, Node PNG, and the CLI.
83
77
 
84
78
  ```bash
85
- npx quadqr keygen
86
- npx quadqr encode "Hello from npm" -o hello.png
87
- npx quadqr decode hello.png
79
+ npx quadqr-js keygen
80
+ npx quadqr-js encode "Hello from npm" -o hello.png
81
+ npx quadqr-js decode hello.png
88
82
  ```
89
83
 
90
84
  ## 7. Verify CDN availability
@@ -92,8 +86,8 @@ npx quadqr decode hello.png
92
86
  After npm and CDN caches update, test:
93
87
 
94
88
  ```text
95
- https://cdn.jsdelivr.net/npm/quadqr@0.7.0/dist/quadqr.min.js
96
- https://unpkg.com/quadqr@0.7.0/dist/quadqr.min.js
89
+ https://cdn.jsdelivr.net/npm/quadqr-js@1.0.0/dist/quadqr.min.js
90
+ https://unpkg.com/quadqr-js@1.0.0/dist/quadqr.min.js
97
91
  ```
98
92
 
99
93
  Then call `QuadQR.encodeText(...)` from a plain HTML page.
package/docs/README.md CHANGED
@@ -1,26 +1,41 @@
1
1
  # QuadQR Documentation
2
2
 
3
- QuadQR is an experimental four-state RGBW matrix symbology. Each data cell carries exactly two bits using red, green, blue, or white. The library adds Spectrum ECC, perspective-aware scanning, optional authenticated encryption, browser camera support, Node.js PNG support, a CDN/global build, and an optional prebuilt WebAssembly accelerator.
3
+ QuadQR is an experimental four-state RGBW matrix symbology. Each data cell carries exactly two bits using red, green, blue, or white. The JavaScript library supports encoding, rendering, matrix decoding, image and camera scanning, Spectrum ECC, optional authenticated encryption, Node.js PNG workflows, CDN usage, a CLI, TypeScript declarations, and optional prebuilt WebAssembly acceleration.
4
4
 
5
- ## Documentation map
5
+ ## Live links
6
+
7
+ - [Documentation Site](https://akanshsirohi.github.io/QuadQR/docs-site/)
8
+ - [Interactive Demo](https://akanshsirohi.github.io/QuadQR/demo/)
9
+ - [quadqr-js on npm](https://www.npmjs.com/package/quadqr-js)
10
+ - [GitHub Repository](https://github.com/akanshsirohi/QuadQR)
11
+
12
+ ## Documentation
6
13
 
7
14
  - [Getting Started](./GETTING_STARTED.md)
8
15
  - [API Reference](./API.md)
9
16
  - [Browser and CDN](./BROWSER_CDN.md)
10
17
  - [Node.js](./NODE.md)
18
+ - [CLI](./CLI.md)
11
19
  - [Secure Payloads](./SECURITY.md)
12
- - [WASM](./WASM.md)
13
- - [Publishing to npm](./PUBLISHING.md)
20
+ - [WebAssembly](./WASM.md)
14
21
  - [Wire Format](../FORMAT.md)
15
22
 
16
23
  ## Package entry points
17
24
 
18
25
  | Entry | Purpose |
19
26
  | --- | --- |
20
- | `quadqr` | Runtime-neutral core API plus optional WASM loader |
21
- | `quadqr/browser` | Browser ESM entry |
22
- | `quadqr/node` | Node.js core plus PNG/file helpers |
23
- | `quadqr/benchmark` | Capacity and codec benchmark helpers |
24
- | `quadqr/quadqr.min.js` | Classic browser global bundle for CDNs |
27
+ | `quadqr-js` | Runtime-neutral core API, rendering, scanning, secure payloads, utilities, and optional WASM |
28
+ | `quadqr-js/browser` | Browser ESM entry for canvas, files, video, and camera workflows |
29
+ | `quadqr-js/node` | Node.js core plus PNG, file, and buffer helpers |
30
+ | `quadqr-js/benchmark` | Capacity and codec benchmark helpers |
31
+ | `quadqr-js/quadqr.min.js` | Classic browser global bundle for CDN/script-tag usage |
32
+
33
+ The matrix codec is shared across runtimes. Browser and Node.js adapters only handle environment-specific input and output.
34
+
35
+ ## Compatibility note
36
+
37
+ QuadQR is a custom experimental format, not ISO QR Code. Standard QR scanner applications cannot decode QuadQR symbols.
38
+
39
+ ## License
25
40
 
26
- The package is designed so the matrix codec is shared across all runtimes. Browser and Node adapters only handle runtime-specific input/output.
41
+ QuadQR is licensed under AGPL-3.0. See [`LICENSE`](../LICENSE).
package/docs/SECURITY.md CHANGED
@@ -1,17 +1,26 @@
1
1
  # Secure Payloads
2
2
 
3
- QuadQR Secure Payload v1 is an optional layer above the matrix codec and Spectrum ECC.
3
+ QuadQR Secure Payload v1 is an optional authenticated-encryption layer above the matrix codec and Spectrum ECC.
4
4
 
5
5
  ```text
6
6
  plaintext
7
- -> encryption/authentication
7
+ -> encryption + authentication
8
8
  -> secure envelope
9
9
  -> QuadQR framing
10
10
  -> Spectrum ECC
11
11
  -> RGBW matrix
12
12
  ```
13
13
 
14
- Scanning and error correction therefore remain independent from encryption.
14
+ Normal QuadQR symbols are unencrypted by default. Secure Payload is used only when explicitly requested.
15
+
16
+ ## Which mode should I use?
17
+
18
+ | Mode | Use it when |
19
+ | --- | --- |
20
+ | Password | A person will enter or share a secret password to unlock the payload |
21
+ | Raw 256-bit key | Your application, service, device, or scanner already manages cryptographic keys |
22
+
23
+ Both modes use AES-256-GCM for confidentiality and authenticated integrity.
15
24
 
16
25
  ## Password mode
17
26
 
@@ -22,9 +31,11 @@ Password mode uses:
22
31
  - configurable iteration count, default 600,000
23
32
  - AES-256-GCM
24
33
  - random 12-byte nonce
25
- - authenticated metadata
34
+ - authenticated envelope metadata
26
35
 
27
36
  ```js
37
+ import { encodeSecureText } from "quadqr-js";
38
+
28
39
  const code = await encodeSecureText("private", {
29
40
  security: {
30
41
  mode: "password",
@@ -37,9 +48,14 @@ The password is never stored in the QuadQR symbol.
37
48
 
38
49
  ## Raw 256-bit key mode
39
50
 
40
- Raw-key mode accepts exactly 32 random bytes.
51
+ Raw-key mode accepts exactly 32 secret bytes, either as bytes or a 64-character hexadecimal string.
41
52
 
42
53
  ```js
54
+ import {
55
+ encodeSecureText,
56
+ generateRaw256Key
57
+ } from "quadqr-js";
58
+
43
59
  const key = generateRaw256Key();
44
60
 
45
61
  const code = await encodeSecureText("machine secret", {
@@ -50,29 +66,64 @@ const code = await encodeSecureText("machine secret", {
50
66
  });
51
67
  ```
52
68
 
53
- By default QuadQR stores only a short SHA-256 fingerprint/key ID so an application can identify the required key without embedding the actual secret.
69
+ By default, the secure envelope can include a short SHA-256 key fingerprint/key ID. This is a non-secret routing hint that can help an application choose the correct key. The actual secret key is never embedded in the symbol.
54
70
 
55
- ## Decryption
71
+ ## Scanning secure QuadQR
56
72
 
57
- A secure scan stays locked:
73
+ Scanning does not automatically reveal protected plaintext. The scanner first returns a locked result:
58
74
 
59
75
  ```js
60
- const locked = scanImageData(imageData);
76
+ const locked = await scanFile(file);
61
77
 
62
- if (locked.secure) {
63
- const unlocked = await decryptDecoded(locked, {
64
- password: "long unique password"
65
- });
66
- }
78
+ console.log(locked.secure); // true
79
+ console.log(locked.requiresDecryption); // true
80
+ console.log(locked.security.mode); // password | raw-key
81
+ console.log(locked.text); // null
82
+ ```
83
+
84
+ Then unlock it with the correct credential:
85
+
86
+ ```js
87
+ const unlocked = await decryptDecoded(locked, {
88
+ password: "long unique password"
89
+ });
90
+
91
+ console.log(unlocked.text);
67
92
  ```
68
93
 
69
- AES-GCM authentication rejects an incorrect password/key or modified ciphertext.
94
+ For raw-key mode:
95
+
96
+ ```js
97
+ const unlocked = await decryptDecoded(locked, { key });
98
+ ```
99
+
100
+ Image upload, camera, matrix, RGBA, and Node.js scan results all use the same secure-result model.
101
+
102
+ ## Authentication behavior
103
+
104
+ AES-GCM authentication rejects:
105
+
106
+ - an incorrect password;
107
+ - an incorrect raw key;
108
+ - modified ciphertext;
109
+ - modified authenticated secure-envelope metadata.
110
+
111
+ QuadQR's CRC and Spectrum ECC still handle matrix/image corruption before decryption is attempted. Cryptographic authentication is a separate final security check.
112
+
113
+ ## Key management guidance
114
+
115
+ - Use long, unique passwords for password mode.
116
+ - Generate raw keys with `generateRaw256Key()` or another cryptographically secure random source.
117
+ - Store long-lived raw keys in an appropriate secret manager, operating-system key store, HSM, or equivalent secure storage for your application.
118
+ - Do not put the secret password or raw key inside the same QuadQR symbol.
119
+ - Do not hard-code a long-lived raw key in public client-side JavaScript if it is intended to remain secret.
120
+
121
+ ## Security boundaries
70
122
 
71
- ## Threat model notes
123
+ Secure Payload protects payload confidentiality and integrity, but it does not solve every application-security problem:
72
124
 
73
- - Secure Payload protects payload confidentiality and integrity.
74
125
  - It does not hide the fact that a QuadQR symbol exists.
75
- - Key IDs are routing hints, not secrets.
76
- - A photographed code can still be copied, so encryption alone is not anti-replay protection.
77
- - Applications needing ticket/access anti-replay should combine QuadQR with server-side nonce/state validation or signed short-lived tokens.
78
- - Do not hard-code long-lived raw keys in public client-side JavaScript if those keys are meant to remain secret.
126
+ - A photographed symbol can still be copied.
127
+ - Encryption by itself is not replay protection.
128
+ - Ticket/access systems should use server-side state, nonces, expiry, signatures, or another replay-control mechanism appropriate to the application.
129
+ - Decoded plaintext is still untrusted application input and should be validated before use.
package/docs/WASM.md CHANGED
@@ -1,36 +1,67 @@
1
1
  # WebAssembly
2
2
 
3
- QuadQR ships a small precompiled WebAssembly module at:
3
+ QuadQR includes an optional prebuilt WebAssembly module at:
4
4
 
5
5
  ```text
6
6
  dist/wasm/quadqr-core.wasm
7
7
  ```
8
8
 
9
- The normal JavaScript codec does not require it. This is intentional: installation, browser loading, serverless execution, and restricted environments should still work when WASM is unavailable.
9
+ The normal JavaScript implementation works without WASM. Applications can opt in when they want to use the bundled accelerator.
10
10
 
11
- ## Enable it
11
+ ## Enable WASM
12
12
 
13
13
  ```js
14
- import { initWasm } from "quadqr";
14
+ import { initWasm } from "quadqr-js";
15
15
 
16
16
  const state = await initWasm();
17
17
  console.log(state);
18
18
  ```
19
19
 
20
- Current 0.7.x acceleration covers CRC-32, which is used by QuadQR framing integrity checks. Once initialized, encode/decode calls automatically use the installed synchronous accelerator.
20
+ In QuadQR 0.7.x, the WASM module accelerates CRC-32. Once initialized, normal encode/decode operations automatically use the installed accelerator.
21
21
 
22
- ## Why start small?
22
+ ## Check the current state
23
23
 
24
- QuadQR scanning and Spectrum ECC are still evolving. Keeping the first WASM ABI narrow lets the library ship a stable prebuilt binary without forcing the matrix format to depend on a specific compiler/runtime implementation.
24
+ ```js
25
+ import { getWasmState } from "quadqr-js";
26
+
27
+ console.log(getWasmState());
28
+ ```
25
29
 
26
- Future profiling can move heavier hot paths, such as image classification or selected ECC operations, behind the same optional acceleration layer without changing the public QuadQR wire format.
30
+ Before initialization, or after disabling WASM, the result is `null`.
27
31
 
28
- ## Disable
32
+ ## Disable WASM
29
33
 
30
34
  ```js
31
- import { disableWasm } from "quadqr";
35
+ import { disableWasm } from "quadqr-js";
32
36
 
33
37
  disableWasm();
34
38
  ```
35
39
 
36
- The JavaScript fallback is restored immediately.
40
+ QuadQR immediately returns to the JavaScript implementation.
41
+
42
+ ## Custom WASM URL
43
+
44
+ Browser and CDN applications can override the asset location:
45
+
46
+ ```js
47
+ await initWasm({
48
+ url: "https://example.com/assets/quadqr-core.wasm"
49
+ });
50
+ ```
51
+
52
+ You can also provide WASM bytes directly through the `bytes` option.
53
+
54
+ ## CDN behavior
55
+
56
+ When the classic `quadqr.min.js` global build is loaded from a CDN, `QuadQR.initWasm()` resolves the bundled sibling WASM asset from the same package/version location.
57
+
58
+ ```html
59
+ <script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.0.0/dist/quadqr.min.js"></script>
60
+ <script>
61
+ await QuadQR.initWasm();
62
+ </script>
63
+ ```
64
+
65
+ ## Fallback behavior
66
+
67
+ WASM is never required for the QuadQR wire format. If your environment cannot load WebAssembly, simply do not call `initWasm()` and continue using the JavaScript implementation.