first commit
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# `compound` handler
|
||||
|
||||
## Purpose
|
||||
|
||||
The `compound` handler is the binding-registry slot responsible for
|
||||
fanning a single control's value out to multiple leaf bindings — for
|
||||
example, a knob that simultaneously drives a plugin parameter, a MIDI CC,
|
||||
and a DMX channel. Unlike the leaf handlers, the compound handler always
|
||||
has a working default because compounding is a pure structural operation
|
||||
that doesn't depend on any external integration.
|
||||
|
||||
The default iterates `binding.bindings` in registration order and calls
|
||||
`registry.dispatchLeaf(leaf, value)` for each — every leaf is sent the
|
||||
same value, so the per-leaf range/scale logic stays in the leaf handlers.
|
||||
The schema rejects nested compounds at parse time, so the iteration is
|
||||
guaranteed to bottom out after one step.
|
||||
|
||||
## Features
|
||||
|
||||
- Default implementation needs no consumer wiring.
|
||||
- Stable iteration order (registration order) for deterministic test
|
||||
assertions.
|
||||
- Takes the owning `BindingRegistry` as a parameter so callers can
|
||||
customise the fan-out target (e.g. dispatch through a wrapping spy
|
||||
registry).
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { BindingRegistry } from "@suaveplan/react-control-surface/runtime/binding-registry";
|
||||
|
||||
// No compound override needed; the default fans out automatically.
|
||||
const registry = new BindingRegistry({ pluginParam: handler });
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
```ts
|
||||
import { defaultCompoundHandler } from "@suaveplan/react-control-surface/runtime/binding-registry";
|
||||
|
||||
// Manually fan out, perhaps after a custom pre-flight check.
|
||||
defaultCompoundHandler(compoundBinding, 0.42, registry);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `defaultCompoundHandler(binding: CompoundBinding, value: number, registry: BindingRegistry): void`
|
||||
— iterates `binding.bindings` and dispatches each leaf through `registry.dispatchLeaf`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The schema's nested-compound rejection is enforced at parse time, but the
|
||||
default handler defends in depth by routing through `dispatchLeaf`, which
|
||||
accepts only the `LeafBinding` union. A nested compound would fail the
|
||||
TypeScript narrowing at the boundary even if a malicious caller bypassed
|
||||
the schema validator.
|
||||
Reference in New Issue
Block a user