reactronic 0.22.303 → 0.22.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/package.json +1 -1
- package/build/dist/source/Buffer.d.ts +0 -8
- package/build/dist/source/Buffer.js +0 -8
- package/build/dist/source/Controller.d.ts +0 -12
- package/build/dist/source/Controller.js +0 -6
- package/build/dist/source/Logging.d.ts +0 -38
- package/build/dist/source/Logging.js +0 -113
- package/build/dist/source/Options.d.ts +0 -38
- package/build/dist/source/Options.js +0 -21
- package/build/dist/source/Ref.d.ts +0 -34
- package/build/dist/source/Ref.js +0 -90
- package/build/dist/source/Rx.d.ts +0 -27
- package/build/dist/source/Rx.js +0 -58
- package/build/dist/source/Worker.d.ts +0 -8
- package/build/dist/source/Worker.js +0 -2
- package/build/dist/source/api.d.ts +0 -14
- package/build/dist/source/api.js +0 -40
- package/build/dist/source/impl/Changeset.d.ts +0 -60
- package/build/dist/source/impl/Changeset.js +0 -361
- package/build/dist/source/impl/Data.d.ts +0 -63
- package/build/dist/source/impl/Data.js +0 -51
- package/build/dist/source/impl/Hooks.d.ts +0 -79
- package/build/dist/source/impl/Hooks.js +0 -281
- package/build/dist/source/impl/Journal.d.ts +0 -34
- package/build/dist/source/impl/Journal.js +0 -149
- package/build/dist/source/impl/Meta.d.ts +0 -13
- package/build/dist/source/impl/Meta.js +0 -33
- package/build/dist/source/impl/Monitor.d.ts +0 -32
- package/build/dist/source/impl/Monitor.js +0 -97
- package/build/dist/source/impl/Operation.d.ts +0 -93
- package/build/dist/source/impl/Operation.js +0 -722
- package/build/dist/source/impl/Transaction.d.ts +0 -30
- package/build/dist/source/impl/Transaction.js +0 -313
- package/build/dist/source/util/Dbg.d.ts +0 -15
- package/build/dist/source/util/Dbg.js +0 -96
- package/build/dist/source/util/Sealant.d.ts +0 -14
- package/build/dist/source/util/Sealant.js +0 -30
- package/build/dist/source/util/SealedArray.d.ts +0 -16
- package/build/dist/source/util/SealedArray.js +0 -28
- package/build/dist/source/util/SealedMap.d.ts +0 -13
- package/build/dist/source/util/SealedMap.js +0 -21
- package/build/dist/source/util/SealedSet.d.ts +0 -13
- package/build/dist/source/util/SealedSet.js +0 -21
- package/build/dist/source/util/Utils.d.ts +0 -9
- package/build/dist/source/util/Utils.js +0 -62
|
@@ -1,722 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.rejectRethrow = exports.resolveReturn = exports.OperationController = void 0;
|
|
4
|
-
const Dbg_1 = require("../util/Dbg");
|
|
5
|
-
const Options_1 = require("../Options");
|
|
6
|
-
const Controller_1 = require("../Controller");
|
|
7
|
-
const Data_1 = require("./Data");
|
|
8
|
-
const Changeset_1 = require("./Changeset");
|
|
9
|
-
const Transaction_1 = require("./Transaction");
|
|
10
|
-
const Monitor_1 = require("./Monitor");
|
|
11
|
-
const Hooks_1 = require("./Hooks");
|
|
12
|
-
const Journal_1 = require("./Journal");
|
|
13
|
-
const BOOT_ARGS = [];
|
|
14
|
-
const BOOT_CAUSE = '<boot>';
|
|
15
|
-
const EMPTY_HANDLE = new Data_1.ObjectHandle(undefined, undefined, Hooks_1.Hooks.handler, Changeset_1.EMPTY_SNAPSHOT, '<empty>');
|
|
16
|
-
class OperationController extends Controller_1.Controller {
|
|
17
|
-
constructor(h, m) {
|
|
18
|
-
super();
|
|
19
|
-
this.objectHandle = h;
|
|
20
|
-
this.memberName = m;
|
|
21
|
-
}
|
|
22
|
-
configure(options) { return OperationController.configureImpl(this, options); }
|
|
23
|
-
get options() { return this.peek(undefined).operation.options; }
|
|
24
|
-
get nonreactive() { return this.peek(undefined).operation.content; }
|
|
25
|
-
get args() { return this.use().operation.args; }
|
|
26
|
-
get result() { return this.useOrRun(true, undefined).content; }
|
|
27
|
-
get error() { return this.use().operation.error; }
|
|
28
|
-
get stamp() { return this.use().snapshot.changeset.timestamp; }
|
|
29
|
-
get isUpToDate() { return this.use().isUpToDate; }
|
|
30
|
-
markObsolete() { Transaction_1.Transaction.run({ hint: Dbg_1.Log.isOn ? `markObsolete(${Changeset_1.Dump.obj(this.objectHandle, this.memberName)})` : 'markObsolete()' }, OperationController.markObsolete, this); }
|
|
31
|
-
pullLastResult(args) { return this.useOrRun(true, args).content; }
|
|
32
|
-
useOrRun(weak, args) {
|
|
33
|
-
var _a;
|
|
34
|
-
let oc = this.peek(args);
|
|
35
|
-
const ctx = oc.changeset;
|
|
36
|
-
const op = oc.operation;
|
|
37
|
-
const opts = op.options;
|
|
38
|
-
if (!oc.isUpToDate && !oc.snapshot.disposed
|
|
39
|
-
&& (!weak || op.cause === BOOT_CAUSE || !op.successor ||
|
|
40
|
-
op.successor.transaction.isFinished)) {
|
|
41
|
-
const outerOpts = (_a = Operation.current) === null || _a === void 0 ? void 0 : _a.options;
|
|
42
|
-
const standalone = weak || opts.standalone || opts.kind === Options_1.Kind.Reaction ||
|
|
43
|
-
(opts.kind === Options_1.Kind.Transaction && outerOpts && (outerOpts.noSideEffects || outerOpts.kind === Options_1.Kind.Cache)) ||
|
|
44
|
-
(opts.kind === Options_1.Kind.Cache && (oc.snapshot.changeset.sealed ||
|
|
45
|
-
oc.snapshot.former.snapshot !== Changeset_1.EMPTY_SNAPSHOT));
|
|
46
|
-
const token = opts.noSideEffects ? this : undefined;
|
|
47
|
-
const oc2 = this.run(oc, standalone, opts, token, args);
|
|
48
|
-
const ctx2 = oc2.operation.changeset;
|
|
49
|
-
if (!weak || ctx === ctx2 || (ctx2.sealed && ctx.timestamp >= ctx2.timestamp))
|
|
50
|
-
oc = oc2;
|
|
51
|
-
}
|
|
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 ? '' : '║', ' (=)', `${Changeset_1.Dump.snapshot2(oc.operation.controller.objectHandle, oc.changeset, this.memberName)} result is reused from T${oc.operation.transaction.id}[${oc.operation.transaction.hint}]`);
|
|
55
|
-
const t = oc.operation;
|
|
56
|
-
Changeset_1.Changeset.markUsed(t, oc.snapshot, this.memberName, this.objectHandle, t.options.kind, weak);
|
|
57
|
-
return t;
|
|
58
|
-
}
|
|
59
|
-
static of(method) {
|
|
60
|
-
const ctl = Data_1.Meta.get(method, Data_1.Meta.Controller);
|
|
61
|
-
if (!ctl)
|
|
62
|
-
throw (0, Dbg_1.misuse)(`given method is not decorated as reactronic one: ${method.name}`);
|
|
63
|
-
return ctl;
|
|
64
|
-
}
|
|
65
|
-
static configureImpl(self, options) {
|
|
66
|
-
let op;
|
|
67
|
-
if (self)
|
|
68
|
-
op = self.edit().operation;
|
|
69
|
-
else
|
|
70
|
-
op = Operation.current;
|
|
71
|
-
if (!op)
|
|
72
|
-
throw (0, Dbg_1.misuse)('reactronic decorator is only applicable to methods');
|
|
73
|
-
op.options = new Hooks_1.OptionsImpl(op.options.getter, op.options.setter, op.options, options, false);
|
|
74
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
75
|
-
Dbg_1.Log.write('║', ' ✎', `${op.hint()}.options are changed`);
|
|
76
|
-
return op.options;
|
|
77
|
-
}
|
|
78
|
-
static runWithin(op, func, ...args) {
|
|
79
|
-
let result = undefined;
|
|
80
|
-
const outer = Operation.current;
|
|
81
|
-
try {
|
|
82
|
-
Operation.current = op;
|
|
83
|
-
result = func(...args);
|
|
84
|
-
}
|
|
85
|
-
catch (e) {
|
|
86
|
-
if (op)
|
|
87
|
-
op.error = e;
|
|
88
|
-
throw e;
|
|
89
|
-
}
|
|
90
|
-
finally {
|
|
91
|
-
Operation.current = outer;
|
|
92
|
-
}
|
|
93
|
-
return result;
|
|
94
|
-
}
|
|
95
|
-
static why() {
|
|
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
|
-
}
|
|
99
|
-
static briefWhy() {
|
|
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
|
-
}
|
|
103
|
-
static dependencies() {
|
|
104
|
-
const op = Operation.current;
|
|
105
|
-
return op ? op.dependencies() : ['Rx.dependencies should be called from inside of reactive method'];
|
|
106
|
-
}
|
|
107
|
-
peek(args) {
|
|
108
|
-
const ctx = Changeset_1.Changeset.current();
|
|
109
|
-
const os = ctx.seekSnapshot(this.objectHandle, this.memberName);
|
|
110
|
-
const op = this.acquireFromSnapshot(os, args);
|
|
111
|
-
const isValid = op.options.kind !== Options_1.Kind.Transaction && op.cause !== BOOT_CAUSE &&
|
|
112
|
-
(ctx === op.changeset || ctx.timestamp < op.obsoleteSince) &&
|
|
113
|
-
(!op.options.triggeringArgs || args === undefined ||
|
|
114
|
-
op.args.length === args.length && op.args.every((t, i) => t === args[i])) || os.disposed;
|
|
115
|
-
return { operation: op, isUpToDate: isValid, changeset: ctx, snapshot: os };
|
|
116
|
-
}
|
|
117
|
-
use() {
|
|
118
|
-
const oc = this.peek(undefined);
|
|
119
|
-
Changeset_1.Changeset.markUsed(oc.operation, oc.snapshot, this.memberName, this.objectHandle, oc.operation.options.kind, true);
|
|
120
|
-
return oc;
|
|
121
|
-
}
|
|
122
|
-
edit() {
|
|
123
|
-
const h = this.objectHandle;
|
|
124
|
-
const m = this.memberName;
|
|
125
|
-
const ctx = Changeset_1.Changeset.edit();
|
|
126
|
-
const os = ctx.getEditableSnapshot(h, m, Data_1.Meta.Handle, this);
|
|
127
|
-
let op = this.acquireFromSnapshot(os, undefined);
|
|
128
|
-
if (op.changeset !== os.changeset) {
|
|
129
|
-
const op2 = new Operation(this, os.changeset, op);
|
|
130
|
-
os.data[m] = op2.reenterOver(op);
|
|
131
|
-
ctx.bumpBy(os.former.snapshot.changeset.timestamp);
|
|
132
|
-
Changeset_1.Changeset.markEdited(op, op2, true, os, m, h);
|
|
133
|
-
op = op2;
|
|
134
|
-
}
|
|
135
|
-
return { operation: op, isUpToDate: true, changeset: ctx, snapshot: os };
|
|
136
|
-
}
|
|
137
|
-
acquireFromSnapshot(os, args) {
|
|
138
|
-
const m = this.memberName;
|
|
139
|
-
let op = os.data[m];
|
|
140
|
-
if (op.controller !== this) {
|
|
141
|
-
if (os.changeset !== Changeset_1.EMPTY_SNAPSHOT.changeset) {
|
|
142
|
-
const hint = Dbg_1.Log.isOn ? `${Changeset_1.Dump.obj(this.objectHandle, m)}/boot` : 'MethodController/init';
|
|
143
|
-
const standalone = os.changeset.sealed || os.former.snapshot !== Changeset_1.EMPTY_SNAPSHOT;
|
|
144
|
-
op = Transaction_1.Transaction.run({ hint, standalone, token: this }, () => {
|
|
145
|
-
const h = this.objectHandle;
|
|
146
|
-
let r2 = Changeset_1.Changeset.current().getRelevantSnapshot(h, m);
|
|
147
|
-
let op2 = r2.data[m];
|
|
148
|
-
if (op2.controller !== this) {
|
|
149
|
-
r2 = Changeset_1.Changeset.edit().getEditableSnapshot(h, m, Data_1.Meta.Handle, this);
|
|
150
|
-
const t = new Operation(this, r2.changeset, op2);
|
|
151
|
-
if (args)
|
|
152
|
-
t.args = args;
|
|
153
|
-
t.cause = BOOT_CAUSE;
|
|
154
|
-
r2.data[m] = t;
|
|
155
|
-
Changeset_1.Changeset.markEdited(op2, t, true, r2, m, h);
|
|
156
|
-
op2 = t;
|
|
157
|
-
}
|
|
158
|
-
return op2;
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
const t = new Operation(this, os.changeset, op);
|
|
163
|
-
if (args)
|
|
164
|
-
t.args = args;
|
|
165
|
-
t.cause = BOOT_CAUSE;
|
|
166
|
-
os.data[m] = t;
|
|
167
|
-
op = t;
|
|
168
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
169
|
-
Dbg_1.Log.write('║', ' ⎘⎘', `${Changeset_1.Dump.obj(this.objectHandle, m)} - new snapshot is created outside of transaction (revision ${os.revision})`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return op;
|
|
173
|
-
}
|
|
174
|
-
run(existing, standalone, options, token, args) {
|
|
175
|
-
const hint = Dbg_1.Log.isOn ? `${Changeset_1.Dump.obj(this.objectHandle, this.memberName)}${args && args.length > 0 && (typeof args[0] === 'number' || typeof args[0] === 'string') ? ` - ${args[0]}` : ''}` : `${Changeset_1.Dump.obj(this.objectHandle, this.memberName)}`;
|
|
176
|
-
let oc = existing;
|
|
177
|
-
const opts = { hint, standalone, journal: options.journal, logging: options.logging, token };
|
|
178
|
-
const result = Transaction_1.Transaction.run(opts, (argsx) => {
|
|
179
|
-
if (!oc.operation.transaction.isCanceled) {
|
|
180
|
-
oc = this.edit();
|
|
181
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
182
|
-
Dbg_1.Log.write('║', ' 𝑓', `${oc.operation.why()}`);
|
|
183
|
-
oc.operation.run(this.objectHandle.proxy, argsx);
|
|
184
|
-
}
|
|
185
|
-
else {
|
|
186
|
-
oc = this.peek(argsx);
|
|
187
|
-
if (oc.operation.options.kind === Options_1.Kind.Transaction || !oc.isUpToDate) {
|
|
188
|
-
oc = this.edit();
|
|
189
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
190
|
-
Dbg_1.Log.write('║', ' 𝑓', `${oc.operation.why()}`);
|
|
191
|
-
oc.operation.run(this.objectHandle.proxy, argsx);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return oc.operation.result;
|
|
195
|
-
}, args);
|
|
196
|
-
oc.operation.result = result;
|
|
197
|
-
return oc;
|
|
198
|
-
}
|
|
199
|
-
static markObsolete(self) {
|
|
200
|
-
const oc = self.peek(undefined);
|
|
201
|
-
const ctx = oc.changeset;
|
|
202
|
-
oc.operation.markObsoleteDueTo(oc.operation, self.memberName, Changeset_1.EMPTY_SNAPSHOT.changeset, EMPTY_HANDLE, BOOT_CAUSE, ctx.timestamp, ctx.reactions);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
exports.OperationController = OperationController;
|
|
206
|
-
class Operation extends Data_1.Subscription {
|
|
207
|
-
constructor(controller, changeset, former) {
|
|
208
|
-
super(undefined);
|
|
209
|
-
this.margin = Operation.current ? Operation.current.margin + 1 : 1;
|
|
210
|
-
this.transaction = Transaction_1.Transaction.current;
|
|
211
|
-
this.controller = controller;
|
|
212
|
-
this.changeset = changeset;
|
|
213
|
-
this.subscriptions = new Map();
|
|
214
|
-
if (former instanceof Operation) {
|
|
215
|
-
this.options = former.options;
|
|
216
|
-
this.args = former.args;
|
|
217
|
-
this.cause = former.obsoleteDueTo;
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
this.options = former;
|
|
221
|
-
this.args = BOOT_ARGS;
|
|
222
|
-
this.cause = undefined;
|
|
223
|
-
}
|
|
224
|
-
this.started = 0;
|
|
225
|
-
this.obsoleteSince = 0;
|
|
226
|
-
this.obsoleteDueTo = undefined;
|
|
227
|
-
this.successor = undefined;
|
|
228
|
-
}
|
|
229
|
-
get isOperation() { return true; }
|
|
230
|
-
get originSnapshotId() { return this.changeset.id; }
|
|
231
|
-
hint() { return `${Changeset_1.Dump.snapshot2(this.controller.objectHandle, this.changeset, this.controller.memberName)}`; }
|
|
232
|
-
get order() { return this.options.order; }
|
|
233
|
-
get ['#this']() {
|
|
234
|
-
return `Operation: ${this.why()}`;
|
|
235
|
-
}
|
|
236
|
-
why() {
|
|
237
|
-
let cause;
|
|
238
|
-
if (this.cause)
|
|
239
|
-
cause = ` << ${this.cause}`;
|
|
240
|
-
else if (this.controller.options.kind === Options_1.Kind.Transaction)
|
|
241
|
-
cause = ' << operation';
|
|
242
|
-
else
|
|
243
|
-
cause = ` << T${this.changeset.id}[${this.changeset.hint}]`;
|
|
244
|
-
return `${this.hint()}${cause}`;
|
|
245
|
-
}
|
|
246
|
-
briefWhy() {
|
|
247
|
-
return this.why();
|
|
248
|
-
}
|
|
249
|
-
dependencies() {
|
|
250
|
-
throw (0, Dbg_1.misuse)('not implemented yet');
|
|
251
|
-
}
|
|
252
|
-
wrap(func) {
|
|
253
|
-
const wrappedForOperation = (...args) => {
|
|
254
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.step && this.result)
|
|
255
|
-
Dbg_1.Log.writeAs({ margin2: this.margin }, '║', '‾\\', `${this.hint()} - step in `, 0, ' │');
|
|
256
|
-
const started = Date.now();
|
|
257
|
-
const result = OperationController.runWithin(this, func, ...args);
|
|
258
|
-
const ms = Date.now() - started;
|
|
259
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.step && this.result)
|
|
260
|
-
Dbg_1.Log.writeAs({ margin2: this.margin }, '║', '_/', `${this.hint()} - step out `, 0, this.started > 0 ? ' │' : '');
|
|
261
|
-
if (ms > Hooks_1.Hooks.mainThreadBlockingWarningThreshold)
|
|
262
|
-
Dbg_1.Log.write('', '[!]', this.why(), ms, ' *** main thread is too busy ***');
|
|
263
|
-
return result;
|
|
264
|
-
};
|
|
265
|
-
return wrappedForOperation;
|
|
266
|
-
}
|
|
267
|
-
run(proxy, args) {
|
|
268
|
-
if (args)
|
|
269
|
-
this.args = args;
|
|
270
|
-
this.obsoleteSince = Changeset_1.MAX_REVISION;
|
|
271
|
-
if (!this.error)
|
|
272
|
-
OperationController.runWithin(this, Operation.run, this, proxy);
|
|
273
|
-
else
|
|
274
|
-
this.result = Promise.reject(this.error);
|
|
275
|
-
}
|
|
276
|
-
markObsoleteDueTo(subscription, m, changeset, h, outer, since, reactions) {
|
|
277
|
-
var _a, _b, _c;
|
|
278
|
-
if (this.subscriptions !== undefined) {
|
|
279
|
-
const skip = !subscription.isOperation &&
|
|
280
|
-
changeset === this.changeset;
|
|
281
|
-
if (!skip) {
|
|
282
|
-
const why = `${Changeset_1.Dump.snapshot2(h, changeset, m, subscription)} << ${outer}`;
|
|
283
|
-
const isReaction = this.options.kind === Options_1.Kind.Reaction;
|
|
284
|
-
this.obsoleteDueTo = why;
|
|
285
|
-
this.obsoleteSince = since;
|
|
286
|
-
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.obsolete || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.obsolete)))
|
|
287
|
-
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Changeset_1.Changeset.current().sealed ? '║' : ' ', isReaction ? '█' : '▒', isReaction && changeset === Changeset_1.EMPTY_SNAPSHOT.changeset
|
|
288
|
-
? `${this.hint()} is a reaction and will run automatically (order ${this.options.order})`
|
|
289
|
-
: `${this.hint()} is obsolete due to ${Changeset_1.Dump.snapshot2(h, changeset, m)} since v${since}${isReaction ? ` and will run automatically (order ${this.options.order})` : ''}`);
|
|
290
|
-
this.unsubscribeFromAllSubscriptions();
|
|
291
|
-
if (isReaction)
|
|
292
|
-
reactions.push(this);
|
|
293
|
-
else
|
|
294
|
-
(_b = this.subscribers) === null || _b === void 0 ? void 0 : _b.forEach(s => s.markObsoleteDueTo(this, this.controller.memberName, this.changeset, this.controller.objectHandle, why, since, reactions));
|
|
295
|
-
const tran = this.transaction;
|
|
296
|
-
if (tran.changeset === changeset) {
|
|
297
|
-
}
|
|
298
|
-
else if (!tran.isFinished && this !== subscription)
|
|
299
|
-
tran.cancel(new Error(`T${tran.id}[${tran.hint}] is canceled due to obsolete ${Changeset_1.Dump.snapshot2(h, changeset, m)} changed by T${changeset.id}[${changeset.hint}]`), null);
|
|
300
|
-
}
|
|
301
|
-
else if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.obsolete || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.obsolete)))
|
|
302
|
-
Dbg_1.Log.write(' ', 'x', `${this.hint()} is not obsolete due to its own change to ${Changeset_1.Dump.snapshot2(h, changeset, m)}`);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
runIfNotUpToDate(now, nothrow) {
|
|
306
|
-
const t = this.options.throttling;
|
|
307
|
-
const interval = Date.now() + this.started;
|
|
308
|
-
const hold = t ? t - interval : 0;
|
|
309
|
-
if (now || hold < 0) {
|
|
310
|
-
if (this.isNotUpToDate()) {
|
|
311
|
-
try {
|
|
312
|
-
const op = this.controller.useOrRun(false, undefined);
|
|
313
|
-
if (op.result instanceof Promise)
|
|
314
|
-
op.result.catch(error => {
|
|
315
|
-
if (op.options.kind === Options_1.Kind.Reaction)
|
|
316
|
-
(0, Dbg_1.misuse)(`reaction ${op.hint()} failed and will not run anymore: ${error}`, error);
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
catch (e) {
|
|
320
|
-
if (!nothrow)
|
|
321
|
-
throw e;
|
|
322
|
-
else if (this.options.kind === Options_1.Kind.Reaction)
|
|
323
|
-
(0, Dbg_1.misuse)(`reaction ${this.hint()} failed and will not run anymore: ${e}`, e);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
else if (t < Number.MAX_SAFE_INTEGER) {
|
|
328
|
-
if (hold > 0)
|
|
329
|
-
setTimeout(() => this.runIfNotUpToDate(true, true), hold);
|
|
330
|
-
else
|
|
331
|
-
this.addToDeferredReactions();
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
isNotUpToDate() {
|
|
335
|
-
return !this.error && (this.options.kind === Options_1.Kind.Transaction ||
|
|
336
|
-
!this.successor || this.successor.transaction.isCanceled);
|
|
337
|
-
}
|
|
338
|
-
reenterOver(head) {
|
|
339
|
-
let error = undefined;
|
|
340
|
-
const opponent = head.successor;
|
|
341
|
-
if (opponent && !opponent.transaction.isFinished) {
|
|
342
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.obsolete)
|
|
343
|
-
Dbg_1.Log.write('║', ' [!]', `${this.hint()} is trying to re-enter over ${opponent.hint()}`);
|
|
344
|
-
switch (head.options.reentrance) {
|
|
345
|
-
case Options_1.Reentrance.PreventWithError:
|
|
346
|
-
if (!opponent.transaction.isCanceled)
|
|
347
|
-
throw (0, Dbg_1.misuse)(`${head.hint()} (${head.why()}) is not reentrant over ${opponent.hint()} (${opponent.why()})`);
|
|
348
|
-
error = new Error(`T${this.transaction.id}[${this.transaction.hint}] is on hold/PreventWithError due to canceled T${opponent.transaction.id}[${opponent.transaction.hint}]`);
|
|
349
|
-
this.transaction.cancel(error, opponent.transaction);
|
|
350
|
-
break;
|
|
351
|
-
case Options_1.Reentrance.WaitAndRestart:
|
|
352
|
-
error = new Error(`T${this.transaction.id}[${this.transaction.hint}] is on hold/WaitAndRestart due to active T${opponent.transaction.id}[${opponent.transaction.hint}]`);
|
|
353
|
-
this.transaction.cancel(error, opponent.transaction);
|
|
354
|
-
break;
|
|
355
|
-
case Options_1.Reentrance.CancelAndWaitPrevious:
|
|
356
|
-
error = new Error(`T${this.transaction.id}[${this.transaction.hint}] is on hold/CancelAndWaitPrevious due to active T${opponent.transaction.id}[${opponent.transaction.hint}]`);
|
|
357
|
-
this.transaction.cancel(error, opponent.transaction);
|
|
358
|
-
opponent.transaction.cancel(new Error(`T${opponent.transaction.id}[${opponent.transaction.hint}] is canceled due to re-entering T${this.transaction.id}[${this.transaction.hint}]`), null);
|
|
359
|
-
break;
|
|
360
|
-
case Options_1.Reentrance.CancelPrevious:
|
|
361
|
-
opponent.transaction.cancel(new Error(`T${opponent.transaction.id}[${opponent.transaction.hint}] is canceled due to re-entering T${this.transaction.id}[${this.transaction.hint}]`), null);
|
|
362
|
-
break;
|
|
363
|
-
case Options_1.Reentrance.RunSideBySide:
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
if (!error)
|
|
368
|
-
head.successor = this;
|
|
369
|
-
else
|
|
370
|
-
this.error = error;
|
|
371
|
-
return this;
|
|
372
|
-
}
|
|
373
|
-
static run(op, proxy) {
|
|
374
|
-
op.enter();
|
|
375
|
-
try {
|
|
376
|
-
op.result = op.options.getter.call(proxy, ...op.args);
|
|
377
|
-
}
|
|
378
|
-
finally {
|
|
379
|
-
op.leaveOrAsync();
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
enter() {
|
|
383
|
-
if (this.options.monitor)
|
|
384
|
-
this.monitorEnter(this.options.monitor);
|
|
385
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
386
|
-
Dbg_1.Log.write('║', '‾\\', `${this.hint()} - enter`, undefined, ` [ ${Changeset_1.Dump.obj(this.controller.objectHandle, this.controller.memberName)} ]`);
|
|
387
|
-
this.started = Date.now();
|
|
388
|
-
}
|
|
389
|
-
leaveOrAsync() {
|
|
390
|
-
if (this.result instanceof Promise) {
|
|
391
|
-
this.result = this.result.then(value => {
|
|
392
|
-
this.content = value;
|
|
393
|
-
this.leave(false, ' ⚐', '- finished ', ' OK ──┘');
|
|
394
|
-
return value;
|
|
395
|
-
}, error => {
|
|
396
|
-
this.error = error;
|
|
397
|
-
this.leave(false, ' ⚐', '- finished ', 'ERR ──┘');
|
|
398
|
-
throw error;
|
|
399
|
-
});
|
|
400
|
-
if (Dbg_1.Log.isOn) {
|
|
401
|
-
if (Dbg_1.Log.opt.operation)
|
|
402
|
-
Dbg_1.Log.write('║', '_/', `${this.hint()} - leave... `, 0, 'ASYNC ──┐');
|
|
403
|
-
else if (Dbg_1.Log.opt.transaction)
|
|
404
|
-
Dbg_1.Log.write('║', ' ', `${this.why()} ...`, 0, 'ASYNC');
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
else {
|
|
408
|
-
this.content = this.result;
|
|
409
|
-
this.leave(true, '_/', '- leave');
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
leave(main, op, message, highlight = undefined) {
|
|
413
|
-
const ms = Date.now() - this.started;
|
|
414
|
-
this.started = -this.started;
|
|
415
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.operation)
|
|
416
|
-
Dbg_1.Log.write('║', `${op}`, `${this.hint()} ${message}`, ms, highlight);
|
|
417
|
-
if (ms > (main ? Hooks_1.Hooks.mainThreadBlockingWarningThreshold : Hooks_1.Hooks.asyncActionDurationWarningThreshold))
|
|
418
|
-
Dbg_1.Log.write('', '[!]', this.why(), ms, main ? ' *** main thread is too busy ***' : ' *** async is too long ***');
|
|
419
|
-
this.cause = undefined;
|
|
420
|
-
if (this.options.monitor)
|
|
421
|
-
this.monitorLeave(this.options.monitor);
|
|
422
|
-
}
|
|
423
|
-
monitorEnter(mon) {
|
|
424
|
-
const options = {
|
|
425
|
-
hint: 'Monitor.enter',
|
|
426
|
-
standalone: 'isolated',
|
|
427
|
-
logging: Dbg_1.Log.isOn && Dbg_1.Log.opt.monitor ? undefined : Dbg_1.Log.global
|
|
428
|
-
};
|
|
429
|
-
OperationController.runWithin(undefined, Transaction_1.Transaction.run, options, Monitor_1.MonitorImpl.enter, mon, this.transaction);
|
|
430
|
-
}
|
|
431
|
-
monitorLeave(mon) {
|
|
432
|
-
Transaction_1.Transaction.off(() => {
|
|
433
|
-
const leave = () => {
|
|
434
|
-
const options = {
|
|
435
|
-
hint: 'Monitor.leave',
|
|
436
|
-
standalone: 'isolated',
|
|
437
|
-
logging: Dbg_1.Log.isOn && Dbg_1.Log.opt.monitor ? undefined : Dbg_1.Log.DefaultLevel
|
|
438
|
-
};
|
|
439
|
-
OperationController.runWithin(undefined, Transaction_1.Transaction.run, options, Monitor_1.MonitorImpl.leave, mon, this.transaction);
|
|
440
|
-
};
|
|
441
|
-
this.transaction.whenFinished().then(leave, leave);
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
addToDeferredReactions() {
|
|
445
|
-
Operation.deferredReactions.push(this);
|
|
446
|
-
if (Operation.deferredReactions.length === 1)
|
|
447
|
-
setTimeout(Operation.processDeferredReactions, 0);
|
|
448
|
-
}
|
|
449
|
-
static processDeferredReactions() {
|
|
450
|
-
const reactions = Operation.deferredReactions;
|
|
451
|
-
Operation.deferredReactions = [];
|
|
452
|
-
for (const x of reactions)
|
|
453
|
-
x.runIfNotUpToDate(true, true);
|
|
454
|
-
}
|
|
455
|
-
static markUsed(subscription, os, m, h, kind, weak) {
|
|
456
|
-
if (kind !== Options_1.Kind.Transaction) {
|
|
457
|
-
const op = Operation.current;
|
|
458
|
-
if (op && op.options.kind !== Options_1.Kind.Transaction &&
|
|
459
|
-
op.transaction === Transaction_1.Transaction.current && m !== Data_1.Meta.Handle) {
|
|
460
|
-
const ctx = Changeset_1.Changeset.current();
|
|
461
|
-
if (ctx !== os.changeset)
|
|
462
|
-
ctx.bumpBy(os.changeset.timestamp);
|
|
463
|
-
const t = weak ? -1 : ctx.timestamp;
|
|
464
|
-
if (!op.subscribeTo(subscription, os, m, h, t))
|
|
465
|
-
op.markObsoleteDueTo(subscription, m, os.changeset, h, BOOT_CAUSE, ctx.timestamp, ctx.reactions);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
static markEdited(oldValue, newValue, edited, os, m, h) {
|
|
470
|
-
edited ? os.changes.add(m) : os.changes.delete(m);
|
|
471
|
-
if (Dbg_1.Log.isOn && Dbg_1.Log.opt.write)
|
|
472
|
-
edited ? Dbg_1.Log.write('║', ' ✎', `${Changeset_1.Dump.snapshot2(h, os.changeset, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`) : Dbg_1.Log.write('║', ' ✎', `${Changeset_1.Dump.snapshot2(h, os.changeset, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`, undefined, ' (same as previous)');
|
|
473
|
-
}
|
|
474
|
-
static isConflicting(oldValue, newValue) {
|
|
475
|
-
let result = oldValue !== newValue;
|
|
476
|
-
if (result)
|
|
477
|
-
result = oldValue instanceof Operation && oldValue.cause !== BOOT_CAUSE;
|
|
478
|
-
return result;
|
|
479
|
-
}
|
|
480
|
-
static propagateAllChangesThroughSubscriptions(changeset) {
|
|
481
|
-
var _a;
|
|
482
|
-
const since = changeset.timestamp;
|
|
483
|
-
const reactions = changeset.reactions;
|
|
484
|
-
changeset.items.forEach((os, h) => {
|
|
485
|
-
Operation.propagateMemberChangeThroughSubscriptions(false, since, os, Data_1.Meta.Revision, h, reactions);
|
|
486
|
-
if (!os.disposed)
|
|
487
|
-
os.changes.forEach((o, m) => Operation.propagateMemberChangeThroughSubscriptions(false, since, os, m, h, reactions));
|
|
488
|
-
else
|
|
489
|
-
for (const m in os.former.snapshot.data)
|
|
490
|
-
Operation.propagateMemberChangeThroughSubscriptions(true, since, os, m, h, reactions);
|
|
491
|
-
});
|
|
492
|
-
reactions.sort(compareReactionsByOrder);
|
|
493
|
-
(_a = changeset.options.journal) === null || _a === void 0 ? void 0 : _a.edited(Journal_1.JournalImpl.buildPatch(changeset.hint, changeset.items));
|
|
494
|
-
}
|
|
495
|
-
static revokeAllSubscriptions(changeset) {
|
|
496
|
-
changeset.items.forEach((os, h) => {
|
|
497
|
-
Operation.propagateMemberChangeThroughSubscriptions(true, changeset.timestamp, os, Data_1.Meta.Revision, h, undefined);
|
|
498
|
-
os.changes.forEach((o, m) => Operation.propagateMemberChangeThroughSubscriptions(true, changeset.timestamp, os, m, h, undefined));
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
static propagateMemberChangeThroughSubscriptions(unsubscribe, timestamp, os, m, h, reactions) {
|
|
502
|
-
var _a;
|
|
503
|
-
const curr = os.data[m];
|
|
504
|
-
if (reactions) {
|
|
505
|
-
const former = os.former.snapshot.data[m];
|
|
506
|
-
if (former !== undefined && former instanceof Data_1.Subscription) {
|
|
507
|
-
const why = `T${os.changeset.id}[${os.changeset.hint}]`;
|
|
508
|
-
if (former instanceof Operation) {
|
|
509
|
-
if ((former.obsoleteSince === Changeset_1.MAX_REVISION || former.obsoleteSince <= 0)) {
|
|
510
|
-
former.obsoleteDueTo = why;
|
|
511
|
-
former.obsoleteSince = timestamp;
|
|
512
|
-
former.unsubscribeFromAllSubscriptions();
|
|
513
|
-
}
|
|
514
|
-
const formerSuccessor = former.successor;
|
|
515
|
-
if (formerSuccessor !== curr) {
|
|
516
|
-
if (formerSuccessor && !formerSuccessor.transaction.isFinished)
|
|
517
|
-
formerSuccessor.transaction.cancel(new Error(`T${formerSuccessor.transaction.id}[${formerSuccessor.transaction.hint}] is canceled by T${os.changeset.id}[${os.changeset.hint}] and will not run anymore`), null);
|
|
518
|
-
}
|
|
519
|
-
else
|
|
520
|
-
former.successor = undefined;
|
|
521
|
-
}
|
|
522
|
-
(_a = former.subscribers) === null || _a === void 0 ? void 0 : _a.forEach(s => s.markObsoleteDueTo(former, m, os.changeset, h, why, timestamp, reactions));
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
if (curr instanceof Operation) {
|
|
526
|
-
if (curr.changeset === os.changeset && curr.subscriptions !== undefined) {
|
|
527
|
-
if (Hooks_1.Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
528
|
-
curr.subscriptions.forEach((info, v) => {
|
|
529
|
-
if (info.usageCount > Hooks_1.Hooks.repetitiveUsageWarningThreshold)
|
|
530
|
-
Dbg_1.Log.write('', '[!]', `${curr.hint()} uses ${info.memberHint} ${info.usageCount} times (consider remembering it in a local variable)`, 0, ' *** WARNING ***');
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
if (unsubscribe)
|
|
534
|
-
curr.unsubscribeFromAllSubscriptions();
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
else if (curr instanceof Data_1.Subscription && curr.subscribers) {
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
static enqueueReactionsToRun(reactions) {
|
|
541
|
-
const queue = Operation.queuedReactions;
|
|
542
|
-
const isReactionLoopRequired = queue.length === 0;
|
|
543
|
-
for (const r of reactions)
|
|
544
|
-
queue.push(r);
|
|
545
|
-
if (isReactionLoopRequired)
|
|
546
|
-
OperationController.runWithin(undefined, Operation.runQueuedReactionsLoop);
|
|
547
|
-
}
|
|
548
|
-
static runQueuedReactionsLoop() {
|
|
549
|
-
const queue = Operation.queuedReactions;
|
|
550
|
-
let i = 0;
|
|
551
|
-
while (i < queue.length) {
|
|
552
|
-
const reaction = queue[i];
|
|
553
|
-
reaction.runIfNotUpToDate(false, true);
|
|
554
|
-
i++;
|
|
555
|
-
}
|
|
556
|
-
Operation.queuedReactions = [];
|
|
557
|
-
}
|
|
558
|
-
unsubscribeFromAllSubscriptions() {
|
|
559
|
-
var _a;
|
|
560
|
-
(_a = this.subscriptions) === null || _a === void 0 ? void 0 : _a.forEach((info, value) => {
|
|
561
|
-
var _a;
|
|
562
|
-
value.subscribers.delete(this);
|
|
563
|
-
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
564
|
-
Dbg_1.Log.write(Dbg_1.Log.opt.transaction && !Changeset_1.Changeset.current().sealed ? '║' : ' ', '-', `${this.hint()} is unsubscribed from ${info.memberHint}`);
|
|
565
|
-
});
|
|
566
|
-
this.subscriptions = undefined;
|
|
567
|
-
}
|
|
568
|
-
subscribeTo(subscription, os, m, h, timestamp) {
|
|
569
|
-
var _a, _b, _c;
|
|
570
|
-
const ok = Operation.canSubscribe(subscription, os, m, h, timestamp);
|
|
571
|
-
if (ok) {
|
|
572
|
-
let times = 0;
|
|
573
|
-
if (Hooks_1.Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
574
|
-
const existing = this.subscriptions.get(subscription);
|
|
575
|
-
times = existing ? existing.usageCount + 1 : 1;
|
|
576
|
-
}
|
|
577
|
-
if (this.subscriptions !== undefined) {
|
|
578
|
-
if (!subscription.subscribers)
|
|
579
|
-
subscription.subscribers = new Set();
|
|
580
|
-
const info = { memberHint: Changeset_1.Dump.snapshot2(h, os.changeset, m), usageCount: times };
|
|
581
|
-
subscription.subscribers.add(this);
|
|
582
|
-
this.subscriptions.set(subscription, info);
|
|
583
|
-
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
584
|
-
Dbg_1.Log.write('║', ' ∞ ', `${this.hint()} is subscribed to ${Changeset_1.Dump.snapshot2(h, os.changeset, m)}${info.usageCount > 1 ? ` (${info.usageCount} times)` : ''}`);
|
|
585
|
-
}
|
|
586
|
-
else if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_b = this.options.logging) === null || _b === void 0 ? void 0 : _b.read)))
|
|
587
|
-
Dbg_1.Log.write('║', ' x ', `${this.hint()} is obsolete and is NOT subscribed to ${Changeset_1.Dump.snapshot2(h, os.changeset, m)}`);
|
|
588
|
-
}
|
|
589
|
-
else {
|
|
590
|
-
if (Dbg_1.Log.isOn && (Dbg_1.Log.opt.read || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.read)))
|
|
591
|
-
Dbg_1.Log.write('║', ' x ', `${this.hint()} is NOT subscribed to already obsolete ${Changeset_1.Dump.snapshot2(h, os.changeset, m)}`);
|
|
592
|
-
}
|
|
593
|
-
return ok;
|
|
594
|
-
}
|
|
595
|
-
static canSubscribe(subscription, os, m, h, timestamp) {
|
|
596
|
-
let result = !os.changeset.sealed || subscription === h.head.data[m];
|
|
597
|
-
if (result && timestamp !== -1)
|
|
598
|
-
result = !(subscription instanceof Operation && timestamp >= subscription.obsoleteSince);
|
|
599
|
-
return result;
|
|
600
|
-
}
|
|
601
|
-
static createOperation(h, m, options) {
|
|
602
|
-
const ctl = new OperationController(h, m);
|
|
603
|
-
const operation = (...args) => {
|
|
604
|
-
return ctl.useOrRun(false, args).result;
|
|
605
|
-
};
|
|
606
|
-
Data_1.Meta.set(operation, Data_1.Meta.Controller, ctl);
|
|
607
|
-
return operation;
|
|
608
|
-
}
|
|
609
|
-
static rememberOperationOptions(proto, m, getter, setter, enumerable, configurable, options, implicit) {
|
|
610
|
-
const initial = Data_1.Meta.acquire(proto, Data_1.Meta.Initial);
|
|
611
|
-
let op = initial[m];
|
|
612
|
-
const ctl = op ? op.controller : new OperationController(EMPTY_HANDLE, m);
|
|
613
|
-
const opts = op ? op.options : Hooks_1.OptionsImpl.INITIAL;
|
|
614
|
-
initial[m] = op = new Operation(ctl, Changeset_1.EMPTY_SNAPSHOT.changeset, new Hooks_1.OptionsImpl(getter, setter, opts, options, implicit));
|
|
615
|
-
if (op.options.kind === Options_1.Kind.Reaction && op.options.throttling < Number.MAX_SAFE_INTEGER) {
|
|
616
|
-
const reactions = Data_1.Meta.acquire(proto, Data_1.Meta.Reactions);
|
|
617
|
-
reactions[m] = op;
|
|
618
|
-
}
|
|
619
|
-
else if (op.options.kind === Options_1.Kind.Reaction && op.options.throttling >= Number.MAX_SAFE_INTEGER) {
|
|
620
|
-
const reactions = Data_1.Meta.getFrom(proto, Data_1.Meta.Reactions);
|
|
621
|
-
delete reactions[m];
|
|
622
|
-
}
|
|
623
|
-
return op.options;
|
|
624
|
-
}
|
|
625
|
-
static init() {
|
|
626
|
-
Object.freeze(BOOT_ARGS);
|
|
627
|
-
Dbg_1.Log.getMergedLoggingOptions = getMergedLoggingOptions;
|
|
628
|
-
Changeset_1.Dump.valueHint = valueHint;
|
|
629
|
-
Changeset_1.Changeset.markUsed = Operation.markUsed;
|
|
630
|
-
Changeset_1.Changeset.markEdited = Operation.markEdited;
|
|
631
|
-
Changeset_1.Changeset.isConflicting = Operation.isConflicting;
|
|
632
|
-
Changeset_1.Changeset.propagateAllChangesThroughSubscriptions = Operation.propagateAllChangesThroughSubscriptions;
|
|
633
|
-
Changeset_1.Changeset.revokeAllSubscriptions = Operation.revokeAllSubscriptions;
|
|
634
|
-
Changeset_1.Changeset.enqueueReactionsToRun = Operation.enqueueReactionsToRun;
|
|
635
|
-
Hooks_1.Hooks.createOperation = Operation.createOperation;
|
|
636
|
-
Hooks_1.Hooks.rememberOperationOptions = Operation.rememberOperationOptions;
|
|
637
|
-
Promise.prototype.then = reactronicHookedThen;
|
|
638
|
-
try {
|
|
639
|
-
Object.defineProperty(globalThis, 'rWhy', {
|
|
640
|
-
get: OperationController.why, configurable: false, enumerable: false,
|
|
641
|
-
});
|
|
642
|
-
Object.defineProperty(globalThis, 'rBriefWhy', {
|
|
643
|
-
get: OperationController.briefWhy, configurable: false, enumerable: false,
|
|
644
|
-
});
|
|
645
|
-
}
|
|
646
|
-
catch (e) {
|
|
647
|
-
}
|
|
648
|
-
try {
|
|
649
|
-
Object.defineProperty(global, 'rWhy', {
|
|
650
|
-
get: OperationController.why, configurable: false, enumerable: false,
|
|
651
|
-
});
|
|
652
|
-
Object.defineProperty(global, 'rBriefWhy', {
|
|
653
|
-
get: OperationController.briefWhy, configurable: false, enumerable: false,
|
|
654
|
-
});
|
|
655
|
-
}
|
|
656
|
-
catch (e) {
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
Operation.current = undefined;
|
|
661
|
-
Operation.queuedReactions = [];
|
|
662
|
-
Operation.deferredReactions = [];
|
|
663
|
-
function valueHint(value, m) {
|
|
664
|
-
let result = '';
|
|
665
|
-
if (Array.isArray(value))
|
|
666
|
-
result = `Array(${value.length})`;
|
|
667
|
-
else if (value instanceof Set)
|
|
668
|
-
result = `Set(${value.size})`;
|
|
669
|
-
else if (value instanceof Map)
|
|
670
|
-
result = `Map(${value.size})`;
|
|
671
|
-
else if (value instanceof Operation)
|
|
672
|
-
result = `${Changeset_1.Dump.snapshot2(value.controller.objectHandle, value.changeset, m)}`;
|
|
673
|
-
else if (value === Data_1.Meta.Undefined)
|
|
674
|
-
result = 'undefined';
|
|
675
|
-
else if (typeof (value) === 'string')
|
|
676
|
-
result = `"${value.toString().slice(0, 20)}"`;
|
|
677
|
-
else if (value !== undefined && value !== null)
|
|
678
|
-
result = value.toString().slice(0, 40);
|
|
679
|
-
else
|
|
680
|
-
result = 'undefined';
|
|
681
|
-
return result;
|
|
682
|
-
}
|
|
683
|
-
function getMergedLoggingOptions(local) {
|
|
684
|
-
const t = Transaction_1.Transaction.current;
|
|
685
|
-
let res = Dbg_1.Log.merge(t.options.logging, t.id > 1 ? 31 + t.id % 6 : 37, t.id > 1 ? `T${t.id}` : `-${Changeset_1.Changeset.idGen.toString().replace(/[0-9]/g, '-')}`, Dbg_1.Log.global);
|
|
686
|
-
res = Dbg_1.Log.merge({ margin1: t.margin }, undefined, undefined, res);
|
|
687
|
-
if (Operation.current)
|
|
688
|
-
res = Dbg_1.Log.merge({ margin2: Operation.current.margin }, undefined, undefined, res);
|
|
689
|
-
if (local)
|
|
690
|
-
res = Dbg_1.Log.merge(local, undefined, undefined, res);
|
|
691
|
-
return res;
|
|
692
|
-
}
|
|
693
|
-
const ORIGINAL_PROMISE_THEN = Promise.prototype.then;
|
|
694
|
-
function reactronicHookedThen(resolve, reject) {
|
|
695
|
-
const tran = Transaction_1.Transaction.current;
|
|
696
|
-
if (!tran.isFinished) {
|
|
697
|
-
if (!resolve)
|
|
698
|
-
resolve = resolveReturn;
|
|
699
|
-
if (!reject)
|
|
700
|
-
reject = rejectRethrow;
|
|
701
|
-
const op = Operation.current;
|
|
702
|
-
if (op) {
|
|
703
|
-
resolve = op.wrap(resolve);
|
|
704
|
-
reject = op.wrap(reject);
|
|
705
|
-
}
|
|
706
|
-
resolve = tran.wrap(resolve, false);
|
|
707
|
-
reject = tran.wrap(reject, true);
|
|
708
|
-
}
|
|
709
|
-
return ORIGINAL_PROMISE_THEN.call(this, resolve, reject);
|
|
710
|
-
}
|
|
711
|
-
function compareReactionsByOrder(a, b) {
|
|
712
|
-
return a.order - b.order;
|
|
713
|
-
}
|
|
714
|
-
function resolveReturn(value) {
|
|
715
|
-
return value;
|
|
716
|
-
}
|
|
717
|
-
exports.resolveReturn = resolveReturn;
|
|
718
|
-
function rejectRethrow(error) {
|
|
719
|
-
throw error;
|
|
720
|
-
}
|
|
721
|
-
exports.rejectRethrow = rejectRethrow;
|
|
722
|
-
Operation.init();
|