// Типы 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; /** откуда исходная картинка: сгенерирована (text — SDXL) или загружена */ imageSource: 'text' | 'upload'; /** исходная картинка */ image: BatchImage; /** последняя очищенная картинка (история очисток не хранится) */ clean: FileRef | null; cleanUpdated: number | null; /** идёт очистка: prompt_id в ComfyUI */ cleanJobId: string | null; /** ошибка последней очистки */ cleanError?: string; /** положение идущей очистки в очереди ComfyUI */ live?: LiveStatus; /** * 3D-модель без текстур (история не хранится). Генерирует её Hunyuan3D-2 mini или TRELLIS.2; * TRELLIS.2 заодно заполняет и texture. */ model: ModelArtifacts | null; /** идёт генерация модели: prompt_id в ComfyUI */ modelJobId: string | null; modelError?: string; /** положение идущей генерации в очереди ComfyUI */ modelLive?: LiveStatus; /** текстурированная модель и её текстуры (от TRELLIS.2 или Hunyuan3D-2 Paint) */ texture: TextureArtifacts | null; /** идёт текстурирование (Paint): prompt_id в ComfyUI */ textureJobId: string | null; textureError?: string; textureLive?: LiveStatus; } /** Чем сгенерирована 3D-модель. */ export type ModelGenerator = 'hunyuan' | 'trellis'; export const GENERATOR_NAMES: Record = { hunyuan: 'Hunyuan3D-2 mini', trellis: 'TRELLIS.2' }; /** Модель без текстур. */ export interface ModelArtifacts { generator: ModelGenerator; glb: FileRef; /** PNG-превью (рендер без текстур) */ preview: FileRef | null; /** число треугольников в GLB */ faces: number | null; /** мс */ updated: number; } /** Откуда текстуры: вместе с моделью от TRELLIS.2 или отдельным текстурированием Hunyuan3D-2 Paint. */ export type TextureSource = 'trellis' | 'paint'; /** Текстурированная модель и всё, что к ней относится; каких-то файлов может не быть (у Paint — metallic, roughness). */ export interface TextureArtifacts { source: TextureSource; /** текстурированная модель */ glb: FileRef | null; faces: number | null; baseColor: FileRef | null; /** металличность (канал B карты metallicRoughness glTF) в оттенках серого */ metallic: FileRef | null; /** шероховатость (канал G карты metallicRoughness glTF) в оттенках серого */ roughness: FileRef | null; /** изображение UV-развёртки */ uv: FileRef | null; /** виды: у TRELLIS.2 — рендеры модели с 4 сторон, у Paint — 6 видов, нарисованных моделью */ views: FileRef[]; /** мс */ updated: number; } /** Генерация 3D-модели проекта. */ export interface ProjectModelRequest { generator: ModelGenerator; /** Пусто — случайный. */ seed: number | string; /** Hunyuan3D-2 mini */ steps: number | string; octree: number | string; /** целевое число треугольников после упрощения */ faces: number | string; /** TRELLIS.2: размер текстуры, px */ textureSize: number | string; /** TRELLIS.2: металличность и шероховатость (карты metallic, roughness) в модели */ pbr: boolean; } /** Текстурирование модели проекта (Hunyuan3D-2 Paint). */ export interface ProjectTextureRequest { /** Пусто — случайный. */ seed: number | string; /** размер текстуры, px */ textureSize: number | string; /** снимать блики и тени с картинки (Hunyuan3D Delight) */ delight: boolean; } 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' | 'texture'; 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; generator: ModelGenerator; seed: number; faces: number; /** Hunyuan3D-2 mini */ steps?: number; octree?: number; /** TRELLIS.2 */ textureSize?: number; pbr?: boolean; } export interface TextureParams { /** проект, к которому прикрепляется результат */ projectId: number; seed: number; textureSize: number; delight: boolean; } 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, texture) */ models: FileRef[]; live?: LiveStatus; } export type Text2ImgJob = JobOf<'text2img', Text2ImgParams>; export type CleanupJob = JobOf<'cleanup', CleanupParams>; export type ModelJob = JobOf<'model', ModelParams>; export type TextureJob = JobOf<'texture', TextureParams>; export type Job = Text2ImgJob | CleanupJob | ModelJob | TextureJob; // ---------- значения полей форм (тоже в 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 { generator: ModelGenerator; seed: string; /** Hunyuan3D-2 mini */ steps: string; octree: string; faces: string; /** TRELLIS.2 */ trellisFaces: string; textureSize: string; trellisPbr: boolean; } export interface TextureSettings { seed: string; textureSize: string; delight: boolean; } export type SettingsByPage = { text2img: Text2ImgSettings; cleanup: CleanupSettings; model: ModelSettings; texture: TextureSettings; }; 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.';