initial commit

This commit is contained in:
Aggtaa
2026-09-23 21:56:40 +03:00
commit 77da3ec94e
39 changed files with 9667 additions and 0 deletions
+240
View File
@@ -0,0 +1,240 @@
// Типы 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<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) */
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<SettingsByPage[P]> }>;
}
export const DEFAULT_TEMPLATE =
'Game character. Full body visible. Empty arms. {a}, centered on white background. {b}. Game sprite aesthetic.';