Отслеживание состояния

Система отслеживания состояния в Vest строится вокруг идеи декларативного описания правил и последующего детерминированного вычисления результата валидации. В отличие от императивных подходов, где ошибки накапливаются вручную, здесь состояние является производным от выполнения набора тестов, сгруппированных в единый валидационный набор.

Ключевая особенность заключается в том, что состояние не хранится как изменяемая сущность «внутри» правил — оно вычисляется при каждом запуске проверки и представляет собой структурированный снимок результата.


Структура состояния валидации

Результирующее состояние после выполнения валидационного набора включает несколько уровней:

Общий уровень состояния

На верхнем уровне формируется агрегированное представление:

  • наличие ошибок (hasErrors)
  • наличие предупреждений (hasWarnings)
  • общая валидность набора
  • состояние выполнения (успешное / прерванное / частично выполненное)

Это позволяет быстро определить итог без обхода всех полей.

Состояние по полям

Каждое поле получает собственный сегмент состояния:

  • список ошибок
  • список предупреждений
  • флаг валидности поля
  • метаданные (например, какие тесты были применены)

Такой подход позволяет рассматривать форму как дерево состояний, где каждый узел автономен, но связан с общим результатом.


Принцип вычисления состояния

В Vest состояние формируется не через мутацию, а через последовательное выполнение тестов, которые описывают условия проверки.

Каждый тест:

  • получает входные данные
  • выполняет проверку
  • либо добавляет ошибку в локальное состояние поля, либо завершает успешно

Важно, что тесты не изменяют глобальное состояние напрямую. Вместо этого они влияют на контекст выполнения, который затем агрегируется в финальный результат.


Контекст выполнения и его роль

Контекст выступает промежуточным слоем между тестами и итоговым состоянием.

Он отвечает за:

  • накопление ошибок по полям
  • группировку результатов
  • управление зависимостями между полями
  • хранение временных значений во время выполнения набора тестов

Контекст изолирует логику тестирования от финальной структуры результата, что делает систему предсказуемой.


Изменяемость и иммутабельность состояния

Одним из фундаментальных решений в архитектуре является отсутствие прямой мутации итогового состояния.

Каждый запуск валидации:

  1. создаёт новый контекст
  2. выполняет все тесты заново
  3. формирует новый объект состояния

Это даёт несколько преимуществ:

  • отсутствие побочных эффектов между запусками
  • возможность безопасного повторного выполнения
  • упрощённая отладка
  • детерминированность результата

Дифференциальное отслеживание изменений

Хотя состояние пересоздаётся полностью, система эффективно отслеживает изменения входных данных.

Механизм сравнения входов позволяет:

  • запускать только релевантные группы тестов
  • пропускать неизменённые части схемы
  • минимизировать количество вычислений

Отслеживание изменений обычно опирается на сравнение значений полей между текущим и предыдущим запуском.


Группировка состояния

Тесты в Vest объединяются в группы. Каждая группа имеет собственное поддерево состояния.

Группы позволяют:

  • логически разделять форму на блоки
  • изолировать наборы правил
  • управлять зависимостями внутри секций

Состояние группы агрегируется из состояния входящих тестов и влияет на общий результат только через итоговую сводку.


Ленивое и условное формирование состояния

Не все части состояния вычисляются одновременно. Система поддерживает условное выполнение тестов, что влияет на структуру итогового результата.

Условная логика позволяет:

  • пропускать проверки, если данные не удовлетворяют базовым условиям
  • формировать частичное состояние
  • уменьшать вычислительную нагрузку

В результате состояние может быть «неполным» до тех пор, пока не выполнены все релевантные условия.


Связь состояния с зависимыми полями

Одним из ключевых аспектов является реактивная зависимость между полями.

Если одно поле влияет на другое, изменение первого приводит к пересчёту состояния зависимого поля.

Типичные сценарии:

  • подтверждение пароля зависит от значения основного пароля
  • условная валидация адресных полей зависит от выбора страны
  • бизнес-правила связывают несколько полей в единую проверку

Система отслеживает такие зависимости через контекст и пересчитывает только затронутые узлы.


Ошибки как часть состояния

Ошибки не являются побочным эффектом — они представляют основную часть состояния.

Каждая ошибка включает:

  • идентификатор поля
  • сообщение
  • тип нарушения
  • источник (какой тест сгенерировал ошибку)

Это делает состояние самодостаточным и пригодным для UI-отображения без дополнительной обработки.


Временное состояние выполнения тестов

Во время выполнения набора тестов формируется промежуточное состояние:

  • текущий выполняемый тест
  • локальные результаты группы
  • частично собранные ошибки

Это состояние существует только в рамках одного запуска и не сохраняется после завершения.


Агрегация состояния на уровне формы

Финальное состояние формы — это результат объединения всех подуровней:

  • полей
  • групп
  • глобальных правил

Агрегация выполняется детерминированно, что позволяет одинаковым входным данным всегда давать идентичный результат.


Оптимизация обновления состояния

Для повышения производительности система использует несколько стратегий:

  • пропуск неизменённых полей
  • кеширование результатов тестов
  • раннее завершение при критических ошибках
  • разделение независимых ветвей выполнения

Эти подходы позволяют масштабировать валидацию на большие формы без линейного роста затрат.


Роль состояния в интеграции с UI

Хотя состояние не зависит от конкретного интерфейса, его структура оптимизирована для UI-слоя.

Обычно используется:

  • отображение ошибок по полям
  • подсветка групп с ошибками
  • блокировка отправки формы при наличии глобальных ошибок
  • динамическое обновление состояния при изменении ввода

Таким образом, состояние выступает единственным источником истины для интерфейса.


Согласованность состояния при повторных запусках

Повторные запуски валидации всегда приводят к полной пересборке состояния, что исключает:

  • частично устаревшие ошибки
  • конфликтующие результаты
  • несогласованные данные между полями

Это особенно важно при сложных формах с множественными зависимостями, где инкрементальные изменения могли бы привести к рассинхронизации.


Модель предсказуемости состояния

Система строится на строгом принципе:

одни и те же входные данные → одно и то же состояние

Это достигается за счёт:

  • отсутствия внешних побочных эффектов
  • чистоты тестовых функций
  • неизменяемости результатов
  • полной пересборки состояния при каждом запуске

Такой подход делает поведение валидации полностью воспроизводимым.