import type { DbExec } from "../db/client.js"; export declare const SYNC_EVENTS_RETENTION_MS: number; export declare const SYNC_EVENTS_PRUNE_STATE_TABLE = "sync_events_prune_state"; export interface SyncEventsPruneOptions { now?: number; retentionMs?: number; batchSize?: number; maxBatches?: number; budgetMs?: number; statementTimeoutMs?: number; /** Absolute wall-clock deadline of the caller (a recurring sweep tick). */ deadlineAt?: number; signal?: AbortSignal; /** Probe even if a recent run found nothing to prune. */ force?: boolean; } /** * `idle` means the head of the table is newer than the retention cutoff. A * run that could not prune is `failed` and is recorded on the state row; it * never degrades into `idle`. */ export type SyncEventsPruneResult = { status: "pruned"; deleted: number; batches: number; drained: boolean; cursorVersion: number; } | { status: "idle"; } | { status: "lease-held"; } | { status: "failed"; error: string; deleted: number; consecutiveFailures: number; }; export interface SyncEventsPruneState { cursorVersion: number; leaseExpiresAt: number; lastRunAt: number | null; lastCheckedAt: number | null; lastSuccessAt: number | null; lastDeleted: number; totalDeleted: number; backlog: boolean; consecutiveFailures: number; lastError: string | null; lastErrorAt: number | null; } export declare function readSyncEventsPruneState(client: DbExec): Promise; /** * Delete sync events older than the retention window in bounded batches. * * Progress is a persisted version cursor and the lease lives on the same row, * so a cold instance resumes where the last one stopped and concurrent * instances skip instead of piling up. Every failure is counted on the row and * logged at error level, and is returned as `failed` rather than `idle`. */ export declare function pruneSyncEvents(client: DbExec, options?: SyncEventsPruneOptions): Promise;