reactronic 0.24.123 → 0.24.125
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/README.md +5 -5
- package/build/dist/source/Clock.d.ts +1 -1
- package/build/dist/source/Clock.js +2 -2
- package/build/dist/source/Logging.d.ts +4 -4
- package/build/dist/source/Logging.js +6 -6
- package/build/dist/source/Options.d.ts +12 -12
- package/build/dist/source/Options.js +1 -1
- package/build/dist/source/Pipe.d.ts +1 -1
- package/build/dist/source/Pipe.js +2 -2
- package/build/dist/source/Reaction.d.ts +2 -2
- package/build/dist/source/Reaction.js +2 -2
- package/build/dist/source/Ref.js +4 -4
- package/build/dist/source/RxSystem.d.ts +2 -2
- package/build/dist/source/RxSystem.js +7 -7
- package/build/dist/source/Worker.d.ts +3 -3
- package/build/dist/source/api.d.ts +23 -23
- package/build/dist/source/api.js +18 -18
- package/build/dist/source/core/Changeset.d.ts +2 -2
- package/build/dist/source/core/Changeset.js +33 -33
- package/build/dist/source/core/Data.d.ts +11 -11
- package/build/dist/source/core/Data.js +3 -3
- package/build/dist/source/core/Journal.d.ts +2 -2
- package/build/dist/source/core/Journal.js +12 -12
- package/build/dist/source/core/Meta.js +7 -7
- package/build/dist/source/core/Monitor.d.ts +2 -2
- package/build/dist/source/core/Monitor.js +6 -6
- package/build/dist/source/core/Mvcc.d.ts +6 -6
- package/build/dist/source/core/Mvcc.js +8 -8
- package/build/dist/source/core/MvccArray.d.ts +1 -1
- package/build/dist/source/core/MvccArray.js +2 -2
- package/build/dist/source/core/MvccMap.d.ts +1 -1
- package/build/dist/source/core/MvccMap.js +2 -2
- package/build/dist/source/core/MvccMergeList.d.ts +2 -2
- package/build/dist/source/core/MvccMergeList.js +1 -1
- package/build/dist/source/core/Reaction.d.ts +6 -6
- package/build/dist/source/core/Reaction.js +59 -59
- package/build/dist/source/core/RxNode.d.ts +9 -9
- package/build/dist/source/core/RxNode.js +15 -15
- package/build/dist/source/core/Transaction.d.ts +4 -4
- package/build/dist/source/core/Transaction.js +13 -13
- package/build/dist/source/util/Dbg.d.ts +1 -1
- package/build/dist/source/util/Dbg.js +11 -11
- package/build/dist/source/util/MergeList.d.ts +4 -4
- package/build/dist/source/util/MergeList.js +5 -5
- package/build/dist/source/util/Sealant.d.ts +4 -4
- package/build/dist/source/util/Sealant.js +5 -5
- package/build/dist/source/util/SealedArray.d.ts +1 -1
- package/build/dist/source/util/SealedArray.js +2 -2
- package/build/dist/source/util/SealedMap.d.ts +1 -1
- package/build/dist/source/util/SealedMap.js +2 -2
- package/build/dist/source/util/SealedSet.d.ts +1 -1
- package/build/dist/source/util/SealedSet.js +2 -2
- package/build/dist/source/util/Utils.js +14 -14
- package/package.json +4 -4
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Log, misuse } from
|
|
2
|
-
import { Kind, Reentrance } from
|
|
3
|
-
import { ObjectHandle, ValueSnapshot, Meta } from
|
|
4
|
-
import { Changeset, Dump, EMPTY_SNAPSHOT, MAX_REVISION } from
|
|
5
|
-
import { Transaction } from
|
|
6
|
-
import { MonitorImpl } from
|
|
7
|
-
import { Mvcc, OptionsImpl } from
|
|
8
|
-
import { JournalImpl } from
|
|
1
|
+
import { Log, misuse } from "../util/Dbg.js";
|
|
2
|
+
import { Kind, Reentrance } from "../Options.js";
|
|
3
|
+
import { ObjectHandle, ValueSnapshot, Meta } from "./Data.js";
|
|
4
|
+
import { Changeset, Dump, EMPTY_SNAPSHOT, MAX_REVISION } from "./Changeset.js";
|
|
5
|
+
import { Transaction } from "./Transaction.js";
|
|
6
|
+
import { MonitorImpl } from "./Monitor.js";
|
|
7
|
+
import { Mvcc, OptionsImpl } from "./Mvcc.js";
|
|
8
|
+
import { JournalImpl } from "./Journal.js";
|
|
9
9
|
const BOOT_ARGS = [];
|
|
10
|
-
const BOOT_CAUSE =
|
|
11
|
-
const EMPTY_HANDLE = new ObjectHandle(undefined, undefined, Mvcc.observable, EMPTY_SNAPSHOT,
|
|
10
|
+
const BOOT_CAUSE = "<boot>";
|
|
11
|
+
const EMPTY_HANDLE = new ObjectHandle(undefined, undefined, Mvcc.observable, EMPTY_SNAPSHOT, "<boot>");
|
|
12
12
|
export class ReactionImpl {
|
|
13
13
|
configure(options) { return ReactionImpl.configureImpl(this, options); }
|
|
14
14
|
get options() { return this.peek(undefined).launch.options; }
|
|
@@ -18,7 +18,7 @@ export class ReactionImpl {
|
|
|
18
18
|
get error() { return this.use().launch.error; }
|
|
19
19
|
get stamp() { return this.use().snapshot.changeset.timestamp; }
|
|
20
20
|
get isUpToDate() { return this.use().isUpToDate; }
|
|
21
|
-
markObsolete() { Transaction.run({ hint: Log.isOn ? `markObsolete(${Dump.obj(this.objectHandle, this.memberName)})` :
|
|
21
|
+
markObsolete() { Transaction.run({ hint: Log.isOn ? `markObsolete(${Dump.obj(this.objectHandle, this.memberName)})` : "markObsolete()" }, ReactionImpl.markObsolete, this); }
|
|
22
22
|
pullLastResult(args) { return this.reuseOrRelaunch(true, args).content; }
|
|
23
23
|
constructor(h, m) {
|
|
24
24
|
this.objectHandle = h;
|
|
@@ -46,7 +46,7 @@ export class ReactionImpl {
|
|
|
46
46
|
}
|
|
47
47
|
else if (Log.isOn && Log.opt.operation && (opts.logging === undefined ||
|
|
48
48
|
opts.logging.operation === undefined || opts.logging.operation === true))
|
|
49
|
-
Log.write(Transaction.current.isFinished ?
|
|
49
|
+
Log.write(Transaction.current.isFinished ? "" : "║", " (=)", `${Dump.snapshot2(ror.launch.reaction.objectHandle, ror.changeset, this.memberName)} result is reused from T${ror.launch.transaction.id}[${ror.launch.transaction.hint}]`);
|
|
50
50
|
const t = ror.launch;
|
|
51
51
|
Changeset.markUsed(t, ror.snapshot, this.memberName, this.objectHandle, t.options.kind, weak);
|
|
52
52
|
return t;
|
|
@@ -64,10 +64,10 @@ export class ReactionImpl {
|
|
|
64
64
|
else
|
|
65
65
|
launch = Launch.current;
|
|
66
66
|
if (!launch)
|
|
67
|
-
throw misuse(
|
|
67
|
+
throw misuse("reactronic decorator is only applicable to methods");
|
|
68
68
|
launch.options = new OptionsImpl(launch.options.getter, launch.options.setter, launch.options, options, false);
|
|
69
69
|
if (Log.isOn && Log.opt.write)
|
|
70
|
-
Log.write(
|
|
70
|
+
Log.write("║", " =", `${launch.hint()}.options are changed`);
|
|
71
71
|
return launch.options;
|
|
72
72
|
}
|
|
73
73
|
static proceedWithinGivenLaunch(launch, func, ...args) {
|
|
@@ -97,7 +97,7 @@ export class ReactionImpl {
|
|
|
97
97
|
}
|
|
98
98
|
static dependencies() {
|
|
99
99
|
const l = Launch.current;
|
|
100
|
-
return l ? l.dependencies() : [
|
|
100
|
+
return l ? l.dependencies() : ["RxSystem.dependencies should be called from inside of reactive method"];
|
|
101
101
|
}
|
|
102
102
|
peek(args) {
|
|
103
103
|
const ctx = Changeset.current();
|
|
@@ -134,7 +134,7 @@ export class ReactionImpl {
|
|
|
134
134
|
let launch = os.data[m];
|
|
135
135
|
if (launch.reaction !== this) {
|
|
136
136
|
if (os.changeset !== EMPTY_SNAPSHOT.changeset) {
|
|
137
|
-
const hint = Log.isOn ? `${Dump.obj(this.objectHandle, m)}/init` :
|
|
137
|
+
const hint = Log.isOn ? `${Dump.obj(this.objectHandle, m)}/init` : "MethodController/init";
|
|
138
138
|
const separation = os.changeset.sealed || os.former.snapshot !== EMPTY_SNAPSHOT;
|
|
139
139
|
launch = Transaction.run({ hint, separation, token: this }, () => {
|
|
140
140
|
const h = this.objectHandle;
|
|
@@ -161,20 +161,20 @@ export class ReactionImpl {
|
|
|
161
161
|
os.data[m] = initialLaunch;
|
|
162
162
|
launch = initialLaunch;
|
|
163
163
|
if (Log.isOn && Log.opt.write)
|
|
164
|
-
Log.write(
|
|
164
|
+
Log.write("║", " ++", `${Dump.obj(this.objectHandle, m)} is initialized (revision ${os.revision})`);
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
return launch;
|
|
168
168
|
}
|
|
169
169
|
relaunch(existing, separation, options, token, args) {
|
|
170
|
-
const hint = Log.isOn ? `${Dump.obj(this.objectHandle, this.memberName)}${args && args.length > 0 && (typeof args[0] ===
|
|
170
|
+
const hint = Log.isOn ? `${Dump.obj(this.objectHandle, this.memberName)}${args && args.length > 0 && (typeof args[0] === "number" || typeof args[0] === "string") ? ` - ${args[0]}` : ""}` : `${Dump.obj(this.objectHandle, this.memberName)}`;
|
|
171
171
|
let ror = existing;
|
|
172
172
|
const opts = { hint, separation, journal: options.journal, logging: options.logging, token };
|
|
173
173
|
const result = Transaction.run(opts, (argsx) => {
|
|
174
174
|
if (!ror.launch.transaction.isCanceled) {
|
|
175
175
|
ror = this.edit();
|
|
176
176
|
if (Log.isOn && Log.opt.operation)
|
|
177
|
-
Log.write(
|
|
177
|
+
Log.write("║", " o", `${ror.launch.why()}`);
|
|
178
178
|
ror.launch.proceed(this.objectHandle.proxy, argsx);
|
|
179
179
|
}
|
|
180
180
|
else {
|
|
@@ -182,7 +182,7 @@ export class ReactionImpl {
|
|
|
182
182
|
if (ror.launch.options.kind === Kind.Transactional || !ror.isUpToDate) {
|
|
183
183
|
ror = this.edit();
|
|
184
184
|
if (Log.isOn && Log.opt.operation)
|
|
185
|
-
Log.write(
|
|
185
|
+
Log.write("║", " o", `${ror.launch.why()}`);
|
|
186
186
|
ror.launch.proceed(this.objectHandle.proxy, argsx);
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -224,7 +224,7 @@ class Launch extends ValueSnapshot {
|
|
|
224
224
|
get originSnapshotId() { return this.changeset.id; }
|
|
225
225
|
hint() { return `${Dump.snapshot2(this.reaction.objectHandle, this.changeset, this.reaction.memberName)}`; }
|
|
226
226
|
get order() { return this.options.order; }
|
|
227
|
-
get [
|
|
227
|
+
get ["#this#"]() {
|
|
228
228
|
return `Operation: ${this.why()}`;
|
|
229
229
|
}
|
|
230
230
|
why() {
|
|
@@ -232,7 +232,7 @@ class Launch extends ValueSnapshot {
|
|
|
232
232
|
if (this.cause)
|
|
233
233
|
cause = ` ◀◀ ${this.cause}`;
|
|
234
234
|
else if (this.reaction.options.kind === Kind.Transactional)
|
|
235
|
-
cause =
|
|
235
|
+
cause = " ◀◀ operation";
|
|
236
236
|
else
|
|
237
237
|
cause = ` ◀◀ T${this.changeset.id}[${this.changeset.hint}]`;
|
|
238
238
|
return `${this.hint()}${cause}`;
|
|
@@ -241,19 +241,19 @@ class Launch extends ValueSnapshot {
|
|
|
241
241
|
return this.why();
|
|
242
242
|
}
|
|
243
243
|
dependencies() {
|
|
244
|
-
throw misuse(
|
|
244
|
+
throw misuse("not implemented yet");
|
|
245
245
|
}
|
|
246
246
|
wrap(func) {
|
|
247
247
|
const wrappedForOperation = (...args) => {
|
|
248
248
|
if (Log.isOn && Log.opt.step && this.result)
|
|
249
|
-
Log.writeAs({ margin2: this.margin },
|
|
249
|
+
Log.writeAs({ margin2: this.margin }, "║", "‾\\", `${this.hint()} - step in `, 0, " │");
|
|
250
250
|
const started = Date.now();
|
|
251
251
|
const result = ReactionImpl.proceedWithinGivenLaunch(this, func, ...args);
|
|
252
252
|
const ms = Date.now() - started;
|
|
253
253
|
if (Log.isOn && Log.opt.step && this.result)
|
|
254
|
-
Log.writeAs({ margin2: this.margin },
|
|
254
|
+
Log.writeAs({ margin2: this.margin }, "║", "_/", `${this.hint()} - step out `, 0, this.started > 0 ? " │" : "");
|
|
255
255
|
if (ms > Mvcc.mainThreadBlockingWarningThreshold)
|
|
256
|
-
Log.write(
|
|
256
|
+
Log.write("", "[!]", this.why(), ms, " *** main thread is too busy ***");
|
|
257
257
|
return result;
|
|
258
258
|
};
|
|
259
259
|
return wrappedForOperation;
|
|
@@ -278,9 +278,9 @@ class Launch extends ValueSnapshot {
|
|
|
278
278
|
this.obsoleteDueTo = why;
|
|
279
279
|
this.obsoleteSince = since;
|
|
280
280
|
if (Log.isOn && (Log.opt.obsolete || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.obsolete)))
|
|
281
|
-
Log.write(Log.opt.transaction && !Changeset.current().sealed ?
|
|
281
|
+
Log.write(Log.opt.transaction && !Changeset.current().sealed ? "║" : " ", isReactive ? "█" : "▒", isReactive && changeset === EMPTY_SNAPSHOT.changeset
|
|
282
282
|
? `${this.hint()} is reactive and will run automatically (order ${this.options.order})`
|
|
283
|
-
: `${this.hint()} is obsolete due to ${Dump.snapshot2(h, changeset, m)} since s${since}${isReactive ? ` and will run automatically (order ${this.options.order})` :
|
|
283
|
+
: `${this.hint()} is obsolete due to ${Dump.snapshot2(h, changeset, m)} since s${since}${isReactive ? ` and will run automatically (order ${this.options.order})` : ""}`);
|
|
284
284
|
this.unsubscribeFromAllObservables();
|
|
285
285
|
if (isReactive)
|
|
286
286
|
obsolete.push(this);
|
|
@@ -293,7 +293,7 @@ class Launch extends ValueSnapshot {
|
|
|
293
293
|
tran.cancel(new Error(`T${tran.id}[${tran.hint}] is canceled due to obsolete ${Dump.snapshot2(h, changeset, m)} changed by T${changeset.id}[${changeset.hint}]`), null);
|
|
294
294
|
}
|
|
295
295
|
else if (Log.isOn && (Log.opt.obsolete || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.obsolete)))
|
|
296
|
-
Log.write(
|
|
296
|
+
Log.write(" ", "x", `${this.hint()} is not obsolete due to its own change to ${Dump.snapshot2(h, changeset, m)}`);
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
relaunchIfNotUpToDate(now, nothrow) {
|
|
@@ -334,7 +334,7 @@ class Launch extends ValueSnapshot {
|
|
|
334
334
|
const opponent = head.successor;
|
|
335
335
|
if (opponent && !opponent.transaction.isFinished) {
|
|
336
336
|
if (Log.isOn && Log.opt.obsolete)
|
|
337
|
-
Log.write(
|
|
337
|
+
Log.write("║", " [!]", `${this.hint()} is trying to re-enter over ${opponent.hint()}`);
|
|
338
338
|
switch (head.options.reentrance) {
|
|
339
339
|
case Reentrance.PreventWithError:
|
|
340
340
|
if (!opponent.transaction.isCanceled)
|
|
@@ -377,47 +377,47 @@ class Launch extends ValueSnapshot {
|
|
|
377
377
|
if (this.options.monitor)
|
|
378
378
|
this.monitorEnter(this.options.monitor);
|
|
379
379
|
if (Log.isOn && Log.opt.operation)
|
|
380
|
-
Log.write(
|
|
380
|
+
Log.write("║", "‾\\", `${this.hint()} - enter`, undefined, ` [ ${Dump.obj(this.reaction.objectHandle, this.reaction.memberName)} ]`);
|
|
381
381
|
this.started = Date.now();
|
|
382
382
|
}
|
|
383
383
|
leaveOrAsync() {
|
|
384
384
|
if (this.result instanceof Promise) {
|
|
385
385
|
this.result = this.result.then(value => {
|
|
386
386
|
this.content = value;
|
|
387
|
-
this.leave(false,
|
|
387
|
+
this.leave(false, " ⚐", "- finished ", " OK ──┘");
|
|
388
388
|
return value;
|
|
389
389
|
}, error => {
|
|
390
390
|
this.error = error;
|
|
391
|
-
this.leave(false,
|
|
391
|
+
this.leave(false, " ⚐", "- finished ", "ERR ──┘");
|
|
392
392
|
throw error;
|
|
393
393
|
});
|
|
394
394
|
if (Log.isOn) {
|
|
395
395
|
if (Log.opt.operation)
|
|
396
|
-
Log.write(
|
|
396
|
+
Log.write("║", "_/", `${this.hint()} - leave... `, 0, "ASYNC ──┐");
|
|
397
397
|
else if (Log.opt.transaction)
|
|
398
|
-
Log.write(
|
|
398
|
+
Log.write("║", " ", `${this.why()} ...`, 0, "ASYNC");
|
|
399
399
|
}
|
|
400
400
|
}
|
|
401
401
|
else {
|
|
402
402
|
this.content = this.result;
|
|
403
|
-
this.leave(true,
|
|
403
|
+
this.leave(true, "_/", "- leave");
|
|
404
404
|
}
|
|
405
405
|
}
|
|
406
406
|
leave(main, op, message, highlight = undefined) {
|
|
407
407
|
const ms = Date.now() - this.started;
|
|
408
408
|
this.started = -this.started;
|
|
409
409
|
if (Log.isOn && Log.opt.operation)
|
|
410
|
-
Log.write(
|
|
410
|
+
Log.write("║", `${op}`, `${this.hint()} ${message}`, ms, highlight);
|
|
411
411
|
if (ms > (main ? Mvcc.mainThreadBlockingWarningThreshold : Mvcc.asyncActionDurationWarningThreshold))
|
|
412
|
-
Log.write(
|
|
412
|
+
Log.write("", "[!]", this.why(), ms, main ? " *** main thread is too busy ***" : " *** async is too long ***");
|
|
413
413
|
this.cause = undefined;
|
|
414
414
|
if (this.options.monitor)
|
|
415
415
|
this.monitorLeave(this.options.monitor);
|
|
416
416
|
}
|
|
417
417
|
monitorEnter(mon) {
|
|
418
418
|
const options = {
|
|
419
|
-
hint:
|
|
420
|
-
separation:
|
|
419
|
+
hint: "Monitor.enter",
|
|
420
|
+
separation: "isolated",
|
|
421
421
|
logging: Log.isOn && Log.opt.monitor ? undefined : Log.global
|
|
422
422
|
};
|
|
423
423
|
ReactionImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options, MonitorImpl.enter, mon, this.transaction);
|
|
@@ -426,8 +426,8 @@ class Launch extends ValueSnapshot {
|
|
|
426
426
|
Transaction.outside(() => {
|
|
427
427
|
const leave = () => {
|
|
428
428
|
const options = {
|
|
429
|
-
hint:
|
|
430
|
-
separation:
|
|
429
|
+
hint: "Monitor.leave",
|
|
430
|
+
separation: "isolated",
|
|
431
431
|
logging: Log.isOn && Log.opt.monitor ? undefined : Log.DefaultLevel
|
|
432
432
|
};
|
|
433
433
|
ReactionImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options, MonitorImpl.leave, mon, this.transaction);
|
|
@@ -463,7 +463,7 @@ class Launch extends ValueSnapshot {
|
|
|
463
463
|
static markEdited(oldValue, newValue, edited, os, m, h) {
|
|
464
464
|
edited ? os.changes.add(m) : os.changes.delete(m);
|
|
465
465
|
if (Log.isOn && Log.opt.write)
|
|
466
|
-
edited ? Log.write(
|
|
466
|
+
edited ? Log.write("║", " =", `${Dump.snapshot2(h, os.changeset, m)} is changed: ${valueHint(oldValue)} ▸▸ ${valueHint(newValue)}`) : Log.write("║", " =", `${Dump.snapshot2(h, os.changeset, m)} is changed: ${valueHint(oldValue)} ▸▸ ${valueHint(newValue)}`, undefined, " (same as previous)");
|
|
467
467
|
}
|
|
468
468
|
static isConflicting(oldValue, newValue) {
|
|
469
469
|
let result = oldValue !== newValue;
|
|
@@ -521,7 +521,7 @@ class Launch extends ValueSnapshot {
|
|
|
521
521
|
if (Mvcc.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
522
522
|
curr.observables.forEach((info, v) => {
|
|
523
523
|
if (info.usageCount > Mvcc.repetitiveUsageWarningThreshold)
|
|
524
|
-
Log.write(
|
|
524
|
+
Log.write("", "[!]", `${curr.hint()} uses ${info.memberHint} ${info.usageCount} times (consider remembering it in a local variable)`, 0, " *** WARNING ***");
|
|
525
525
|
});
|
|
526
526
|
}
|
|
527
527
|
if (unsubscribe)
|
|
@@ -555,7 +555,7 @@ class Launch extends ValueSnapshot {
|
|
|
555
555
|
var _a;
|
|
556
556
|
value.observers.delete(this);
|
|
557
557
|
if (Log.isOn && (Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
558
|
-
Log.write(Log.opt.transaction && !Changeset.current().sealed ?
|
|
558
|
+
Log.write(Log.opt.transaction && !Changeset.current().sealed ? "║" : " ", "-", `${this.hint()} is unsubscribed from ${info.memberHint}`);
|
|
559
559
|
});
|
|
560
560
|
this.observables = undefined;
|
|
561
561
|
}
|
|
@@ -575,14 +575,14 @@ class Launch extends ValueSnapshot {
|
|
|
575
575
|
observable.observers.add(this);
|
|
576
576
|
this.observables.set(observable, subscription);
|
|
577
577
|
if (Log.isOn && (Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
578
|
-
Log.write(
|
|
578
|
+
Log.write("║", " ∞", `${this.hint()} is subscribed to ${Dump.snapshot2(h, os.changeset, m)}${subscription.usageCount > 1 ? ` (${subscription.usageCount} times)` : ""}`);
|
|
579
579
|
}
|
|
580
580
|
else if (Log.isOn && (Log.opt.read || ((_b = this.options.logging) === null || _b === void 0 ? void 0 : _b.read)))
|
|
581
|
-
Log.write(
|
|
581
|
+
Log.write("║", " x", `${this.hint()} is obsolete and is NOT subscribed to ${Dump.snapshot2(h, os.changeset, m)}`);
|
|
582
582
|
}
|
|
583
583
|
else {
|
|
584
584
|
if (Log.isOn && (Log.opt.read || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.read)))
|
|
585
|
-
Log.write(
|
|
585
|
+
Log.write("║", " x", `${this.hint()} is NOT subscribed to already obsolete ${Dump.snapshot2(h, os.changeset, m)}`);
|
|
586
586
|
}
|
|
587
587
|
return ok;
|
|
588
588
|
}
|
|
@@ -631,20 +631,20 @@ class Launch extends ValueSnapshot {
|
|
|
631
631
|
Mvcc.rememberOperationOptions = Launch.rememberOperationOptions;
|
|
632
632
|
Promise.prototype.then = reactronicHookedThen;
|
|
633
633
|
try {
|
|
634
|
-
Object.defineProperty(globalThis,
|
|
634
|
+
Object.defineProperty(globalThis, "rWhy", {
|
|
635
635
|
get: ReactionImpl.why, configurable: false, enumerable: false,
|
|
636
636
|
});
|
|
637
|
-
Object.defineProperty(globalThis,
|
|
637
|
+
Object.defineProperty(globalThis, "rBriefWhy", {
|
|
638
638
|
get: ReactionImpl.briefWhy, configurable: false, enumerable: false,
|
|
639
639
|
});
|
|
640
640
|
}
|
|
641
641
|
catch (e) {
|
|
642
642
|
}
|
|
643
643
|
try {
|
|
644
|
-
Object.defineProperty(global,
|
|
644
|
+
Object.defineProperty(global, "rWhy", {
|
|
645
645
|
get: ReactionImpl.why, configurable: false, enumerable: false,
|
|
646
646
|
});
|
|
647
|
-
Object.defineProperty(global,
|
|
647
|
+
Object.defineProperty(global, "rBriefWhy", {
|
|
648
648
|
get: ReactionImpl.briefWhy, configurable: false, enumerable: false,
|
|
649
649
|
});
|
|
650
650
|
}
|
|
@@ -656,7 +656,7 @@ Launch.current = undefined;
|
|
|
656
656
|
Launch.queuedReactiveFunctions = [];
|
|
657
657
|
Launch.deferredReactiveFunctions = [];
|
|
658
658
|
function valueHint(value) {
|
|
659
|
-
let result =
|
|
659
|
+
let result = "";
|
|
660
660
|
if (Array.isArray(value))
|
|
661
661
|
result = `Array(${value.length})`;
|
|
662
662
|
else if (value instanceof Set)
|
|
@@ -664,20 +664,20 @@ function valueHint(value) {
|
|
|
664
664
|
else if (value instanceof Map)
|
|
665
665
|
result = `Map(${value.size})`;
|
|
666
666
|
else if (value instanceof Launch)
|
|
667
|
-
result = `#${value.reaction.objectHandle.id}t${value.changeset.id}s${value.changeset.timestamp}${value.originSnapshotId !== undefined && value.originSnapshotId !== 0 ? `t${value.originSnapshotId}` :
|
|
667
|
+
result = `#${value.reaction.objectHandle.id}t${value.changeset.id}s${value.changeset.timestamp}${value.originSnapshotId !== undefined && value.originSnapshotId !== 0 ? `t${value.originSnapshotId}` : ""}`;
|
|
668
668
|
else if (value === Meta.Undefined)
|
|
669
|
-
result =
|
|
670
|
-
else if (typeof (value) ===
|
|
671
|
-
result = `"${value.toString().slice(0, 20)}${value.length > 20 ?
|
|
669
|
+
result = "undefined";
|
|
670
|
+
else if (typeof (value) === "string")
|
|
671
|
+
result = `"${value.toString().slice(0, 20)}${value.length > 20 ? "..." : ""}"`;
|
|
672
672
|
else if (value !== undefined && value !== null)
|
|
673
673
|
result = value.toString().slice(0, 40);
|
|
674
674
|
else
|
|
675
|
-
result =
|
|
675
|
+
result = "undefined";
|
|
676
676
|
return result;
|
|
677
677
|
}
|
|
678
678
|
function getMergedLoggingOptions(local) {
|
|
679
679
|
const t = Transaction.current;
|
|
680
|
-
let res = Log.merge(t.options.logging, t.id > 1 ? 31 + t.id % 6 : 37, t.id > 1 ? `T${t.id}` : `-${Changeset.idGen.toString().replace(/[0-9]/g,
|
|
680
|
+
let res = Log.merge(t.options.logging, t.id > 1 ? 31 + t.id % 6 : 37, t.id > 1 ? `T${t.id}` : `-${Changeset.idGen.toString().replace(/[0-9]/g, "-")}`, Log.global);
|
|
681
681
|
res = Log.merge({ margin1: t.margin }, undefined, undefined, res);
|
|
682
682
|
if (Launch.current)
|
|
683
683
|
res = Log.merge({ margin2: Launch.current.margin }, undefined, undefined, res);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { LoggingOptions } from
|
|
2
|
-
import { MergeListReader, MergedItem } from
|
|
3
|
-
import { MemberOptions } from
|
|
1
|
+
import { LoggingOptions } from "../Logging.js";
|
|
2
|
+
import { MergeListReader, MergedItem } from "../util/MergeList.js";
|
|
3
|
+
import { MemberOptions } from "../Options.js";
|
|
4
4
|
export type Delegate<T> = (element: T, base: () => void) => void;
|
|
5
5
|
export type SimpleDelegate<T = unknown, R = void> = (element: T) => R;
|
|
6
6
|
export declare enum Mode {
|
|
@@ -53,7 +53,7 @@ export declare abstract class RxNode<E = unknown> {
|
|
|
53
53
|
static getDefaultLoggingOptions(): LoggingOptions | undefined;
|
|
54
54
|
static setDefaultLoggingOptions(logging?: LoggingOptions): void;
|
|
55
55
|
}
|
|
56
|
-
export
|
|
56
|
+
export type RxNodeDecl<E = unknown> = {
|
|
57
57
|
preset?: RxNodeDecl<E>;
|
|
58
58
|
key?: string;
|
|
59
59
|
mode?: Mode;
|
|
@@ -61,8 +61,8 @@ export interface RxNodeDecl<E = unknown> {
|
|
|
61
61
|
initialize?: Delegate<E>;
|
|
62
62
|
update?: Delegate<E>;
|
|
63
63
|
finalize?: Delegate<E>;
|
|
64
|
-
}
|
|
65
|
-
export
|
|
64
|
+
};
|
|
65
|
+
export type RxNodeDriver<E = unknown> = {
|
|
66
66
|
readonly name: string;
|
|
67
67
|
readonly isPartitionSeparator: boolean;
|
|
68
68
|
readonly predefine?: SimpleDelegate<E>;
|
|
@@ -71,10 +71,10 @@ export interface RxNodeDriver<E = unknown> {
|
|
|
71
71
|
mount(node: RxNode<E>): void;
|
|
72
72
|
update(node: RxNode<E>): void | Promise<void>;
|
|
73
73
|
finalize(node: RxNode<E>, isLeader: boolean): boolean;
|
|
74
|
-
}
|
|
75
|
-
export
|
|
74
|
+
};
|
|
75
|
+
export type RxNodeContext<T extends Object = Object> = {
|
|
76
76
|
value: T;
|
|
77
|
-
}
|
|
77
|
+
};
|
|
78
78
|
export declare abstract class BaseDriver<E = unknown> implements RxNodeDriver<E> {
|
|
79
79
|
readonly name: string;
|
|
80
80
|
readonly isPartitionSeparator: boolean;
|
|
@@ -16,12 +16,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
16
16
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
17
17
|
});
|
|
18
18
|
};
|
|
19
|
-
import { MergeList } from
|
|
20
|
-
import { emitLetters, getCallerInfo } from
|
|
21
|
-
import { Reentrance } from
|
|
22
|
-
import { ObservableObject } from
|
|
23
|
-
import { Transaction } from
|
|
24
|
-
import { RxSystem, options, raw, reactive, unobs } from
|
|
19
|
+
import { MergeList } from "../util/MergeList.js";
|
|
20
|
+
import { emitLetters, getCallerInfo } from "../util/Utils.js";
|
|
21
|
+
import { Reentrance } from "../Options.js";
|
|
22
|
+
import { ObservableObject } from "../core/Mvcc.js";
|
|
23
|
+
import { Transaction } from "../core/Transaction.js";
|
|
24
|
+
import { RxSystem, options, raw, reactive, unobs } from "../RxSystem.js";
|
|
25
25
|
export var Mode;
|
|
26
26
|
(function (Mode) {
|
|
27
27
|
Mode[Mode["Default"] = 0] = "Default";
|
|
@@ -52,7 +52,7 @@ export class RxNode {
|
|
|
52
52
|
if (((_a = last === null || last === void 0 ? void 0 : last.instance) === null || _a === void 0 ? void 0 : _a.driver) === driver)
|
|
53
53
|
existing = last;
|
|
54
54
|
}
|
|
55
|
-
existing !== null && existing !== void 0 ? existing : (existing = children.tryMergeAsExisting(key = key || generateKey(owner), undefined,
|
|
55
|
+
existing !== null && existing !== void 0 ? existing : (existing = children.tryMergeAsExisting(key = key || generateKey(owner), undefined, "nested elements can be declared inside update function only"));
|
|
56
56
|
if (existing) {
|
|
57
57
|
result = existing.instance;
|
|
58
58
|
if (result.driver !== driver && driver !== undefined)
|
|
@@ -68,7 +68,7 @@ export class RxNode {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
else {
|
|
71
|
-
result = new RxNodeImpl(key ||
|
|
71
|
+
result = new RxNodeImpl(key || "", driver, declaration, owner);
|
|
72
72
|
result.seat = MergeList.createItem(result);
|
|
73
73
|
triggerUpdateViaSeat(result.seat);
|
|
74
74
|
}
|
|
@@ -112,9 +112,9 @@ export class RxNode {
|
|
|
112
112
|
static markAsMounted(node, yes) {
|
|
113
113
|
const n = node;
|
|
114
114
|
if (n.stamp < 0)
|
|
115
|
-
throw new Error(
|
|
115
|
+
throw new Error("finalized node cannot be mounted or unmounted");
|
|
116
116
|
if (n.stamp >= Number.MAX_SAFE_INTEGER)
|
|
117
|
-
throw new Error(
|
|
117
|
+
throw new Error("node must be initialized before mounting");
|
|
118
118
|
n.stamp = yes ? 0 : Number.MAX_SAFE_INTEGER - 1;
|
|
119
119
|
}
|
|
120
120
|
static findMatchingHost(node, match) {
|
|
@@ -276,12 +276,12 @@ class RxNodeImpl extends RxNode {
|
|
|
276
276
|
}
|
|
277
277
|
configureReactronic(options) {
|
|
278
278
|
if (this.stamp < Number.MAX_SAFE_INTEGER - 1 || !this.has(Mode.IndependentUpdate))
|
|
279
|
-
throw new Error(
|
|
279
|
+
throw new Error("reactronic can be configured only for elements with independent update mode and only inside initialize");
|
|
280
280
|
return RxSystem.getReaction(this.update).configure(options);
|
|
281
281
|
}
|
|
282
282
|
static get ownSeat() {
|
|
283
283
|
if (!gOwnSeat)
|
|
284
|
-
throw new Error(
|
|
284
|
+
throw new Error("current element is undefined");
|
|
285
285
|
return gOwnSeat;
|
|
286
286
|
}
|
|
287
287
|
static tryUseNodeVariableValue(variable) {
|
|
@@ -295,7 +295,7 @@ class RxNodeImpl extends RxNode {
|
|
|
295
295
|
var _a;
|
|
296
296
|
const result = (_a = RxNodeImpl.tryUseNodeVariableValue(variable)) !== null && _a !== void 0 ? _a : variable.defaultValue;
|
|
297
297
|
if (!result)
|
|
298
|
-
throw new Error(
|
|
298
|
+
throw new Error("unknown node variable");
|
|
299
299
|
return result;
|
|
300
300
|
}
|
|
301
301
|
static setNodeVariableValue(variable, value) {
|
|
@@ -486,7 +486,7 @@ function updateNow(seat) {
|
|
|
486
486
|
const driver = node.driver;
|
|
487
487
|
result = driver.update(node);
|
|
488
488
|
if (result instanceof Promise)
|
|
489
|
-
result.then(v => { runUpdateNestedNodesThenDo(undefined, NOP); return v; }, e => { console.log(e); runUpdateNestedNodesThenDo(e !== null && e !== void 0 ? e : new Error(
|
|
489
|
+
result.then(v => { runUpdateNestedNodesThenDo(undefined, NOP); return v; }, e => { console.log(e); runUpdateNestedNodesThenDo(e !== null && e !== void 0 ? e : new Error("unknown error"), NOP); });
|
|
490
490
|
else
|
|
491
491
|
runUpdateNestedNodesThenDo(undefined, NOP);
|
|
492
492
|
}
|
|
@@ -515,7 +515,7 @@ function triggerFinalization(seat, isLeader, individual) {
|
|
|
515
515
|
else
|
|
516
516
|
gFirstToDispose = gLastToDispose = seat;
|
|
517
517
|
if (gFirstToDispose === seat)
|
|
518
|
-
Transaction.run({ separation:
|
|
518
|
+
Transaction.run({ separation: "disposal", hint: `runDisposalLoop(initiator=${seat.instance.key})` }, () => {
|
|
519
519
|
void runDisposalLoop().then(NOP, error => console.log(error));
|
|
520
520
|
});
|
|
521
521
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { F } from
|
|
2
|
-
import { Worker } from
|
|
3
|
-
import { SnapshotOptions } from
|
|
4
|
-
import { Changeset } from
|
|
1
|
+
import { F } from "../util/Utils.js";
|
|
2
|
+
import { Worker } from "../Worker.js";
|
|
3
|
+
import { SnapshotOptions } from "../Options.js";
|
|
4
|
+
import { Changeset } from "./Changeset.js";
|
|
5
5
|
export declare abstract class Transaction implements Worker {
|
|
6
6
|
static get current(): Transaction;
|
|
7
7
|
abstract readonly id: number;
|
|
@@ -7,9 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { UNDEF, pause } from
|
|
11
|
-
import { Log, misuse, error, fatal } from
|
|
12
|
-
import { Changeset, Dump } from
|
|
10
|
+
import { UNDEF, pause } from "../util/Utils.js";
|
|
11
|
+
import { Log, misuse, error, fatal } from "../util/Dbg.js";
|
|
12
|
+
import { Changeset, Dump } from "./Changeset.js";
|
|
13
13
|
export class Transaction {
|
|
14
14
|
static get current() { return TransactionImpl.current; }
|
|
15
15
|
whenFinished() {
|
|
@@ -51,7 +51,7 @@ class TransactionImpl extends Transaction {
|
|
|
51
51
|
try {
|
|
52
52
|
TransactionImpl.inspection = true;
|
|
53
53
|
if (Log.isOn && Log.opt.transaction)
|
|
54
|
-
Log.write(
|
|
54
|
+
Log.write(" ", " ", `T${this.id}[${this.hint}] is being inspected by T${TransactionImpl.curr.id}[${TransactionImpl.curr.hint}]`);
|
|
55
55
|
return this.runImpl(undefined, func, ...args);
|
|
56
56
|
}
|
|
57
57
|
finally {
|
|
@@ -60,7 +60,7 @@ class TransactionImpl extends Transaction {
|
|
|
60
60
|
}
|
|
61
61
|
apply() {
|
|
62
62
|
if (this.pending > 0)
|
|
63
|
-
throw misuse(
|
|
63
|
+
throw misuse("cannot apply transaction having active operations running");
|
|
64
64
|
if (this.canceled)
|
|
65
65
|
throw misuse(`cannot apply transaction that is already canceled: ${this.canceled}`);
|
|
66
66
|
this.seal();
|
|
@@ -153,14 +153,14 @@ class TransactionImpl extends Transaction {
|
|
|
153
153
|
}
|
|
154
154
|
static acquire(options) {
|
|
155
155
|
const curr = TransactionImpl.curr;
|
|
156
|
-
if ((options === null || options === void 0 ? void 0 : options.separation) || curr.isFinished || curr.options.separation ===
|
|
156
|
+
if ((options === null || options === void 0 ? void 0 : options.separation) || curr.isFinished || curr.options.separation === "isolated")
|
|
157
157
|
return new TransactionImpl(options);
|
|
158
158
|
else
|
|
159
159
|
return TransactionImpl.curr;
|
|
160
160
|
}
|
|
161
161
|
guard() {
|
|
162
162
|
if (this.sealed && TransactionImpl.curr !== this)
|
|
163
|
-
throw misuse(
|
|
163
|
+
throw misuse("cannot run transaction that is already sealed");
|
|
164
164
|
}
|
|
165
165
|
wrapToRetry(p, func, ...args) {
|
|
166
166
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -176,7 +176,7 @@ class TransactionImpl extends Transaction {
|
|
|
176
176
|
yield this.after.whenFinished();
|
|
177
177
|
const options = {
|
|
178
178
|
hint: `${this.hint} - restart after T${this.after.id}`,
|
|
179
|
-
separation: this.options.separation ===
|
|
179
|
+
separation: this.options.separation === "isolated" ? "isolated" : true,
|
|
180
180
|
logging: this.changeset.options.logging,
|
|
181
181
|
token: this.changeset.options.token,
|
|
182
182
|
};
|
|
@@ -238,9 +238,9 @@ class TransactionImpl extends Transaction {
|
|
|
238
238
|
t.canceled = error;
|
|
239
239
|
t.after = after;
|
|
240
240
|
if (Log.isOn && Log.opt.transaction) {
|
|
241
|
-
Log.write(
|
|
241
|
+
Log.write("║", " [!]", `${error.message}`, undefined, " *** CANCEL ***");
|
|
242
242
|
if (after && after !== TransactionImpl.none)
|
|
243
|
-
Log.write(
|
|
243
|
+
Log.write("║", " [!]", `T${t.id}[${t.hint}] will be restarted${t !== after ? ` after T${after.id}[${after.hint}]` : ""}`);
|
|
244
244
|
}
|
|
245
245
|
Changeset.revokeAllSubscriptions(t.changeset);
|
|
246
246
|
}
|
|
@@ -258,7 +258,7 @@ class TransactionImpl extends Transaction {
|
|
|
258
258
|
let reactive;
|
|
259
259
|
try {
|
|
260
260
|
if (Log.isOn && Log.opt.change)
|
|
261
|
-
Log.write(
|
|
261
|
+
Log.write("╠═", "", "", undefined, "changes");
|
|
262
262
|
reactive = this.changeset.applyOrDiscard(this.canceled);
|
|
263
263
|
this.changeset.triggerGarbageCollection();
|
|
264
264
|
if (this.promise) {
|
|
@@ -290,7 +290,7 @@ class TransactionImpl extends Transaction {
|
|
|
290
290
|
}
|
|
291
291
|
static getEditableChangeset() {
|
|
292
292
|
if (TransactionImpl.inspection)
|
|
293
|
-
throw misuse(
|
|
293
|
+
throw misuse("cannot make changes during transaction inspection");
|
|
294
294
|
return TransactionImpl.curr.changeset;
|
|
295
295
|
}
|
|
296
296
|
static _init() {
|
|
@@ -301,7 +301,7 @@ class TransactionImpl extends Transaction {
|
|
|
301
301
|
Changeset._init();
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
|
-
TransactionImpl.none = new TransactionImpl({ hint:
|
|
304
|
+
TransactionImpl.none = new TransactionImpl({ hint: "<none>" });
|
|
305
305
|
TransactionImpl.curr = TransactionImpl.none;
|
|
306
306
|
TransactionImpl.inspection = false;
|
|
307
307
|
TransactionImpl.frameStartTime = 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LoggingOptions } from
|
|
1
|
+
import { LoggingOptions } from "../Logging.js";
|
|
2
2
|
export declare function error(message: string, dump: Error | undefined): Error;
|
|
3
3
|
export declare function misuse(message: string, dump?: any): Error;
|
|
4
4
|
export declare function fatal(error: Error): Error;
|