2.1 KiB
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
BindingRegistryas a parameter so callers can customise the fan-out target (e.g. dispatch through a wrapping spy registry).
Usage: Basic
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
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— iteratesbinding.bindingsand dispatches each leaf throughregistry.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.