reactronic 0.24.401 → 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.
|
@@ -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,13 +36,13 @@ 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
|
|
@@ -113,9 +113,9 @@ export class ReactiveNode {
|
|
|
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
121
|
runUpdateNestedNodesThenDo(ReactiveNodeImpl.ownSlot, undefined, action);
|
|
@@ -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) {
|
|
@@ -382,7 +382,7 @@ function runUpdateNestedNodesThenDo(ownSlot, error, action) {
|
|
|
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;
|
|
@@ -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)
|
|
@@ -529,14 +529,14 @@ function updateNow(slot) {
|
|
|
529
529
|
});
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
|
-
function
|
|
532
|
+
function triggerFinalization(slot, isLeader, individual) {
|
|
533
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;
|
|
@@ -550,7 +550,7 @@ function triggerDeactivation(slot, isLeader, individual) {
|
|
|
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
|
}
|
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"
|