import { type Credential } from "@bastani/pi-ai"; export type LockResult = { result: T; next?: string; }; export interface AuthStorageBackend { /** * Read the current credential snapshot WITHOUT acquiring the exclusive write * lock. Pure reads do not need cross-process write-exclusion: writers replace * the file atomically (temp file + rename), so a lock-free reader always * observes a complete previous-or-next snapshot, never a torn one. Keeping * reads lock-free is what prevents many concurrent sessions from starving each * other on `auth.json` and misreporting configured providers as unreadable * under contention (issue #1431). * * Optional for backward compatibility with custom backends that predate this * method (the released `AuthStorageBackend` interface): when absent, * `AuthStorage.reload()` falls back to a `withLock`-based read. */ read?(): string | undefined; version?(): string; deleteProvider?(provider: string): string | undefined; deleteProviderAsync?(provider: string): Promise; modifyProviderAsync?(provider: string, fn: (current: Credential | undefined) => Promise, signal?: AbortSignal): Promise>; withLock(fn: (current: string | undefined) => LockResult): T; withLockAsync(fn: (current: string | undefined) => Promise>): Promise; } export declare class FileAuthStorageBackend implements AuthStorageBackend { private authPath; private readPaths; constructor(authPath?: string, readPaths?: string[]); modifyProviderAsync(provider: string, fn: (current: Credential | undefined) => Promise, signal?: AbortSignal): Promise>; private ensureParentDir; private ensureFileExists; private getRetryableLockErrorCode; /** Takes a provider lock, waiting up to PROVIDER_LOCK_WAIT_MS for its holder; the caller's signal stops the wait. */ private acquireProviderLock; private acquireLockSyncWithRetry; private readMergedAuth; /** * Atomically replace `auth.json` with `content`: write a sibling temp file * (same directory, so `rename` is a same-filesystem atomic swap), fix its * permissions, then `rename` it over the target. Lock-free readers therefore * never observe a half-written file. The temp file is best-effort cleaned up * if the rename fails. */ private writeAtomic; read(): string | undefined; version(): string; deleteProvider(provider: string): string | undefined; deleteProviderAsync(provider: string): Promise; withLock(fn: (current: string | undefined) => LockResult): T; withLockAsync(fn: (current: string | undefined) => Promise>): Promise; } export declare class InMemoryAuthStorageBackend implements AuthStorageBackend { private value; private pendingWrite; read(): string | undefined; withLock(fn: (current: string | undefined) => LockResult): T; withLockAsync(fn: (current: string | undefined) => Promise>): Promise; } //# sourceMappingURL=auth-storage-backends.d.ts.map