/** * BlobSavingQueue - Queues resolved blobs for saving back to IndexedDB. * * This is an internal collaborator of BlobDownloadTracker and is not * intended to be used directly by middleware or other code. See * BlobDownloadTracker.enqueueSave(). * * Uses setTimeout(fn, 0) instead of queueMicrotask to completely isolate * from Dexie's Promise.PSD context. This prevents the save operation * from inheriting any ongoing transaction. * * Each blob is saved atomically using downCore transaction with the specific * keyPath to avoid race conditions with other property changes. */ import { ResolvedBlob } from './blobResolve'; import { DexieCloudDB } from '../db/DexieCloudDB'; export declare class BlobSavingQueue { private queue; private isProcessing; private db; private onPersisted; private drainResolvers; constructor(db: DexieCloudDB, onPersisted: (refs: string[]) => void); /** * Queue a resolved blob for saving. * Only the specific blob property will be updated atomically. */ saveBlobs(tableName: string, primaryKey: any, resolvedBlobs: ResolvedBlob[]): void; /** * Returns a promise that resolves when the queue is empty AND no item * is currently being processed. Used by callers that need to know when * all previously enqueued saves have been persisted to IndexedDB before * making decisions based on the on-disk state (e.g., the eager blob * downloader looping over `_hasBlobRefs=1` rows in chunks). * * Note: New work enqueued AFTER drain() is called does NOT extend the * wait. Callers that race against concurrent producers should treat the * returned promise as "queue was empty at some point after this call". */ drain(): Promise; /** * Start the consumer if not already processing. * Uses setTimeout(fn, 0) to completely break out of any * Dexie transaction context (Promise.PSD). */ private startConsumer; /** * Process all queued blobs. * Runs in a completely isolated context (no inherited transaction). * Uses atomic updates to avoid race conditions. */ private processQueue; }