quadqr-js 1.0.0 → 1.0.2

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,137 +1,142 @@
1
- # Browser and CDN Usage
2
-
3
- ## Browser ESM
4
-
5
- With Vite, webpack, Rollup, Next.js client code, or another browser bundler:
6
-
7
- ```js
8
- import {
9
- encodeText,
10
- renderToCanvas,
11
- scanFile,
12
- startCameraScanner
13
- } from "quadqr-js/browser";
14
- ```
15
-
16
- The main `quadqr-js` entry also works in modern browser bundlers for runtime-neutral APIs.
17
-
18
- ## Render to canvas
19
-
20
- ```js
21
- const code = encodeText("Hello browser");
22
-
23
- renderToCanvas(code, document.querySelector("#qr"), {
24
- moduleSize: 12,
25
- quietZone: 4,
26
- style: "classic"
27
- });
28
- ```
29
-
30
- Available styles are `classic`, `depth`, `soft`, and `inset`.
31
-
32
- ## Scan an uploaded image
33
-
34
- ```js
35
- const input = document.querySelector("#image");
36
- const result = await scanFile(input.files[0]);
37
-
38
- console.log(result.text);
39
- ```
40
-
41
- If the symbol uses Secure Payload, the scan result has `secure: true` and `requiresDecryption: true` until it is successfully unlocked.
42
-
43
- ## Live camera scanning
44
-
45
- ```js
46
- const video = document.querySelector("#camera");
47
-
48
- const scanner = await startCameraScanner(video, {
49
- scanInterval: 120,
50
- async onDecode(result) {
51
- console.log(result);
52
- scanner.stop();
53
- },
54
- onError(error) {
55
- console.error(error);
56
- }
57
- });
58
- ```
59
-
60
- Camera access requires HTTPS or localhost.
61
-
62
- ## Decrypt a secure scan
63
-
64
- ```js
65
- import { decryptDecoded } from "quadqr-js/browser";
66
-
67
- const locked = await scanFile(file);
68
-
69
- if (locked.secure) {
70
- const unlocked = await decryptDecoded(locked, {
71
- password: "my-password"
72
- });
73
-
74
- console.log(unlocked.text);
75
- }
76
- ```
77
-
78
- Raw-key mode uses `{ key }` instead of `{ password }`.
79
-
80
- ## Classic script tag
81
-
82
- The global browser build exposes `window.QuadQR` / `globalThis.QuadQR`.
83
-
84
- ```html
85
- <canvas id="qr"></canvas>
86
- <script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.0.0/dist/quadqr.min.js"></script>
87
- <script>
88
- const code = QuadQR.encodeText("Hello CDN");
89
-
90
- QuadQR.renderToCanvas(code, document.querySelector("#qr"), {
91
- moduleSize: 12,
92
- quietZone: 4
93
- });
94
- </script>
95
- ```
96
-
97
- ## unpkg
98
-
99
- ```html
100
- <script src="https://unpkg.com/quadqr-js@1.0.0/dist/quadqr.min.js"></script>
101
- ```
102
-
103
- ## Direct CDN ESM
104
-
105
- ```html
106
- <script type="module">
107
- import {
108
- encodeText,
109
- renderToCanvas
110
- } from "https://cdn.jsdelivr.net/npm/quadqr-js@1.0.0/dist/browser.js";
111
-
112
- const code = encodeText("ES module CDN");
113
- renderToCanvas(code, document.querySelector("#qr"));
114
- </script>
115
- ```
116
-
117
- ## Optional WASM from a CDN
118
-
119
- The classic global build can resolve the bundled WASM asset relative to its own script URL:
120
-
121
- ```js
122
- await QuadQR.initWasm();
123
- ```
124
-
125
- You can also provide a custom URL:
126
-
127
- ```js
128
- await QuadQR.initWasm({
129
- url: "https://example.com/assets/quadqr-core.wasm"
130
- });
131
- ```
132
-
133
- WASM is optional. The normal JavaScript implementation remains available if it cannot load.
134
-
135
- ## Production recommendation
136
-
137
- Pin a concrete package version such as `@1.0.0` in CDN URLs so an existing site does not silently change when a newer package version becomes available.
1
+ # Browser and CDN Usage
2
+
3
+ ## Browser ESM
4
+
5
+ With Vite, webpack, Rollup, Next.js client code, or another browser bundler:
6
+
7
+ ```js
8
+ import {
9
+ encodeText,
10
+ renderToCanvas,
11
+ scanFile,
12
+ startCameraScanner
13
+ } from "quadqr-js/browser";
14
+ ```
15
+
16
+ The main `quadqr-js` entry also works in modern browser bundlers for runtime-neutral APIs.
17
+
18
+ ## Render to canvas
19
+
20
+ ```js
21
+ const code = encodeText("Hello browser");
22
+
23
+ renderToCanvas(code, document.querySelector("#qr"), {
24
+ moduleSize: 12,
25
+ quietZone: 4,
26
+ style: "classic"
27
+ });
28
+ ```
29
+
30
+ Available styles are `classic`, `depth`, `soft`, and `inset`.
31
+
32
+ ## Scan an uploaded image
33
+
34
+ ```js
35
+ const input = document.querySelector("#image");
36
+ const result = await scanFile(input.files[0]);
37
+
38
+ console.log(result.text);
39
+ ```
40
+
41
+ If the symbol uses Secure Payload, the scan result has `secure: true` and `requiresDecryption: true` until it is successfully unlocked.
42
+
43
+ ## Live camera scanning
44
+
45
+ ```js
46
+ const video = document.querySelector("#camera");
47
+
48
+ const scanner = await startCameraScanner(video, {
49
+ scanInterval: 120,
50
+ cameraFinderRecoveryEvery: 2,
51
+ async onResult(result) {
52
+ console.log(result);
53
+ scanner.stop();
54
+ },
55
+ onScanMiss() {
56
+ // Keep searching.
57
+ },
58
+ onDiagnostic(event) {
59
+ // Useful for live finder overlays and scanner debug logs.
60
+ console.log(event.method, event.finderMethod, event.finderCount, event.geometry?.version);
61
+ }
62
+ });
63
+ ```
64
+
65
+ Camera access requires HTTPS or localhost. QuadQR scans the part of an `object-fit: cover` video that is actually visible to the user. The fast finder pass uses the RGB value channel (`max(R,G,B)`) so saturated data colors are less likely to be mistaken for structural black. After misses, throttled recovery frames can try alternate finder thresholds before stronger color correction. `onDiagnostic` exposes the finder method and geometry work already performed by the scanner.
66
+
67
+ ## Decrypt a secure scan
68
+
69
+ ```js
70
+ import { decryptDecoded } from "quadqr-js/browser";
71
+
72
+ const locked = await scanFile(file);
73
+
74
+ if (locked.secure) {
75
+ const unlocked = await decryptDecoded(locked, {
76
+ password: "my-password"
77
+ });
78
+
79
+ console.log(unlocked.text);
80
+ }
81
+ ```
82
+
83
+ Raw-key mode uses `{ key }` instead of `{ password }`.
84
+
85
+ ## Classic script tag
86
+
87
+ The global browser build exposes `window.QuadQR` / `globalThis.QuadQR`.
88
+
89
+ ```html
90
+ <canvas id="qr"></canvas>
91
+ <script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.0.1/dist/quadqr.min.js"></script>
92
+ <script>
93
+ const code = QuadQR.encodeText("Hello CDN");
94
+
95
+ QuadQR.renderToCanvas(code, document.querySelector("#qr"), {
96
+ moduleSize: 12,
97
+ quietZone: 4
98
+ });
99
+ </script>
100
+ ```
101
+
102
+ ## unpkg
103
+
104
+ ```html
105
+ <script src="https://unpkg.com/quadqr-js@1.0.1/dist/quadqr.min.js"></script>
106
+ ```
107
+
108
+ ## Direct CDN ESM
109
+
110
+ ```html
111
+ <script type="module">
112
+ import {
113
+ encodeText,
114
+ renderToCanvas
115
+ } from "https://cdn.jsdelivr.net/npm/quadqr-js@1.0.1/dist/browser.js";
116
+
117
+ const code = encodeText("ES module CDN");
118
+ renderToCanvas(code, document.querySelector("#qr"));
119
+ </script>
120
+ ```
121
+
122
+ ## Optional WASM from a CDN
123
+
124
+ The classic global build can resolve the bundled WASM asset relative to its own script URL:
125
+
126
+ ```js
127
+ await QuadQR.initWasm();
128
+ ```
129
+
130
+ You can also provide a custom URL:
131
+
132
+ ```js
133
+ await QuadQR.initWasm({
134
+ url: "https://example.com/assets/quadqr-core.wasm"
135
+ });
136
+ ```
137
+
138
+ WASM is optional. The normal JavaScript implementation remains available if it cannot load.
139
+
140
+ ## Production recommendation
141
+
142
+ Pin a concrete package version such as `@1.0.1` in CDN URLs so an existing site does not silently change when a newer package version becomes available.
@@ -1,173 +1,174 @@
1
- # Getting Started
2
-
3
- ## Install
4
-
5
- ```bash
6
- npm install quadqr-js
7
- ```
8
-
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
-
11
- ## Encode and decode text
12
-
13
- ```js
14
- import { encodeText, decodeMatrix } from "quadqr-js";
15
-
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
- ```
42
-
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);
54
- ```
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
-
75
- ## Secure password mode
76
-
77
- Secure payloads are optional. Password mode is the simplest choice when a person will provide the secret during decryption.
78
-
79
- ```js
80
- import {
81
- encodeSecureText,
82
- decodeMatrix,
83
- decryptDecoded
84
- } from "quadqr-js";
85
-
86
- const code = await encodeSecureText("Private payload", {
87
- ecc: "M",
88
- security: {
89
- mode: "password",
90
- password: "correct horse battery staple"
91
- }
92
- });
93
-
94
- const locked = decodeMatrix(code.matrix);
95
-
96
- const unlocked = await decryptDecoded(locked, {
97
- password: "correct horse battery staple"
98
- });
99
-
100
- console.log(unlocked.text);
101
- ```
102
-
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.
108
-
109
- ```js
110
- import {
111
- encodeSecureText,
112
- generateRaw256Key
113
- } from "quadqr-js";
114
-
115
- const key = generateRaw256Key();
116
-
117
- const code = await encodeSecureText("Application-managed secret", {
118
- security: {
119
- mode: "raw-key",
120
- key
121
- }
122
- });
123
- ```
124
-
125
- The key must be exactly 32 bytes. Never embed the secret key inside the same QuadQR payload.
126
-
127
- ## Generate and scan PNG files in Node.js
128
-
129
- ```js
130
- import { encodeText } from "quadqr-js";
131
- import { savePNG, scanFile } from "quadqr-js/node";
132
-
133
- const code = encodeText("Generated on Node.js");
134
-
135
- await savePNG(code, "quadqr.png", {
136
- moduleSize: 12,
137
- quietZone: 4
138
- });
139
-
140
- const result = await scanFile("quadqr.png");
141
- console.log(result.text);
142
- ```
143
-
144
- PNG generation and decoding are built into the Node.js adapter.
145
-
146
- ## Use a script tag
147
-
148
- ```html
149
- <canvas id="qr"></canvas>
150
- <script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.0.0/dist/quadqr.min.js"></script>
151
- <script>
152
- const code = QuadQR.encodeText("No build step");
153
- QuadQR.renderToCanvas(code, document.querySelector("#qr"));
154
- </script>
155
- ```
156
-
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.
1
+ # Getting Started
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install quadqr-js
7
+ ```
8
+
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
+
11
+ ## Encode and decode text
12
+
13
+ ```js
14
+ import { encodeText, decodeMatrix } from "quadqr-js";
15
+
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
+ ```
42
+
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);
54
+ ```
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
+ cameraFinderRecoveryEvery: 2,
66
+ onResult(result) {
67
+ console.log(result);
68
+ scanner.stop();
69
+ }
70
+ }
71
+ );
72
+ ```
73
+
74
+ Camera access requires HTTPS or localhost. Finder detection uses a QuadQR-specific RGB value pass first, then throttled threshold recovery when the fast pass cannot lock onto all three finder patterns.
75
+
76
+ ## Secure password mode
77
+
78
+ Secure payloads are optional. Password mode is the simplest choice when a person will provide the secret during decryption.
79
+
80
+ ```js
81
+ import {
82
+ encodeSecureText,
83
+ decodeMatrix,
84
+ decryptDecoded
85
+ } from "quadqr-js";
86
+
87
+ const code = await encodeSecureText("Private payload", {
88
+ ecc: "M",
89
+ security: {
90
+ mode: "password",
91
+ password: "correct horse battery staple"
92
+ }
93
+ });
94
+
95
+ const locked = decodeMatrix(code.matrix);
96
+
97
+ const unlocked = await decryptDecoded(locked, {
98
+ password: "correct horse battery staple"
99
+ });
100
+
101
+ console.log(unlocked.text);
102
+ ```
103
+
104
+ A secure image or camera scan follows the same pattern: scanning returns a locked result, then `decryptDecoded()` reveals plaintext only after successful authentication.
105
+
106
+ ## Secure raw-key mode
107
+
108
+ Use raw-key mode when an application already manages its own cryptographic keys.
109
+
110
+ ```js
111
+ import {
112
+ encodeSecureText,
113
+ generateRaw256Key
114
+ } from "quadqr-js";
115
+
116
+ const key = generateRaw256Key();
117
+
118
+ const code = await encodeSecureText("Application-managed secret", {
119
+ security: {
120
+ mode: "raw-key",
121
+ key
122
+ }
123
+ });
124
+ ```
125
+
126
+ The key must be exactly 32 bytes. Never embed the secret key inside the same QuadQR payload.
127
+
128
+ ## Generate and scan PNG files in Node.js
129
+
130
+ ```js
131
+ import { encodeText } from "quadqr-js";
132
+ import { savePNG, scanFile } from "quadqr-js/node";
133
+
134
+ const code = encodeText("Generated on Node.js");
135
+
136
+ await savePNG(code, "quadqr.png", {
137
+ moduleSize: 12,
138
+ quietZone: 4
139
+ });
140
+
141
+ const result = await scanFile("quadqr.png");
142
+ console.log(result.text);
143
+ ```
144
+
145
+ PNG generation and decoding are built into the Node.js adapter.
146
+
147
+ ## Use a script tag
148
+
149
+ ```html
150
+ <canvas id="qr"></canvas>
151
+ <script src="https://cdn.jsdelivr.net/npm/quadqr-js@1.0.1/dist/quadqr.min.js"></script>
152
+ <script>
153
+ const code = QuadQR.encodeText("No build step");
154
+ QuadQR.renderToCanvas(code, document.querySelector("#qr"));
155
+ </script>
156
+ ```
157
+
158
+ Pin an exact package version in production.
159
+
160
+ ## Use the CLI
161
+
162
+ ```bash
163
+ npx quadqr-js encode "Hello QuadQR" -o hello.png
164
+ npx quadqr-js decode hello.png
165
+ ```
166
+
167
+ Password-protected CLI workflow:
168
+
169
+ ```bash
170
+ npx quadqr-js encode "Private data" --password "my-password" -o secure.png
171
+ npx quadqr-js decode secure.png --password "my-password"
172
+ ```
173
+
174
+ See [CLI.md](./CLI.md) for the full command reference.