// Типы API между страницами и сервером. /** Файл в папках ComfyUI (как в ответах ComfyUI и параметрах /view). */ export interface FileRef { filename: string; subfolder: string; type: string; // 'input' | 'output' | 'temp' } export interface ApiError { error: string; } // ---------- батчи картинок (ImageBatches + источники + Images) ---------- /** Пользовательский ввод text2img (ImageBatchTextSources) — всё, что нужно, чтобы повторить запуск. */ export interface Text2ImgInput { shape: string; colors: string; /** Шаблон как его ввёл пользователь: {a} — форма, {b} — цвета. Пусто — шаблон по умолчанию. */ template: string; negative: string; /** Картинок в батче. */ batch: number; /** Как введено: пусто — случайный при каждом запуске. */ seed: string; } /** * draft — можно править и запускать; pending — в работе; done / error — завершён. * Батч с картинками, в работе или из загрузки заблокирован: text-батч можно только продублировать. */ export type BatchState = 'draft' | 'pending' | 'done' | 'error'; /** Картинка батча (Images): id и проект, если из неё создан проект. */ export interface BatchImage extends FileRef { id: number; projectId: number | null; } /** Проект — работа над одной картинкой из батча. */ export interface Project { id: number; created: number; /** батч, из которого картинка */ batchId: number; /** исходная картинка */ image: BatchImage; /** последняя очищенная картинка (история очисток не хранится) */ clean: FileRef | null; cleanUpdated: number | null; /** идёт очистка: prompt_id в ComfyUI */ cleanJobId: string | null; /** ошибка последней очистки */ cleanError?: string; /** положение идущей очистки в очереди ComfyUI */ live?: LiveStatus; /** последняя 3D-модель из очищенной картинки: GLB и PNG-превью (история не хранится) */ model: FileRef | null; modelPreview: FileRef | null; modelUpdated: number | null; /** число треугольников в GLB (null — неизвестно) */ modelFaces: number | null; /** идёт генерация модели: prompt_id в ComfyUI */ modelJobId: string | null; modelError?: string; /** положение идущей генерации модели в очереди ComfyUI */ modelLive?: LiveStatus; } /** Генерация 3D-модели проекта. */ export interface ProjectModelRequest { /** Пусто — случайный. */ seed: number | string; steps: number | string; octree: number | string; faces: number | string; } interface BatchBase { id: number; created: number; updated: number; /** ImageBatchTextSources.id или ImageBatchUploadSources.id — по sourceType */ sourceId: number; state: BatchState; error?: string; /** Из какого батча продублирован. */ clonedFrom: number | null; /** Картинки батча (Images.batchId). */ images: BatchImage[]; live?: LiveStatus; } export interface TextBatch extends BatchBase { sourceType: 'text'; source: { id: number; input: Text2ImgInput }; /** prompt_id последнего запуска в ComfyUI. */ jobId: string | null; /** Фактический seed последнего запуска. */ seedUsed: number | null; /** Итоговый позитивный промпт последнего запуска. */ prompt: string; } export interface UploadBatch extends BatchBase { sourceType: 'upload'; /** Исходные имена загруженных файлов. */ source: { id: number; files: string[] }; } export type ImageBatch = TextBatch | UploadBatch; /** В батче есть картинка, из которой создан проект. */ export function hasProject(b: ImageBatch): boolean { return b.images.some(i => i.projectId != null); } export function isLocked(b: ImageBatch): boolean { return b.sourceType === 'upload' || b.state === 'pending' || b.images.length > 0; } // ---------- запросы на запуск ---------- /** Очистка исходника проекта. */ export interface CleanupRequest { size: number | string; /** Отступ от объекта до края кадра, px с каждой стороны. */ margin: number | string; grow: number | string; background: string; } // ---------- задачи ComfyUI (таблица jobs; отслеживаются трекером) ---------- export type JobType = 'text2img' | 'cleanup' | 'model'; export type JobState = 'pending' | 'done' | 'error'; /** Состояние незавершённой задачи в очереди ComfyUI (не хранится, считается сервером на лету). */ export type LiveStatus = { state: 'queued'; position: number } | { state: 'running' }; export interface Text2ImgParams { /** батч (ImageBatches.id), к которому прикрепляются картинки */ batchId: number; shape: string; colors: string; template: string; negative: string; batch: number; seed: number; /** Итоговый позитивный промпт, как его увидит модель. */ prompt: string; } export interface CleanupParams { /** проект, к которому прикрепляется результат */ projectId: number; size: number; margin: number; grow: number; background: string; } export interface ModelParams { /** проект, к которому прикрепляется модель */ projectId: number; seed: number; steps: number; octree: number; faces: number; } interface JobOf { /** prompt_id в ComfyUI */ id: string; type: T; /** мс с эпохи */ created: number; state: JobState; error?: string; /** картинка-исходник (для cleanup и model) */ source: FileRef | null; params: P; /** результаты-картинки (для model — PNG-превью) */ images: FileRef[]; /** GLB-файлы (только model) */ models: FileRef[]; live?: LiveStatus; } export type Text2ImgJob = JobOf<'text2img', Text2ImgParams>; export type CleanupJob = JobOf<'cleanup', CleanupParams>; export type ModelJob = JobOf<'model', ModelParams>; export type Job = Text2ImgJob | CleanupJob | ModelJob; // ---------- значения полей форм (тоже в SQLite) ---------- export interface Text2ImgSettings { shape: string; colors: string; template: string; negative: string; batch: string; seed: string; promptsOpen: boolean; } export interface CleanupSettings { size: string; margin: string; grow: string; background: string; } export interface ModelSettings { seed: string; steps: string; octree: string; faces: string; } export type SettingsByPage = { text2img: Text2ImgSettings; cleanup: CleanupSettings; model: ModelSettings }; export type SettingsPage = keyof SettingsByPage; // ---------- очередь ComfyUI ---------- export type JobKind = 'генерация' | 'очистка фона' | '3D-модель' | 'другое'; export interface QueueItem { id: string; kind: JobKind; } export interface QueueInfo { running: QueueItem[]; pending: QueueItem[]; } // ---------- перенос из localStorage старой версии ---------- export interface ImportRequest { settings: Partial<{ [P in SettingsPage]: Partial }>; } export const DEFAULT_TEMPLATE = 'Game character. Full body visible. Empty arms. {a}, centered on white background. {b}. Game sprite aesthetic.';