@squoosh-kit/wp2 0.2.1 → 0.2.3

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.
Files changed (2) hide show
  1. package/README.md +269 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,269 @@
1
+ # @squoosh-kit/wp2
2
+
3
+ [![npm version](https://badge.fury.io/js/%40squoosh-kit%2Fwp2.svg)](https://badge.fury.io/js/%40squoosh-kit%2Fwp2)
4
+ [![Bun](https://img.shields.io/badge/Bun-000000?logo=bun&logoColor=white)](https://bun.sh/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
+
8
+ ![Squoosh-Kit](https://github.com/bnowak008/squoosh-kit/blob/main/squoosh-kit-banner.webp)
9
+
10
+ ## Squoosh-Kit
11
+
12
+ Squoosh-Kit is built on a simple idea: provide a lightweight and modular bridge to the powerful, production-tested codecs from Google's Squoosh project. This package (`@squoosh-kit/wp2`) is one of those modules.
13
+
14
+ **Directly from the Source**
15
+ We don't modify the core WP2 codec. The WebAssembly (`.wasm`) binary is taken directly from the official Squoosh repository builds. This means you get the exact same performance, quality, and reliability you'd expect from Squoosh.
16
+
17
+ **A Thin, Modern Wrapper**
18
+ Our goal is to provide a minimal, modern JavaScript wrapper around the codec. We handle the tricky parts—like loading WASM, managing web workers, and providing a clean, type-safe API—so you can focus on your application. The library is designed to be a thin bridge, not a heavy framework.
19
+
20
+ **Modular by Design**
21
+ We believe you should only install what you need. As a standalone package, `@squoosh-kit/wp2` allows you to add WP2 encoding and decoding to your project without pulling in other unrelated image processing tools.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ bun add @squoosh-kit/wp2
27
+ # or
28
+ npm install @squoosh-kit/wp2
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```typescript
34
+ import {
35
+ encode,
36
+ decode,
37
+ createWp2Encoder,
38
+ UVMode,
39
+ Csp,
40
+ } from '@squoosh-kit/wp2';
41
+ import type { ImageInput, Wp2EncodeOptions } from '@squoosh-kit/wp2';
42
+
43
+ const imageData: ImageInput = {
44
+ data: imageBuffer,
45
+ width: 1920,
46
+ height: 1080,
47
+ };
48
+
49
+ // Encode with default settings
50
+ const wp2Buffer = await encode(imageData, { quality: 75 });
51
+
52
+ // Decode WP2 back to raw pixel data
53
+ const rawImage = await decode(wp2Buffer);
54
+
55
+ // With cancellation support
56
+ const controller = new AbortController();
57
+ const wp2 = await encode(
58
+ imageData,
59
+ { quality: 75, effort: 5 },
60
+ controller.signal
61
+ );
62
+
63
+ // For multiple images, create a persistent encoder
64
+ const encoder = createWp2Encoder('worker');
65
+ const result = await encoder(imageData, { quality: 80 });
66
+ await encoder.terminate();
67
+ ```
68
+
69
+ ## What is WP2?
70
+
71
+ WP2 (WebP 2) is an experimental successor to WebP developed by Google. It offers improved compression compared to WebP at the cost of browser compatibility — WP2 has no native browser support and is primarily used for research and experimentation.
72
+
73
+ WP2 is included in Squoosh-Kit to match the feature set of the Squoosh tool. For production web delivery, consider `@squoosh-kit/webp`, `@squoosh-kit/avif`, or `@squoosh-kit/jxl` instead.
74
+
75
+ ## Public API
76
+
77
+ Only the following exports are part of the public API and guaranteed to be stable across versions:
78
+
79
+ - `encode(imageData, options?, signal?)` - Encode an image to WP2 format
80
+ - `decode(data, signal?)` - Decode a WP2 file to raw pixel data
81
+ - `createWp2Encoder(mode?)` - Create a reusable encoder function
82
+ - `createWp2Decoder(mode?)` - Create a reusable decoder function
83
+ - `UVMode` - Chroma subsampling mode enum
84
+ - `Csp` - Color space enum
85
+ - `ImageInput` type - Input image data structure
86
+ - `Wp2EncodeOptions` type - WP2 encoding configuration
87
+ - `Wp2EncoderFactory` type - Type for reusable encoder functions
88
+ - `Wp2DecoderFactory` type - Type for reusable decoder functions
89
+
90
+ ## Real-World Examples
91
+
92
+ **Encode with default settings**
93
+
94
+ ```typescript
95
+ const controller = new AbortController();
96
+ setTimeout(() => controller.abort(), 30000);
97
+
98
+ try {
99
+ const wp2 = await encode(
100
+ imageData,
101
+ { quality: 75, effort: 4 },
102
+ controller.signal
103
+ );
104
+ await saveToStorage('image.wp2', wp2);
105
+ } catch (error) {
106
+ if (error.name === 'AbortError') {
107
+ console.log('Encoding timed out');
108
+ }
109
+ }
110
+ ```
111
+
112
+ **Batch encoding with a persistent encoder**
113
+
114
+ ```typescript
115
+ const encoder = createWp2Encoder('client');
116
+
117
+ for (const imagePath of imageFiles) {
118
+ const imageData = await loadImage(imagePath);
119
+ const wp2Data = await encoder(imageData, { quality: 70, effort: 5 });
120
+ await writeFile(`${imagePath}.wp2`, wp2Data);
121
+ }
122
+
123
+ await encoder.terminate();
124
+ ```
125
+
126
+ ## API Reference
127
+
128
+ ### `encode(imageData, options?, signal?)`
129
+
130
+ Encodes raw RGBA pixel data to WP2 format.
131
+
132
+ **Note**: `encode()` uses a global singleton worker. For long-running applications where worker cleanup is important, use `createWp2Encoder()` instead.
133
+
134
+ - `imageData` - `ImageInput` object with your pixel data
135
+ - `options` - (optional) `Wp2EncodeOptions` for quality and compression settings
136
+ - `signal` - (optional) `AbortSignal` to cancel the operation
137
+ - **Returns** - `Promise<Uint8Array>` with the encoded WP2 data
138
+
139
+ ### `decode(data, signal?)`
140
+
141
+ Decodes a WP2 file back to raw RGBA pixel data.
142
+
143
+ - `data` - `BufferSource` containing the WP2 file bytes
144
+ - `signal` - (optional) `AbortSignal` to cancel the operation
145
+ - **Returns** - `Promise<ImageData>` with decoded pixel data, width, and height
146
+
147
+ ### `createWp2Encoder(mode?)`
148
+
149
+ Creates a reusable encoder. More efficient for processing multiple images.
150
+
151
+ - `mode` - (optional) `'worker'` or `'client'`, defaults to `'worker'`
152
+ - **Returns** - A function with the same signature as `encode()`
153
+
154
+ ### `createWp2Decoder(mode?)`
155
+
156
+ Creates a reusable decoder.
157
+
158
+ - `mode` - (optional) `'worker'` or `'client'`, defaults to `'worker'`
159
+ - **Returns** - A function with the same signature as `decode()`
160
+
161
+ ## Cancellation Support
162
+
163
+ To cancel an encoding operation in progress, pass an `AbortSignal`:
164
+
165
+ ```typescript
166
+ const controller = new AbortController();
167
+
168
+ const encodePromise = encode(imageData, { quality: 75 }, controller.signal);
169
+ setTimeout(() => controller.abort(), 10000);
170
+
171
+ try {
172
+ const result = await encodePromise;
173
+ } catch (error) {
174
+ if (error.name === 'AbortError') {
175
+ console.log('Encoding was cancelled');
176
+ }
177
+ }
178
+ ```
179
+
180
+ ## Input Validation
181
+
182
+ All inputs are automatically validated before processing:
183
+
184
+ ```typescript
185
+ // Will throw TypeError: image must be an object
186
+ await encode(null, { quality: 75 });
187
+
188
+ // Will throw TypeError: image.data must be Uint8Array or Uint8ClampedArray
189
+ await encode({ data: [0, 0, 0, 255], width: 32, height: 32 }, { quality: 75 });
190
+
191
+ // Will throw RangeError: image.data too small
192
+ await encode(
193
+ { data: new Uint8Array(100), width: 800, height: 600 },
194
+ { quality: 75 }
195
+ );
196
+ ```
197
+
198
+ ### Package Size
199
+
200
+ **Size breakdown:**
201
+
202
+ - JavaScript code: ~5-8KB gzipped
203
+ - TypeScript definitions: ~3KB
204
+ - WASM binaries: ~50-70KB gzipped (multi-threaded and SIMD variants included)
205
+
206
+ ### Worker Cleanup
207
+
208
+ When using worker mode, always clean up when done:
209
+
210
+ ```typescript
211
+ const encoder = createWp2Encoder('worker');
212
+
213
+ try {
214
+ const wp2Data = await encoder(imageData, { quality: 75 });
215
+ } finally {
216
+ await encoder.terminate();
217
+ }
218
+ ```
219
+
220
+ **Note**: In client mode, `terminate()` is a no-op. It's always safe to call for consistency.
221
+
222
+ ### `Wp2EncodeOptions`
223
+
224
+ ```typescript
225
+ type Wp2EncodeOptions = {
226
+ quality?: number; // 0–100, visual quality (default: 75)
227
+ alpha_quality?: number; // 0–100, alpha channel quality (default: 75)
228
+ effort?: number; // 0–9, encoding effort (default: 5, lower = faster)
229
+ pass?: number; // 1–10, number of encoding passes (default: 1)
230
+ sns?: number; // 0–100, spatial noise shaping (default: 50)
231
+ uv_mode?: UVMode; // Chroma subsampling mode (default: UVModeAdapt)
232
+ csp_type?: Csp; // Color space (default: kYCoCg)
233
+ error_diffusion?: number; // 0–100, error diffusion strength (default: 0)
234
+ use_random_matrix?: boolean; // Use random matrix for encoding (default: false)
235
+ };
236
+ ```
237
+
238
+ **Key options:**
239
+
240
+ - `quality` — Primary quality control. `75` is a good default.
241
+ - `effort` — Encoding effort. `0` = fastest; `9` = best compression. `5` is a practical default.
242
+ - `uv_mode` — Chroma subsampling:
243
+ - `UVMode.UVModeAdapt` — Mix of 4:2:0 and 4:4:4 per block (default)
244
+ - `UVMode.UVMode420` — All blocks 4:2:0 (smaller files, less color detail)
245
+ - `UVMode.UVMode444` — All blocks 4:4:4 (larger files, best color)
246
+ - `UVMode.UVModeAuto` — Automatically choose
247
+ - `csp_type` — Color space conversion:
248
+ - `Csp.kYCoCg` — YCoCg (default, generally best for WP2)
249
+ - `Csp.kYCbCr` — Standard YCbCr
250
+ - `Csp.kCustom` — Custom color space
251
+ - `Csp.kYIQ` — YIQ color space
252
+
253
+ ## Performance Tips
254
+
255
+ - **WP2 is experimental** — For production use, prefer WebP, AVIF, or JXL which have browser support
256
+ - **Use workers for UI apps** — Encoding at high effort levels can be slow
257
+ - **Effort 4–6 is practical** — Good compression without excessive encoding time
258
+ - **Batch with persistent encoders** — Amortizes WASM initialization across multiple encodes
259
+
260
+ ## Works With
261
+
262
+ - **Bun** - First-class support, fastest performance
263
+ - **Node.js** - Works great in server environments
264
+ - **Browsers** - Full Web Worker support for responsive UIs
265
+ - **TypeScript** - Complete type definitions included
266
+
267
+ ## License
268
+
269
+ MIT - use it freely in your projects
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squoosh-kit/wp2",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "WP2 codec for squoosh-kit, providing encoding and decoding functionality.",
6
6
  "author": "Bartosz Nowak <bnowak008@gmail.com>",
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/bnowak008/squoosh-kit.git",
11
11
  "directory": "packages/wp2"
12
12
  },
13
- "homepage": "https://github.com/bnowak008/squoosh-kit/tree/main/packages/wp2#readme",
13
+ "homepage": "http://squoosh-kit.dev",
14
14
  "publishConfig": {
15
15
  "access": "public",
16
16
  "registry": "https://registry.npmjs.org/"