/** DB-name prefix for the per-(session,kind) recording buffers. */ export declare const RECORDING_DB_PREFIX = "proctoring-rec"; /** The IndexedDB database name for a recording buffer. */ export declare function recordingDbName(sessionId: string, kind: string): string; export interface DurableBlobStoreOptions { sessionId: string; kind: "screen" | "webcam"; /** * Max persisted-but-un-committed bytes. Over this the oldest record is * evicted (front truncation → the server completes up to the gap). * Default 128 MB — comfortably above the uploader's in-memory buffer cap, * so in normal operation commit() keeps disk near the un-acked working set. */ maxBytes?: number; /** * Max bytes queued for write but not yet persisted. Over this the oldest * pending write is dropped. The memory backstop for a stalled IndexedDB. * Default 32 MB. */ maxPendingBytes?: number; /** Fires once when the store degrades to a no-op (IndexedDB unusable). */ onDegrade?: (reason: string) => void; /** Fires when a record/pending-write is dropped by a cap (byte count). */ onEvict?: (bytes: number, reason: "disk-cap" | "pending-cap") => void; } /** * Open a durable blob store for one recording stream. Never rejects: on any * IndexedDB failure it returns a degraded no-op store (recording falls back * to the in-memory buffer). Call {@link DurableBlobStore.close} when done. */ export declare function openDurableBlobStore(opts: DurableBlobStoreOptions): Promise; export declare class DurableBlobStore { private readonly opts; private db; private degraded; /** Running absolute offset for the NEXT appended byte. Persisted. */ private totalBytes; /** Front truncation watermark from eviction. Persisted. */ private floorBytes; /** * Snapshot of `totalBytes` at open. `restore()` only returns records BELOW * this — i.e. the tail persisted by PRIOR instances (a refresh). Blobs this * instance appends live sit at or above it and must never be restored, or a * resume would re-prepend (and thus duplicate) its own live bytes. */ private openTotalBytes; /** Actual bytes currently stored (drives the disk cap; not persisted). */ private diskBytes; private writeChain; private pendingBytes; constructor(opts: DurableBlobStoreOptions); open(): Promise; /** * Persist one recorder blob. Non-blocking: enqueues onto the serialised * writer. Assigns the blob its absolute offset synchronously so ordering is * deterministic even if writes settle out of order. */ append(blob: Blob): void; private writeRecord; /** * The un-committed tail as blobs, in order, sliced exactly at * `committedBytes` (bytes already durably in S3, from the server's resume * point). Records fully below the watermark are ignored; a straddling * record is sliced. Returns [] when degraded or nothing remains. */ restore(committedBytes: number): Promise; /** Delete records lying fully below `committedBytes`. Front truncation. */ commit(committedBytes: number): Promise; /** Drop everything (call after a graceful multipart complete). */ clear(): Promise; /** Await all queued writes. */ flush(): Promise; close(): Promise; /** Actual bytes currently persisted (post-commit / post-eviction). */ bytesOnDisk(): number; isDegraded(): boolean; private enforceDiskCap; private degrade; } /** * Delete recording buffers left over from previous sessions. Keeps the DBs * named in `keep` (the current session's). Mirrors the event queue's stale * sweep; no-ops where `indexedDB.databases()` is unavailable. Returns the * count deleted. */ export declare function sweepOrphanRecordingStores(keep?: ReadonlySet): Promise; //# sourceMappingURL=durable-blob-store.d.ts.map