6.0 KiB
Enterprise Migration: @suaveplan/audio-engine
Package: @suaveplan/audio-engine
Status: PROPOSED
Type: new-package (migration from suaveplan)
Why
@suaveplan/audio-engine is the core browser-side Web Audio engine used by every audio surface in the monorepo. It owns the AudioContext lifecycle, typed plugin system (AudioPlugin + PluginRegistry), AudioGraph node-routing, AudioWorkletManager, AudioQueueEngine, and EventBus. Migrating it to genesis is a prerequisite for audio-plugins-fx, audio-controllers, and all react-audio* packages. The upstream version lacks tests for graph / queue / worklet / registry, exceeds file-size caps, uses plain Error throws, and has no OTel or Zod boundaries.
What changes
- ADDED:
AudioEngineclass withAudioContextinjection seam — initialize, resume, suspend, destroy, plugin lifecycle, metrics. - ADDED:
AudioGraphclass — node add/remove, connect/disconnect with cycle detection, topological sort, BFS path finding, serialization. - ADDED:
AudioQueueEngineclass — extendsAudioEnginewith@suaveplan/queue-based serial/parallel plugin chains, retry, rate limiting. - ADDED:
AudioWorkletManagerclass — module loading, node creation, messaging, statistics. - ADDED:
PluginRegistryclass — constructor + descriptor registration, dependency validation, search, instantiation. - ADDED:
EventBusclass — typed wrapper around@suaveplan/eventswith per-listener error isolation. - ADDED:
AudioPluginabstract base class — state machine, metadata, parameters, node accessors. - ADDED: Error codes via
@suaveplan/error(AUDIO_ENGINE_STATE_INVALID,PLUGIN_NOT_FOUND,GRAPH_CYCLE_DETECTED,WORKLET_LOAD_FAILED, etc.). - ADDED: Zod boundary schemas for
AudioEngineConfig,PluginMetadata,AudioPluginDescriptor. - ADDED: OTel counters/histograms for plugin loads, engine latency, worklet round-trip, graph connect duration.
- ADDED: Plugin quarantine — a crashing plugin is marked
ERRORwithout tearing down the engine or other plugins. - ADDED: Worklet module URL allow-list gate.
- ADDED: Co-located
.mddocs for every exported symbol. - ADDED: Benchmarks for graph traversal and worklet messaging.
Out of scope
- Plugin hot-swap with crossfade ramp — new feature, not in upstream; deferred to follow-up change.
- Latency budget enforcement / watchdog — new feature; deferred.
- MIDI clock source transport — new feature; deferred.
- Sample-accurate parameter automation curves — new feature; deferred.
SharedArrayBuffer-backed meter/analyser — new feature; deferred.- Worklet hot-reload for dev-time — new feature; deferred.
OfflineAudioContextrender-on-demand mode — new feature; deferred.ScriptProcessorNodefallback for non-worklet browsers — upstream usesstandardized-audio-contextwhich handles this; we retain the upstream abstraction level without adding a new fallback layer.
Source mapping
This change derives from ../suaveplan/enterprise/audio-engine.md.
| Requirement | Source lines | Notes |
|---|---|---|
| Split files over 300-line cap | L46 | engine → engine + state + metrics; graph → graph + connect + traverse; queue → queue + cue + scheduler; worklet → loader + messaging + registry |
| Unit tests for every module | L47 | graph, queue, worklet, registry, plugin base, event-bus |
| AudioContext injection seam | L48 | constructor accepts pre-built context |
| Typed event map | L49 | replaces AudioEngineEvents enum |
| OTel metrics | L50 | counters + histograms |
| Worklet URL allow-list | L52 | security gate |
| Plugin lifecycle docs | L53 | state diagram in README + per-symbol .md |
| Coverage ≥ 95 % | L57 | genesis policy is 100 % |
| File budget 250/300/500 | L59 | enforced |
No any / ts-ignore |
L64 | enforced |
| Zod schemas at boundaries | L65 | PluginMetadata, AudioPluginDescriptor |
| Error hierarchy | L66 | via @suaveplan/error |
| Plugin quarantine | L111 | error isolation per plugin |
Requirements with no source line
| Requirement | Justification |
|---|---|
| 100 % Istanbul coverage threshold | Genesis-wide policy (AGENTS.md §5, §13) |
No direct vitest imports |
Genesis-wide policy (AGENTS.md §7) |
export * banned in feature barrels |
Genesis-wide policy (AGENTS.md §6a) |
sideEffects: false retained |
Genesis-wide policy |
Verification approach
src/engine/engine.test.ts— AudioEngine lifecycle, state transitions, plugin load/unload, metrics, destruction.src/engine/engine.spec-conformance.test.ts— OTel instrument assertions, Zod boundary rejection, typed event map.src/graph/graph.test.ts— node management, connect/disconnect, cycle detection, topological sort, path finding, serialization.src/graph/graph.spec-conformance.test.ts— strict-mode error paths, graph stats, clone round-trip.src/queue-engine/queue-engine.test.ts— serial/parallel chain processing, retry, rate limit, queue status.src/worklet/worklet-manager.test.ts— module load/unload, node create/destroy, messaging, statistics.src/worklet/worklet-manager.spec-conformance.test.ts— URL allow-list rejection, OTel round-trip histogram.src/registry/plugin-registry.test.ts— constructor/descriptor registration, dependency validation, search, instantiation.src/event-bus/event-bus.test.ts— subscribe/unsubscribe, emit, listener error isolation.src/plugin/plugin-base.test.ts— AudioPlugin abstract class, state machine, parameter get/set.tests/purity.test.ts— zero import-time side effects, no global mutation.tests/integration.test.ts— full engine + graph + registry round-trip.src/__benchmarks__/graph.bench.ts— graph traversal performance.src/__benchmarks__/worklet.bench.ts— worklet messaging round-trip.
Migration impact
Packages awaiting this dependency:
@suaveplan/audio-plugins-fx@suaveplan/audio-controllers@suaveplan/react-audio@suaveplan/react-audio-player@suaveplan/react-audio-stream@suaveplan/r3f-audio
None are yet migrated, so impact is sequencing-only.