2.3 KiB
provider/provider-bus-registry
Purpose
ProviderBusRegistry is a thin wrapper around
DefaultBusRegistry from @suaveplan/audio-fx-plugin-base that adds a
synchronous close() method. The wrapper is owned by
<AudioProvider> and torn down on unmount; closing it force-closes
every still-active SidechainPublisher issued through this registry
so no buses leak across remounts (especially relevant under React 19
Strict Mode, which double-invokes effects).
Features
- Implements
BusRegistryso it is a drop-in for the inner default. - Tracks every
SidechainPublisherreturned bypublish()and force-closes them onclose(). - Inert after close — late
publish()calls return a no-op publisher rather than throwing. - Forwards
get,list,subscribeto the inner registry untouched.
Usage: Basic
import { ProviderBusRegistry } from "@suaveplan/react-audio/provider";
const buses = new ProviderBusRegistry();
const pub = buses.publish("sidechain", 1);
pub.write([new Float32Array(128)]);
buses.close(); // closes pub; subsequent publish() returns a no-op.
Usage: Advanced
import { ProviderBusRegistry } from "@suaveplan/react-audio/provider";
const buses = new ProviderBusRegistry();
const pub = buses.publish("kick", 1);
const off = buses.subscribe("kick", (bus) => {
if (bus === undefined) console.log("bus closed");
});
buses.close();
off();
API Reference
new ProviderBusRegistry()— no constructor arguments.publish(name, channels): SidechainPublisher— tracked and closed onclose().get(name),list(),subscribe(name, listener)— delegate.close()— idempotent; closes all tracked publishers.
Implementation Notes
Wrapping rather than subclassing keeps the implementation independent
of the inner class's private state. The Set<SidechainPublisher>
tracks the outer (wrapped) publisher so closing it removes itself
from the set before delegating to the inner close — this avoids
double-iteration concerns when close() calls each publisher's close
which would in turn try to mutate the set. Iterating via
Array.from(this.active) snapshots the set so concurrent mutation
during the close loop is safe. Once closed, publish() returns an
inert publisher whose write / close are no-ops, allowing late
consumers to drain without throwing.