Files
sprite-ai/shared/api.ts
T

332 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Типы 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<ModelGenerator, string> = { 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<T extends JobType, P> {
/** 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<SettingsByPage[P]> }>;
}
export const DEFAULT_TEMPLATE =
'Game character. Full body visible. Empty arms. {a}, centered on white background. {b}. Game sprite aesthetic.';