@raphy-js/raph 1.0.1-dev.20 → 1.0.1-dev.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/{core-CyilRD7s.js → core-CClhT8WR.js} +389 -400
  2. package/dist/core-cPQWYD4K.cjs +1 -0
  3. package/dist/debug/api/Raph.cjs +1 -1
  4. package/dist/debug/api/Raph.js +46 -47
  5. package/dist/debug/api/RaphFacadeSession.cjs +1 -1
  6. package/dist/debug/api/RaphFacadeSession.js +85 -89
  7. package/dist/debug/api/RaphReactivityInstance.cjs +1 -1
  8. package/dist/debug/api/RaphReactivityInstance.js +27 -30
  9. package/dist/debug/path/DataPath.cjs +1 -1
  10. package/dist/debug/path/DataPath.js +198 -202
  11. package/dist/debug/path/PathRouter.cjs +1 -1
  12. package/dist/debug/path/PathRouter.js +44 -50
  13. package/dist/debug/path/RaphKernel.cjs +1 -1
  14. package/dist/debug/path/RaphKernel.js +257 -228
  15. package/dist/debug/path/data-path.utils.cjs +1 -1
  16. package/dist/debug/path/data-path.utils.js +41 -41
  17. package/dist/debug/path/derived/DerivedRegistry.cjs +1 -1
  18. package/dist/debug/path/derived/DerivedRegistry.js +52 -66
  19. package/dist/debug/path/derived/RaphDerivedHandle.cjs +1 -1
  20. package/dist/debug/path/derived/RaphDerivedHandle.js +19 -22
  21. package/dist/debug/path/derived/derived-collection.utils.cjs +1 -1
  22. package/dist/debug/path/derived/derived-collection.utils.js +70 -70
  23. package/dist/debug/path/meta/MetaController.cjs +1 -1
  24. package/dist/debug/path/meta/MetaController.js +57 -65
  25. package/dist/debug/path/meta/RaphMeta.cjs +1 -1
  26. package/dist/debug/path/meta/RaphMeta.js +26 -32
  27. package/dist/debug/path/meta/RaphMetaStore.cjs +1 -1
  28. package/dist/debug/path/meta/RaphMetaStore.js +24 -30
  29. package/dist/debug/path/storage/AdapterPathStore.cjs +1 -1
  30. package/dist/debug/path/storage/AdapterPathStore.js +49 -54
  31. package/dist/debug/path/storage/DefaultDataAdapter.cjs +1 -1
  32. package/dist/debug/path/storage/DefaultDataAdapter.js +46 -56
  33. package/dist/debug/path/storage/PathEventHub.cjs +1 -1
  34. package/dist/debug/path/storage/PathEventHub.js +74 -61
  35. package/dist/debug/path/storage/PathStore.cjs +1 -1
  36. package/dist/debug/path/storage/PathStore.js +89 -99
  37. package/dist/debug/path/storage/createDataDraft.cjs +1 -1
  38. package/dist/debug/path/storage/createDataDraft.js +24 -28
  39. package/dist/debug/reactivity/disposal.cjs +1 -0
  40. package/dist/debug/reactivity/disposal.js +32 -0
  41. package/dist/debug/reactivity/engine.cjs +1 -1
  42. package/dist/debug/reactivity/engine.js +787 -392
  43. package/dist/debug/reactivity/reactive-object.cjs +1 -1
  44. package/dist/debug/reactivity/reactive-object.js +81 -96
  45. package/dist/debug/reactivity/scope.cjs +1 -1
  46. package/dist/debug/reactivity/scope.js +221 -117
  47. package/dist/debug/reactivity/watch.cjs +1 -1
  48. package/dist/debug/reactivity/watch.js +1 -1
  49. package/dist/debug/runtime/RaphRuntime.cjs +1 -1
  50. package/dist/debug/runtime/RaphRuntime.js +764 -411
  51. package/dist/debug/runtime/diagnostics/RaphDebug.cjs +1 -1
  52. package/dist/debug/runtime/diagnostics/RaphDebug.js +90 -100
  53. package/dist/debug/runtime/ownership/RaphEffectScope.cjs +1 -1
  54. package/dist/debug/runtime/ownership/RaphEffectScope.js +215 -82
  55. package/dist/debug/runtime/ownership/RaphNode.cjs +1 -1
  56. package/dist/debug/runtime/ownership/RaphNode.js +595 -136
  57. package/dist/debug/runtime/ownership/RaphScope.cjs +1 -1
  58. package/dist/debug/runtime/ownership/RaphScope.js +203 -68
  59. package/dist/debug/runtime/phases/RaphFrameLoop.cjs +1 -1
  60. package/dist/debug/runtime/phases/RaphFrameLoop.js +13 -17
  61. package/dist/debug/runtime/phases/RaphPhasePipeline.cjs +1 -1
  62. package/dist/debug/runtime/phases/RaphPhasePipeline.js +618 -357
  63. package/dist/debug/runtime/phases/RaphPhaseTaskRecord.cjs +1 -0
  64. package/dist/debug/runtime/phases/RaphPhaseTaskRecord.js +176 -0
  65. package/dist/debug/runtime/phases/RaphPhaseWatch.cjs +1 -0
  66. package/dist/debug/runtime/phases/RaphPhaseWatch.js +20 -0
  67. package/dist/debug/runtime/reactivity/PathHandle.cjs +1 -1
  68. package/dist/debug/runtime/reactivity/PathHandle.js +50 -60
  69. package/dist/debug/runtime/reactivity/RaphMetaSource.cjs +1 -1
  70. package/dist/debug/runtime/reactivity/RaphMetaSource.js +28 -32
  71. package/dist/debug/runtime/reactivity/RaphSelector.cjs +1 -0
  72. package/dist/debug/runtime/reactivity/RaphSelector.js +503 -0
  73. package/dist/debug/runtime/reactivity/RaphWorkGraph.cjs +1 -1
  74. package/dist/debug/runtime/reactivity/RaphWorkGraph.js +541 -379
  75. package/dist/debug/runtime/reactivity/RuntimeReactivity.cjs +1 -1
  76. package/dist/debug/runtime/reactivity/RuntimeReactivity.js +484 -90
  77. package/dist/debug/runtime/reactivity/RuntimeWatch.cjs +1 -1
  78. package/dist/debug/runtime/reactivity/RuntimeWatch.js +33 -44
  79. package/dist/debug/runtime/reactivity/disposal-sweep.utils.cjs +1 -0
  80. package/dist/debug/runtime/reactivity/disposal-sweep.utils.js +42 -0
  81. package/dist/entrypoints/runtime.d.ts +2 -1
  82. package/dist/machine-testing.cjs +1 -1
  83. package/dist/machine-testing.js +1 -1
  84. package/dist/machine.cjs +1 -1
  85. package/dist/machine.js +216 -231
  86. package/dist/path/RaphKernel.d.ts +24 -0
  87. package/dist/path/storage/PathEventHub.d.ts +14 -0
  88. package/dist/path/storage/PathStore.d.ts +4 -4
  89. package/dist/reactivity/disposal.d.ts +14 -0
  90. package/dist/reactivity/engine.d.ts +177 -4
  91. package/dist/reactivity/scope.d.ts +108 -30
  92. package/dist/runtime/RaphRuntime.d.ts +236 -17
  93. package/dist/runtime/ownership/RaphEffectScope.d.ts +70 -1
  94. package/dist/runtime/ownership/RaphNode.d.ts +276 -6
  95. package/dist/runtime/ownership/RaphScope.d.ts +144 -14
  96. package/dist/runtime/phases/RaphPhasePipeline.d.ts +202 -28
  97. package/dist/runtime/phases/RaphPhaseTaskRecord.d.ts +195 -0
  98. package/dist/runtime/phases/RaphPhaseWatch.d.ts +22 -0
  99. package/dist/runtime/phases/phase.types.d.ts +83 -4
  100. package/dist/runtime/reactivity/RaphSelector.d.ts +338 -0
  101. package/dist/runtime/reactivity/RaphWorkGraph.d.ts +163 -25
  102. package/dist/runtime/reactivity/RuntimeReactivity.d.ts +258 -10
  103. package/dist/runtime/reactivity/RuntimeWatch.d.ts +8 -8
  104. package/dist/runtime/reactivity/disposal-sweep.utils.d.ts +19 -0
  105. package/dist/runtime/reactivity/runtime-reactivity.types.d.ts +48 -3
  106. package/package.json +9 -1
  107. package/dist/core-ugchZNqC.cjs +0 -1
