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

5.5 KiB

Change: enterprise-media

  • Package: @suaveplan/media
  • Status: PROPOSED
  • Design: ./design.md
  • Spec delta: ./specs/media/spec.md
  • Upstream: /mnt/s/web/suaveplan/packages/universal/media (1.1.0)
  • Enterprise audit: /mnt/s/web/suaveplan/enterprise/media.md

Why

Genesis is migrating @suaveplan/media from the legacy packages/universal/media/ checkout into the canonical packages/foundation/data/media/ location alongside the already-shipped @suaveplan/mime. The upstream package shipped at 1.1.0 as a ~140-line universal-tier facade over four functions — detectMediaType (magic bytes), detectMediaTypeFromName (MIME lookup), getMetadata, and validateMedia. The enterprise audit (enterprise/media.md) flagged the gaps shared by every pre-enterprise package:

  1. Hand-rolled error strings — no @suaveplan/error integration, no stable codes, no programmatic discrimination.
  2. No Zod validation of MediaConstraints — malformed input silently passes through.
  3. No OpenTelemetry instrumentation — production cannot measure detection / metadata / validation volume, latency, or error rate.
  4. Magic-byte signatures hard-coded inside the implementation — no extension point for downstream packages to add formats like AVIF, HEIC, or M4A.
  5. No async metadata extractor hook — width / height / duration / codec extraction has to happen outside the package.
  6. No custom-predicate constraint — non-trivial business rules cannot be expressed.
  7. No throwing assert variant for guard sites.
  8. No filename-MIME refinement when both bytes and filename are available.
  9. No signatureLabel surfacing — consumers cannot route on the exact matched format.

The greenfield rewrite addresses every gap while preserving every upstream public symbol so downstream consumers continue to compile against the same import paths.

What changes

  • Add: @suaveplan/media at version 0.1.0 under packages/foundation/data/media/ with full enterprise surface — typed errors via @suaveplan/error, OTel counters + histograms, Zod-validated constraints, pluggable SignatureRegistry, async metadata extractor hook, custom predicate support, async + assert validation variants, filename + bytes MIME resolution, canonical MIME inference from signature label.
  • Add: error-code namespace MEDIA.* with eight stable codes (EMPTY_INPUT, INVALID_CONSTRAINTS, VALIDATION_FAILED, UNSUPPORTED_TYPE, PREDICATE_FAILED, DUPLICATE_SIGNATURE, METADATA_EXTRACTOR_FAILED, INVALID_SIGNATURE).
  • Add: OTel instruments — counters media_detect_total, media_metadata_total, media_validate_total, media_error_total and histograms media_op_latency_ms, media_input_size_bytes.
  • Add: subpath exports per feature module (./detection/detection, ./metadata/metadata, ./validation/validation, ./errors/errors, ./observability/observability, ./signatures/signatures, ./types).
  • Add: media to the data plugin in scripts/folder-reorg/assignment.yml.

Impact

Affected dependents

bunx turbo ls --filter=...@suaveplan/media — empty (media is a leaf migration; no current genesis package depends on it).

Parity Checklist

Capability Upstream Migrated Notes
detectMediaType(bytes) yes yes Now routes through pluggable SignatureRegistry.
detectMediaTypeFromName(filename) yes yes Same MIME-bucket semantics; emits counter + latency.
getMetadata(bytes, filename?) yes yes Adds signatureLabel; MIME refines to filename when present.
validateMedia(bytes, constraints, filename?) yes yes Now Zod-validated; reports MIME / minSize / minWidth / minHeight / maxDuration.
MediaType / MediaMetadata / MediaConstraints / MediaResult yes yes Preserved; MediaConstraints extended with new fields.
Pluggable signatures no yes New SignatureRegistry class + defaultSignatureRegistry.
Async metadata extractor no yes New getMetadataAsync + MediaMetadataExtractor hook.
Async validation predicate no yes New validateMediaAsync runs constraints.predicate.
Throwing assert variant no yes New assertValidMedia.
Typed errors no yes MediaError + MEDIA_CODES + per-code metadata.
OTel instrumentation no yes Four counters + two histograms.