@raphy-js/raph 1.0.0-dev.2 → 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/README.md +1096 -0
- package/dist/api/Raph.d.ts +59 -190
- package/dist/api/RaphFacadeSession.d.ts +90 -0
- package/dist/api/RaphReactivityInstance.d.ts +72 -0
- package/dist/api/errors.d.ts +9 -4
- package/dist/api/types.d.ts +162 -17
- package/dist/core-CClhT8WR.js +1044 -0
- package/dist/core-cPQWYD4K.cjs +1 -0
- package/dist/debug/api/Raph.cjs +1 -1
- package/dist/debug/api/Raph.js +368 -367
- package/dist/debug/api/RaphFacadeSession.cjs +1 -0
- package/dist/debug/api/RaphFacadeSession.js +302 -0
- package/dist/debug/api/RaphReactivityInstance.cjs +1 -0
- package/dist/debug/api/RaphReactivityInstance.js +146 -0
- package/dist/debug/api/errors.cjs +1 -1
- package/dist/debug/api/errors.js +10 -7
- package/dist/debug/path/DataPath.cjs +1 -0
- package/dist/debug/path/DataPath.js +390 -0
- package/dist/debug/path/PathRouter.cjs +1 -0
- package/dist/debug/path/PathRouter.js +80 -0
- package/dist/debug/path/RaphKernel.cjs +1 -1
- package/dist/debug/path/RaphKernel.js +316 -236
- package/dist/debug/path/data-path.utils.cjs +1 -0
- package/dist/debug/path/data-path.utils.js +56 -0
- package/dist/debug/path/derived/DerivedRegistry.cjs +1 -0
- package/dist/debug/path/derived/DerivedRegistry.js +143 -0
- package/dist/debug/path/derived/RaphDerivedHandle.cjs +1 -0
- package/dist/debug/path/{RaphDerivedHandle.js → derived/RaphDerivedHandle.js} +19 -22
- package/dist/debug/path/derived/derived-collection.utils.cjs +1 -0
- package/dist/debug/path/{derived-collection.js → derived/derived-collection.utils.js} +71 -71
- package/dist/debug/path/derived/derived-strategy.types.cjs +1 -0
- package/dist/debug/path/derived/derived-strategy.types.js +1 -0
- package/dist/debug/path/meta/MetaController.cjs +1 -0
- package/dist/debug/path/{MetaController.js → meta/MetaController.js} +58 -66
- package/dist/debug/path/meta/RaphMeta.cjs +1 -0
- package/dist/debug/path/meta/RaphMeta.js +62 -0
- package/dist/debug/path/meta/RaphMetaStore.cjs +1 -0
- package/dist/debug/path/{RaphMetaStore.js → meta/RaphMetaStore.js} +24 -30
- package/dist/debug/path/meta/meta.types.cjs +1 -0
- package/dist/debug/path/meta/meta.types.js +1 -0
- package/dist/debug/path/storage/AdapterPathStore.cjs +1 -0
- package/dist/debug/path/storage/AdapterPathStore.js +128 -0
- package/dist/debug/path/storage/DefaultDataAdapter.cjs +1 -0
- package/dist/debug/path/{data-adapter.js → storage/DefaultDataAdapter.js} +47 -57
- package/dist/debug/path/storage/PathEventHub.cjs +1 -0
- package/dist/debug/path/storage/PathEventHub.js +161 -0
- package/dist/debug/path/storage/PathStore.cjs +1 -0
- package/dist/debug/path/{PathStore.js → storage/PathStore.js} +88 -98
- package/dist/debug/path/storage/createDataDraft.cjs +1 -0
- package/dist/debug/path/{data-draft.js → storage/createDataDraft.js} +24 -28
- package/dist/debug/path/storage/data-adapter.types.cjs +1 -0
- package/dist/debug/path/storage/data-adapter.types.js +1 -0
- 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 +888 -321
- package/dist/debug/reactivity/reactive-object.cjs +1 -0
- package/dist/debug/reactivity/reactive-object.js +265 -0
- 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 +1134 -502
- package/dist/debug/runtime/diagnostics/RaphDebug.cjs +1 -0
- package/dist/debug/runtime/diagnostics/RaphDebug.js +287 -0
- package/dist/debug/runtime/errors.cjs +1 -1
- package/dist/debug/runtime/errors.js +6 -3
- package/dist/debug/runtime/ownership/RaphEffectScope.cjs +1 -0
- package/dist/debug/runtime/ownership/RaphEffectScope.js +304 -0
- package/dist/debug/runtime/ownership/RaphNode.cjs +1 -0
- package/dist/debug/runtime/ownership/RaphNode.js +665 -0
- package/dist/debug/runtime/ownership/RaphScope.cjs +1 -0
- package/dist/debug/runtime/ownership/RaphScope.js +236 -0
- package/dist/debug/runtime/ownership/parent-graph.types.cjs +1 -0
- package/dist/debug/runtime/ownership/parent-graph.types.js +1 -0
- package/dist/debug/runtime/phases/RaphFrameLoop.cjs +1 -0
- package/dist/debug/runtime/{RaphFrameLoop.js → phases/RaphFrameLoop.js} +13 -17
- package/dist/debug/runtime/phases/RaphPhasePipeline.cjs +1 -0
- package/dist/debug/runtime/phases/RaphPhasePipeline.js +848 -0
- 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/phases/orderPhaseTasks.cjs +1 -0
- package/dist/debug/runtime/phases/orderPhaseTasks.js +59 -0
- package/dist/debug/runtime/reactivity/PathHandle.cjs +1 -0
- package/dist/debug/runtime/reactivity/PathHandle.js +165 -0
- package/dist/debug/runtime/reactivity/RaphMetaSource.cjs +1 -0
- package/dist/debug/runtime/reactivity/RaphMetaSource.js +108 -0
- 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 -0
- package/dist/debug/runtime/reactivity/RaphWorkGraph.js +1157 -0
- package/dist/debug/runtime/reactivity/RuntimeReactivity.cjs +1 -0
- package/dist/debug/runtime/reactivity/RuntimeReactivity.js +550 -0
- package/dist/debug/runtime/reactivity/RuntimeWatch.cjs +1 -0
- package/dist/debug/runtime/reactivity/RuntimeWatch.js +77 -0
- package/dist/debug/runtime/reactivity/disposal-sweep.utils.cjs +1 -0
- package/dist/debug/runtime/reactivity/disposal-sweep.utils.js +42 -0
- package/dist/debug/runtime/reactivity/runtime-reactivity.types.cjs +1 -0
- package/dist/debug/runtime/reactivity/runtime-reactivity.types.js +1 -0
- package/dist/entrypoints/machine-testing.d.ts +2 -0
- package/dist/entrypoints/machine.d.ts +5 -0
- package/dist/entrypoints/path.d.ts +14 -0
- package/dist/entrypoints/reactivity.d.ts +1 -0
- package/dist/entrypoints/runtime.d.ts +18 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +46 -38
- package/dist/machine/compiler.d.ts +71 -0
- package/dist/machine/core.d.ts +50 -0
- package/dist/machine/persistence.d.ts +5 -0
- package/dist/machine/runtime.d.ts +4 -0
- package/dist/machine/testing.d.ts +43 -0
- package/dist/machine/types.d.ts +155 -0
- package/dist/machine-testing.cjs +1 -0
- package/dist/machine-testing.js +188 -0
- package/dist/machine.cjs +1 -0
- package/dist/machine.js +822 -0
- package/dist/main.d.ts +20 -0
- package/dist/path/{data-path.d.ts → DataPath.d.ts} +16 -40
- package/dist/path/{path-router.d.ts → PathRouter.d.ts} +1 -1
- package/dist/path/RaphKernel.d.ts +37 -10
- package/dist/path/data-path.types.d.ts +34 -0
- package/dist/path/data-path.utils.d.ts +9 -0
- package/dist/path/{DerivedRegistry.d.ts → derived/DerivedRegistry.d.ts} +2 -2
- package/dist/path/{RaphDerivedHandle.d.ts → derived/RaphDerivedHandle.d.ts} +3 -3
- package/dist/path/derived/derived-collection.types.d.ts +12 -0
- package/dist/path/{derived-collection.d.ts → derived/derived-collection.utils.d.ts} +3 -13
- package/dist/path/{derived-strategies.d.ts → derived/derived-strategy.types.d.ts} +0 -3
- package/dist/path/derived/derived-strategy.utils.d.ts +4 -0
- package/dist/path/{MetaController.d.ts → meta/MetaController.d.ts} +4 -4
- package/dist/path/{RaphMeta.d.ts → meta/RaphMeta.d.ts} +2 -2
- package/dist/path/{RaphMetaStore.d.ts → meta/RaphMetaStore.d.ts} +1 -1
- package/dist/path/{meta.types.d.ts → meta/meta.types.d.ts} +2 -4
- package/dist/path/path.types.d.ts +3 -2
- package/dist/path/{segment-key.d.ts → pathSegmentKey.d.ts} +1 -1
- package/dist/path/{AdapterPathStore.d.ts → storage/AdapterPathStore.d.ts} +4 -4
- package/dist/path/{data-adapter.d.ts → storage/DefaultDataAdapter.d.ts} +2 -17
- package/dist/path/storage/PathEventHub.d.ts +62 -0
- package/dist/path/{PathStore.d.ts → storage/PathStore.d.ts} +7 -7
- package/dist/path/storage/data-adapter.types.d.ts +17 -0
- package/dist/path.cjs +1 -1
- package/dist/path.js +16 -16
- package/dist/raph.cjs +1 -1
- package/dist/raph.js +46 -38
- package/dist/reactivity/disposal.d.ts +14 -0
- package/dist/reactivity/engine.d.ts +193 -6
- package/dist/reactivity/reactive-object.d.ts +36 -0
- package/dist/reactivity/scope.d.ts +108 -30
- package/dist/reactivity/types.d.ts +25 -0
- package/dist/reactivity.cjs +1 -1
- package/dist/reactivity.js +12 -12
- package/dist/runtime/RaphRuntime.d.ts +319 -160
- package/dist/runtime/diagnostics/RaphDebug.d.ts +239 -0
- package/dist/runtime/errors.d.ts +5 -0
- package/dist/runtime/ownership/RaphEffectScope.d.ts +98 -0
- package/dist/runtime/ownership/RaphNode.d.ts +310 -0
- package/dist/runtime/ownership/RaphScope.d.ts +168 -0
- package/dist/runtime/{parent-graph.d.ts → ownership/parent-graph.types.d.ts} +0 -1
- package/dist/runtime/ownership/parentGraph.d.ts +3 -0
- package/dist/runtime/phases/RaphPhasePipeline.d.ts +253 -0
- package/dist/runtime/phases/RaphPhaseTaskRecord.d.ts +195 -0
- package/dist/runtime/phases/RaphPhaseWatch.d.ts +22 -0
- package/dist/runtime/phases/orderPhaseTasks.d.ts +6 -0
- package/dist/runtime/phases/phase.types.d.ts +171 -0
- package/dist/runtime/{PathHandle.d.ts → reactivity/PathHandle.d.ts} +14 -6
- package/dist/runtime/reactivity/RaphMetaSource.d.ts +32 -0
- package/dist/runtime/reactivity/RaphSelector.d.ts +338 -0
- package/dist/runtime/reactivity/RaphWorkGraph.d.ts +309 -0
- package/dist/runtime/reactivity/RuntimeReactivity.d.ts +293 -0
- package/dist/runtime/{RuntimeWatch.d.ts → reactivity/RuntimeWatch.d.ts} +12 -6
- package/dist/runtime/reactivity/disposal-sweep.utils.d.ts +19 -0
- package/dist/runtime/reactivity/runtime-reactivity.types.d.ts +56 -0
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.js +21 -16
- package/package.json +76 -35
- package/ReadMe.md +0 -153
- package/dist/api/public.d.ts +0 -22
- package/dist/debug/api/public.cjs +0 -1
- package/dist/debug/api/public.js +0 -40
- package/dist/debug/path/AdapterPathStore.cjs +0 -1
- package/dist/debug/path/AdapterPathStore.js +0 -133
- package/dist/debug/path/DerivedRegistry.cjs +0 -1
- package/dist/debug/path/DerivedRegistry.js +0 -157
- package/dist/debug/path/MetaController.cjs +0 -1
- package/dist/debug/path/PathEventHub.cjs +0 -1
- package/dist/debug/path/PathEventHub.js +0 -148
- package/dist/debug/path/PathStore.cjs +0 -1
- package/dist/debug/path/RaphDerivedHandle.cjs +0 -1
- package/dist/debug/path/RaphMeta.cjs +0 -1
- package/dist/debug/path/RaphMeta.js +0 -68
- package/dist/debug/path/RaphMetaStore.cjs +0 -1
- package/dist/debug/path/data-adapter.cjs +0 -1
- package/dist/debug/path/data-draft.cjs +0 -1
- package/dist/debug/path/data-path.cjs +0 -1
- package/dist/debug/path/data-path.js +0 -423
- package/dist/debug/path/derived-collection.cjs +0 -1
- package/dist/debug/path/path-router.cjs +0 -1
- package/dist/debug/path/path-router.js +0 -86
- package/dist/debug/path/public.cjs +0 -1
- package/dist/debug/path/public.js +0 -18
- package/dist/debug/runtime/PathHandle.cjs +0 -1
- package/dist/debug/runtime/PathHandle.js +0 -139
- package/dist/debug/runtime/RaphDebug.cjs +0 -1
- package/dist/debug/runtime/RaphDebug.js +0 -15
- package/dist/debug/runtime/RaphFrameLoop.cjs +0 -1
- package/dist/debug/runtime/RaphNode.cjs +0 -1
- package/dist/debug/runtime/RaphNode.js +0 -143
- package/dist/debug/runtime/RaphPhasePipeline.cjs +0 -1
- package/dist/debug/runtime/RaphPhasePipeline.js +0 -526
- package/dist/debug/runtime/RaphScope.cjs +0 -1
- package/dist/debug/runtime/RaphScope.js +0 -64
- package/dist/debug/runtime/RuntimeReactivity.cjs +0 -1
- package/dist/debug/runtime/RuntimeReactivity.js +0 -154
- package/dist/debug/runtime/RuntimeWatch.cjs +0 -1
- package/dist/debug/runtime/RuntimeWatch.js +0 -71
- package/dist/debug/runtime/public.cjs +0 -1
- package/dist/debug/runtime/public.js +0 -18
- package/dist/path/PathEventHub.d.ts +0 -48
- package/dist/path/public.d.ts +0 -14
- package/dist/runtime/RaphDebug.d.ts +0 -32
- package/dist/runtime/RaphNode.d.ts +0 -68
- package/dist/runtime/RaphPhasePipeline.d.ts +0 -133
- package/dist/runtime/RaphScope.d.ts +0 -50
- package/dist/runtime/RuntimeReactivity.d.ts +0 -40
- package/dist/runtime/phase.types.d.ts +0 -49
- package/dist/runtime/public.d.ts +0 -13
- package/dist/runtime/runtime-reactivity.types.d.ts +0 -9
- /package/dist/debug/path/{meta.types.cjs → data-path.types.cjs} +0 -0
- /package/dist/debug/path/{meta.types.js → data-path.types.js} +0 -0
- /package/dist/debug/{runtime/runtime-reactivity.types.cjs → path/derived/derived-collection.types.cjs} +0 -0
- /package/dist/debug/{runtime/runtime-reactivity.types.js → path/derived/derived-collection.types.js} +0 -0
- /package/dist/debug/path/{derived-strategies.cjs → derived/derived-strategy.utils.cjs} +0 -0
- /package/dist/debug/path/{derived-strategies.js → derived/derived-strategy.utils.js} +0 -0
- /package/dist/debug/path/{segment-key.cjs → pathSegmentKey.cjs} +0 -0
- /package/dist/debug/path/{segment-key.js → pathSegmentKey.js} +0 -0
- /package/dist/debug/runtime/{parent-graph.cjs → ownership/parentGraph.cjs} +0 -0
- /package/dist/debug/runtime/{parent-graph.js → ownership/parentGraph.js} +0 -0
- /package/dist/debug/runtime/{disposal.cjs → ownership/throwDisposalErrors.cjs} +0 -0
- /package/dist/debug/runtime/{disposal.js → ownership/throwDisposalErrors.js} +0 -0
- /package/dist/debug/runtime/{phase.types.cjs → phases/phase.types.cjs} +0 -0
- /package/dist/debug/runtime/{phase.types.js → phases/phase.types.js} +0 -0
- /package/dist/path/{data-draft.d.ts → storage/createDataDraft.d.ts} +0 -0
- /package/dist/runtime/{disposal.d.ts → ownership/throwDisposalErrors.d.ts} +0 -0
- /package/dist/runtime/{RaphFrameLoop.d.ts → phases/RaphFrameLoop.d.ts} +0 -0
|
@@ -1,26 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (
|
|
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) {
|
|
6
|
+
c.dependencyLookupDebt === void 0 && c.dependencyIndex === void 0 || (c.dependencyIndex = void 0, c.dependencyLookupDebt = void 0, c.dependencyLookupSearches = void 0);
|
|
7
|
+
}
|
|
8
|
+
function H(c, e) {
|
|
9
|
+
if (e <= I || c.flags & x || c.dependencyIndex !== void 0)
|
|
10
|
+
return;
|
|
11
|
+
const t = (c.dependencyLookupSearches ?? 0) + 1, i = (c.dependencyLookupDebt ?? 0) + e;
|
|
12
|
+
if (c.dependencyLookupSearches = t, c.dependencyLookupDebt = i, t < F || i < c.depCount)
|
|
10
13
|
return;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
const s = /* @__PURE__ */ new Map();
|
|
15
|
+
for (let n = c.firstDep; n !== null; n = n.nextDep)
|
|
16
|
+
s.set(n.dep, n);
|
|
17
|
+
c.dependencyIndex = s, c.dependencyLookupDebt = void 0, c.dependencyLookupSearches = void 0;
|
|
18
|
+
}
|
|
19
|
+
function Q(c, e, t) {
|
|
20
|
+
const i = c.firstSub;
|
|
21
|
+
if (i === null)
|
|
22
|
+
return;
|
|
23
|
+
if (i === c.lastSub)
|
|
24
|
+
return i.sub === e ? i : void 0;
|
|
25
|
+
const s = c.subSearchCursor ?? i;
|
|
26
|
+
let n = 1;
|
|
27
|
+
if (s.sub === e)
|
|
28
|
+
return c.subSearchCursor = s.nextSub ?? i, s;
|
|
29
|
+
if (t) {
|
|
30
|
+
const a = e.dependencyIndex?.get(c);
|
|
31
|
+
if (a !== void 0)
|
|
32
|
+
return c.subSearchCursor = a.nextSub ?? i, a;
|
|
33
|
+
if (e.dependencyIndex !== void 0)
|
|
34
|
+
return;
|
|
21
35
|
}
|
|
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;
|
|
41
|
+
}
|
|
42
|
+
t && H(e, n);
|
|
22
43
|
}
|
|
23
|
-
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;
|
|
24
83
|
/**
|
|
25
84
|
* Выбирает политику исполнения и сохраняет совместимость извлечённых методов.
|
|
26
85
|
* Тела методов находятся на прототипе; bind() выполняется только при создании
|
|
@@ -28,41 +87,7 @@ class y {
|
|
|
28
87
|
* @param options Необязательная внешняя политика эффектов.
|
|
29
88
|
*/
|
|
30
89
|
constructor(e = {}) {
|
|
31
|
-
|
|
32
|
-
p(this, "activeSub", null);
|
|
33
|
-
// Глубина вложенных синхронных границ группировки.
|
|
34
|
-
p(this, "batchDepth", 0);
|
|
35
|
-
// Индекс следующего элемента внутренней очереди эффектов.
|
|
36
|
-
p(this, "effectReadIndex", 0);
|
|
37
|
-
// Позиция добавления элемента в текущем проходе очереди.
|
|
38
|
-
p(this, "effectWriteIndex", 0);
|
|
39
|
-
// Граница активного префикса переиспользуемого стека invalidation.
|
|
40
|
-
p(this, "invalidationDepth", 0);
|
|
41
|
-
// Граница активного префикса стека проверки зависимостей.
|
|
42
|
-
p(this, "dependencyDepth", 0);
|
|
43
|
-
// Защита внутренней очереди от вложенного повторного прохода.
|
|
44
|
-
p(this, "flushingEffects", !1);
|
|
45
|
-
// Переиспользуемый буфер очереди; прочитанная ячейка сразу освобождает ссылку.
|
|
46
|
-
p(this, "effectQueue", new Array(16).fill(void 0));
|
|
47
|
-
// Переиспользуемый стек распространения invalidation; исходный способ выделения сохранён.
|
|
48
|
-
p(this, "invalidationStack", new Array(512).fill(null));
|
|
49
|
-
// Переиспользуемый стек проверки зависимостей с защитой активного вложенного префикса.
|
|
50
|
-
p(this, "dependencyStack", []);
|
|
51
|
-
// Общие адаптеры receiver для handles этого экземпляра.
|
|
52
|
-
// Создаются один раз, чтобы computed не хранил дополнительную ссылку на движок
|
|
53
|
-
// и не выделял отдельные get/peek closures на каждый источник.
|
|
54
|
-
p(this, "handleReaders", this.createHandleReaders());
|
|
55
|
-
// Выбранная внешняя политика; у синхронного экземпляра отсутствует.
|
|
56
|
-
p(this, "effectScheduler");
|
|
57
|
-
// Прямой обработчик очереди, выбранный один раз при создании экземпляра.
|
|
58
|
-
p(this, "flushEffects");
|
|
59
|
-
/**
|
|
60
|
-
* Синхронная регистрация эффекта для Runtime и watch независимо от внешней политики.
|
|
61
|
-
* Это связанная ссылка на реализацию effect(), а не делегирующая функция.
|
|
62
|
-
* @internal
|
|
63
|
-
*/
|
|
64
|
-
p(this, "_effectImmediate");
|
|
65
|
-
this.effectScheduler = e.effectScheduler, this._effectImmediate = this.effect.bind(this), this.signal = this.signal.bind(this), this.computed = this.computed.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;
|
|
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;
|
|
66
91
|
}
|
|
67
92
|
// ---------------------------------------------
|
|
68
93
|
// PUBLIC API
|
|
@@ -78,15 +103,15 @@ class y {
|
|
|
78
103
|
const r = i;
|
|
79
104
|
if (r !== void 0)
|
|
80
105
|
return this.readSignalValue(r);
|
|
81
|
-
const
|
|
82
|
-
return
|
|
106
|
+
const a = this.activeSub;
|
|
107
|
+
return a === null || (i = this.materializeSignal(
|
|
83
108
|
t,
|
|
84
|
-
|
|
109
|
+
a
|
|
85
110
|
)), t;
|
|
86
111
|
}, n = (r) => {
|
|
87
|
-
const
|
|
88
|
-
if (
|
|
89
|
-
this.writeSignalValue(
|
|
112
|
+
const a = i;
|
|
113
|
+
if (a !== void 0) {
|
|
114
|
+
this.writeSignalValue(a, r);
|
|
90
115
|
return;
|
|
91
116
|
}
|
|
92
117
|
t !== r && (t = r);
|
|
@@ -97,6 +122,13 @@ class y {
|
|
|
97
122
|
set: n
|
|
98
123
|
};
|
|
99
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Возвращает стабильный глубокий Proxy для plain object или array.
|
|
127
|
+
* Object context и per-property sources создаются лениво внутри этого engine.
|
|
128
|
+
*/
|
|
129
|
+
reactive(e) {
|
|
130
|
+
return O(this, e, () => this.createReactivePropertySourceBridge());
|
|
131
|
+
}
|
|
100
132
|
computed(e) {
|
|
101
133
|
if (typeof e == "function")
|
|
102
134
|
return this.createComputedHandle(e);
|
|
@@ -113,10 +145,10 @@ class y {
|
|
|
113
145
|
* @param onStop Однократная окончательная очистка, независимая от повторных запусков.
|
|
114
146
|
*/
|
|
115
147
|
effect(e, t) {
|
|
116
|
-
const i = this.allocateGraphRecord(void 0, e, f |
|
|
148
|
+
const i = this.allocateGraphRecord(void 0, e, f | g | d);
|
|
117
149
|
t !== void 0 && (i.onStop = t);
|
|
118
150
|
const s = this.activeSub;
|
|
119
|
-
s !== null && s.flags &
|
|
151
|
+
s !== null && s.flags & d && W(s, i);
|
|
120
152
|
try {
|
|
121
153
|
this.executeEffect(i);
|
|
122
154
|
} catch (n) {
|
|
@@ -133,7 +165,7 @@ class y {
|
|
|
133
165
|
* Наблюдает за источниками; callback и cleanup не создают зависимостей.
|
|
134
166
|
*/
|
|
135
167
|
watch(e, t, i) {
|
|
136
|
-
return
|
|
168
|
+
return z(this.effect, this.untracked, e, t, i);
|
|
137
169
|
}
|
|
138
170
|
/**
|
|
139
171
|
* Группирует синхронные записи и обрабатывает эффекты после внешней границы.
|
|
@@ -179,7 +211,7 @@ class y {
|
|
|
179
211
|
* Создаёт владельца ресурсов в текущем графе без Runtime и фаз.
|
|
180
212
|
*/
|
|
181
213
|
scope() {
|
|
182
|
-
return new
|
|
214
|
+
return new U(this);
|
|
183
215
|
}
|
|
184
216
|
// ---------------------------------------------
|
|
185
217
|
// PRIVATE
|
|
@@ -201,6 +233,26 @@ class y {
|
|
|
201
233
|
cachedValue: e
|
|
202
234
|
};
|
|
203
235
|
}
|
|
236
|
+
/** Creates a narrow Proxy adapter over the existing intrusive graph. */
|
|
237
|
+
createReactivePropertySourceBridge() {
|
|
238
|
+
return {
|
|
239
|
+
batch: this.batch,
|
|
240
|
+
create: () => {
|
|
241
|
+
if (this.activeSub === null)
|
|
242
|
+
throw new Error("[Raph] Reactive property source requires a tracked read.");
|
|
243
|
+
return { firstSub: null, lastSub: null };
|
|
244
|
+
},
|
|
245
|
+
isTracking: this._isTracking,
|
|
246
|
+
track: (e) => {
|
|
247
|
+
const t = this.activeSub;
|
|
248
|
+
t !== null && this.trackDependency(e, t);
|
|
249
|
+
},
|
|
250
|
+
trigger: (e) => {
|
|
251
|
+
const t = e.firstSub;
|
|
252
|
+
t !== null && (this.propagateInvalidation(t), !this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects());
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
}
|
|
204
256
|
/**
|
|
205
257
|
* Материализует signal в графе при первом отслеживаемом чтении
|
|
206
258
|
* и связывает его с активным потребителем.
|
|
@@ -208,24 +260,25 @@ class y {
|
|
|
208
260
|
* До этого момента signal может хранить значение только в замыкании
|
|
209
261
|
* и вообще не создавать `ReactiveNode`.
|
|
210
262
|
*/
|
|
211
|
-
materializeSignal(e, t) {
|
|
212
|
-
const
|
|
263
|
+
materializeSignal(e, t, i) {
|
|
264
|
+
const s = this.allocateGraphRecord(
|
|
213
265
|
e,
|
|
214
266
|
void 0,
|
|
215
267
|
0
|
|
216
268
|
);
|
|
217
|
-
return t.flags &
|
|
269
|
+
return i !== void 0 && (s.sourceHooks = i, s.flags |= o), t.flags & x ? this.appendInitialDependency(s, t) : this.trackDependency(s, t), s;
|
|
218
270
|
}
|
|
219
271
|
/**
|
|
220
272
|
* Создаёт минимальный handle computed без преждевременного выделения полей графа.
|
|
221
273
|
* Первый get() материализует запись на этом же объекте и заменяет метод чтения.
|
|
222
274
|
*/
|
|
223
|
-
createComputedHandle(e) {
|
|
224
|
-
|
|
275
|
+
createComputedHandle(e, t) {
|
|
276
|
+
const i = {
|
|
225
277
|
evaluate: e,
|
|
226
278
|
get: this.handleReaders.initializeComputed,
|
|
227
279
|
peek: this.handleReaders.peek
|
|
228
280
|
};
|
|
281
|
+
return t !== void 0 && (i.sourceHooks = t), i;
|
|
229
282
|
}
|
|
230
283
|
/**
|
|
231
284
|
* Создаёт эффект с одной постоянной задачей внешнего scheduler.
|
|
@@ -235,39 +288,43 @@ class y {
|
|
|
235
288
|
* @param onStop Однократная окончательная очистка.
|
|
236
289
|
*/
|
|
237
290
|
createScheduledEffect(e, t) {
|
|
238
|
-
const i = this.allocateGraphRecord(void 0, e, f |
|
|
291
|
+
const i = this.allocateGraphRecord(void 0, e, f | g | d);
|
|
292
|
+
let s = !1;
|
|
239
293
|
t !== void 0 && (i.onStop = t);
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
const
|
|
294
|
+
const n = this.activeSub;
|
|
295
|
+
n !== null && n.flags & d && W(n, i);
|
|
296
|
+
const r = () => {
|
|
243
297
|
if (!(!(i.flags & v) || i.evaluate === void 0)) {
|
|
244
|
-
i.flags &= ~v;
|
|
298
|
+
i.flags &= ~v, s = !0;
|
|
245
299
|
try {
|
|
246
300
|
this.executeEffect(i);
|
|
247
|
-
} catch (
|
|
301
|
+
} catch (a) {
|
|
248
302
|
if (!this.batchDepth && this.effectReadIndex !== this.effectWriteIndex)
|
|
249
303
|
try {
|
|
250
304
|
this.flushEffects();
|
|
251
305
|
} catch (l) {
|
|
252
306
|
throw new AggregateError(
|
|
253
|
-
[
|
|
307
|
+
[a, l],
|
|
254
308
|
"Effect execution and queue processing failed."
|
|
255
309
|
);
|
|
256
310
|
}
|
|
257
|
-
throw
|
|
311
|
+
throw a;
|
|
258
312
|
}
|
|
259
313
|
!this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects();
|
|
260
314
|
}
|
|
261
315
|
};
|
|
262
316
|
try {
|
|
263
|
-
|
|
264
|
-
|
|
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());
|
|
320
|
+
}, i.effectTask = a, this.requestEffectTask(i);
|
|
321
|
+
} catch (a) {
|
|
265
322
|
try {
|
|
266
323
|
this.disposeEffect(i);
|
|
267
324
|
} catch (l) {
|
|
268
|
-
throw new AggregateError([
|
|
325
|
+
throw new AggregateError([a, l], "Effect registration and cleanup failed.");
|
|
269
326
|
}
|
|
270
|
-
throw
|
|
327
|
+
throw a;
|
|
271
328
|
}
|
|
272
329
|
return !this.batchDepth && this.effectReadIndex !== this.effectWriteIndex && this.flushEffects(), () => this.disposeEffect(i);
|
|
273
330
|
}
|
|
@@ -294,11 +351,11 @@ class y {
|
|
|
294
351
|
e.flags &= ~f, e.pendingAuthor = void 0;
|
|
295
352
|
else {
|
|
296
353
|
e.flags |= f;
|
|
297
|
-
const
|
|
298
|
-
s ? e.pendingAuthor !==
|
|
354
|
+
const a = this.activeSub !== null && this.activeSub.flags & p ? this.activeSub : null;
|
|
355
|
+
s ? e.pendingAuthor !== a && (e.pendingAuthor = null) : e.pendingAuthor = a;
|
|
299
356
|
}
|
|
300
357
|
const r = e.firstSub;
|
|
301
|
-
r != null && (!s || this.activeSub !== null && this.activeSub.flags &
|
|
358
|
+
r != null && (!s || this.activeSub !== null && this.activeSub.flags & p || e.flags & o) && this.propagateInvalidation(r, !0);
|
|
302
359
|
return;
|
|
303
360
|
}
|
|
304
361
|
if (e.cachedValue === t)
|
|
@@ -309,14 +366,21 @@ class y {
|
|
|
309
366
|
}
|
|
310
367
|
/**
|
|
311
368
|
* Возвращает кеш либо синхронно актуализирует вычисляемое значение.
|
|
312
|
-
* Неуспешное вычисление не считается значением.
|
|
313
|
-
*
|
|
369
|
+
* Неуспешное вычисление не считается значением. Ошибка getter сохраняет связь
|
|
370
|
+
* с активным потребителем для восстановления. Повторное чтение во время
|
|
371
|
+
* первого сбора зависимостей отклоняется до регистрации связи и чтения кеша.
|
|
314
372
|
*/
|
|
315
373
|
readComputedValue(e) {
|
|
316
|
-
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);
|
|
378
|
+
if (e.evaluate === void 0)
|
|
379
|
+
return s;
|
|
380
|
+
const n = this.activeSub;
|
|
317
381
|
if (n !== null) {
|
|
318
382
|
const r = n.tailDep;
|
|
319
|
-
n.flags &
|
|
383
|
+
n.flags & x ? (r === null || r.dep !== e) && this.appendInitialDependency(e, n) : this.trackDependency(e, n);
|
|
320
384
|
}
|
|
321
385
|
return s;
|
|
322
386
|
}
|
|
@@ -326,30 +390,34 @@ class y {
|
|
|
326
390
|
* Уже прочитанные зависимости сохраняются для последующего уведомления.
|
|
327
391
|
*/
|
|
328
392
|
evaluateFirstValue(e) {
|
|
329
|
-
e.flags
|
|
330
|
-
|
|
393
|
+
const t = e.flags & o, i = e.evaluate;
|
|
394
|
+
e.flags = t | p | x;
|
|
395
|
+
const s = this.activeSub;
|
|
331
396
|
this.activeSub = e;
|
|
397
|
+
let n;
|
|
332
398
|
try {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
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);
|
|
337
404
|
} finally {
|
|
338
|
-
this.activeSub =
|
|
405
|
+
this.activeSub = s;
|
|
339
406
|
}
|
|
407
|
+
return e.flags & f ? this.refreshComputedValue(e, e.flags) : (e.cachedValue = n, n);
|
|
340
408
|
}
|
|
341
409
|
/**
|
|
342
410
|
* Актуализирует computed: выполняет прямой пересчёт либо проверяет зависимости.
|
|
343
411
|
* После ошибки getter разрешён повторный пересчёт даже без новой записи источника.
|
|
344
412
|
*/
|
|
345
|
-
refreshComputedValue(e, t) {
|
|
413
|
+
refreshComputedValue(e, t, i = null) {
|
|
346
414
|
try {
|
|
347
|
-
if (t & (f |
|
|
348
|
-
return this.recomputeValue(e
|
|
349
|
-
const
|
|
350
|
-
return
|
|
351
|
-
} catch (
|
|
352
|
-
throw this.activeSub !== null && this.trackDependency(e, this.activeSub),
|
|
415
|
+
if (t & (f | D | k))
|
|
416
|
+
return this.recomputeValue(e, i), e.cachedValue;
|
|
417
|
+
const s = e.firstDep;
|
|
418
|
+
return s !== null && this.refreshDependencies(e, s) ? this.recomputeValue(e, i) : e.flags &= ~b, e.cachedValue;
|
|
419
|
+
} catch (s) {
|
|
420
|
+
throw this.activeSub !== null && this.trackDependency(e, this.activeSub), s;
|
|
353
421
|
}
|
|
354
422
|
}
|
|
355
423
|
/**
|
|
@@ -383,32 +451,32 @@ class y {
|
|
|
383
451
|
*/
|
|
384
452
|
reconcileDependency(e, t, i, s) {
|
|
385
453
|
if (t.depCount <= I) {
|
|
386
|
-
for (let
|
|
387
|
-
if (
|
|
388
|
-
return this.reorderDependency(t,
|
|
389
|
-
for (let
|
|
390
|
-
if (
|
|
391
|
-
return
|
|
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;
|
|
392
460
|
return s !== null ? (t.tailDep = this.reuseDepLink(s, e), s) : t.tailDep = this.insertDependency(e, t, i);
|
|
393
461
|
}
|
|
394
462
|
let n = 0, r = s;
|
|
395
463
|
for (; r !== null && n < I; ) {
|
|
396
|
-
const
|
|
397
|
-
if (
|
|
398
|
-
return this.reorderDependency(t,
|
|
399
|
-
r =
|
|
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;
|
|
400
468
|
}
|
|
401
|
-
let
|
|
402
|
-
for (;
|
|
403
|
-
const
|
|
404
|
-
if (
|
|
405
|
-
return
|
|
406
|
-
|
|
469
|
+
let a = i;
|
|
470
|
+
for (; a !== null && n < I; ) {
|
|
471
|
+
const l = a;
|
|
472
|
+
if (l.dep === e)
|
|
473
|
+
return l;
|
|
474
|
+
a = l.prevDep, ++n;
|
|
407
475
|
}
|
|
408
|
-
if (r !== null ||
|
|
409
|
-
const
|
|
410
|
-
if (
|
|
411
|
-
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;
|
|
412
480
|
}
|
|
413
481
|
return s !== null ? (t.tailDep = this.reuseDepLink(s, e), s) : t.tailDep = this.insertDependency(e, t, i);
|
|
414
482
|
}
|
|
@@ -426,7 +494,7 @@ class y {
|
|
|
426
494
|
prevDep: i,
|
|
427
495
|
nextDep: null
|
|
428
496
|
};
|
|
429
|
-
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, n;
|
|
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;
|
|
430
498
|
}
|
|
431
499
|
/**
|
|
432
500
|
* Вставляет связь после заданного курсора зависимостей потребителя.
|
|
@@ -443,16 +511,17 @@ class y {
|
|
|
443
511
|
};
|
|
444
512
|
s === null ? e.firstSub = n : s.nextSub = n, e.lastSub = n;
|
|
445
513
|
const r = i === null ? t.firstDep : i.nextDep;
|
|
446
|
-
return n.nextDep = r, r !== null && (r.prevDep = n), i === null ? t.firstDep = n : i.nextDep = n, ++t.depCount, n;
|
|
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;
|
|
447
515
|
}
|
|
448
516
|
/**
|
|
449
517
|
* Переназначает существующую связь другому производителю.
|
|
450
518
|
* Положение в списке зависимостей потребителя и число его связей сохраняются.
|
|
451
519
|
*/
|
|
452
520
|
reuseDepLink(e, t) {
|
|
521
|
+
const i = e.sub.dependencyIndex;
|
|
453
522
|
this.detachSubLink(e);
|
|
454
|
-
const
|
|
455
|
-
return e.dep = t, e.prevSub =
|
|
523
|
+
const s = t.lastSub;
|
|
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;
|
|
456
525
|
}
|
|
457
526
|
/**
|
|
458
527
|
* Перемещает существующую зависимость после курсора текущего чтения.
|
|
@@ -469,24 +538,50 @@ class y {
|
|
|
469
538
|
/**
|
|
470
539
|
* Удаляет непрочитанный хвост зависимостей завершившегося запуска.
|
|
471
540
|
* trackedTail обозначает границу прочитанного префикса, а не неизменный конец списка.
|
|
472
|
-
*
|
|
541
|
+
* Ошибка cleanup не прерывает освобождение оставшегося хвоста зависимостей.
|
|
473
542
|
*/
|
|
474
543
|
pruneUnreadDependencies(e) {
|
|
475
544
|
const t = e.tailDep;
|
|
476
545
|
let i = t === null ? e.firstDep : t.nextDep;
|
|
477
|
-
if (i
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
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);
|
|
481
559
|
}
|
|
560
|
+
i = n;
|
|
561
|
+
}
|
|
562
|
+
s !== void 0 && V(s, "Dependency cleanup failed.");
|
|
482
563
|
}
|
|
483
564
|
/**
|
|
484
565
|
* Удаляет связь только из списка потребителей производителя.
|
|
485
566
|
* Список зависимостей потребителя и его счётчик здесь не изменяются.
|
|
486
567
|
* Также исправляет курсор поиска, если он указывал на удаляемую связь.
|
|
487
568
|
*/
|
|
488
|
-
detachSubLink(e) {
|
|
489
|
-
e.
|
|
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);
|
|
577
|
+
}
|
|
578
|
+
/** Connects Runtime ownership metadata only for edges whose producer opted in. */
|
|
579
|
+
attachDependencyCleanup(e) {
|
|
580
|
+
const i = e.dep.sourceHooks?.onDependency;
|
|
581
|
+
if (i === void 0)
|
|
582
|
+
return;
|
|
583
|
+
const s = e.sub.sourceHooks?.dependencyOwner ?? e.sub.effectTask?.dependencyOwner;
|
|
584
|
+
s !== void 0 && (e.dependencyCleanup = i(s));
|
|
490
585
|
}
|
|
491
586
|
/**
|
|
492
587
|
* Отсоединяет owned-источник сразу с обеих сторон каждой связи.
|
|
@@ -494,14 +589,29 @@ class y {
|
|
|
494
589
|
* Переводит ожидавших проверку потребителей к повторному вычислению при необходимости.
|
|
495
590
|
*/
|
|
496
591
|
releaseSourceSubs(e) {
|
|
497
|
-
|
|
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;
|
|
599
|
+
}
|
|
600
|
+
e.firstSub = e.lastSub = null, e.subSearchCursor = void 0;
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
let t = e.firstSub, i;
|
|
498
604
|
for (; t != null; ) {
|
|
499
|
-
const
|
|
500
|
-
this.detachDependencyLink(t)
|
|
501
|
-
|
|
502
|
-
|
|
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;
|
|
503
613
|
}
|
|
504
|
-
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.");
|
|
505
615
|
}
|
|
506
616
|
/**
|
|
507
617
|
* Удаляет связь только из списка зависимостей потребителя.
|
|
@@ -510,14 +620,15 @@ class y {
|
|
|
510
620
|
*/
|
|
511
621
|
detachDependencyLink(e) {
|
|
512
622
|
const t = e.sub, i = e.prevDep, s = e.nextDep;
|
|
513
|
-
i === null ? t.firstDep = s : i.nextDep = s, s !== null && (s.prevDep = i), t.tailDep === e && (t.tailDep = i), --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));
|
|
514
624
|
}
|
|
515
625
|
/**
|
|
516
626
|
* Добавляет эффект во внутреннюю очередь один раз до обработки текущей записи.
|
|
517
627
|
* Флаг SCHEDULED предотвращает повторное добавление без создания task-объекта.
|
|
518
628
|
*/
|
|
519
|
-
enqueueEffect(e) {
|
|
520
|
-
|
|
629
|
+
enqueueEffect(e, t) {
|
|
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);
|
|
521
632
|
}
|
|
522
633
|
/**
|
|
523
634
|
* Распространяет invalidation от непосредственных к транзитивным потребителям.
|
|
@@ -525,31 +636,55 @@ class y {
|
|
|
525
636
|
* не выполняет. Непосредственное и потенциальное изменения отмечает разными флагами.
|
|
526
637
|
*/
|
|
527
638
|
propagateInvalidation(e, t = !1) {
|
|
639
|
+
this.checkingDepth !== 0 && this.markActiveChecks(e);
|
|
528
640
|
const i = this.invalidationDepth;
|
|
529
641
|
let s = i;
|
|
530
642
|
for (let n = e; n !== null; n = n.nextSub) {
|
|
531
|
-
const r = n.sub,
|
|
532
|
-
let
|
|
533
|
-
|
|
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));
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
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));
|
|
534
653
|
}
|
|
535
654
|
for (; s !== i; ) {
|
|
536
655
|
let n = this.invalidationStack[--s];
|
|
537
|
-
|
|
538
|
-
const r = n.sub,
|
|
539
|
-
let
|
|
540
|
-
if (
|
|
541
|
-
if (
|
|
542
|
-
|
|
543
|
-
|
|
656
|
+
do {
|
|
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)) {
|
|
544
664
|
n.nextSub !== null && (this.invalidationStack[s++] = n.nextSub), n = r.firstSub;
|
|
545
665
|
continue;
|
|
546
666
|
}
|
|
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;
|
|
671
|
+
continue;
|
|
547
672
|
}
|
|
548
673
|
n = n.nextSub;
|
|
549
|
-
}
|
|
674
|
+
} while (n !== null);
|
|
550
675
|
}
|
|
551
676
|
this.invalidationDepth = i;
|
|
552
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
|
+
}
|
|
553
688
|
/**
|
|
554
689
|
* Помечает работающего потребителя, только если затронута уже прочитанная связь.
|
|
555
690
|
* Связи за trackedTail принадлежат прошлому запуску и не означают повторную invalidation.
|
|
@@ -564,7 +699,7 @@ class y {
|
|
|
564
699
|
if (r === s)
|
|
565
700
|
return 0;
|
|
566
701
|
}
|
|
567
|
-
const n = i |
|
|
702
|
+
const n = i | D | g;
|
|
568
703
|
return t.flags = n, n;
|
|
569
704
|
}
|
|
570
705
|
/**
|
|
@@ -577,7 +712,7 @@ class y {
|
|
|
577
712
|
if (s === t || s.sub === i)
|
|
578
713
|
continue;
|
|
579
714
|
const n = s.sub, r = n.flags;
|
|
580
|
-
r & f || (n.flags = r & ~
|
|
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));
|
|
581
716
|
}
|
|
582
717
|
}
|
|
583
718
|
/**
|
|
@@ -588,24 +723,52 @@ class y {
|
|
|
588
723
|
* Неверное значение в кеш не записывается.
|
|
589
724
|
*/
|
|
590
725
|
recomputeValue(e, t = null) {
|
|
591
|
-
const i = e.
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
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) {
|
|
598
766
|
try {
|
|
599
|
-
|
|
600
|
-
} catch (
|
|
601
|
-
throw
|
|
602
|
-
} finally {
|
|
603
|
-
this.activeSub = n;
|
|
767
|
+
this.restoreComputedFailure(e, t);
|
|
768
|
+
} catch (s) {
|
|
769
|
+
throw new AggregateError([i, s], "Computed evaluation and dependency cleanup failed.");
|
|
604
770
|
}
|
|
605
|
-
|
|
606
|
-
(u === null ? e.firstDep : u.nextDep) !== null && this.pruneUnreadDependencies(e);
|
|
607
|
-
const D = e.cachedValue;
|
|
608
|
-
return e.cachedValue = r, e.flags = l ? f : c, D === r ? !1 : (e.firstSub !== null && this.confirmSubUpdates(e.firstSub, t), !0);
|
|
771
|
+
throw i;
|
|
609
772
|
}
|
|
610
773
|
/**
|
|
611
774
|
* Восстанавливает связи и состояния после неудачного getter.
|
|
@@ -613,7 +776,12 @@ class y {
|
|
|
613
776
|
* Потребитель исключаемой связи мог уже покинуть активный префикс стека.
|
|
614
777
|
*/
|
|
615
778
|
restoreComputedFailure(e, t) {
|
|
616
|
-
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
|
+
}
|
|
617
785
|
}
|
|
618
786
|
/**
|
|
619
787
|
* Итеративно проверяет зависимые computed и pending-сигналы перед запуском потребителя.
|
|
@@ -626,12 +794,19 @@ class y {
|
|
|
626
794
|
try {
|
|
627
795
|
return this.walkDependencyChain(e, t);
|
|
628
796
|
} catch (s) {
|
|
629
|
-
this.restoreFailedDependency(e);
|
|
797
|
+
this.markRecoveryDependencies(e), this.restoreFailedDependency(e);
|
|
630
798
|
for (let n = i; n < this.dependencyDepth; n++)
|
|
631
799
|
this.restoreFailedDependency(this.dependencyStack[n].sub);
|
|
632
800
|
throw this.dependencyDepth = i, this.dependencyStack.length = i, s;
|
|
633
801
|
}
|
|
634
802
|
}
|
|
803
|
+
/** Settles every direct dependency so a cancelled external delivery can be re-armed. */
|
|
804
|
+
settleCancelledDependencies(e) {
|
|
805
|
+
for (let t = e.firstDep; t !== null; t = t.nextDep) {
|
|
806
|
+
const i = t.dep, s = i.flags;
|
|
807
|
+
s & (_ | b | k) && (i.evaluate === void 0 ? s & f && this.commitSignalValue(i, t) : this.refreshComputedValue(i, s, t));
|
|
808
|
+
}
|
|
809
|
+
}
|
|
635
810
|
/**
|
|
636
811
|
* Выполняет исходный итеративный обход зависимостей без обработки ошибок внутри цикла.
|
|
637
812
|
* Перед пользовательским вычислением публикует активную высоту стека; оболочка
|
|
@@ -639,51 +814,70 @@ class y {
|
|
|
639
814
|
*/
|
|
640
815
|
walkDependencyChain(e, t) {
|
|
641
816
|
const i = this.dependencyDepth;
|
|
642
|
-
let s = i, n = !1;
|
|
643
|
-
e
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
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
|
+
}
|
|
654
858
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
659
|
-
if (!n && t.nextDep !== null) {
|
|
660
|
-
t = t.nextDep;
|
|
661
|
-
continue;
|
|
662
|
-
}
|
|
663
|
-
if (n) {
|
|
859
|
+
if (n)
|
|
860
|
+
return this.dependencyDepth = i, !0;
|
|
861
|
+
}
|
|
664
862
|
for (; s !== i; ) {
|
|
863
|
+
if (e.flags & (f | E))
|
|
864
|
+
continue e;
|
|
665
865
|
this.dependencyDepth = --s;
|
|
666
|
-
const
|
|
667
|
-
if (
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
continue e;
|
|
671
|
-
}
|
|
672
|
-
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;
|
|
673
870
|
}
|
|
674
871
|
}
|
|
675
|
-
if (
|
|
676
|
-
return this.dependencyDepth = i, !0;
|
|
677
|
-
}
|
|
678
|
-
for (; s !== i; ) {
|
|
679
|
-
this.dependencyDepth = --s;
|
|
680
|
-
const r = this.dependencyStack[s];
|
|
681
|
-
if (e.flags &= ~d, e = r.sub, r.nextDep !== null) {
|
|
682
|
-
t = r.nextDep;
|
|
872
|
+
if (e.flags & (f | E))
|
|
683
873
|
continue e;
|
|
684
|
-
|
|
874
|
+
return e.flags &= ~(g | R), this.dependencyDepth = i, !1;
|
|
685
875
|
}
|
|
686
|
-
|
|
876
|
+
} finally {
|
|
877
|
+
e.flags &= ~R;
|
|
878
|
+
for (let a = i; a < s; a++)
|
|
879
|
+
this.dependencyStack[a].sub.flags &= ~R;
|
|
880
|
+
--this.checkingDepth;
|
|
687
881
|
}
|
|
688
882
|
}
|
|
689
883
|
/**
|
|
@@ -692,7 +886,11 @@ class y {
|
|
|
692
886
|
* для следующей invalidation. Вызывается только на ошибочном пути.
|
|
693
887
|
*/
|
|
694
888
|
restoreFailedDependency(e) {
|
|
695
|
-
|
|
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);
|
|
696
894
|
}
|
|
697
895
|
/**
|
|
698
896
|
* Проверяет необходимость запуска, очищает прошлые ресурсы и выполняет тело эффекта.
|
|
@@ -703,22 +901,22 @@ class y {
|
|
|
703
901
|
*/
|
|
704
902
|
executeEffect(e) {
|
|
705
903
|
const t = e.flags;
|
|
706
|
-
if (!(t &
|
|
904
|
+
if (!(t & b))
|
|
707
905
|
return;
|
|
708
|
-
if (!(t & (f |
|
|
906
|
+
if (!(t & (f | D))) {
|
|
709
907
|
const u = e.firstDep;
|
|
710
908
|
try {
|
|
711
909
|
if (u === null || !this.refreshDependencies(e, u)) {
|
|
712
|
-
e.flags &= ~
|
|
910
|
+
e.flags &= ~b;
|
|
713
911
|
return;
|
|
714
912
|
}
|
|
715
|
-
} catch (
|
|
716
|
-
throw e.flags &= -80,
|
|
913
|
+
} catch (w) {
|
|
914
|
+
throw e.flags &= -80, w;
|
|
717
915
|
}
|
|
718
916
|
}
|
|
719
917
|
const i = e.evaluate;
|
|
720
918
|
if (i === void 0) {
|
|
721
|
-
e.flags &= ~
|
|
919
|
+
e.flags &= ~b;
|
|
722
920
|
return;
|
|
723
921
|
}
|
|
724
922
|
let s;
|
|
@@ -729,11 +927,11 @@ class y {
|
|
|
729
927
|
s = [u];
|
|
730
928
|
}
|
|
731
929
|
const n = typeof e.cachedValue == "function" ? e.cachedValue : void 0;
|
|
732
|
-
if (e.cachedValue = void 0, e.flags &= ~
|
|
930
|
+
if (e.cachedValue = void 0, e.flags &= ~D, n !== void 0)
|
|
733
931
|
try {
|
|
734
932
|
this.untracked(n);
|
|
735
933
|
} catch (u) {
|
|
736
|
-
s
|
|
934
|
+
s ??= [], s.push(u);
|
|
737
935
|
}
|
|
738
936
|
if (s !== void 0) {
|
|
739
937
|
try {
|
|
@@ -741,32 +939,32 @@ class y {
|
|
|
741
939
|
} catch (u) {
|
|
742
940
|
s.push(u);
|
|
743
941
|
}
|
|
744
|
-
|
|
942
|
+
V(s, "Effect cleanup failed.");
|
|
745
943
|
}
|
|
746
944
|
if (e.evaluate === void 0)
|
|
747
945
|
return;
|
|
748
|
-
e.tailDep = null, e.flags = e.flags & ~
|
|
946
|
+
e.tailDep = null, e.flags = e.flags & ~D | p;
|
|
749
947
|
const r = this.activeSub;
|
|
750
948
|
this.activeSub = e;
|
|
751
|
-
let
|
|
949
|
+
let a;
|
|
752
950
|
try {
|
|
753
|
-
|
|
951
|
+
a = i();
|
|
754
952
|
} catch (u) {
|
|
755
|
-
this.activeSub = r, e.flags &= ~
|
|
953
|
+
this.activeSub = r, e.flags &= ~p, this.failEffectRun(e, u, s);
|
|
756
954
|
} finally {
|
|
757
|
-
this.activeSub = r, e.flags &= ~
|
|
955
|
+
this.activeSub = r, e.flags &= ~p;
|
|
758
956
|
}
|
|
759
|
-
const
|
|
760
|
-
if ((
|
|
957
|
+
const l = e.tailDep;
|
|
958
|
+
if ((l === null ? e.firstDep : l.nextDep) !== null && this.pruneUnreadDependencies(e), typeof a == "function")
|
|
761
959
|
if (e.evaluate === void 0)
|
|
762
960
|
try {
|
|
763
|
-
this.untracked(
|
|
961
|
+
this.untracked(a);
|
|
764
962
|
} catch (u) {
|
|
765
|
-
s
|
|
963
|
+
s ??= [], s.push(u);
|
|
766
964
|
}
|
|
767
965
|
else
|
|
768
|
-
e.cachedValue =
|
|
769
|
-
e.flags & v ? e.flags = e.flags & -7 |
|
|
966
|
+
e.cachedValue = a;
|
|
967
|
+
e.flags & v ? e.flags = e.flags & -7 | g : e.flags &= -8;
|
|
770
968
|
}
|
|
771
969
|
/**
|
|
772
970
|
* Завершает неудачный запуск эффекта, не затрагивая успешный путь исполнения.
|
|
@@ -789,7 +987,7 @@ class y {
|
|
|
789
987
|
* Путь не проверяет наличие внешней задачи у каждого узла.
|
|
790
988
|
*/
|
|
791
989
|
flushSyncEffects() {
|
|
792
|
-
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (
|
|
990
|
+
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (d | p)) === (d | p))) {
|
|
793
991
|
this.flushingEffects = !0;
|
|
794
992
|
try {
|
|
795
993
|
for (; this.effectReadIndex !== this.effectWriteIndex; ) {
|
|
@@ -809,12 +1007,14 @@ class y {
|
|
|
809
1007
|
* Ошибка одного элемента не оставляет необработанные записи со старым SCHEDULED.
|
|
810
1008
|
*/
|
|
811
1009
|
flushExternalEffects() {
|
|
812
|
-
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (
|
|
1010
|
+
if (!(this.flushingEffects || this.activeSub !== null && (this.activeSub.flags & (d | p)) === (d | p))) {
|
|
813
1011
|
this.flushingEffects = !0;
|
|
814
1012
|
try {
|
|
815
1013
|
for (; this.effectReadIndex !== this.effectWriteIndex; ) {
|
|
816
1014
|
const e = this.effectReadIndex, t = this.effectQueue[e];
|
|
817
|
-
this.effectQueue[e] = void 0, ++this.effectReadIndex
|
|
1015
|
+
this.effectQueue[e] = void 0, ++this.effectReadIndex;
|
|
1016
|
+
const i = t.effectTask;
|
|
1017
|
+
i === void 0 ? (t.flags &= ~v, this.executeEffect(t)) : t.evaluate !== void 0 ? this.scheduleEffectTask(t, i) : t.flags &= ~v;
|
|
818
1018
|
}
|
|
819
1019
|
} catch (e) {
|
|
820
1020
|
this.drainQueueAfterError(e, !0);
|
|
@@ -823,6 +1023,20 @@ class y {
|
|
|
823
1023
|
}
|
|
824
1024
|
}
|
|
825
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
|
+
}
|
|
826
1040
|
/**
|
|
827
1041
|
* Завершает очередь после первой ошибки, собирая последующие причины сбоя.
|
|
828
1042
|
* Вызывается только на ошибочном пути; успешный проход не создаёт массив ошибок
|
|
@@ -832,9 +1046,10 @@ class y {
|
|
|
832
1046
|
const i = [e];
|
|
833
1047
|
for (; this.effectReadIndex !== this.effectWriteIndex; ) {
|
|
834
1048
|
const s = this.effectReadIndex++, n = this.effectQueue[s];
|
|
835
|
-
this.effectQueue[s] = void 0
|
|
1049
|
+
this.effectQueue[s] = void 0;
|
|
836
1050
|
try {
|
|
837
|
-
t
|
|
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));
|
|
838
1053
|
} catch (r) {
|
|
839
1054
|
i.push(r);
|
|
840
1055
|
}
|
|
@@ -848,13 +1063,14 @@ class y {
|
|
|
848
1063
|
*/
|
|
849
1064
|
requestEffectTask(e) {
|
|
850
1065
|
const t = e.effectTask;
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1066
|
+
t === void 0 || e.evaluate === void 0 || (e.flags |= v, this.scheduleEffectTask(e, t));
|
|
1067
|
+
}
|
|
1068
|
+
// Передаёт уже запланированный эффект его постоянной внешней задаче.
|
|
1069
|
+
scheduleEffectTask(e, t) {
|
|
1070
|
+
try {
|
|
1071
|
+
t.schedule();
|
|
1072
|
+
} catch (i) {
|
|
1073
|
+
throw e.flags &= -72, i;
|
|
858
1074
|
}
|
|
859
1075
|
}
|
|
860
1076
|
/**
|
|
@@ -866,39 +1082,40 @@ class y {
|
|
|
866
1082
|
disposeEffect(e) {
|
|
867
1083
|
if (e.evaluate === void 0)
|
|
868
1084
|
return;
|
|
1085
|
+
this.activeSub === e && (this.activeSub = null);
|
|
869
1086
|
const t = e.effectTask, i = e.onStop, s = typeof e.cachedValue == "function" ? e.cachedValue : void 0;
|
|
870
|
-
e.evaluate = void 0, e.flags = 0, e.cachedValue = void 0, e.effectTask = void 0, i !== void 0 && (e.onStop = void 0),
|
|
871
|
-
let n
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
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];
|
|
875
1094
|
}
|
|
876
|
-
e.firstDep = e.tailDep = null, e.depCount = 0
|
|
877
|
-
let r;
|
|
878
|
-
if (t !== void 0)
|
|
1095
|
+
if (e.firstDep = e.tailDep = null, e.depCount = 0, A(e), t !== void 0)
|
|
879
1096
|
try {
|
|
880
1097
|
t.dispose();
|
|
881
|
-
} catch (
|
|
882
|
-
|
|
1098
|
+
} catch (r) {
|
|
1099
|
+
n ??= [], n.push(r);
|
|
883
1100
|
}
|
|
884
1101
|
try {
|
|
885
1102
|
this.disposeNestedEffects(e);
|
|
886
|
-
} catch (
|
|
887
|
-
|
|
1103
|
+
} catch (r) {
|
|
1104
|
+
n ??= [], n.push(r);
|
|
888
1105
|
}
|
|
889
1106
|
if (s !== void 0)
|
|
890
1107
|
try {
|
|
891
1108
|
this.untracked(s);
|
|
892
|
-
} catch (
|
|
893
|
-
|
|
1109
|
+
} catch (r) {
|
|
1110
|
+
n ??= [], n.push(r);
|
|
894
1111
|
}
|
|
895
1112
|
if (i !== void 0)
|
|
896
1113
|
try {
|
|
897
1114
|
this.untracked(i);
|
|
898
|
-
} catch (
|
|
899
|
-
|
|
1115
|
+
} catch (r) {
|
|
1116
|
+
n ??= [], n.push(r);
|
|
900
1117
|
}
|
|
901
|
-
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.");
|
|
902
1119
|
}
|
|
903
1120
|
/**
|
|
904
1121
|
* Останавливает все вложенные эффекты в обратном порядке регистрации.
|
|
@@ -911,16 +1128,16 @@ class y {
|
|
|
911
1128
|
try {
|
|
912
1129
|
this.disposeEffect(e.scopeLastChild);
|
|
913
1130
|
} catch (i) {
|
|
914
|
-
t
|
|
1131
|
+
t ??= [], t.push(i);
|
|
915
1132
|
}
|
|
916
|
-
t !== void 0 &&
|
|
1133
|
+
t !== void 0 && V(t, "Nested effect disposal failed.");
|
|
917
1134
|
}
|
|
918
1135
|
/**
|
|
919
1136
|
* Задаёт обязательные поля графа перед первым вычислением.
|
|
920
1137
|
* Вызывается только для нематериализованного handle; getter и контекст сохраняются.
|
|
921
1138
|
*/
|
|
922
1139
|
static materializeComputed(e) {
|
|
923
|
-
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;
|
|
924
1141
|
}
|
|
925
1142
|
/**
|
|
926
1143
|
* Связывает два разных receiver: движок-владелец и читаемый handle.
|
|
@@ -938,14 +1155,14 @@ class y {
|
|
|
938
1155
|
*/
|
|
939
1156
|
initializeComputed() {
|
|
940
1157
|
const i = this;
|
|
941
|
-
return
|
|
1158
|
+
return N.materializeComputed(i), this.get = t, e.readComputedValue(i);
|
|
942
1159
|
},
|
|
943
1160
|
/**
|
|
944
1161
|
* Материализует raw computed, сохраняя извлечение read после первого вызова.
|
|
945
1162
|
*/
|
|
946
1163
|
initializeRaw() {
|
|
947
1164
|
const i = this;
|
|
948
|
-
|
|
1165
|
+
N.materializeComputed(i);
|
|
949
1166
|
const s = () => e.readComputedValue(i);
|
|
950
1167
|
return this.read = s, s();
|
|
951
1168
|
},
|
|
@@ -989,11 +1206,11 @@ class y {
|
|
|
989
1206
|
u !== void 0 ? t.writeSignalValue(u, r) : i !== r && (i = r);
|
|
990
1207
|
return;
|
|
991
1208
|
}
|
|
992
|
-
const
|
|
993
|
-
if (
|
|
994
|
-
return t.readSignalValue(
|
|
995
|
-
const
|
|
996
|
-
return
|
|
1209
|
+
const a = s;
|
|
1210
|
+
if (a !== void 0)
|
|
1211
|
+
return t.readSignalValue(a);
|
|
1212
|
+
const l = t.activeSub;
|
|
1213
|
+
return l === null || (s = t.materializeSignal(i, l)), i;
|
|
997
1214
|
}
|
|
998
1215
|
return {
|
|
999
1216
|
read: n,
|
|
@@ -1019,29 +1236,36 @@ class y {
|
|
|
1019
1236
|
*
|
|
1020
1237
|
* @internal
|
|
1021
1238
|
*/
|
|
1022
|
-
_ownedSignal(e) {
|
|
1023
|
-
const
|
|
1024
|
-
let
|
|
1025
|
-
const
|
|
1026
|
-
const
|
|
1027
|
-
if (
|
|
1028
|
-
return this.readSignalValue(
|
|
1029
|
-
const
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1239
|
+
_ownedSignal(e, t) {
|
|
1240
|
+
const i = this;
|
|
1241
|
+
let s = e, n, r = !1;
|
|
1242
|
+
const a = () => {
|
|
1243
|
+
const h = n;
|
|
1244
|
+
if (h !== void 0)
|
|
1245
|
+
return this.readSignalValue(h);
|
|
1246
|
+
const S = this.activeSub;
|
|
1247
|
+
if (S === null)
|
|
1248
|
+
return s;
|
|
1249
|
+
const C = s;
|
|
1250
|
+
return n = this.materializeSignal(
|
|
1251
|
+
C,
|
|
1252
|
+
S,
|
|
1253
|
+
t
|
|
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);
|
|
1038
1263
|
return;
|
|
1039
1264
|
}
|
|
1040
|
-
|
|
1041
|
-
}
|
|
1042
|
-
return {
|
|
1265
|
+
s !== h && (t.onChange?.(s, h, !1), s = h);
|
|
1266
|
+
}, w = {
|
|
1043
1267
|
source: {
|
|
1044
|
-
get:
|
|
1268
|
+
get: a,
|
|
1045
1269
|
peek: this.handleReaders.peek,
|
|
1046
1270
|
set: l
|
|
1047
1271
|
},
|
|
@@ -1049,36 +1273,77 @@ class y {
|
|
|
1049
1273
|
* Освобождает источник и отсоединяет его от реактивного графа.
|
|
1050
1274
|
*/
|
|
1051
1275
|
dispose() {
|
|
1052
|
-
|
|
1276
|
+
if (r)
|
|
1277
|
+
return !0;
|
|
1278
|
+
r = !0, s = void 0;
|
|
1279
|
+
let h;
|
|
1280
|
+
try {
|
|
1281
|
+
t?.onDispose?.(n?.firstSub != null);
|
|
1282
|
+
} catch (S) {
|
|
1283
|
+
(h ??= []).push(S);
|
|
1284
|
+
}
|
|
1285
|
+
if (n !== void 0) {
|
|
1286
|
+
try {
|
|
1287
|
+
i.releaseSourceSubs(n);
|
|
1288
|
+
} catch (S) {
|
|
1289
|
+
(h ??= []).push(S);
|
|
1290
|
+
}
|
|
1291
|
+
n.cachedValue = void 0, n.pendingValue = void 0, n.pendingAuthor = void 0, n.flags = 0;
|
|
1292
|
+
}
|
|
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.");
|
|
1297
|
+
return !0;
|
|
1053
1298
|
}
|
|
1054
1299
|
};
|
|
1300
|
+
return t !== void 0 && (w.hasSubscribers = () => n?.firstSub != null), w;
|
|
1055
1301
|
}
|
|
1056
1302
|
/**
|
|
1057
1303
|
* Создаёт ленивый computed с финализатором исходящих и входящих связей.
|
|
1058
1304
|
* Финализатор работает и до первого вычисления, не материализуя узел ради очистки.
|
|
1059
1305
|
* @internal
|
|
1060
1306
|
*/
|
|
1061
|
-
_ownedComputed(e) {
|
|
1062
|
-
const
|
|
1063
|
-
let
|
|
1064
|
-
|
|
1065
|
-
source:
|
|
1307
|
+
_ownedComputed(e, t) {
|
|
1308
|
+
const i = this, s = this.createComputedHandle(e, t);
|
|
1309
|
+
let n = !1;
|
|
1310
|
+
const r = {
|
|
1311
|
+
source: s,
|
|
1066
1312
|
/**
|
|
1067
1313
|
* Отсоединяет принадлежащий источник и освобождает его ссылки.
|
|
1068
1314
|
* Повторный вызов возвращает true без повторной очистки.
|
|
1069
1315
|
*/
|
|
1070
1316
|
dispose() {
|
|
1071
|
-
if (
|
|
1317
|
+
if (n)
|
|
1072
1318
|
return !0;
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1319
|
+
n = !0, i.activeSub === s && (i.activeSub = null);
|
|
1320
|
+
const a = [];
|
|
1321
|
+
try {
|
|
1322
|
+
t?.onDispose?.(s.firstSub != null);
|
|
1323
|
+
} catch (u) {
|
|
1324
|
+
a.push(u);
|
|
1078
1325
|
}
|
|
1079
|
-
|
|
1326
|
+
if (s.flags !== void 0)
|
|
1327
|
+
try {
|
|
1328
|
+
i.releaseSourceSubs(s);
|
|
1329
|
+
} catch (u) {
|
|
1330
|
+
a.push(u);
|
|
1331
|
+
}
|
|
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)
|
|
1340
|
+
throw a[0];
|
|
1341
|
+
if (a.length > 1)
|
|
1342
|
+
throw new AggregateError(a, "Owned computed disposal failed.");
|
|
1343
|
+
return !0;
|
|
1080
1344
|
}
|
|
1081
1345
|
};
|
|
1346
|
+
return t !== void 0 && (r.hasSubscribers = () => s.firstSub != null), r;
|
|
1082
1347
|
}
|
|
1083
1348
|
/**
|
|
1084
1349
|
* Открывает вложенную синхронную границу группировки.
|
|
@@ -1110,24 +1375,326 @@ class y {
|
|
|
1110
1375
|
_isFlushingEffects() {
|
|
1111
1376
|
return this.flushingEffects;
|
|
1112
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
|
+
}
|
|
1113
1679
|
}
|
|
1114
|
-
let
|
|
1115
|
-
function
|
|
1116
|
-
return
|
|
1680
|
+
let P;
|
|
1681
|
+
function y() {
|
|
1682
|
+
return P ??= new N();
|
|
1117
1683
|
}
|
|
1118
|
-
const
|
|
1119
|
-
function
|
|
1120
|
-
return
|
|
1684
|
+
const K = (c) => y().signal(c), Y = (c) => y().reactive(c);
|
|
1685
|
+
function X(c) {
|
|
1686
|
+
return y().computed(c);
|
|
1121
1687
|
}
|
|
1122
|
-
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();
|
|
1123
1689
|
export {
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
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
|
|
1133
1700
|
};
|