Files
suaveplan/packages/foundation/flow/streams-metadata/src/events/events.md
2026-05-27 23:47:53 +01:00

3.2 KiB

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

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

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<Record<string, unknown>> 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.