first commit
This commit is contained in:
210
docs/media/audio/control-surface-schema/README.md
Normal file
210
docs/media/audio/control-surface-schema/README.md
Normal file
@@ -0,0 +1,210 @@
|
||||
# @suaveplan/control-surface-schema - Universal canonical schema for DAW-style control surfaces: ControlSurface root, ControlNode (Group | Control) discriminated union, 18 ControlKind variants, 6 Binding variants, 4 GroupLayout variants, Zod validators, forward migrations, DFS traversal, duplicate-id and binding-reference cross-check. Zero runtime deps beyond error, types, tslib, zod.
|
||||
|
||||
Universal canonical schema for DAW-style control surfaces. Owns the
|
||||
`ControlSurface` root document, the `ControlNode = Group | Control`
|
||||
discriminated tree, the 18 `ControlKind` variants, the 6 `Binding`
|
||||
variants, the 4 `GroupLayout` variants, and the Zod schemas / validators
|
||||
/ forward migrations every renderer reads. Zero runtime dependencies
|
||||
beyond `@suaveplan/error`, `@suaveplan/types`, `tslib`, and `zod`.
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
## Documentation tree
|
||||
|
||||
- [constants](./src/constants/constants.md) — The constants module owns the single source of truth for the current schema version of `@suaveplan/control-surface-sche…
|
||||
- [constants](./src/constants/constants.md) — The constants module owns the single source of truth for the current schema version of `@suaveplan/control-surface-sche…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable error-code registry for `@suaveplan/control-surface-schema`. Every entrypoint of the packag…
|
||||
- [error-codes](./src/error-codes/error-codes.md) — This module owns the stable error-code registry for `@suaveplan/control-surface-schema`. Every entrypoint of the packag…
|
||||
- [identity](./src/identity/identity.md) — The identity module owns the structural cross-checks that run after a candidate surface passes its Zod parse: duplicate…
|
||||
- [identity](./src/identity/identity.md) — The identity module owns the structural cross-checks that run after a candidate surface passes its Zod parse: duplicate…
|
||||
- [schemas](./src/schemas/control-surface-schema.md) — This module owns the Zod schemas that mirror every TypeScript type in the package: `TransformSchema`, `BindingSchema`,…
|
||||
- [control-surface-schema](./src/schemas/control-surface-schema.md) — This module owns the Zod schemas that mirror every TypeScript type in the package: `TransformSchema`, `BindingSchema`,…
|
||||
- [upgrade](./src/upgrade/upgrade.md) — This module owns `upgradeSurface` and the `MigrationRegistry` chain that walks an older schema-version document forward…
|
||||
- [upgrade](./src/upgrade/upgrade.md) — This module owns `upgradeSurface` and the `MigrationRegistry` chain that walks an older schema-version document forward…
|
||||
- [validate](./src/validate/validate.md) — This module exports `validateSurface` — the canonical entrypoint for parsing and structurally cross-validating a `Contr…
|
||||
- [validate](./src/validate/validate.md) — This module exports `validateSurface` — the canonical entrypoint for parsing and structurally cross-validating a `Contr…
|
||||
- [walk](./src/walk/walk.md) — This module exports `walkSurface` — the canonical depth-first traversal helper for `ControlSurface` documents. Every cr…
|
||||
- [walk](./src/walk/walk.md) — This module exports `walkSurface` — the canonical depth-first traversal helper for `ControlSurface` documents. Every cr…
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add @suaveplan/control-surface-schema
|
||||
```
|
||||
|
||||
## Quick start
|
||||
|
||||
```ts
|
||||
import {
|
||||
CURRENT_SCHEMA_VERSION,
|
||||
validateSurface,
|
||||
walkSurface,
|
||||
} from "@suaveplan/control-surface-schema";
|
||||
|
||||
const result = validateSurface({
|
||||
id: "surface-1",
|
||||
name: "Empty",
|
||||
version: CURRENT_SCHEMA_VERSION,
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
skin: { id: "default" },
|
||||
root: {
|
||||
type: "group",
|
||||
id: "root",
|
||||
layout: { kind: "absolute" },
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
children: [],
|
||||
},
|
||||
});
|
||||
|
||||
if (result.error !== undefined) throw result.error;
|
||||
walkSurface(result.surface, (node) => console.log(node.id));
|
||||
```
|
||||
|
||||
## Surface document shape
|
||||
|
||||
```text
|
||||
ControlSurface
|
||||
├── id, name, version, createdAt, updatedAt
|
||||
├── skin: { id; vars? }
|
||||
└── root: ControlNode
|
||||
├── Group { type; id; layout; transform; children[]; label?; collapsible? }
|
||||
└── Control { type; id; kind; transform; label?; appearance?; binding?; range?; behaviour? }
|
||||
```
|
||||
|
||||
The 18 `ControlKind` literals: `knob`, `slider-v`, `slider-h`,
|
||||
`button-momentary`, `button-latching`, `switch-2`, `switch-3`, `led`,
|
||||
`digital-display`, `meter-vu`, `meter-peak`, `meter-spectral`, `xy-pad`,
|
||||
`jog-wheel`, `piano-key`, `drum-pad`, `text-label`, `image`.
|
||||
|
||||
The 6 `Binding` variants: `pluginParam`, `transport`, `midiOut`,
|
||||
`midiIn`, `dmx`, `compound` (flat-only).
|
||||
|
||||
The 4 `GroupLayout` variants: `grid`, `absolute`, `stack`, `free3d` —
|
||||
only `free3d` admits z-axis transforms.
|
||||
|
||||
## Worked examples
|
||||
|
||||
### 4-pad drum machine (grid layout, drum-pad kind)
|
||||
|
||||
```ts
|
||||
const drumMachine = {
|
||||
id: "drum-4",
|
||||
name: "4-pad",
|
||||
version: CURRENT_SCHEMA_VERSION,
|
||||
createdAt: 0,
|
||||
updatedAt: 0,
|
||||
skin: { id: "default" },
|
||||
root: {
|
||||
type: "group",
|
||||
id: "root",
|
||||
layout: { kind: "grid", columns: 4, rows: 1, gap: 8 },
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
children: Array.from({ length: 4 }, (_, i) => ({
|
||||
type: "control",
|
||||
id: `pad-${i}`,
|
||||
kind: "drum-pad",
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
binding: { kind: "midiOut", portId: "out", channel: 9, cc: 60 + i },
|
||||
})),
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### 8-channel mixer (stack-row of stack-columns)
|
||||
|
||||
```ts
|
||||
const mixer = {
|
||||
/* … */
|
||||
root: {
|
||||
type: "group",
|
||||
id: "mixer",
|
||||
layout: { kind: "stack", direction: "row", gap: 4 },
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
children: Array.from({ length: 8 }, (_, ch) => ({
|
||||
type: "group",
|
||||
id: `ch-${ch}`,
|
||||
layout: { kind: "stack", direction: "column", gap: 2 },
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
children: [
|
||||
{
|
||||
type: "control",
|
||||
id: `ch-${ch}-vol`,
|
||||
kind: "slider-v",
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
binding: {
|
||||
kind: "pluginParam",
|
||||
pluginId: "mixer",
|
||||
paramPath: `channels/${ch}/volume`,
|
||||
curve: "log",
|
||||
},
|
||||
},
|
||||
],
|
||||
})),
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Piano keyboard (absolute layout, piano-key kind)
|
||||
|
||||
```ts
|
||||
const piano = {
|
||||
/* … */
|
||||
root: {
|
||||
type: "group",
|
||||
id: "keyboard",
|
||||
layout: { kind: "absolute" },
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
children: Array.from({ length: 88 }, (_, key) => ({
|
||||
type: "control",
|
||||
id: `key-${21 + key}`,
|
||||
kind: "piano-key",
|
||||
transform: { position: { x: key * 22, y: 0 } },
|
||||
binding: { kind: "midiOut", portId: "out", channel: 0, cc: 21 + key },
|
||||
})),
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
### Traktor-style DJ surface (3D free layout)
|
||||
|
||||
```ts
|
||||
const traktor = {
|
||||
/* … */
|
||||
root: {
|
||||
type: "group",
|
||||
id: "deck",
|
||||
layout: { kind: "free3d" },
|
||||
transform: { position: { x: 0, y: 0 } },
|
||||
children: [
|
||||
{
|
||||
type: "control",
|
||||
id: "jog",
|
||||
kind: "jog-wheel",
|
||||
transform: { position: { x: 0, y: 0, z: 0.1 } },
|
||||
binding: { kind: "midiOut", portId: "deck-a", channel: 0, cc: 32 },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
## Modules
|
||||
|
||||
- [Constants](./src/constants.md) — `CURRENT_SCHEMA_VERSION`.
|
||||
- [Error codes](./src/error-codes.md) — `CONTROL_SURFACE_SCHEMA_CODES`, `SchemaError`.
|
||||
- [Transform types](./src/types/transform.md)
|
||||
- [Binding types](./src/types/binding.md)
|
||||
- [Range types](./src/types/range.md)
|
||||
- [Action types](./src/types/action.md)
|
||||
- [Behaviour types](./src/types/behaviour.md)
|
||||
- [Appearance types](./src/types/appearance.md)
|
||||
- [Control-kind types](./src/types/control-kind.md)
|
||||
- [Group-layout types](./src/types/group-layout.md)
|
||||
- [Control-node types](./src/types/control-node.md)
|
||||
- [Control-surface types](./src/types/control-surface.md)
|
||||
- [Validate](./src/validate/validate.md)
|
||||
- [Upgrade](./src/upgrade/upgrade.md)
|
||||
- [Walk](./src/walk/walk.md)
|
||||
- [Identity](./src/identity/identity.md)
|
||||
|
||||
Reference in New Issue
Block a user