/** Written into the lock file so a waiter can identify — and outlive — its holder. */ interface LockRecord { pid: number; host: string; acquiredAt: number; } export interface ProvisioningLock { /** Release the lock. Safe to call twice; never throws. */ release(): void; } export interface AcquireLockOptions { /** Give up after this long and throw. Default 30s — long enough to outlast a * normal provisioning run, short enough that a wedged CLI still returns. */ timeoutMs?: number; /** How long an UNREADABLE lock file must sit before it is assumed abandoned. */ staleMs?: number; /** Injected for tests. */ now?: () => number; sleep?: (ms: number) => Promise; } export declare class ProvisioningLockTimeoutError extends Error { readonly code: "provisioning_locked"; constructor(path: string, holder: LockRecord | null, waitedMs: number); } export declare function provisioningLockPath(stateDir: string): string; /** * Take the provisioning lock, waiting for a live holder to finish. * * Throws {@link ProvisioningLockTimeoutError} rather than proceeding unlocked: * running anyway is the one outcome this module exists to prevent, and a clear * refusal naming the holder is far more actionable than an interleaved write. */ export declare function acquireProvisioningLock(stateDir: string, options?: AcquireLockOptions): Promise; /** Run `fn` holding the lock, releasing it on every path including a throw. */ export declare function withProvisioningLock(stateDir: string, fn: () => Promise, options?: AcquireLockOptions): Promise; export {}; //# sourceMappingURL=provisioning-lock.d.ts.map