jxl-rs-polyfill 0.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/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2024, JXL-RS Contributors
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # jxl-rs-polyfill
2
+
3
+ JPEG XL (JXL) polyfill for browsers without native support. Decodes JXL images to PNG using WebAssembly, powered by [jxl-rs](https://github.com/libjxl/jxl-rs).
4
+
5
+ ## Features
6
+
7
+ - **Zero-config CDN usage** - Just add a script tag
8
+ - **npm package** - Full control with TypeScript support
9
+ - **Automatic detection** - Skips polyfill if browser has native JXL support
10
+ - **Comprehensive coverage** - Handles `<img>`, CSS backgrounds, `<picture>`, SVG images
11
+ - **Small footprint** - ~540KB gzipped WASM module
12
+ - **Caching** - Decoded images are cached for performance
13
+
14
+ ## Quick Start
15
+
16
+ ### CDN (Zero Config)
17
+
18
+ Add this single line to your HTML - that's it!
19
+
20
+ ```html
21
+ <script src="https://cdn.jsdelivr.net/npm/jxl-rs-polyfill/dist/auto.js"></script>
22
+ ```
23
+
24
+ Then use JXL images normally:
25
+
26
+ ```html
27
+ <img src="photo.jxl" alt="My photo">
28
+ ```
29
+
30
+ ### npm Package
31
+
32
+ ```bash
33
+ npm install jxl-rs-polyfill
34
+ ```
35
+
36
+ ```javascript
37
+ import { JXLPolyfill } from 'jxl-rs-polyfill';
38
+
39
+ const polyfill = new JXLPolyfill();
40
+ await polyfill.start();
41
+ ```
42
+
43
+ ## Usage Examples
44
+
45
+ ### Basic HTML
46
+
47
+ ```html
48
+ <!DOCTYPE html>
49
+ <html>
50
+ <head>
51
+ <script src="https://cdn.jsdelivr.net/npm/jxl-rs-polyfill/dist/auto.js"></script>
52
+ </head>
53
+ <body>
54
+ <!-- These just work! -->
55
+ <img src="photo.jxl" alt="Photo">
56
+
57
+ <div style="background-image: url('background.jxl')"></div>
58
+
59
+ <picture>
60
+ <source srcset="image.jxl" type="image/jxl">
61
+ <img src="fallback.png" alt="Fallback">
62
+ </picture>
63
+
64
+ <svg>
65
+ <image href="graphic.jxl" width="200" height="150" />
66
+ </svg>
67
+ </body>
68
+ </html>
69
+ ```
70
+
71
+ ### npm with Configuration
72
+
73
+ ```javascript
74
+ import { JXLPolyfill } from 'jxl-rs-polyfill';
75
+
76
+ const polyfill = new JXLPolyfill({
77
+ patchImageConstructor: true, // Intercept new Image()
78
+ handleCSSBackgrounds: true, // Convert background-image
79
+ handleSourceElements: true, // Convert <source srcset>
80
+ handleSVGElements: true, // Convert SVG <image>/<feImage>
81
+ cacheDecoded: true, // Cache converted images
82
+ showLoadingState: false, // Show loading indicator
83
+ verbose: false, // Debug logging
84
+ });
85
+
86
+ await polyfill.start();
87
+
88
+ // Get statistics
89
+ console.log(polyfill.getStats());
90
+ // { imagesConverted: 5, cacheHits: 2, cacheSize: 5 }
91
+ ```
92
+
93
+ ### Manual Decoding
94
+
95
+ ```javascript
96
+ import { decodeJxlToPng, getJxlInfo } from 'jxl-rs-polyfill';
97
+
98
+ // Decode JXL bytes to PNG
99
+ const jxlData = new Uint8Array(await file.arrayBuffer());
100
+ const pngData = await decodeJxlToPng(jxlData);
101
+
102
+ // Create blob URL for use in img.src
103
+ const blob = new Blob([pngData], { type: 'image/png' });
104
+ const url = URL.createObjectURL(blob);
105
+ document.getElementById('myImage').src = url;
106
+
107
+ // Get image info without full decode
108
+ const info = await getJxlInfo(jxlData);
109
+ console.log(info); // { width: 1920, height: 1080, numFrames: 1, hasAlpha: false }
110
+ ```
111
+
112
+ ### React
113
+
114
+ ```jsx
115
+ import { useEffect } from 'react';
116
+ import { JXLPolyfill } from 'jxl-rs-polyfill';
117
+
118
+ function App() {
119
+ useEffect(() => {
120
+ const polyfill = new JXLPolyfill();
121
+ polyfill.start();
122
+
123
+ return () => polyfill.stop();
124
+ }, []);
125
+
126
+ return <img src="photo.jxl" alt="Photo" />;
127
+ }
128
+ ```
129
+
130
+ ### Next.js
131
+
132
+ ```javascript
133
+ // pages/_app.js
134
+ import { useEffect } from 'react';
135
+
136
+ export default function App({ Component, pageProps }) {
137
+ useEffect(() => {
138
+ // Only run on client
139
+ if (typeof window !== 'undefined') {
140
+ import('jxl-rs-polyfill').then(({ JXLPolyfill }) => {
141
+ const polyfill = new JXLPolyfill();
142
+ polyfill.start();
143
+ });
144
+ }
145
+ }, []);
146
+
147
+ return <Component {...pageProps} />;
148
+ }
149
+ ```
150
+
151
+ ## API Reference
152
+
153
+ ### `JXLPolyfill` Class
154
+
155
+ | Method | Description |
156
+ |--------|-------------|
157
+ | `start()` | Start the polyfill (async) |
158
+ | `stop()` | Stop observing DOM changes |
159
+ | `getStats()` | Get conversion statistics |
160
+
161
+ ### Standalone Functions
162
+
163
+ | Function | Description |
164
+ |----------|-------------|
165
+ | `initWasm()` | Initialize the WASM module |
166
+ | `checkNativeJxlSupport()` | Check if browser has native JXL support |
167
+ | `decodeJxlToPng(data)` | Decode JXL Uint8Array to PNG Uint8Array |
168
+ | `getJxlInfo(data)` | Get image dimensions and metadata |
169
+ | `decodeJxlFromUrl(url)` | Fetch and decode JXL, returns PNG Blob |
170
+
171
+ ## CDN Links
172
+
173
+ | File | Description | Size |
174
+ |------|-------------|------|
175
+ | `auto.js` | Self-contained, auto-starting | ~1.4MB |
176
+ | `auto-lite.js` | Requires separate WASM file | ~5KB |
177
+ | `jxl-polyfill.js` | ESM module | ~8KB |
178
+ | `jxl_wasm.js` | WASM bindings | ~15KB |
179
+ | `jxl_wasm_bg.wasm` | WASM binary | ~1.4MB |
180
+
181
+ ```html
182
+ <!-- Recommended: All-in-one -->
183
+ <script src="https://cdn.jsdelivr.net/npm/jxl-rs-polyfill/dist/auto.js"></script>
184
+
185
+ <!-- Alternative: Separate files (better caching) -->
186
+ <script type="module">
187
+ import { JXLPolyfill } from 'https://cdn.jsdelivr.net/npm/jxl-rs-polyfill/dist/jxl-polyfill.js';
188
+ new JXLPolyfill().start();
189
+ </script>
190
+ ```
191
+
192
+ ## Building from Source
193
+
194
+ ### Prerequisites
195
+
196
+ - [Rust](https://rustup.rs/)
197
+ - [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
198
+ - Node.js 16+
199
+
200
+ ### Build
201
+
202
+ ```bash
203
+ # Clone this repo
204
+ git clone https://github.com/hjanuschka/jxl-rs-polyfill
205
+ cd jxl-rs-polyfill
206
+
207
+ # Install dependencies
208
+ npm install
209
+
210
+ # Build WASM from latest jxl-rs
211
+ npm run build:wasm
212
+
213
+ # Or build from local jxl-rs checkout
214
+ JXL_RS_DIR=~/jxl-rs bash scripts/build-wasm-local.sh
215
+
216
+ # Bundle everything
217
+ npm run build:bundle
218
+
219
+ # Full build (wasm + bundle)
220
+ npm run build
221
+ ```
222
+
223
+ ### Publish
224
+
225
+ ```bash
226
+ # Update version
227
+ npm version patch # or minor, major
228
+
229
+ # Build and publish
230
+ npm publish
231
+ ```
232
+
233
+ ## Browser Support
234
+
235
+ Works in all browsers with WebAssembly support:
236
+
237
+ | Browser | Version |
238
+ |---------|---------|
239
+ | Chrome | 57+ |
240
+ | Firefox | 52+ |
241
+ | Safari | 11+ |
242
+ | Edge | 79+ |
243
+
244
+ Browsers with native JXL support (the polyfill auto-detects and skips):
245
+ - Safari 17+ (macOS/iOS)
246
+ - Chrome 116+ (with flag, 117+ by default planned)
247
+
248
+ ## License
249
+
250
+ BSD-3-Clause (same as jxl-rs)
251
+
252
+ ## Credits
253
+
254
+ - [jxl-rs](https://github.com/libjxl/jxl-rs) - The Rust JXL decoder
255
+ - [libjxl](https://github.com/libjxl/libjxl) - Reference JXL implementation
package/dist/.gitkeep ADDED
File without changes
package/dist/auto.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Auto-initializing JXL Polyfill
3
+ *
4
+ * This module automatically starts the polyfill when loaded.
5
+ * No configuration needed - just include the script.
6
+ *
7
+ * @example
8
+ * <script src="https://cdn.jsdelivr.net/npm/jxl-rs-polyfill/dist/auto.js"></script>
9
+ */
10
+
11
+ declare global {
12
+ interface Window {
13
+ JXLPolyfill: {
14
+ /**
15
+ * Manually start the polyfill (automatically called on load)
16
+ */
17
+ start(): Promise<void>;
18
+
19
+ /**
20
+ * Process all current elements
21
+ */
22
+ processAll(): void;
23
+
24
+ /**
25
+ * Get polyfill statistics
26
+ */
27
+ getStats(): {
28
+ imagesConverted: number;
29
+ cacheHits: number;
30
+ cacheSize: number;
31
+ };
32
+ };
33
+ }
34
+ }
35
+
36
+ export {};