import type { Connection } from '../connection'; import { type Storage } from './storage'; export interface BlobRecord { key: string; data: Uint8Array; mime: string; createdAt?: Date; } export interface ListedBlobRecord { key: string; mime: string; size: number; createdAt?: Date; } export type BlobSource = | { type: 'currentDoc'; workspaceId: string; docId: string } | { type: 'history'; workspaceId: string; docId: string; timestampMs: number; }; export interface SourceBlobRecord extends ListedBlobRecord { source: BlobSource; } export interface SourceScopedBlobStorage { registerSource(source: BlobSource, signal?: AbortSignal): Promise; unregisterSource(source: BlobSource): Promise; readableSources(signal?: AbortSignal): AsyncIterable; } export function isSourceScopedBlobStorage( storage: BlobStorage ): storage is BlobStorage & SourceScopedBlobStorage { return 'registerSource' in storage && 'readableSources' in storage; } export interface BlobStorage extends Storage { readonly storageType: 'blob'; readonly isReadonly: boolean; get( key: string, signal?: AbortSignal, source?: BlobSource ): Promise; set(blob: BlobRecord, signal?: AbortSignal): Promise; delete( key: string, permanently: boolean, signal?: AbortSignal ): Promise; release(signal?: AbortSignal): Promise; list(signal?: AbortSignal): Promise; } export abstract class BlobStorageBase implements BlobStorage { readonly storageType = 'blob'; abstract readonly connection: Connection; abstract readonly isReadonly: boolean; abstract get( key: string, signal?: AbortSignal, source?: BlobSource ): Promise; abstract set(blob: BlobRecord, signal?: AbortSignal): Promise; abstract delete( key: string, permanently: boolean, signal?: AbortSignal ): Promise; abstract release(signal?: AbortSignal): Promise; abstract list(signal?: AbortSignal): Promise; }