Hypergraph — ядро управления состоянием Mercury: пакет @fiberfx/hypergraph версии 4.0.0 без зависимостей. Модель — граф единиц Hypergraph (unit), который выполняет ядро.
Что такое Hypergraph
Hypergraph — планировщик и исполнитель графа. Он пакетно выполняет связи модели до состояния покоя, без промежуточных несогласованных значений, с изолированными областями, эффектами и единым интерфейсом наблюдения. Его отличают три свойства:
- По замыслу за идентичность отвечает компилятор. У каждой единицы есть стабильный идентификатор sid и описание структуры (shape), чтобы хранилище (store) можно было снова найти после правки, при серверном рендеринге или в другой среде выполнения. Сегодня проход компилятора, назначающий sid, обрабатывает только вызовы прежнего фасада, а не Hypergraph. Поэтому у единицы Hypergraph есть sid лишь тогда, когда вы задали его сами; без этого она получает идентификатор времени выполнения
api:<n>, пока её не именует компилятор. Пока компилятор не выдаёт и описания структуры, ядро определяет структуру каждого хранилища по его начальному значению. - Связи представлены данными. Единицы и рёбра модели образуют граф, который загружает ядро, поэтому браузер, сервер и тест могут выполнять одно и то же описание.
- Семантика задана тестовыми векторами. Требуемое поведение ядра описано 467 векторами проверки соответствия, объединёнными в 19 семейств. Каждая среда выполнения, содержащая область состояния, запускает те же файлы; утверждение о соответствии опирается на результат этих проверок.
Имена API
- Единицы называются по своему виду:
store,eventиeffect— хранилище, событие (event) и эффект. Эффект принимает обработчик напрямую. - Связи:
sample— единый примитив композиции.combineобъединяет обновления своих источников через барьер. Его дополняютsplit,attach,mergeиrestore, а также методы единицon,reset,map,filter,filterMapиprepend. - Области состояния:
forkсоздаёт изолированную область,allSettledвыполняет в ней работу, аscopeBindпривязывает к ней функцию.snapshotвозвращает кадр состояния (frame) со структурой каждого значения;applyприводит область к состоянию кадра;diffописывает изменения между двумя кадрами;disposeзавершает работу области. - Наблюдение:
watch(unit, fn, {scope})принадлежит своему поколению. При замене графа модели наблюдатели старого поколения завершаются вместе с ним. - Виды:
kindOfвозвращаетstore,event,effect,scopeлибо ничего.
import { event, store } from "@fiberfx/hypergraph";
const increment = event<number>();
export const $count = store(0, { name: "$count" }).on(increment, (count, by) => count + by);
Пути экспорта
@fiberfx/hypergraph: единицы, связи, кадры состояния области и типы.@fiberfx/hypergraph/node:nodeCarrier, сохраняющий контекст области состояния черезawaitна сервере JavaScript. Он вынесен в отдельную точку входа, чтобы браузерный код не импортировал серверные модули.@fiberfx/hypergraph/inspect:inspectиdescribe, а также типыObservation,Declaration,KindиResetReason.
Ещё два пути пока запланированы и не экспортируются: /hyperscript — интеграция с Mercury Hyperscript (useUnit, Provider), и /hmr — горячая замена.
Что происходит при правке в mx dev
Когда mx dev начнёт доставлять замену, сохранение правки модели будет заменять её граф, а не перезагружать страницу. Если изменились только тела функций, замена выполняется на месте: область состояния, её значения и выполняющийся эффект сохраняются. Любая другая правка загружает новое поколение графа, переносит каждое хранилище с совпадающими sid и структурой, а затем завершает старое поколение вместе с его наблюдателями.
Для каждого хранилища, которое не перенесено, указывается причина:
- removed — удалено: ни одно хранилище нового графа не использует его sid;
- shape changed — изменилась структура: тот же sid присутствует с другой структурой; указываются обе структуры;
- renamed — переименовано: только подсказка, которая никогда не применяется автоматически; возникает, если ровно одно удалённое и одно новое хранилище имеют одинаковое имя;
- positional — позиционный идентификатор: ключ получен из положения в файле, а после изменения файла это не доказывает, что хранилище осталось тем же.
Хранилище, объявленное только в новом графе, помечается new — новое: оно начинает с исходного значения, ничего не потеряно, поэтому это информационное сообщение, а не сброс.
Главы
Читайте их по порядку: каждая опирается на предыдущие.
- Единицы: store, event и effect. Модель состоит из трёх видов единиц, названных по видам, которые записаны в графе. Хранилище содержит значение, событие передаёт данные, эффект запускает обработчик и завершается.
- Связи: от единиц к графу. Связи объединяют единицы в граф. sample — примитив композиции; combine соединяет хранилища через барьер; split, attach, merge и restore дополняют набор.
- Области состояния: создать, завершить работу, передать. Область — изолированная копия состояния модели для серверного запроса, теста или корня на странице. Её кадры содержат каждое значение по sid, вместе со структурой, поэтому кадр из одной сборки можно применить в другой.
- Наблюдение: watch, inspect, describe. Два способа наблюдать модель. watch вызывает функцию при обновлениях единицы; inspect в отдельной точке входа — единый интерфейс для инструментов, где каждое обновление, пропуск, ошибка, объявление, запуск эффекта и сброс представлены наблюдением.
- Виды, перенос контекста и ошибки. Три небольших механизма, обеспечивающих корректную работу модели. kindOf отличает единицу от области состояния, переносчик контекста сохраняет область через await, а каждый отказ представлен HypergraphError с одинаковым для всех сред выполнения кодом.
- Горячая замена. Правка модели должна сохранять состояние, которое вы видели, и точно сообщать, что сохранить не удалось. Hypergraph принимает решение для каждого хранилища по sid и структуре и указывает причину потери каждого значения.
- Серверный рендеринг: область на каждый запрос. На сервере множество запросов одновременно используют одну модель. Каждый получает собственную область состояния, дожидается завершения её работы и передаёт значения браузеру кадром с ключами sid; клиент применяет его к своей области.
- Тестирование модели: область на каждый тест. Тест — это область состояния. Создайте её, задайте нужные тесту обработчики эффектов, запустите работу через allSettled и прочитайте результат из значений области или наблюдений. Тестовые векторы соответствия выражают тот же подход в данных.
- Большие модели: структура и идентичность. Реальная модель состоит из многих модулей, множества хранилищ и нескольких эффектов. Правила ядра об идентичности, производных единицах и областях состояния определяют организацию модели: она должна тестироваться в отдельной области, передаваться кадром состояния и переживать правки.
- Итоговая работа: передача и восстановление модели. Весь курс в одном файле и одном тесте. Постройте модель из экспортов, запустите её в области состояния, получите кадр, приведите новую область к этому кадру и докажите, что состояния совпадают.
Переход с Effector
Если вы знаете Effector, руководство сопоставит знакомые понятия с Hypergraph: где находится каждое понятие, какие имена изменились и какие исчезли. Effector выведен из использования; здесь он нигде не импортируется.
- Переход с Effector. Большая часть знаний пригодится. Единицы называются по своему виду, область состояния обменивается кадрами, а некоторые имена Effector удалены окончательно.
- Единицы и связи. Конструкторы переименованы, а связи — нет. sample остаётся единым примитивом композиции.
- Области состояния и тестирование. fork, allSettled и scopeBind остаются на своих местах. Теперь из области передаётся кадр состояния.
- Фреймворки после effector-react. У Mercury один слой представления — Hyperscript. Его интеграция с Hypergraph появится следующим шагом; пока компонент читает хранилище через уже существующий хук Hyperscript.
Что реализовано
Ядро, его API и механизм замены реализованы внутри @fiberfx/hypergraph. Версия 4.0.0 доступна в npm с 2026-11-05. mx dev пока не доставляет замену: это следующий шаг, а до него правка модели перезагружает страницу.