first commit
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
# `distortion/schemas`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
Zod schemas validating the construction-time options and preset payload of `DistortionPlugin`. These run at the public boundary so any malformed object — wrong mode name, out-of-range drive, non-integer bit depth, NaN gain — is rejected with `AUDIO_FX.INVALID_OPTIONS` or `AUDIO_FX.INVALID_PRESET` before it can corrupt runtime state.
|
||||
|
||||
Separating schemas from the plugin module lets `index.ts` re-export them so callers can introspect the option surface (for forms, RPC validation, or storybook controls) without importing the audio implementation.
|
||||
|
||||
## Features
|
||||
|
||||
- `DistortionModeSchema` — `z.enum(["waveshaper", "bitcrusher", "overdrive"])` — used in both options and preset payloads.
|
||||
- `DistortionPluginOptionsSchema` — validates all four optional construction fields with their documented ranges (`drive` 0..40 dB, `bits` 1..16 integer, `outputGain` ±24 dB).
|
||||
- `DistortionPresetDataSchema` — `.strict()` object carrying only `mode`; extra fields are rejected.
|
||||
- `bits` is `z.number().int()` so float bit-depths (which would round unpredictably) cannot sneak through.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { DistortionPluginOptionsSchema } from "@suaveplan/audio-fx-plugin-distortion";
|
||||
|
||||
const parsed = DistortionPluginOptionsSchema.parse({
|
||||
initialMode: "waveshaper",
|
||||
});
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
DistortionModeSchema,
|
||||
DistortionPresetDataSchema,
|
||||
} from "@suaveplan/audio-fx-plugin-distortion";
|
||||
|
||||
// Validate a preset blob coming off the wire before applying it.
|
||||
function safeApplyPreset(plugin: DistortionPlugin, payload: unknown) {
|
||||
const parsed = DistortionPresetDataSchema.safeParse(payload);
|
||||
if (!parsed.success) {
|
||||
log.warn("dropped bad distortion preset", parsed.error.issues);
|
||||
return;
|
||||
}
|
||||
plugin.applyPreset({
|
||||
version: 1,
|
||||
parameters: {},
|
||||
presetData: parsed.data,
|
||||
});
|
||||
}
|
||||
|
||||
const modes = DistortionModeSchema.options;
|
||||
console.log(modes); // ["waveshaper", "bitcrusher", "overdrive"]
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `DistortionModeSchema: z.ZodEnum<["waveshaper", "bitcrusher", "overdrive"]>`
|
||||
- `DistortionPluginOptionsSchema: z.ZodObject<{ initialMode?, initialDriveDb?, initialBitDepth?, initialOutputGainDb? }>`
|
||||
- `DistortionPresetDataSchema: z.ZodObject<{ mode: DistortionMode }, "strict">`
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
`DistortionModeSchema` is exported as a named schema (not inlined) so the same value is reused by `DistortionPluginOptionsSchema.initialMode` and `DistortionPresetDataSchema.mode`. That guarantees both validation paths agree byte-for-byte on the legal mode set — adding a fourth mode in a future revision is a one-line change in `schemas.ts`.
|
||||
|
||||
`DistortionPresetDataSchema` uses `.strict()` for the same reason as the other plugins: unknown fields almost always indicate a payload from a sibling plugin or a forwards-incompatible schema, and silent rejection at the boundary is much less harmful than partial application. The combined "mode-must-be-known, payload-must-be-exact" stance keeps the preset surface stable across plugin versions.
|
||||
Reference in New Issue
Block a user