5.6 KiB
5.6 KiB
id, name, library, description
| id | name | library | description |
|---|---|---|---|
| sp-compress-image | Compress Image | @suaveplan/compress-image | Runtime-agnostic image compression utilities with pluggable adapters. Supports resize, quality reduction, format conversion (JPEG, PNG, WebP, AVIF), and metadata stripping. Core is pure TypeScript; Sharp adapter requires the native `sharp` library. |
@suaveplan/compress-image
Architecture
| Module | Role | Key exports |
|---|---|---|
| Compressor | Orchestrator + validation + OTel | ImageCompressor, createCompressor(adapter?) |
| Sharp Adapter | Production Node.js adapter | SharpAdapter — wraps sharp library |
| Memory Adapter | Test / no-op adapter | MemoryAdapter — passthrough with format detection |
| Schemas | Zod validation | CompressOptionsSchema |
| Types | TypeScript contracts | ImageAdapter, CompressOptions, CompressResult, ImageInfo |
| Utils | Pure helpers | detectFormat, parseJpegDimensions, parsePngDimensions, validateDimensions |
| Errors | Typed errors | CompressImageError, COMPRESS_IMAGE_CODES |
File Structure
src/
├── index.ts # Public barrel
├── core/
│ └── compressor/
│ └── compressor.ts # ImageCompressor, createCompressor()
├── adapters/
│ ├── sharp/
│ │ └── sharp.ts # SharpAdapter (production)
│ └── memory/
│ └── memory.ts # MemoryAdapter (testing)
├── schemas/
│ └── compress-options.schema.ts # Zod schema for options
├── types/
│ └── compress-image.types.ts # TypeScript interfaces
├── utils/
│ └── image-utils.ts # detectFormat, validateDimensions
└── errors/
└── compress-image-error.ts # CompressImageError, COMPRESS_IMAGE_CODES
Patterns
Basic — Compress with Sharp adapter
import { createCompressor } from "@suaveplan/compress-image/compressor";
import { SharpAdapter } from "@suaveplan/compress-image/adapters/sharp";
import sharp from "sharp";
const compressor = createCompressor(new SharpAdapter(sharp));
const result = await compressor.compress(imageBuffer, {
format: "webp",
quality: 75,
width: 1280,
height: 720,
resizeMode: "cover",
stripMetadata: true,
});
console.log(result.compressionRatio, result.compressedSize);
Basic — Compress only if larger than threshold
const result = await compressor.compressIfLarger(imageBuffer, 500_000, {
format: "jpeg",
quality: 80,
});
// If input ≤ 500KB: returns original with ratio = 1
// If input > 500KB: compresses and returns compressed data
Basic — Extract metadata
const info = await compressor.getInfo(imageBuffer);
console.log(info.format, info.width, info.height, info.size);
Basic — Resize
const resized = await compressor.resize(imageBuffer, 400, 300, "contain");
// Returns Uint8Array of resized image
Advanced — Swap adapter at runtime
const compressor = createCompressor(new MemoryAdapter());
// Later, swap to Sharp for production
compressor.setAdapter(new SharpAdapter(sharp));
Advanced — Write a custom adapter
import type { ImageAdapter, CompressOptions, CompressResult } from "@suaveplan/compress-image";
class MyAdapter implements ImageAdapter {
async compress(input: Uint8Array, options: CompressOptions): Promise<CompressResult> {
// … implementation …
}
async getInfo(input: Uint8Array): Promise<ImageInfo> {
// … implementation …
}
async resize(input: Uint8Array, w: number, h: number, mode?: ResizeMode): Promise<Uint8Array> {
// … implementation …
}
}
Constraints
- Adapter pattern: core is pure TypeScript; actual image processing delegated to pluggable
ImageAdapter. - Sharp is optional: only required when using
SharpAdapter. Package has zero direct dependency onsharp. - Zod validation: all options validated before adapter call; invalid options throw
CompressImageError(INVALID_OPTIONS). - Dimension limits: width/height must be 1–32767 inclusive.
- Quality range: 1–100 inclusive, integer only.
- Effort range: 0–6 inclusive (Sharp-specific encoding effort).
- Supported formats:
jpeg,png,webp,avif. - Resize modes:
cover,contain,fill,inside,outside. - OTel:
compress_image.compress.total(counter),compress_image.compress.duration_ms(histogram). - Error codes:
COMPRESS_IMAGE.UNSUPPORTED_FORMAT,COMPRESS_IMAGE.COMPRESS_FAILED,COMPRESS_IMAGE.INVALID_OPTIONS,COMPRESS_IMAGE.ADAPTER_NOT_SET. - MemoryAdapter: safe for tests; detects format and returns passthrough data with synthetic metadata.
Subpath Exports
| Export | Path |
|---|---|
| Main | @suaveplan/compress-image |
| Compressor | @suaveplan/compress-image/compressor |
| Sharp Adapter | @suaveplan/compress-image/adapters/sharp |
| Memory Adapter | @suaveplan/compress-image/adapters/memory |
| Errors | @suaveplan/compress-image/errors |
Checklist
- Need to compress images →
compressor.compress(input, options) - Need conditional compression →
compressor.compressIfLarger(input, maxBytes, options) - Need to resize →
compressor.resize(input, width, height, mode) - Need metadata extraction →
compressor.getInfo(input) - Need Sharp integration →
new SharpAdapter(sharp) - Need test adapter →
new MemoryAdapter() - Need custom adapter → implement
ImageAdapterinterface - Need Zod option validation →
CompressOptionsSchema - Need typed errors →
CompressImageError,COMPRESS_IMAGE_CODES