Files
easy-png-tools/docs/roadmap.md
T

14 KiB
Raw Blame History

План разработки: easy-png-tools

Статус (2026-09-07): Фаза 1 (полноценный TS-сайт) в основном выполнена — сайт живёт, каталог переведён в типизированный registry-new (121/125), идёт редизайн на preview/* по plan-redesign.md (параллельная ветка, старый UI на (old)/). Фазы 28 (эталоны, 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<PixelImage>), поэтому:
    • когда появятся тяжёлые MEDIUM-операции (свёртки, квантование), внутренности executeStep переезжают в Web Worker — воркер импортирует тот же чистый core как TS-фолбэк, алгоритмы не дублируются, вызывающий код не меняется;
    • в WASM-фазе тот же воркер принимает wasm-модуль и диспетчеризует по toolId — свитч A/B из фазы 5 сводится к замене реализации внутри исполнителя;
    • до появления MEDIUM-операций воркер не вводится: EASY-операции быстры и не блокируют UI.

1. Структура репозитория (этап TS)

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.
  • 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. Команды верификации

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)