# `events` _(no submodules)_ ## Purpose Declares the typed `StreamsMetadataEvents` map consumed by every transform in this package. `BaseTransform` from `@suaveplan/streams` already carries a generic event API parameterised by an event-map type, so this package does not need (and does not expose) a separate `EventEmitter` property: every transform subclasses `BaseTransform<{}, StreamsMetadataEvents>` and inherits typed `on(name, fn)` / `off(name, fn)` methods. The event map is the public observability contract — listeners attach to the transform directly and receive strongly typed payloads, with TypeScript rejecting accesses to fields that do not exist on the declared payload. ## Features - Single-source map of event name to payload type, consumed by all three transforms and re-exported from the package root. - Compatible with the `EventMap` constraint declared by `@suaveplan/streams::BaseTransform`. - Four events covering both child stages (`mime:detected`, `exif:detected`) and the wrapper's lifecycle (`metadata:complete`, `metadata:error`). ## Usage: Basic Example ```ts import { MetadataTransform } from "@suaveplan/streams-metadata"; const transform = new MetadataTransform(); transform.on("mime:detected", (r) => { console.log("MIME:", r.mimeType, "source:", r.source); }); transform.on("metadata:complete", (p) => { console.log("Done:", p.mime?.mimeType, p.exif?.format); }); ``` ## Usage: Advanced Example ```ts import { MetadataTransform, type StreamsMetadataEvents, } from "@suaveplan/streams-metadata"; const transform = new MetadataTransform(); const handlers: { [K in keyof StreamsMetadataEvents]: (payload: StreamsMetadataEvents[K]) => void; } = { "mime:detected": (r) => console.log("MIME", r.priority, r.mimeType), "exif:detected": (m) => console.log("EXIF", m.format), "metadata:complete": (p) => console.log("OK", p.bytes.byteLength, "bytes"), "metadata:error": (e) => console.error("FAIL", e), }; for (const name of Object.keys(handlers) as (keyof StreamsMetadataEvents)[]) { transform.on(name, handlers[name] as never); } ``` ## API Reference - `type StreamsMetadataEvents`: - `"mime:detected": MimeDetectionResult` — fired by `MimeTransform` (and forwarded by `MetadataTransform`) after detection completes. - `"exif:detected": ImageMetadata` — fired by `ExifTransform` (and forwarded by `MetadataTransform`) after the underlying `@suaveplan/exif::readMetadata` returns. - `"metadata:complete": EnrichedPayload` — fired only by `MetadataTransform`, once both children succeed. - `"metadata:error": unknown` — fired only by `MetadataTransform` when either child throws. The payload is the original thrown value. ## Implementation Notes - The map is declared as a `type` alias (not an `interface`) so it satisfies the structural `Readonly>` constraint imposed by `@suaveplan/streams::EventMap` without interface widening. - Field order is fixed for stable JSDoc generation: child events first, wrapper events last. - Adding a new event is a breaking change to the public API — bump the package version and document it in the next archived spec change.