14 KiB
План развития: easy-png-tools
Статус: фаза 1 выполнена — сайт живёт на типизированном реестре, production UI — корневые маршруты. Текущий фокус: SEO S1-free (
docs/plan-seo.md) + открытые задачи (docs/backlog.md). Домен нужен для SEO (S1-domain). Фазы 2–8 — будущие; 9–10 спланированы вdocs/plan-platform.md; 11 — пайплайн.Идентификаторы. Ссылаться на фазу этого документа. Пространства идентификаторов задач:
FA-*— правки полей и раскладки (docs/plan-fields-audit-fixes.md);S*— SEO/GEO (docs/plan-seo.md);A*— API,P*— PWA,F*— шрифты (docs/plan-platform.md);R*— бренд и домен (docs/plan-seo.md, §6). БуквыQ*/C*в архивных документах относятся к волнам редизайна и как идентификаторы задач не используются.
0. Решения
Продуктовые и стратегические — здесь; устройство кода (реестр, исполнитель,
слои) — docs/architecture.md, разделы 2–3.
- Набор утилит для изображений, всё в браузере (SvelteKit +
adapter-static), данные не покидают машину. - Первый и главный приоритет — полностью рабочий сайт: максимум простых инструментов, UX/UI, пайплайны (несколько инструментов подряд), описания инструментов.
- Никакого wasm/Rust на этом этапе. TS-реализация на canvas +
ImageData— эталон алгоритмов, из которого позже генерируются эталонные файлы для проверки Rust-порта. Rust-ядро, WASM и CLI — отдельные фазы позже, когда сайт живёт. - Пайплайн = JSON-список шагов
{tool, params}. Формат зафиксирован этим решением и станет общим для браузера, wasm и CLI; реализуется в фазе 11, не в фазе 1. - Валидация будущего Rust-порта — эталонные файлы, сгенерированные из TS-реализации. Сравнение: бит-в-бит для чистых пиксельных операций, perceptual diff для canvas-зависимых (правила сравнения — раздел 3).
1. Где что лежит
Актуальная карта модулей, поток данных и рецепт добавления инструмента —
docs/architecture.md. Список реализованных инструментов — docs/tools-map.md,
открытые продуктовые задачи — docs/backlog.md.
2. Фазы
Фаза 1 — Полноценный TS-сайт (выполнена)
Поставлено: каркас SvelteKit + static, дизайн-система и общий лейаут; ядро над
ImageData (загрузка/декодирование, кодирование, операции по категориям) без
DOM-зависимостей; типизированный реестр с универсальным рендерером страницы и
формы; массовая реализация EASY-инструментов; i18n, темы, состояния
загрузки/ошибок. Checkpoint достигнут: загрузил PNG → применил инструмент →
скачал результат, без wasm.
В фазе 1 пайплайна нет. Workspace цепочек с сохранением в localStorage и
экспортом в JSON — фаза 11, не поставленная часть фазы 1. Страница инструмента
работает ровно с одной записью реестра; что именно зарезервировано под пайплайн
(компонент StepCard, ключи chain.*), перечислено в docs/architecture.md,
раздел 1 «Чего в коде нет».
Незакрытый долг по фазе — в docs/backlog.md; он не входит в фазы 2–8 и 11.
Фаза 2 — Тестовые PNG и генератор эталонов
- Фикстурные входы: градиенты/паттерны/шум + пара «настоящих» PNG.
- Правило: сравниваем распакованные пиксели, не байты файла.
- Checkpoint: в
tests/reference/<op>/лежатinput-*.png+expected-*.png.
Фаза 3 — Эталонные файлы и UI-регресс
UI-регресс на Playwright уже существует и закрывает фазу 3 частично (
web/e2e/, browser matrix). Недостающая часть фазы — именно эталоны.
- Скрипт генерации эталонов: грузит страницу, гоняет TS-реализацию, сохраняет
expected-*.png. - Checkpoint: регресс-тесты падают при изменении выхода эталона.
Фаза 4 — Rust-ядро
- Порт 1:1 чистых операций (первым делом те, что покрыты эталонными файлами) с
PixelImage↔ TSImageData. 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-фаз не требует, идёт после S1 из
plan-seo.md. Чек-лист — docs/plan-platform.md, §2.
Фаза 11 — Пайплайн (цепочки шагов)
Продуктовая фича, не зависит от wasm-фаз: работает на существующем исполнителе и реестре, поэтому может идти параллельно с SEO. Номер 11 выбран чтобы не сдвигать уже используемые ссылки на фазы 2–10.
- Формат шага —
{tool, params}, список шагов применяется последовательно, результат предыдущего идёт в следующий. Формат зафиксирован в §0 как общий для браузера, wasm и CLI, поэтому версионируется с первого дня. - Первый шаг фазы: модуль состояния цепочки + сохранение в localStorage +
экспорт/импорт JSON (ошибки разбора уже описаны ключами
errors.badPipelineShape/errors.pipelineVersion/errors.noSteps). - Затем: редактирование шагов (drag-n-drop, удаление, добавление), переход «один инструмент → цепочка» без перезагрузки, сохранённые именованные цепочки, отображение маски результата.
- Checkpoint: собрал цепочку из N шагов → сохранил → вернулся позже → скачал результат последнего шага, всё в браузере.
Ограничения и открытые вопросы (1 → many не терминален, many → 1, частичные
ошибки, имена частей) — docs/backlog.md, раздел «Идеи». Пайплайн из архивного
UI-v1 удалён; что осталось в коде под эту фазу — docs/architecture.md,
раздел 1.
3. Правила сравнения (для фаз 4–7)
| Класс операции | Критерий |
|---|---|
| Чистые пиксельные: цвет, альфа, порог, свёртки, морфология, квантование | бит-в-бит |
Canvas-растеризация: текст, градиенты, антиалиасинг, drawImage, ctx.filter |
perceptual diff (допуск: % изменившихся пикселей / цветовое расстояние) |
| PNG-декод | бит-в-бит (lossless) |
| JPEG-декод | perceptual (разные декодеры дают лёгкий дрейф) |
| Кодирование | сравниваем декодированные пиксели, не байты файла |
| compress/optimize | своя метрика: размер + визуальная дельта |
4. Риски и контрмеры
- Реестр разрастается, страницы дублируются — один универсальный рендерер
страниц/форм из записей реестра; инструмент = данные +
run. - Семантика пайплайна — зафиксирована: каждый шаг применяется к результату
предыдущего; единый тип
PixelImageна всём пути; схема параметров на шаге. - Canvas-операции не бит-в-бит — класс perceptual закладывается на Фазе 2–3, а не в конце.
- WASM + Vite — спайк на Фазе 5 до массовой интеграции (риск отложен сознательно: сайт уже живёт на TS).
- Расползание реестра при будущем Rust-порте — схема параметров в JSON, её можно парсить и из Rust.
- Разные декодеры PNG — фикстурные PNG генерировать самим, чтобы не тащить чужие артефакты.
5. Команды верификации
Команды текущего этапа и матрица «изменение → проверки» —
docs/quality-gates.md (pnpm verify — быстрый gate). Команды фаз 2–8
(cargo test, harness compare) в проекте не существуют и появятся вместе
с соответствующими фазами: до этапа 2 проверять нечем, кроме pnpm verify и
e2e.