38 lines
2.0 KiB
Markdown
38 lines
2.0 KiB
Markdown
# Capability Spec: compress-image
|
|
|
|
**Package**: `@suaveplan/compress-image`
|
|
**Version**: 0.0.0 (genesis)
|
|
**Status**: ADDED
|
|
|
|
---
|
|
|
|
## ADDED Requirements
|
|
|
|
### CI-01 — Format coverage
|
|
|
|
`VALID_FORMATS` MUST include `'jpeg' | 'png' | 'webp' | 'avif'`. Each format MUST have a working adapter invoked by the dispatcher.
|
|
|
|
### CI-02 — Compression API
|
|
|
|
`ImageCompressor.compress(input, options?)` MUST accept `Uint8Array | ArrayBuffer | Blob`, resolve options to a `ResolvedCompressionOptions`, build a `CompressionPlan`, and execute it to produce `CompressionResult { format, bytes, width, height, durationMs, steps: CompressionStep[], inputBytes, outputBytes, savedBytes }`.
|
|
|
|
### CI-03 — Quality presets
|
|
|
|
`QUALITY_PRESETS` MUST define `'maximum' | 'high' | 'balanced' | 'fast' | 'aggressive'` with deterministic per-format quality values obeying `FORMAT_QUALITY_RANGES`. Custom `options.quality` numeric values outside the format range MUST throw `COMPRESS_IMAGE.INVALID_QUALITY`.
|
|
|
|
### CI-04 — Max dimension
|
|
|
|
`options.maxDimension` MUST resize the longest side to at most the given pixel count. A resize step MUST appear in `CompressionPlan.steps`. Inputs exceeding `MAX_DIMENSION` (default 20 000) MUST throw `COMPRESS_IMAGE.DIMENSION_TOO_LARGE`.
|
|
|
|
### CI-05 — Degenerate output
|
|
|
|
If `outputBytes > inputBytes` and `options.preserveSmaller` is `true` (default), the compressor MUST return the original input with a `CompressionStep { action: 'skip', reason: 'output-larger-than-input' }`. Otherwise the larger compressed output is returned.
|
|
|
|
### CI-06 — Format selection
|
|
|
|
When `options.format` is omitted, the compressor MUST keep the input format. `options.format: 'auto'` MUST choose based on input type (`jpeg` → `webp` at lower size if supported; `png` with alpha → `webp`/`avif`; etc.).
|
|
|
|
### CI-07 — Observability
|
|
|
|
Every compress call MUST record `compress_image.compress.duration_ms{format, preset}`, `compress_image.compress.total{format, outcome}`, and `compress_image.bytes.saved{format}` gauge.
|