ilokesto

validate

validate runs a Standard Schema v1 validator before the store accepts the next state. If validation fails, the update is stopped and onError is called.

Signature

validate<Schema>(
  schema: StandardSchemaV1<T, T>,
  options?: { onError?: (issues: ReadonlyArray<StandardSchemaIssue>) => void },
): PipeMiddleware<T>

Example

import { validate } from '@ilokesto/state/middleware';
import { pipe } from '@ilokesto/state/utils';

type CounterState = { count: number };

const schema = {
  '~standard': {
    version: 1,
    vendor: 'counter',
    validate(value: unknown) {
      if (typeof value === 'object' && value !== null && typeof (value as CounterState).count === 'number') {
        return { value: value as CounterState };
      }
      return { issues: [{ message: 'count must be a number' }] };
    },
  },
} as const;

const store = pipe
  .use(validate(schema))
  .create<CounterState>({ count: 0 });

What happens on failure

When the schema returns issues, validate calls onError (defaults to console.error) and does not call the next middleware. The store keeps its previous state.

Custom error handling

Pass onError to control failure behavior. Throw inside the callback to propagate the error to the caller of setState:

const store = pipe
  .use(validate(schema, {
    onError: (issues) => { throw new Error(issues[0]?.message ?? 'Validation failed'); },
  }))
  .create<CounterState>({ count: 0 });

Async caveat

Async Standard Schema validation is not supported. If validate() returns a Promise-like result, the middleware calls onError with a synthetic issue and stops the update. Run async checks before calling setState.

On this page