mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-09-14 21:46:35 +00:00
200 lines
15 KiB
Markdown
200 lines
15 KiB
Markdown
# План разработки: easy-png-tools
|
||
|
||
> **Статус (2026-09-07):** Фаза 1 (полноценный TS-сайт) в основном выполнена —
|
||
> сайт живёт, каталог переведён в типизированный `registry-new` (121/125), идёт
|
||
> редизайн на `preview/*` по `plan-redesign.md` (параллельная ветка, старый UI
|
||
> на `(old)/`). Фазы 2–8 (эталоны, Rust/wasm, CLI, harness) — будущие, разделам
|
||
> ниже не запущены. Фазы 9–10 (API, PWA) спланированы отдельно в
|
||
> `docs/plan-platform.md`.
|
||
|
||
## 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<PixelImage>`), поэтому:
|
||
- когда появятся тяжёлые 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/<op>/` лежат `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. Для текста выбран курс на
|
||
реимплементацию в Rust (рендер без DOM + шрифты OFL с лицензионными
|
||
паспортами) — `docs/plan-platform.md`, §4.
|
||
- batch-страница: дроп папки → wasm по всем файлам → zip. localStorage-пресеты
|
||
(тот же JSON, что у CLI).
|
||
- HARD: compress/optimize через oxipng/zopfli (в Rust — нативно).
|
||
|
||
### Фаза 9 — API (монетизация) — см. `docs/plan-platform.md`
|
||
|
||
Серверная обёртка над тем же ядром (нативный Rust или wasm на edge — решает
|
||
спайк), ключи и free tier, платные лимиты, индексируемая документация `/api`.
|
||
Чек-лист и решения — `docs/plan-platform.md`, §1.
|
||
|
||
### Фаза 10 — PWA — см. `docs/plan-platform.md`
|
||
|
||
Manifest + service worker, оффлайн-режим («работает без сети — файлы не покидают
|
||
устройство»), установка как приложение. Wasm-фаз не требует, идёт после C17/C19
|
||
и S1 из `plan-seo.md`. Чек-лист — `docs/plan-platform.md`, §2.
|
||
|
||
## 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)
|
||
```
|