reactronic 0.24.400 → 0.24.500
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.
|
@@ -23,7 +23,7 @@ export declare abstract class ReactiveNode<E = unknown> {
|
|
|
23
23
|
abstract element: E;
|
|
24
24
|
abstract readonly host: ReactiveNode;
|
|
25
25
|
abstract readonly children: MergeListReader<ReactiveNode>;
|
|
26
|
-
abstract readonly
|
|
26
|
+
abstract readonly slot: MergedItem<ReactiveNode<E>> | undefined;
|
|
27
27
|
abstract readonly stamp: number;
|
|
28
28
|
abstract readonly outer: ReactiveNode;
|
|
29
29
|
abstract readonly context: ReactiveNodeContext | undefined;
|
|
@@ -36,9 +36,9 @@ export declare abstract class ReactiveNode<E = unknown> {
|
|
|
36
36
|
static readonly longFrameDuration = 300;
|
|
37
37
|
static currentUpdatePriority: Priority;
|
|
38
38
|
static frameDuration: number;
|
|
39
|
-
static declare<E = void>(driver: ReactiveNodeDriver<E>, content?: Script<E>, contentAsync?: ScriptAsync<E>, key?: string, mode?: Mode,
|
|
39
|
+
static declare<E = void>(driver: ReactiveNodeDriver<E>, content?: Script<E>, contentAsync?: ScriptAsync<E>, key?: string, mode?: Mode, preparation?: Script<E>, preparationAsync?: ScriptAsync<E>, finalization?: Script<E>, triggers?: unknown, basis?: ReactiveNodeDecl<E>): ReactiveNode<E>;
|
|
40
40
|
static declare<E = void>(driver: ReactiveNodeDriver<E>, declaration?: ReactiveNodeDecl<E>): ReactiveNode<E>;
|
|
41
|
-
static declare<E = void>(driver: ReactiveNodeDriver<E>, contentOrDeclaration?: Script<E> | ReactiveNodeDecl<E>, contentAsync?: ScriptAsync<E>, key?: string, mode?: Mode,
|
|
41
|
+
static declare<E = void>(driver: ReactiveNodeDriver<E>, contentOrDeclaration?: Script<E> | ReactiveNodeDecl<E>, contentAsync?: ScriptAsync<E>, key?: string, mode?: Mode, preparation?: Script<E>, preparationAsync?: ScriptAsync<E>, finalization?: Script<E>, triggers?: unknown, basis?: ReactiveNodeDecl<E>): ReactiveNode<E>;
|
|
42
42
|
static withBasis<E = void>(declaration?: ReactiveNodeDecl<E>, basis?: ReactiveNodeDecl<E>): ReactiveNodeDecl<E>;
|
|
43
43
|
static get isFirstUpdate(): boolean;
|
|
44
44
|
static get key(): string;
|
|
@@ -49,7 +49,7 @@ export declare abstract class ReactiveNode<E = unknown> {
|
|
|
49
49
|
static get childrenShuffling(): boolean;
|
|
50
50
|
static set childrenShuffling(value: boolean);
|
|
51
51
|
static triggerUpdate(node: ReactiveNode<any>, triggers: unknown): void;
|
|
52
|
-
static
|
|
52
|
+
static triggerFinalization(node: ReactiveNode<any>): void;
|
|
53
53
|
static updateNestedNodesThenDo(action: (error: unknown) => void): void;
|
|
54
54
|
static markAsMounted(node: ReactiveNode<any>, yes: boolean): void;
|
|
55
55
|
static findMatchingHost<E = unknown, R = unknown>(node: ReactiveNode<E>, match: Handler<ReactiveNode<E>, boolean>): ReactiveNode<R> | undefined;
|
|
@@ -63,9 +63,9 @@ export type ReactiveNodeDecl<E = unknown> = {
|
|
|
63
63
|
contentAsync?: ScriptAsync<E>;
|
|
64
64
|
key?: string;
|
|
65
65
|
mode?: Mode;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
preparation?: Script<E>;
|
|
67
|
+
preparationAsync?: ScriptAsync<E>;
|
|
68
|
+
finalization?: Script<E>;
|
|
69
69
|
triggers?: unknown;
|
|
70
70
|
basis?: ReactiveNodeDecl<E>;
|
|
71
71
|
};
|
|
@@ -74,12 +74,12 @@ export type ReactiveNodeDriver<E = unknown> = {
|
|
|
74
74
|
readonly isPartition: boolean;
|
|
75
75
|
readonly initialize?: Handler<E>;
|
|
76
76
|
allocate(node: ReactiveNode<E>): E;
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
prepare(node: ReactiveNode<E>): void;
|
|
78
|
+
finalize(node: ReactiveNode<E>, isLeader: boolean): boolean;
|
|
79
79
|
mount(node: ReactiveNode<E>): void;
|
|
80
80
|
update(node: ReactiveNode<E>): void | Promise<void>;
|
|
81
81
|
child(ownerNode: ReactiveNode<E>, childDriver: ReactiveNodeDriver<any>, childDeclaration?: ReactiveNodeDecl<any>, childBasis?: ReactiveNodeDecl<any>): MergedItem<ReactiveNode> | undefined;
|
|
82
|
-
|
|
82
|
+
provideHost(node: ReactiveNode<E>): ReactiveNode<E>;
|
|
83
83
|
};
|
|
84
84
|
export type ReactiveNodeContext<T extends Object = Object> = {
|
|
85
85
|
value: T;
|
|
@@ -90,12 +90,12 @@ export declare abstract class BaseDriver<E = unknown> implements ReactiveNodeDri
|
|
|
90
90
|
readonly initialize?: Handler<E> | undefined;
|
|
91
91
|
constructor(name: string, isPartition: boolean, initialize?: Handler<E> | undefined);
|
|
92
92
|
abstract allocate(node: ReactiveNode<E>): E;
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
prepare(node: ReactiveNode<E>): void | Promise<void>;
|
|
94
|
+
finalize(node: ReactiveNode<E>, isLeader: boolean): boolean;
|
|
95
95
|
mount(node: ReactiveNode<E>): void;
|
|
96
96
|
update(node: ReactiveNode<E>): void | Promise<void>;
|
|
97
97
|
child(ownerNode: ReactiveNode<E>, childDriver: ReactiveNodeDriver<any>, childDeclaration?: ReactiveNodeDecl<any>, childBasis?: ReactiveNodeDecl<any>): MergedItem<ReactiveNode> | undefined;
|
|
98
|
-
|
|
98
|
+
provideHost(node: ReactiveNode<E>): ReactiveNode<E>;
|
|
99
99
|
}
|
|
100
100
|
export declare class ReactiveNodeVariable<T extends Object = Object> {
|
|
101
101
|
readonly defaultValue: T | undefined;
|
|
@@ -36,19 +36,19 @@ export var Priority;
|
|
|
36
36
|
Priority[Priority["background"] = 2] = "background";
|
|
37
37
|
})(Priority || (Priority = {}));
|
|
38
38
|
export class ReactiveNode {
|
|
39
|
-
static declare(driver, contentOrDeclaration, contentAsync, key, mode,
|
|
39
|
+
static declare(driver, contentOrDeclaration, contentAsync, key, mode, preparation, preparationAsync, finalization, triggers, basis) {
|
|
40
40
|
let result;
|
|
41
41
|
let declaration;
|
|
42
42
|
if (contentOrDeclaration instanceof Function) {
|
|
43
43
|
declaration = {
|
|
44
44
|
content: contentOrDeclaration, contentAsync, key, mode,
|
|
45
|
-
|
|
45
|
+
preparation, preparationAsync, finalization, triggers, basis,
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
else
|
|
49
49
|
declaration = contentOrDeclaration !== null && contentOrDeclaration !== void 0 ? contentOrDeclaration : {};
|
|
50
50
|
let effectiveKey = declaration.key;
|
|
51
|
-
const owner =
|
|
51
|
+
const owner = gOwnSlot === null || gOwnSlot === void 0 ? void 0 : gOwnSlot.instance;
|
|
52
52
|
if (owner) {
|
|
53
53
|
let existing = owner.driver.child(owner, driver, declaration, declaration.basis);
|
|
54
54
|
const children = owner.children;
|
|
@@ -64,13 +64,13 @@ export class ReactiveNode {
|
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
66
|
result = new ReactiveNodeImpl(effectiveKey || generateKey(owner), driver, declaration, owner);
|
|
67
|
-
result.
|
|
67
|
+
result.slot = children.mergeAsAdded(result);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
else {
|
|
71
71
|
result = new ReactiveNodeImpl(effectiveKey || "", driver, declaration, owner);
|
|
72
|
-
result.
|
|
73
|
-
|
|
72
|
+
result.slot = MergeList.createItem(result);
|
|
73
|
+
triggerUpdateViaSlot(result.slot);
|
|
74
74
|
}
|
|
75
75
|
return result;
|
|
76
76
|
}
|
|
@@ -82,43 +82,43 @@ export class ReactiveNode {
|
|
|
82
82
|
return declaration;
|
|
83
83
|
}
|
|
84
84
|
static get isFirstUpdate() {
|
|
85
|
-
return ReactiveNodeImpl.
|
|
85
|
+
return ReactiveNodeImpl.ownSlot.instance.stamp === 1;
|
|
86
86
|
}
|
|
87
87
|
static get key() {
|
|
88
|
-
return ReactiveNodeImpl.
|
|
88
|
+
return ReactiveNodeImpl.ownSlot.instance.key;
|
|
89
89
|
}
|
|
90
90
|
static get stamp() {
|
|
91
|
-
return ReactiveNodeImpl.
|
|
91
|
+
return ReactiveNodeImpl.ownSlot.instance.stamp;
|
|
92
92
|
}
|
|
93
93
|
static get triggers() {
|
|
94
|
-
return ReactiveNodeImpl.
|
|
94
|
+
return ReactiveNodeImpl.ownSlot.instance.declaration.triggers;
|
|
95
95
|
}
|
|
96
96
|
static get priority() {
|
|
97
|
-
return ReactiveNodeImpl.
|
|
97
|
+
return ReactiveNodeImpl.ownSlot.instance.priority;
|
|
98
98
|
}
|
|
99
99
|
static set priority(value) {
|
|
100
|
-
ReactiveNodeImpl.
|
|
100
|
+
ReactiveNodeImpl.ownSlot.instance.priority = value;
|
|
101
101
|
}
|
|
102
102
|
static get childrenShuffling() {
|
|
103
|
-
return ReactiveNodeImpl.
|
|
103
|
+
return ReactiveNodeImpl.ownSlot.instance.childrenShuffling;
|
|
104
104
|
}
|
|
105
105
|
static set childrenShuffling(value) {
|
|
106
|
-
ReactiveNodeImpl.
|
|
106
|
+
ReactiveNodeImpl.ownSlot.instance.childrenShuffling = value;
|
|
107
107
|
}
|
|
108
108
|
static triggerUpdate(node, triggers) {
|
|
109
109
|
const impl = node;
|
|
110
110
|
const declaration = impl.declaration;
|
|
111
111
|
if (!triggersAreEqual(triggers, declaration.triggers)) {
|
|
112
112
|
declaration.triggers = triggers;
|
|
113
|
-
|
|
113
|
+
triggerUpdateViaSlot(impl.slot);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
static
|
|
116
|
+
static triggerFinalization(node) {
|
|
117
117
|
const impl = node;
|
|
118
|
-
|
|
118
|
+
triggerFinalization(impl.slot, true, true);
|
|
119
119
|
}
|
|
120
120
|
static updateNestedNodesThenDo(action) {
|
|
121
|
-
runUpdateNestedNodesThenDo(ReactiveNodeImpl.
|
|
121
|
+
runUpdateNestedNodesThenDo(ReactiveNodeImpl.ownSlot, undefined, action);
|
|
122
122
|
}
|
|
123
123
|
static markAsMounted(node, yes) {
|
|
124
124
|
const n = node;
|
|
@@ -135,7 +135,7 @@ export class ReactiveNode {
|
|
|
135
135
|
return p;
|
|
136
136
|
}
|
|
137
137
|
static findMatchingPrevSibling(node, match) {
|
|
138
|
-
let p = node.
|
|
138
|
+
let p = node.slot.prev;
|
|
139
139
|
while (p && !match(p.instance))
|
|
140
140
|
p = p.prev;
|
|
141
141
|
return p === null || p === void 0 ? void 0 : p.instance;
|
|
@@ -162,13 +162,13 @@ export class BaseDriver {
|
|
|
162
162
|
this.isPartition = isPartition;
|
|
163
163
|
this.initialize = initialize;
|
|
164
164
|
}
|
|
165
|
-
|
|
165
|
+
prepare(node) {
|
|
166
166
|
var _a;
|
|
167
167
|
(_a = this.initialize) === null || _a === void 0 ? void 0 : _a.call(this, node.element);
|
|
168
|
-
return
|
|
168
|
+
return invokePreparationUsingBasisChain(node.element, node.declaration);
|
|
169
169
|
}
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
finalize(node, isLeader) {
|
|
171
|
+
invokeFinalizationUsingBasisChain(node.element, node.declaration);
|
|
172
172
|
return isLeader;
|
|
173
173
|
}
|
|
174
174
|
mount(node) {
|
|
@@ -179,7 +179,7 @@ export class BaseDriver {
|
|
|
179
179
|
child(ownerNode, childDriver, childDeclaration, childBasis) {
|
|
180
180
|
return undefined;
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
provideHost(node) {
|
|
183
183
|
return node;
|
|
184
184
|
}
|
|
185
185
|
}
|
|
@@ -226,28 +226,28 @@ function invokeContentUsingBasisChain(element, declaration) {
|
|
|
226
226
|
result = invokeContentUsingBasisChain(element, basis);
|
|
227
227
|
return result;
|
|
228
228
|
}
|
|
229
|
-
function
|
|
229
|
+
function invokePreparationUsingBasisChain(element, declaration) {
|
|
230
230
|
let result = undefined;
|
|
231
231
|
const basis = declaration.basis;
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
if (
|
|
235
|
-
throw misuse("'
|
|
236
|
-
if (
|
|
237
|
-
result =
|
|
238
|
-
else if (
|
|
239
|
-
result =
|
|
232
|
+
const preparation = declaration.preparation;
|
|
233
|
+
const preparationAsync = declaration.preparationAsync;
|
|
234
|
+
if (preparation && preparationAsync)
|
|
235
|
+
throw misuse("'preparation' and 'preparationAsync' cannot be defined together");
|
|
236
|
+
if (preparation)
|
|
237
|
+
result = preparation(element, basis ? () => invokePreparationUsingBasisChain(element, basis) : NOP);
|
|
238
|
+
else if (preparationAsync)
|
|
239
|
+
result = preparationAsync(element, basis ? () => invokePreparationUsingBasisChain(element, basis) : NOP_ASYNC);
|
|
240
240
|
else if (basis)
|
|
241
|
-
result =
|
|
241
|
+
result = invokePreparationUsingBasisChain(element, basis);
|
|
242
242
|
return result;
|
|
243
243
|
}
|
|
244
|
-
function
|
|
244
|
+
function invokeFinalizationUsingBasisChain(element, declaration) {
|
|
245
245
|
const basis = declaration.basis;
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
|
|
246
|
+
const finalization = declaration.finalization;
|
|
247
|
+
if (finalization)
|
|
248
|
+
finalization(element, basis ? () => invokeFinalizationUsingBasisChain(element, basis) : NOP);
|
|
249
249
|
else if (basis)
|
|
250
|
-
|
|
250
|
+
invokeFinalizationUsingBasisChain(element, basis);
|
|
251
251
|
}
|
|
252
252
|
class ReactiveNodeContextImpl extends ObservableObject {
|
|
253
253
|
constructor(variable, value) {
|
|
@@ -286,7 +286,7 @@ class ReactiveNodeImpl extends ReactiveNode {
|
|
|
286
286
|
this.element = driver.allocate(this);
|
|
287
287
|
this.host = thisAsUnknown;
|
|
288
288
|
this.children = new MergeList(getNodeKey, true);
|
|
289
|
-
this.
|
|
289
|
+
this.slot = undefined;
|
|
290
290
|
this.stamp = Number.MAX_SAFE_INTEGER;
|
|
291
291
|
this.context = undefined;
|
|
292
292
|
this.numerator = 0;
|
|
@@ -298,28 +298,28 @@ class ReactiveNodeImpl extends ReactiveNode {
|
|
|
298
298
|
}
|
|
299
299
|
get strictOrder() { return this.children.isStrict; }
|
|
300
300
|
set strictOrder(value) { this.children.isStrict = value; }
|
|
301
|
-
get isMoved() { return this.owner.children.isMoved(this.
|
|
301
|
+
get isMoved() { return this.owner.children.isMoved(this.slot); }
|
|
302
302
|
has(mode) {
|
|
303
303
|
return (getModeUsingBasisChain(this.declaration) & mode) === mode;
|
|
304
304
|
}
|
|
305
305
|
update(_triggers) {
|
|
306
|
-
updateNow(this.
|
|
306
|
+
updateNow(this.slot);
|
|
307
307
|
}
|
|
308
308
|
configureReactronic(options) {
|
|
309
309
|
if (this.stamp < Number.MAX_SAFE_INTEGER - 1 || !this.has(Mode.autonomous))
|
|
310
310
|
throw new Error("reactronic can be configured only for elements with autonomous mode and only during activation");
|
|
311
311
|
return ReactiveSystem.getOperation(this.update).configure(options);
|
|
312
312
|
}
|
|
313
|
-
static get
|
|
314
|
-
if (!
|
|
313
|
+
static get ownSlot() {
|
|
314
|
+
if (!gOwnSlot)
|
|
315
315
|
throw new Error("current element is undefined");
|
|
316
|
-
return
|
|
316
|
+
return gOwnSlot;
|
|
317
317
|
}
|
|
318
318
|
static tryUseNodeVariableValue(variable) {
|
|
319
319
|
var _a, _b;
|
|
320
|
-
let node = ReactiveNodeImpl.
|
|
320
|
+
let node = ReactiveNodeImpl.ownSlot.instance;
|
|
321
321
|
while (((_a = node.context) === null || _a === void 0 ? void 0 : _a.variable) !== variable && node.owner !== node)
|
|
322
|
-
node = node.outer.
|
|
322
|
+
node = node.outer.slot.instance;
|
|
323
323
|
return (_b = node.context) === null || _b === void 0 ? void 0 : _b.value;
|
|
324
324
|
}
|
|
325
325
|
static useNodeVariableValue(variable) {
|
|
@@ -330,7 +330,7 @@ class ReactiveNodeImpl extends ReactiveNode {
|
|
|
330
330
|
return result;
|
|
331
331
|
}
|
|
332
332
|
static setNodeVariableValue(variable, value) {
|
|
333
|
-
const node = ReactiveNodeImpl.
|
|
333
|
+
const node = ReactiveNodeImpl.ownSlot.instance;
|
|
334
334
|
const owner = node.owner;
|
|
335
335
|
const hostCtx = unobs(() => { var _a; return (_a = owner.context) === null || _a === void 0 ? void 0 : _a.value; });
|
|
336
336
|
if (value && value !== hostCtx) {
|
|
@@ -372,17 +372,17 @@ __decorate([
|
|
|
372
372
|
function getNodeKey(node) {
|
|
373
373
|
return node.stamp >= 0 ? node.key : undefined;
|
|
374
374
|
}
|
|
375
|
-
function runUpdateNestedNodesThenDo(
|
|
376
|
-
runInside(
|
|
375
|
+
function runUpdateNestedNodesThenDo(ownSlot, error, action) {
|
|
376
|
+
runInside(ownSlot, () => {
|
|
377
377
|
var _a;
|
|
378
|
-
const owner =
|
|
378
|
+
const owner = ownSlot.instance;
|
|
379
379
|
const children = owner.children;
|
|
380
380
|
if (children.isMergeInProgress) {
|
|
381
381
|
let promised = undefined;
|
|
382
382
|
try {
|
|
383
383
|
children.endMerge(error);
|
|
384
384
|
for (const child of children.removedItems(true))
|
|
385
|
-
|
|
385
|
+
triggerFinalization(child, true, true);
|
|
386
386
|
if (!error) {
|
|
387
387
|
const sequential = children.isStrict;
|
|
388
388
|
let p1 = undefined;
|
|
@@ -398,7 +398,7 @@ function runUpdateNestedNodesThenDo(ownSeat, error, action) {
|
|
|
398
398
|
mounting = markToMountIfNecessary(mounting, host, child, children, sequential);
|
|
399
399
|
const p = (_a = childNode.priority) !== null && _a !== void 0 ? _a : Priority.realtime;
|
|
400
400
|
if (p === Priority.realtime)
|
|
401
|
-
|
|
401
|
+
triggerUpdateViaSlot(child);
|
|
402
402
|
else if (p === Priority.normal)
|
|
403
403
|
p1 = push(child, p1);
|
|
404
404
|
else
|
|
@@ -407,7 +407,7 @@ function runUpdateNestedNodesThenDo(ownSeat, error, action) {
|
|
|
407
407
|
partition = childNode;
|
|
408
408
|
}
|
|
409
409
|
if (!Transaction.isCanceled && (p1 !== undefined || p2 !== undefined))
|
|
410
|
-
promised = startIncrementalUpdate(
|
|
410
|
+
promised = startIncrementalUpdate(ownSlot, children, p1, p2).then(() => action(error), e => action(e));
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
413
|
finally {
|
|
@@ -417,26 +417,26 @@ function runUpdateNestedNodesThenDo(ownSeat, error, action) {
|
|
|
417
417
|
}
|
|
418
418
|
});
|
|
419
419
|
}
|
|
420
|
-
function markToMountIfNecessary(mounting, host,
|
|
421
|
-
const node =
|
|
420
|
+
function markToMountIfNecessary(mounting, host, slot, children, sequential) {
|
|
421
|
+
const node = slot.instance;
|
|
422
422
|
if (node.element.native && !node.has(Mode.manualMount)) {
|
|
423
423
|
if (mounting || node.host !== host) {
|
|
424
|
-
children.markAsMoved(
|
|
424
|
+
children.markAsMoved(slot);
|
|
425
425
|
mounting = false;
|
|
426
426
|
}
|
|
427
427
|
}
|
|
428
|
-
else if (sequential && children.isMoved(
|
|
428
|
+
else if (sequential && children.isMoved(slot))
|
|
429
429
|
mounting = true;
|
|
430
430
|
node.host = host;
|
|
431
431
|
return mounting;
|
|
432
432
|
}
|
|
433
|
-
function startIncrementalUpdate(
|
|
433
|
+
function startIncrementalUpdate(ownerSlot, allChildren, priority1, priority2) {
|
|
434
434
|
return __awaiter(this, void 0, void 0, function* () {
|
|
435
|
-
const stamp =
|
|
435
|
+
const stamp = ownerSlot.instance.stamp;
|
|
436
436
|
if (priority1)
|
|
437
|
-
yield updateIncrementally(
|
|
437
|
+
yield updateIncrementally(ownerSlot, stamp, allChildren, priority1, Priority.normal);
|
|
438
438
|
if (priority2)
|
|
439
|
-
yield updateIncrementally(
|
|
439
|
+
yield updateIncrementally(ownerSlot, stamp, allChildren, priority2, Priority.background);
|
|
440
440
|
});
|
|
441
441
|
}
|
|
442
442
|
function updateIncrementally(owner, stamp, allChildren, items, priority) {
|
|
@@ -452,7 +452,7 @@ function updateIncrementally(owner, stamp, allChildren, items, priority) {
|
|
|
452
452
|
const frameDurationLimit = priority === Priority.background ? ReactiveNode.shortFrameDuration : Infinity;
|
|
453
453
|
let frameDuration = Math.min(frameDurationLimit, Math.max(ReactiveNode.frameDuration / 4, ReactiveNode.shortFrameDuration));
|
|
454
454
|
for (const child of items) {
|
|
455
|
-
|
|
455
|
+
triggerUpdateViaSlot(child);
|
|
456
456
|
if (Transaction.isFrameOver(1, frameDuration)) {
|
|
457
457
|
ReactiveNode.currentUpdatePriority = outerPriority;
|
|
458
458
|
yield Transaction.requestNextFrame(0);
|
|
@@ -470,8 +470,8 @@ function updateIncrementally(owner, stamp, allChildren, items, priority) {
|
|
|
470
470
|
}
|
|
471
471
|
});
|
|
472
472
|
}
|
|
473
|
-
function
|
|
474
|
-
const node =
|
|
473
|
+
function triggerUpdateViaSlot(slot) {
|
|
474
|
+
const node = slot.instance;
|
|
475
475
|
if (node.stamp >= 0) {
|
|
476
476
|
if (node.has(Mode.autonomous)) {
|
|
477
477
|
if (node.stamp === Number.MAX_SAFE_INTEGER) {
|
|
@@ -486,7 +486,7 @@ function triggerUpdateViaSeat(seat) {
|
|
|
486
486
|
unobs(node.update, node.declaration.triggers);
|
|
487
487
|
}
|
|
488
488
|
else
|
|
489
|
-
updateNow(
|
|
489
|
+
updateNow(slot);
|
|
490
490
|
}
|
|
491
491
|
}
|
|
492
492
|
function mountOrRemountIfNecessary(node) {
|
|
@@ -494,7 +494,7 @@ function mountOrRemountIfNecessary(node) {
|
|
|
494
494
|
if (node.stamp === Number.MAX_SAFE_INTEGER) {
|
|
495
495
|
unobs(() => {
|
|
496
496
|
node.stamp = Number.MAX_SAFE_INTEGER - 1;
|
|
497
|
-
driver.
|
|
497
|
+
driver.prepare(node);
|
|
498
498
|
if (!node.has(Mode.manualMount)) {
|
|
499
499
|
node.stamp = 0;
|
|
500
500
|
if (node.host !== node)
|
|
@@ -505,11 +505,11 @@ function mountOrRemountIfNecessary(node) {
|
|
|
505
505
|
else if (node.isMoved && !node.has(Mode.manualMount) && node.host !== node)
|
|
506
506
|
unobs(() => driver.mount(node));
|
|
507
507
|
}
|
|
508
|
-
function updateNow(
|
|
509
|
-
const node =
|
|
508
|
+
function updateNow(slot) {
|
|
509
|
+
const node = slot.instance;
|
|
510
510
|
if (node.stamp >= 0) {
|
|
511
511
|
let result = undefined;
|
|
512
|
-
runInside(
|
|
512
|
+
runInside(slot, () => {
|
|
513
513
|
mountOrRemountIfNecessary(node);
|
|
514
514
|
if (node.stamp < Number.MAX_SAFE_INTEGER - 1) {
|
|
515
515
|
try {
|
|
@@ -518,10 +518,10 @@ function updateNow(seat) {
|
|
|
518
518
|
node.children.beginMerge();
|
|
519
519
|
const driver = node.driver;
|
|
520
520
|
result = driver.update(node);
|
|
521
|
-
result = proceedSyncOrAsync(result, v => { runUpdateNestedNodesThenDo(
|
|
521
|
+
result = proceedSyncOrAsync(result, v => { runUpdateNestedNodesThenDo(slot, undefined, NOP); return v; }, e => { console.log(e); runUpdateNestedNodesThenDo(slot, e !== null && e !== void 0 ? e : new Error("unknown error"), NOP); });
|
|
522
522
|
}
|
|
523
523
|
catch (e) {
|
|
524
|
-
runUpdateNestedNodesThenDo(
|
|
524
|
+
runUpdateNestedNodesThenDo(slot, e, NOP);
|
|
525
525
|
console.log(`Update failed: ${node.key}`);
|
|
526
526
|
console.log(`${e}`);
|
|
527
527
|
}
|
|
@@ -529,40 +529,40 @@ function updateNow(seat) {
|
|
|
529
529
|
});
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
|
-
function
|
|
533
|
-
const node =
|
|
532
|
+
function triggerFinalization(slot, isLeader, individual) {
|
|
533
|
+
const node = slot.instance;
|
|
534
534
|
if (node.stamp >= 0) {
|
|
535
535
|
const driver = node.driver;
|
|
536
536
|
if (individual && node.key !== node.declaration.key && !driver.isPartition)
|
|
537
537
|
console.log(`WARNING: it is recommended to assign explicit key for conditional element in order to avoid unexpected side effects: ${node.key}`);
|
|
538
538
|
node.stamp = ~node.stamp;
|
|
539
|
-
const childrenAreLeaders = unobs(() => driver.
|
|
539
|
+
const childrenAreLeaders = unobs(() => driver.finalize(node, isLeader));
|
|
540
540
|
if (node.has(Mode.autonomous)) {
|
|
541
|
-
|
|
541
|
+
slot.aux = undefined;
|
|
542
542
|
const last = gLastToDispose;
|
|
543
543
|
if (last)
|
|
544
|
-
gLastToDispose = last.aux =
|
|
544
|
+
gLastToDispose = last.aux = slot;
|
|
545
545
|
else
|
|
546
|
-
gFirstToDispose = gLastToDispose =
|
|
547
|
-
if (gFirstToDispose ===
|
|
548
|
-
Transaction.run({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${
|
|
546
|
+
gFirstToDispose = gLastToDispose = slot;
|
|
547
|
+
if (gFirstToDispose === slot)
|
|
548
|
+
Transaction.run({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${slot.instance.key})` }, () => {
|
|
549
549
|
void runDisposalLoop().then(NOP, error => console.log(error));
|
|
550
550
|
});
|
|
551
551
|
}
|
|
552
552
|
for (const child of node.children.items())
|
|
553
|
-
|
|
553
|
+
triggerFinalization(child, childrenAreLeaders, false);
|
|
554
554
|
ReactiveNodeImpl.grandNodeCount--;
|
|
555
555
|
}
|
|
556
556
|
}
|
|
557
557
|
function runDisposalLoop() {
|
|
558
558
|
return __awaiter(this, void 0, void 0, function* () {
|
|
559
559
|
yield Transaction.requestNextFrame();
|
|
560
|
-
let
|
|
561
|
-
while (
|
|
560
|
+
let slot = gFirstToDispose;
|
|
561
|
+
while (slot !== undefined) {
|
|
562
562
|
if (Transaction.isFrameOver(500, 5))
|
|
563
563
|
yield Transaction.requestNextFrame();
|
|
564
|
-
ReactiveSystem.dispose(
|
|
565
|
-
|
|
564
|
+
ReactiveSystem.dispose(slot.instance);
|
|
565
|
+
slot = slot.aux;
|
|
566
566
|
ReactiveNodeImpl.disposableNodeCount--;
|
|
567
567
|
}
|
|
568
568
|
gFirstToDispose = gLastToDispose = undefined;
|
|
@@ -570,7 +570,7 @@ function runDisposalLoop() {
|
|
|
570
570
|
}
|
|
571
571
|
function wrapToRunInside(func) {
|
|
572
572
|
let wrappedToRunInside;
|
|
573
|
-
const outer =
|
|
573
|
+
const outer = gOwnSlot;
|
|
574
574
|
if (outer)
|
|
575
575
|
wrappedToRunInside = (...args) => {
|
|
576
576
|
return runInside(outer, func, ...args);
|
|
@@ -579,14 +579,14 @@ function wrapToRunInside(func) {
|
|
|
579
579
|
wrappedToRunInside = func;
|
|
580
580
|
return wrappedToRunInside;
|
|
581
581
|
}
|
|
582
|
-
function runInside(
|
|
583
|
-
const outer =
|
|
582
|
+
function runInside(slot, func, ...args) {
|
|
583
|
+
const outer = gOwnSlot;
|
|
584
584
|
try {
|
|
585
|
-
|
|
585
|
+
gOwnSlot = slot;
|
|
586
586
|
return func(...args);
|
|
587
587
|
}
|
|
588
588
|
finally {
|
|
589
|
-
|
|
589
|
+
gOwnSlot = outer;
|
|
590
590
|
}
|
|
591
591
|
}
|
|
592
592
|
function triggersAreEqual(a1, a2) {
|
|
@@ -640,6 +640,6 @@ function defaultReject(error) {
|
|
|
640
640
|
Promise.prototype.then = reactronicDomHookedThen;
|
|
641
641
|
const NOP = (...args) => { };
|
|
642
642
|
const NOP_ASYNC = (...args) => __awaiter(void 0, void 0, void 0, function* () { });
|
|
643
|
-
let
|
|
643
|
+
let gOwnSlot = undefined;
|
|
644
644
|
let gFirstToDispose = undefined;
|
|
645
645
|
let gLastToDispose = undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reactronic",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.500",
|
|
4
4
|
"description": "Reactronic - Transactional Reactive State Management",
|
|
5
5
|
"publisher": "Nezaboodka Software",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/nezaboodka/reactronic/blob/master/README.md#readme",
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "22.8.
|
|
34
|
+
"@types/node": "22.8.6",
|
|
35
35
|
"@types/react": "18.3.12",
|
|
36
36
|
"@typescript-eslint/eslint-plugin": "8.12.2",
|
|
37
37
|
"@typescript-eslint/parser": "8.12.2",
|
|
38
38
|
"ava": "6.2.0",
|
|
39
39
|
"c8": "10.1.2",
|
|
40
|
-
"eslint": "9.
|
|
40
|
+
"eslint": "9.14.0",
|
|
41
41
|
"react": "18.3.1",
|
|
42
42
|
"ts-node": "10.9.2",
|
|
43
43
|
"typescript": "5.5.4"
|