reactronic 0.22.109 → 0.22.202
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 +18 -27
- package/build/dist/source/{Trace.d.ts → Logging.d.ts} +9 -9
- package/build/dist/source/{Trace.js → Logging.js} +25 -25
- package/build/dist/source/Options.d.ts +5 -5
- package/build/dist/source/Options.js +3 -3
- package/build/dist/source/Rx.d.ts +7 -7
- package/build/dist/source/Rx.js +6 -6
- package/build/dist/source/api.d.ts +1 -1
- package/build/dist/source/api.js +2 -2
- package/build/dist/source/impl/Data.js +1 -1
- package/build/dist/source/impl/Hooks.d.ts +6 -6
- package/build/dist/source/impl/Hooks.js +19 -21
- package/build/dist/source/impl/Operation.d.ts +2 -2
- package/build/dist/source/impl/Operation.js +109 -97
- package/build/dist/source/impl/Snapshot.d.ts +1 -1
- package/build/dist/source/impl/Snapshot.js +33 -33
- package/build/dist/source/impl/Transaction.js +12 -12
- package/build/dist/source/util/Dbg.d.ts +10 -10
- package/build/dist/source/util/Dbg.js +30 -30
- package/build/dist/source/util/Sealant.js +2 -2
- package/package.json +1 -1
|
@@ -10,9 +10,9 @@ const Transaction_1 = require("./Transaction");
|
|
|
10
10
|
const Monitor_1 = require("./Monitor");
|
|
11
11
|
const Hooks_1 = require("./Hooks");
|
|
12
12
|
const TransactionJournal_1 = require("./TransactionJournal");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
13
|
+
const BOOT_ARGS = [];
|
|
14
|
+
const BOOT_CAUSE = '<boot>';
|
|
15
|
+
const ROOT_HOLDER = new Data_1.ObjectHolder(undefined, undefined, Hooks_1.Hooks.proxy, Snapshot_1.ROOT_REV, '<root>');
|
|
16
16
|
class OperationController extends Controller_1.Controller {
|
|
17
17
|
constructor(ownHolder, memberName) {
|
|
18
18
|
super();
|
|
@@ -27,7 +27,7 @@ class OperationController extends Controller_1.Controller {
|
|
|
27
27
|
get error() { return this.use().operation.error; }
|
|
28
28
|
get stamp() { return this.use().revision.snapshot.timestamp; }
|
|
29
29
|
get isUpToDate() { return this.use().isUpToDate; }
|
|
30
|
-
markObsolete() { Transaction_1.Transaction.run({ hint: Dbg_1.
|
|
30
|
+
markObsolete() { Transaction_1.Transaction.run({ hint: Dbg_1.Log.isOn ? `markObsolete(${Snapshot_1.Dump.obj(this.ownHolder, this.memberName)})` : 'markObsolete()' }, OperationController.markObsolete, this); }
|
|
31
31
|
pullLastResult(args) { return this.useOrRun(true, args).value; }
|
|
32
32
|
useOrRun(weak, args) {
|
|
33
33
|
var _a;
|
|
@@ -36,7 +36,7 @@ class OperationController extends Controller_1.Controller {
|
|
|
36
36
|
const op = oc.operation;
|
|
37
37
|
const opts = op.options;
|
|
38
38
|
if (!oc.isUpToDate && oc.revision.data[Data_1.Meta.Disposed] === undefined
|
|
39
|
-
&& (!weak || op.cause ===
|
|
39
|
+
&& (!weak || op.cause === BOOT_CAUSE || !op.successor ||
|
|
40
40
|
op.successor.transaction.isFinished)) {
|
|
41
41
|
const outerOpts = (_a = Operation.current) === null || _a === void 0 ? void 0 : _a.options;
|
|
42
42
|
const standalone = weak || opts.standalone || opts.kind === Options_1.Kind.Reaction ||
|
|
@@ -49,9 +49,9 @@ class OperationController extends Controller_1.Controller {
|
|
|
49
49
|
if (!weak || ctx === ctx2 || (ctx2.sealed && ctx.timestamp >= ctx2.timestamp))
|
|
50
50
|
oc = oc2;
|
|
51
51
|
}
|
|
52
|
-
else if (Dbg_1.
|
|
53
|
-
opts.
|
|
54
|
-
Dbg_1.
|
|
52
|
+
else if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation && (opts.logging === undefined ||
|
|
53
|
+
opts.logging.operation === undefined || opts.logging.operation === true))
|
|
54
|
+
Dbg_1.Log.write(Transaction_1.Transaction.current.isFinished ? '' : '║', ' (=)', `${Snapshot_1.Dump.rev2(oc.operation.controller.ownHolder, oc.snapshot, this.memberName)} result is reused from T${oc.operation.transaction.id}[${oc.operation.transaction.hint}]`);
|
|
55
55
|
const t = oc.operation;
|
|
56
56
|
Snapshot_1.Snapshot.markUsed(t, oc.revision, this.memberName, this.ownHolder, t.options.kind, weak);
|
|
57
57
|
return t;
|
|
@@ -68,11 +68,11 @@ class OperationController extends Controller_1.Controller {
|
|
|
68
68
|
op = self.edit().operation;
|
|
69
69
|
else
|
|
70
70
|
op = Operation.current;
|
|
71
|
-
if (!op
|
|
72
|
-
throw (0, Dbg_1.misuse)('
|
|
71
|
+
if (!op)
|
|
72
|
+
throw (0, Dbg_1.misuse)('reactronic decorator is only applicable to methods');
|
|
73
73
|
op.options = new Hooks_1.OptionsImpl(op.options.getter, op.options.setter, op.options, options, false);
|
|
74
|
-
if (Dbg_1.
|
|
75
|
-
Dbg_1.
|
|
74
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
75
|
+
Dbg_1.Log.write('║', ' ✎', `${op.hint()}.options are changed`);
|
|
76
76
|
return op.options;
|
|
77
77
|
}
|
|
78
78
|
static runWithin(op, func, ...args) {
|
|
@@ -93,12 +93,12 @@ class OperationController extends Controller_1.Controller {
|
|
|
93
93
|
return result;
|
|
94
94
|
}
|
|
95
95
|
static why() {
|
|
96
|
-
|
|
97
|
-
return
|
|
96
|
+
var _a, _b;
|
|
97
|
+
return (_b = (_a = Operation.current) === null || _a === void 0 ? void 0 : _a.why()) !== null && _b !== void 0 ? _b : BOOT_CAUSE;
|
|
98
98
|
}
|
|
99
99
|
static briefWhy() {
|
|
100
|
-
|
|
101
|
-
return
|
|
100
|
+
var _a, _b;
|
|
101
|
+
return (_b = (_a = Operation.current) === null || _a === void 0 ? void 0 : _a.briefWhy()) !== null && _b !== void 0 ? _b : BOOT_CAUSE;
|
|
102
102
|
}
|
|
103
103
|
static dependencies() {
|
|
104
104
|
const op = Operation.current;
|
|
@@ -107,10 +107,10 @@ class OperationController extends Controller_1.Controller {
|
|
|
107
107
|
peek(args) {
|
|
108
108
|
const ctx = Snapshot_1.Snapshot.current();
|
|
109
109
|
const r = ctx.seekRevision(this.ownHolder, this.memberName);
|
|
110
|
-
const op = this.
|
|
111
|
-
const isValid = op.options.kind !== Options_1.Kind.Transaction && op.cause !==
|
|
110
|
+
const op = this.acquireFromRevision(r, args);
|
|
111
|
+
const isValid = op.options.kind !== Options_1.Kind.Transaction && op.cause !== BOOT_CAUSE &&
|
|
112
112
|
(ctx === op.snapshot || ctx.timestamp < op.obsoleteSince) &&
|
|
113
|
-
(!op.options.
|
|
113
|
+
(!op.options.triggeringArgs || args === undefined ||
|
|
114
114
|
op.args.length === args.length && op.args.every((t, i) => t === args[i])) ||
|
|
115
115
|
r.data[Data_1.Meta.Disposed] !== undefined;
|
|
116
116
|
return { operation: op, isUpToDate: isValid, snapshot: ctx, revision: r };
|
|
@@ -125,7 +125,7 @@ class OperationController extends Controller_1.Controller {
|
|
|
125
125
|
const m = this.memberName;
|
|
126
126
|
const ctx = Snapshot_1.Snapshot.edit();
|
|
127
127
|
const r = ctx.getEditableRevision(h, m, Data_1.Meta.Holder, this);
|
|
128
|
-
let op = this.
|
|
128
|
+
let op = this.acquireFromRevision(r, undefined);
|
|
129
129
|
if (op.snapshot !== r.snapshot) {
|
|
130
130
|
const op2 = new Operation(this, r.snapshot, op);
|
|
131
131
|
r.data[m] = op2.reenterOver(op);
|
|
@@ -135,48 +135,60 @@ class OperationController extends Controller_1.Controller {
|
|
|
135
135
|
}
|
|
136
136
|
return { operation: op, isUpToDate: true, snapshot: ctx, revision: r };
|
|
137
137
|
}
|
|
138
|
-
|
|
138
|
+
acquireFromRevision(r, args) {
|
|
139
139
|
const m = this.memberName;
|
|
140
140
|
let op = r.data[m];
|
|
141
141
|
if (op.controller !== this) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
142
|
+
if (r.snapshot !== Snapshot_1.ROOT_REV.snapshot) {
|
|
143
|
+
const hint = Dbg_1.Log.isOn ? `${Snapshot_1.Dump.obj(this.ownHolder, m)}/boot` : 'MethodController/init';
|
|
144
|
+
const standalone = r.snapshot.sealed || r.prev.revision !== Snapshot_1.ROOT_REV;
|
|
145
|
+
op = Transaction_1.Transaction.run({ hint, standalone, token: this }, () => {
|
|
146
|
+
const h = this.ownHolder;
|
|
147
|
+
let r2 = Snapshot_1.Snapshot.current().getCurrentRevision(h, m);
|
|
148
|
+
let op2 = r2.data[m];
|
|
149
|
+
if (op2.controller !== this) {
|
|
150
|
+
r2 = Snapshot_1.Snapshot.edit().getEditableRevision(h, m, Data_1.Meta.Holder, this);
|
|
151
|
+
const t = new Operation(this, r2.snapshot, op2);
|
|
152
|
+
if (args)
|
|
153
|
+
t.args = args;
|
|
154
|
+
t.cause = BOOT_CAUSE;
|
|
155
|
+
r2.data[m] = t;
|
|
156
|
+
Snapshot_1.Snapshot.markEdited(op2, t, true, r2, m, h);
|
|
157
|
+
op2 = t;
|
|
158
|
+
}
|
|
159
|
+
return op2;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
const t = new Operation(this, r.snapshot, op);
|
|
164
|
+
if (args)
|
|
165
|
+
t.args = args;
|
|
166
|
+
t.cause = BOOT_CAUSE;
|
|
167
|
+
r.data[m] = t;
|
|
168
|
+
op = t;
|
|
169
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
170
|
+
Dbg_1.Log.write('║', ' ⎘', `${Snapshot_1.Dump.obj(this.ownHolder, m)} is cloned outside of transaction`);
|
|
171
|
+
}
|
|
160
172
|
}
|
|
161
173
|
return op;
|
|
162
174
|
}
|
|
163
175
|
run(existing, standalone, options, token, args) {
|
|
164
|
-
const hint = Dbg_1.
|
|
176
|
+
const hint = Dbg_1.Log.isOn ? `${Snapshot_1.Dump.obj(this.ownHolder, this.memberName)}${args && args.length > 0 && (typeof args[0] === 'number' || typeof args[0] === 'string') ? ` - ${args[0]}` : ''}` : `${Snapshot_1.Dump.obj(this.ownHolder, this.memberName)}`;
|
|
165
177
|
let oc = existing;
|
|
166
|
-
const opts = { hint, standalone, journal: options.journal,
|
|
178
|
+
const opts = { hint, standalone, journal: options.journal, logging: options.logging, token };
|
|
167
179
|
const result = Transaction_1.Transaction.run(opts, (argsx) => {
|
|
168
180
|
if (!oc.operation.transaction.isCanceled) {
|
|
169
181
|
oc = this.edit();
|
|
170
|
-
if (Dbg_1.
|
|
171
|
-
Dbg_1.
|
|
182
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
183
|
+
Dbg_1.Log.write('║', ' 𝑓', `${oc.operation.why()}`);
|
|
172
184
|
oc.operation.run(this.ownHolder.proxy, argsx);
|
|
173
185
|
}
|
|
174
186
|
else {
|
|
175
187
|
oc = this.peek(argsx);
|
|
176
188
|
if (oc.operation.options.kind === Options_1.Kind.Transaction || !oc.isUpToDate) {
|
|
177
189
|
oc = this.edit();
|
|
178
|
-
if (Dbg_1.
|
|
179
|
-
Dbg_1.
|
|
190
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
191
|
+
Dbg_1.Log.write('║', ' 𝑓', `${oc.operation.why()}`);
|
|
180
192
|
oc.operation.run(this.ownHolder.proxy, argsx);
|
|
181
193
|
}
|
|
182
194
|
}
|
|
@@ -188,7 +200,7 @@ class OperationController extends Controller_1.Controller {
|
|
|
188
200
|
static markObsolete(self) {
|
|
189
201
|
const oc = self.peek(undefined);
|
|
190
202
|
const ctx = oc.snapshot;
|
|
191
|
-
oc.operation.markObsoleteDueTo(oc.operation, self.memberName, Snapshot_1.ROOT_REV.snapshot, ROOT_HOLDER,
|
|
203
|
+
oc.operation.markObsoleteDueTo(oc.operation, self.memberName, Snapshot_1.ROOT_REV.snapshot, ROOT_HOLDER, BOOT_CAUSE, ctx.timestamp, ctx.reactions);
|
|
192
204
|
}
|
|
193
205
|
}
|
|
194
206
|
exports.OperationController = OperationController;
|
|
@@ -207,7 +219,7 @@ class Operation extends Data_1.Observable {
|
|
|
207
219
|
}
|
|
208
220
|
else {
|
|
209
221
|
this.options = prev;
|
|
210
|
-
this.args =
|
|
222
|
+
this.args = BOOT_ARGS;
|
|
211
223
|
this.cause = undefined;
|
|
212
224
|
}
|
|
213
225
|
this.started = 0;
|
|
@@ -240,15 +252,15 @@ class Operation extends Data_1.Observable {
|
|
|
240
252
|
}
|
|
241
253
|
wrap(func) {
|
|
242
254
|
const wrappedForOperation = (...args) => {
|
|
243
|
-
if (Dbg_1.
|
|
244
|
-
Dbg_1.
|
|
255
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.step && this.result)
|
|
256
|
+
Dbg_1.Log.writeAs({ margin2: this.margin }, '║', '‾\\', `${this.hint()} - step in `, 0, ' │');
|
|
245
257
|
const started = Date.now();
|
|
246
258
|
const result = OperationController.runWithin(this, func, ...args);
|
|
247
259
|
const ms = Date.now() - started;
|
|
248
|
-
if (Dbg_1.
|
|
249
|
-
Dbg_1.
|
|
260
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.step && this.result)
|
|
261
|
+
Dbg_1.Log.writeAs({ margin2: this.margin }, '║', '_/', `${this.hint()} - step out `, 0, this.started > 0 ? ' │' : '');
|
|
250
262
|
if (ms > Hooks_1.Hooks.mainThreadBlockingWarningThreshold)
|
|
251
|
-
Dbg_1.
|
|
263
|
+
Dbg_1.Log.write('', '[!]', this.why(), ms, ' *** main thread is too busy ***');
|
|
252
264
|
return result;
|
|
253
265
|
};
|
|
254
266
|
return wrappedForOperation;
|
|
@@ -273,8 +285,8 @@ class Operation extends Data_1.Observable {
|
|
|
273
285
|
this.obsoleteDueTo = why;
|
|
274
286
|
this.obsoleteSince = since;
|
|
275
287
|
const isReaction = this.options.kind === Options_1.Kind.Reaction;
|
|
276
|
-
if (Dbg_1.
|
|
277
|
-
Dbg_1.
|
|
288
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.obsolete || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.obsolete)))
|
|
289
|
+
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', isReaction ? '█' : '▒', isReaction && snapshot === Snapshot_1.ROOT_REV.snapshot
|
|
278
290
|
? `${this.hint()} is a reaction and will run automatically (order ${this.options.order})`
|
|
279
291
|
: `${this.hint()} is obsolete due to ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)} since v${since}${isReaction ? ` and will run automatically (order ${this.options.order})` : ''}`);
|
|
280
292
|
if (isReaction)
|
|
@@ -287,8 +299,8 @@ class Operation extends Data_1.Observable {
|
|
|
287
299
|
else if (!tran.isFinished && this !== observable)
|
|
288
300
|
tran.cancel(new Error(`T${tran.id}[${tran.hint}] is canceled due to obsolete ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)} changed by T${snapshot.id}[${snapshot.hint}]`), null);
|
|
289
301
|
}
|
|
290
|
-
else if (Dbg_1.
|
|
291
|
-
Dbg_1.
|
|
302
|
+
else if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.obsolete || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.obsolete)))
|
|
303
|
+
Dbg_1.Log.write(' ', 'x', `${this.hint()} is not obsolete due to its own change to ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)}`);
|
|
292
304
|
}
|
|
293
305
|
}
|
|
294
306
|
runIfNotUpToDate(now, nothrow) {
|
|
@@ -328,8 +340,8 @@ class Operation extends Data_1.Observable {
|
|
|
328
340
|
let error = undefined;
|
|
329
341
|
const opponent = head.successor;
|
|
330
342
|
if (opponent && !opponent.transaction.isFinished) {
|
|
331
|
-
if (Dbg_1.
|
|
332
|
-
Dbg_1.
|
|
343
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.obsolete)
|
|
344
|
+
Dbg_1.Log.write('║', ' [!]', `${this.hint()} is trying to re-enter over ${opponent.hint()}`);
|
|
333
345
|
switch (head.options.reentrance) {
|
|
334
346
|
case Options_1.Reentrance.PreventWithError:
|
|
335
347
|
if (!opponent.transaction.isCanceled)
|
|
@@ -371,8 +383,8 @@ class Operation extends Data_1.Observable {
|
|
|
371
383
|
enter() {
|
|
372
384
|
if (this.options.monitor)
|
|
373
385
|
this.monitorEnter(this.options.monitor);
|
|
374
|
-
if (Dbg_1.
|
|
375
|
-
Dbg_1.
|
|
386
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
387
|
+
Dbg_1.Log.write('║', '‾\\', `${this.hint()} - enter`, undefined, ` [ ${Snapshot_1.Dump.obj(this.controller.ownHolder, this.controller.memberName)} ]`);
|
|
376
388
|
this.started = Date.now();
|
|
377
389
|
}
|
|
378
390
|
leaveOrAsync() {
|
|
@@ -386,11 +398,11 @@ class Operation extends Data_1.Observable {
|
|
|
386
398
|
this.leave(false, ' ⚐', '- finished ', 'ERR ──┘');
|
|
387
399
|
throw error;
|
|
388
400
|
});
|
|
389
|
-
if (Dbg_1.
|
|
390
|
-
if (Dbg_1.
|
|
391
|
-
Dbg_1.
|
|
392
|
-
else if (Dbg_1.
|
|
393
|
-
Dbg_1.
|
|
401
|
+
if (Dbg_1.Log.isOn) {
|
|
402
|
+
if (Dbg_1.Log.opt.operation)
|
|
403
|
+
Dbg_1.Log.write('║', '_/', `${this.hint()} - leave... `, 0, 'ASYNC ──┐');
|
|
404
|
+
else if (Dbg_1.Log.opt.transaction)
|
|
405
|
+
Dbg_1.Log.write('║', ' ', `${this.why()} ...`, 0, 'ASYNC');
|
|
394
406
|
}
|
|
395
407
|
}
|
|
396
408
|
else {
|
|
@@ -401,10 +413,10 @@ class Operation extends Data_1.Observable {
|
|
|
401
413
|
leave(main, op, message, highlight = undefined) {
|
|
402
414
|
const ms = Date.now() - this.started;
|
|
403
415
|
this.started = -this.started;
|
|
404
|
-
if (Dbg_1.
|
|
405
|
-
Dbg_1.
|
|
416
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
417
|
+
Dbg_1.Log.write('║', `${op}`, `${this.hint()} ${message}`, ms, highlight);
|
|
406
418
|
if (ms > (main ? Hooks_1.Hooks.mainThreadBlockingWarningThreshold : Hooks_1.Hooks.asyncActionDurationWarningThreshold))
|
|
407
|
-
Dbg_1.
|
|
419
|
+
Dbg_1.Log.write('', '[!]', this.why(), ms, main ? ' *** main thread is too busy ***' : ' *** async is too long ***');
|
|
408
420
|
this.cause = undefined;
|
|
409
421
|
if (this.options.monitor)
|
|
410
422
|
this.monitorLeave(this.options.monitor);
|
|
@@ -413,7 +425,7 @@ class Operation extends Data_1.Observable {
|
|
|
413
425
|
const options = {
|
|
414
426
|
hint: 'Monitor.enter',
|
|
415
427
|
standalone: 'isolated',
|
|
416
|
-
|
|
428
|
+
logging: Dbg_1.Log.isOn && Dbg_1.Log.opt.monitor ? undefined : Dbg_1.Log.global
|
|
417
429
|
};
|
|
418
430
|
OperationController.runWithin(undefined, Transaction_1.Transaction.run, options, Monitor_1.MonitorImpl.enter, mon, this.transaction);
|
|
419
431
|
}
|
|
@@ -423,7 +435,7 @@ class Operation extends Data_1.Observable {
|
|
|
423
435
|
const options = {
|
|
424
436
|
hint: 'Monitor.leave',
|
|
425
437
|
standalone: 'isolated',
|
|
426
|
-
|
|
438
|
+
logging: Dbg_1.Log.isOn && Dbg_1.Log.opt.monitor ? undefined : Dbg_1.Log.DefaultLevel
|
|
427
439
|
};
|
|
428
440
|
OperationController.runWithin(undefined, Transaction_1.Transaction.run, options, Monitor_1.MonitorImpl.leave, mon, this.transaction);
|
|
429
441
|
};
|
|
@@ -451,19 +463,19 @@ class Operation extends Data_1.Observable {
|
|
|
451
463
|
ctx.bumpBy(r.snapshot.timestamp);
|
|
452
464
|
const t = weak ? -1 : ctx.timestamp;
|
|
453
465
|
if (!op.subscribeTo(observable, r, m, h, t))
|
|
454
|
-
op.markObsoleteDueTo(observable, m, r.snapshot, h,
|
|
466
|
+
op.markObsoleteDueTo(observable, m, r.snapshot, h, BOOT_CAUSE, ctx.timestamp, ctx.reactions);
|
|
455
467
|
}
|
|
456
468
|
}
|
|
457
469
|
}
|
|
458
470
|
static markEdited(oldValue, newValue, edited, r, m, h) {
|
|
459
471
|
edited ? r.changes.add(m) : r.changes.delete(m);
|
|
460
|
-
if (Dbg_1.
|
|
461
|
-
edited ? Dbg_1.
|
|
472
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
473
|
+
edited ? Dbg_1.Log.write('║', ' ✎', `${Snapshot_1.Dump.rev2(h, r.snapshot, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`) : Dbg_1.Log.write('║', ' ✎', `${Snapshot_1.Dump.rev2(h, r.snapshot, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`, undefined, ' (same as previous)');
|
|
462
474
|
}
|
|
463
475
|
static isConflicting(oldValue, newValue) {
|
|
464
476
|
let result = oldValue !== newValue;
|
|
465
477
|
if (result)
|
|
466
|
-
result = oldValue instanceof Operation && oldValue.cause !==
|
|
478
|
+
result = oldValue instanceof Operation && oldValue.cause !== BOOT_CAUSE;
|
|
467
479
|
return result;
|
|
468
480
|
}
|
|
469
481
|
static propagateAllChangesThroughSubscriptions(snapshot) {
|
|
@@ -512,7 +524,7 @@ class Operation extends Data_1.Observable {
|
|
|
512
524
|
if (Hooks_1.Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
513
525
|
curr.observables.forEach((info, v) => {
|
|
514
526
|
if (info.usageCount > Hooks_1.Hooks.repetitiveUsageWarningThreshold)
|
|
515
|
-
Dbg_1.
|
|
527
|
+
Dbg_1.Log.write('', '[!]', `${curr.hint()} uses ${info.memberHint} ${info.usageCount} times (consider remembering it in a local variable)`, 0, ' *** WARNING ***');
|
|
516
528
|
});
|
|
517
529
|
}
|
|
518
530
|
if (unsubscribe)
|
|
@@ -522,8 +534,8 @@ class Operation extends Data_1.Observable {
|
|
|
522
534
|
else if (curr instanceof Data_1.Observable && curr.observers) {
|
|
523
535
|
curr.observers.forEach(o => {
|
|
524
536
|
o.observables.delete(curr);
|
|
525
|
-
if (Dbg_1.
|
|
526
|
-
Dbg_1.
|
|
537
|
+
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.read)
|
|
538
|
+
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', '-', `${o.hint()} is unsubscribed from own-changed ${Snapshot_1.Dump.rev(r, m)}`);
|
|
527
539
|
});
|
|
528
540
|
curr.observers = undefined;
|
|
529
541
|
}
|
|
@@ -551,8 +563,8 @@ class Operation extends Data_1.Observable {
|
|
|
551
563
|
(_a = this.observables) === null || _a === void 0 ? void 0 : _a.forEach((info, value) => {
|
|
552
564
|
var _a;
|
|
553
565
|
value.observers.delete(this);
|
|
554
|
-
if (Dbg_1.
|
|
555
|
-
Dbg_1.
|
|
566
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
567
|
+
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', '-', `${this.hint()} is unsubscribed from ${info.memberHint}`);
|
|
556
568
|
});
|
|
557
569
|
this.observables = undefined;
|
|
558
570
|
}
|
|
@@ -571,15 +583,15 @@ class Operation extends Data_1.Observable {
|
|
|
571
583
|
const info = { memberHint: Snapshot_1.Dump.rev2(h, r.snapshot, m), usageCount: times };
|
|
572
584
|
observable.observers.add(this);
|
|
573
585
|
this.observables.set(observable, info);
|
|
574
|
-
if (Dbg_1.
|
|
575
|
-
Dbg_1.
|
|
586
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
587
|
+
Dbg_1.Log.write('║', ' ∞ ', `${this.hint()} is subscribed to ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}${info.usageCount > 1 ? ` (${info.usageCount} times)` : ''}`);
|
|
576
588
|
}
|
|
577
|
-
else if (Dbg_1.
|
|
578
|
-
Dbg_1.
|
|
589
|
+
else if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_b = this.options.logging) === null || _b === void 0 ? void 0 : _b.read)))
|
|
590
|
+
Dbg_1.Log.write('║', ' x ', `${this.hint()} is obsolete and is NOT subscribed to ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}`);
|
|
579
591
|
}
|
|
580
592
|
else {
|
|
581
|
-
if (Dbg_1.
|
|
582
|
-
Dbg_1.
|
|
593
|
+
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.read)))
|
|
594
|
+
Dbg_1.Log.write('║', ' x ', `${this.hint()} is NOT subscribed to already obsolete ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}`);
|
|
583
595
|
}
|
|
584
596
|
return ok;
|
|
585
597
|
}
|
|
@@ -589,13 +601,13 @@ class Operation extends Data_1.Observable {
|
|
|
589
601
|
result = !(observable instanceof Operation && timestamp >= observable.obsoleteSince);
|
|
590
602
|
return result;
|
|
591
603
|
}
|
|
592
|
-
static
|
|
604
|
+
static createOperation(h, m, options) {
|
|
593
605
|
const ctl = new OperationController(h, m);
|
|
594
|
-
const
|
|
606
|
+
const operation = (...args) => {
|
|
595
607
|
return ctl.useOrRun(false, args).result;
|
|
596
608
|
};
|
|
597
|
-
Data_1.Meta.set(
|
|
598
|
-
return
|
|
609
|
+
Data_1.Meta.set(operation, Data_1.Meta.Controller, ctl);
|
|
610
|
+
return operation;
|
|
599
611
|
}
|
|
600
612
|
static rememberOperationOptions(proto, m, getter, setter, enumerable, configurable, options, implicit) {
|
|
601
613
|
const initial = Data_1.Meta.acquire(proto, Data_1.Meta.Initial);
|
|
@@ -614,15 +626,15 @@ class Operation extends Data_1.Observable {
|
|
|
614
626
|
return op.options;
|
|
615
627
|
}
|
|
616
628
|
static init() {
|
|
617
|
-
Object.freeze(
|
|
618
|
-
Dbg_1.
|
|
629
|
+
Object.freeze(BOOT_ARGS);
|
|
630
|
+
Dbg_1.Log.getMergedLoggingOptions = getMergedLoggingOptions;
|
|
619
631
|
Snapshot_1.Snapshot.markUsed = Operation.markUsed;
|
|
620
632
|
Snapshot_1.Snapshot.markEdited = Operation.markEdited;
|
|
621
633
|
Snapshot_1.Snapshot.isConflicting = Operation.isConflicting;
|
|
622
634
|
Snapshot_1.Snapshot.propagateAllChangesThroughSubscriptions = Operation.propagateAllChangesThroughSubscriptions;
|
|
623
635
|
Snapshot_1.Snapshot.revokeAllSubscriptions = Operation.revokeAllSubscriptions;
|
|
624
636
|
Snapshot_1.Snapshot.enqueueReactionsToRun = Operation.enqueueReactionsToRun;
|
|
625
|
-
Hooks_1.Hooks.
|
|
637
|
+
Hooks_1.Hooks.createOperation = Operation.createOperation;
|
|
626
638
|
Hooks_1.Hooks.rememberOperationOptions = Operation.rememberOperationOptions;
|
|
627
639
|
Promise.prototype.then = reactronicHookedThen;
|
|
628
640
|
try {
|
|
@@ -668,14 +680,14 @@ function valueHint(value, m) {
|
|
|
668
680
|
result = '∅';
|
|
669
681
|
return result;
|
|
670
682
|
}
|
|
671
|
-
function
|
|
683
|
+
function getMergedLoggingOptions(local) {
|
|
672
684
|
const t = Transaction_1.Transaction.current;
|
|
673
|
-
let res = Dbg_1.
|
|
674
|
-
res = Dbg_1.
|
|
685
|
+
let res = Dbg_1.Log.merge(t.options.logging, t.id > 1 ? 31 + t.id % 6 : 37, t.id > 1 ? `T${t.id}` : `-${Snapshot_1.Snapshot.idGen.toString().replace(/[0-9]/g, '-')}`, Dbg_1.Log.global);
|
|
686
|
+
res = Dbg_1.Log.merge({ margin1: t.margin }, undefined, undefined, res);
|
|
675
687
|
if (Operation.current)
|
|
676
|
-
res = Dbg_1.
|
|
688
|
+
res = Dbg_1.Log.merge({ margin2: Operation.current.margin }, undefined, undefined, res);
|
|
677
689
|
if (local)
|
|
678
|
-
res = Dbg_1.
|
|
690
|
+
res = Dbg_1.Log.merge(local, undefined, undefined, res);
|
|
679
691
|
return res;
|
|
680
692
|
}
|
|
681
693
|
const ORIGINAL_PROMISE_THEN = Promise.prototype.then;
|
|
@@ -35,7 +35,7 @@ export declare class Snapshot implements AbstractSnapshot {
|
|
|
35
35
|
static takeSnapshot<T>(obj: T): T;
|
|
36
36
|
static dispose(obj: any): void;
|
|
37
37
|
static doDispose(ctx: Snapshot, h: ObjectHolder): ObjectRevision;
|
|
38
|
-
private
|
|
38
|
+
private isNewRevisionRequired;
|
|
39
39
|
acquire(outer: Snapshot): void;
|
|
40
40
|
bumpBy(timestamp: number): void;
|
|
41
41
|
rebase(): ObjectRevision[] | undefined;
|