# `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.