# db/registry ## Purpose The central in-memory MIME type database for `@suaveplan/mime`. Maintains two indexes over the built-in `MimeEntry` list: a `type → extensions` forward map and an `extension → entry` reverse map. Provides O(1) lookup in both directions and supports registering additional entries at runtime for extensibility. ## Features - `getEntryByMime(mime)` — forward lookup: MIME type string → `MimeEntry` - `getEntryByExtension(ext)` — reverse lookup: file extension → `MimeEntry` - `registerEntry(entry)` — register a custom MIME type at runtime - First-write-wins semantics: built-in entries take precedence over later registrations for the same extension - Extension keys are normalized to lowercase with no leading dot - Both indexes are populated lazily on first access (module load) - `_indexEntryForTesting` — exported only for internal test instrumentation ## Usage: Basic Example ```typescript import { getEntryByMime, getEntryByExtension } from "@suaveplan/mime/db/registry"; // Forward lookup const pngEntry = getEntryByMime("image/png"); console.log(pngEntry?.extensions); // ["png"] // Reverse lookup const entry = getEntryByExtension("jpg"); console.log(entry?.mime); // "image/jpeg" ``` ## Usage: Advanced Example ```typescript import { getEntryByMime, registerEntry } from "@suaveplan/mime/db/registry"; // Register a custom MIME type registerEntry({ mime: "application/x-my-format", extensions: ["myf", "myfmt"], encoding: "binary", }); // Immediately available via lookup const custom = getEntryByMime("application/x-my-format"); console.log(custom?.extensions); // ["myf", "myfmt"] // Built-in extensions are protected (first-write-wins) // Registering a second entry for ".png" will not override image/png registerEntry({ mime: "image/x-fake-png", extensions: ["png"] }); const png = getEntryByExtension("png"); console.log(png?.mime); // still "image/png" ``` ## API Reference ### `getEntryByMime(mime: string): MimeEntry | undefined` Looks up a `MimeEntry` by its MIME type string. Returns `undefined` if not found. ### `getEntryByExtension(ext: string): MimeEntry | undefined` Looks up a `MimeEntry` by file extension (with or without leading dot, case-insensitive). Returns `undefined` if not found. ### `registerEntry(entry: MimeEntry): void` Registers a new MIME type entry. First-write-wins for extensions: if an extension is already in the index, the new entry does not replace it. ## Implementation Notes The registry is initialized at module load by iterating `BUILTIN_DB` once and calling the private `index()` function for each entry. The `index()` function implements the first-write-wins extension guard: `if (!byExtension.has(key)) byExtension.set(key, entry)`. This guard prevents downstream `registerEntry` calls from overriding the canonical extension-to-type mapping established by the built-in database, which is important for stable behavior across multiple `registerEntry` calls in plugin-style usage.