Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
# `provider/chain-map`
## Purpose
`ChainMap` is the provider-scoped lazy registry of `PluginChain`
instances, keyed by track id. The hook `usePluginChain(trackId)` calls
`getOrCreate(trackId)` to fetch (or create) the chain associated with
that track, so two consumers asking for the same id see the same
chain instance. The map's `dispose()` is wired into the provider's
unmount path to dispose every chain it holds.
## Features
- Lazy creation: chains are constructed on first request, not
eagerly at mount.
- Identity stable for the same `trackId` across calls.
- Configurable default channels / sampleRate / blockSize at
construction; per-call overrides via `getOrCreate(id, config)`.
- Inert after `dispose()` — further calls throw.
## Usage: Basic
```ts
import { ChainMap, ProviderBusRegistry } from "@suaveplan/react-audio/provider";
const buses = new ProviderBusRegistry();
const chains = new ChainMap(buses);
const chainA = chains.getOrCreate("track-a");
const sameChainA = chains.getOrCreate("track-a"); // === chainA
```
## Usage: Advanced
```ts
import { ChainMap, ProviderBusRegistry } from "@suaveplan/react-audio/provider";
const buses = new ProviderBusRegistry();
const chains = new ChainMap(buses, {
channels: 1,
sampleRate: 44_100,
blockSize: 256,
});
// Per-track override:
const monoChain = chains.getOrCreate("voice", { channels: 1 });
const stereoChain = chains.getOrCreate("master", { channels: 2 });
```
## API Reference
- `new ChainMap(buses, defaultConfig?)`.
- `getOrCreate(trackId, config?): PluginChain`.
- `get(trackId): PluginChain | undefined`.
- `list(): ReadonlyArray<string>`.
- `dispose(): void`.
## Implementation Notes
The map stores fully-constructed `PluginChain` instances; there is
no proxy or wrapping. `dispose()` is idempotent and iterates the
internal map's `values()`, calling `chain.dispose()` on each. After
dispose the map is cleared so a late `get()` returns `undefined`
and a late `getOrCreate()` throws. The Phase-1 default channels /
sampleRate / blockSize line up with the typical browser audio context
defaults; consumers who need different shapes pass them through
`getOrCreate(id, config)` per chain. The `buses` argument is held by
reference and passed into every chain — keeping a single bus registry
for the whole provider subtree means sidechain wiring across tracks
remains coherent.