@squoosh-kit/rotate 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 +203 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # @squoosh-kit/rotate
2
+
3
+ [![npm version](https://badge.fury.io/js/%40squoosh-kit%2Frotate.svg)](https://badge.fury.io/js/%40squoosh-kit%2Frotate)
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/rotate`) is one of those modules.
13
+
14
+ **Directly from the Source**
15
+ We don't modify the core rotation 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/rotate` allows you to add WASM-powered image rotation to your project without pulling in other unrelated image processing tools.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ bun add @squoosh-kit/rotate
27
+ # or
28
+ npm install @squoosh-kit/rotate
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```typescript
34
+ import { rotate, createRotator } from '@squoosh-kit/rotate';
35
+ import type { ImageInput } from '@squoosh-kit/rotate';
36
+
37
+ const imageData: ImageInput = {
38
+ data: imageBuffer,
39
+ width: 1920,
40
+ height: 1080,
41
+ };
42
+
43
+ // Rotate 90 degrees clockwise
44
+ const rotated = await rotate(imageData, { rotate: 90 });
45
+ // rotated.width === 1080, rotated.height === 1920
46
+
47
+ // For multiple images, use a persistent rotator
48
+ const rotator = createRotator('worker');
49
+ const result = await rotator(imageData, { rotate: 270 });
50
+ await rotator.terminate();
51
+ ```
52
+
53
+ ## Public API
54
+
55
+ Only the following exports are part of the public API and guaranteed to be stable across versions:
56
+
57
+ - `rotate(image, options?, signal?)` - Rotate an image by a multiple of 90 degrees
58
+ - `createRotator(mode?)` - Create a reusable rotator function
59
+ - `ImageInput` type - Input/output image data structure
60
+ - `RotateOptions` type - Rotation configuration
61
+ - `RotatorFactory` type - Type for reusable rotator functions
62
+
63
+ ## Real-World Examples
64
+
65
+ **EXIF orientation correction**
66
+
67
+ ```typescript
68
+ // Many cameras store images sideways and use EXIF orientation to indicate rotation.
69
+ // Use this package to apply that rotation explicitly.
70
+
71
+ const exifRotation = getExifRotation(imageFile); // your EXIF reader
72
+ const corrected = await rotate(imageData, {
73
+ rotate: exifRotation as 0 | 90 | 180 | 270,
74
+ });
75
+ ```
76
+
77
+ **Pipeline with cancellation**
78
+
79
+ ```typescript
80
+ const controller = new AbortController();
81
+ const timeout = setTimeout(() => controller.abort(), 10000);
82
+
83
+ try {
84
+ const rotated = await rotate(imageData, { rotate: 90 }, controller.signal);
85
+ // Continue processing rotated image...
86
+ } catch (error) {
87
+ if (error.name === 'AbortError') {
88
+ console.log('Rotation cancelled');
89
+ }
90
+ } finally {
91
+ clearTimeout(timeout);
92
+ }
93
+ ```
94
+
95
+ ## API Reference
96
+
97
+ ### `rotate(image, options?, signal?)`
98
+
99
+ Rotates raw RGBA pixel data by the specified angle. The returned image has swapped dimensions for 90° and 270° rotations.
100
+
101
+ - `image` - `ImageInput` object with your pixel data
102
+ - `options` - (optional) `RotateOptions` — defaults to `{ rotate: 0 }`
103
+ - `signal` - (optional) `AbortSignal` to cancel the operation
104
+ - **Returns** - `Promise<ImageInput>` with rotated pixel data and updated dimensions
105
+
106
+ **Note**: `rotate()` uses a global singleton worker that is never automatically terminated. For long-running applications where worker cleanup is important, use `createRotator()` instead.
107
+
108
+ ### `createRotator(mode?)`
109
+
110
+ Creates a reusable rotator. More efficient for processing multiple images.
111
+
112
+ - `mode` - (optional) `'worker'` or `'client'`, defaults to `'worker'`
113
+ - **Returns** - A function with the same signature as `rotate()`
114
+
115
+ ## Cancellation Support
116
+
117
+ To cancel a rotation in progress, pass an `AbortSignal`:
118
+
119
+ ```typescript
120
+ const controller = new AbortController();
121
+
122
+ const rotatePromise = rotate(imageData, { rotate: 90 }, controller.signal);
123
+ setTimeout(() => controller.abort(), 5000);
124
+
125
+ try {
126
+ const result = await rotatePromise;
127
+ } catch (error) {
128
+ if (error.name === 'AbortError') {
129
+ console.log('Rotation was cancelled');
130
+ }
131
+ }
132
+ ```
133
+
134
+ ## Input Validation
135
+
136
+ All inputs are automatically validated before processing:
137
+
138
+ ```typescript
139
+ // Will throw TypeError: image must be an object
140
+ await rotate(null, { rotate: 90 });
141
+
142
+ // Will throw TypeError: image.data must be Uint8Array or Uint8ClampedArray
143
+ await rotate({ data: [0, 0, 0, 255], width: 32, height: 32 }, { rotate: 90 });
144
+
145
+ // Will throw RangeError: image.data too small
146
+ await rotate(
147
+ { data: new Uint8Array(100), width: 800, height: 600 },
148
+ { rotate: 90 }
149
+ );
150
+ ```
151
+
152
+ ### Package Size
153
+
154
+ **Size breakdown:**
155
+
156
+ - JavaScript code: ~4-6KB gzipped
157
+ - TypeScript definitions: ~2KB
158
+ - WASM binary: ~10-15KB gzipped
159
+
160
+ ### Worker Cleanup
161
+
162
+ When using worker mode (`createRotator('worker')`), clean up the worker when done:
163
+
164
+ ```typescript
165
+ const rotator = createRotator('worker');
166
+
167
+ try {
168
+ const rotated = await rotator(imageData, { rotate: 180 });
169
+ } finally {
170
+ await rotator.terminate();
171
+ }
172
+ ```
173
+
174
+ ### `RotateOptions`
175
+
176
+ ```typescript
177
+ type RotateOptions = {
178
+ rotate?: 0 | 90 | 180 | 270; // Degrees clockwise (default: 0)
179
+ };
180
+ ```
181
+
182
+ - `0` — no rotation (pass-through)
183
+ - `90` — 90° clockwise (landscape → portrait; dimensions swap)
184
+ - `180` — upside down (dimensions unchanged)
185
+ - `270` — 270° clockwise / 90° counter-clockwise (portrait → landscape; dimensions swap)
186
+
187
+ ## Performance Tips
188
+
189
+ - **Use workers for UI apps** - Keeps your interface responsive
190
+ - **Use client mode for servers** - Direct processing without worker overhead
191
+ - **Batch with persistent rotators** - More efficient than one-off calls
192
+ - **Rotation is lossless** - No quality loss regardless of angle
193
+
194
+ ## Works With
195
+
196
+ - **Bun** - First-class support, fastest performance
197
+ - **Node.js** - Works great in server environments
198
+ - **Browsers** - Full Web Worker support for responsive UIs
199
+ - **TypeScript** - Complete type definitions included
200
+
201
+ ## License
202
+
203
+ MIT - use it freely in your projects
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squoosh-kit/rotate",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "description": "Image rotation codec for squoosh-kit, using raw WebAssembly (no JS glue).",
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/rotate"
12
12
  },
13
- "homepage": "https://github.com/bnowak008/squoosh-kit/tree/main/packages/rotate#readme",
13
+ "homepage": "http://squoosh-kit.dev",
14
14
  "publishConfig": {
15
15
  "access": "public",
16
16
  "registry": "https://registry.npmjs.org/"