import { renameSync } from "node:fs"; import { type FileLockOptions } from "./file-lock.js"; /** * Windows can transiently reject an otherwise-valid replace rename while another short-lived * reader (including AV/indexing software) has the destination open. Keep retrying the SAME temp * file for about one second; never unlink the destination, because that would create a visibility * gap and weaken the atomic-write contract. * * The injected dependencies are a deterministic test seam. Production callers omit them. */ export declare function replaceFileWithRetrySync(sourcePath: string, targetPath: string, deps?: { readonly platform?: NodeJS.Platform | undefined; readonly rename?: typeof renameSync | undefined; readonly sleep?: ((ms: number) => void) | undefined; }): void; /** * Options for atomic JSON serialization and file writes. */ export interface AtomicJsonWriteOptions { readonly space?: number | undefined; readonly mode?: number | undefined; /** If true, write failures throw instead of failing silently. Defaults to false (best-effort). */ readonly strict?: boolean | undefined; } /** * Options for safe JSON reading. */ export interface SafeJsonReadOptions { readonly validator?: ((data: unknown) => data is T) | undefined; readonly fallback?: T | undefined; } /** * Atomically writes data to a JSON file via an adjacent temp file and atomic rename. * Guarantees directory creation and cleans up temporary files on failure. */ export declare function atomicWriteJsonSync(targetPath: string, data: unknown, options?: AtomicJsonWriteOptions): boolean; /** * Safely reads and parses a JSON file, guarding against missing files, IO errors, * corrupt JSON syntax, and invalid schema shapes. */ export declare function safeReadJsonSync(targetPath: string, options?: SafeJsonReadOptions): T | null; /** * Options for a synchronous read/update/write transaction over one JSON file. * * The lock covers the read as well as the atomic rename. That is the part an atomic writer alone * cannot provide: without it, two processes can both read snapshot N and each replace it with a * different N+1, losing whichever row the earlier rename introduced. */ export interface TransactionalJsonUpdateOptions extends AtomicJsonWriteOptions { readonly validator?: ((data: unknown) => data is T) | undefined; readonly lock?: FileLockOptions | undefined; } /** * Serialize one JSON mutation across processes, then commit it with the existing atomic writer. * * A failed lock/read/write is best-effort by default, matching atomicWriteJsonSync. strict=true * makes the failure visible to a caller that wants to decide its own fallback policy. */ export declare function transactionalUpdateJsonSync(targetPath: string, update: (current: T | null) => T, options?: TransactionalJsonUpdateOptions): boolean;