@raphy-js/raph 1.0.1-dev.20 → 1.0.1-dev.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{core-CyilRD7s.js → core-CClhT8WR.js} +389 -400
- package/dist/core-cPQWYD4K.cjs +1 -0
- package/dist/debug/api/Raph.cjs +1 -1
- package/dist/debug/api/Raph.js +46 -47
- package/dist/debug/api/RaphFacadeSession.cjs +1 -1
- package/dist/debug/api/RaphFacadeSession.js +85 -89
- package/dist/debug/api/RaphReactivityInstance.cjs +1 -1
- package/dist/debug/api/RaphReactivityInstance.js +27 -30
- package/dist/debug/path/DataPath.cjs +1 -1
- package/dist/debug/path/DataPath.js +198 -202
- package/dist/debug/path/PathRouter.cjs +1 -1
- package/dist/debug/path/PathRouter.js +44 -50
- package/dist/debug/path/RaphKernel.cjs +1 -1
- package/dist/debug/path/RaphKernel.js +257 -228
- package/dist/debug/path/data-path.utils.cjs +1 -1
- package/dist/debug/path/data-path.utils.js +41 -41
- package/dist/debug/path/derived/DerivedRegistry.cjs +1 -1
- package/dist/debug/path/derived/DerivedRegistry.js +52 -66
- package/dist/debug/path/derived/RaphDerivedHandle.cjs +1 -1
- package/dist/debug/path/derived/RaphDerivedHandle.js +19 -22
- package/dist/debug/path/derived/derived-collection.utils.cjs +1 -1
- package/dist/debug/path/derived/derived-collection.utils.js +70 -70
- package/dist/debug/path/meta/MetaController.cjs +1 -1
- package/dist/debug/path/meta/MetaController.js +57 -65
- package/dist/debug/path/meta/RaphMeta.cjs +1 -1
- package/dist/debug/path/meta/RaphMeta.js +26 -32
- package/dist/debug/path/meta/RaphMetaStore.cjs +1 -1
- package/dist/debug/path/meta/RaphMetaStore.js +24 -30
- package/dist/debug/path/storage/AdapterPathStore.cjs +1 -1
- package/dist/debug/path/storage/AdapterPathStore.js +49 -54
- package/dist/debug/path/storage/DefaultDataAdapter.cjs +1 -1
- package/dist/debug/path/storage/DefaultDataAdapter.js +46 -56
- package/dist/debug/path/storage/PathEventHub.cjs +1 -1
- package/dist/debug/path/storage/PathEventHub.js +74 -61
- package/dist/debug/path/storage/PathStore.cjs +1 -1
- package/dist/debug/path/storage/PathStore.js +89 -99
- package/dist/debug/path/storage/createDataDraft.cjs +1 -1
- package/dist/debug/path/storage/createDataDraft.js +24 -28
- package/dist/debug/reactivity/disposal.cjs +1 -0
- package/dist/debug/reactivity/disposal.js +32 -0
- package/dist/debug/reactivity/engine.cjs +1 -1
- package/dist/debug/reactivity/engine.js +787 -392
- package/dist/debug/reactivity/reactive-object.cjs +1 -1
- package/dist/debug/reactivity/reactive-object.js +81 -96
- package/dist/debug/reactivity/scope.cjs +1 -1
- package/dist/debug/reactivity/scope.js +221 -117
- package/dist/debug/reactivity/watch.cjs +1 -1
- package/dist/debug/reactivity/watch.js +1 -1
- package/dist/debug/runtime/RaphRuntime.cjs +1 -1
- package/dist/debug/runtime/RaphRuntime.js +764 -411
- package/dist/debug/runtime/diagnostics/RaphDebug.cjs +1 -1
- package/dist/debug/runtime/diagnostics/RaphDebug.js +90 -100
- package/dist/debug/runtime/ownership/RaphEffectScope.cjs +1 -1
- package/dist/debug/runtime/ownership/RaphEffectScope.js +215 -82
- package/dist/debug/runtime/ownership/RaphNode.cjs +1 -1
- package/dist/debug/runtime/ownership/RaphNode.js +595 -136
- package/dist/debug/runtime/ownership/RaphScope.cjs +1 -1
- package/dist/debug/runtime/ownership/RaphScope.js +203 -68
- package/dist/debug/runtime/phases/RaphFrameLoop.cjs +1 -1
- package/dist/debug/runtime/phases/RaphFrameLoop.js +13 -17
- package/dist/debug/runtime/phases/RaphPhasePipeline.cjs +1 -1
- package/dist/debug/runtime/phases/RaphPhasePipeline.js +618 -357
- package/dist/debug/runtime/phases/RaphPhaseTaskRecord.cjs +1 -0
- package/dist/debug/runtime/phases/RaphPhaseTaskRecord.js +176 -0
- package/dist/debug/runtime/phases/RaphPhaseWatch.cjs +1 -0
- package/dist/debug/runtime/phases/RaphPhaseWatch.js +20 -0
- package/dist/debug/runtime/reactivity/PathHandle.cjs +1 -1
- package/dist/debug/runtime/reactivity/PathHandle.js +50 -60
- package/dist/debug/runtime/reactivity/RaphMetaSource.cjs +1 -1
- package/dist/debug/runtime/reactivity/RaphMetaSource.js +28 -32
- package/dist/debug/runtime/reactivity/RaphSelector.cjs +1 -0
- package/dist/debug/runtime/reactivity/RaphSelector.js +503 -0
- package/dist/debug/runtime/reactivity/RaphWorkGraph.cjs +1 -1
- package/dist/debug/runtime/reactivity/RaphWorkGraph.js +541 -379
- package/dist/debug/runtime/reactivity/RuntimeReactivity.cjs +1 -1
- package/dist/debug/runtime/reactivity/RuntimeReactivity.js +484 -90
- package/dist/debug/runtime/reactivity/RuntimeWatch.cjs +1 -1
- package/dist/debug/runtime/reactivity/RuntimeWatch.js +33 -44
- package/dist/debug/runtime/reactivity/disposal-sweep.utils.cjs +1 -0
- package/dist/debug/runtime/reactivity/disposal-sweep.utils.js +42 -0
- package/dist/entrypoints/runtime.d.ts +2 -1
- package/dist/machine-testing.cjs +1 -1
- package/dist/machine-testing.js +1 -1
- package/dist/machine.cjs +1 -1
- package/dist/machine.js +216 -231
- package/dist/path/RaphKernel.d.ts +24 -0
- package/dist/path/storage/PathEventHub.d.ts +14 -0
- package/dist/path/storage/PathStore.d.ts +4 -4
- package/dist/reactivity/disposal.d.ts +14 -0
- package/dist/reactivity/engine.d.ts +177 -4
- package/dist/reactivity/scope.d.ts +108 -30
- package/dist/runtime/RaphRuntime.d.ts +236 -17
- package/dist/runtime/ownership/RaphEffectScope.d.ts +70 -1
- package/dist/runtime/ownership/RaphNode.d.ts +276 -6
- package/dist/runtime/ownership/RaphScope.d.ts +144 -14
- package/dist/runtime/phases/RaphPhasePipeline.d.ts +202 -28
- package/dist/runtime/phases/RaphPhaseTaskRecord.d.ts +195 -0
- package/dist/runtime/phases/RaphPhaseWatch.d.ts +22 -0
- package/dist/runtime/phases/phase.types.d.ts +83 -4
- package/dist/runtime/reactivity/RaphSelector.d.ts +338 -0
- package/dist/runtime/reactivity/RaphWorkGraph.d.ts +163 -25
- package/dist/runtime/reactivity/RuntimeReactivity.d.ts +258 -10
- package/dist/runtime/reactivity/RuntimeWatch.d.ts +8 -8
- package/dist/runtime/reactivity/disposal-sweep.utils.d.ts +19 -0
- package/dist/runtime/reactivity/runtime-reactivity.types.d.ts +48 -3
- package/package.json +9 -1
- package/dist/core-ugchZNqC.cjs +0 -1
|
@@ -1,25 +1,219 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OwnedSourceEntry } from '../../reactivity/scope';
|
|
2
|
+
import { EffectCallback, OwnedSourceHooks, ReactiveNode, ReactivityOptions, ReadonlySignal, Signal } from '../../reactivity/types';
|
|
2
3
|
import { RaphScope } from '../ownership/RaphScope';
|
|
3
|
-
import {
|
|
4
|
+
import { RaphSelectorOptions, RuntimeSelector } from './RaphSelector';
|
|
5
|
+
import { RaphProducerDescription, RaphProducerKind, RaphProducer } from './RaphWorkGraph';
|
|
6
|
+
import { ReleasedGraphShapes, RuntimeSignalLifecycle, RuntimeSignalWriteTap } from './runtime-reactivity.types';
|
|
4
7
|
import { RaphReactivity } from '../../reactivity/engine';
|
|
8
|
+
/**
|
|
9
|
+
* Компактное описание Runtime signal, которое возвращает его toJSON().
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export interface RuntimeSignalDescription extends RaphProducerDescription {
|
|
14
|
+
readonly index: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Наибольший номер, который toJSON() Runtime signal считает точно. Номер
|
|
18
|
+
* считается проходом по списку источников владельца, и граница делает цену
|
|
19
|
+
* одного описания постоянной: сериализация всех signals одного владельца
|
|
20
|
+
* линейна по их числу, а не квадратична.
|
|
21
|
+
*
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
24
|
+
export declare const SIGNAL_INDEX_LIMIT = 64;
|
|
25
|
+
/**
|
|
26
|
+
* Runtime signal одним объектом: публичный handle, producer WorkGraph, source
|
|
27
|
+
* hooks своей записи графа и запись в списке источников владельца. Методы
|
|
28
|
+
* лежат на prototype, поэтому signal не создаёт ни одной closure; get, peek и
|
|
29
|
+
* set нужно вызывать через handle или с явным receiver.
|
|
30
|
+
*
|
|
31
|
+
* Значение лежит в самом signal до первого отслеживаемого чтения. Оно
|
|
32
|
+
* материализует запись графа, и дальше значением владеет запись.
|
|
33
|
+
*
|
|
34
|
+
* Поля объявлены через `declare` и присваиваются в constructor в одном порядке
|
|
35
|
+
* вслед за полями RaphProducer: у всех signals один hidden class.
|
|
36
|
+
*/
|
|
37
|
+
export declare class RuntimeSignal<T> extends RaphProducer implements Signal<T>, OwnedSourceHooks, OwnedSourceEntry {
|
|
38
|
+
private _value;
|
|
39
|
+
private _node;
|
|
40
|
+
/**
|
|
41
|
+
* Источник, зарегистрированный у владельца перед этим.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
_previousSource: OwnedSourceEntry | undefined;
|
|
45
|
+
private _writeTaps;
|
|
46
|
+
/**
|
|
47
|
+
* Создаёт signal своим собственным handle. Регистрацию у владельца
|
|
48
|
+
* выполняет вызывающий код.
|
|
49
|
+
*/
|
|
50
|
+
constructor(owner: RaphScope, kind: RaphProducerKind, includeRuntime: boolean, value: T);
|
|
51
|
+
/**
|
|
52
|
+
* Identity producer для задач implicit effects: сам signal.
|
|
53
|
+
* @internal
|
|
54
|
+
*/
|
|
55
|
+
get token(): this;
|
|
56
|
+
/**
|
|
57
|
+
* Владелец signal. Engine читает это поле только у потребителей, а signal
|
|
58
|
+
* потребителем не бывает; getter сохраняет полный контракт source hooks.
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
get dependencyOwner(): RaphScope;
|
|
62
|
+
/**
|
|
63
|
+
* Возвращает компактное описание signal для JSON.stringify, логов и diff
|
|
64
|
+
* неуспешной проверки. К описанию producer добавлен номер signal среди
|
|
65
|
+
* источников его владельца в порядке регистрации: один и тот же signal
|
|
66
|
+
* описывается одинаково, сколько бы раз и через какую копию его ни
|
|
67
|
+
* печатали, а разные живые signals одного владельца различаются номером,
|
|
68
|
+
* пока он меньше SIGNAL_INDEX_LIMIT. Номер считается проходом по списку
|
|
69
|
+
* источников только при сериализации и не дальше этой границы: у каждого
|
|
70
|
+
* источника, зарегистрированного после первых SIGNAL_INDEX_LIMIT, он равен
|
|
71
|
+
* границе. У освобождённого signal номер равен нулю. Значение в описание не
|
|
72
|
+
* входит: оно может быть сколь угодно большим и само содержать циклы.
|
|
73
|
+
*/
|
|
74
|
+
toJSON(): RuntimeSignalDescription;
|
|
75
|
+
/**
|
|
76
|
+
* Читает значение и регистрирует зависимость активного потребителя.
|
|
77
|
+
*/
|
|
78
|
+
get(): T;
|
|
79
|
+
/**
|
|
80
|
+
* Читает значение без подписки текущего потребителя.
|
|
81
|
+
*/
|
|
82
|
+
peek(): T;
|
|
83
|
+
/**
|
|
84
|
+
* Записывает значение в собственной границе записи Runtime. Граница
|
|
85
|
+
* открывается и закрывается явными вызовами, без closure.
|
|
86
|
+
*/
|
|
87
|
+
set(value: T): void;
|
|
88
|
+
/**
|
|
89
|
+
* Записывает значение внутри уже открытой границы записи, минуя политику
|
|
90
|
+
* actions: так Runtime продвигает собственный frame signal.
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
_writeInBoundary(value: T): void;
|
|
94
|
+
/**
|
|
95
|
+
* Подключает наблюдателя фактических записей этого signal. Наблюдатель
|
|
96
|
+
* вызывается синхронно внутри границы записи, после того как новое значение
|
|
97
|
+
* стало видимым для чтения, и до выхода из записи. Запись, которая уже идёт,
|
|
98
|
+
* нового наблюдателя не вызывает. Цена подключения не зависит от числа
|
|
99
|
+
* наблюдателей.
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
_addWriteTap(tap: RuntimeSignalWriteTap): void;
|
|
103
|
+
/**
|
|
104
|
+
* Отключает наблюдателя записей: его место занимает последний наблюдатель
|
|
105
|
+
* списка. Запись, которая уже идёт, ещё вызовет отключённого наблюдателя.
|
|
106
|
+
* Отключение неизвестного наблюдателя и отключение у освобождённого signal
|
|
107
|
+
* безопасны. Цена отключения не зависит от числа наблюдателей.
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
_removeWriteTap(tap: RuntimeSignalWriteTap): void;
|
|
111
|
+
/**
|
|
112
|
+
* Сообщает WorkGraph о фактической записи до распространения по графу.
|
|
113
|
+
* @internal
|
|
114
|
+
*/
|
|
115
|
+
onChange(previous: unknown, value: unknown, hasReactiveSubscribers: boolean): void;
|
|
116
|
+
/**
|
|
117
|
+
* Освобождает producer-сторону signal в WorkGraph.
|
|
118
|
+
* @internal
|
|
119
|
+
*/
|
|
120
|
+
onDispose(hasReactiveSubscribers: boolean): void;
|
|
121
|
+
/**
|
|
122
|
+
* Ищет среди текущих потребителей signal в графе первого, чьего владельца
|
|
123
|
+
* принимает accept, и возвращает этого владельца. Signal не ведёт учёта
|
|
124
|
+
* своих implicit-рёбер и не имеет hook onDependency: рёбра читаются из
|
|
125
|
+
* записи графа только по запросу. У signal без записи графа потребителей
|
|
126
|
+
* нет: его ещё не читал ни один потребитель либо он уже освобождён.
|
|
127
|
+
* Владельцы наблюдателей записи считаются потребителями наравне с ними.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
130
|
+
_findConsumerOwner<Context>(accept: (consumerOwner: object, context: Context) => boolean, context: Context): object | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Освобождает signal как источник владельца: публикует финальную причину,
|
|
133
|
+
* отсоединяет запись графа и отпускает значение. Сбой одного шага не
|
|
134
|
+
* отменяет остальные. Повторный вызов безопасен.
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
_finalizeSource(): boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Записывает значение без проверок lifetime и без границы записи.
|
|
140
|
+
* Критерий изменения — ===, как у записи графа.
|
|
141
|
+
*/
|
|
142
|
+
private _write;
|
|
143
|
+
/**
|
|
144
|
+
* Запись signal с наблюдателями. Отличается от `_write()` двумя вещами.
|
|
145
|
+
* Причина записи публикуется и тогда, когда потребители есть только у
|
|
146
|
+
* наблюдателя: их будит эта же запись. После того как новое значение стало
|
|
147
|
+
* видимым, каждый наблюдатель получает прежнее и новое значение. Сбой
|
|
148
|
+
* распространения по графу или одного наблюдателя не отменяет остальных.
|
|
149
|
+
*
|
|
150
|
+
* Запись обходит тот список наблюдателей, который застала: подключение и
|
|
151
|
+
* отключение во время обхода меняют его копию.
|
|
152
|
+
*/
|
|
153
|
+
private _writeTapped;
|
|
154
|
+
}
|
|
5
155
|
/**
|
|
6
156
|
* Внутренний policy adapter, наследующий реактивные алгоритмы без дублирования.
|
|
7
157
|
*/
|
|
8
158
|
export declare class RuntimeReactivity extends RaphReactivity {
|
|
9
|
-
|
|
10
|
-
|
|
159
|
+
/** @internal */
|
|
160
|
+
readonly _lifecycle: RuntimeSignalLifecycle;
|
|
11
161
|
/**
|
|
12
|
-
*
|
|
162
|
+
* Удерживает формы, которые записи графа получают только при освобождении.
|
|
163
|
+
* Создаётся первым графом Runtime в isolate и дальше не заменяется.
|
|
164
|
+
* @internal
|
|
13
165
|
*/
|
|
14
|
-
|
|
166
|
+
static _releasedShapeAnchor: ReleasedGraphShapes | undefined;
|
|
15
167
|
/**
|
|
16
|
-
*
|
|
168
|
+
* Тело записи engine каждого implicit phase effect этого графа: одна
|
|
169
|
+
* функция на граф, а не closure на binding. Engine вызывает тело без
|
|
170
|
+
* аргументов, поэтому свой binding оно берёт у engine: запись исполняемого
|
|
171
|
+
* effect — активный потребитель, а её задача — запись binding. Регистрация
|
|
172
|
+
* binding поэтому не выделяет ни closure, ни context, а запуск тела, которое
|
|
173
|
+
* не вернуло cleanup, не выделяет ничего.
|
|
174
|
+
*
|
|
175
|
+
* Тело binding вызывается с его consumer owner в качестве активного
|
|
176
|
+
* Runtime-контекста; контекст возвращается и после сбоя тела. Что получает
|
|
177
|
+
* тело, решает запись: frozen task либо, под `TASK_TASKLESS`, поле `group` —
|
|
178
|
+
* запуск slot у группы и `undefined` у binding без task, facade которого при
|
|
179
|
+
* этом не создаётся. Возвращённый cleanup выполняется вне любого
|
|
180
|
+
* Runtime-контекста.
|
|
181
|
+
*
|
|
182
|
+
* Вызывать функцию вправе только engine как тело записи, созданной через
|
|
183
|
+
* `_allocateTaskEffect()` с записью binding в роли задачи.
|
|
184
|
+
*
|
|
185
|
+
* @internal
|
|
17
186
|
*/
|
|
18
|
-
|
|
187
|
+
readonly _phaseBody: EffectCallback;
|
|
188
|
+
/**
|
|
189
|
+
* Создаёт policy adapter реактивного графа для одного runtime.
|
|
190
|
+
* @param _lifecycle Политика lifetime и записи Runtime; её читают handles
|
|
191
|
+
* этого графа, поэтому поле доступно внутри пакета.
|
|
192
|
+
*/
|
|
193
|
+
constructor(
|
|
194
|
+
/** @internal */
|
|
195
|
+
_lifecycle: RuntimeSignalLifecycle, options?: Pick<ReactivityOptions, 'adaptiveDependencyIndex'>);
|
|
19
196
|
/**
|
|
20
197
|
* Выполняет untracked-операцию, сохраняя runtime owner context.
|
|
21
198
|
*/
|
|
22
199
|
untrackedWithOwner<T>(operation: () => T): T;
|
|
200
|
+
/**
|
|
201
|
+
* Вызывает операцию с её аргументами вне Runtime owner context и вне graph
|
|
202
|
+
* consumer: форма `untrackedWithOwner(() => operation(...args))` без closure.
|
|
203
|
+
* Closure создаётся, только когда вызов пришёл изнутри отслеживаемого
|
|
204
|
+
* вычисления и graph consumer нужно снять.
|
|
205
|
+
*
|
|
206
|
+
* @internal
|
|
207
|
+
*/
|
|
208
|
+
_applyUntrackedWithOwner<Args extends unknown[], Result>(operation: (...args: Args) => Result, args: Args): Result;
|
|
209
|
+
/**
|
|
210
|
+
* Выполняет одну открытую доставку phase effect вне Runtime owner context и
|
|
211
|
+
* вне graph consumer: форма untrackedWithOwner() без closure для записи,
|
|
212
|
+
* подготовленной через _beginTaskEffectRun().
|
|
213
|
+
*
|
|
214
|
+
* @internal
|
|
215
|
+
*/
|
|
216
|
+
_runTaskEffectUntracked(node: ReactiveNode): void;
|
|
23
217
|
/**
|
|
24
218
|
* Возвращает owner текущего синхронного реактивного контекста.
|
|
25
219
|
*/
|
|
@@ -35,9 +229,63 @@ export declare class RuntimeReactivity extends RaphReactivity {
|
|
|
35
229
|
*/
|
|
36
230
|
runWithOwner<T>(lifecycle: RuntimeSignalLifecycle | undefined, consumerOwner: RaphScope | undefined, operation: () => T): T;
|
|
37
231
|
/**
|
|
38
|
-
*
|
|
232
|
+
* Ищет среди текущих потребителей Runtime signals владельца `sourceOwner`
|
|
233
|
+
* первого, чьего владельца принимает accept, и возвращает этого владельца.
|
|
234
|
+
* Signals обходятся от нового к старому по списку источников владельца;
|
|
235
|
+
* остальные источники списка пропускаются: их рёбра учитывает сам WorkGraph.
|
|
236
|
+
* Обход ничего не выделяет. Его цена — длина списка источников владельца
|
|
237
|
+
* плюс потребители каждого его signal с записью графа до первого принятого.
|
|
238
|
+
*
|
|
239
|
+
* @internal
|
|
240
|
+
*/
|
|
241
|
+
_findSignalConsumerOwner<Context>(sourceOwner: RaphScope, accept: (consumerOwner: object, context: Context) => boolean, context: Context): object | undefined;
|
|
242
|
+
/**
|
|
243
|
+
* Проверяет отслеживаемое чтение источника владельца `sourceOwner` теми же
|
|
244
|
+
* правилами, что и чтение его Runtime signal: Runtime жив, активный
|
|
245
|
+
* потребитель принадлежит этому Runtime и вправе неявно зависеть от
|
|
246
|
+
* владельца. Lifetime самого владельца проверяет вызывающий код.
|
|
247
|
+
*
|
|
248
|
+
* @internal
|
|
249
|
+
*/
|
|
250
|
+
_assertTrackedRead(sourceOwner: RaphScope): void;
|
|
251
|
+
/**
|
|
252
|
+
* Сообщает, что у записи ровно один потребитель. Внутри cleanup связи,
|
|
253
|
+
* который engine вызывает до снятия этой связи со списка, ответ `true`
|
|
254
|
+
* означает, что снимается последняя связь записи.
|
|
255
|
+
*
|
|
256
|
+
* @internal
|
|
257
|
+
*/
|
|
258
|
+
_hasSingleSubscriber(node: ReactiveNode): boolean;
|
|
259
|
+
/**
|
|
260
|
+
* Считает записи, у которых есть потребители, в двух частях одного индекса:
|
|
261
|
+
* в ряду, где пустое место хранит undefined, и в индексе по ключам, если он
|
|
262
|
+
* есть. Ряд обходится циклом без вызовов. Обход ничего не выделяет и не
|
|
263
|
+
* меняет граф.
|
|
264
|
+
*
|
|
265
|
+
* @internal
|
|
266
|
+
*/
|
|
267
|
+
_countObserved(row: readonly (ReactiveNode | undefined)[], index: Map<unknown, ReactiveNode> | undefined): number;
|
|
268
|
+
/**
|
|
269
|
+
* Убирает записи без потребителей из обеих частей индекса: место ряда
|
|
270
|
+
* становится пустым, запись индекса по ключам удаляется. Возвращает число
|
|
271
|
+
* мест ряда, оставшихся занятыми. Сами записи не освобождаются: без
|
|
272
|
+
* потребителей и без ссылки из индекса они недостижимы.
|
|
273
|
+
*
|
|
274
|
+
* @internal
|
|
275
|
+
*/
|
|
276
|
+
_dropUnobserved(row: (ReactiveNode | undefined)[], index: Map<unknown, ReactiveNode> | undefined): number;
|
|
277
|
+
/**
|
|
278
|
+
* Создаёт selector над записываемым Runtime signal и ставит его в список
|
|
279
|
+
* источников владельца. Source должен быть доступен владельцу для implicit
|
|
280
|
+
* чтения: принадлежать ему самому, его предку или root scope. Тогда source
|
|
281
|
+
* переживает selector, а потребители selector могли бы читать source сами.
|
|
282
|
+
*/
|
|
283
|
+
selectorForOwner<Key>(source: Signal<Key>, owner: RaphScope, options?: RaphSelectorOptions<Key>): RuntimeSelector<Key>;
|
|
284
|
+
/**
|
|
285
|
+
* Создаёт Runtime signal и ставит его в список источников владельца. Signal
|
|
286
|
+
* одним объектом является handle, producer WorkGraph и записью источника.
|
|
39
287
|
*/
|
|
40
|
-
signalForOwner<T>(initialValue: T, owner: RaphScope,
|
|
288
|
+
signalForOwner<T>(initialValue: T, owner: RaphScope, kind?: RaphProducerKind, includeRuntime?: boolean): RuntimeSignal<T>;
|
|
41
289
|
/**
|
|
42
290
|
* Создаёт owned computed с runtime lifecycle policy.
|
|
43
291
|
*/
|
|
@@ -2,25 +2,25 @@ import { Disposer } from '../../reactivity/types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Хранит общий callback/cleanup lifecycle Runtime-watch без знания источника
|
|
4
4
|
* событий. Регистрация в Kernel и фазовая доставка остаются у Runtime.
|
|
5
|
+
*
|
|
6
|
+
* Поля объявлены без initializers и присваиваются в constructor в одном
|
|
7
|
+
* фиксированном порядке: у каждого watch, включая наследников, один hidden
|
|
8
|
+
* class, и ни один build target не превращает поля в вызовы helper.
|
|
5
9
|
*/
|
|
6
10
|
export declare class RuntimeWatch {
|
|
7
|
-
private readonly _runUntracked;
|
|
8
|
-
private readonly _callback;
|
|
9
11
|
private _cleanup;
|
|
10
12
|
private _stopped;
|
|
13
|
+
private readonly _runUntracked;
|
|
14
|
+
private readonly _callback;
|
|
15
|
+
readonly deliver: () => void;
|
|
11
16
|
/**
|
|
12
17
|
* Создаёт runtime-owned watch с явным lifecycle остановки.
|
|
13
18
|
*/
|
|
14
|
-
constructor(
|
|
19
|
+
constructor(runUntracked: <T>(operation: () => T) => T, callback: () => void | Disposer);
|
|
15
20
|
/**
|
|
16
21
|
* Показывает, остановлен ли watch.
|
|
17
22
|
*/
|
|
18
23
|
get stopped(): boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Освобождает предыдущий результат callback и выполняет новую доставку.
|
|
21
|
-
* Ошибка cleanup не лишает живой watcher текущего события.
|
|
22
|
-
*/
|
|
23
|
-
readonly deliver: () => void;
|
|
24
24
|
/**
|
|
25
25
|
* Preserves cleanup/callback error aggregation and reentrant stop semantics
|
|
26
26
|
* for the less common resource-returning callback path.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { RuntimeDisposalSweeper } from './runtime-reactivity.types';
|
|
2
|
+
/**
|
|
3
|
+
* Ставит участника в очередь со сроком `due`.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare function enqueueSweeper(queue: RuntimeDisposalSweeper[], sweeper: RuntimeDisposalSweeper, due: number): void;
|
|
8
|
+
/**
|
|
9
|
+
* Убирает участника из очереди. Возвращает false, если участника в ней нет.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function dequeueSweeper(queue: RuntimeDisposalSweeper[], sweeper: RuntimeDisposalSweeper): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Назначает ближайшему участнику очереди новый срок не раньше прежнего.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare function postponeFirstSweeper(queue: RuntimeDisposalSweeper[], due: number): void;
|
|
@@ -1,11 +1,56 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReactiveEdge, ReactiveNode } from '../../reactivity/types';
|
|
2
2
|
import { RaphScope } from '../ownership/RaphScope';
|
|
3
3
|
export interface RuntimeSignalLifecycle {
|
|
4
4
|
owner: object | undefined;
|
|
5
5
|
assertWriteAllowed?: () => void;
|
|
6
|
-
runWrite?: <T>(operation: () => T) => T;
|
|
7
6
|
assertDependencyAllowed: (sourceOwner: RaphScope, consumerOwner: RaphScope) => void;
|
|
8
7
|
throwDisposed: () => never;
|
|
9
8
|
throwCrossRuntime: (owner: object) => never;
|
|
10
9
|
}
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Записи графа одного consumer и его producers после их полного освобождения.
|
|
12
|
+
* Engine больше не достигает их ни через один список; их удерживает только
|
|
13
|
+
* якорь форм `RuntimeReactivity._releasedShapeAnchor`.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export interface ReleasedGraphShapes {
|
|
18
|
+
readonly source: ReactiveNode;
|
|
19
|
+
readonly written: ReactiveNode;
|
|
20
|
+
readonly edge: ReactiveEdge;
|
|
21
|
+
readonly consumer: ReactiveNode;
|
|
22
|
+
readonly counter: ReactiveNode<number>;
|
|
23
|
+
readonly bumped: ReactiveNode<number>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Участник уборки после освобождения владельцев. Runtime считает освобождённых
|
|
27
|
+
* владельцев и на внешней границе освобождения вызывает только тех участников,
|
|
28
|
+
* чей срок подошёл. Так selector находит triggers, потерявшие потребителей, не
|
|
29
|
+
* получая уведомления о каждой снятой связи графа.
|
|
30
|
+
*
|
|
31
|
+
* Участник подключается не более чем к одному Runtime и не более одного раза.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export interface RuntimeDisposalSweeper {
|
|
36
|
+
_sweepSlot: number;
|
|
37
|
+
_sweepDue: number;
|
|
38
|
+
_afterOwnerDisposals: (disposals: number) => number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Наблюдатель фактических записей одного Runtime signal. Signal вызывает его
|
|
42
|
+
* синхронно внутри своей границы записи, после того как новое значение стало
|
|
43
|
+
* видимым для чтения. Так selector будит потребителей отдельных ключей, не
|
|
44
|
+
* подписывая их на сам signal.
|
|
45
|
+
*
|
|
46
|
+
* Наблюдатель подключается не более чем к одному signal и не более одного
|
|
47
|
+
* раза. Порядок вызова наблюдателей одного signal не определён.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
export interface RuntimeSignalWriteTap {
|
|
52
|
+
_tapSlot: number;
|
|
53
|
+
readonly _tapOwner: object;
|
|
54
|
+
_observesWrites: () => boolean;
|
|
55
|
+
_afterSourceWrite: (previous: unknown, value: unknown) => void;
|
|
56
|
+
}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"url": "https://gitlab.com/raphyjs/raphy-js-raph.git"
|
|
6
6
|
},
|
|
7
7
|
"type": "module",
|
|
8
|
-
"version": "1.0.1-dev.
|
|
8
|
+
"version": "1.0.1-dev.25",
|
|
9
9
|
"private": false,
|
|
10
10
|
"description": "Reactive signals, paths and application runtime",
|
|
11
11
|
"license": "Apache-2.0",
|
|
@@ -78,6 +78,14 @@
|
|
|
78
78
|
"test:benchmark:reactivity": "pnpm --ignore-workspace run bench:reactivity:correctness",
|
|
79
79
|
"bench:install": "pnpm --ignore-workspace run bench:reactivity:install",
|
|
80
80
|
"bench": "pnpm --ignore-workspace run bench:reactivity:performance",
|
|
81
|
+
"bench:churn:install": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run install:lab",
|
|
82
|
+
"bench:churn:test": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn test",
|
|
83
|
+
"bench:churn:correctness": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run correctness",
|
|
84
|
+
"bench:churn:light": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run light",
|
|
85
|
+
"bench:churn:balanced": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run balanced",
|
|
86
|
+
"bench:churn:parts": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run parts",
|
|
87
|
+
"bench:churn:paired": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run paired",
|
|
88
|
+
"bench:churn:aa": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/runtime-churn run aa",
|
|
81
89
|
"bench:path": "node src/test/benchmarks/path/run.mjs",
|
|
82
90
|
"bench:reactivity:install": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/reactivity run install:lab",
|
|
83
91
|
"bench:reactivity:correctness": "pnpm --ignore-workspace --dir src/test/benchmarks/labs/reactivity run correctness",
|
package/dist/core-ugchZNqC.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const Z=new WeakMap,St=16384;function xt(t){var j;if(Pt(t.id,t.version),typeof t.states!="object"||t.states===null||Array.isArray(t.states))throw new TypeError("[Raph machine] states must be an object.");const e=t,n=[],r=new Map,i=[];for(const[h,b]of Object.entries(e.states))i.push(ct(h,b,void 0,0,n,r));const o=r.get(t.initial);if(o===void 0||((j=n[o])==null?void 0:j.parent)!==void 0)throw new Error(`[Raph machine] Initial state "${t.initial}" must be a root state key.`);const a=new Set,s=n.map(h=>{const b=h.initialKey===void 0?void 0:h.children.find(z=>{var l;return((l=n[z])==null?void 0:l.key)===h.initialKey});if(h.kind==="compound"&&b===void 0)throw new Error(`[Raph machine] Compound state "${h.path}" requires a valid direct initial child.`);if(b!==void 0&&n[b].kind==="history")throw new Error(`[Raph machine] Compound state "${h.path}" cannot use history as its initial child.`);const E=h.historyFallbackPath===void 0?void 0:r.get(h.historyFallbackPath);if(h.historyFallbackPath!==void 0&&E===void 0)throw new Error(`[Raph machine] History state "${h.path}" has unknown fallback "${h.historyFallbackPath}".`);for(const z of h.on.keys())a.add(z);return{after:h.after,always:h.always,children:Object.freeze([...h.children]),depth:h.depth,entry:h.entry,exit:h.exit,history:h.history,...E===void 0?{}:{historyFallback:E},id:h.id,...b===void 0?{}:{initial:b},invokes:h.invokes,key:h.key,kind:h.kind,...h.meta===void 0?{}:{meta:h.meta},on:h.on,onDone:h.onDone,...h.output===void 0?{}:{output:h.output},...h.parent===void 0?{}:{parent:h.parent},path:h.path,resources:h.resources,tags:h.tags}});for(const h of s)$t(h,r,s);const c=t.version??1;It(s);const f=Object.freeze([...a]),u=new Map(f.map((h,b)=>[h,b])),d=Object.freeze(s.map(h=>Object.freeze(gt(s,h.id)))),p=Rt(s),v=p&&f.length<=Math.floor(St/s.length)?zt(s,u,f.length):void 0,w=Object.freeze({ancestry:d,context:_t(e.context),eventIndexes:u,eventTypes:f,flat:p,...v===void 0?{}:{flatDispatch:v},id:t.id,initial:o,migrations:Dt(t.migrations,c),...e.output===void 0?{}:{output:e.output},pathToState:r,rootChildren:Object.freeze(i),states:Object.freeze(s),version:c}),m=Object.freeze({id:t.id,version:c});return Z.set(m,w),m}function zt(t,e,n){const r=Array.from({length:t.length*n}).fill(void 0);for(const i of t){const o=i.id*n;for(const[a,s]of i.on)r[o+e.get(a)]=s}return Object.freeze(r)}function gt(t,e){const n=[];for(let r=e;r!==void 0;r=t[r].parent)n.push(r);return n}function Rt(t){return t.every(e=>{if(e.parent!==void 0||e.kind!=="atomic"&&e.kind!=="final"||e.always.length!==0||e.onDone.length!==0||e.after.size!==0||e.entry.length!==0||e.exit.length!==0||e.resources.length!==0||e.invokes.length!==0)return!1;for(const n of e.on.values())if(n.some(r=>r.raise!==void 0))return!1;return!0})}function A(t){const e=Z.get(t);if(e===void 0)throw new TypeError("[Raph machine] Model was not created by defineMachine().");return e}function ct(t,e,n,r,i,o){if(typeof e!="object"||e===null||Array.isArray(e))throw new TypeError(`[Raph machine] State "${t}" must be an object.`);At(e,t),Ct(t);const a=n===void 0?"":i[n].path,s=a?`${a}.${t}`:t,c=i.length;if(o.has(s))throw new Error(`[Raph machine] Duplicate state path "${s}".`);const f=kt(e),u={after:new Map,always:Object.freeze([]),children:[],depth:r,entry:I(e.entry),exit:I(e.exit),history:e.history??"shallow",...e.target===void 0?{}:{historyFallbackPath:e.target},id:c,...e.initial===void 0?{}:{initialKey:e.initial},invokes:Object.freeze([]),key:t,kind:f,...e.meta===void 0?{}:{meta:Object.freeze({...e.meta})},on:new Map,onDone:Object.freeze([]),...e.output===void 0?{}:{output:e.output},...n===void 0?{}:{parent:n},path:s,resources:ot(e.resources),tags:ot(e.tags)};i.push(u),o.set(s,c);for(const[v,w]of Object.entries(e.states??{}))u.children.push(ct(v,w,c,r+1,i,o));let d=0;for(const[v,w]of Object.entries(e.on??{})){if(!v.trim())throw new Error(`[Raph machine] State "${s}" has an empty event type.`);u.on.set(v,P(w,c,()=>d++))}u.always=P(e.always,c,()=>d++),u.onDone=P(e.onDone,c,()=>d++);for(const[v,w]of Object.entries(e.after??{})){if(!v.trim())throw new Error(`[Raph machine] State "${s}" has an empty delay key.`);u.after.set(v,P(w,c,()=>d++))}const p=Ft(e.invoke);return u.invokes=Object.freeze(p.map((v,w)=>Tt(v,u,w,()=>d++))),Mt(u,i),c}function Tt(t,e,n,r){if(typeof t!="object"||t===null||Array.isArray(t))throw new TypeError(`[Raph machine] Invoke in "${e.path}" must be an object.`);const i=typeof t.src=="string"?"task":"machine",o=t.type??i,a=t.id??`${e.path}:invoke#${n+1}`;if(!a.trim())throw new Error(`[Raph machine] Invoke id in "${e.path}" must not be empty.`);if(o!=="machine"&&o!=="task")throw new Error(`[Raph machine] Invoke "${a}" has unsupported type "${String(o)}".`);if(typeof t.src=="string"){if(!t.src.trim())throw new Error(`[Raph machine] Invoke "${a}" source must not be empty.`)}else if(!Z.has(t.src))throw new TypeError(`[Raph machine] Invoke "${a}" actor source must come from defineMachine().`);if(o==="task"&&typeof t.src!="string")throw new TypeError(`[Raph machine] Task invoke "${a}" requires a string source.`);return Object.freeze({id:a,...t.input===void 0?{}:{input:t.input},onDone:P(t.onDone,e.id,r),onError:P(t.onError,e.id,r),src:t.src,type:o})}function P(t,e,n){if(t===void 0)return Object.freeze([]);const r=Array.isArray(t)?t:[t];return Object.freeze(r.map(i=>{const o=typeof i=="string"?{target:i}:i;if(o===null||typeof o!="object")throw new TypeError("[Raph machine] Transition must be a target string or object.");if(o.reenter===!0&&o.target===void 0)throw new Error("[Raph machine] A targetless transition cannot declare reenter: true.");if(o.reason!==void 0&&(typeof o.reason!="string"||!o.reason.trim()))throw new Error("[Raph machine] Transition reason must be a non-empty string.");return W(o.guard===void 0?[]:[o.guard],"guard"),W(I(o.reduce),"reducer"),W(I(o.emit),"output"),{emit:I(o.emit),...o.guard===void 0?{}:{guard:o.guard},index:n(),...o.raise===void 0?{}:{raise:o.raise},...o.reason===void 0?{}:{reason:o.reason},reduce:I(o.reduce),reenter:o.reenter===!0,source:e,...o.target===void 0?{}:{target:o.target}}}))}function $t(t,e,n){var i;const r=[t.always,t.onDone,...t.on.values(),...t.after.values()];for(const o of t.invokes)r.push(o.onDone,o.onError);for(const o of r)for(const a of o){if(a.target!==void 0){const s=a.target,c=e.get(s);if(c===void 0)throw new Error(`[Raph machine] Transition from "${t.path}" targets unknown state "${s}".`);a.target=c}Object.freeze(a)}if(t.kind==="history"&&t.historyFallback!==void 0){const o=(i=[...e].find(([,s])=>s===t.historyFallback))==null?void 0:i[0],a=t.path.slice(0,t.path.lastIndexOf("."));if(o===void 0||o===t.path||t.historyFallback===void 0||!o.startsWith(`${a}.`))throw new Error(`[Raph machine] History fallback for "${t.path}" must stay inside its parent state.`);if(n[t.historyFallback].kind==="history")throw new Error(`[Raph machine] History fallback for "${t.path}" cannot target another history state.`)}}function kt(t){if(t.type!==void 0){if(t.type!=="atomic"&&t.type!=="compound"&&t.type!=="final"&&t.type!=="history"&&t.type!=="parallel")throw new TypeError(`[Raph machine] Unsupported state type "${String(t.type)}".`);return t.type}return t.states===void 0?"atomic":"compound"}function Mt(t,e){if((t.kind==="atomic"||t.kind==="final"||t.kind==="history")&&t.children.length!==0)throw new Error(`[Raph machine] ${t.kind} state "${t.path}" cannot have children.`);if(t.kind==="parallel"&&t.initialKey!==void 0)throw new Error(`[Raph machine] Parallel state "${t.path}" cannot declare initial.`);if(t.kind==="parallel"&&!t.children.some(n=>e[n].kind!=="history"))throw new Error(`[Raph machine] Parallel state "${t.path}" requires at least one region.`);if(t.kind==="history"&&t.parent===void 0)throw new Error(`[Raph machine] History state "${t.path}" must have a parent.`);if(t.kind!=="history"&&t.historyFallbackPath!==void 0)throw new Error("[Raph machine] Only a history state may declare target as fallback.");if((t.kind==="atomic"||t.kind==="final"||t.kind==="history")&&t.initialKey!==void 0)throw new Error(`[Raph machine] ${t.kind} state "${t.path}" cannot declare initial.`);if((t.kind==="final"||t.kind==="history")&&(t.on.size!==0||t.always.length!==0||t.after.size!==0||t.onDone.length!==0||t.invokes.length!==0))throw new Error(`[Raph machine] ${t.kind} state "${t.path}" cannot declare transitions or invokes.`)}function At(t,e){if(U(t.states,`State "${e}" states`),U(t.on,`State "${e}" on`),U(t.after,`State "${e}" after`),t.history!==void 0&&t.history!=="deep"&&t.history!=="shallow")throw new TypeError(`[Raph machine] State "${e}" has unsupported history mode.`)}function U(t,e){if(t!==void 0&&(typeof t!="object"||t===null||Array.isArray(t)))throw new TypeError(`[Raph machine] ${e} must be an object.`)}function Pt(t,e){if(typeof t!="string"||!t.trim())throw new TypeError("[Raph machine] Model id must be a non-empty string.");const n=e??1;if(!Number.isSafeInteger(n)||n<1)throw new TypeError("[Raph machine] Model version must be a positive safe integer.")}function It(t){const e=new Set;for(const n of t)for(const r of n.invokes){if(e.has(r.id))throw new Error(`[Raph machine] Invoke id "${r.id}" is duplicated.`);e.add(r.id)}}function Dt(t,e){const n=new Map;for(const[r,i]of Object.entries(t??{})){const o=Number(r);if(!Number.isSafeInteger(o)||o<1||o>=e)throw new Error(`[Raph machine] Migration version "${r}" must be a positive integer below ${e}.`);if(typeof i!="function")throw new TypeError(`[Raph machine] Migration from version ${o} must be a function.`);n.set(o,i)}return n}function W(t,e){for(const n of t)if(typeof n!="function"&&(typeof n!="string"||!n.trim()))throw new TypeError(`[Raph machine] ${e} reference must be a function or non-empty string.`)}function Ct(t){if(!t||t.includes("."))throw new Error("[Raph machine] State keys must be non-empty and cannot contain dots.")}function I(t){return Object.freeze(t===void 0?[]:Array.isArray(t)?[...t]:[t])}function ot(t){if(t===void 0)return Object.freeze([]);const e=typeof t=="string"?[t]:[...t];for(const n of e)if(typeof n!="string"||!n.trim())throw new TypeError("[Raph machine] Tags and resource names must be non-empty strings.");return Object.freeze(e)}function Ft(t){return t===void 0?[]:Array.isArray(t)?t:[t]}function _t(t){return Array.isArray(t)?Object.freeze([...t]):typeof t=="object"&&t!==null&&Object.getPrototypeOf(t)===Object.prototype?Object.freeze({...t}):t}const T=Symbol("RaphMachineSnapshot"),it=new WeakMap;function ut(t){const e=Object.getPrototypeOf(t);return e!==null&&Object.hasOwn(e,T)?e:void 0}function ft(t){return t[T]}function L(t,e,n){const r=n??Object.freeze({[T]:e}),i=Object.create(r);return i.active=t.active,i.context=t.context,i.history=t.history,t.output!==void 0&&(i.output=t.output),i.revision=t.revision,i.status=t.status,Object.freeze(i)}function J(t,e,n,r,i){let o=t==null?void 0:t.flatPrototypes;o===void 0&&(n===void 0?(o=it.get(r),o===void 0&&(o=[],it.set(r,o))):o=[]);const a=o[e];if(a!==void 0)return a;const s=Object.freeze({[T]:Object.freeze({active:Object.freeze([e]),flatPrototypes:o,input:n,model:r,publicActive:Object.freeze([i])})});return o[e]=s,s}const Nt=100,G=Object.freeze({type:"@@init"}),ht=Object.freeze([]),q=Object.freeze({}),K=Object.freeze([]),C=Object.freeze([]),Ht=Object.freeze([]),Q=Object.freeze({entered:K,entryOutputs:C,event:G,exited:K,exitOutputs:C,transitionOutputs:C});function qt(t,e){return pt(t,e,void 0).snapshot}function Kt(t,e,n,r,i){const o=ft(e);if(o!==void 0&&o.model!==t)throw new TypeError("[Raph machine] Snapshot belongs to another model.");const a=A(t);return tt(t,e,n,r,o==null?void 0:o.input,i,a).snapshot}function dt(t,e){var n;if(((n=ut(e))==null?void 0:n[T].model)!==t)throw new TypeError("[Raph machine] Snapshot belongs to another model or was not created by Raph.")}function Lt(t,e){if(dt(t,e),e.status==="stopped")return e;const n=ut(e);return L({active:e.active,context:e.context,history:e.history,...e.output===void 0?{}:{output:e.output},revision:e.revision+1,status:"stopped"},n[T],n)}function pt(t,e,n,r){const i=A(t),o=i.context,a=typeof o=="function"?o(e):o;if(i.flat){const f=i.states[i.initial],u=f.kind==="final"?"done":"active",d=u==="done"?f.output??i.output:void 0,p=typeof d=="function"?d({context:a,event:G,input:e}):d,v=J(void 0,i.initial,e,t,f.path),w=v[T],m=L({active:w.publicActive,context:rt(a),history:q,...p===void 0?{}:{output:p},revision:0,status:u},w,v);return{changed:!1,plan:Q,snapshot:m}}const s=$(i,i.initial,q),c=F(t,e,{active:s,context:a,history:q},0,"active",void 0,i);return tt(t,c,G,n,e,r,i,!0)}function tt(t,e,n,r,i,o,a,s=!1,c=ht){return Et(n),lt(t,e,n,r,i,o,a,void 0,s,c)}function lt(t,e,n,r,i,o,a,s,c=!1,f=ht){const u=a??A(t);if(e.status!=="active")return D(e);if(!c&&u.flat){const y=s??u.eventIndexes.get(n.type);return y===void 0?D(e):Yt(t,u,e,n,y,r,i,o)}if(!c&&!ee(u,e.active,n.type))return D(e);const d={active:e.active.map(y=>N(u,y)),context:e.context,history:{...e.history}},p=r,v=new Set,w=new Set,m=[],j=[],h=[],b=[...f];let E=!1;if(!c){const y=at(u,d,n,p,i,o);st(y,v,w,m,j,h),E=y.changed,b.push(...y.raised)}const z=new Set;let l=0;for(;;){const y=b.shift();let S;if(y!==void 0?S=at(u,d,y,p,i,o):(S=Wt(u,d,n,p,i,o),S.changed||(S=Gt(u,d,n,p,i,z,o))),!S.changed){if(b.length!==0)continue;break}if(++l>Nt)throw new Error("[Raph machine] Macrostep exceeded 100 stabilization microsteps.");for(const B of S.exited)z.delete(B);for(const B of S.entered)z.delete(B);E=!0,st(S,v,w,m,j,h),b.push(...S.raised)}const O=nt(u,d.active)?"done":"active";if(!E&&O===e.status)return D(e);const k=O==="done"?bt(u,d,n,i):void 0,g=F(t,i,d,e.revision+1,O,k,u),R=new Set(_(u,d.active));return Object.freeze({changed:!0,plan:Object.freeze({entered:Object.freeze([...w].filter(y=>R.has(y)).sort((y,S)=>u.states[y].depth-u.states[S].depth)),entryOutputs:Object.freeze(h),event:n,exited:Object.freeze([...v].sort((y,S)=>u.states[S].depth-u.states[y].depth)),exitOutputs:Object.freeze(m),transitionOutputs:Object.freeze(j)}),snapshot:g})}function Yt(t,e,n,r,i,o,a,s){const c=ft(n),f=(c==null?void 0:c.active[0])??N(e,n.active[0]),u=e.flatDispatch===void 0?e.states[f].on.get(r.type):e.flatDispatch[f*e.eventTypes.length+i],d=H(u??Ht,n.context,r,o,a,s);if(d===void 0)return D(n);yt(e,d,s);let p=n.context;for(const z of d.reduce)p=Ot(z,o)({context:p,event:r,input:a});const v=d.target??f,w=e.states[v],m=w.kind==="final"?"done":"active",j=m==="done"?w.output??e.output:void 0,h=typeof j=="function"?j({context:p,event:r,input:a}):j,b=J(c,v,a,t,w.path),E=L({active:v===f?n.active:b[T].publicActive,context:p===n.context?n.context:rt(p),history:n.history,...h===void 0?{}:{output:h},revision:n.revision+1,status:m},b[T],b);return{changed:!0,plan:d.emit.length===0?Q:{entered:K,entryOutputs:C,event:r,exited:K,exitOutputs:C,transitionOutputRefs:d.emit,transitionOutputs:C},snapshot:E}}function Vt(t,e,n,r,i,o,a){const s=A(t),c=H(r,e.context,n,i,o,a);if(c===void 0)return D(e);const f={active:e.active.map(b=>N(s,b)),context:e.context,history:{...e.history}},u=Y(s,f,[c],n,i,o,a),d=F(t,o,f,e.revision,"active",void 0,s),p=tt(t,d,n,i,o,a,s,!0,u.raised),v=p.changed?{active:p.snapshot.active.map(b=>N(s,b)),context:p.snapshot.context,history:{...p.snapshot.history}}:f,w=p.changed?p.snapshot.status:nt(s,v.active)?"done":"active",m=w==="done"?p.snapshot.output??bt(s,v,n,o):void 0,j=F(t,o,v,e.revision+1,w,m,s),h=new Set(_(s,v.active));return Object.freeze({changed:!0,plan:Object.freeze({entered:Object.freeze(M([...u.entered,...p.plan.entered]).filter(b=>h.has(b)).sort((b,E)=>s.states[b].depth-s.states[E].depth)),entryOutputs:Object.freeze([...u.entryOutputs,...p.plan.entryOutputs]),event:n,exited:Object.freeze(M([...u.exited,...p.plan.exited]).sort((b,E)=>s.states[E].depth-s.states[b].depth)),exitOutputs:Object.freeze([...u.exitOutputs,...p.plan.exitOutputs]),transitionOutputs:Object.freeze([...u.transitionOutputs,...p.plan.transitionOutputs])}),snapshot:j})}function Bt(t,e,n){const r=A(t);if(e.status!=="active"&&e.status!=="done"&&e.status!=="stopped")throw new Error(`[Raph machine] Unknown persisted status "${String(e.status)}".`);if(!Number.isSafeInteger(e.revision)||e.revision<0)throw new Error("[Raph machine] Persisted revision must be a non-negative safe integer.");const i=e.active.map(o=>N(r,o));return Ut(r,i,e.history,e.status),F(t,n,{active:M(i),context:e.context,history:{...e.history}},e.revision,e.status,e.output,r)}function Ut(t,e,n,r){if(e.length===0||new Set(e).size!==e.length)throw new Error("[Raph machine] Persisted active configuration must contain unique leaf states.");for(const a of e){const s=t.states[a].kind;if(s!=="atomic"&&s!=="final")throw new Error(`[Raph machine] Persisted active state "${t.states[a].path}" is not a leaf.`)}if(new Set(e.map(a=>V(t,a))).size!==1)throw new Error("[Raph machine] Persisted configuration spans multiple root states.");for(const a of t.states){if(a.kind!=="compound"&&a.kind!=="parallel")continue;const s=a.children.filter(f=>t.states[f].kind!=="history"&&e.some(u=>u===f||x(t,f,u)));if(e.some(f=>x(t,a.id,f))){if(a.kind==="compound"&&s.length!==1)throw new Error(`[Raph machine] Compound state "${a.path}" requires one active child.`);if(a.kind==="parallel"&&s.length!==a.children.filter(f=>t.states[f].kind!=="history").length)throw new Error(`[Raph machine] Parallel state "${a.path}" requires every region.`)}}const o=nt(t,e);if(r==="done"&&!o)throw new Error("[Raph machine] Done persisted snapshot is not in a final configuration.");if(r==="active"&&o)throw new Error("[Raph machine] Active persisted snapshot is already final.");for(const[a,s]of Object.entries(n)){const c=t.pathToState.get(a);if(c===void 0)throw new Error(`[Raph machine] Persisted history has unknown owner "${a}".`);const f=t.states[c];if(f.kind!=="compound"&&f.kind!=="parallel")throw new Error(`[Raph machine] Persisted history owner "${a}" cannot own history.`);if(!Array.isArray(s))throw new TypeError(`[Raph machine] Persisted history for "${a}" must be an array.`);for(const u of s){const d=t.pathToState.get(u);if(d===void 0||!x(t,c,d))throw new Error(`[Raph machine] Persisted history path "${u}" is invalid for "${a}".`)}}}function at(t,e,n,r,i,o){const a=[],s=new Set,c=[...e.active].sort((f,u)=>t.states[u].depth-t.states[f].depth||f-u);for(const f of c)for(let u=f;u!==void 0&&!s.has(u);u=t.states[u].parent){const d=t.states[u].on.get(n.type);if(d===void 0)continue;const p=H(d,e.context,n,r,i,o);if(p!==void 0){s.add(u),a.push(p);break}}return Y(t,e,vt(t,a),n,r,i,o)}function Wt(t,e,n,r,i,o){const a=[],s=new Set;for(const c of e.active)for(let f=c;f!==void 0;f=t.states[f].parent){if(s.has(f))continue;s.add(f);const u=H(t.states[f].always,e.context,n,r,i,o);u!==void 0&&a.push(u)}return Y(t,e,vt(t,a),n,r,i,o)}function Gt(t,e,n,r,i,o,a){const s=_(t,e.active).filter(c=>!o.has(c)&&et(t,c,e.active)).sort((c,f)=>t.states[f].depth-t.states[c].depth);for(const c of s){o.add(c);const f=H(t.states[c].onDone,e.context,n,r,i,a);if(f!==void 0)return Y(t,e,[f],n,r,i,a)}return mt()}function Y(t,e,n,r,i,o,a){var z;if(n.length===0)return mt();const s=[...e.active],c=new Set(_(t,s)),f=new Set,u=new Set,d=new Set,p=[],v=[];let w=!1;for(const l of n){yt(t,l,a);for(const y of l.reduce)e.context=Ot(y,i)({context:e.context,event:r,input:o}),w=!0;for(const y of l.emit)p.push({event:r,ref:y});if(l.emit.length!==0&&(w=!0),l.raise!==void 0){const y=typeof l.raise=="function"?l.raise({context:e.context,event:r,input:o}):l.raise;Et(y),v.push(y),w=!0}if(l.target===void 0){w=!0;continue}const O=l.source,k=l.target;if(O===k&&!l.reenter){w=!0;continue}const g=X(t,O,k);if(l.reenter){d.add(g);for(const y of c)(y===g||x(t,g,y))&&f.add(y)}e.active=e.active.filter(y=>y!==g&&!x(t,g,y));const R=wt(t,k,e.history);e.active.push(...R),w=!0}e.active=Zt(t,M(e.active),e.history);const m=new Set(_(t,e.active));for(const l of d)for(const O of m)(O===l||x(t,l,O))&&u.add(O);const j=[...c].filter(l=>!m.has(l)||f.has(l)).sort((l,O)=>t.states[O].depth-t.states[l].depth),h=[...m].filter(l=>!c.has(l)||u.has(l)).sort((l,O)=>t.states[l].depth-t.states[O].depth);for(const l of j){const O=t.states[l];if(O.kind==="compound"||O.kind==="parallel"){const k=s.filter(g=>x(t,l,g));if(k.length!==0){const g=((z=O.children.map(R=>t.states[R]).find(R=>R.kind==="history"))==null?void 0:z.history)??O.history;e.history[O.path]=Object.freeze(k.map(R=>{if(g==="deep")return t.states[R].path;const y=jt(t,l,R);return t.states[y].path}))}}}const b=j.flatMap(l=>t.states[l].exit.map(O=>({event:r,ref:O}))),E=h.flatMap(l=>t.states[l].entry.map(O=>({event:r,ref:O})));return Object.freeze({changed:w||j.length!==0||h.length!==0,entered:Object.freeze(h),entryOutputs:Object.freeze(E),exited:Object.freeze(j),exitOutputs:Object.freeze(b),raised:Object.freeze(v),transitionOutputs:Object.freeze(p)})}function yt(t,e,n){(n==null?void 0:n.transition)!==void 0&&n.transition({...e.reason===void 0?{}:{reason:e.reason},source:t.states[e.source].path,...e.target===void 0?{}:{target:t.states[e.target].path}})}function H(t,e,n,r,i,o){var a;for(const s of t){if(s.guard===void 0)return s;const c=Jt(s.guard,r),f=c({context:e,event:n,input:i});if((a=o==null?void 0:o.guard)==null||a.call(o,typeof s.guard=="string"?s.guard:c.name||"inline",f,re(e)?e:void 0),f)return s}}function vt(t,e){const n=[...e].sort((i,o)=>t.states[o.source].depth-t.states[i.source].depth||i.source-o.source||i.index-o.index),r=[];for(const i of n)r.some(a=>Xt(t,i,a))||r.push(i);return r}function Xt(t,e,n){const r=X(t,e.source,e.target??e.source),i=X(t,n.source,n.target??n.source);return e.source===n.source||x(t,e.source,n.source)||x(t,n.source,e.source)||r===i||x(t,r,i)||x(t,i,r)}function X(t,e,n){if(e===n||x(t,e,n))return e;const r=Qt(t,e,n);return r!==void 0&&t.states[r].kind==="parallel"?r:r===void 0?V(t,e):jt(t,r,e)}function wt(t,e,n){const r=t.states[e];if(r.kind!=="history")return $(t,e,n);const i=r.parent,o=n[t.states[i].path];if(o!==void 0&&o.length!==0){const a=[];for(const s of o){const c=t.pathToState.get(s);c!==void 0&&a.push(...r.history==="deep"?$(t,c,n):$(t,c,{}))}if(a.length!==0)return M(a)}return r.historyFallback!==void 0?$(t,r.historyFallback,n):$(t,i,{})}function Zt(t,e,n){const r=[...e];for(let i=0;i<r.length;i++)for(const o of t.ancestry[r[i]].slice(1)){const a=t.states[o];if(a.kind==="parallel")for(const s of a.children)t.states[s].kind!=="history"&&(r.some(c=>c===s||x(t,s,c))||r.push(...$(t,s,n)))}return M(r)}function $(t,e,n){const r=t.states[e];if(r.kind==="history")return wt(t,e,n);if(r.kind==="atomic"||r.kind==="final")return[e];if(r.kind==="compound")return $(t,r.initial,n);const i=[];for(const o of r.children)t.states[o].kind!=="history"&&i.push(...$(t,o,n));return M(i)}function et(t,e,n){const r=t.states[e];return r.kind==="final"?n.includes(e):r.kind==="compound"?r.children.some(i=>t.states[i].kind==="final"&&n.includes(i)):r.kind==="parallel"?r.children.filter(i=>t.states[i].kind!=="history").every(i=>et(t,i,n)):!1}function nt(t,e){const n=te(t,e[0]);return n===void 0?!1:et(t,n,e)}function bt(t,e,n,r){const i=V(t,e.active[0]),o=t.states[i],a=o.kind==="compound"?e.active.find(c=>t.states[c].parent===i&&t.states[c].kind==="final"):o.kind==="final"?i:void 0,s=a===void 0?t.output:t.states[a].output??t.output;return typeof s=="function"?s({context:e.context,event:n,input:r}):s}function Jt(t,e){var r;if(typeof t=="function")return t;const n=(r=e==null?void 0:e.guards)==null?void 0:r[t];if(n===void 0)throw new Error(`[Raph machine] Guard binding "${t}" is not defined.`);return n}function Ot(t,e){var r;if(typeof t=="function")return t;const n=(r=e==null?void 0:e.reducers)==null?void 0:r[t];if(n===void 0)throw new Error(`[Raph machine] Reducer binding "${t}" is not defined.`);return n}function F(t,e,n,r,i,o,a){const s=a??A(t),c=s.flat&&n.active.length===1?n.active[0]:void 0,f=c===void 0?void 0:J(void 0,c,e,t,s.states[c].path),u=f===void 0?Object.freeze([...n.active]):void 0,d=(f==null?void 0:f[T])??Object.freeze({active:u,input:e,model:t});return L({active:d.publicActive??Object.freeze(u.map(p=>s.states[p].path)),context:rt(n.context),history:s.flat?q:ne(n.history),...o===void 0?{}:{output:o},revision:r,status:i},d,f)}function D(t,e){return{changed:!1,plan:Q,snapshot:t}}function mt(){return Object.freeze({changed:!1,entered:Object.freeze([]),entryOutputs:Object.freeze([]),exited:Object.freeze([]),exitOutputs:Object.freeze([]),raised:Object.freeze([]),transitionOutputs:Object.freeze([])})}function st(t,e,n,r,i,o){for(const a of t.exited)e.add(a);for(const a of t.entered)n.add(a);r.push(...t.exitOutputs),i.push(...t.transitionOutputs),o.push(...t.entryOutputs)}function _(t,e){const n=new Set;for(const r of e)for(const i of t.ancestry[r])n.add(i);return[...n]}function Qt(t,e,n){const r=new Set(t.ancestry[e]);for(const i of t.ancestry[n])if(r.has(i))return i}function x(t,e,n){const r=t.ancestry[n];return r.length>1&&r.includes(e,1)}function jt(t,e,n){let r=n;for(;t.states[r].parent!==e;){const i=t.states[r].parent;if(i===void 0)return r;r=i}return r}function V(t,e){return t.ancestry[e].at(-1)}function te(t,e){return e===void 0?void 0:V(t,e)}function N(t,e){const n=t.pathToState.get(e);if(n===void 0)throw new Error(`[Raph machine] Snapshot contains unknown state "${e}".`);return n}function ee(t,e,n){if(!t.eventIndexes.has(n))return!1;for(const r of e){const i=t.pathToState.get(r);if(i!==void 0){for(const o of t.ancestry[i])if(t.states[o].on.has(n))return!0}}return!1}function M(t){return[...new Set(t)].sort((e,n)=>e-n)}function rt(t){return typeof t=="object"&&t!==null?Object.freeze(t):t}function ne(t){const e={};for(const[n,r]of Object.entries(t))e[n]=Object.freeze([...r]);return Object.freeze(e)}function Et(t){if(typeof t!="object"||t===null||typeof t.type!="string"||!t.type)throw new TypeError("[Raph machine] Event must contain a non-empty string type.")}function re(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}exports.assertMachineSnapshot=dt;exports.createInitialSnapshot=pt;exports.defineMachine=xt;exports.getCompiledMachine=A;exports.getInitialSnapshot=qt;exports.hydrateSnapshot=Bt;exports.runExplicitTransitions=Vt;exports.runValidatedMacrostep=lt;exports.stopMachineSnapshot=Lt;exports.transition=Kt;
|