/** * @module pipeline * * B23 — the per-field generation pipeline, promoted from a flat `for` body * with 7 inline rungs in `WorldImpl.generateObjectFields` to a `PIPELINE` * list of named `PipelineStep` functions returning a `FieldResolution` * tagged union. * * The same list powers three call sites: * - `WorldImpl.generateObjectFields` walks `PIPELINE` per field; * - `explainSchema` (in `src/explain.ts`) walks `PIPELINE` with * `dryRun: true` for read-only inspection; * - `generateZodObject` (in `src/generators/schema/collection.ts`) walks * `PIPELINE_NO_REGISTRATION` — a 3-step subset omitting the four * registration-dependent rungs. * * PRNG fork keys, deep-merge contracts (B12 / B18), and absent-roll * semantics are preserved byte-identically — see B23-R5 / B23-R6. */ import type { ZodTypeAny } from "zod"; import type { GeneratorContext, KeyGenerator } from "./types.js"; import type { TraceResolution } from "./trace.js"; export interface SchemaReg { readonly schema: ZodTypeAny; readonly from: ZodTypeAny | null; readonly sourceKey: string | null; readonly relations: Record boolean) | null; }>; readonly matchers: Record unknown>; readonly regId: number; } export declare const EMPTY_SCHEMA_REG: SchemaReg; export type FieldResolution = { kind: "override"; value: unknown; } | { kind: "matcher"; value: unknown; } | { kind: "keymap"; value: unknown; } | { kind: "absent"; value: undefined | null; } | { kind: "default"; value: unknown; } | { kind: "custom-gen"; value: unknown; } | { kind: "key-based"; value: unknown; } | { kind: "schema-based"; value: unknown; }; /** * Mutable side-channel used by `unwrapOptionalStep` to communicate the * unwrapped inner schema to downstream steps. The context reference itself * is readonly on `PipelineStepContext`, but the slot inside it is mutated * by step 3 before falling through to steps 4-6. */ export interface PipelineState { inner: ZodTypeAny; } export interface PipelineStepContext { /** The field's Zod schema (pre-unwrap-optional). */ readonly fieldSchema: ZodTypeAny; /** The field name (the property key on the Zod object's shape). */ readonly fieldName: string; /** The field's `GeneratorContext` — carries `prng`, `gen`, `source`, etc. */ readonly fieldCtx: GeneratorContext; /** Pre-extracted override slice for this field (`overrides?.[key]`). */ readonly fieldOverride: unknown; /** Registration record for the outer (registered) schema; `EMPTY_SCHEMA_REG` for ad-hoc. */ readonly reg: SchemaReg; /** The outer object schema reference (used by `schemaKeyMapStep`'s two-level lookup). */ readonly outerSchema: ZodTypeAny; /** Lazy-resolved schema for the same lookup. */ readonly resolvedSchema: ZodTypeAny; /** World-level custom key generators (registered via `withGenerators`). */ readonly customKeyGenerators: ReadonlyMap; /** Per-schema key maps (registered via `withKeyMap`). */ readonly schemaKeyMaps: ReadonlyMap unknown>>; /** Optional-roll probability (`world.options.optionalProbability ?? 0.2`). */ readonly optionalProbability: number; /** * Read-only dry-run flag. When `true`, steps MUST NOT execute side-effects * (no PRNG draws, no `applyModifiers`, no generator invocations). Steps * report the resolution they would produce as a `FieldResolution` with * `value: undefined`; the `explainSchema` walk consumes the `kind` field * and the `meta` slot (for keyHeuristicStep's identifier/reason). */ readonly dryRun: boolean; /** Mutable slot for the unwrapped inner schema (written by step 3, read by 4-6). */ readonly state: PipelineState; /** * Mutable slot for explain-mode metadata (rendered identifier + reason). * * B97: on the hot generate() path this is `null` so the per-field ctx * literal stores one slot instead of allocating a nested `{}`. Pipeline * steps that write to `explainMeta` MUST null-check first; only the * `explain()` path in `src/explain.ts` constructs a `{}` and reads the * captured identifier/reason. */ readonly explainMeta: { identifier?: string; reason?: string; } | null; } export type PipelineStep = (ctx: PipelineStepContext) => FieldResolution | null; export declare function traceResolutionForKind(kind: FieldResolution["kind"]): TraceResolution; /** * B12 deep-merge helper. Applies a plain-object override on top of a value * (arrays / primitives / atomic objects replace verbatim via `deepMerge`). * Retained as a standalone helper (the B23-R6 contract); the per-rung override * application now flows through {@link applyOverride} (B134). */ export declare function applyObjectOverride(value: unknown, fieldOverride: unknown): unknown; export declare function applyOverride(fieldOverride: unknown, generateRaw: () => FieldResolution): FieldResolution; export declare function overrideEagerStep(_ctx: PipelineStepContext): FieldResolution | null; export declare function matcherStep(ctx: PipelineStepContext): FieldResolution | null; export declare function schemaKeyMapStep(ctx: PipelineStepContext): FieldResolution | null; export declare function unwrapOptionalStep(ctx: PipelineStepContext): FieldResolution | null; export declare function customKeyGenStep(ctx: PipelineStepContext): FieldResolution | null; export declare function keyHeuristicStep(ctx: PipelineStepContext): FieldResolution | null; export declare function schemaBasedStep(ctx: PipelineStepContext): FieldResolution | null; export declare const PIPELINE: ReadonlyArray; export declare const PIPELINE_NO_REGISTRATION: ReadonlyArray; /** * Walks `pipeline` in order. Returns the first non-`null` `FieldResolution` * a step produces. `schemaBasedStep` always resolves, so the loop never * falls off the end for a valid context; the throw is a regression guard. */ export declare function walkPipeline(pipeline: ReadonlyArray, ctx: PipelineStepContext): FieldResolution; //# sourceMappingURL=pipeline.d.ts.map