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:
- Hand-rolled error strings — no
@suaveplan/errorintegration, no stable codes, no programmatic discrimination. - No Zod validation of
MediaConstraints— malformed input silently passes through. - No OpenTelemetry instrumentation — production cannot measure detection / metadata / validation volume, latency, or error rate.
- Magic-byte signatures hard-coded inside the implementation — no extension point for downstream packages to add formats like AVIF, HEIC, or M4A.
- No async metadata extractor hook — width / height / duration / codec extraction has to happen outside the package.
- No custom-predicate constraint — non-trivial business rules cannot be expressed.
- No throwing assert variant for guard sites.
- No filename-MIME refinement when both bytes and filename are available.
- No
signatureLabelsurfacing — 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/mediaat version0.1.0underpackages/foundation/data/media/with full enterprise surface — typed errors via@suaveplan/error, OTel counters + histograms, Zod-validated constraints, pluggableSignatureRegistry, 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_totaland histogramsmedia_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:
mediato thedataplugin inscripts/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. |