/** Delete every orphaned ".part" in the cache, returning how many were * removed and the bytes they held. * * A .part file at rest is by definition the debris of a download that never * finished — the rename that promotes one is the last step of `downloadFile`, * so a live .part exists only while THIS process is writing it. Sweeping at * startup is therefore safe, and it is load-bearing rather than cosmetic: * `cacheSize` deliberately counts .part files (an in-flight download really * does occupy the disk), so debris left by a killed run consumes ceiling * budget that nothing would ever free, and `ensureCacheRoom` would wait for * room that cannot appear. * * The one assumption is that a cache directory belongs to ONE run at a time. * That was already true — two trainers sharing CACHE_DIR would write the same * .part path — so this adds no constraint that did not exist. */ export declare function sweepPartials(): { files: number; bytes: number; }; /** Total bytes currently held in the cache directory — INCLUDING any .part * file, because an in-flight download occupies the disk like any other file. * Orphaned ones are removed by {@link sweepPartials} at startup. */ export declare function cacheSize(): number; /** Block until there is room for a file of `fileBytes` under the ceiling. * A single file larger than the whole ceiling can never "fit", so we let it * through (it is deleted right after processing) rather than wait forever. */ export declare function ensureCacheRoom(fileBytes: number, signal: AbortSignal, warn?: (msg: string) => void, maxWaitMs?: number): Promise; export interface DownloadOptions { signal: AbortSignal; tries: number; onFail?: (attempt: number, err: Error) => void; onProgress?: (done: number, total: number) => void; } /** Stream `url` to `destPath`, atomically and with backpressure. */ export declare function downloadFile(url: string, destPath: string, opts: DownloadOptions): Promise;