export interface LockHolder { pid: number; /** Epoch ms when the holder took the lock. */ startedAt: number; /** The project the holder was working on, for the waiting line. */ root: string; /** The command that took it — `verify`, `dev` — for the same line. */ command: string; } export interface MachineLockDeps { baseDir?: string; now?: () => number; sleep?: (ms: number) => Promise; isAlive?: (pid: number) => boolean; /** Epoch ms of this machine's boot, below which a holder cannot be alive. */ bootTime?: () => number; pid?: number; pollMs?: number; timeoutMs?: number; maxAgeMs?: number; /** Called once, the first time the lock turns out to be held by someone else. */ onWait?: (holder: LockHolder) => void; /** Called when a lock is reclaimed for being too old — the one stale case worth a warning. */ onStale?: (holder: LockHolder) => void; } export interface MachineLock { /** Whether acquiring involved waiting for another holder at all. */ readonly waited: boolean; /** Give it back. Idempotent; never removes a lock someone else has since taken. */ release(): void; } /** A poll, not a watch: cheap, portable, and a released lock is noticed within this. */ export declare const LOCK_POLL_MS = 500; /** How long a waiter queues before giving up with the holder's name. */ export declare const LOCK_TIMEOUT_MS: number; /** No holder legitimately keeps a lock this long; beyond it the record is treated as abandoned. */ export declare const LOCK_MAX_AGE_MS: number; export declare function lockPath(name: string, baseDir?: string): string; /** The recorded holder, or null for a file that is missing, empty or garbage. */ export declare function readLockHolder(file: string): LockHolder | null; /** Whether the holder is one no longer worth waiting for, and why. */ export declare function staleReason(holder: LockHolder, deps: { now: number; isAlive: (pid: number) => boolean; bootTime: number; maxAgeMs: number; }): 'dead' | 'pre-boot' | 'too-old' | null; export declare function acquireMachineLock(name: string, info: { root: string; command: string; }, deps?: MachineLockDeps): Promise; /** Hold `name` for the duration of `fn`, releasing however it ends. */ export declare function withMachineLock(name: string, info: { root: string; command: string; }, fn: (lock: MachineLock) => Promise, deps?: MachineLockDeps): Promise;