Files
skills/docs/foundation/flow/streams-chunk-queue/src/events/events.md
2026-05-29 08:20:56 +01:00

2.2 KiB

events

(no submodules)

Purpose

Implements the lightweight event bus that powers the queue's addEventListener / removeEventListener surface. The emitter keeps a Map<StreamEventType, Set<Listener>> so registration and removal are both O(1), and exposes a wildcard "*" subscription so debugging tools can observe every event without enumerating types.

Features

  • Concrete-type subscriptions (chunk:received, stream:progress, …).
  • Wildcard subscription via "*" that receives every emitted event.
  • O(1) add, remove, and emit per listener.
  • clear() for tear-down (used by StreamingChunkQueue.clear()).

Usage: Basic

import { StreamEventEmitter } from "@suaveplan/streams-chunk-queue";

const emitter = new StreamEventEmitter();
emitter.addEventListener("chunk:received", (event) => {
    console.info("got chunk", event.chunkId);
});

Usage: Advanced

const wildcard = (event: StreamEvent) =>
    telemetry.record("stream.event", { type: event.type });
emitter.addEventListener("*", wildcard);
emitter.removeEventListener("*", wildcard);

API Reference

StreamEventEmitter

  • addEventListener(type, listener) — register listener under type (either a concrete event type or "*").
  • removeEventListener(type, listener) — remove a previously registered listener.
  • emit(event) — dispatch to all matching subscribers, then to all wildcard subscribers.
  • clear() — drop every registered listener.

WILDCARD_EVENT_TYPE

The constant "*". Exported so callers don't sprinkle string literals.

Implementation Notes

The wildcard dispatch happens after concrete dispatch, mirroring the ordering observable consumers expect (a tracing tool sees the event after the application code has reacted). Listeners are synchronous — the bus does not await listener return values; callers that need async work should queueMicrotask inside their listener. The emitter is intentionally allocation-light: a Map<type, Set<listener>> means add/remove are O(1) and dispatch is O(N) over only the matching listeners. There is no priority ordering; concrete-type listeners are dispatched in insertion order, then wildcard listeners in their own insertion order.