# SpritePlayerEvents _(no submodules)_ ## Purpose `SpritePlayerEvents` is the typed event surface a `SpritePlayer` exposes for downstream consumers — analytics, UI feedback, observability sinks, debug overlays. It is a thin facade over `@suaveplan/events`'s `EventBus`, narrowed to the five event names the player can emit. The class is intentionally write-internal / read-external: the player constructs it and emits, consumers subscribe and never emit. The internal `EventBus` is not exposed so consumers cannot dispatch arbitrary events through the player's surface, which keeps the contract auditable. ## Features - Five typed event names: `play`, `stop`, `complete`, `voice-stolen`, `error`. - Strongly-typed `on` returning an unsubscribe closure — no string-typed payloads at the call site. - `clear()` wipes all listeners — used by `SpritePlayer.dispose()` to break consumer-to-player references. - Backed by `@suaveplan/events.EventBus` so payloads flow through the same FIFO dispatch used elsewhere in the platform. ## Usage: Basic Example ```ts import { createSpritePlayer } from "@suaveplan/audio-sprite-player"; const player = createSpritePlayer({ adapter }); const off = player.events.on("play", (e) => { console.log(`play ${e.entryName} (${e.handleId}) at ${e.startedAt}`); }); // ...later off(); ``` ## Usage: Advanced Example ```ts import { createSpritePlayer } from "@suaveplan/audio-sprite-player"; const player = createSpritePlayer({ adapter }); const offs = [ player.events.on("voice-stolen", (e) => { metrics.voicesStolen.add(1, { entry: e.entryName }); }), player.events.on("complete", (e) => { histograms.playMs.record(e.durationMs, { entry: e.entryName }); }), player.events.on("error", (e) => { log.error("sprite playback failed", { handleId: e.handleId, code: e.code, message: e.message, }); }), ]; return () => offs.forEach((off) => off()); ``` ## API Reference ### `class SpritePlayerEvents` - `on(event, listener): () => void` — subscribes, returns the unsubscribe closure. - `emit(event, payload): void` — internal; called by `SpritePlayer`. - `clear(): void` — drops every listener. ### Event payloads - `play` → `{ handleId, entryName, startedAt }` - `stop` → `{ handleId, entryName, fadeOutMs }` - `complete` → `{ handleId, entryName, durationMs }` - `voice-stolen` → `{ stolenId, replacedBy, entryName }` - `error` → `{ handleId, entryName, code, message }` ## Implementation Notes - The class deliberately exposes `emit` so the orchestrator can fire events; downstream consumers should treat it as internal and never call it (TypeScript visibility cannot enforce package-level boundaries, so the convention is documented here). - `clear()` is invoked by `SpritePlayer.dispose()` to release references — consumers should not call it directly because it would silence other listeners. - The underlying `EventBus` dispatches synchronously in FIFO order; throwing in a listener does not poison the bus but does prevent later listeners from running for that emission.