/** * Persistent record of the last successful prune run. Survives Signal K * restarts so the weekly/monthly cadence is measured in wall-clock time, * not continuous process uptime — a dev box that restarts the server * daily still prunes once the interval has elapsed. */ export interface PruneStateStore { /** Epoch ms of the last successful run, or null if never run. */ load(): number | null; save(lastRunAt: number): void; } /** * File-backed store. Failures are non-fatal — an unreadable or corrupt * state file means the next prune is treated as due (the run itself is * idempotent and cheap), and a failed write just repeats that on the * next start. */ export declare class FilePruneStateStore implements PruneStateStore { private readonly path; private readonly debug; constructor(path: string, debug?: (msg: string) => void); load(): number | null; save(lastRunAt: number): void; } /** In-memory store for tests. */ export declare class MemoryPruneStateStore implements PruneStateStore { private lastRunAt; load(): number | null; save(lastRunAt: number): void; } export interface PruneClock { now(): number; setTimer(fn: () => void, delayMs: number): unknown; clearTimer(handle: unknown): void; } /** * Grace period before an overdue (or never-run) prune fires after * startup, so image cleanup doesn't compete with runtime detection, * update checks, and consumer-plugin container starts happening in the * same boot window. */ export declare const STARTUP_PRUNE_DELAY_MS: number; /** * Long waits are chained in chunks instead of a single timer. This keeps * every delay far below Node's 2^31-1 ms setTimeout ceiling (a 30-day * "monthly" interval overflows it and would fire immediately) and * re-anchors the due time against the wall clock, which drifts from * timer time across system sleep. */ export declare const MAX_TIMER_CHUNK_MS: number; export interface PruneSchedulerOptions { intervalMs: number; /** * The prune work. A resolved run records a new last-run timestamp; a * rejected run does not, so it is retried one interval later (and * shortly after the next startup, since it stays overdue). */ run: () => Promise; store: PruneStateStore; clock?: PruneClock; debug?: (msg: string) => void; startupDelayMs?: number; maxTimerChunkMs?: number; } /** * Schedules the prune/reap pass against wall-clock due times persisted * in a PruneStateStore. `start()` computes the next due time from the * stored last run — running shortly after startup when overdue — and * each completed run schedules the next one interval later. */ export declare class PruneScheduler { private readonly intervalMs; private readonly run; private readonly store; private readonly clock; private readonly debug; private readonly startupDelayMs; private readonly maxTimerChunkMs; private timer; private stopped; constructor(opts: PruneSchedulerOptions); start(): void; stop(): void; private scheduleAt; private fire; } //# sourceMappingURL=pruneScheduler.d.ts.map