/** * Eager Blob Downloader * * Downloads unresolved blobs in the background when blobMode='eager'. * Called after sync completes to prefetch blobs for offline access. * * Strategy: * 1. Snapshot the primary keys of all rows currently flagged * `_hasBlobRefs=1` for each syncable table. * 2. Walk that key list in chunks via `bulkGet`. Each `bulkGet` * triggers the blob-resolve middleware, which does all the actual * work — downloading blobs (throttled and deduplicated by the * shared BlobDownloadTracker) and enqueueing them for persistence * via the internal save queue. * * This keeps a single, symmetric code path with normal application * reads, which is important when other middlewares are present * (e.g., a hypothetical encryption middleware): writes from the save * queue and reads from this loop both pass through the full middleware * stack, so on-disk representation stays consistent. * * Why a snapshot of primary keys (rather than re-querying the index)? * - Rows that get resolved by parallel application reads simply * disappear from the table contents we're about to re-fetch; the * middleware skips them since `_hasBlobRefs` is already cleared. * - Stuck rows (e.g., blob 404s) are naturally bypassed: we just * advance to the next chunk in the snapshot. No `seenKeys` * bookkeeping required. * - The snapshot is `string[]`-shaped for typical Dexie Cloud rows * (~36 bytes/UUID), so ~28K keys per MB. Acceptable for any * realistic dataset. * * Progress is tracked automatically via liveQuery in blobProgress.ts — * no manual progress reporting needed here. * * --- Throughput note --- * The chunk loop is sequential: bulkGet → wait for all downloads to * settle → next bulkGet. The save queue drains in the background and * does not block iteration (saves no longer need to be persisted before * the next iteration, since we don't re-query the index). For typical * blob sizes (10 KB – 10 MB) the network dominates total time. If * real-world profiling later shows the per-chunk fixed cost matters, * the next bulkGet could be kicked off in parallel with the current * one's middleware work — but we keep it simple until measurements * justify otherwise. */ import { BehaviorSubject } from 'rxjs'; import { DexieCloudDB } from '../db/DexieCloudDB'; /** * Download all unresolved blobs in the background. * * This is called when blobMode='eager' (default) after sync completes. */ export declare function downloadUnresolvedBlobs(db: DexieCloudDB, downloading$: BehaviorSubject, signal?: AbortSignal): Promise;