# Signatures _(no submodules)_ ## Purpose Owns the magic-byte signature registry that powers byte-level detection. The module ships a frozen `BUILTIN_SIGNATURES` list covering common image (PNG, JPEG, GIF, BMP, WEBP, RIFF), video (MP4/MOV, WebM/MKV), and audio (MP3, FLAC, OGG) formats, plus a mutable `SignatureRegistry` class that lets downstream consumers add or remove entries without forking the package. ## Features - Frozen built-in registry covering twelve canonical formats. - `SignatureRegistry` class with `register`, `unregister`, `list`, `match`, and `detect` methods. - Per-entry `offset` so ftyp-style signatures (MP4) and RIFF chunk markers (WebP) can match at non-zero positions. - Duplicate-label detection: `register` throws `MEDIA.DUPLICATE_SIGNATURE` if a second entry uses the same label. - Byte validation: registration rejects empty byte arrays and non-byte numbers with `MEDIA.INVALID_SIGNATURE`. - Process-wide `defaultSignatureRegistry` seeded with the built-ins. ## Usage: Basic ```ts import { defaultSignatureRegistry } from "@suaveplan/media"; const png = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a]); const sig = defaultSignatureRegistry.match(png); console.log(sig?.label); // "PNG" ``` ## Usage: Advanced ```ts import { SignatureRegistry } from "@suaveplan/media"; const reg = new SignatureRegistry(); reg.register({ type: "image", label: "AVIF", bytes: [0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66], offset: 4, }); const type = reg.detect(myBytes); ``` ## API Reference - `BUILTIN_SIGNATURES` — readonly array of twelve canonical signatures. - `SignatureRegistry` — mutable registry class. - `register(sig)` — add entry; throws on duplicate label / invalid bytes. - `unregister(label)` — remove by label; returns whether removed. - `list()` — frozen snapshot. - `match(input)` — first matching `MediaSignature` or `null`. - `detect(input)` — `MediaType`, defaulting to `"unknown"`. - `defaultSignatureRegistry` — process-wide default. ## Implementation Notes `match` honours each signature's `offset` so non-zero-anchored formats work correctly. The built-in list orders longer / more-specific signatures before shorter ones (RIFF is listed after WEBP because the WEBP marker lives inside a RIFF container at offset 8). The registry's internal array is private so external mutation cannot break ordering.