# @suaveplan/controller - Universal input controller foundation — unified 32-field ControllerInput shape, BaseController abstract base with Clock-injected pollRate gating and threshold/deadzone normalisation, typed InputEventEmitter, stable CONTROLLER.* error code registry, and OpenTelemetry instrumentation. Chunk A of the @suaveplan/controller migration; device adapters and merger ship in follow-up chunks. Universal input controller foundation. Ships the unified `ControllerInput` shape (37 normalised fields in `[0, 255]`), `BaseController` abstract base with injectable `Clock`/`IdGenerator`, `pollRate` gating and per-input threshold/deadzone normalisation, the typed `InputEventEmitter`, the stable `CONTROLLER.*` error-code registry, and the package's OpenTelemetry instruments. Device adapters (`KeyboardController`, `GamepadController`, `TouchController`, `MouseController`) and `ControllerMerger` ship in Chunks B and C. ## Documentation tree - [base](./src/base/base.md) — Abstract base for every device-specific controller adapter shipped by this package. Owns the 37-field `ControllerInput`… - [base](./src/base/base.md) — Abstract base for every device-specific controller adapter shipped by this package. Owns the 37-field `ControllerInput`… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable `CONTROLLER.*` error-code registry and the typed `ControllerError` class used by every public surfac… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable `CONTROLLER.*` error-code registry and the typed `ControllerError` class used by every public surfac… - [events](./src/events/events.md) — Typed event dispatcher used by `BaseController` to fan input, state and combo events out to listeners. Centralising the… - [events](./src/events/events.md) — Typed event dispatcher used by `BaseController` to fan input, state and combo events out to listeners. Centralising the… - [gamepad](./src/gamepad/gamepad.md) — Browser-tier device adapter that polls the Web Gamepad API and normalises button + axis state into the canonical 37-fie… - [gamepad.internal](./src/gamepad/gamepad.internal.md) — Module-private helpers used by `GamepadController` to keep the main class file under the repository's 300-line hard cap… - [gamepad](./src/gamepad/gamepad.md) — Browser-tier device adapter that polls the Web Gamepad API and normalises button + axis state into the canonical 37-fie… - [keyboard](./src/keyboard/keyboard.md) — Browser-tier device adapter that normalises DOM `keydown`/`keyup` events into the canonical 37-field `ControllerInput`… - [keyboard](./src/keyboard/keyboard.md) — Browser-tier device adapter that normalises DOM `keydown`/`keyup` events into the canonical 37-field `ControllerInput`… - [merger](./src/merger/merger.md) — `ControllerMerger` fuses an ordered list of `BaseController` children into a single virtual controller whose `Controlle… - [merger](./src/merger/merger.md) — `ControllerMerger` fuses an ordered list of `BaseController` children into a single virtual controller whose `Controlle… - [telemetry](./src/telemetry/telemetry.md) — Owns the OpenTelemetry instruments emitted by `@suaveplan/controller`: two counters tracking input and state-change thr… - [telemetry](./src/telemetry/telemetry.md) — Owns the OpenTelemetry instruments emitted by `@suaveplan/controller`: two counters tracking input and state-change thr… - [types](./src/types/keys.md) — Provides the canonical iteration order over the 37 `ControllerInput` keys and a `createDefaultControllerInput()` factor… - [keys](./src/types/keys.md) — Provides the canonical iteration order over the 37 `ControllerInput` keys and a `createDefaultControllerInput()` factor… ## Modules - [`base/base.md`](src/base/base.md) — `BaseController` lifecycle, state, normalisation, pollRate gating. - [`events/events.md`](src/events/events.md) — `InputEventEmitter` typed dispatcher with disposable listeners. - [`error-codes.md`](src/error-codes.md) — `CONTROLLER_CODES` registry and `ControllerError` class. - [`telemetry.md`](src/telemetry.md) — `controller_inputs_total`, `controller_state_changes_total` counters and the pattern-match duration histogram. - [`types/keys.md`](src/types/keys.md) — `CONTROLLER_INPUT_KEYS` and `createDefaultControllerInput`. ## Status `0.1.0` — Chunk A foundation. Chunks B (device adapters) and C (merger) extend the barrel with additional named exports. ## Verification ```bash bunx turbo lint typecheck test --filter=@suaveplan/controller bunx turbo test:coverage --filter=@suaveplan/controller ``` The coverage gate is 100/100/100/100 (istanbul). The package's `tests/setup/polyfills.ts` registers an in-memory `MeterProvider` before source modules import the OTel meter so the telemetry assertions resolve against a real exporter, with no mocks.