The value to check.
What the value is, for the error message.
The same plan.
import { assertCompositionPlan } from '@libraz/libcantus';
import { resolveKey } from '@libraz/libcantus';
const plan = {
planVersion: 1, seed: 0, algorithmVersion: 1,
keys: [resolveKey('C major')],
meters: [{ startBeat: 0, ts: { numerator: 4, denominator: 4 } }],
span: { startBeat: 0, endBeat: 4, bars: 1 },
sections: [{ label: 'A', startBeat: 0, endBeat: 4 }],
phrases: [],
harmony: [{ startBeat: 0, endBeat: 4, key: 0, roman: 'I' }],
motifs: [],
rhythm: { onsetLevels: [1, 0, 0, 0, 0, 0], interOnsetShares: new Array(17).fill(0).fill(1, 8, 9), syncopation: 0 },
};
assertCompositionPlan(plan); // the plan, unchanged
Reject a value that is not a CompositionPlan.
A plan is the shape a caller's stored JSON, a config file, or a plugin host most plausibly hands back malformed: a missing field, a distribution that no longer sums to 1, an index a later edit left dangling, a numeral no reader can parse, a derivation that points at itself or at a later motif. Every field is checked before a generator or evaluator reads it, and a violation names the path to the field that is wrong.