import type { ImageContent } from "./content.ts"; import { debugLog } from "./debug.ts"; export interface ImagePipelineDeps { resizeModelImage?: (image: ImageContent) => Promise; resizePreviewImage?: (image: ImageContent) => Promise; storeImage?: (image: ImageContent) => Promise; } /** One source, independently cached model/preview bytes, and one model blob. */ export class PreparedImage { private modelPromise?: Promise; private previewPromise?: Promise; private referencePromise?: Promise; preview?: ImageContent; reference?: string; constructor(readonly source: ImageContent, private readonly deps: ImagePipelineDeps) {} model(): Promise { return this.modelPromise ??= this.resize(this.deps.resizeModelImage); } thumbnail(): Promise { return this.previewPromise ??= this.resize(this.deps.resizePreviewImage).then((image) => { this.preview = image; return image; }); } persist(): Promise { return this.referencePromise ??= this.model().then(async (image) => { try { this.reference = await this.deps.storeImage?.(image); } catch (error) { debugLog("Failed to persist model image", error); } return this.reference; }); } private async resize(resize?: (image: ImageContent) => Promise): Promise { try { return resize ? await resize(this.source) : this.source; } catch (error) { debugLog("Image preparation failed; keeping source attachment", error); return this.source; } } }