# План разработки: easy-png-tools > **Статус (2026-09-07):** Фаза 1 (полноценный TS-сайт) в основном выполнена — > сайт живёт, каталог переведён в типизированный `registry-new` (121/125), идёт > редизайн на `preview/*` по `plan-redesign.md` (параллельная ветка, старый UI > на `(old)/`). Фазы 2–8 (эталоны, Rust/wasm, CLI, harness) — будущие, разделам > ниже не запущены. ## 0. Решения - **Набор PNG-утилит, всё в браузере** (SvelteKit + `adapter-static`), данные не покидают машину. - **Первый и главный приоритет — полностью рабочий TS-сайт**: максимум простых инструментов уровня EASY, UX/UI, пайплайны (несколько инструментов подряд), описания инструментов. Сайтом можно пользоваться уже после этой фазы. - **Никакого wasm/Rust на этом этапе.** TS-реализация на canvas + `ImageData` — эталон алгоритмов, из которого позже генерируются эталонные файлы для проверки Rust-порта. Rust-ядро, WASM и CLI — отдельные фазы позже, когда сайт живёт. - **Пайплайн = JSON-список шагов** `{tool, params}`. Формат закладывается сейчас и потом станет общим для браузера, wasm и CLI. - **Реестр инструментов** (id, title, description, схема параметров, `run`) — источник истины: из него генерируются страницы, формы, пайплайны. Позже — общий формат для Rust-парсера. - Валидация будущего Rust-порта — эталонные файлы, сгенерированные из TS-реализации. Сравнение: **бит-в-бит** для чистых пиксельных операций, **perceptual diff** для canvas-зависимых. - **Единая точка исполнения инструментов.** Страницы вызывают операции только через `web/src/lib/tools/executor.ts::executeStep` — нигде напрямую `tool.run`. Контракт уже асинхронный (`Promise`), поэтому: - когда появятся тяжёлые MEDIUM-операции (свёртки, квантование), внутренности `executeStep` переезжают в Web Worker — воркер импортирует тот же чистый core как TS-фолбэк, алгоритмы не дублируются, вызывающий код не меняется; - в WASM-фазе тот же воркер принимает wasm-модуль и диспетчеризует по `toolId` — свитч A/B из фазы 5 сводится к замене реализации внутри исполнителя; - до появления MEDIUM-операций воркер не вводится: EASY-операции быстры и не блокируют UI. ## 1. Структура репозитория (этап TS) ```txt easy-png-tools/ web/ # SvelteKit (adapter-static) src/lib/core/ # TS-ядро: Image (ImageData) + операции (без DOM) color.ts alpha.ts geometry.ts format.ts text.ts analyze.ts src/lib/registry.ts # реестр инструментов: id, title, description, params, run src/lib/pipeline.ts # пайплайн: шаги, применение, localStorage, экспорт/импорт JSON src/lib/components/ # DropZone, Preview, ParamForm (из схемы), Download, PipelineSteps src/routes/ # маршруты-утилиты (генерируются из реестра) + /workspace docs/ core/ # (позже) Rust-крейт tests/ # (позже) эталонные файлы и harness ``` ## 2. Фазы ### Фаза 1 — Полноценный TS-сайт (единственный приоритет) **Цель: сайт, которым можно пользоваться.** Без wasm, без Rust, без clamp-семантики (в TS это делает `Uint8ClampedArray` сам). 1.1 **Каркас и UX/UI.** SvelteKit + static adapter, дизайн-система (цвета, типографика, компоненты), общий лейаут, шапка с навигацией по категориям. 1.2 **Ядро.** Тип `Image` (обёртка над `ImageData`), загрузка/декодирование файла, кодирование и скачивание, библиотека операций (color/alpha/geometry/format/text/analyze). Всё без DOM-зависимостей внутри `core`. 1.3 **Реестр инструментов.** Одна запись = `{ id, title, description, category, params: ParamDef[], run }`. Универсальный рендерер: страница инструмента и форма параметров строятся из записи реестра автоматически; маршруты-утилиты генерируются из реестра на билде. Новый инструмент = новая запись + функция `run`. 1.4 **Пайплайн-workspace** (`/workspace`): загрузил изображение → список шагов (инструмент + его параметры) → последовательное применение с превью каждого шага → скачивание финального результата. Добавление/удаление/перестановка шагов. Сохранение пайплайнов в localStorage, экспорт/импорт JSON. Общие компоненты: DropZone, Preview, ParamForm, Download, PipelineSteps. 1.5 **Массовая реализация EASY-инструментов** по категориям: - конвертация форматов (png/jpg/webp/bmp/base64/gif) и текстовые представления; - прозрачность и альфа-канал; - цвет: замена, тон, каналы, оттенки серого, инверсии; - геометрия и холст: resize, crop, rotate, flip, border, padding, background; - текст и простые эффекты: watermark, add-text, рамки, шум, pixelate; - анализ: размеры, палитра, проверки, просмотр. Приоритет — ширина, не глубина: как можно больше простых инструментов. 1.6 **Полировка.** Описания и подсказки для всех инструментов, состояния загрузки/ошибок, доступность, пустые состояния. **Checkpoint:** загрузил PNG → применил пайплайн из N шагов → сохранил и вернул пайплайн → скачал результат. Все инструменты 1.5 работают на сайте. Ни одного wasm. ### Фаза 2 — Тестовые PNG и генератор эталонов - Фикстурные входы: градиенты/паттерны/шум + пара «настоящих» PNG. - Правило: сравниваем **распакованные пиксели**, не байты файла. - **Checkpoint:** в `tests/reference//` лежат `input-*.png` + `expected-*.png`. ### Фаза 3 — Playwright-тесты - `tools/gen-references.ts`: грузит страницу, гоняет TS-эталон, сохраняет `expected-*.png`. - Регресс: изменение TS-ядра ловится тестами. - **Checkpoint:** регресс-тесты падают при изменении выхода эталона. ### Фаза 4 — Rust-ядро - Порт 1:1 чистых операций (первым делом те, что покрыты эталонными файлами) с `Image` ↔ TS `ImageData`. - `clamp_to_u8` с семантикой `ToUint8Clamp` (round-half-to-even, ≥255 → 255) + юнит-тесты на краях. - `cargo test` читает эталонные файлы напрямую, **без браузера**. - **Checkpoint:** `cargo test` зелёный на всех эталонных файлах. ### Фаза 5 — WASM на сайте - Спайк WASM + Vite (проверить интеграцию) → wasm-bindgen-биндинги. - Свитч A/B: TS-реализация заменяется на wasm-вызов. - Playwright-проверка: wasm-результат == эталон. - **Checkpoint:** сайт работает через WASM; A/B TS vs WASM идентично. ### Фаза 6 — Rust-CLI - CLI: обход папки, `--pipeline pipeline.json`, запись результатов. - Воспроизведение эталонов из консоли. - **Checkpoint:** CLI выдаёт те же пиксели, что сохранены в эталонных файлах. ### Фаза 7 — Сквозная проверка идентичности - Матрица: **эталонные файлы (из TS) ↔ Rust-native ↔ Rust-wasm**, одна команда `harness compare`. - **Checkpoint:** сходимость по всем покрытым операциям во всех трёх рантаймах. ### Фаза 8 — Масштабирование и продвинутое - Порт оставшихся EASY → MEDIUM (свёртки, морфология, квантование; кодеки через крейт `image`). - Canvas-зависимые операции (текст, градиенты, штампы, `ctx.filter`): остаются в TS с perceptual-классом либо реимплементация в Rust. - batch-страница: дроп папки → wasm по всем файлам → zip. localStorage-пресеты (тот же JSON, что у CLI). - HARD: compress/optimize через oxipng/zopfli (в Rust — нативно). ## 3. Правила сравнения (для фаз 4–7) | Класс операции | Критерий | | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------- | | Чистые пиксельные: цвет, альфа, порог, свёртки, морфология, квантование | **бит-в-бит** | | Canvas-растеризация: текст, градиенты, антиалиасинг, `drawImage`, `ctx.filter` | **perceptual diff** (допуск: % изменившихся пикселей / цветовое расстояние) | | PNG-декод | бит-в-бит (lossless) | | JPEG-декод | perceptual (разные декодеры дают лёгкий дрейф) | | Кодирование | сравниваем декодированные пиксели, не байты файла | | compress/optimize | своя метрика: размер + визуальная дельта | ## 4. Риски и контрмеры - **Реестр разрастается, страницы дублируются** — один универсальный рендерер страниц/форм из записей реестра; инструмент = данные + `run`. - **Семантика пайплайна** — зафиксировать: каждый шаг применяется к результату предыдущего; единый тип `Image` на всём пути; схема параметров на шаге. - **Canvas-операции не бит-в-бит** — класс perceptual закладывается на Фазе 2–3, а не в конце. - **WASM + Vite** — спайк на Фазе 5 до массовой интеграции (риск отложен сознательно: сайт уже живёт на TS). - **Расползание реестра при будущем Rust-порте** — схема параметров в JSON, её можно парсить и из Rust. - **Разные декодеры PNG** — фикстурные PNG генерировать самим, чтобы не тащить чужие артефакты. ## 5. Команды верификации ```bash pnpm dev # разработка (Фаза 1+, обёртка `pnpm --dir web dev`) pnpm build # статический экспорт (обёртка `pnpm --dir web build`) pnpm --dir web exec playwright test # эталоны + UI-регресс (Фаза 3+) cargo test # Rust-ядро против эталонных файлов (Фаза 4+) harness compare tests/reference # сквозная сверка native + wasm (Фаза 7) ```