Optionalpreload?: (value: unknown, field: string, context: CommandContext) => Promise<T>Optional async preload. The dispatcher awaits each preload AFTER
MQL resolution but BEFORE the sync validator phase runs (see
CommandApi.preloadValidatorDeps), so the sync body's data is
ready before it runs.
The preload's resolved value is passed back to the sync body as
its fourth argument (preloaded). For validators whose preload
just warms a singleton cache (the original use-case — e.g., a
requiresAnimateTarget validator preloading a species clade so
the sync findByTemplatePath hits warm), return void and the
sync body ignores the extra arg. For validators whose sync
decision is itself async (e.g., the access checks), return the
decision directly and the sync body reads it from preloaded.
Signature mirrors the sync body — (value, field, context).
Field validators that want per-bound-target deps inspect the
resolved Stuff and preload accordingly. Validators that only need
giver-side deps ignore value / field and read
context.commandGiver.
// Cache-warming preload (legacy shape — returns void):
const v: FieldValidator = (value, field, ctx) => { ... };
v.preload = async (value, field, ctx) => {
await StuffApi.singleton(somePathFromTarget(value));
};
// Decision-returning preload:
const v: FieldValidator<boolean> = (_v, _f, _ctx, allowed) =>
allowed ? undefined : 'denied';
v.preload = async (_v, _f, ctx) => AccessApi.can(ctx.commandGiver, 'x', null);
Omit on validators that only check mixin presence or call sync-pure helpers.
Field validator function type.
Returns
undefinedwhen the field is valid, or an error message string when it is invalid.Sync by design — see CommandValidator for the rationale and the
preloadescape hatch for sync validators that need singleton-backed reads.