@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
@@ -1,44 +1,66 @@
1
- var y = Object.defineProperty;
2
- var b = (o, h, t) => h in o ? y(o, h, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[h] = t;
3
- var l = (o, h, t) => b(o, typeof h != "symbol" ? h + "" : h, t);
4
- import { RaphCrossRuntimeError as a } from "../errors.js";
5
- import { RaphScope as w } from "./RaphScope.js";
6
- import { throwDisposalErrors as v } from "./throwDisposalErrors.js";
7
- let g = 0;
8
- const _ = Symbol("RaphProvisionalNode");
9
- class c extends w {
10
- constructor(t, e = {}, i, r) {
11
- const s = i ?? (t instanceof c ? t.runtime : t ?? void 0);
1
+ import { throwDisposalFailure as S, unroutedDisposalFailure as u, combineDisposalFailures as w } from "../../reactivity/disposal.js";
2
+ import { RaphCrossRuntimeError as v } from "../errors.js";
3
+ import { RaphProducer as x } from "../reactivity/RaphWorkGraph.js";
4
+ import { RaphScope as A } from "./RaphScope.js";
5
+ let O = 0;
6
+ const C = Symbol("RaphProvisionalNode"), N = Object.freeze({}), I = "[Raph] Child order must contain every direct child exactly once.", f = "[Raph] Child order can contain only direct children of the node.";
7
+ let p, c;
8
+ class o extends A {
9
+ #i;
10
+ constructor(i, t = {}, e, r) {
11
+ const s = e ?? (i instanceof o ? i.runtime : i ?? void 0);
12
12
  if (s === void 0)
13
13
  throw new Error("[RaphNode] A root node requires an explicit runtime.");
14
- const n = t instanceof c ? t : (t == null ? void 0 : t.root) ?? null;
14
+ const n = i instanceof o ? i : i?.root ?? null;
15
15
  if (n !== null && n.runtime !== s)
16
- throw new a("[Raph] Parent belongs to another runtime.");
17
- n == null || n._assertAlive();
18
- const d = e.priority ?? 0;
19
- p(d);
20
- super(e.id ?? `node-${g++}`, s);
21
- l(this, "priority");
22
- l(this, "_parent");
23
- l(this, "_children", []);
24
- l(this, "_published");
25
- l(this, "api");
26
- l(this, "meta");
27
- l(this, "type");
28
- /** Distinguishes a subtree granule from the node's self granule. @internal */
29
- l(this, "_subtreeSourceIdentity", Object.freeze({}));
30
- this.priority = d, this._parent = n, this.meta = { ...e.meta }, this.type = e.type ?? "default", this.api = Object.freeze({});
31
- const f = r === _;
32
- if (this._published = n === null || !f && n._published, n !== null) {
33
- const m = n._children.length;
34
- if (n._children.push(this), !this._published)
16
+ throw new v("[Raph] Parent belongs to another runtime.");
17
+ const l = t.priority ?? 0, h = t.id, a = t.meta, y = a === void 0 ? void 0 : { ...a }, m = t.type ?? "default";
18
+ n?._assertAlive(), b(l), super(h ?? O++, s);
19
+ const g = r === C;
20
+ if (this.priority = l, this._parent = n, this._prevSibling = null, this._nextSibling = null, this._firstChild = null, this._lastChild = null, this._childCount = 0, this._childArray = void 0, this._published = n === null || !g && n._published, this.#i = N, new.target !== o && Object.defineProperty(this, "api", {
21
+ configurable: !0,
22
+ enumerable: !0,
23
+ value: this.#i,
24
+ writable: !0
25
+ }), this._meta = y, this.type = m, this._subtreeIdentity = void 0, n !== null) {
26
+ if (n._appendChild(this), !this._published)
35
27
  return;
36
- s._notifyNodeStructure(this, {
28
+ s._hasNodeStructureDemand(this) ? s._notifyNodeStructure(this, {
37
29
  node: this,
38
- newIndex: m,
30
+ newIndex: n._childCount - 1,
39
31
  newParent: n
40
- }, [], u(this)), this._assertAlive();
41
- }
32
+ }, [], d(this)) : s._touchMutationBoundary(), this._assertAlive();
33
+ } else
34
+ s._addTopOwner(this);
35
+ }
36
+ /**
37
+ * Возвращает id; номер id по умолчанию превращается в `node-N` при первом чтении.
38
+ */
39
+ get id() {
40
+ const i = this._id;
41
+ return typeof i == "string" ? i : this._id = `node-${i}`;
42
+ }
43
+ /**
44
+ * Возвращает изменяемую metadata node; объект создаётся при первом чтении.
45
+ */
46
+ get meta() {
47
+ return this._meta ??= {};
48
+ }
49
+ set meta(i) {
50
+ this._meta = i;
51
+ }
52
+ /**
53
+ * Возвращает api, зафиксированный после setup; присваивание снаружи запрещено.
54
+ */
55
+ get api() {
56
+ return this.#i;
57
+ }
58
+ /**
59
+ * Отличает subtree granule от self granule; identity создаётся по запросу.
60
+ * @internal
61
+ */
62
+ get _subtreeSourceIdentity() {
63
+ return this._subtreeIdentity ??= Object.freeze({});
42
64
  }
43
65
  get node() {
44
66
  return this;
@@ -46,118 +68,244 @@ class c extends w {
46
68
  get parent() {
47
69
  return this._parent;
48
70
  }
71
+ /**
72
+ * Возвращает прямых детей в их порядке. Массив действителен до следующей
73
+ * структурной mutation этой node; после неё порядок даёт новое чтение.
74
+ *
75
+ * Добавление в конец, удаление последнего child и `reorderChildren`
76
+ * обновляют уже выданный массив на месте. После удаления любого другого
77
+ * child — первого или из середины — выданный массив либо остаётся прежним, и
78
+ * следующее чтение строит новый, либо обновляется на месте — второе
79
+ * происходит, пока у Runtime есть подписчик на node.
80
+ *
81
+ * `moveChild` и `_swapChildren` следуют тому же правилу, что и удаление не
82
+ * последнего child: без подписчика на node выданный массив остаётся прежним,
83
+ * с подписчиком получает новый порядок на месте. `_disposeChildren` забывает
84
+ * выданный массив, если набор начинается с первого child списка: массив
85
+ * хранит состав на начало удаления. Набор, который начинается с другого
86
+ * child, следует правилу отдельных удалений.
87
+ *
88
+ * Собственный dispose node выданный массив не обновляет: пока node удаляет
89
+ * своих детей, он хранит их состав на начало удаления, а после удаления
90
+ * последнего child становится пустым. Оставшихся детей в это время даёт
91
+ * новое чтение; выданный им массив остаётся массивом node до конца удаления:
92
+ * дети выходят из него на месте и при отсутствии подписчика на node, а после
93
+ * последнего child он тоже пуст.
94
+ */
49
95
  get children() {
50
- return this._children;
96
+ return this._childArray ?? this._materializeChildren();
51
97
  }
52
- addChild(t) {
53
- if (this._assertAlive(), t._assertAlive(), t.runtime !== this.runtime)
54
- throw new a("[Raph] Child belongs to another runtime.");
55
- if (this === t)
98
+ addChild(i) {
99
+ if (this._assertAlive(), i._assertAlive(), i.runtime !== this.runtime)
100
+ throw new v("[Raph] Child belongs to another runtime.");
101
+ if (this === i)
56
102
  throw new Error("[Raph] A node cannot become its own ancestor.");
57
- if (!t._published || !this._published)
103
+ if (!i._published || !this._published)
58
104
  throw new Error("[Raph] A provisional node cannot be reparented before setup commits.");
59
- for (let e = this; e !== null; e = e.parent)
60
- if (e === t)
105
+ for (let t = this; t !== null; t = t.parent)
106
+ if (t === i)
61
107
  throw new Error("[Raph] A node cannot become its own ancestor.");
62
- return t.parent === this ? !0 : this.runtime._runNodeMutation(() => {
63
- this.runtime._assertNodeReparentAllowed(t, this);
64
- const e = u(t), i = t._parent, r = i == null ? void 0 : i._children.indexOf(t);
65
- i !== null && r !== void 0 && r >= 0 && i._children.splice(r, 1), t._parent = this;
66
- const s = this._children.length;
67
- return this._children.push(t), this.runtime._notifyNodeStructure(t, {
68
- node: t,
69
- ...i === null ? {} : { oldParent: i },
70
- ...r === void 0 || r < 0 ? {} : { oldIndex: r },
108
+ return i.parent === this ? !0 : this.runtime._runNodeMutation(() => {
109
+ const t = this.runtime;
110
+ t._assertNodeReparentAllowed(i, this);
111
+ const e = i._parent;
112
+ if (!t._hasNodeStructureDemand(i))
113
+ return e !== null && i._unlinkFrom(e, -1), i._parent = this, this._appendChild(i), e === null && t._removeTopOwner(i), !0;
114
+ const r = d(i), s = e === null ? -1 : i._indexIn(e);
115
+ e !== null && i._unlinkFrom(e, s), i._parent = this;
116
+ const n = this._childCount;
117
+ return this._appendChild(i), e === null && t._removeTopOwner(i), t._notifyNodeStructure(i, {
118
+ node: i,
119
+ ...e === null ? {} : { oldParent: e },
120
+ ...s < 0 ? {} : { oldIndex: s },
71
121
  newParent: this,
72
- newIndex: s
73
- }, e, u(t)), !0;
122
+ newIndex: n
123
+ }, r, d(i)), !0;
74
124
  });
75
125
  }
76
- reorderChildren(t) {
77
- if (this._assertAlive(), t.length !== this._children.length || new Set(t).size !== t.length)
78
- throw new Error("[Raph] Child order must contain every direct child exactly once.");
79
- for (const e of t)
80
- if (e._assertAlive(), e._parent !== this)
81
- throw new Error("[Raph] Child order can contain only direct children of the node.");
82
- this.runtime._runNodeMutation(() => {
83
- const e = new Map(this._children.map((i, r) => [i, r]));
84
- this._children.splice(0, this._children.length, ...t);
85
- for (let i = 0; i < t.length; i++) {
86
- const r = t[i], s = e.get(r);
87
- if (s === i)
88
- continue;
89
- const n = u(r);
90
- this.runtime._notifyNodeStructure(r, {
91
- node: r,
92
- oldParent: this,
93
- newParent: this,
94
- oldIndex: s,
95
- newIndex: i
96
- }, n, n);
126
+ /**
127
+ * Ставит прямых детей в порядок `nodes`: в нём каждый прямой child ровно
128
+ * один раз. Без подписчика на node порядок проверяется и применяется по
129
+ * связям между siblings, без Set и Map.
130
+ *
131
+ * Каждый элемент `nodes` читается один раз, до проверки. Чтение, которое само
132
+ * меняет дерево — элемент Proxy либо accessor, — не оставляет списки в
133
+ * промежуточном состоянии: порядок проверяется по составу детей после чтения.
134
+ */
135
+ reorderChildren(i) {
136
+ this._assertAlive(), this._applyChildOrder(i) || this._rejectChildOrder(i);
137
+ }
138
+ /**
139
+ * Ставит прямого child перед прямым child `before` либо в конец списка, если
140
+ * `before === null`. Без подписчика на node меняются только связи самого
141
+ * child и его соседей: цена не зависит от числа детей. С подписчиком каждый
142
+ * child, чей индекс изменился, получает тот же structure cause, что и после
143
+ * `reorderChildren` с итоговым порядком.
144
+ */
145
+ moveChild(i, t) {
146
+ if (this._assertAlive(), i._assertAlive(), t !== null && t._assertAlive(), i._parent !== this || t !== null && t._parent !== this)
147
+ throw new Error(f);
148
+ const e = this.runtime;
149
+ if (i === t || i._nextSibling === t) {
150
+ e._touchMutationBoundary();
151
+ return;
152
+ }
153
+ const r = e._hasNodeSubscribers() ? this._indexChildren() : void 0;
154
+ if (this._relinkBefore(i, t), r !== void 0) {
155
+ this._publishChildOrder(r);
156
+ return;
157
+ }
158
+ this._childArray = void 0, e._touchMutationBoundary();
159
+ }
160
+ /**
161
+ * Меняет местами двух прямых детей. Без подписчика на node правятся только
162
+ * связи этих детей и их соседей; с подписчиком оба child получают те же
163
+ * structure causes, что и после `reorderChildren` с итоговым порядком.
164
+ *
165
+ * @internal
166
+ */
167
+ _swapChildren(i, t) {
168
+ if (this._assertAlive(), i._assertAlive(), t._assertAlive(), i._parent !== this || t._parent !== this)
169
+ throw new Error(f);
170
+ const e = this.runtime;
171
+ if (i === t) {
172
+ e._touchMutationBoundary();
173
+ return;
174
+ }
175
+ const r = e._hasNodeSubscribers() ? this._indexChildren() : void 0, s = i._nextSibling, n = t._nextSibling;
176
+ if (s === t ? this._relinkBefore(t, i) : n === i ? this._relinkBefore(i, t) : (this._relinkBefore(i, n), this._relinkBefore(t, s)), r !== void 0) {
177
+ this._publishChildOrder(r);
178
+ return;
179
+ }
180
+ this._childArray = void 0, e._touchMutationBoundary();
181
+ }
182
+ _disposeChildren(i, t = 0, e = i === void 0 ? 0 : i.length) {
183
+ let r = i;
184
+ if (r === void 0 && (r = this._childArray ?? this._collectChildren(), e = r.length), t >= e)
185
+ return;
186
+ const s = this._childArray;
187
+ s !== void 0 && (s === r || this._firstChild === r[t].node) && (this._childArray = void 0);
188
+ const n = this.runtime;
189
+ let l;
190
+ n._beginOwnerDisposal();
191
+ for (let h = t; h < e; h++)
192
+ try {
193
+ r[h].node.dispose();
194
+ } catch (a) {
195
+ (l ??= []).push(a);
97
196
  }
98
- });
197
+ try {
198
+ n._endOwnerDisposal();
199
+ } catch (h) {
200
+ (l ??= []).push(h);
201
+ }
202
+ return l;
99
203
  }
100
- options(t) {
101
- this._assertAlive(), t.meta !== void 0 && (this.meta = { ...t.meta }), t.priority !== void 0 && (p(t.priority), this.priority = t.priority), t.type !== void 0 && (this.type = t.type), this.touch(Object.freeze({ options: Object.freeze({ ...t }) }));
204
+ options(i) {
205
+ this._assertAlive(), i.meta !== void 0 && (this._meta = { ...i.meta }), i.priority !== void 0 && (b(i.priority), this.priority = i.priority), i.type !== void 0 && (this.type = i.type), this.touch(Object.freeze({ options: Object.freeze({ ...i }) }));
102
206
  }
103
207
  /** Invalidates coarse self/subtree/runtime granules for non-reactive state. */
104
- touch(t) {
105
- this._assertAlive(), this.runtime._runNodeMutation(() => this.runtime._notifyNodeTouch(this, t));
208
+ touch(i) {
209
+ this._assertAlive(), this.runtime._runNodeMutation(() => this.runtime._notifyNodeTouch(this, i));
106
210
  }
107
211
  remove() {
108
212
  this.dispose();
109
213
  }
110
214
  dispose() {
215
+ S(c.call(this));
216
+ }
217
+ /** Calls actual public dispatch once; only native disposal can return provenance. @internal */
218
+ _disposeForOwner() {
219
+ try {
220
+ const i = this.dispose;
221
+ if (i === p)
222
+ return c.call(this);
223
+ i.call(this);
224
+ return;
225
+ } catch (i) {
226
+ return u(i);
227
+ }
228
+ }
229
+ /** Result of this exact framework call, without changing raw public disposal. @internal */
230
+ _disposeWithOutcome() {
111
231
  if (this._disposed || this._disposing)
112
232
  return;
113
- this._disposing = !0, this.runtime._beginOwnerDisposal();
114
- const t = [];
233
+ this._disposing = !0;
234
+ const i = this.runtime;
235
+ i._beginOwnerDisposal(this);
236
+ let t;
115
237
  try {
116
- for (const s of [...this._children])
117
- try {
118
- s.dispose();
119
- } catch (n) {
120
- t.push(n);
238
+ if (this._firstChild !== null) {
239
+ const r = this._takeChildSnapshot();
240
+ for (let s = 0; s < r.length; s++) {
241
+ const n = r[s];
242
+ try {
243
+ const l = n.dispose;
244
+ if (l === p) {
245
+ const h = c.call(n);
246
+ h !== void 0 && (t ??= []).push(h);
247
+ } else
248
+ l.call(n);
249
+ } catch (l) {
250
+ (t ??= []).push(u(l));
251
+ }
121
252
  }
122
- this._children.length = 0;
123
- const e = this._parent, i = u(this), r = e == null ? void 0 : e._children.indexOf(this);
124
- if (e !== null && r !== void 0 && r >= 0 && e._children.splice(r, 1), this._parent = null, this._published)
253
+ this._resetChildList(r);
254
+ }
255
+ const e = this._parent;
256
+ if (this._published && i._hasNodeStructureDemand(this)) {
257
+ const r = d(this), s = e === null ? -1 : this._indexIn(e);
258
+ e !== null && (this._unlinkFrom(e, s), this._parent = null);
125
259
  try {
126
- this.runtime._notifyNodeStructure(this, {
260
+ i._notifyNodeStructure(this, {
127
261
  node: this,
128
262
  ...e === null ? {} : { oldParent: e },
129
- ...r === void 0 || r < 0 ? {} : { oldIndex: r }
130
- }, i, []);
131
- } catch (s) {
132
- t.push(s);
263
+ ...s < 0 ? {} : { oldIndex: s }
264
+ }, r, []);
265
+ } catch (n) {
266
+ (t ??= []).push(u(n));
267
+ }
268
+ } else if (e !== null && (this._unlinkFrom(e, -1), this._parent = null), this._published)
269
+ try {
270
+ i._touchMutationBoundary();
271
+ } catch (r) {
272
+ (t ??= []).push(u(r));
133
273
  }
134
274
  try {
135
- super.dispose();
136
- } catch (s) {
137
- t.push(s);
275
+ const r = super._disposeScopeForOwner(super.dispose);
276
+ r !== void 0 && (t ??= []).push(r);
277
+ } catch (r) {
278
+ (t ??= []).push(u(r));
138
279
  }
139
- this._published = !1;
280
+ e === null && i._removeTopOwner(this), this._published = !1;
140
281
  try {
141
- this.runtime._releaseNode(this);
142
- } catch (s) {
143
- t.push(s);
282
+ i._releaseNode(this);
283
+ } catch (r) {
284
+ (t ??= []).push(u(r));
144
285
  }
145
286
  } finally {
146
287
  try {
147
- this.runtime._endOwnerDisposal();
288
+ i._endOwnerDisposal();
148
289
  } catch (e) {
149
- t.push(e);
290
+ (t ??= []).push(u(e));
150
291
  }
151
292
  }
152
- v(t, `[Raph] Node "${this.id}" disposal failed.`);
293
+ if (t !== void 0)
294
+ return w(t, `[Raph] Node "${this.id}" disposal failed.`);
153
295
  }
154
- /** @internal */
155
- _setApi(t) {
156
- const e = typeof t == "object" && t !== null ? Object.freeze(t) : t;
157
- Object.defineProperty(this, "api", {
296
+ /**
297
+ * Фиксирует api после setup; object api замораживается, как и раньше.
298
+ * Исключение — Runtime signal, возвращённый как api: значение, запись графа
299
+ * и связи подписчиков лежат в его собственных полях, поэтому заморозка
300
+ * лишила бы его записи, отслеживаемого чтения, watch и освобождения вместе
301
+ * с владельцем.
302
+ * @internal
303
+ */
304
+ _setApi(i) {
305
+ this.#i = typeof i == "object" && i !== null && !(i instanceof x) ? Object.freeze(i) : i, Object.hasOwn(this, "api") && Object.defineProperty(this, "api", {
158
306
  configurable: !1,
159
307
  enumerable: !0,
160
- value: e,
308
+ value: this.#i,
161
309
  writable: !1
162
310
  });
163
311
  }
@@ -165,42 +313,353 @@ class c extends w {
165
313
  _publishCreation() {
166
314
  if (this._published)
167
315
  return;
168
- const t = this._parent;
169
- if (t === null || !t._published)
170
- return;
171
- this._published = !0;
172
- const e = t._children.indexOf(this);
173
- try {
174
- this.runtime._notifyNodeStructure(this, {
175
- node: this,
176
- newIndex: e,
177
- newParent: t
178
- }, [], u(this));
179
- for (const i of this._children)
180
- i._publishCreation();
181
- } catch (i) {
182
- throw this._published = !1, i;
316
+ const i = this._parent;
317
+ if (!(i === null || !i._published)) {
318
+ this._published = !0;
319
+ try {
320
+ const t = this.runtime;
321
+ t._hasNodeStructureDemand(this) ? t._notifyNodeStructure(this, {
322
+ node: this,
323
+ newIndex: this._indexIn(i),
324
+ newParent: i
325
+ }, [], d(this)) : t._touchMutationBoundary();
326
+ for (let e = this._firstChild; e !== null; e = e._nextSibling)
327
+ e._publishCreation();
328
+ } catch (t) {
329
+ throw this._published = !1, t;
330
+ }
183
331
  }
184
332
  }
185
333
  /** @internal */
186
334
  _isPublished() {
187
335
  return this._published;
188
336
  }
337
+ /**
338
+ * Сообщает, стоит ли node в списке детей своего parent. Node без parent и
339
+ * node, чей parent уже сбросил свой список, в нём не стоят.
340
+ *
341
+ * @internal
342
+ */
343
+ _isLinked() {
344
+ const i = this._parent;
345
+ return i !== null && (this._prevSibling !== null || i._firstChild === this);
346
+ }
347
+ /**
348
+ * Добавляет в `into` всех потомков node по связям списков детей: каждый
349
+ * child сразу за своим parent, дети — в порядке списка. Обход не строит
350
+ * массивы `children` и не зависит от глубины стека.
351
+ *
352
+ * @internal
353
+ */
354
+ _collectDescendants(i) {
355
+ let t = this;
356
+ for (; ; ) {
357
+ let e = t._firstChild;
358
+ for (; e === null; ) {
359
+ if (t === this)
360
+ return;
361
+ e = t._nextSibling, e === null && (t = t._parent);
362
+ }
363
+ t = e, i.push(t);
364
+ }
365
+ }
366
+ /**
367
+ * Прибавляет к `totals` число ресурсов и sources самой node и всех её
368
+ * потомков. Обход тот же, что у `_collectDescendants`, но владельцев он не
369
+ * собирает: подсчёт для diagnostics не выделяет память по числу владельцев.
370
+ *
371
+ * @internal
372
+ */
373
+ _countSubtree(i) {
374
+ let t = this;
375
+ for (; ; ) {
376
+ i.resources += t._debugResourceCount(), i.sources += t._debugSourceCount();
377
+ let e = t._firstChild;
378
+ for (; e === null; ) {
379
+ if (t === this)
380
+ return;
381
+ e = t._nextSibling, e === null && (t = t._parent);
382
+ }
383
+ t = e;
384
+ }
385
+ }
386
+ /**
387
+ * Ищет node по id в своём поддереве. Порядок обхода прежний: сама node,
388
+ * затем дети от последнего к первому, каждый вместе со своим поддеревом.
389
+ *
390
+ * @internal
391
+ */
392
+ _findNode(i) {
393
+ let t = this;
394
+ for (; ; ) {
395
+ if (t.id === i)
396
+ return t;
397
+ let e = t._lastChild;
398
+ for (; e === null; ) {
399
+ if (t === this)
400
+ return;
401
+ e = t._prevSibling, e === null && (t = t._parent);
402
+ }
403
+ t = e;
404
+ }
405
+ }
406
+ /**
407
+ * Применяет порядок детей `nodes`. Возвращает `false` и оставляет список
408
+ * прежним, если `nodes` не содержит каждого живого прямого child ровно один
409
+ * раз. Прежние индексы собираются только при подписчике на node: без него
410
+ * structure cause никто не получит.
411
+ */
412
+ _applyChildOrder(i) {
413
+ const t = i.length;
414
+ if (t !== this._childCount)
415
+ return !1;
416
+ const e = [];
417
+ for (let l = 0; l < t; l++)
418
+ e.push(i[l]);
419
+ if (t !== this._childCount)
420
+ return !1;
421
+ const r = this.runtime, s = r._hasNodeSubscribers() ? this._indexChildren() : void 0;
422
+ if (!this._relinkChildren(e))
423
+ return !1;
424
+ const n = this._childArray;
425
+ if (n !== void 0 && n !== i)
426
+ for (let l = 0; l < t; l++)
427
+ n[l] = e[l];
428
+ return s === void 0 ? r._touchMutationBoundary() : this._notifyChildOrder(e, s), !0;
429
+ }
430
+ /**
431
+ * Проверяет порядок и переставляет связи за три прохода без Set и Map.
432
+ * Сначала каждый child списка получает метку: его `_prevSibling` указывает на
433
+ * parent, чего у прямого child не бывает. Затем метка снимается у каждой node
434
+ * из `nodes`: node без метки — чужая, удаляемая либо повторная. При отказе
435
+ * и при ошибке чтения `nodes` связи `_prevSibling` восстанавливаются по
436
+ * нетронутым `_nextSibling`.
437
+ *
438
+ * `nodes` — собственная копия порядка: её чтение не исполняет чужой код, и
439
+ * между расстановкой меток и их снятием дерево никто не меняет.
440
+ */
441
+ _relinkChildren(i) {
442
+ for (let n = this._firstChild; n !== null; n = n._nextSibling)
443
+ n._prevSibling = this;
444
+ const t = i.length;
445
+ let e = null, r = 0;
446
+ try {
447
+ for (; r < t; r++) {
448
+ const n = i[r];
449
+ if (n?._parent !== this || n._prevSibling !== this || n._disposing)
450
+ break;
451
+ n._prevSibling = e, e = n;
452
+ }
453
+ } finally {
454
+ if (r !== t) {
455
+ let n = null;
456
+ for (let l = this._firstChild; l !== null; l = l._nextSibling)
457
+ l._prevSibling = n, n = l;
458
+ }
459
+ }
460
+ if (r !== t)
461
+ return !1;
462
+ let s = null;
463
+ for (let n = e; n !== null; n = n._prevSibling)
464
+ n._nextSibling = s, s = n;
465
+ return this._firstChild = s, this._lastChild = e, !0;
466
+ }
467
+ /**
468
+ * Сообщает причину отказа порядка `nodes` теми же ошибками и в том же
469
+ * порядке, что и прежняя проверка; Set нужен только здесь.
470
+ */
471
+ _rejectChildOrder(i) {
472
+ if (i.length === this._childCount && new Set(i).size === i.length) {
473
+ for (const t of i)
474
+ if (t._assertAlive(), t._parent !== this)
475
+ throw new Error(f);
476
+ }
477
+ throw new Error(I);
478
+ }
479
+ /**
480
+ * Запоминает индекс каждого child до перестановки; нужен только для
481
+ * structure causes.
482
+ */
483
+ _indexChildren() {
484
+ const i = /* @__PURE__ */ new Map();
485
+ let t = 0;
486
+ for (let e = this._firstChild; e !== null; e = e._nextSibling)
487
+ i.set(e, t++);
488
+ return i;
489
+ }
490
+ /**
491
+ * Завершает перестановку связей при подписчике на node: массив детей
492
+ * получает новый порядок на месте либо строится, и каждый child со
493
+ * сменившимся индексом получает structure cause.
494
+ */
495
+ _publishChildOrder(i) {
496
+ let t = this._childArray;
497
+ if (t === void 0)
498
+ t = this._materializeChildren();
499
+ else {
500
+ let e = 0;
501
+ for (let r = this._firstChild; r !== null; r = r._nextSibling)
502
+ t[e++] = r;
503
+ }
504
+ this._notifyChildOrder(t, i);
505
+ }
506
+ /**
507
+ * Публикует structure cause каждому child, чей индекс изменился, в новом
508
+ * порядке детей и одной границей mutation.
509
+ */
510
+ _notifyChildOrder(i, t) {
511
+ const e = this.runtime;
512
+ e._runNodeMutation(() => {
513
+ for (let r = 0; r < i.length; r++) {
514
+ const s = i[r], n = t.get(s);
515
+ if (n === r)
516
+ continue;
517
+ const l = d(s);
518
+ e._notifyNodeStructure(s, {
519
+ node: s,
520
+ oldParent: this,
521
+ newParent: this,
522
+ oldIndex: n,
523
+ newIndex: r
524
+ }, l, l);
525
+ }
526
+ });
527
+ }
528
+ /**
529
+ * Переставляет child перед `before` либо в конец списка, меняя только связи
530
+ * child и его соседей. Вызывающий гарантирует, что оба — дети этой node и
531
+ * что child ещё не стоит перед `before`.
532
+ */
533
+ _relinkBefore(i, t) {
534
+ const e = i._prevSibling, r = i._nextSibling;
535
+ e === null ? this._firstChild = r : e._nextSibling = r, r === null ? this._lastChild = e : r._prevSibling = e;
536
+ const s = t === null ? this._lastChild : t._prevSibling;
537
+ i._prevSibling = s, i._nextSibling = t, s === null ? this._firstChild = i : s._nextSibling = i, t === null ? this._lastChild = i : t._prevSibling = i;
538
+ }
539
+ /**
540
+ * Строит массив детей по связям и запоминает его для следующих чтений.
541
+ */
542
+ _materializeChildren() {
543
+ return this._childArray = this._collectChildren();
544
+ }
545
+ /**
546
+ * Собирает детей по связям в новый массив, не запоминая его.
547
+ */
548
+ _collectChildren() {
549
+ const i = [];
550
+ for (let t = this._firstChild; t !== null; t = t._nextSibling)
551
+ i.push(t);
552
+ return i;
553
+ }
554
+ /**
555
+ * Очищает и забывает выданный массив детей, если он есть.
556
+ */
557
+ _clearChildArray() {
558
+ const i = this._childArray;
559
+ i !== void 0 && (i.length = 0, this._childArray = void 0);
560
+ }
561
+ /**
562
+ * Добавляет child в конец списка; уже выданный массив получает его через push.
563
+ */
564
+ _appendChild(i) {
565
+ const t = this._lastChild;
566
+ i._prevSibling = t, t === null ? this._firstChild = i : t._nextSibling = i, this._lastChild = i, this._childCount++;
567
+ const e = this._childArray;
568
+ e !== void 0 && e.push(i);
569
+ }
570
+ /**
571
+ * Возвращает позицию node среди детей `parent` либо -1, если `parent` уже
572
+ * сбросил свой список и node в нём не состоит. Нужна только для structure
573
+ * cause. Первый и последний child определяются по связям, остальные — через
574
+ * `indexOf` по массиву детей, как и раньше; массив строится один раз и затем
575
+ * поддерживается, поэтому обход связей на каждый запрос не повторяется.
576
+ */
577
+ _indexIn(i) {
578
+ return this._prevSibling === null ? i._firstChild === this ? 0 : -1 : i._lastChild === this ? i._childCount - 1 : (i._childArray ?? i._materializeChildren()).indexOf(this);
579
+ }
580
+ /**
581
+ * Вынимает node из списка `parent` и обнуляет её связи, чтобы удержанная node
582
+ * не удерживала соседей. Связи правятся за постоянное время.
583
+ *
584
+ * Уже выданный массив теряет последний child через pop. Любой другой child —
585
+ * первый или из середины — вырезается на месте, только если его `index`
586
+ * известен (>= 0) либо у Runtime есть подписчик на node: тогда массив ещё
587
+ * понадобится для индексов и перестраивать его по связям после каждого
588
+ * удаления дороже. Иначе массив не правится, а отбрасывается, и следующее
589
+ * чтение `children` строит новый: очистка списка от первого child к
590
+ * последнему не сдвигает массив на каждое удаление.
591
+ *
592
+ * Пока parent удаляет собственных детей, массив не отбрасывается: его мог
593
+ * запросить только cleanup уже удаляемого child, и `_resetChildList` обязан
594
+ * очистить именно его. Отброшенный массив остался бы у cleanup с удалёнными
595
+ * детьми внутри.
596
+ */
597
+ _unlinkFrom(i, t) {
598
+ const e = this._prevSibling, r = this._nextSibling;
599
+ if (e === null) {
600
+ if (i._firstChild !== this)
601
+ return;
602
+ i._firstChild = r;
603
+ } else
604
+ e._nextSibling = r, this._prevSibling = null;
605
+ r === null ? i._lastChild = e : (r._prevSibling = e, this._nextSibling = null), i._childCount--;
606
+ const s = i._childArray;
607
+ if (s !== void 0)
608
+ if (r === null)
609
+ s.pop();
610
+ else if (t < 0 && !i._disposing && !this.runtime._hasNodeSubscribers())
611
+ i._childArray = void 0;
612
+ else if (e === null)
613
+ s.shift();
614
+ else {
615
+ const n = t >= 0 ? t : s.indexOf(this);
616
+ n >= 0 ? s.splice(n, 1) : i._childArray = void 0;
617
+ }
618
+ }
619
+ /**
620
+ * Возвращает snapshot детей для их удаления. Уже выданный массив
621
+ * переиспользуется без копии и на время удаления перестаёт быть массивом
622
+ * node: дети выходят из списка только через связи, snapshot не сдвигается, и
623
+ * удаление не платит за `shift` на каждого child. Иначе snapshot строится по
624
+ * связям.
625
+ */
626
+ _takeChildSnapshot() {
627
+ const i = this._childArray;
628
+ return i === void 0 ? this._collectChildren() : (this._childArray = void 0, i);
629
+ }
630
+ /**
631
+ * Сбрасывает собственный список после удаления детей. `snapshot` мог быть
632
+ * выданным массивом: как и раньше, у удалённой node он остаётся пустым.
633
+ * Массив, запрошенный во время удаления, очищается так же: `_unlinkFrom` не
634
+ * отбрасывает его, пока node удаляет своих детей.
635
+ */
636
+ _resetChildList(i) {
637
+ i.length = 0, this._clearChildArray();
638
+ let t = this._firstChild;
639
+ for (; t !== null; ) {
640
+ const e = t._nextSibling;
641
+ t._prevSibling = null, t._nextSibling = null, t = e;
642
+ }
643
+ this._firstChild = null, this._lastChild = null, this._childCount = 0;
644
+ }
189
645
  }
190
- function O(o, h, t) {
191
- return new c(o, h, t, _);
646
+ function E(_, i, t) {
647
+ return new o(_, i, t, C);
192
648
  }
193
- function u(o) {
194
- const h = [];
195
- for (let t = o; t !== null; t = t.parent)
196
- h.push(t);
197
- return h;
649
+ o.prototype._isNode = !0;
650
+ function d(_) {
651
+ const i = [];
652
+ for (let t = _; t !== null; t = t.parent)
653
+ i.push(t);
654
+ return i;
198
655
  }
199
- function p(o) {
200
- if (!Number.isFinite(o))
656
+ function b(_) {
657
+ if (!Number.isFinite(_))
201
658
  throw new TypeError("[Raph] Node priority must be finite.");
202
659
  }
660
+ p = o.prototype.dispose;
661
+ c = o.prototype._disposeWithOutcome;
203
662
  export {
204
- c as RaphNode,
205
- O as createProvisionalNode
663
+ o as RaphNode,
664
+ E as createProvisionalNode
206
665
  };