@@ -6,9 +6,11 @@ import { Disposer, ReadonlySignal, Signal, WritableComputedOptions } from '../re
6
6
  import { RaphDebugOptions, RaphMachineDebugRegistration, RaphRuntimeDebug, RaphTraceEventInput, RaphTraceKind } from './diagnostics/RaphDebug';
7
7
  import { DepGraph } from './ownership/parent-graph.types';
8
8
  import { NodeOptions, RaphNode } from './ownership/RaphNode';
9
- import { FrameLoopLease, RaphAggregateSource, RaphEffectOptions, RaphPhase, RaphPhaseEffect, RaphSchedulerMode, RaphStructureCause, RaphWatchOptions, RaphWatchSource } from './phases/phase.types';
9
+ import { FrameLoopLease, RaphAggregateSource, RaphEffectGroupOptions, RaphEffectGroupSlot, RaphEffectInitialMode, RaphEffectOptions, RaphPhase, RaphPhaseEffect, RaphSchedulerMode, RaphStructureCause, RaphWatchOptions, RaphWatchSource } from './phases/phase.types';
10
+ import { RaphPhaseTaskRecord } from './phases/RaphPhaseTaskRecord';
10
11
  import { RaphMetaSourceOptions, RaphMetaSource } from './reactivity/RaphMetaSource';
