reactronic 0.24.305 → 0.24.307
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/dist/source/Options.d.ts +1 -1
- package/build/dist/source/core/Changeset.d.ts +4 -1
- package/build/dist/source/core/Changeset.js +9 -5
- package/build/dist/source/core/Indicator.js +5 -5
- package/build/dist/source/core/Operation.d.ts +2 -2
- package/build/dist/source/core/Operation.js +23 -13
- package/build/dist/source/core/RxNode.d.ts +3 -1
- package/build/dist/source/core/RxNode.js +22 -10
- package/build/dist/source/core/Transaction.d.ts +1 -0
- package/package.json +1 -1
|
@@ -50,7 +50,7 @@ export type Operation<T> = {
|
|
|
50
50
|
readonly result: T;
|
|
51
51
|
readonly error: any;
|
|
52
52
|
readonly stamp: number;
|
|
53
|
-
readonly
|
|
53
|
+
readonly isReusable: boolean;
|
|
54
54
|
configure(options: Partial<MemberOptions>): MemberOptions;
|
|
55
55
|
markObsolete(): void;
|
|
56
56
|
pullLastResult(args?: any[]): T | undefined;
|
|
@@ -26,7 +26,10 @@ export declare class Changeset implements AbstractChangeset {
|
|
|
26
26
|
static edit: () => Changeset;
|
|
27
27
|
static markUsed: (fv: FieldVersion, ov: ObjectVersion, fk: FieldKey, h: ObjectHandle, kind: Kind, weak: boolean) => void;
|
|
28
28
|
static markEdited: (oldValue: any, newValue: any, edited: boolean, ov: ObjectVersion, fk: FieldKey, h: ObjectHandle) => void;
|
|
29
|
-
static
|
|
29
|
+
static tryResolveConflict: (theirValue: any, ourFormerValue: any, ourValue: any) => {
|
|
30
|
+
isResolved: boolean;
|
|
31
|
+
resolvedValue: any;
|
|
32
|
+
};
|
|
30
33
|
static propagateAllChangesThroughSubscriptions: (changeset: Changeset) => void;
|
|
31
34
|
static revokeAllSubscriptions: (changeset: Changeset) => void;
|
|
32
35
|
static enqueueReactiveFunctionsToRun: (reactive: Array<Observer>) => void;
|
|
@@ -157,7 +157,7 @@ export class Changeset {
|
|
|
157
157
|
let conflicts = undefined;
|
|
158
158
|
if (this.items.size > 0) {
|
|
159
159
|
this.items.forEach((ov, h) => {
|
|
160
|
-
const theirs = this.parent ? this.parent.lookupObjectVersion(h, Meta.Handle,
|
|
160
|
+
const theirs = this.parent ? this.parent.lookupObjectVersion(h, Meta.Handle, true) : h.applied;
|
|
161
161
|
if (ov.former.objectVersion !== theirs) {
|
|
162
162
|
const merged = this.merge(h, ov, theirs);
|
|
163
163
|
if (ov.conflicts.size > 0) {
|
|
@@ -202,11 +202,15 @@ export class Changeset {
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
else {
|
|
205
|
-
const
|
|
206
|
-
|
|
205
|
+
const theirValue = theirs.data[fk];
|
|
206
|
+
const ourFormerValue = ours.former.objectVersion.data[fk];
|
|
207
|
+
const { isResolved, resolvedValue } = Changeset.tryResolveConflict(theirValue, ourFormerValue, ourFieldVersion);
|
|
208
|
+
if (!isResolved)
|
|
207
209
|
ours.conflicts.set(fk, theirs);
|
|
210
|
+
else if (resolvedValue.isLaunch)
|
|
211
|
+
merged[fk] = resolvedValue;
|
|
208
212
|
if (Log.isOn && Log.opt.change)
|
|
209
|
-
Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, fk)} ${
|
|
213
|
+
Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, fk)} ${!isResolved ? "<>" : "=="} ${Dump.snapshot2(h, theirs.changeset, fk)}`, 0, !isResolved ? " *** CONFLICT ***" : undefined);
|
|
210
214
|
}
|
|
211
215
|
});
|
|
212
216
|
Utils.copyAllMembers(merged, ours.data);
|
|
@@ -311,7 +315,7 @@ Changeset.current = UNDEF;
|
|
|
311
315
|
Changeset.edit = UNDEF;
|
|
312
316
|
Changeset.markUsed = UNDEF;
|
|
313
317
|
Changeset.markEdited = UNDEF;
|
|
314
|
-
Changeset.
|
|
318
|
+
Changeset.tryResolveConflict = UNDEF;
|
|
315
319
|
Changeset.propagateAllChangesThroughSubscriptions = (changeset) => { };
|
|
316
320
|
Changeset.revokeAllSubscriptions = (changeset) => { };
|
|
317
321
|
Changeset.enqueueReactiveFunctionsToRun = (reactive) => { };
|
|
@@ -131,13 +131,13 @@ export class IndicatorImpl extends Indicator {
|
|
|
131
131
|
}
|
|
132
132
|
static tick(mon) {
|
|
133
133
|
if (mon.internals.started !== 0) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
mon.busyDuration = Math.round(resolution * (performance.now() - mon.internals.started)) / resolution;
|
|
137
|
-
});
|
|
134
|
+
const resolution = mon.internals.durationResolution;
|
|
135
|
+
mon.busyDuration = Math.round(resolution * (performance.now() - mon.internals.started)) / resolution;
|
|
138
136
|
const t = globalThis !== null && globalThis !== void 0 ? globalThis : global;
|
|
139
137
|
if (t.requestAnimationFrame)
|
|
140
|
-
requestAnimationFrame(() =>
|
|
138
|
+
requestAnimationFrame(() => {
|
|
139
|
+
Transaction.run(INDICATOR_TICK_OPTIONS, () => IndicatorImpl.tick(mon));
|
|
140
|
+
});
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
}
|
|
@@ -13,7 +13,7 @@ export declare class OperationImpl implements Operation<any> {
|
|
|
13
13
|
get result(): any;
|
|
14
14
|
get error(): boolean;
|
|
15
15
|
get stamp(): number;
|
|
16
|
-
get
|
|
16
|
+
get isReusable(): boolean;
|
|
17
17
|
markObsolete(): void;
|
|
18
18
|
pullLastResult(args?: any[]): any;
|
|
19
19
|
constructor(h: ObjectHandle, fk: FieldKey);
|
|
@@ -74,7 +74,7 @@ declare class Launch extends FieldVersion implements Observer {
|
|
|
74
74
|
private static processDeferredReactiveFunctions;
|
|
75
75
|
private static markUsed;
|
|
76
76
|
private static markEdited;
|
|
77
|
-
private static
|
|
77
|
+
private static tryResolveConflict;
|
|
78
78
|
private static propagateAllChangesThroughSubscriptions;
|
|
79
79
|
private static revokeAllSubscriptions;
|
|
80
80
|
private static propagateFieldChangeThroughSubscriptions;
|
|
@@ -17,7 +17,7 @@ export class OperationImpl {
|
|
|
17
17
|
get result() { return this.reuseOrRelaunch(true, undefined).content; }
|
|
18
18
|
get error() { return this.use().launch.error; }
|
|
19
19
|
get stamp() { return this.use().objectVersion.changeset.timestamp; }
|
|
20
|
-
get
|
|
20
|
+
get isReusable() { return this.use().isReusable; }
|
|
21
21
|
markObsolete() { Transaction.run({ hint: Log.isOn ? `markObsolete(${Dump.obj(this.ownerHandle, this.fieldKey)})` : "markObsolete()" }, OperationImpl.markObsolete, this); }
|
|
22
22
|
pullLastResult(args) { return this.reuseOrRelaunch(true, args).content; }
|
|
23
23
|
constructor(h, fk) {
|
|
@@ -29,7 +29,7 @@ export class OperationImpl {
|
|
|
29
29
|
const ctx = ror.changeset;
|
|
30
30
|
const launch = ror.launch;
|
|
31
31
|
const opts = launch.options;
|
|
32
|
-
if (!ror.
|
|
32
|
+
if (!ror.isReusable && !ror.objectVersion.disposed
|
|
33
33
|
&& (!weak || launch.cause === BOOT_CAUSE || !launch.successor ||
|
|
34
34
|
launch.successor.transaction.isFinished)) {
|
|
35
35
|
const isolation = !weak ? opts.isolation : Isolation.disjoinFromOuterTransaction;
|
|
@@ -98,11 +98,12 @@ export class OperationImpl {
|
|
|
98
98
|
const ctx = Changeset.current();
|
|
99
99
|
const ov = ctx.lookupObjectVersion(this.ownerHandle, this.fieldKey, false);
|
|
100
100
|
const launch = this.acquireFromObjectVersion(ov, args);
|
|
101
|
-
const
|
|
102
|
-
|
|
101
|
+
const applied = this.ownerHandle.applied.data[this.fieldKey];
|
|
102
|
+
const isReusable = launch.options.kind !== Kind.transactional && launch.cause !== BOOT_CAUSE &&
|
|
103
|
+
(ctx === launch.changeset || ctx.timestamp < launch.obsoleteSince || applied.obsoleteDueTo === undefined) &&
|
|
103
104
|
(!launch.options.triggeringArgs || args === undefined ||
|
|
104
105
|
launch.args.length === args.length && launch.args.every((t, i) => t === args[i])) || ov.disposed;
|
|
105
|
-
return { launch,
|
|
106
|
+
return { launch, isReusable, changeset: ctx, objectVersion: ov };
|
|
106
107
|
}
|
|
107
108
|
use() {
|
|
108
109
|
const ror = this.peek(undefined);
|
|
@@ -122,7 +123,7 @@ export class OperationImpl {
|
|
|
122
123
|
Changeset.markEdited(launch, relaunch, true, ov, fk, h);
|
|
123
124
|
launch = relaunch;
|
|
124
125
|
}
|
|
125
|
-
return { launch,
|
|
126
|
+
return { launch, isReusable: true, changeset: ctx, objectVersion: ov };
|
|
126
127
|
}
|
|
127
128
|
acquireFromObjectVersion(ov, args) {
|
|
128
129
|
const fk = this.fieldKey;
|
|
@@ -174,7 +175,7 @@ export class OperationImpl {
|
|
|
174
175
|
}
|
|
175
176
|
else {
|
|
176
177
|
ror = this.peek(argsx);
|
|
177
|
-
if (ror.launch.options.kind === Kind.transactional || !ror.
|
|
178
|
+
if (ror.launch.options.kind === Kind.transactional || !ror.isReusable) {
|
|
178
179
|
ror = this.edit();
|
|
179
180
|
if (Log.isOn && Log.opt.operation)
|
|
180
181
|
Log.write("║", " o", `${ror.launch.why()}`);
|
|
@@ -486,11 +487,20 @@ class Launch extends FieldVersion {
|
|
|
486
487
|
if (Log.isOn && Log.opt.write)
|
|
487
488
|
edited ? Log.write("║", " =", `${Dump.snapshot2(h, ov.changeset, fk)} is changed: ${valueHint(oldValue)} ▸▸ ${valueHint(newValue)}`) : Log.write("║", " =", `${Dump.snapshot2(h, ov.changeset, fk)} is changed: ${valueHint(oldValue)} ▸▸ ${valueHint(newValue)}`, undefined, " (same as previous)");
|
|
488
489
|
}
|
|
489
|
-
static
|
|
490
|
-
let
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
490
|
+
static tryResolveConflict(theirValue, ourFormerValue, ourValue) {
|
|
491
|
+
let isResolved = theirValue === ourFormerValue;
|
|
492
|
+
let resolvedValue = ourValue;
|
|
493
|
+
if (!isResolved) {
|
|
494
|
+
if (ourValue instanceof Launch && ourValue.obsoleteDueTo === undefined) {
|
|
495
|
+
isResolved = true;
|
|
496
|
+
resolvedValue = ourValue;
|
|
497
|
+
}
|
|
498
|
+
else if (theirValue instanceof Launch && (theirValue.obsoleteDueTo === undefined || theirValue.cause === BOOT_CAUSE)) {
|
|
499
|
+
isResolved = true;
|
|
500
|
+
resolvedValue = theirValue;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
return { isResolved, resolvedValue };
|
|
494
504
|
}
|
|
495
505
|
static propagateAllChangesThroughSubscriptions(changeset) {
|
|
496
506
|
var _a;
|
|
@@ -658,7 +668,7 @@ class Launch extends FieldVersion {
|
|
|
658
668
|
Dump.valueHint = valueHint;
|
|
659
669
|
Changeset.markUsed = Launch.markUsed;
|
|
660
670
|
Changeset.markEdited = Launch.markEdited;
|
|
661
|
-
Changeset.
|
|
671
|
+
Changeset.tryResolveConflict = Launch.tryResolveConflict;
|
|
662
672
|
Changeset.propagateAllChangesThroughSubscriptions = Launch.propagateAllChangesThroughSubscriptions;
|
|
663
673
|
Changeset.revokeAllSubscriptions = Launch.revokeAllSubscriptions;
|
|
664
674
|
Changeset.enqueueReactiveFunctionsToRun = Launch.enqueueReactiveFunctionsToRun;
|
|
@@ -36,7 +36,9 @@ export declare abstract class RxNode<E = unknown> {
|
|
|
36
36
|
static readonly longFrameDuration = 300;
|
|
37
37
|
static currentUpdatePriority: Priority;
|
|
38
38
|
static frameDuration: number;
|
|
39
|
-
static declare<E = void>(driver: RxNodeDriver<E>,
|
|
39
|
+
static declare<E = void>(driver: RxNodeDriver<E>, script?: Script<E>, scriptAsync?: ScriptAsync<E>, key?: string, mode?: Mode, creation?: Script<E>, creationAsync?: ScriptAsync<E>, destruction?: Script<E>, triggers?: unknown, basis?: RxNodeDecl<E>): RxNode<E>;
|
|
40
|
+
static declare<E = void>(driver: RxNodeDriver<E>, declaration?: RxNodeDecl<E>): RxNode<E>;
|
|
41
|
+
static rebased<E = void>(declaration?: RxNodeDecl<E>, basis?: RxNodeDecl<E>): RxNodeDecl<E>;
|
|
40
42
|
static get isFirstUpdate(): boolean;
|
|
41
43
|
static get key(): string;
|
|
42
44
|
static get stamp(): number;
|
|
@@ -36,18 +36,23 @@ export var Priority;
|
|
|
36
36
|
Priority[Priority["background"] = 2] = "background";
|
|
37
37
|
})(Priority || (Priority = {}));
|
|
38
38
|
export class RxNode {
|
|
39
|
-
static declare(driver,
|
|
39
|
+
static declare(driver, scriptOrDeclaration, scriptAsync, key, mode, creation, creationAsync, destruction, triggers, basis) {
|
|
40
40
|
let result;
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
let declaration;
|
|
42
|
+
if (scriptOrDeclaration instanceof Function) {
|
|
43
|
+
declaration = {
|
|
44
|
+
script: scriptOrDeclaration, scriptAsync, key, mode,
|
|
45
|
+
creation, creationAsync, destruction, triggers, basis,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
43
48
|
else
|
|
44
|
-
declaration =
|
|
45
|
-
let
|
|
49
|
+
declaration = scriptOrDeclaration !== null && scriptOrDeclaration !== void 0 ? scriptOrDeclaration : {};
|
|
50
|
+
let effectiveKey = declaration.key;
|
|
46
51
|
const owner = gOwnSeat === null || gOwnSeat === void 0 ? void 0 : gOwnSeat.instance;
|
|
47
52
|
if (owner) {
|
|
48
|
-
let existing = owner.driver.child(owner, driver, declaration, basis);
|
|
53
|
+
let existing = owner.driver.child(owner, driver, declaration, declaration.basis);
|
|
49
54
|
const children = owner.children;
|
|
50
|
-
existing !== null && existing !== void 0 ? existing : (existing = children.tryMergeAsExisting(
|
|
55
|
+
existing !== null && existing !== void 0 ? existing : (existing = children.tryMergeAsExisting(effectiveKey = effectiveKey || generateKey(owner), undefined, "nested elements can be declared inside update function only"));
|
|
51
56
|
if (existing) {
|
|
52
57
|
result = existing.instance;
|
|
53
58
|
if (result.driver !== driver && driver !== undefined)
|
|
@@ -58,17 +63,24 @@ export class RxNode {
|
|
|
58
63
|
result.declaration = declaration;
|
|
59
64
|
}
|
|
60
65
|
else {
|
|
61
|
-
result = new RxNodeImpl(
|
|
66
|
+
result = new RxNodeImpl(effectiveKey || generateKey(owner), driver, declaration, owner);
|
|
62
67
|
result.seat = children.mergeAsAdded(result);
|
|
63
68
|
}
|
|
64
69
|
}
|
|
65
70
|
else {
|
|
66
|
-
result = new RxNodeImpl(
|
|
71
|
+
result = new RxNodeImpl(effectiveKey || "", driver, declaration, owner);
|
|
67
72
|
result.seat = MergeList.createItem(result);
|
|
68
73
|
triggerUpdateViaSeat(result.seat);
|
|
69
74
|
}
|
|
70
75
|
return result;
|
|
71
76
|
}
|
|
77
|
+
static rebased(declaration, basis) {
|
|
78
|
+
if (declaration)
|
|
79
|
+
declaration.basis = basis;
|
|
80
|
+
else
|
|
81
|
+
declaration = basis !== null && basis !== void 0 ? basis : {};
|
|
82
|
+
return declaration;
|
|
83
|
+
}
|
|
72
84
|
static get isFirstUpdate() {
|
|
73
85
|
return RxNodeImpl.ownSeat.instance.stamp === 1;
|
|
74
86
|
}
|
|
@@ -354,7 +366,7 @@ RxNodeImpl.disposableNodeCount = 0;
|
|
|
354
366
|
__decorate([
|
|
355
367
|
reactive,
|
|
356
368
|
options({
|
|
357
|
-
reentrance: Reentrance.
|
|
369
|
+
reentrance: Reentrance.cancelAndWaitPrevious,
|
|
358
370
|
allowObsoleteToFinish: true,
|
|
359
371
|
triggeringArgs: true,
|
|
360
372
|
noSideEffects: false,
|
|
@@ -12,6 +12,7 @@ export declare abstract class Transaction implements Worker {
|
|
|
12
12
|
abstract readonly error: Error | undefined;
|
|
13
13
|
abstract readonly changeset: Changeset;
|
|
14
14
|
abstract readonly margin: number;
|
|
15
|
+
abstract readonly parent?: Transaction;
|
|
15
16
|
abstract run<T>(func: F<T>, ...args: any[]): T;
|
|
16
17
|
abstract inspect<T>(func: F<T>, ...args: any[]): T;
|
|
17
18
|
abstract apply(): void;
|