Ядро
@virentia/core — ядро Virentia. С его помощью вы описываете модель бизнес-состояния: какие данные нужны задаче, что может произойти, какая асинхронная работа ей нужна и какие правила связывают все это вместе.
Модель ядра не обязана знать, где ее покажут. Ее можно вызвать из React, из теста, из серверного обработчика или из фоновой задачи. Поэтому в ядре лучше писать язык бизнес-задачи, а не язык конкретного интерфейса.
import { event, reaction, store } from "@virentia/core";
export function createCounterModel() {
const incremented = event<number>();
const count = store(0);
reaction({
on: incremented,
run(amount) {
count.value += amount;
},
});
return { count, incremented };
}В этом примере count — стор, incremented — событие, а reaction — правило. Событие говорит, что произошло. Правило решает, как состояние должно измениться.
Разделение ответственности
Стор хранит значение. Событие сообщает о факте. Эффект запускает работу, которая завершится позже. Реакция связывает эти части в поведение.
Если хочется добавить метод вроде setCount, лучше назвать событие языком задачи: incremented, reset, submitted, messageReceived. Так модель говорит о смысле произошедшего, а не о техническом способе изменить поле.
Хранение значений
Модель ядра можно импортировать один раз, но запустить в разных scopes. Scope хранит конкретные значения сторов, поэтому одна и та же модель может безопасно работать в приложении, тесте, серверном запросе или отдельном виджете.
const first = scope();
const second = scope();
const model = createCounterModel();
await allSettled(model.incremented, { scope: first, payload: 1 });
await allSettled(model.incremented, { scope: second, payload: 10 });Модель одна, состояния два. Это базовая механика Virentia.
Следующие разделы
Сначала разберитесь с главными юнитами: сторы, события, эффекты и реакции. После этого переходите к скоупам: там объясняется, где живут значения и как работает scoped. Если модели создаются и удаляются во время работы приложения, прочитайте владельцев и очистку.
Низкоуровневое ядро нужно только для адаптеров, devtools и своих примитивов.