11
12
  import { RaphAggregate, RaphWorkGraph } from './reactivity/RaphWorkGraph';
13
+ import { RuntimeDisposalSweeper } from './reactivity/runtime-reactivity.types';
12
14
  import { RaphScope } from './ownership/RaphScope';
13
15
  import { PathHandle } from './reactivity/PathHandle';
14
16
  import { RuntimeReactivity } from './reactivity/RuntimeReactivity';
@@ -29,11 +31,18 @@ export interface RaphRuntimeConfiguration {
29
31
  readonly scheduler: RaphSchedulerMode;
30
32
  }
31
33
  export type RaphRuntimeMeta = Pick<RaphMeta, 'delete' | 'get' | 'has' | 'merge' | 'set'>;
32
- /** @internal */
34
+ /**
35
+ * Один phase binding в том виде, в котором его видит effect scope. Регистрацией
36
+ * является сама постоянная запись binding, поэтому её capabilities вызываются
37
+ * только с регистрацией в качестве receiver.
38
+ *
39
+ * @internal
40
+ */
33
41
  export interface RaphPausableRegistration {
34
- readonly dispose: Disposer;
35
- readonly pause: () => void;
36
- readonly resume: () => void;
42
+ readonly active: boolean;
43
+ readonly dispose: (this: RaphPausableRegistration) => void;
44
+ readonly pause: (this: RaphPausableRegistration) => void;
45
+ readonly resume: (this: RaphPausableRegistration) => void;
37
46
  }
38
47
  /** Isolated Runtime execution plane with phase-bound work only. */
