Files
2026-05-27 23:29:53 +01:00

4.7 KiB

Migrate @suaveplan/image to genesis

Package: @suaveplan/image Status: PROPOSED Type: spec-conformance

Why

@suaveplan/image exists upstream (../suaveplan/packages/universal/image) but has not been migrated to genesis. It provides image format detection, metadata extraction, resize math, crop validation, and transform pipeline planning — primitives consumed by compress-image and downstream UI packages. Migrating it unblocks full enterprise-quality parity and brings the package into compliance with genesis conventions: defineCodes, Zod boundaries, OTel instrumentation, explicit barrels, and 100% coverage.

What changes

  • ADDED: IMAGE_CODES — stable defineCodes("IMAGE", [...]) registry replacing upstream ErrorCodes.registerMany side effect.
  • ADDED: ImageError — extends SuaveplanError<ImageCode> with typed ImageErrorContext.
  • ADDED: Zod schemas for every public boundary (ImageProcessorConfigSchema, CropRegionSchema, ResizeOptionsSchema, TransformOpSchema, TransformPipelineSchema, ImageMetadataSchema).
  • ADDED: OTel counters (image.metadata.extracted_total, image.transform.planned_total) and histograms (image.metadata.extract_duration_ms, image.transform.plan_duration_ms) emitted from production paths.
  • ADDED: ImageProcessor spans for extractMetadata and planTransform.
  • ADDED: AbortSignal support on extractMetadata and planTransform (pre-abort short-circuit).
  • MODIFIED: ImageProcessor constructor now validates config via Zod and accepts optional tracer / meter from @opentelemetry/api.
  • MODIFIED: PipelineBuilder quality setter now clamps to [1, 100] and throws IMAGE_CODES.DIMENSIONS_INVALID on bad input.
  • REMOVED: Side-effect import import "./error-codes.js" — package is now sideEffects: false.
  • REMOVED: @deprecated JSDoc aliases (unknownFormat, invalidDimensions, invalidCrop, metadataParseFailed, invalidTransform) — replaced by prose-only backward-compat re-exports.

Out of scope

  • Actual pixel buffer encoding/decoding — compress-image and exif already cover compression and metadata I/O. This package remains a metadata + transform-planning library.
  • Browser-specific APIs (HTMLImageElement, CanvasRenderingContext2D) — the package is universal-tier.
  • Network fetch helpers — callers supply Uint8Array directly.

Source mapping

This change derives from ../suaveplan/enterprise/image.md.

Requirement Source lines Notes
Zero browser / Node / React dependencies L37 verbatim
Zod schemas for public types L38-L39 extended: wired at every boundary
OpenTelemetry instrumentation L41-L42 extended: counters + histograms + spans
Structured errors via @suaveplan/error L42 extended: defineCodes + SuaveplanError
AbortSignal propagation L43 extended: pre-abort on sync entrypoints
Test coverage ≥ 95% L50 extended: genesis requires 100%
No mocks L53 verbatim
sideEffects: false L55 verbatim
Biome clean L58 verbatim
Error hierarchy L61 verbatim

Requirements with no source line

Requirement Justification
Explicit named barrel exports (no export *) Genesis-wide policy per openspec/AGENTS.md §6a
Test imports from @suaveplan/testing/runner Genesis-wide policy per openspec/AGENTS.md §7
Sibling .md for every .ts Genesis-wide docs policy per openspec/AGENTS.md §4
Subpath exports per feature module Genesis-wide tree-shaking policy per openspec/AGENTS.md §6

Verification approach

  • src/error-codes/error-codes.test.ts — covers code registry, type assertions.
  • src/errors/errors.test.ts — covers ImageError construction, context, cause, legacy alias round-trips.
  • src/types/image-types.test.ts — covers format detection, aspect ratio, resize math, crop validation, MIME mapping.
  • src/processor/processor.test.ts — covers metadata extraction, dimension parsing, size limits, transform planning, pipeline builder chaining, event emission.
  • src/processor/processor.spec-conformance.test.ts — pins OTel instrument emission, Zod boundary rejection, strict-mode behaviors, AbortSignal pre-abort.
  • tests/dep-graph.test.ts — pins zero non-catalog external deps.
  • tests/tree-shake.test.ts — pins sideEffects: false.

Migration impact

@suaveplan/image has zero current consumers in genesis (it does not yet exist). Downstream packages that will consume it (compress-image, future react-image) will adopt the new API in follow-up changes. No existing code is affected.

Impact

Affected dependents

No dependents (verified by bunx turbo ls --filter=...@suaveplan/image — package does not exist on disk yet).