/** * A two-phase writer for one generation run: every file is staged next to its * final location under a temporary name, and only once the whole set is on disk * are the temporaries renamed into place. * * The failure mode it exists for is **partial trees**. Writing straight to the * final paths meant a failure halfway through (a `_helpers` path occupied by a * regular file, a full disk) left some generated files behind and others missing * — a tree that compiles against a schema that no longer exists. Staging first * means the run either lands completely or leaves the destination as it found it. * Renaming is not one atomic operation across the whole set, but every rename * happens after all the risky work (generating, creating directories, writing * bytes) has already succeeded, so it is the cheapest place to get the guarantee. * * A generated path that already exists is simply replaced. The writer keeps no * record of what it produced last time: an output directory is generated output, * and version control is where a user sees — and reverts — a replacement they did * not want. What the writer still guarantees is that `--build` only ever deletes * intermediate sources this run committed, so nothing that was already sitting in * the output directory is removed. */ export type OutputWriter = { /** * Stages one file. `relativePath` is relative to the writer's root and may * contain subdirectories; parent directories are created eagerly. */ readonly stage: (relativePath: string, content: string) => Promise; /** Moves every staged file to its final path and returns the committed paths. */ readonly commit: () => Promise; /** Deletes the staged temporaries; call this when the run fails before committing. */ readonly discard: () => Promise; }; /** * Creates an {@link OutputWriter} rooted at `rootDir`. * * Still async with nothing to await: it read the previous run's manifest here * until that was removed, and every call site already awaits it. Keeping the * signature leaves room for setup that does need I/O. * * @param rootDir - Output root. Every write must resolve inside it. */ export declare const createOutputWriter: (rootDir: string) => Promise;