39
48
  export declare class RaphRuntime {
@@ -46,8 +55,7 @@ export declare class RaphRuntime {
46
55
  private readonly _reactivity;
47
56
  private readonly _signalLifecycle;
48
57
  private readonly _workGraph;
49
- private readonly _frameTickWritable;
50
- private readonly _setFrameTick;
58
+ private readonly _frameTickSignal;
51
59
  private _pathHandles;
52
60
  private _meta;
53
61
  private _phases;
@@ -55,11 +63,17 @@ export declare class RaphRuntime {
55
63
  private _debug;
56
64
  private readonly _debugController;
57
65
  private _parentGraph;
58
- private readonly _owners;
66
+ private readonly _topOwners;
67
+ private _ownerRegistrations;
68
+ private _ownersReleased;
59
69
  private _batchDepth;
60
70
  private _mutationDepth;
61
71
  private _kernelBatchDepth;
62
72
  private _ownerDisposalDepth;
73
+ private readonly _disposingNodes;
74
+ private _ownerDisposals;
75
+ private _disposalSweepers;
76
+ private _nextDisposalSweep;
63
77
  private _actionDepth;
64
78
  private _actionCounter;
65
79
  private readonly _traceCauseStack;
@@ -98,12 +112,63 @@ export declare class RaphRuntime {
98
112
  computed<T>(options: WritableComputedOptions<T>, owner?: RaphScope): Signal<T>;
99
113
  /** Low-level adapter form. Prefer consumer.effect(). */
100
114
  effect(consumer: RaphScope, phaseInput: string, callback: RaphPhaseEffect, options?: RaphEffectOptions): Disposer;
101
- /** @internal */
102
- _effectRegistration(consumer: RaphScope, phaseInput: string, callback: RaphPhaseEffect, options?: RaphEffectOptions, startPaused?: boolean): RaphPausableRegistration;
115
+ /**
116
+ * Регистрирует один implicit phase effect. Возвращаемая регистрация является
117
+ * записью binding: она одновременно ресурс владельца, задача engine и элемент
118
+ * очереди pipeline, поэтому на effect больше ничего не выделяется. Тело
119
+ * записи engine у всех bindings графа одно — `RuntimeReactivity._phaseBody`:
120
+ * свой binding оно находит через engine, а не через собственную closure.
121
+ *
122
+ * При `taskless` тело вызывается без task: запись получает `TASK_TASKLESS`,
123
+ * общее тело не читает `record.task`, и frozen facade этого binding не
124
+ * создаётся, пока его не запросит `process` своей phase. Режим — бит поля
125
+ * `state`: запись от него не растёт.
126
+ *
127
+ * @internal
128
+ */
129
+ _effectRegistration(consumer: RaphScope, phaseInput: string, callback: RaphPhaseEffect, options?: RaphEffectOptions, startPaused?: boolean, taskless?: boolean, onExecutionFailure?: (error: unknown) => never, isExecutionCancelled?: () => boolean): RaphPausableRegistration;
130
+ /**
131
+ * Регистрирует группу из `count` implicit phase effects на одной записи
132
+ * binding. Каждый slot получает собственную запись графа engine, то есть
133
+ * собственный набор зависимостей и собственный признак invalidation, а
134
+ * запись binding и её место в очереди phase и в списке ресурсов владельца у
135
+ * группы одни. Тело записи engine у slots то же, что у всех bindings графа.
136
+ * Возвращаемая регистрация — эта запись; она же handle группы.
137
+ *
138
+ * Регистрация ничего не исполняет: каждый slot запускает `_startGroupSlot`.
139
+ * Запись входит в список владельца сразу, поэтому владелец освобождает
140
+ * группу после ресурсов, которые зарегистрируют тела её slots.
141
+ *
142
+ * @internal
143
+ */
144
+ _effectGroupRegistration(consumer: RaphScope, phaseInput: string, count: number, runSlot: RaphEffectGroupSlot, context: unknown, options?: RaphEffectGroupOptions, startPaused?: boolean): RaphPhaseTaskRecord;
145
+ /**
146
+ * Запускает один slot группы: планирует его запись графа, ставит запись
147
+ * группы в очередь и, при `initial: 'sync'`, выполняет flush. Шаги те же, что
148
+ * у регистрации одиночного implicit effect после создания его записи.
149
+ *
150
+ * Сбой внутри вызова останавливает только этот slot и бросается вызывающему,
151
+ * как сбой первой доставки откатывает регистрацию одиночного binding; группа
152
+ * и остальные её slots остаются. Группа, у которой остановлен последний slot,
153
+ * освобождается.
154
+ *
155
+ * Запуск на освобождённом владельце бросает `RaphDisposedError`, как
156
+ * `bindEffect()`: и когда владелец освобождён до вызова, и когда его
157
+ * освободила первая доставка внутри вызова, при любом scheduler. Молчит
158
+ * только запуск slot группы, освобождённой при живом владельце.
159
+ *
160
+ * @internal
161
+ */
162
+ _startGroupSlot(record: RaphPhaseTaskRecord, slot: number, initial: RaphEffectInitialMode, onExecutionFailure?: (error: unknown) => never): void;
103
163
  /** Low-level adapter form. Prefer consumer.watch(). */
104
164
  watch(consumer: RaphScope, source: RaphWatchSource, phaseInput: string, callback: RaphPhaseEffect, options?: RaphWatchOptions): Disposer;
105
- /** @internal */
106
- _watchRegistration(consumer: RaphScope, source: RaphWatchSource, phaseInput: string, callback: RaphPhaseEffect, options?: RaphWatchOptions, startPaused?: boolean): RaphPausableRegistration;
165
+ /**
166
+ * Регистрирует один explicit phase watch. Возвращаемая запись binding является
167
+ * pausable-регистрацией и одновременно ресурсом владельца этого watch.
168
+ *
169
+ * @internal
170
+ */
171
+ _watchRegistration(consumer: RaphScope, source: RaphWatchSource, phaseInput: string, callback: RaphPhaseEffect, options?: RaphWatchOptions, startPaused?: boolean, onExecutionFailure?: (error: unknown) => never, isExecutionCancelled?: () => boolean): RaphPhaseTaskRecord;
107
172
  aggregate(consumer: RaphScope, sources: readonly RaphAggregateSource[]): RaphAggregate;
108
173
  /** Creates a lazy root-owned metadata event source for phase watches. */
109
174
  metaSource(masks: DataPathDef | readonly DataPathDef[], options?: RaphMetaSourceOptions): RaphMetaSource;
@@ -120,11 +185,31 @@ export declare class RaphRuntime {
120
185
  /** Batches an internal reactive-only commit without opening an unused Kernel boundary. @internal */
121
186
  _batchReactive<T>(operation: () => T): T;
122
187
  private _batch;
188
+ /**
189
+ * Закрывает один уровень batch: внешний уровень очищает transient causes и
190
+ * запускает фазы. Бросает ошибку операции, ошибки закрытия либо все вместе;
191
+ * после успешной операции и закрытия возвращает управление.
192
+ */
193
+ private _closeBatch;
194
+ /**
195
+ * Исполняет тело action: `batch(() => _runUntracked(() => operation(...args)))`
196
+ * без closures и без промежуточных вызовов слоёв. Runtime, который один
197
+ * владеет своим Kernel без derived handles, metadata watchers и adapter,
198
+ * открывает границы reactive batch, Kernel и path batch явными вызовами и
199
+ * закрывает их в том же порядке и с теми же ошибками, что вложенные
200
+ * `batch()` этих слоёв. В любом другом состоянии исполняется сам `batch()`.
201
+ */
202
+ private _applyBatch;
123
203
  action<Args extends unknown[], Result>(operation: (...args: Args) => Result, owner?: RaphScope): (...args: Args) => Result;
124
204
  action<Args extends unknown[], Result>(name: string, operation: (...args: Args) => Result, owner?: RaphScope): (...args: Args) => Result;
125
205
  untracked<T>(operation: () => T): T;
126
206
  scope(id: string): RaphScope;
127
207
  node<TApi = void>(options: NodeOptions, setup?: (node: RaphNode) => TApi): RaphNode<TApi>;
208
+ /**
209
+ * Создаёт provisional node, выполняет setup и публикует результат; при ошибке
210
+ * setup откатывает node до выхода из границы mutation.
211
+ */
212
+ private _createCommittedNode;
128
213
  getNode(id: string): RaphNode | undefined;
129
214
  definePhases(phases: readonly RaphPhase[]): void;
130
215
  addPhase(phase: RaphPhase): void;
@@ -141,6 +226,21 @@ export declare class RaphRuntime {
141
226
  _onDisposed(listener: () => void): Disposer;
142
227
  /** @internal */
143
228
  _notifyNodeStructure(node: RaphNode, structure: RaphStructureCause, oldAncestors: readonly RaphNode[], newAncestors: readonly RaphNode[]): void;
229
+ /**
230
+ * Сообщает, может ли structural publication этой node дойти до подписчика;
231
+ * `false` позволяет не строить structure cause и списки ancestors.
232
+ *
233
+ * @internal
234
+ */
235
+ _hasNodeStructureDemand(node: RaphNode): boolean;
236
+ /**
237
+ * Сообщает, есть ли у Runtime хотя бы один подписчик на node: runtime-,
238
+ * subtree- или self-watcher. Пока он есть, node поддерживает выданный массив
239
+ * детей на месте, потому что structure cause берёт из него индексы.
240
+ *
241
+ * @internal
242
+ */
243
+ _hasNodeSubscribers(): boolean;
144
244
  /** @internal */
145
245
  _notifyNodeTouch(node: RaphNode, metadata?: unknown): void;
146
246
  /** @internal */
@@ -149,18 +249,84 @@ export declare class RaphRuntime {
149
249
  _releaseNode(node: RaphNode): void;
150
250
  /** @internal */
151
251
  _runNodeMutation<T>(operation: () => T): T;
252
+ /**
253
+ * Выполняет границу пустой node mutation без аллокаций: эквивалент
254
+ * `_runWrite(noop)` с тем же запросом исполнения и flush на внешней границе.
255
+ *
256
+ * @internal
257
+ */
258
+ _touchMutationBoundary(): void;
152
259
  /** @internal */
153
260
  _runPhaseTransition<T>(operation: () => T): T;
154
- /** @internal */
155
- _beginOwnerDisposal(): void;
261
+ /**
262
+ * Открывает границу освобождения. `node` передаёт только dispose самой node:
263
+ * Runtime помнит её до парного `_endOwnerDisposal`.
264
+ *
265
+ * @internal
266
+ */
267
+ _beginOwnerDisposal(node?: RaphNode): void;
156
268
  /** @internal */
157
269
  _endOwnerDisposal(): void;
270
+ /**
271
+ * Возвращает число владельцев, освобождённых этим Runtime за всё время.
272
+ *
273
+ * @internal
274
+ */
275
+ _ownerDisposalCount(): number;
276
+ /**
277
+ * Подключает участника уборки: Runtime вызовет его на первой внешней границе
278
+ * освобождения, к которой число освобождённых владельцев достигнет `due`.
279
+ * Подключённый участник остаётся в очереди, пока сам не откажется от
280
+ * следующего срока либо не будет отключён.
281
+ *
282
+ * @internal
283
+ */
284
+ _addDisposalSweeper(sweeper: RuntimeDisposalSweeper, due: number): void;
285
+ /**
286
+ * Отключает участника уборки; отключение неизвестного участника безопасно.
287
+ *
288
+ * @internal
289
+ */
290
+ _removeDisposalSweeper(sweeper: RuntimeDisposalSweeper): void;
291
+ /**
292
+ * Вызывает участников уборки, чей срок подошёл, и назначает ближайший
293
+ * следующий срок. Участник, чей срок не подошёл, вызова не получает:
294
+ * освобождение владельца стоит участникам работы, только когда подходит их
295
+ * собственный срок.
296
+ */
297
+ private _sweepAfterDisposals;
158
298
  /** @internal */
159
299
  _ownerDisposalActive(): boolean;
160
- /** @internal */
161
- _registerOwner(owner: RaphScope): void;
162
- /** @internal */
300
+ /**
301
+ * Учитывает нового владельца и возвращает его порядковый номер регистрации.
302
+ * Plain scope сразу входит в набор владельцев вне списков детей; node входит
303
+ * в него сама через `_addTopOwner`, и только если у неё нет parent.
304
+ *
305
+ * @internal
306
+ */
307
+ _registerOwner(owner: RaphScope): number;
308
+ /**
309
+ * Снимает владельца с учёта. Plain scope выходит и из набора владельцев вне
310
+ * списков детей; node без parent выходит из него сама через
311
+ * `_removeTopOwner`, а node с parent в нём не состоит.
312
+ *
313
+ * @internal
314
+ */
163
315
  _unregisterOwner(owner: RaphScope): void;
316
+ /**
317
+ * Вносит node без parent в набор владельцев вне списков детей.
318
+ *
319
+ * @internal
320
+ */
321
+ _addTopOwner(node: RaphNode): void;
322
+ /**
323
+ * Убирает node из набора владельцев вне списков детей: она освобождена либо
324
+ * получила parent. Повторный вызов и вызов после освобождения Runtime
325
+ * безопасны.
326
+ *
327
+ * @internal
328
+ */
329
+ _removeTopOwner(node: RaphNode): void;
164
330
  /** @internal */
165
331
  _assertOwnerRuntime(owner: RaphScope): void;
166
332
  /** @internal */
@@ -195,19 +361,72 @@ export declare class RaphRuntime {
195
361
  _recordTrace(event: RaphTraceEventInput): void;
196
362
  /** Наследует cause через outputs/tasks optional execution layers. @internal */
197
363
  _runWithTraceCause<T>(causeId: number | undefined, operation: () => T): T;
364
+ /**
365
+ * Выполняет единственную проверку binding: pipeline доверяет её результату.
366
+ */
198
367
  private _validatePhaseBinding;
368
+ /**
369
+ * Освобождает binding, регистрация которого не удалась, и повторно бросает
370
+ * причину сбоя; ошибка самого освобождения присоединяется к ней.
371
+ */
372
+ private _rollbackRegistration;
199
373
  private _createDebugSnapshot;
200
374
  private _createDebugTree;
201
375
  private _createDebugStats;
376
+ /**
377
+ * Возвращает число владельцев, которых Runtime числит живыми: зарегистрированных
378
+ * и ещё не снятых с учёта. После освобождения Runtime их нет.
379
+ */
380
+ private _liveOwnerCount;
381
+ /**
382
+ * Собирает всех владельцев, которых Runtime числит живыми. Владельцы вне
383
+ * списков детей идут в порядке регистрации, каждый — вместе с потомками по
384
+ * спискам детей. Node, чей dispose ещё исполняется, из списка parent уже
385
+ * вышла либо потеряла parent, который сбросил свой список: её и оставшихся
386
+ * у неё детей добавляют места границ освобождения.
387
+ */
388
+ private _collectOwners;
202
389
  private _releasePathHandle;
203
390
  private get _execution();
204
391
  private get _clock();
205
392
  private _tickFrameLoop;
393
+ /**
394
+ * Записывает frame signal в собственной границе записи, минуя политику
395
+ * actions: кадр продвигает сам Runtime.
396
+ */
397
+ private _setFrameTick;
206
398
  private _attachWritableComputed;
207
399
  private _own;
208
400
  private _runTracked;
209
401
  private _runUntracked;
210
402
  private _runWrite;
403
+ /**
404
+ * Открывает границу записи без closure; повторяет начало `_runWrite`.
405
+ *
406
+ * @internal
407
+ */
408
+ _enterWrite(): void;
409
+ /**
410
+ * Закрывает успешную запись, открытую `_enterWrite`; внешняя граница очищает
411
+ * transient causes и запускает фазы с теми же ошибками, что и `_runWrite`.
412
+ *
413
+ * @internal
414
+ */
415
+ _exitWrite(): void;
416
+ /**
417
+ * Закрывает запись после ошибки операции и возвращает ошибку для throw:
418
+ * исходную либо AggregateError, если упало и закрытие внешней границы.
419
+ *
420
+ * @internal
421
+ */
422
+ _failWrite(operationError: unknown): unknown;
423
+ /**
424
+ * Сообщает, что внешняя write-, batch-, Kernel- или disposal-граница ещё открыта.
425
+ * В этом состоянии оба шага `_finishExecutionBoundary` заведомо ничего не делают:
426
+ * transient causes очищаются и фазы запускаются только при нулевых глубинах.
427
+ */
428
+ private _executionBoundaryOpen;
429
+ /** Закрывает внешнюю границу; массив ошибок создаётся только при первой ошибке. */
211
430
  private _finishExecutionBoundary;
212
431
  private _clearTransientCausesIfSettled;
213
432
  private _requestExecution;
@@ -1,10 +1,12 @@
1
1
  import { Disposer } from '../../reactivity/types';
2
- import { RaphEffectOptions, RaphOwnerWatchSource, RaphPhaseEffect, RaphWatchOptions } from '../phases/phase.types';
2
+ import { RaphEffectGroup, RaphEffectGroupOptions, RaphEffectGroupSlot, RaphEffectOptions, RaphOwnerWatchSource, RaphPhaseBody, RaphPhaseEffect, RaphWatchOptions, RaphWatchSource } from '../phases/phase.types';
3
+ import { RaphRuntime } from '../RaphRuntime';
3
4
  import { RaphScope } from './RaphScope';
4
5
  /** Pauses phase deliveries without detaching dependencies or losing accumulated causes. */
5
6
  export declare class RaphEffectScope {
6
7
  private readonly _owner;
7
8
  private _registrations;
9
+ private _pruneAt;
8
10
  private _children;
9
11
  private _selfPaused;
10
12
  private _ancestorPauses;
@@ -16,13 +18,80 @@ export declare class RaphEffectScope {
16
18
  get disposed(): boolean;
17
19
  fork(owner: RaphScope): RaphEffectScope;
18
20
  effect(phase: string, callback: RaphPhaseEffect, options?: RaphEffectOptions): Disposer;
21
+ /**
22
+ * Регистрирует в этой группе phase effect без task и без disposer: тело
23
+ * вызывается без аргументов, а binding живёт до освобождения группы или её
24
+ * владельца. Pause и resume группы действуют на него так же, как на effect,
25
+ * зарегистрированный через `effect()`.
26
+ *
27
+ * Binding, зарегистрированный внутри тела другого effect, останавливает ещё и
28
+ * перезапуск этого effect. Остановленный binding больше не исполняется и не
29
+ * реагирует на pause и resume; группа забывает его не сразу, а когда число её
30
+ * регистраций удваивается, поэтому остановленных регистраций в группе не
31
+ * больше, чем действующих, либо меньше `PRUNE_FLOOR`.
32
+ */
33
+ bindEffect(phase: string, body: RaphPhaseBody, options?: RaphEffectOptions): void;
34
+ /**
35
+ * Регистрирует в этой группе регистраций группу из `count` phase effects на
36
+ * одном binding, как `owner.effectGroup()`: без task и без disposer, с
37
+ * отдельным набором зависимостей у каждого slot и с запуском slots через
38
+ * `start()` возвращённой группы. Pause и resume действуют на все slots
39
+ * сразу; slots, запущенные или изменившиеся за время pause, исполняются
40
+ * одной доставкой после resume. Binding живёт до освобождения этой группы
41
+ * регистраций или её владельца.
42
+ *
43
+ * Pause изнутри тела slot останавливает доставку: оставшиеся slots
44
+ * исполняются после resume, и причины прерванной доставки приходят в
45
+ * `causes` следующей целиком, вместе с причинами уже исполненных slots.
46
+ *
47
+ * Освобождение отличается от отдельных bindings этой же группы регистраций:
48
+ * slots останавливаются в порядке, обратном порядку номеров, а не в порядке
49
+ * регистрации, и несколько сбоев их cleanup приходят одним вложенным
50
+ * `AggregateError` с сообщением `[Raph] Effect group disposal failed.`.
51
+ *
52
+ * @typeParam Context — значение, которое получает тело каждого slot.
53
+ * @param phase Имя объявленной phase.
54
+ * @param count Число slots: целое от 1 до 4294967293, иначе `RangeError`.
55
+ * @param runSlot Тело slot: получает запуск с `context` и номером slot.
56
+ * @param context Значение, которое группа передаёт телу каждого slot.
57
+ * @param options `priority` task группы, как у `effect()`.
58
+ */
59
+ effectGroup<Context>(phase: string, count: number, runSlot: RaphEffectGroupSlot<Context>, context: Context, options?: RaphEffectGroupOptions): RaphEffectGroup;
19
60
  watch(source: RaphOwnerWatchSource, phase: string, callback: RaphPhaseEffect, options?: RaphWatchOptions): Disposer;
61
+ /**
62
+ * Внутренний путь renderer сохраняет pause ancestry и late-disposal tracking.
63
+ * Возвращаемый disposer renderer не использует; регистрация остаётся у scope.
64
+ * @internal
65
+ */
66
+ _registerEffect(phase: string, callback: RaphPhaseEffect, options: RaphEffectOptions, taskless: boolean, onExecutionFailure: (error: unknown) => never, isExecutionCancelled?: () => boolean): void;
67
+ /** @internal */
68
+ _registerWatch(source: RaphWatchSource, phase: string, callback: RaphPhaseEffect, options: RaphWatchOptions, onExecutionFailure: (error: unknown) => never, isExecutionCancelled?: () => boolean): void;
69
+ /** @internal */
70
+ _registerEffectGroup<Context>(phase: string, count: number, runSlot: RaphEffectGroupSlot<Context>, context: Context, options?: RaphEffectGroupOptions): ReturnType<RaphRuntime['_effectGroupRegistration']>;
20
71
  pause(): void;
21
72
  resume(): void;
22
73
  private _pause;
23
74
  private _resume;
24
75
  dispose(): void;
25
76
  private _add;
77
+ /**
78
+ * Вносит регистрацию в группу и возвращает её элемент либо `undefined`,
79
+ * когда группа уже освобождена. Disposer здесь не создаётся: его строит
80
+ * только `_add()`, поэтому `bindEffect()` обходится без closure.
81
+ */
82
+ private _track;
83
+ /**
84
+ * Забывает регистрации, которые уже остановлены не через disposer группы:
85
+ * binding, вложенный в тело другого effect, останавливает engine при
86
+ * перезапуске этого effect, а у `bindEffect()` нет disposer, который убрал бы
87
+ * его отсюда. Без этого группа держала бы тело каждого такого binding до
88
+ * собственного освобождения.
89
+ *
90
+ * Проход выполняется, когда число регистраций достигает порога, и ставит
91
+ * следующий порог вдвое выше числа оставшихся: цена регистрации остаётся
92
+ * постоянной в среднем.
93
+ */
94
+ private _prune;
26
95
  private _assertAlive;
27
96
  private _addChild;
28
97
  private _changeAncestorPause;