@raphy-js/raph 1.0.1-dev.20 → 1.0.1-dev.26
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 +10 -2
- package/dist/core-ugchZNqC.cjs +0 -1
|
@@ -1,26 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { watchWithReactivity as Y } from "./watch.js";
|
|
7
|
-
const w = 1, p = 2, C = 4, D = 8, T = 16, y = 32, x = 64, W = 128, m = 256, v = 512, E = w | p, R = 16, X = 2;
|
|
8
|
-
function N(c) {
|
|
1
|
+
import { reactiveObject as O } from "./reactive-object.js";
|
|
2
|
+
import { appendScopeChild as W, ScopeNode as U, throwScopeErrors as V, detachScopeChild as q } from "./scope.js";
|
|
3
|
+
import { watchWithReactivity as z } from "./watch.js";
|
|
4
|
+
const g = 1, f = 2, D = 4, p = 8, _ = 16, d = 32, v = 64, x = 128, k = 256, o = 512, L = 2048, E = 4096, m = 8192, R = L | E, T = 1e4, b = g | f, I = 16, F = 2;
|
|
5
|
+
function A(c) {
|
|
9
6
|
c.dependencyLookupDebt === void 0 && c.dependencyIndex === void 0 || (c.dependencyIndex = void 0, c.dependencyLookupDebt = void 0, c.dependencyLookupSearches = void 0);
|
|
10
7
|
}
|
|
11
|
-
function
|
|
12
|
-
if (e <=
|
|
8
|
+
function H(c, e) {
|
|
9
|
+
if (e <= I || c.flags & x || c.dependencyIndex !== void 0)
|
|
13
10
|
return;
|
|
14
11
|
const t = (c.dependencyLookupSearches ?? 0) + 1, i = (c.dependencyLookupDebt ?? 0) + e;
|
|
15
|
-
if (c.dependencyLookupSearches = t, c.dependencyLookupDebt = i, t <
|
|
12
|
+
if (c.dependencyLookupSearches = t, c.dependencyLookupDebt = i, t < F || i < c.depCount)
|
|
16
13
|
return;
|
|
17
14
|
const s = /* @__PURE__ */ new Map();
|
|
18
15
|
for (let n = c.firstDep; n !== null; n = n.nextDep)
|
|
19
16
|
s.set(n.dep, n);
|
|
20
17
|
c.dependencyIndex = s, c.dependencyLookupDebt = void 0, c.dependencyLookupSearches = void 0;
|
|
21
18
|
}
|
|
22
|
-
function
|
|
23
|
-
var a;
|
|
19
|
+
function Q(c, e, t) {
|
|
24
20
|
const i = c.firstSub;
|
|
25
21
|
if (i === null)
|
|
26
22
|
return;
|
|
@@ -31,21 +27,59 @@ function j(c, e, t) {
|
|
|
31
27
|
if (s.sub === e)
|
|
32
28
|
return c.subSearchCursor = s.nextSub ?? i, s;
|
|
33
29
|
if (t) {
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
return c.subSearchCursor =
|
|
30
|
+
const a = e.dependencyIndex?.get(c);
|
|
31
|
+
if (a !== void 0)
|
|
32
|
+
return c.subSearchCursor = a.nextSub ?? i, a;
|
|
37
33
|
if (e.dependencyIndex !== void 0)
|
|
38
34
|
return;
|
|
39
35
|
}
|
|
40
|
-
let
|
|
41
|
-
for (;
|
|
42
|
-
if (++n,
|
|
43
|
-
return c.subSearchCursor =
|
|
44
|
-
|
|
36
|
+
let r = s.nextSub ?? i;
|
|
37
|
+
for (; r !== s; ) {
|
|
38
|
+
if (++n, r.sub === e)
|
|
39
|
+
return c.subSearchCursor = r.nextSub ?? i, t && H(e, n), r;
|
|
40
|
+
r = r.nextSub ?? i;
|
|
45
41
|
}
|
|
46
|
-
t &&
|
|
42
|
+
t && H(e, n);
|
|
47
43
|
}
|
|
48
|
-
class
|
|
44
|
+
class N {
|
|
45
|
+
// Opt-in стратегия длинного slow path; не добавляет policy field каждой ноде.
|
|
46
|
+
adaptiveDependencyIndex;
|
|
47
|
+
// Потребитель текущего синхронного чтения; null отключает отслеживание.
|
|
48
|
+
activeSub = null;
|
|
49
|
+
// Глубина вложенных синхронных границ группировки.
|
|
50
|
+
batchDepth = 0;
|
|
51
|
+
// Индекс следующего элемента внутренней очереди эффектов.
|
|
52
|
+
effectReadIndex = 0;
|
|
53
|
+
// Позиция добавления элемента в текущем проходе очереди.
|
|
54
|
+
effectWriteIndex = 0;
|
|
55
|
+
// Граница активного префикса переиспользуемого стека invalidation.
|
|
56
|
+
invalidationDepth = 0;
|
|
57
|
+
// Граница активного префикса стека проверки зависимостей.
|
|
58
|
+
dependencyDepth = 0;
|
|
59
|
+
// Только активная проверка зависимостей требует дополнительной отметки записей.
|
|
60
|
+
checkingDepth = 0;
|
|
61
|
+
// Защита внутренней очереди от вложенного повторного прохода.
|
|
62
|
+
flushingEffects = !1;
|
|
63
|
+
// Переиспользуемый буфер очереди; прочитанная ячейка сразу освобождает ссылку.
|
|
64
|
+
effectQueue = new Array(16).fill(void 0);
|
|
65
|
+
// Переиспользуемый стек распространения invalidation; исходный способ выделения сохранён.
|
|
66
|
+
invalidationStack = new Array(512).fill(null);
|
|
67
|
+
// Переиспользуемый стек проверки зависимостей с защитой активного вложенного префикса.
|
|
68
|
+
dependencyStack = [];
|
|
69
|
+
// Общие адаптеры receiver для handles этого экземпляра.
|
|
70
|
+
// Создаются один раз, чтобы computed не хранил дополнительную ссылку на движок
|
|
71
|
+
// и не выделял отдельные get/peek closures на каждый источник.
|
|
72
|
+
handleReaders = this.createHandleReaders();
|
|
73
|
+
// Выбранная внешняя политика; у синхронного экземпляра отсутствует.
|
|
74
|
+
effectScheduler;
|
|
75
|
+
// Прямой обработчик очереди, выбранный один раз при создании экземпляра.
|
|
76
|
+
flushEffects;
|
|
77
|
+
/**
|
|
78
|
+
* Синхронная регистрация эффекта для Runtime и watch независимо от внешней политики.
|
|
79
|
+
* Это связанная ссылка на реализацию effect(), а не делегирующая функция.
|
|
80
|
+
* @internal
|
|
81
|
+
*/
|
|
82
|
+
_effectImmediate;
|
|
49
83
|
/**
|
|
50
84
|
* Выбирает политику исполнения и сохраняет совместимость извлечённых методов.
|
|
51
85
|
* Тела методов находятся на прототипе; bind() выполняется только при создании
|
|
@@ -53,42 +87,6 @@ class U {
|
|
|
53
87
|
* @param options Необязательная внешняя политика эффектов.
|
|
54
88
|
*/
|
|
55
89
|
constructor(e = {}) {
|
|
56
|
-
// Opt-in стратегия длинного slow path; не добавляет policy field каждой ноде.
|
|
57
|
-
b(this, "adaptiveDependencyIndex");
|
|
58
|
-
// Потребитель текущего синхронного чтения; null отключает отслеживание.
|
|
59
|
-
b(this, "activeSub", null);
|
|
60
|
-
// Глубина вложенных синхронных границ группировки.
|
|
61
|
-
b(this, "batchDepth", 0);
|
|
62
|
-
// Индекс следующего элемента внутренней очереди эффектов.
|
|
63
|
-
b(this, "effectReadIndex", 0);
|
|
64
|
-
// Позиция добавления элемента в текущем проходе очереди.
|
|
65
|
-
b(this, "effectWriteIndex", 0);
|
|
66
|
-
// Граница активного префикса переиспользуемого стека invalidation.
|
|
67
|
-
b(this, "invalidationDepth", 0);
|
|
68
|
-
// Граница активного префикса стека проверки зависимостей.
|
|
69
|
-
b(this, "dependencyDepth", 0);
|
|
70
|
-
// Защита внутренней очереди от вложенного повторного прохода.
|
|
71
|
-
b(this, "flushingEffects", !1);
|
|
72
|
-
// Переиспользуемый буфер очереди; прочитанная ячейка сразу освобождает ссылку.
|
|
73
|
-
b(this, "effectQueue", new Array(16).fill(void 0));
|
|
74
|
-
// Переиспользуемый стек распространения invalidation; исходный способ выделения сохранён.
|
|
75
|
-
b(this, "invalidationStack", new Array(512).fill(null));
|
|
76
|
-
// Переиспользуемый стек проверки зависимостей с защитой активного вложенного префикса.
|
|
77
|
-
b(this, "dependencyStack", []);
|
|
78
|
-
// Общие адаптеры receiver для handles этого экземпляра.
|
|
79
|
-
// Создаются один раз, чтобы computed не хранил дополнительную ссылку на движок
|
|
80
|
-
// и не выделял отдельные get/peek closures на каждый источник.
|
|
81
|
-
b(this, "handleReaders", this.createHandleReaders());
|
|
82
|
-
// Выбранная внешняя политика; у синхронного экземпляра отсутствует.
|
|
83
|
-
b(this, "effectScheduler");
|
|
84
|
-
// Прямой обработчик очереди, выбранный один раз при создании экземпляра.
|
|
85
|
-
b(this, "flushEffects");
|
|
86
|
-
/**
|
|
87
|
-
* Синхронная регистрация эффекта для Runtime и watch независимо от внешней политики.
|
|
88
|
-
* Это связанная ссылка на реализацию effect(), а не делегирующая функция.
|
|
89
|
-
* @internal
|
|
90
|
-
*/
|
|
91
|
-
b(this, "_effectImmediate");
|
|
92
90
|
this.adaptiveDependencyIndex = e.adaptiveDependencyIndex ?? !1, this.effectScheduler = e.effectScheduler, this._effectImmediate = this.effect.bind(this), this.signal = this.signal.bind(this), this.computed = this.computed.bind(this), this.reactive = this.reactive.bind(this), this.watch = this.watch.bind(this), this.batch = this.batch.bind(this), this.untracked = this.untracked.bind(this), this.scope = this.scope.bind(this), this._signalAccess = this._signalAccess.bind(this), this._computedAccess = this._computedAccess.bind(this), this._ownedSignal = this._ownedSignal.bind(this), this._ownedComputed = this._ownedComputed.bind(this), this._isTracking = this._isTracking.bind(this), this._isFlushingEffects = this._isFlushingEffects.bind(this), this._startBatch = this._startBatch.bind(this), this._endBatch = this._endBatch.bind(this), this.effect = this.effectScheduler === void 0 ? this._effectImmediate : this.createScheduledEffect.bind(this), this.flushEffects = this.effectScheduler === void 0 ? this.flushSyncEffects : this.flushExternalEffects;
|
|
93
91
|
}
|
|
94
92
|
// ---------------------------------------------
|
|
@@ -102,21 +100,21 @@ class U {
|
|
|
102
100
|
signal(e) {
|
|
103
101
|
let t = e, i;
|
|
104
102
|
const s = () => {
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
107
|
-
return this.readSignalValue(
|
|
103
|
+
const r = i;
|
|
104
|
+
if (r !== void 0)
|
|
105
|
+
return this.readSignalValue(r);
|
|
108
106
|
const a = this.activeSub;
|
|
109
107
|
return a === null || (i = this.materializeSignal(
|
|
110
108
|
t,
|
|
111
109
|
a
|
|
112
110
|
)), t;
|
|
113
|
-
}, n = (
|
|
111
|
+
}, n = (r) => {
|
|
114
112
|
const a = i;
|
|
115
113
|
if (a !== void 0) {
|
|
116
|
-
this.writeSignalValue(a,
|
|
114
|
+
this.writeSignalValue(a, r);
|
|
117
115
|
return;
|
|
118
116
|
}
|
|
119
|
-
t !==
|
|
117
|
+
t !== r && (t = r);
|
|
120
118
|
};
|
|
121
119
|
return {
|
|
122
120
|
get: s,
|
|
@@ -129,7 +127,7 @@ class U {
|
|
|
129
127
|
* Object context и per-property sources создаются лениво внутри этого engine.
|
|
130
128
|
*/
|
|
131
129
|
reactive(e) {
|
|
132
|
-
return
|
|
130
|
+
return O(this, e, () => this.createReactivePropertySourceBridge());
|
|
133
131
|
}
|
|
134
132
|
computed(e) {
|
|
135
133
|
if (typeof e == "function")
|
|
@@ -147,17 +145,17 @@ class U {
|
|
|
147
145
|
* @param onStop Однократная окончательная очистка, независимая от повторных запусков.
|
|
148
146
|
*/
|
|
149
147
|
effect(e, t) {
|
|
150
|
-
const i = this.allocateGraphRecord(void 0, e,
|
|
148
|
+
const i = this.allocateGraphRecord(void 0, e, f | g | d);
|
|
151
149
|
t !== void 0 && (i.onStop = t);
|
|
152
150
|
const s = this.activeSub;
|
|
153
|
-
s !== null && s.flags &
|
|
151
|
+
s !== null && s.flags & d && W(s, i);
|
|
154
152
|
try {
|
|
155
153
|
this.executeEffect(i);
|
|
156
154
|
} catch (n) {
|
|
157
155
|
try {
|
|
158
156
|
this.disposeEffect(i);
|
|
159
|
-
} catch (
|
|
160
|
-
throw new AggregateError([n,
|
|
157
|
+
} catch (r) {
|
|
158
|
+
throw new AggregateError([n, r], "Effect registration and cleanup failed.");
|
|
161
159
|
}
|
|
162
160
|
throw n;
|
|
163
161
|
}
|
|
@@ -167,7 +165,7 @@ class U {
|
|
|
167
165
|
* Наблюдает за источниками; callback и cleanup не создают зависимостей.
|
|
168
166
|
*/
|
|
169
167
|
watch(e, t, i) {
|
|
170
|
-
return
|
|
168
|
+
return z(this.effect, this.untracked, e, t, i);
|
|
171
169
|
}
|
|
172
170
|
/**
|
|
173
171
|
* Группирует синхронные записи и обрабатывает эффекты после внешней границы.
|
|
@@ -213,7 +211,7 @@ class U {
|
|
|
213
211
|
* Создаёт владельца ресурсов в текущем графе без Runtime и фаз.
|
|
214
212
|
*/
|
|
215
213
|
scope() {
|
|
216
|
-
return new
|
|
214
|
+
return new U(this);
|
|
217
215
|
}
|
|
218
216
|
// ---------------------------------------------
|
|
219
217
|
// PRIVATE
|
|
@@ -268,7 +266,7 @@ class U {
|
|
|
268
266
|
void 0,
|
|
269
267
|
0
|
|
270
268
|
);
|
|
271
|
-
return i !== void 0 && (s.sourceHooks = i, s.flags |=
|
|
269
|
+
return i !== void 0 && (s.sourceHooks = i, s.flags |= o), t.flags & x ? this.appendInitialDependency(s, t) : this.trackDependency(s, t), s;
|
|
272
270
|
}
|
|
273
271
|
/**
|
|
274
272
|
* Создаёт минимальный handle computed без преждевременного выделения полей графа.
|
|
@@ -290,23 +288,23 @@ class U {
|
|
|
290
288
|
* @param onStop Однократная окончательная очистка.
|
|
291
289
|
*/
|
|
292
290
|
createScheduledEffect(e, t) {
|
|
293
|
-
const i = this.allocateGraphRecord(void 0, e,
|
|
291
|
+
const i = this.allocateGraphRecord(void 0, e, f | g | d);
|
|
294
292
|
let s = !1;
|
|
295
293
|
t !== void 0 && (i.onStop = t);
|
|
296
294
|
const n = this.activeSub;
|
|
297
|
-
n !== null && n.flags &
|
|
298
|
-
const
|
|
299
|
-
if (!(!(i.flags &
|
|
300
|
-
i.flags &= ~
|
|
295
|
+
n !== null && n.flags & d && W(n, i);
|
|
296
|
+
const r = () => {
|
|
297
|
+
if (!(!(i.flags & v) || i.evaluate === void 0)) {
|
|
298
|
+
i.flags &= ~v, s = !0;
|
|
301
299
|
try {
|
|
302
300
|
this.executeEffect(i);
|
|
303
301
|
} catch (a) {
|
|
304
302
|
if (!this.batchDepth && this.effectReadIndex !== this.effectWriteIndex)
|
|
305
303
|
try {
|
|
306
304
|
this.flushEffects();
|
|
307
|
-
} catch (
|
|
305
|
+
} catch (l) {
|
|
308
306
|
throw new AggregateError(
|
|
309
|
-
[a,
|
|
307
|
+
[a, l],
|
|
310
308
|
"Effect execution and queue processing failed."
|
|
311
309
|
);
|
|
312
310
|
}
|
|
@@ -316,15 +314,15 @@ class U {
|
|
|
316
314
|
}
|
|
317
315
|
};
|
|
318
316
|
try {
|
|
319
|
-
const a = this.effectScheduler.bind(
|
|
320
|
-
a.cancelPending = () => i.evaluate === void 0 || !s ? !1 : (this.settleCancelledDependencies(i), i.flags &= ~(
|
|
321
|
-
i.evaluate !== void 0 && (i.flags |=
|
|
317
|
+
const a = this.effectScheduler.bind(r);
|
|
318
|
+
a.cancelPending = () => i.evaluate === void 0 || !s ? !1 : (this.settleCancelledDependencies(i), i.flags &= ~(v | b | D), !this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects(), !0), a.rearmPending = () => {
|
|
319
|
+
i.evaluate !== void 0 && (i.flags |= f | v, a.schedule());
|
|
322
320
|
}, i.effectTask = a, this.requestEffectTask(i);
|
|
323
321
|
} catch (a) {
|
|
324
322
|
try {
|
|
325
323
|
this.disposeEffect(i);
|
|
326
|
-
} catch (
|
|
327
|
-
throw new AggregateError([a,
|
|
324
|
+
} catch (l) {
|
|
325
|
+
throw new AggregateError([a, l], "Effect registration and cleanup failed.");
|
|
328
326
|
}
|
|
329
327
|
throw a;
|
|
330
328
|
}
|
|
@@ -337,7 +335,7 @@ class U {
|
|
|
337
335
|
readSignalValue(e) {
|
|
338
336
|
const t = this.activeSub;
|
|
339
337
|
let i = null;
|
|
340
|
-
return t !== null && (i = this.trackDependency(e, t)), e.flags &
|
|
338
|
+
return t !== null && (i = this.trackDependency(e, t)), e.flags & f && this.commitSignalValue(e, i), e.cachedValue;
|
|
341
339
|
}
|
|
342
340
|
/**
|
|
343
341
|
* Записывает новое значение или откладывает его фиксацию до чтения в batch.
|
|
@@ -345,19 +343,19 @@ class U {
|
|
|
345
343
|
* Без batch и внешней политики очередь эффектов завершается до возврата из set().
|
|
346
344
|
*/
|
|
347
345
|
writeSignalValue(e, t) {
|
|
348
|
-
if (e.flags &
|
|
349
|
-
const s = !!(e.flags &
|
|
350
|
-
if ((e.flags &
|
|
346
|
+
if (e.flags & f || this.batchDepth) {
|
|
347
|
+
const s = !!(e.flags & f);
|
|
348
|
+
if ((e.flags & f ? e.pendingValue : e.cachedValue) === t)
|
|
351
349
|
return;
|
|
352
350
|
if (e.pendingValue = t, e.cachedValue === t)
|
|
353
|
-
e.flags &= ~
|
|
351
|
+
e.flags &= ~f, e.pendingAuthor = void 0;
|
|
354
352
|
else {
|
|
355
|
-
e.flags |=
|
|
356
|
-
const a = this.activeSub !== null && this.activeSub.flags &
|
|
353
|
+
e.flags |= f;
|
|
354
|
+
const a = this.activeSub !== null && this.activeSub.flags & p ? this.activeSub : null;
|
|
357
355
|
s ? e.pendingAuthor !== a && (e.pendingAuthor = null) : e.pendingAuthor = a;
|
|
358
356
|
}
|
|
359
|
-
const
|
|
360
|
-
|
|
357
|
+
const r = e.firstSub;
|
|
358
|
+
r != null && (!s || this.activeSub !== null && this.activeSub.flags & p || e.flags & o) && this.propagateInvalidation(r, !0);
|
|
361
359
|
return;
|
|
362
360
|
}
|
|
363
361
|
if (e.cachedValue === t)
|
|
@@ -368,17 +366,21 @@ class U {
|
|
|
368
366
|
}
|
|
369
367
|
/**
|
|
370
368
|
* Возвращает кеш либо синхронно актуализирует вычисляемое значение.
|
|
371
|
-
* Неуспешное вычисление не считается значением.
|
|
372
|
-
*
|
|
369
|
+
* Неуспешное вычисление не считается значением. Ошибка getter сохраняет связь
|
|
370
|
+
* с активным потребителем для восстановления. Повторное чтение во время
|
|
371
|
+
* первого сбора зависимостей отклоняется до регистрации связи и чтения кеша.
|
|
373
372
|
*/
|
|
374
373
|
readComputedValue(e) {
|
|
375
|
-
const t = e.flags
|
|
374
|
+
const t = e.flags;
|
|
375
|
+
if ((t & (p | x)) === (p | x))
|
|
376
|
+
throw new Error("Computed value is already being evaluated.");
|
|
377
|
+
const i = t & (_ | b | k), s = i === 0 ? e.cachedValue : i & _ ? this.evaluateFirstValue(e) : this.refreshComputedValue(e, t);
|
|
376
378
|
if (e.evaluate === void 0)
|
|
377
379
|
return s;
|
|
378
380
|
const n = this.activeSub;
|
|
379
381
|
if (n !== null) {
|
|
380
|
-
const
|
|
381
|
-
n.flags &
|
|
382
|
+
const r = n.tailDep;
|
|
383
|
+
n.flags & x ? (r === null || r.dep !== e) && this.appendInitialDependency(e, n) : this.trackDependency(e, n);
|
|
382
384
|
}
|
|
383
385
|
return s;
|
|
384
386
|
}
|
|
@@ -388,18 +390,21 @@ class U {
|
|
|
388
390
|
* Уже прочитанные зависимости сохраняются для последующего уведомления.
|
|
389
391
|
*/
|
|
390
392
|
evaluateFirstValue(e) {
|
|
391
|
-
const t = e.flags &
|
|
392
|
-
e.flags = t |
|
|
393
|
+
const t = e.flags & o, i = e.evaluate;
|
|
394
|
+
e.flags = t | p | x;
|
|
393
395
|
const s = this.activeSub;
|
|
394
396
|
this.activeSub = e;
|
|
397
|
+
let n;
|
|
395
398
|
try {
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
399
|
+
if (n = i(), e.evaluate !== i)
|
|
400
|
+
return e.cachedValue = void 0, e.flags = 0, n;
|
|
401
|
+
e.flags = t | (e.flags & D ? f : 0);
|
|
402
|
+
} catch (r) {
|
|
403
|
+
throw e.evaluate !== i ? (e.cachedValue = void 0, e.flags = 0, r) : (e.flags = t | k, s !== null && this.trackDependency(e, s), r);
|
|
400
404
|
} finally {
|
|
401
405
|
this.activeSub = s;
|
|
402
406
|
}
|
|
407
|
+
return e.flags & f ? this.refreshComputedValue(e, e.flags) : (e.cachedValue = n, n);
|
|
403
408
|
}
|
|
404
409
|
/**
|
|
405
410
|
* Актуализирует computed: выполняет прямой пересчёт либо проверяет зависимости.
|
|
@@ -407,10 +412,10 @@ class U {
|
|
|
407
412
|
*/
|
|
408
413
|
refreshComputedValue(e, t, i = null) {
|
|
409
414
|
try {
|
|
410
|
-
if (t & (
|
|
411
|
-
return this.recomputeValue(e, i)
|
|
415
|
+
if (t & (f | D | k))
|
|
416
|
+
return this.recomputeValue(e, i), e.cachedValue;
|
|
412
417
|
const s = e.firstDep;
|
|
413
|
-
return
|
|
418
|
+
return s !== null && this.refreshDependencies(e, s) ? this.recomputeValue(e, i) : e.flags &= ~b, e.cachedValue;
|
|
414
419
|
} catch (s) {
|
|
415
420
|
throw this.activeSub !== null && this.trackDependency(e, this.activeSub), s;
|
|
416
421
|
}
|
|
@@ -422,7 +427,7 @@ class U {
|
|
|
422
427
|
*/
|
|
423
428
|
commitSignalValue(e, t) {
|
|
424
429
|
const i = e.cachedValue;
|
|
425
|
-
e.cachedValue = e.pendingValue, e.flags &= ~
|
|
430
|
+
e.cachedValue = e.pendingValue, e.flags &= ~f;
|
|
426
431
|
const s = e.pendingAuthor;
|
|
427
432
|
return e.pendingAuthor = void 0, i === e.cachedValue ? !1 : (e.firstSub !== null && this.confirmSubUpdates(e.firstSub, t, s ?? null), !0);
|
|
428
433
|
}
|
|
@@ -445,33 +450,33 @@ class U {
|
|
|
445
450
|
* Существующую связь перемещает или переиспользует; новую создаёт только при необходимости.
|
|
446
451
|
*/
|
|
447
452
|
reconcileDependency(e, t, i, s) {
|
|
448
|
-
if (t.depCount <=
|
|
449
|
-
for (let
|
|
450
|
-
if (
|
|
451
|
-
return this.reorderDependency(t,
|
|
452
|
-
for (let
|
|
453
|
-
if (
|
|
454
|
-
return
|
|
453
|
+
if (t.depCount <= I) {
|
|
454
|
+
for (let l = s; l !== null; l = l.nextDep)
|
|
455
|
+
if (l.dep === e)
|
|
456
|
+
return this.reorderDependency(t, l, i), t.tailDep = l, l;
|
|
457
|
+
for (let l = i; l !== null; l = l.prevDep)
|
|
458
|
+
if (l.dep === e)
|
|
459
|
+
return l;
|
|
455
460
|
return s !== null ? (t.tailDep = this.reuseDepLink(s, e), s) : t.tailDep = this.insertDependency(e, t, i);
|
|
456
461
|
}
|
|
457
|
-
let n = 0,
|
|
458
|
-
for (;
|
|
459
|
-
const
|
|
460
|
-
if (
|
|
461
|
-
return this.reorderDependency(t,
|
|
462
|
-
|
|
462
|
+
let n = 0, r = s;
|
|
463
|
+
for (; r !== null && n < I; ) {
|
|
464
|
+
const l = r;
|
|
465
|
+
if (l.dep === e)
|
|
466
|
+
return this.reorderDependency(t, l, i), t.tailDep = l, l;
|
|
467
|
+
r = l.nextDep, ++n;
|
|
463
468
|
}
|
|
464
469
|
let a = i;
|
|
465
|
-
for (; a !== null && n <
|
|
466
|
-
const
|
|
467
|
-
if (
|
|
468
|
-
return
|
|
469
|
-
a =
|
|
470
|
+
for (; a !== null && n < I; ) {
|
|
471
|
+
const l = a;
|
|
472
|
+
if (l.dep === e)
|
|
473
|
+
return l;
|
|
474
|
+
a = l.prevDep, ++n;
|
|
470
475
|
}
|
|
471
|
-
if (
|
|
472
|
-
const
|
|
473
|
-
if (
|
|
474
|
-
return this.reorderDependency(t,
|
|
476
|
+
if (r !== null || a !== null) {
|
|
477
|
+
const l = Q(e, t, this.adaptiveDependencyIndex);
|
|
478
|
+
if (l !== void 0)
|
|
479
|
+
return this.reorderDependency(t, l, i), t.tailDep = l, l;
|
|
475
480
|
}
|
|
476
481
|
return s !== null ? (t.tailDep = this.reuseDepLink(s, e), s) : t.tailDep = this.insertDependency(e, t, i);
|
|
477
482
|
}
|
|
@@ -481,7 +486,6 @@ class U {
|
|
|
481
486
|
* Связь одновременно включается в список потребителей производителя.
|
|
482
487
|
*/
|
|
483
488
|
appendInitialDependency(e, t) {
|
|
484
|
-
var l;
|
|
485
489
|
const i = t.tailDep, s = e.lastSub, n = {
|
|
486
490
|
dep: e,
|
|
487
491
|
sub: t,
|
|
@@ -490,14 +494,13 @@ class U {
|
|
|
490
494
|
prevDep: i,
|
|
491
495
|
nextDep: null
|
|
492
496
|
};
|
|
493
|
-
return s === null ? e.firstSub = n : s.nextSub = n, e.lastSub = n, i === null ? t.firstDep = n : i.nextDep = n, t.tailDep = n, ++t.depCount,
|
|
497
|
+
return s === null ? e.firstSub = n : s.nextSub = n, e.lastSub = n, i === null ? t.firstDep = n : i.nextDep = n, t.tailDep = n, ++t.depCount, t.dependencyIndex?.set(e, n), e.flags & o && this.attachDependencyCleanup(n), n;
|
|
494
498
|
}
|
|
495
499
|
/**
|
|
496
500
|
* Вставляет связь после заданного курсора зависимостей потребителя.
|
|
497
501
|
* Сохраняет ещё не прочитанный хвост списка и увеличивает dependencyCount.
|
|
498
502
|
*/
|
|
499
503
|
insertDependency(e, t, i) {
|
|
500
|
-
var a;
|
|
501
504
|
const s = e.lastSub, n = {
|
|
502
505
|
dep: e,
|
|
503
506
|
sub: t,
|
|
@@ -507,8 +510,8 @@ class U {
|
|
|
507
510
|
nextDep: null
|
|
508
511
|
};
|
|
509
512
|
s === null ? e.firstSub = n : s.nextSub = n, e.lastSub = n;
|
|
510
|
-
const
|
|
511
|
-
return n.nextDep =
|
|
513
|
+
const r = i === null ? t.firstDep : i.nextDep;
|
|
514
|
+
return n.nextDep = r, r !== null && (r.prevDep = n), i === null ? t.firstDep = n : i.nextDep = n, ++t.depCount, t.dependencyIndex?.set(e, n), e.flags & o && this.attachDependencyCleanup(n), n;
|
|
512
515
|
}
|
|
513
516
|
/**
|
|
514
517
|
* Переназначает существующую связь другому производителю.
|
|
@@ -518,7 +521,7 @@ class U {
|
|
|
518
521
|
const i = e.sub.dependencyIndex;
|
|
519
522
|
this.detachSubLink(e);
|
|
520
523
|
const s = t.lastSub;
|
|
521
|
-
return e.dep = t, e.prevSub = s, e.nextSub = null, s === null ? t.firstSub = e : s.nextSub = e, t.lastSub = e, i
|
|
524
|
+
return e.dep = t, e.prevSub = s, e.nextSub = null, s === null ? t.firstSub = e : s.nextSub = e, t.lastSub = e, i?.set(t, e), t.flags & o && this.attachDependencyCleanup(e), e;
|
|
522
525
|
}
|
|
523
526
|
/**
|
|
524
527
|
* Перемещает существующую зависимость после курсора текущего чтения.
|
|
@@ -529,45 +532,55 @@ class U {
|
|
|
529
532
|
return;
|
|
530
533
|
const s = t.prevDep, n = t.nextDep;
|
|
531
534
|
s === null ? e.firstDep = n : s.nextDep = n, n !== null && (n.prevDep = s);
|
|
532
|
-
const
|
|
533
|
-
t.prevDep = i, t.nextDep =
|
|
535
|
+
const r = i === null ? e.firstDep : i.nextDep;
|
|
536
|
+
t.prevDep = i, t.nextDep = r, r !== null && (r.prevDep = t), i === null ? e.firstDep = t : i.nextDep = t;
|
|
534
537
|
}
|
|
535
538
|
/**
|
|
536
539
|
* Удаляет непрочитанный хвост зависимостей завершившегося запуска.
|
|
537
540
|
* trackedTail обозначает границу прочитанного префикса, а не неизменный конец списка.
|
|
538
|
-
*
|
|
541
|
+
* Ошибка cleanup не прерывает освобождение оставшегося хвоста зависимостей.
|
|
539
542
|
*/
|
|
540
543
|
pruneUnreadDependencies(e) {
|
|
541
544
|
const t = e.tailDep;
|
|
542
545
|
let i = t === null ? e.firstDep : t.nextDep;
|
|
543
|
-
if (i
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
546
|
+
if (i === null)
|
|
547
|
+
return;
|
|
548
|
+
t === null ? e.firstDep = null : t.nextDep = null;
|
|
549
|
+
for (let n = i; n !== null; n = n.nextDep)
|
|
550
|
+
n.prevDep = null, --e.depCount;
|
|
551
|
+
e.depCount <= I && A(e);
|
|
552
|
+
let s;
|
|
553
|
+
for (; i !== null; ) {
|
|
554
|
+
const n = i.nextDep;
|
|
555
|
+
try {
|
|
556
|
+
this.detachSubLink(i, !0);
|
|
557
|
+
} catch (r) {
|
|
558
|
+
this.unlinkSubLink(i, !0), s ??= [], s.push(r);
|
|
547
559
|
}
|
|
548
|
-
|
|
560
|
+
i = n;
|
|
549
561
|
}
|
|
562
|
+
s !== void 0 && V(s, "Dependency cleanup failed.");
|
|
550
563
|
}
|
|
551
564
|
/**
|
|
552
565
|
* Удаляет связь только из списка потребителей производителя.
|
|
553
566
|
* Список зависимостей потребителя и его счётчик здесь не изменяются.
|
|
554
567
|
* Также исправляет курсор поиска, если он указывал на удаляемую связь.
|
|
555
568
|
*/
|
|
556
|
-
detachSubLink(e) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
569
|
+
detachSubLink(e, t = !1) {
|
|
570
|
+
e.sub.dependencyIndex?.delete(e.dep);
|
|
571
|
+
let i;
|
|
572
|
+
e.dep.flags & o && (i = e.dependencyCleanup, e.dependencyCleanup = void 0, i?.()), this.unlinkSubLink(e, t || i !== void 0);
|
|
573
|
+
}
|
|
574
|
+
/** Завершает удаление producer-связи без вызова source cleanup. */
|
|
575
|
+
unlinkSubLink(e, t) {
|
|
576
|
+
t && ((e.prevSub === null ? e.dep.firstSub !== e : e.prevSub.nextSub !== e) || (e.nextSub === null ? e.dep.lastSub !== e : e.nextSub.prevSub !== e)) || (e.dep.subSearchCursor === e && (e.dep.subSearchCursor = e.nextSub ?? (e.dep.firstSub === e ? void 0 : e.dep.firstSub ?? void 0)), e.prevSub === null ? e.dep.firstSub = e.nextSub : e.prevSub.nextSub = e.nextSub, e.nextSub === null ? e.dep.lastSub = e.prevSub : e.nextSub.prevSub = e.prevSub);
|
|
563
577
|
}
|
|
564
578
|
/** Connects Runtime ownership metadata only for edges whose producer opted in. */
|
|
565
579
|
attachDependencyCleanup(e) {
|
|
566
|
-
|
|
567
|
-
const t = e.dep.sourceHooks, i = t == null ? void 0 : t.onDependency;
|
|
580
|
+
const i = e.dep.sourceHooks?.onDependency;
|
|
568
581
|
if (i === void 0)
|
|
569
582
|
return;
|
|
570
|
-
const s =
|
|
583
|
+
const s = e.sub.sourceHooks?.dependencyOwner ?? e.sub.effectTask?.dependencyOwner;
|
|
571
584
|
s !== void 0 && (e.dependencyCleanup = i(s));
|
|
572
585
|
}
|
|
573
586
|
/**
|
|
@@ -576,23 +589,29 @@ class U {
|
|
|
576
589
|
* Переводит ожидавших проверку потребителей к повторному вычислению при необходимости.
|
|
577
590
|
*/
|
|
578
591
|
releaseSourceSubs(e) {
|
|
579
|
-
if (!(e.flags &
|
|
580
|
-
let
|
|
581
|
-
for (;
|
|
582
|
-
const
|
|
583
|
-
this.detachDependencyLink(
|
|
584
|
-
const
|
|
585
|
-
(
|
|
592
|
+
if (!(e.flags & o)) {
|
|
593
|
+
let s = e.firstSub;
|
|
594
|
+
for (; s != null; ) {
|
|
595
|
+
const n = s.nextSub, r = s.sub;
|
|
596
|
+
this.detachDependencyLink(s), this.detachSubLink(s);
|
|
597
|
+
const a = r.flags;
|
|
598
|
+
(a & (b | p)) === g && (r.flags = a & ~g | f, a & d && this.enqueueEffect(r, e)), s = n;
|
|
586
599
|
}
|
|
587
600
|
e.firstSub = e.lastSub = null, e.subSearchCursor = void 0;
|
|
588
601
|
return;
|
|
589
602
|
}
|
|
590
|
-
let t = e.firstSub;
|
|
603
|
+
let t = e.firstSub, i;
|
|
591
604
|
for (; t != null; ) {
|
|
592
|
-
const
|
|
593
|
-
this.detachDependencyLink(t)
|
|
605
|
+
const s = t.nextSub;
|
|
606
|
+
this.detachDependencyLink(t);
|
|
607
|
+
try {
|
|
608
|
+
this.detachSubLink(t, !0);
|
|
609
|
+
} catch (n) {
|
|
610
|
+
this.unlinkSubLink(t, !0), i ??= [], i.push(n);
|
|
611
|
+
}
|
|
612
|
+
t = s;
|
|
594
613
|
}
|
|
595
|
-
e.firstSub = e.lastSub = null, e.subSearchCursor = void 0;
|
|
614
|
+
e.firstSub = e.lastSub = null, e.subSearchCursor = void 0, i !== void 0 && V(i, "Source dependency cleanup failed.");
|
|
596
615
|
}
|
|
597
616
|
/**
|
|
598
617
|
* Удаляет связь только из списка зависимостей потребителя.
|
|
@@ -601,16 +620,15 @@ class U {
|
|
|
601
620
|
*/
|
|
602
621
|
detachDependencyLink(e) {
|
|
603
622
|
const t = e.sub, i = e.prevDep, s = e.nextDep;
|
|
604
|
-
i === null ? t.firstDep = s : i.nextDep = s, s !== null && (s.prevDep = i), t.tailDep === e && (t.tailDep = i), --t.depCount, t.depCount <=
|
|
623
|
+
(i === null ? t.firstDep !== e : i.nextDep !== e) || (i === null ? t.firstDep = s : i.nextDep = s, s !== null && (s.prevDep = i), t.tailDep === e && (t.tailDep = i), --t.depCount, t.depCount <= I && A(t));
|
|
605
624
|
}
|
|
606
625
|
/**
|
|
607
626
|
* Добавляет эффект во внутреннюю очередь один раз до обработки текущей записи.
|
|
608
627
|
* Флаг SCHEDULED предотвращает повторное добавление без создания task-объекта.
|
|
609
628
|
*/
|
|
610
629
|
enqueueEffect(e, t) {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
i !== void 0 && ((n = (s = e.effectTask) == null ? void 0 : s.notify) == null || n.call(s, i)), !(e.flags & x) && (e.flags |= x, this.effectQueue[this.effectWriteIndex] = e, ++this.effectWriteIndex);
|
|
630
|
+
const i = t !== void 0 && t.flags & o ? t.sourceHooks.token : void 0;
|
|
631
|
+
i !== void 0 && e.effectTask?.notify?.(i), !(e.flags & v) && (e.flags |= v, this.effectQueue[this.effectWriteIndex] = e, ++this.effectWriteIndex);
|
|
614
632
|
}
|
|
615
633
|
/**
|
|
616
634
|
* Распространяет invalidation от непосредственных к транзитивным потребителям.
|
|
@@ -618,45 +636,55 @@ class U {
|
|
|
618
636
|
* не выполняет. Непосредственное и потенциальное изменения отмечает разными флагами.
|
|
619
637
|
*/
|
|
620
638
|
propagateInvalidation(e, t = !1) {
|
|
621
|
-
|
|
639
|
+
this.checkingDepth !== 0 && this.markActiveChecks(e);
|
|
622
640
|
const i = this.invalidationDepth;
|
|
623
641
|
let s = i;
|
|
624
|
-
for (let
|
|
625
|
-
const
|
|
626
|
-
let
|
|
627
|
-
if (
|
|
628
|
-
if (
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
} else
|
|
642
|
+
for (let n = e; n !== null; n = n.nextSub) {
|
|
643
|
+
const r = n.sub, a = r.flags;
|
|
644
|
+
let l = 0;
|
|
645
|
+
if (a & (b | p) ? a & p ? l = this.invalidateReadDependency(n, r, a) : !t && !(a & f) && (r.flags = a & ~g | f) : (l = a & ~D | (t ? g : f), r.flags = l), l === 0) {
|
|
646
|
+
if (a & d && a & v) {
|
|
647
|
+
const u = n.dep.flags & o ? n.dep.sourceHooks.token : void 0;
|
|
648
|
+
u !== void 0 && r.effectTask?.notify?.(u);
|
|
649
|
+
} else r.flags & (o | m) && (r.flags & o && r.sourceHooks.onInvalidate?.(r.firstSub !== null), r.flags &= ~m, r.firstSub !== null && (this.invalidationStack[s++] = r.firstSub));
|
|
632
650
|
continue;
|
|
633
651
|
}
|
|
634
|
-
|
|
652
|
+
l & d ? (!(l & p) || r.effectTask?.allowScheduleDuringRun === !0) && this.enqueueEffect(r, n.dep) : (!(a & b) && r.flags & o && r.sourceHooks.onInvalidate?.(r.firstSub !== null), r.firstSub !== null && (this.invalidationStack[s++] = r.firstSub));
|
|
635
653
|
}
|
|
636
654
|
for (; s !== i; ) {
|
|
637
|
-
let
|
|
655
|
+
let n = this.invalidationStack[--s];
|
|
638
656
|
do {
|
|
639
|
-
const
|
|
640
|
-
let
|
|
641
|
-
if (
|
|
642
|
-
if (
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
} else if (
|
|
646
|
-
|
|
657
|
+
const r = n.sub, a = r.flags;
|
|
658
|
+
let l = 0;
|
|
659
|
+
if (a & (b | p) ? a & p && (l = this.invalidateReadDependency(n, r, a)) : (l = a & ~D | g, r.flags = l), l === 0) {
|
|
660
|
+
if (a & d && a & v) {
|
|
661
|
+
const u = n.dep.flags & o ? n.dep.sourceHooks.token : void 0;
|
|
662
|
+
u !== void 0 && r.effectTask?.notify?.(u);
|
|
663
|
+
} else if (r.flags & (o | m) && (r.flags & o && r.sourceHooks.onInvalidate?.(r.firstSub !== null), r.flags &= ~m, r.firstSub !== null)) {
|
|
664
|
+
n.nextSub !== null && (this.invalidationStack[s++] = n.nextSub), n = r.firstSub;
|
|
647
665
|
continue;
|
|
648
666
|
}
|
|
649
|
-
} else if (
|
|
650
|
-
this.enqueueEffect(
|
|
651
|
-
else if (!(
|
|
652
|
-
|
|
667
|
+
} else if (l & d)
|
|
668
|
+
this.enqueueEffect(r, n.dep);
|
|
669
|
+
else if (!(a & b) && r.flags & o && r.sourceHooks.onInvalidate?.(r.firstSub !== null), r.firstSub !== null) {
|
|
670
|
+
n.nextSub !== null && (this.invalidationStack[s++] = n.nextSub), n = r.firstSub;
|
|
653
671
|
continue;
|
|
654
672
|
}
|
|
655
|
-
|
|
656
|
-
} while (
|
|
673
|
+
n = n.nextSub;
|
|
674
|
+
} while (n !== null);
|
|
657
675
|
}
|
|
658
676
|
this.invalidationDepth = i;
|
|
659
677
|
}
|
|
678
|
+
// Дополнительный обход не вызывает callbacks и проходит уже dirty computed:
|
|
679
|
+
// флаги обычной invalidation не показывают, какую связь check уже прошёл.
|
|
680
|
+
markActiveChecks(e) {
|
|
681
|
+
const t = [e], i = /* @__PURE__ */ new Set();
|
|
682
|
+
for (; t.length !== 0; )
|
|
683
|
+
for (let s = t.pop(); s !== null; s = s.nextSub) {
|
|
684
|
+
const n = s.sub;
|
|
685
|
+
i.has(n) || (i.add(n), n.flags & L && (n.flags |= E), !(n.flags & d) && n.firstSub !== null && t.push(n.firstSub));
|
|
686
|
+
}
|
|
687
|
+
}
|
|
660
688
|
/**
|
|
661
689
|
* Помечает работающего потребителя, только если затронута уже прочитанная связь.
|
|
662
690
|
* Связи за trackedTail принадлежат прошлому запуску и не означают повторную invalidation.
|
|
@@ -667,11 +695,11 @@ class U {
|
|
|
667
695
|
if (s === null)
|
|
668
696
|
return 0;
|
|
669
697
|
if (e !== s) {
|
|
670
|
-
for (let
|
|
671
|
-
if (
|
|
698
|
+
for (let r = e.prevDep; r !== null; r = r.prevDep)
|
|
699
|
+
if (r === s)
|
|
672
700
|
return 0;
|
|
673
701
|
}
|
|
674
|
-
const n = i |
|
|
702
|
+
const n = i | D | g;
|
|
675
703
|
return t.flags = n, n;
|
|
676
704
|
}
|
|
677
705
|
/**
|
|
@@ -680,12 +708,11 @@ class U {
|
|
|
680
708
|
* текущую связь и автора записи.
|
|
681
709
|
*/
|
|
682
710
|
confirmSubUpdates(e, t, i = null) {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
if (l === t || l.sub === i)
|
|
711
|
+
for (let s = e; s !== null; s = s.nextSub) {
|
|
712
|
+
if (s === t || s.sub === i)
|
|
686
713
|
continue;
|
|
687
|
-
const
|
|
688
|
-
r &
|
|
714
|
+
const n = s.sub, r = n.flags;
|
|
715
|
+
r & f || (n.flags = r & ~g | f, r & d ? this.enqueueEffect(n, s.dep) : r & b || n.flags & o && n.sourceHooks.onInvalidate?.(n.firstSub !== null));
|
|
689
716
|
}
|
|
690
717
|
}
|
|
691
718
|
/**
|
|
@@ -696,26 +723,52 @@ class U {
|
|
|
696
723
|
* Неверное значение в кеш не записывается.
|
|
697
724
|
*/
|
|
698
725
|
recomputeValue(e, t = null) {
|
|
699
|
-
const i = e.
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
726
|
+
const i = e.cachedValue;
|
|
727
|
+
for (let s = 0; s < T; s++) {
|
|
728
|
+
const n = e.evaluate;
|
|
729
|
+
e.tailDep = null;
|
|
730
|
+
const r = e.flags & -6149 | p;
|
|
731
|
+
e.flags = r;
|
|
732
|
+
const a = this.activeSub;
|
|
733
|
+
this.activeSub = e;
|
|
734
|
+
let l;
|
|
735
|
+
try {
|
|
736
|
+
l = n();
|
|
737
|
+
} catch (h) {
|
|
738
|
+
if (e.evaluate !== n)
|
|
739
|
+
throw e.cachedValue = void 0, e.flags = 0, h;
|
|
740
|
+
this.failComputedValue(e, t, h);
|
|
741
|
+
} finally {
|
|
742
|
+
this.activeSub = a;
|
|
743
|
+
}
|
|
744
|
+
if (e.evaluate !== n)
|
|
745
|
+
return e.cachedValue = void 0, e.flags = 0, !1;
|
|
746
|
+
const u = e.tailDep;
|
|
747
|
+
if ((u === null ? e.firstDep : u.nextDep) !== null)
|
|
748
|
+
try {
|
|
749
|
+
this.pruneUnreadDependencies(e);
|
|
750
|
+
} catch (h) {
|
|
751
|
+
this.failComputedValue(e, t, h);
|
|
752
|
+
}
|
|
753
|
+
if (e.evaluate !== n)
|
|
754
|
+
return e.cachedValue = void 0, e.flags = 0, !1;
|
|
755
|
+
const w = e.flags & D;
|
|
756
|
+
if (e.flags = r & -8460, w) {
|
|
757
|
+
e.flags |= f;
|
|
758
|
+
continue;
|
|
759
|
+
}
|
|
760
|
+
return e.cachedValue = l, i === l ? !1 : (e.firstSub !== null && this.confirmSubUpdates(e.firstSub, t), !0);
|
|
761
|
+
}
|
|
762
|
+
return this.failComputedValue(e, t, new Error(`Computed settlement exceeded ${T} attempts.`));
|
|
763
|
+
}
|
|
764
|
+
/** Сохраняет первичную ошибку и отдельные ошибки cleanup при восстановлении. */
|
|
765
|
+
failComputedValue(e, t, i) {
|
|
706
766
|
try {
|
|
707
|
-
|
|
708
|
-
} catch (
|
|
709
|
-
throw
|
|
710
|
-
} finally {
|
|
711
|
-
this.activeSub = n;
|
|
767
|
+
this.restoreComputedFailure(e, t);
|
|
768
|
+
} catch (s) {
|
|
769
|
+
throw new AggregateError([i, s], "Computed evaluation and dependency cleanup failed.");
|
|
712
770
|
}
|
|
713
|
-
|
|
714
|
-
return e.cachedValue = void 0, e.flags = 0, !1;
|
|
715
|
-
const a = e.flags & C, r = s & -268, h = e.tailDep;
|
|
716
|
-
(h === null ? e.firstDep : h.nextDep) !== null && this.pruneUnreadDependencies(e);
|
|
717
|
-
const g = e.cachedValue;
|
|
718
|
-
return e.cachedValue = l, e.flags = s & v | (a ? p : r), g === l ? !1 : (e.firstSub !== null && this.confirmSubUpdates(e.firstSub, t), !0);
|
|
771
|
+
throw i;
|
|
719
772
|
}
|
|
720
773
|
/**
|
|
721
774
|
* Восстанавливает связи и состояния после неудачного getter.
|
|
@@ -723,7 +776,12 @@ class U {
|
|
|
723
776
|
* Потребитель исключаемой связи мог уже покинуть активный префикс стека.
|
|
724
777
|
*/
|
|
725
778
|
restoreComputedFailure(e, t) {
|
|
726
|
-
e.flags = e.flags & -
|
|
779
|
+
e.evaluate !== void 0 && (e.flags = e.flags & -6288 | k);
|
|
780
|
+
try {
|
|
781
|
+
e.evaluate !== void 0 && this.pruneUnreadDependencies(e);
|
|
782
|
+
} finally {
|
|
783
|
+
e.evaluate === void 0 && (e.cachedValue = void 0, e.flags = 0), t !== null && this.restoreFailedDependency(t.sub);
|
|
784
|
+
}
|
|
727
785
|
}
|
|
728
786
|
/**
|
|
729
787
|
* Итеративно проверяет зависимые computed и pending-сигналы перед запуском потребителя.
|
|
@@ -736,7 +794,7 @@ class U {
|
|
|
736
794
|
try {
|
|
737
795
|
return this.walkDependencyChain(e, t);
|
|
738
796
|
} catch (s) {
|
|
739
|
-
this.restoreFailedDependency(e);
|
|
797
|
+
this.markRecoveryDependencies(e), this.restoreFailedDependency(e);
|
|
740
798
|
for (let n = i; n < this.dependencyDepth; n++)
|
|
741
799
|
this.restoreFailedDependency(this.dependencyStack[n].sub);
|
|
742
800
|
throw this.dependencyDepth = i, this.dependencyStack.length = i, s;
|
|
@@ -746,7 +804,7 @@ class U {
|
|
|
746
804
|
settleCancelledDependencies(e) {
|
|
747
805
|
for (let t = e.firstDep; t !== null; t = t.nextDep) {
|
|
748
806
|
const i = t.dep, s = i.flags;
|
|
749
|
-
s & (
|
|
807
|
+
s & (_ | b | k) && (i.evaluate === void 0 ? s & f && this.commitSignalValue(i, t) : this.refreshComputedValue(i, s, t));
|
|
750
808
|
}
|
|
751
809
|
}
|
|
752
810
|
/**
|
|
@@ -756,51 +814,70 @@ class U {
|
|
|
756
814
|
*/
|
|
757
815
|
walkDependencyChain(e, t) {
|
|
758
816
|
const i = this.dependencyDepth;
|
|
759
|
-
let s = i, n = !1;
|
|
760
|
-
e
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
817
|
+
let s = i, n = !1, r;
|
|
818
|
+
e.flags = e.flags & ~E | L, ++this.checkingDepth;
|
|
819
|
+
try {
|
|
820
|
+
e: for (; ; ) {
|
|
821
|
+
if (e.flags & E) {
|
|
822
|
+
r ??= /* @__PURE__ */ new Map();
|
|
823
|
+
const a = (r.get(e) ?? 0) + 1;
|
|
824
|
+
if (r.set(e, a), a > T)
|
|
825
|
+
throw new Error(`Dependency check exceeded ${T} restarts.`);
|
|
826
|
+
e.flags &= ~E, e.firstDep !== null && (t = e.firstDep);
|
|
827
|
+
}
|
|
828
|
+
if (e.flags & f)
|
|
829
|
+
n = !0;
|
|
830
|
+
else {
|
|
831
|
+
const a = t.dep, l = a.flags;
|
|
832
|
+
if (l & (f | k))
|
|
833
|
+
this.dependencyDepth = s, n = a.evaluate === void 0 ? this.commitSignalValue(a, t) : this.recomputeValue(a, t);
|
|
834
|
+
else if (l & g) {
|
|
835
|
+
if (a.firstDep !== null) {
|
|
836
|
+
this.dependencyStack[s++] = t, e = a, e.flags = e.flags & ~E | L, t = a.firstDep;
|
|
837
|
+
continue e;
|
|
838
|
+
}
|
|
839
|
+
this.dependencyDepth = s, n = this.recomputeValue(a, t);
|
|
840
|
+
} else
|
|
841
|
+
n = !1;
|
|
842
|
+
}
|
|
843
|
+
if (!n && t.nextDep !== null) {
|
|
844
|
+
t = t.nextDep;
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
if (n) {
|
|
848
|
+
for (; s !== i; ) {
|
|
849
|
+
this.dependencyDepth = --s;
|
|
850
|
+
const a = this.dependencyStack[s];
|
|
851
|
+
if (e.flags &= ~R, n = this.recomputeValue(e, a), e = a.sub, !n) {
|
|
852
|
+
if (a.nextDep !== null) {
|
|
853
|
+
t = a.nextDep;
|
|
854
|
+
continue e;
|
|
855
|
+
}
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
771
858
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
}
|
|
776
|
-
if (!n && t.nextDep !== null) {
|
|
777
|
-
t = t.nextDep;
|
|
778
|
-
continue;
|
|
779
|
-
}
|
|
780
|
-
if (n) {
|
|
859
|
+
if (n)
|
|
860
|
+
return this.dependencyDepth = i, !0;
|
|
861
|
+
}
|
|
781
862
|
for (; s !== i; ) {
|
|
863
|
+
if (e.flags & (f | E))
|
|
864
|
+
continue e;
|
|
782
865
|
this.dependencyDepth = --s;
|
|
783
|
-
const
|
|
784
|
-
if (
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
continue e;
|
|
788
|
-
}
|
|
789
|
-
break;
|
|
866
|
+
const a = this.dependencyStack[s];
|
|
867
|
+
if (e.flags &= ~(g | R), e = a.sub, a.nextDep !== null) {
|
|
868
|
+
t = a.nextDep;
|
|
869
|
+
continue e;
|
|
790
870
|
}
|
|
791
871
|
}
|
|
792
|
-
if (
|
|
793
|
-
return this.dependencyDepth = i, !0;
|
|
794
|
-
}
|
|
795
|
-
for (; s !== i; ) {
|
|
796
|
-
this.dependencyDepth = --s;
|
|
797
|
-
const l = this.dependencyStack[s];
|
|
798
|
-
if (e.flags &= ~w, e = l.sub, l.nextDep !== null) {
|
|
799
|
-
t = l.nextDep;
|
|
872
|
+
if (e.flags & (f | E))
|
|
800
873
|
continue e;
|
|
801
|
-
|
|
874
|
+
return e.flags &= ~(g | R), this.dependencyDepth = i, !1;
|
|
802
875
|
}
|
|
803
|
-
|
|
876
|
+
} finally {
|
|
877
|
+
e.flags &= ~R;
|
|
878
|
+
for (let a = i; a < s; a++)
|
|
879
|
+
this.dependencyStack[a].sub.flags &= ~R;
|
|
880
|
+
--this.checkingDepth;
|
|
804
881
|
}
|
|
805
882
|
}
|
|
806
883
|
/**
|
|
@@ -809,7 +886,11 @@ class U {
|
|
|
809
886
|
* для следующей invalidation. Вызывается только на ошибочном пути.
|
|
810
887
|
*/
|
|
811
888
|
restoreFailedDependency(e) {
|
|
812
|
-
|
|
889
|
+
if (e.evaluate === void 0) {
|
|
890
|
+
e.cachedValue = void 0, e.flags = 0;
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
e.flags &= -6160, e.flags & d || (e.flags |= k);
|
|
813
894
|
}
|
|
814
895
|
/**
|
|
815
896
|
* Проверяет необходимость запуска, очищает прошлые ресурсы и выполняет тело эффекта.
|
|
@@ -820,70 +901,70 @@ class U {
|
|
|
820
901
|
*/
|
|
821
902
|
executeEffect(e) {
|
|
822
903
|
const t = e.flags;
|
|
823
|
-
if (!(t &
|
|
904
|
+
if (!(t & b))
|
|
824
905
|
return;
|
|
825
|
-
if (!(t & (
|
|
826
|
-
const
|
|
906
|
+
if (!(t & (f | D))) {
|
|
907
|
+
const u = e.firstDep;
|
|
827
908
|
try {
|
|
828
|
-
if (
|
|
829
|
-
e.flags &= ~
|
|
909
|
+
if (u === null || !this.refreshDependencies(e, u)) {
|
|
910
|
+
e.flags &= ~b;
|
|
830
911
|
return;
|
|
831
912
|
}
|
|
832
|
-
} catch (
|
|
833
|
-
throw e.flags &= -80,
|
|
913
|
+
} catch (w) {
|
|
914
|
+
throw e.flags &= -80, w;
|
|
834
915
|
}
|
|
835
916
|
}
|
|
836
917
|
const i = e.evaluate;
|
|
837
918
|
if (i === void 0) {
|
|
838
|
-
e.flags &= ~
|
|
919
|
+
e.flags &= ~b;
|
|
839
920
|
return;
|
|
840
921
|
}
|
|
841
922
|
let s;
|
|
842
923
|
if (e.scopeLastChild !== void 0)
|
|
843
924
|
try {
|
|
844
925
|
this.disposeNestedEffects(e);
|
|
845
|
-
} catch (
|
|
846
|
-
s = [
|
|
926
|
+
} catch (u) {
|
|
927
|
+
s = [u];
|
|
847
928
|
}
|
|
848
929
|
const n = typeof e.cachedValue == "function" ? e.cachedValue : void 0;
|
|
849
|
-
if (e.cachedValue = void 0, e.flags &= ~
|
|
930
|
+
if (e.cachedValue = void 0, e.flags &= ~D, n !== void 0)
|
|
850
931
|
try {
|
|
851
932
|
this.untracked(n);
|
|
852
|
-
} catch (
|
|
853
|
-
s
|
|
933
|
+
} catch (u) {
|
|
934
|
+
s ??= [], s.push(u);
|
|
854
935
|
}
|
|
855
936
|
if (s !== void 0) {
|
|
856
937
|
try {
|
|
857
938
|
this.disposeEffect(e);
|
|
858
|
-
} catch (
|
|
859
|
-
s.push(
|
|
939
|
+
} catch (u) {
|
|
940
|
+
s.push(u);
|
|
860
941
|
}
|
|
861
|
-
|
|
942
|
+
V(s, "Effect cleanup failed.");
|
|
862
943
|
}
|
|
863
944
|
if (e.evaluate === void 0)
|
|
864
945
|
return;
|
|
865
|
-
e.tailDep = null, e.flags = e.flags & ~
|
|
866
|
-
const
|
|
946
|
+
e.tailDep = null, e.flags = e.flags & ~D | p;
|
|
947
|
+
const r = this.activeSub;
|
|
867
948
|
this.activeSub = e;
|
|
868
949
|
let a;
|
|
869
950
|
try {
|
|
870
951
|
a = i();
|
|
871
|
-
} catch (
|
|
872
|
-
this.activeSub =
|
|
952
|
+
} catch (u) {
|
|
953
|
+
this.activeSub = r, e.flags &= ~p, this.failEffectRun(e, u, s);
|
|
873
954
|
} finally {
|
|
874
|
-
this.activeSub =
|
|
955
|
+
this.activeSub = r, e.flags &= ~p;
|
|
875
956
|
}
|
|
876
|
-
const
|
|
877
|
-
if ((
|
|
957
|
+
const l = e.tailDep;
|
|
958
|
+
if ((l === null ? e.firstDep : l.nextDep) !== null && this.pruneUnreadDependencies(e), typeof a == "function")
|
|
878
959
|
if (e.evaluate === void 0)
|
|
879
960
|
try {
|
|
880
961
|
this.untracked(a);
|
|
881
|
-
} catch (
|
|
882
|
-
s
|
|
962
|
+
} catch (u) {
|
|
963
|
+
s ??= [], s.push(u);
|
|
883
964
|
}
|
|
884
965
|
else
|
|
885
966
|
e.cachedValue = a;
|
|
886
|
-
e.flags &
|
|
967
|
+
e.flags & v ? e.flags = e.flags & -7 | g : e.flags &= -8;
|
|
887
968
|
}
|
|
888
969
|
/**
|
|
889
970
|
* Завершает неудачный запуск эффекта, не затрагивая успешный путь исполнения.
|
|
@@ -906,12 +987,12 @@ class U {
|
|
|
906
987
|
* Путь не проверяет наличие внешней задачи у каждого узла.
|
|
907
988
|
*/
|
|
908
989
|
flushSyncEffects() {
|
|
909
|
-
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (
|
|
990
|
+
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (d | p)) === (d | p))) {
|
|
910
991
|
this.flushingEffects = !0;
|
|
911
992
|
try {
|
|
912
993
|
for (; this.effectReadIndex !== this.effectWriteIndex; ) {
|
|
913
994
|
const e = this.effectReadIndex, t = this.effectQueue[e];
|
|
914
|
-
this.effectQueue[e] = void 0, ++this.effectReadIndex, t.flags &= ~
|
|
995
|
+
this.effectQueue[e] = void 0, ++this.effectReadIndex, t.flags &= ~v, this.executeEffect(t);
|
|
915
996
|
}
|
|
916
997
|
} catch (e) {
|
|
917
998
|
this.drainQueueAfterError(e, !1);
|
|
@@ -926,14 +1007,14 @@ class U {
|
|
|
926
1007
|
* Ошибка одного элемента не оставляет необработанные записи со старым SCHEDULED.
|
|
927
1008
|
*/
|
|
928
1009
|
flushExternalEffects() {
|
|
929
|
-
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (
|
|
1010
|
+
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (d | p)) === (d | p))) {
|
|
930
1011
|
this.flushingEffects = !0;
|
|
931
1012
|
try {
|
|
932
1013
|
for (; this.effectReadIndex !== this.effectWriteIndex; ) {
|
|
933
1014
|
const e = this.effectReadIndex, t = this.effectQueue[e];
|
|
934
1015
|
this.effectQueue[e] = void 0, ++this.effectReadIndex;
|
|
935
1016
|
const i = t.effectTask;
|
|
936
|
-
i === void 0 ? (t.flags &= ~
|
|
1017
|
+
i === void 0 ? (t.flags &= ~v, this.executeEffect(t)) : t.evaluate !== void 0 ? this.scheduleEffectTask(t, i) : t.flags &= ~v;
|
|
937
1018
|
}
|
|
938
1019
|
} catch (e) {
|
|
939
1020
|
this.drainQueueAfterError(e, !0);
|
|
@@ -942,6 +1023,20 @@ class U {
|
|
|
942
1023
|
}
|
|
943
1024
|
}
|
|
944
1025
|
}
|
|
1026
|
+
// Только ошибочный путь; новые fields/ссылки в graph records не добавляются.
|
|
1027
|
+
markRecoveryDependencies(e) {
|
|
1028
|
+
const t = [e], i = /* @__PURE__ */ new Set();
|
|
1029
|
+
for (; t.length !== 0; ) {
|
|
1030
|
+
const s = t.pop();
|
|
1031
|
+
if (!i.has(s)) {
|
|
1032
|
+
i.add(s);
|
|
1033
|
+
for (let n = s.firstDep; n !== null; n = n.nextDep) {
|
|
1034
|
+
const r = n.dep;
|
|
1035
|
+
r.evaluate !== void 0 && !(r.flags & d) && (r.flags |= m, t.push(r));
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
945
1040
|
/**
|
|
946
1041
|
* Завершает очередь после первой ошибки, собирая последующие причины сбоя.
|
|
947
1042
|
* Вызывается только на ошибочном пути; успешный проход не создаёт массив ошибок
|
|
@@ -953,10 +1048,10 @@ class U {
|
|
|
953
1048
|
const s = this.effectReadIndex++, n = this.effectQueue[s];
|
|
954
1049
|
this.effectQueue[s] = void 0;
|
|
955
1050
|
try {
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
} catch (
|
|
959
|
-
i.push(
|
|
1051
|
+
const r = t ? n.effectTask : void 0;
|
|
1052
|
+
r !== void 0 && n.evaluate !== void 0 ? this.scheduleEffectTask(n, r) : (n.flags &= ~v, this.executeEffect(n));
|
|
1053
|
+
} catch (r) {
|
|
1054
|
+
i.push(r);
|
|
960
1055
|
}
|
|
961
1056
|
}
|
|
962
1057
|
throw i.length === 1 ? e : new AggregateError(i, "Effect queue processing failed.");
|
|
@@ -968,7 +1063,7 @@ class U {
|
|
|
968
1063
|
*/
|
|
969
1064
|
requestEffectTask(e) {
|
|
970
1065
|
const t = e.effectTask;
|
|
971
|
-
t === void 0 || e.evaluate === void 0 || (e.flags |=
|
|
1066
|
+
t === void 0 || e.evaluate === void 0 || (e.flags |= v, this.scheduleEffectTask(e, t));
|
|
972
1067
|
}
|
|
973
1068
|
// Передаёт уже запланированный эффект его постоянной внешней задаче.
|
|
974
1069
|
scheduleEffectTask(e, t) {
|
|
@@ -989,38 +1084,38 @@ class U {
|
|
|
989
1084
|
return;
|
|
990
1085
|
this.activeSub === e && (this.activeSub = null);
|
|
991
1086
|
const t = e.effectTask, i = e.onStop, s = typeof e.cachedValue == "function" ? e.cachedValue : void 0;
|
|
992
|
-
e.evaluate = void 0, e.flags = 0, e.cachedValue = void 0, e.effectTask = void 0, i !== void 0 && (e.onStop = void 0),
|
|
993
|
-
let n
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
this.
|
|
1087
|
+
e.evaluate = void 0, e.flags = 0, e.cachedValue = void 0, e.effectTask = void 0, i !== void 0 && (e.onStop = void 0), q(e);
|
|
1088
|
+
let n;
|
|
1089
|
+
e.tailDep = null;
|
|
1090
|
+
try {
|
|
1091
|
+
this.pruneUnreadDependencies(e);
|
|
1092
|
+
} catch (r) {
|
|
1093
|
+
n = [r];
|
|
997
1094
|
}
|
|
998
|
-
e.firstDep = e.tailDep = null, e.depCount = 0,
|
|
999
|
-
let l;
|
|
1000
|
-
if (t !== void 0)
|
|
1095
|
+
if (e.firstDep = e.tailDep = null, e.depCount = 0, A(e), t !== void 0)
|
|
1001
1096
|
try {
|
|
1002
1097
|
t.dispose();
|
|
1003
|
-
} catch (
|
|
1004
|
-
|
|
1098
|
+
} catch (r) {
|
|
1099
|
+
n ??= [], n.push(r);
|
|
1005
1100
|
}
|
|
1006
1101
|
try {
|
|
1007
1102
|
this.disposeNestedEffects(e);
|
|
1008
|
-
} catch (
|
|
1009
|
-
|
|
1103
|
+
} catch (r) {
|
|
1104
|
+
n ??= [], n.push(r);
|
|
1010
1105
|
}
|
|
1011
1106
|
if (s !== void 0)
|
|
1012
1107
|
try {
|
|
1013
1108
|
this.untracked(s);
|
|
1014
|
-
} catch (
|
|
1015
|
-
|
|
1109
|
+
} catch (r) {
|
|
1110
|
+
n ??= [], n.push(r);
|
|
1016
1111
|
}
|
|
1017
1112
|
if (i !== void 0)
|
|
1018
1113
|
try {
|
|
1019
1114
|
this.untracked(i);
|
|
1020
|
-
} catch (
|
|
1021
|
-
|
|
1115
|
+
} catch (r) {
|
|
1116
|
+
n ??= [], n.push(r);
|
|
1022
1117
|
}
|
|
1023
|
-
this.invalidationStack.length = this.invalidationDepth, this.dependencyStack.length = this.dependencyDepth,
|
|
1118
|
+
this.invalidationStack.length !== this.invalidationDepth && (this.invalidationStack.length = this.invalidationDepth), this.dependencyStack.length !== this.dependencyDepth && (this.dependencyStack.length = this.dependencyDepth), n !== void 0 && V(n, "Effect disposal failed.");
|
|
1024
1119
|
}
|
|
1025
1120
|
/**
|
|
1026
1121
|
* Останавливает все вложенные эффекты в обратном порядке регистрации.
|
|
@@ -1033,16 +1128,16 @@ class U {
|
|
|
1033
1128
|
try {
|
|
1034
1129
|
this.disposeEffect(e.scopeLastChild);
|
|
1035
1130
|
} catch (i) {
|
|
1036
|
-
t
|
|
1131
|
+
t ??= [], t.push(i);
|
|
1037
1132
|
}
|
|
1038
|
-
t !== void 0 &&
|
|
1133
|
+
t !== void 0 && V(t, "Nested effect disposal failed.");
|
|
1039
1134
|
}
|
|
1040
1135
|
/**
|
|
1041
1136
|
* Задаёт обязательные поля графа перед первым вычислением.
|
|
1042
1137
|
* Вызывается только для нематериализованного handle; getter и контекст сохраняются.
|
|
1043
1138
|
*/
|
|
1044
1139
|
static materializeComputed(e) {
|
|
1045
|
-
e.flags =
|
|
1140
|
+
e.flags = _ | (e.sourceHooks === void 0 ? 0 : o), e.firstSub = null, e.lastSub = null, e.firstDep = null, e.tailDep = null, e.depCount = 0, e.cachedValue = void 0;
|
|
1046
1141
|
}
|
|
1047
1142
|
/**
|
|
1048
1143
|
* Связывает два разных receiver: движок-владелец и читаемый handle.
|
|
@@ -1060,14 +1155,14 @@ class U {
|
|
|
1060
1155
|
*/
|
|
1061
1156
|
initializeComputed() {
|
|
1062
1157
|
const i = this;
|
|
1063
|
-
return
|
|
1158
|
+
return N.materializeComputed(i), this.get = t, e.readComputedValue(i);
|
|
1064
1159
|
},
|
|
1065
1160
|
/**
|
|
1066
1161
|
* Материализует raw computed, сохраняя извлечение read после первого вызова.
|
|
1067
1162
|
*/
|
|
1068
1163
|
initializeRaw() {
|
|
1069
1164
|
const i = this;
|
|
1070
|
-
|
|
1165
|
+
N.materializeComputed(i);
|
|
1071
1166
|
const s = () => e.readComputedValue(i);
|
|
1072
1167
|
return this.read = s, s();
|
|
1073
1168
|
},
|
|
@@ -1105,17 +1200,17 @@ class U {
|
|
|
1105
1200
|
_signalAccess(e) {
|
|
1106
1201
|
const t = this;
|
|
1107
1202
|
let i = e, s;
|
|
1108
|
-
function n(
|
|
1203
|
+
function n(r) {
|
|
1109
1204
|
if (arguments.length !== 0) {
|
|
1110
|
-
const
|
|
1111
|
-
|
|
1205
|
+
const u = s;
|
|
1206
|
+
u !== void 0 ? t.writeSignalValue(u, r) : i !== r && (i = r);
|
|
1112
1207
|
return;
|
|
1113
1208
|
}
|
|
1114
1209
|
const a = s;
|
|
1115
1210
|
if (a !== void 0)
|
|
1116
1211
|
return t.readSignalValue(a);
|
|
1117
|
-
const
|
|
1118
|
-
return
|
|
1212
|
+
const l = t.activeSub;
|
|
1213
|
+
return l === null || (s = t.materializeSignal(i, l)), i;
|
|
1119
1214
|
}
|
|
1120
1215
|
return {
|
|
1121
1216
|
read: n,
|
|
@@ -1143,68 +1238,66 @@ class U {
|
|
|
1143
1238
|
*/
|
|
1144
1239
|
_ownedSignal(e, t) {
|
|
1145
1240
|
const i = this;
|
|
1146
|
-
let s = e, n,
|
|
1241
|
+
let s = e, n, r = !1;
|
|
1147
1242
|
const a = () => {
|
|
1148
|
-
const
|
|
1149
|
-
if (
|
|
1150
|
-
return this.readSignalValue(
|
|
1151
|
-
const
|
|
1152
|
-
if (
|
|
1243
|
+
const h = n;
|
|
1244
|
+
if (h !== void 0)
|
|
1245
|
+
return this.readSignalValue(h);
|
|
1246
|
+
const S = this.activeSub;
|
|
1247
|
+
if (S === null)
|
|
1153
1248
|
return s;
|
|
1154
|
-
const
|
|
1249
|
+
const C = s;
|
|
1155
1250
|
return n = this.materializeSignal(
|
|
1156
|
-
|
|
1157
|
-
|
|
1251
|
+
C,
|
|
1252
|
+
S,
|
|
1158
1253
|
t
|
|
1159
|
-
), s = void 0,
|
|
1160
|
-
},
|
|
1161
|
-
const
|
|
1162
|
-
|
|
1163
|
-
} : (
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
A !== u && ((I = t.onChange) == null || I.call(t, A, u, o.firstSub !== null)), this.writeSignalValue(o, u);
|
|
1254
|
+
), s = void 0, C;
|
|
1255
|
+
}, l = t === void 0 ? (h) => {
|
|
1256
|
+
const S = n;
|
|
1257
|
+
S !== void 0 ? this.writeSignalValue(S, h) : s !== h && (s = h);
|
|
1258
|
+
} : (h) => {
|
|
1259
|
+
const S = n;
|
|
1260
|
+
if (S !== void 0) {
|
|
1261
|
+
const C = S.flags & f ? S.pendingValue : S.cachedValue;
|
|
1262
|
+
C !== h && t.onChange?.(C, h, S.firstSub !== null), this.writeSignalValue(S, h);
|
|
1169
1263
|
return;
|
|
1170
1264
|
}
|
|
1171
|
-
s !==
|
|
1172
|
-
},
|
|
1265
|
+
s !== h && (t.onChange?.(s, h, !1), s = h);
|
|
1266
|
+
}, w = {
|
|
1173
1267
|
source: {
|
|
1174
1268
|
get: a,
|
|
1175
1269
|
peek: this.handleReaders.peek,
|
|
1176
|
-
set:
|
|
1270
|
+
set: l
|
|
1177
1271
|
},
|
|
1178
1272
|
/**
|
|
1179
1273
|
* Освобождает источник и отсоединяет его от реактивного графа.
|
|
1180
1274
|
*/
|
|
1181
1275
|
dispose() {
|
|
1182
|
-
|
|
1183
|
-
if (l)
|
|
1276
|
+
if (r)
|
|
1184
1277
|
return !0;
|
|
1185
|
-
|
|
1186
|
-
let
|
|
1278
|
+
r = !0, s = void 0;
|
|
1279
|
+
let h;
|
|
1187
1280
|
try {
|
|
1188
|
-
|
|
1189
|
-
} catch (
|
|
1190
|
-
(
|
|
1281
|
+
t?.onDispose?.(n?.firstSub != null);
|
|
1282
|
+
} catch (S) {
|
|
1283
|
+
(h ??= []).push(S);
|
|
1191
1284
|
}
|
|
1192
1285
|
if (n !== void 0) {
|
|
1193
1286
|
try {
|
|
1194
1287
|
i.releaseSourceSubs(n);
|
|
1195
|
-
} catch (
|
|
1196
|
-
(
|
|
1288
|
+
} catch (S) {
|
|
1289
|
+
(h ??= []).push(S);
|
|
1197
1290
|
}
|
|
1198
1291
|
n.cachedValue = void 0, n.pendingValue = void 0, n.pendingAuthor = void 0, n.flags = 0;
|
|
1199
1292
|
}
|
|
1200
|
-
if (n = void 0,
|
|
1201
|
-
throw
|
|
1202
|
-
if (
|
|
1203
|
-
throw new AggregateError(
|
|
1293
|
+
if (n = void 0, h?.length === 1)
|
|
1294
|
+
throw h[0];
|
|
1295
|
+
if (h !== void 0 && h.length > 1)
|
|
1296
|
+
throw new AggregateError(h, "Owned signal disposal failed.");
|
|
1204
1297
|
return !0;
|
|
1205
1298
|
}
|
|
1206
1299
|
};
|
|
1207
|
-
return t !== void 0 && (
|
|
1300
|
+
return t !== void 0 && (w.hasSubscribers = () => n?.firstSub != null), w;
|
|
1208
1301
|
}
|
|
1209
1302
|
/**
|
|
1210
1303
|
* Создаёт ленивый computed с финализатором исходящих и входящих связей.
|
|
@@ -1214,42 +1307,43 @@ class U {
|
|
|
1214
1307
|
_ownedComputed(e, t) {
|
|
1215
1308
|
const i = this, s = this.createComputedHandle(e, t);
|
|
1216
1309
|
let n = !1;
|
|
1217
|
-
const
|
|
1310
|
+
const r = {
|
|
1218
1311
|
source: s,
|
|
1219
1312
|
/**
|
|
1220
1313
|
* Отсоединяет принадлежащий источник и освобождает его ссылки.
|
|
1221
1314
|
* Повторный вызов возвращает true без повторной очистки.
|
|
1222
1315
|
*/
|
|
1223
1316
|
dispose() {
|
|
1224
|
-
var h;
|
|
1225
1317
|
if (n)
|
|
1226
1318
|
return !0;
|
|
1227
1319
|
n = !0, i.activeSub === s && (i.activeSub = null);
|
|
1228
1320
|
const a = [];
|
|
1229
1321
|
try {
|
|
1230
|
-
|
|
1231
|
-
} catch (
|
|
1232
|
-
a.push(
|
|
1322
|
+
t?.onDispose?.(s.firstSub != null);
|
|
1323
|
+
} catch (u) {
|
|
1324
|
+
a.push(u);
|
|
1233
1325
|
}
|
|
1234
1326
|
if (s.flags !== void 0)
|
|
1235
1327
|
try {
|
|
1236
1328
|
i.releaseSourceSubs(s);
|
|
1237
|
-
} catch (
|
|
1238
|
-
a.push(
|
|
1329
|
+
} catch (u) {
|
|
1330
|
+
a.push(u);
|
|
1239
1331
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1332
|
+
const l = s.flags !== void 0;
|
|
1333
|
+
if (s.evaluate = void 0, s.cachedValue = void 0, s.flags = 0, s.tailDep = null, l)
|
|
1334
|
+
try {
|
|
1335
|
+
i.pruneUnreadDependencies(s);
|
|
1336
|
+
} catch (u) {
|
|
1337
|
+
a.push(u);
|
|
1338
|
+
}
|
|
1339
|
+
if (s.firstDep = s.tailDep = null, s.depCount = 0, A(s), a.length === 1)
|
|
1246
1340
|
throw a[0];
|
|
1247
1341
|
if (a.length > 1)
|
|
1248
1342
|
throw new AggregateError(a, "Owned computed disposal failed.");
|
|
1249
1343
|
return !0;
|
|
1250
1344
|
}
|
|
1251
1345
|
};
|
|
1252
|
-
return t !== void 0 && (
|
|
1346
|
+
return t !== void 0 && (r.hasSubscribers = () => s.firstSub != null), r;
|
|
1253
1347
|
}
|
|
1254
1348
|
/**
|
|
1255
1349
|
* Открывает вложенную синхронную границу группировки.
|
|
@@ -1281,25 +1375,326 @@ class U {
|
|
|
1281
1375
|
_isFlushingEffects() {
|
|
1282
1376
|
return this.flushingEffects;
|
|
1283
1377
|
}
|
|
1378
|
+
// ---------------------------------------------
|
|
1379
|
+
// TASK EFFECT GLUE
|
|
1380
|
+
// ---------------------------------------------
|
|
1381
|
+
//
|
|
1382
|
+
// Аналог createScheduledEffect() без closures для вызывающего слоя, который
|
|
1383
|
+
// владеет одним постоянным объектом задачи на эффект. Вызывающий слой хранит
|
|
1384
|
+
// состояние запусков и управляет записью графа через методы ниже; engine не
|
|
1385
|
+
// создаёт closures runner, cancel и re-arm. Такие эффекты требуют экземпляр
|
|
1386
|
+
// с внешним effect scheduler, как и эффекты, связанные через scheduler.
|
|
1387
|
+
/**
|
|
1388
|
+
* Создаёт запись графа для эффекта с внешним планированием и подключает его
|
|
1389
|
+
* постоянную задачу. Запуск ещё не запрошен: вызывающий слой сохраняет запись
|
|
1390
|
+
* и затем вызывает _requestTaskEffect(). Запись, созданная во время работы
|
|
1391
|
+
* другого эффекта, становится его вложенным ресурсом.
|
|
1392
|
+
* @internal
|
|
1393
|
+
*/
|
|
1394
|
+
_allocateTaskEffect(e, t) {
|
|
1395
|
+
const i = this.allocateGraphRecord(void 0, e, f | g | d), s = this.activeSub;
|
|
1396
|
+
return s !== null && s.flags & d && W(s, i), i.effectTask = t, i;
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Запрашивает первый запуск эффекта с задачей. При `schedule` задача получает
|
|
1400
|
+
* schedule(), как на пути scheduler bind; без него вызывающий слой уже сам
|
|
1401
|
+
* поставил задачу в очередь, и запись только помечается запланированной.
|
|
1402
|
+
* Если метод бросает исключение, запись освобождает вызывающий слой.
|
|
1403
|
+
* @internal
|
|
1404
|
+
*/
|
|
1405
|
+
_requestTaskEffect(e, t) {
|
|
1406
|
+
t ? this.requestEffectTask(e) : e.effectTask !== void 0 && e.evaluate !== void 0 && (e.flags |= v), !this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects();
|
|
1407
|
+
}
|
|
1408
|
+
/**
|
|
1409
|
+
* Открывает одну доставку эффекта с задачей. Возвращает false для устаревшей
|
|
1410
|
+
* доставки: запись остановлена или запуск больше не запланирован.
|
|
1411
|
+
* @internal
|
|
1412
|
+
*/
|
|
1413
|
+
_beginTaskEffectRun(e) {
|
|
1414
|
+
return !(e.flags & v) || e.evaluate === void 0 ? !1 : (e.flags &= ~v, !0);
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Выполняет доставку, открытую через _beginTaskEffectRun(), вне активного
|
|
1418
|
+
* потребителя и затем обрабатывает очередь эффектов, в том числе после
|
|
1419
|
+
* неудачного запуска; при двух сбоях передаёт обе причины.
|
|
1420
|
+
* @internal
|
|
1421
|
+
*/
|
|
1422
|
+
_finishTaskEffectRun(e) {
|
|
1423
|
+
const t = this.activeSub;
|
|
1424
|
+
this.activeSub = null;
|
|
1425
|
+
try {
|
|
1426
|
+
try {
|
|
1427
|
+
this.executeEffect(e);
|
|
1428
|
+
} catch (i) {
|
|
1429
|
+
if (!this.batchDepth && this.effectReadIndex !== this.effectWriteIndex)
|
|
1430
|
+
try {
|
|
1431
|
+
this.flushEffects();
|
|
1432
|
+
} catch (s) {
|
|
1433
|
+
throw new AggregateError(
|
|
1434
|
+
[i, s],
|
|
1435
|
+
"Effect execution and queue processing failed."
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
throw i;
|
|
1439
|
+
}
|
|
1440
|
+
!this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects();
|
|
1441
|
+
} finally {
|
|
1442
|
+
this.activeSub = t;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Гасит ожидающую доставку, от которой отказывается задача. Вызывающий слой
|
|
1447
|
+
* не должен отменять доставку до первого запуска: зависимости до него ещё не
|
|
1448
|
+
* собраны. Возвращает false, если запись уже остановлена.
|
|
1449
|
+
* @internal
|
|
1450
|
+
*/
|
|
1451
|
+
_cancelTaskEffect(e) {
|
|
1452
|
+
return e.evaluate === void 0 ? !1 : (this.settleCancelledDependencies(e), e.flags &= -72, !this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects(), !0);
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
1455
|
+
* Делает следующую доставку исполняемой и снова планирует задачу. Нужен,
|
|
1456
|
+
* когда invalidation пришла после снимка текущей доставки: её запуск
|
|
1457
|
+
* расходует предыдущее dirty-состояние.
|
|
1458
|
+
* @internal
|
|
1459
|
+
*/
|
|
1460
|
+
_rearmTaskEffect(e) {
|
|
1461
|
+
const t = e.effectTask;
|
|
1462
|
+
t === void 0 || e.evaluate === void 0 || (e.flags |= f | v, t.schedule());
|
|
1463
|
+
}
|
|
1464
|
+
/**
|
|
1465
|
+
* Окончательно останавливает эффект с задачей. Engine один раз вызывает
|
|
1466
|
+
* task.dispose() изнутри, поэтому задача может направлять собственное
|
|
1467
|
+
* освобождение через этот метод.
|
|
1468
|
+
* @internal
|
|
1469
|
+
*/
|
|
1470
|
+
_disposeTaskEffect(e) {
|
|
1471
|
+
this.disposeEffect(e);
|
|
1472
|
+
}
|
|
1473
|
+
// ---------------------------------------------
|
|
1474
|
+
// SIGNAL NODE GLUE
|
|
1475
|
+
// ---------------------------------------------
|
|
1476
|
+
//
|
|
1477
|
+
// Аналог _ownedSignal() без closures для вызывающего слоя, который хранит
|
|
1478
|
+
// значение, запись графа и source hooks одного signal в одном постоянном
|
|
1479
|
+
// объекте. Вызывающий слой сам держит значение до материализации и ссылку на
|
|
1480
|
+
// запись после неё; engine не создаёт handle, closures чтения и записи и
|
|
1481
|
+
// объект финализатора. Методы повторяют шаги _ownedSignal() по одному.
|
|
1482
|
+
/**
|
|
1483
|
+
* Материализует signal для активного потребителя и связывает их. Без
|
|
1484
|
+
* потребителя возвращает undefined: signal остаётся значением у вызывающего
|
|
1485
|
+
* слоя. После материализации значением владеет запись.
|
|
1486
|
+
* @internal
|
|
1487
|
+
*/
|
|
1488
|
+
_trackSignalNode(e, t) {
|
|
1489
|
+
const i = this.activeSub;
|
|
1490
|
+
if (i !== null)
|
|
1491
|
+
return this.materializeSignal(e, i, t);
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Читает материализованный signal и регистрирует зависимость активного
|
|
1495
|
+
* потребителя.
|
|
1496
|
+
* @internal
|
|
1497
|
+
*/
|
|
1498
|
+
_readSignalNode(e) {
|
|
1499
|
+
return this.readSignalValue(e);
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Читает материализованный signal без подписки текущего потребителя;
|
|
1503
|
+
* pending-значение фиксируется так же, как при обычном чтении.
|
|
1504
|
+
* @internal
|
|
1505
|
+
*/
|
|
1506
|
+
_peekSignalNode(e) {
|
|
1507
|
+
const t = this.activeSub;
|
|
1508
|
+
if (t === null)
|
|
1509
|
+
return this.readSignalValue(e);
|
|
1510
|
+
this.activeSub = null;
|
|
1511
|
+
try {
|
|
1512
|
+
return this.readSignalValue(e);
|
|
1513
|
+
} finally {
|
|
1514
|
+
this.activeSub = t;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Возвращает значение, которое увидит следующее чтение: pending-значение
|
|
1519
|
+
* незавершённой группировки либо зафиксированное. Ничего не фиксирует.
|
|
1520
|
+
* @internal
|
|
1521
|
+
*/
|
|
1522
|
+
_visibleSignalValue(e) {
|
|
1523
|
+
return e.flags & f ? e.pendingValue : e.cachedValue;
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Записывает значение материализованного signal с обычной семантикой batch.
|
|
1527
|
+
* @internal
|
|
1528
|
+
*/
|
|
1529
|
+
_writeSignalNode(e, t) {
|
|
1530
|
+
this.writeSignalValue(e, t);
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* Сообщает, есть ли у материализованного signal потребители в графе.
|
|
1534
|
+
* @internal
|
|
1535
|
+
*/
|
|
1536
|
+
_signalNodeHasSubscribers(e) {
|
|
1537
|
+
return e.firstSub !== null;
|
|
1538
|
+
}
|
|
1539
|
+
/**
|
|
1540
|
+
* Отсоединяет материализованный signal от потребителей и освобождает его
|
|
1541
|
+
* значения. Значения освобождаются и при сбое отсоединения. Поля pending
|
|
1542
|
+
* сбрасываются, только если запись их получала: запись без группировок не
|
|
1543
|
+
* меняет набор своих полей при освобождении.
|
|
1544
|
+
* @internal
|
|
1545
|
+
*/
|
|
1546
|
+
_releaseSignalNode(e) {
|
|
1547
|
+
try {
|
|
1548
|
+
this.releaseSourceSubs(e);
|
|
1549
|
+
} finally {
|
|
1550
|
+
e.cachedValue = void 0, e.pendingValue !== void 0 && (e.pendingValue = void 0), e.pendingAuthor != null && (e.pendingAuthor = void 0), e.flags = 0;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
// ---------------------------------------------
|
|
1554
|
+
// SUBSCRIBER OWNER GLUE
|
|
1555
|
+
// ---------------------------------------------
|
|
1556
|
+
//
|
|
1557
|
+
// Чтение живых связей производителя для вызывающего слоя, которому нужен
|
|
1558
|
+
// ответ о владельцах потребителей только по запросу. Слой не ведёт своего
|
|
1559
|
+
// учёта рёбер: связь, снятая графом, перестаёт быть видимой сразу, без
|
|
1560
|
+
// отдельного cleanup на ребро.
|
|
1561
|
+
/**
|
|
1562
|
+
* Ищет среди текущих потребителей записи первого, чьего владельца принимает
|
|
1563
|
+
* accept, и возвращает этого владельца. Владелец потребителя определяется
|
|
1564
|
+
* так же, как при привязке ребра через onDependency: у computed это
|
|
1565
|
+
* dependencyOwner его source hooks, у эффекта — dependencyOwner его задачи.
|
|
1566
|
+
* Потребители без владельца пропускаются. Обход идёт в порядке списка
|
|
1567
|
+
* потребителей, ничего не выделяет и не меняет граф; accept не должен менять
|
|
1568
|
+
* связи этой записи.
|
|
1569
|
+
* @param node Материализованная запись производителя.
|
|
1570
|
+
* @param accept Проверка владельца потребителя; context передаётся ей без closure.
|
|
1571
|
+
* @param context Произвольное значение вызывающего слоя для accept.
|
|
1572
|
+
* @internal
|
|
1573
|
+
*/
|
|
1574
|
+
_findSubscriberOwner(e, t, i) {
|
|
1575
|
+
for (let s = e.firstSub; s !== null; s = s.nextSub) {
|
|
1576
|
+
const n = s.sub, r = n.sourceHooks?.dependencyOwner ?? n.effectTask?.dependencyOwner;
|
|
1577
|
+
if (r !== void 0 && t(r, i))
|
|
1578
|
+
return r;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Возвращает владельца активного потребителя: того, кому engine привязал бы
|
|
1583
|
+
* ребро следующего отслеживаемого чтения. Владелец определяется так же, как
|
|
1584
|
+
* в _findSubscriberOwner(). Без активного потребителя и у потребителя без
|
|
1585
|
+
* владельца результат undefined. Метод ничего не выделяет и не меняет граф.
|
|
1586
|
+
*
|
|
1587
|
+
* Вызывающий слой проверяет по этому владельцу допустимость чтения, когда
|
|
1588
|
+
* его собственный контекст снят, а потребитель engine остался активным.
|
|
1589
|
+
* @internal
|
|
1590
|
+
*/
|
|
1591
|
+
_activeSubscriberOwner() {
|
|
1592
|
+
const e = this.activeSub;
|
|
1593
|
+
if (e !== null)
|
|
1594
|
+
return e.sourceHooks?.dependencyOwner ?? e.effectTask?.dependencyOwner;
|
|
1595
|
+
}
|
|
1596
|
+
// ---------------------------------------------
|
|
1597
|
+
// COUNTER NODE GLUE
|
|
1598
|
+
// ---------------------------------------------
|
|
1599
|
+
//
|
|
1600
|
+
// Запись графа со счётчиком вместо значения: вызывающий слой будит через неё
|
|
1601
|
+
// потребителей, которым важен сам факт изменения. Значение счётчика только
|
|
1602
|
+
// растёт, поэтому одну запись нельзя отменить следующей.
|
|
1603
|
+
/**
|
|
1604
|
+
* Увеличивает счётчик материализованного signal и уведомляет его
|
|
1605
|
+
* потребителей. Без потребителей ничего не пишет и возвращает false.
|
|
1606
|
+
*
|
|
1607
|
+
* Сдвиг — обычная запись signal. Вне группировки она прямая: счётчик
|
|
1608
|
+
* фиксируется сразу, а потребитель становится обязательным к пересчёту, в
|
|
1609
|
+
* том числе тот, кто ждал только проверки зависимостей или стоит на стеке
|
|
1610
|
+
* идущей проверки. Внутри группировки и у записи с ещё не прочитанным
|
|
1611
|
+
* отложенным сдвигом запись откладывается до первого чтения, как любая запись
|
|
1612
|
+
* внутри batch().
|
|
1613
|
+
*
|
|
1614
|
+
* Потребитель, который выполняется в момент прямого сдвига, получает его по
|
|
1615
|
+
* общему правилу записи во время запуска: у записи не остаётся отложенного
|
|
1616
|
+
* сдвига, который позже подтвердил бы ему изменение.
|
|
1617
|
+
*
|
|
1618
|
+
* Очередь эффектов обрабатывается на выходе, если группировки нет: отложенная
|
|
1619
|
+
* запись сама её не обрабатывает, а потребитель, которого она поставила в
|
|
1620
|
+
* очередь, не должен ждать следующей записи.
|
|
1621
|
+
* @internal
|
|
1622
|
+
*/
|
|
1623
|
+
_bumpSignalNode(e) {
|
|
1624
|
+
return e.firstSub === null ? !1 : (this.writeSignalValue(
|
|
1625
|
+
e,
|
|
1626
|
+
(e.flags & f ? e.pendingValue : e.cachedValue) + 1
|
|
1627
|
+
), !this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects(), !0);
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Создаёт запись-счётчик для активного потребителя и связывает их; без
|
|
1631
|
+
* потребителя возвращает undefined. Счётчик начинается с нуля и сдвигается
|
|
1632
|
+
* через _bumpSignalNode().
|
|
1633
|
+
*
|
|
1634
|
+
* Счётчик — производитель без собственных зависимостей. Граф читает у него
|
|
1635
|
+
* то же, что у записи signal в роли производителя: признаки, список
|
|
1636
|
+
* потребителей, отсутствие getter, значение и source hooks. Полей списка
|
|
1637
|
+
* зависимостей у записи нет, а hooks лежат в ней самой: счётчик стоит одной
|
|
1638
|
+
* аллокации из шести полей, а запись signal с hooks — двух. Поля отложенной
|
|
1639
|
+
* записи появляются у счётчика с первым сдвигом.
|
|
1640
|
+
* @internal
|
|
1641
|
+
*/
|
|
1642
|
+
_trackCounterNode(e) {
|
|
1643
|
+
const t = this.activeSub;
|
|
1644
|
+
if (t === null)
|
|
1645
|
+
return;
|
|
1646
|
+
const i = {
|
|
1647
|
+
flags: o,
|
|
1648
|
+
firstSub: null,
|
|
1649
|
+
lastSub: null,
|
|
1650
|
+
evaluate: void 0,
|
|
1651
|
+
cachedValue: 0,
|
|
1652
|
+
sourceHooks: e
|
|
1653
|
+
};
|
|
1654
|
+
return t.flags & x ? this.appendInitialDependency(i, t) : this.trackDependency(i, t), i;
|
|
1655
|
+
}
|
|
1656
|
+
// ---------------------------------------------
|
|
1657
|
+
// ACTIVE TASK GLUE
|
|
1658
|
+
// ---------------------------------------------
|
|
1659
|
+
//
|
|
1660
|
+
// Тело эффекта с задачей engine вызывает без аргументов и без receiver.
|
|
1661
|
+
// Вызывающий слой, который даёт всем своим эффектам одно общее тело, находит
|
|
1662
|
+
// через метод ниже эффект, ради которого тело вызвано: записи графа не нужна
|
|
1663
|
+
// собственная closure тела.
|
|
1664
|
+
/**
|
|
1665
|
+
* Возвращает постоянную задачу активного потребителя. Engine делает запись
|
|
1666
|
+
* эффекта активным потребителем непосредственно перед вызовом её тела,
|
|
1667
|
+
* поэтому первое обращение из тела возвращает задачу именно этого эффекта,
|
|
1668
|
+
* какие бы доставки ни выполнил cleanup его прошлого запуска.
|
|
1669
|
+
*
|
|
1670
|
+
* Без активного потребителя и у потребителя без задачи — computed либо
|
|
1671
|
+
* эффекта, созданного без внешнего планирования, — результат undefined.
|
|
1672
|
+
* Метод ничего не выделяет и не меняет граф.
|
|
1673
|
+
* @internal
|
|
1674
|
+
*/
|
|
1675
|
+
_activeEffectTask() {
|
|
1676
|
+
const e = this.activeSub;
|
|
1677
|
+
return e === null ? void 0 : e.effectTask;
|
|
1678
|
+
}
|
|
1284
1679
|
}
|
|
1285
|
-
let
|
|
1286
|
-
function
|
|
1287
|
-
return
|
|
1680
|
+
let P;
|
|
1681
|
+
function y() {
|
|
1682
|
+
return P ??= new N();
|
|
1288
1683
|
}
|
|
1289
|
-
const
|
|
1290
|
-
function
|
|
1291
|
-
return
|
|
1684
|
+
const K = (c) => y().signal(c), Y = (c) => y().reactive(c);
|
|
1685
|
+
function X(c) {
|
|
1686
|
+
return y().computed(c);
|
|
1292
1687
|
}
|
|
1293
|
-
const
|
|
1688
|
+
const $ = (c, e) => y().effect(c, e), j = (c, e, t) => y().watch(c, e, t), Z = (c) => y().batch(c), J = (c) => y().untracked(c), ee = () => y().scope();
|
|
1294
1689
|
export {
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1690
|
+
N as RaphReactivity,
|
|
1691
|
+
U as ScopeNode,
|
|
1692
|
+
Z as batch,
|
|
1693
|
+
X as computed,
|
|
1694
|
+
$ as effect,
|
|
1695
|
+
Y as reactive,
|
|
1696
|
+
ee as scope,
|
|
1697
|
+
K as signal,
|
|
1698
|
+
J as untracked,
|
|
1699
|
+
j as watch
|
|
1305
1700
|
};
|