reactronic 0.21.602 → 0.22.102
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 +4 -4
- package/build/dist/source/Rx.d.ts +1 -1
- package/build/dist/source/Rx.js +4 -4
- package/build/dist/source/Trace.d.ts +1 -0
- package/build/dist/source/Trace.js +18 -0
- package/build/dist/source/api.d.ts +1 -1
- package/build/dist/source/api.js +2 -2
- package/build/dist/source/impl/Data.d.ts +3 -2
- package/build/dist/source/impl/Operation.d.ts +6 -6
- package/build/dist/source/impl/Operation.js +56 -69
- package/build/dist/source/impl/Snapshot.d.ts +2 -2
- package/build/dist/source/impl/Snapshot.js +16 -18
- package/build/dist/source/impl/Transaction.d.ts +1 -1
- package/build/dist/source/impl/Transaction.js +5 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -196,7 +196,7 @@ class Component<P> extends React.Component<P> {
|
|
|
196
196
|
@reaction // called immediately in response to changes
|
|
197
197
|
ensureUpToDate(): void {
|
|
198
198
|
if (this.shouldComponentUpdate())
|
|
199
|
-
|
|
199
|
+
nontransactional(() => this.setState({})) // ask React to re-render
|
|
200
200
|
} // ensureUpToDate is subscribed to render
|
|
201
201
|
|
|
202
202
|
shouldComponentUpdate(): boolean {
|
|
@@ -208,7 +208,7 @@ class Component<P> extends React.Component<P> {
|
|
|
208
208
|
}
|
|
209
209
|
|
|
210
210
|
componentWillUnmount(): void {
|
|
211
|
-
standalone
|
|
211
|
+
Transaction.runAs({ standalone: true }, Rx.dispose, this)
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
```
|
|
@@ -310,7 +310,7 @@ function monitor(value: Monitor | null)
|
|
|
310
310
|
function trace(value: Partial<TraceOptions>)
|
|
311
311
|
|
|
312
312
|
function nonreactive<T>(func: F<T>, ...args: any[]): T
|
|
313
|
-
function
|
|
313
|
+
function nontransactional<T>(func: F<T>, ...args: any[]): T
|
|
314
314
|
function sensitive<T>(sensitivity: Sensitivity, func: F<T>, ...args: any[]): T
|
|
315
315
|
|
|
316
316
|
// Options, ObjectOptions, Kind, Reentrance, Monitor, TraceOptions, ProfilingOptions
|
|
@@ -421,7 +421,7 @@ class Transaction implements Worker {
|
|
|
421
421
|
static run<T>(hint: string, func: F<T>, ...args: any[]): T
|
|
422
422
|
static runEx<T>(hint: string, standalone: boolean, sidebyside: boolean,
|
|
423
423
|
trace: Partial<TraceOptions | undefined>, func: F<T>, ...args: any[]): T
|
|
424
|
-
static
|
|
424
|
+
static nontransactional<T>(func: F<T>, ...args: any[]): T
|
|
425
425
|
}
|
|
426
426
|
|
|
427
427
|
// Controller
|
|
@@ -18,7 +18,7 @@ export declare class Rx {
|
|
|
18
18
|
static setProfilingMode(enabled: boolean, options?: Partial<ProfilingOptions>): void;
|
|
19
19
|
}
|
|
20
20
|
export declare function nonreactive<T>(func: F<T>, ...args: any[]): T;
|
|
21
|
-
export declare function
|
|
21
|
+
export declare function nontransactional<T>(func: F<T>, ...args: any[]): T;
|
|
22
22
|
export declare function sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
|
|
23
23
|
export declare function unobservable(proto: object, prop: PropertyKey): any;
|
|
24
24
|
export declare function transaction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
|
package/build/dist/source/Rx.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.options = exports.cached = exports.reaction = exports.transaction = exports.unobservable = exports.sensitive = exports.
|
|
3
|
+
exports.options = exports.cached = exports.reaction = exports.transaction = exports.unobservable = exports.sensitive = exports.nontransactional = exports.nonreactive = exports.Rx = void 0;
|
|
4
4
|
const Dbg_1 = require("./util/Dbg");
|
|
5
5
|
const Options_1 = require("./Options");
|
|
6
6
|
const Data_1 = require("./impl/Data");
|
|
@@ -29,10 +29,10 @@ function nonreactive(func, ...args) {
|
|
|
29
29
|
return Operation_1.OperationController.runWithin(undefined, func, ...args);
|
|
30
30
|
}
|
|
31
31
|
exports.nonreactive = nonreactive;
|
|
32
|
-
function
|
|
33
|
-
return
|
|
32
|
+
function nontransactional(func, ...args) {
|
|
33
|
+
return Transaction_1.Transaction.off(func, ...args);
|
|
34
34
|
}
|
|
35
|
-
exports.
|
|
35
|
+
exports.nontransactional = nontransactional;
|
|
36
36
|
function sensitive(sensitivity, func, ...args) {
|
|
37
37
|
return Hooks_1.Hooks.sensitive(sensitivity, func, ...args);
|
|
38
38
|
}
|
|
@@ -20,6 +20,24 @@ exports.TraceLevel = {
|
|
|
20
20
|
margin1: 0,
|
|
21
21
|
margin2: 0,
|
|
22
22
|
},
|
|
23
|
+
Reactions: {
|
|
24
|
+
silent: false,
|
|
25
|
+
transaction: false,
|
|
26
|
+
operation: false,
|
|
27
|
+
step: false,
|
|
28
|
+
monitor: false,
|
|
29
|
+
read: false,
|
|
30
|
+
write: false,
|
|
31
|
+
change: false,
|
|
32
|
+
obsolete: true,
|
|
33
|
+
error: true,
|
|
34
|
+
warning: true,
|
|
35
|
+
gc: false,
|
|
36
|
+
color: 37,
|
|
37
|
+
prefix: '',
|
|
38
|
+
margin1: 0,
|
|
39
|
+
margin2: 0,
|
|
40
|
+
},
|
|
23
41
|
Transactions: {
|
|
24
42
|
silent: false,
|
|
25
43
|
transaction: true,
|
|
@@ -11,4 +11,4 @@ export { Snapshot } from './impl/Snapshot';
|
|
|
11
11
|
export { Transaction } from './impl/Transaction';
|
|
12
12
|
export { Monitor } from './impl/Monitor';
|
|
13
13
|
export { TransactionJournal } from './impl/TransactionJournal';
|
|
14
|
-
export { Rx, nonreactive,
|
|
14
|
+
export { Rx, nonreactive, nontransactional, sensitive, unobservable, transaction, reaction, cached, options } from './Rx';
|
package/build/dist/source/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.options = exports.cached = exports.reaction = exports.transaction = exports.unobservable = exports.sensitive = exports.
|
|
3
|
+
exports.options = exports.cached = exports.reaction = exports.transaction = exports.unobservable = exports.sensitive = exports.nontransactional = exports.nonreactive = exports.Rx = exports.TransactionJournal = exports.Monitor = exports.Transaction = exports.Snapshot = exports.ObservableObject = exports.ToggleRef = exports.Ref = exports.Controller = exports.TraceLevel = exports.Reentrance = exports.Kind = exports.SealedSet = exports.SealedMap = exports.SealedArray = exports.pause = exports.all = void 0;
|
|
4
4
|
var Utils_1 = require("./util/Utils");
|
|
5
5
|
Object.defineProperty(exports, "all", { enumerable: true, get: function () { return Utils_1.all; } });
|
|
6
6
|
Object.defineProperty(exports, "pause", { enumerable: true, get: function () { return Utils_1.pause; } });
|
|
@@ -32,7 +32,7 @@ Object.defineProperty(exports, "TransactionJournal", { enumerable: true, get: fu
|
|
|
32
32
|
var Rx_1 = require("./Rx");
|
|
33
33
|
Object.defineProperty(exports, "Rx", { enumerable: true, get: function () { return Rx_1.Rx; } });
|
|
34
34
|
Object.defineProperty(exports, "nonreactive", { enumerable: true, get: function () { return Rx_1.nonreactive; } });
|
|
35
|
-
Object.defineProperty(exports, "
|
|
35
|
+
Object.defineProperty(exports, "nontransactional", { enumerable: true, get: function () { return Rx_1.nontransactional; } });
|
|
36
36
|
Object.defineProperty(exports, "sensitive", { enumerable: true, get: function () { return Rx_1.sensitive; } });
|
|
37
37
|
Object.defineProperty(exports, "unobservable", { enumerable: true, get: function () { return Rx_1.unobservable; } });
|
|
38
38
|
Object.defineProperty(exports, "transaction", { enumerable: true, get: function () { return Rx_1.transaction; } });
|
|
@@ -18,12 +18,13 @@ export interface Observer {
|
|
|
18
18
|
readonly observables: Map<Observable, MemberInfo> | undefined;
|
|
19
19
|
readonly obsoleteSince: number;
|
|
20
20
|
hint(nop?: boolean): string;
|
|
21
|
-
markObsoleteDueTo(observable: Observable,
|
|
21
|
+
markObsoleteDueTo(observable: Observable, memberName: MemberName, snapshot: AbstractSnapshot, holder: ObjectHolder, outer: string, since: number, reactions: Observer[]): void;
|
|
22
22
|
runIfNotUpToDate(now: boolean, nothrow: boolean): void;
|
|
23
23
|
}
|
|
24
24
|
export declare type MemberName = PropertyKey;
|
|
25
25
|
export interface MemberInfo {
|
|
26
|
-
readonly
|
|
26
|
+
readonly holder: ObjectHolder;
|
|
27
|
+
readonly snapshot: AbstractSnapshot;
|
|
27
28
|
readonly memberName: MemberName;
|
|
28
29
|
readonly usageCount: number;
|
|
29
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { F } from '../util/Utils';
|
|
2
2
|
import { MemberOptions } from '../Options';
|
|
3
3
|
import { Controller } from '../Controller';
|
|
4
|
-
import {
|
|
4
|
+
import { MemberName, ObjectHolder, Observable, Observer, MemberInfo, AbstractSnapshot } from './Data';
|
|
5
5
|
import { Transaction } from './Transaction';
|
|
6
6
|
import { OptionsImpl } from './Hooks';
|
|
7
7
|
export declare class OperationController extends Controller<any> {
|
|
@@ -39,18 +39,18 @@ declare class Operation extends Observable implements Observer {
|
|
|
39
39
|
readonly margin: number;
|
|
40
40
|
readonly transaction: Transaction;
|
|
41
41
|
readonly controller: OperationController;
|
|
42
|
-
readonly
|
|
42
|
+
readonly snapshot: AbstractSnapshot;
|
|
43
43
|
observables: Map<Observable, MemberInfo> | undefined;
|
|
44
44
|
options: OptionsImpl;
|
|
45
|
-
cause:
|
|
45
|
+
cause: string | undefined;
|
|
46
46
|
args: any[];
|
|
47
47
|
result: any;
|
|
48
48
|
error: any;
|
|
49
49
|
started: number;
|
|
50
|
-
obsoleteDueTo:
|
|
50
|
+
obsoleteDueTo: string | undefined;
|
|
51
51
|
obsoleteSince: number;
|
|
52
52
|
successor: Operation | undefined;
|
|
53
|
-
constructor(controller: OperationController,
|
|
53
|
+
constructor(controller: OperationController, snapshot: AbstractSnapshot, prev: Operation | OptionsImpl);
|
|
54
54
|
get isOperation(): boolean;
|
|
55
55
|
get selfSnapshotId(): number;
|
|
56
56
|
hint(): string;
|
|
@@ -61,7 +61,7 @@ declare class Operation extends Observable implements Observer {
|
|
|
61
61
|
dependencies(): string[];
|
|
62
62
|
wrap<T>(func: F<T>): F<T>;
|
|
63
63
|
run(proxy: any, args: any[] | undefined): void;
|
|
64
|
-
markObsoleteDueTo(observable: Observable,
|
|
64
|
+
markObsoleteDueTo(observable: Observable, memberName: MemberName, snapshot: AbstractSnapshot, holder: ObjectHolder, outer: string, since: number, reactions: Observer[]): void;
|
|
65
65
|
runIfNotUpToDate(now: boolean, nothrow: boolean): void;
|
|
66
66
|
isNotUpToDate(): boolean;
|
|
67
67
|
reenterOver(head: Operation): this;
|
|
@@ -12,7 +12,7 @@ const Hooks_1 = require("./Hooks");
|
|
|
12
12
|
const TransactionJournal_1 = require("./TransactionJournal");
|
|
13
13
|
const ROOT_ARGS = [];
|
|
14
14
|
const ROOT_HOLDER = new Data_1.ObjectHolder(undefined, undefined, Hooks_1.Hooks.proxy, Snapshot_1.ROOT_REV, 'root-holder');
|
|
15
|
-
const
|
|
15
|
+
const INITIAL_CAUSE = 'initial';
|
|
16
16
|
class OperationController extends Controller_1.Controller {
|
|
17
17
|
constructor(ownHolder, memberName) {
|
|
18
18
|
super();
|
|
@@ -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 === INITIAL_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 ||
|
|
@@ -45,13 +45,13 @@ class OperationController extends Controller_1.Controller {
|
|
|
45
45
|
oc.revision.prev.revision !== Snapshot_1.ROOT_REV));
|
|
46
46
|
const token = opts.noSideEffects ? this : undefined;
|
|
47
47
|
const oc2 = this.run(oc, standalone, opts, token, args);
|
|
48
|
-
const ctx2 = oc2.operation.
|
|
48
|
+
const ctx2 = oc2.operation.snapshot;
|
|
49
49
|
if (!weak || ctx === ctx2 || (ctx2.sealed && ctx.timestamp >= ctx2.timestamp))
|
|
50
50
|
oc = oc2;
|
|
51
51
|
}
|
|
52
52
|
else if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.operation && (opts.trace === undefined ||
|
|
53
53
|
opts.trace.operation === undefined || opts.trace.operation === true))
|
|
54
|
-
Dbg_1.Dbg.log(Transaction_1.Transaction.current.isFinished ? '' : '║', ' (=)', `${Snapshot_1.Dump.
|
|
54
|
+
Dbg_1.Dbg.log(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;
|
|
@@ -108,8 +108,8 @@ class OperationController extends Controller_1.Controller {
|
|
|
108
108
|
const ctx = Snapshot_1.Snapshot.current();
|
|
109
109
|
const r = ctx.seekRevision(this.ownHolder, this.memberName);
|
|
110
110
|
const op = this.peekFromRevision(r, args);
|
|
111
|
-
const isValid = op.options.kind !== Options_1.Kind.Transaction && op.cause !==
|
|
112
|
-
(ctx === op.
|
|
111
|
+
const isValid = op.options.kind !== Options_1.Kind.Transaction && op.cause !== INITIAL_CAUSE &&
|
|
112
|
+
(ctx === op.snapshot || ctx.timestamp < op.obsoleteSince) &&
|
|
113
113
|
(!op.options.sensitiveArgs || 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;
|
|
@@ -126,8 +126,8 @@ class OperationController extends Controller_1.Controller {
|
|
|
126
126
|
const ctx = Snapshot_1.Snapshot.edit();
|
|
127
127
|
const r = ctx.getEditableRevision(h, m, Data_1.Meta.Holder, this);
|
|
128
128
|
let op = this.peekFromRevision(r, undefined);
|
|
129
|
-
if (op.
|
|
130
|
-
const op2 = new Operation(this, r, op);
|
|
129
|
+
if (op.snapshot !== r.snapshot) {
|
|
130
|
+
const op2 = new Operation(this, r.snapshot, op);
|
|
131
131
|
r.data[m] = op2.reenterOver(op);
|
|
132
132
|
ctx.bumpBy(r.prev.revision.snapshot.timestamp);
|
|
133
133
|
Snapshot_1.Snapshot.markEdited(op, op2, true, r, m, h);
|
|
@@ -147,10 +147,10 @@ class OperationController extends Controller_1.Controller {
|
|
|
147
147
|
let op2 = r2.data[m];
|
|
148
148
|
if (op2.controller !== this) {
|
|
149
149
|
r2 = Snapshot_1.Snapshot.edit().getEditableRevision(h, m, Data_1.Meta.Holder, this);
|
|
150
|
-
const t = new Operation(this, r2, op2);
|
|
150
|
+
const t = new Operation(this, r2.snapshot, op2);
|
|
151
151
|
if (args)
|
|
152
152
|
t.args = args;
|
|
153
|
-
t.cause =
|
|
153
|
+
t.cause = INITIAL_CAUSE;
|
|
154
154
|
r2.data[m] = t;
|
|
155
155
|
Snapshot_1.Snapshot.markEdited(op2, t, true, r2, m, h);
|
|
156
156
|
op2 = t;
|
|
@@ -188,17 +188,17 @@ class OperationController extends Controller_1.Controller {
|
|
|
188
188
|
static markObsolete(self) {
|
|
189
189
|
const oc = self.peek(undefined);
|
|
190
190
|
const ctx = oc.snapshot;
|
|
191
|
-
oc.operation.markObsoleteDueTo(oc.operation,
|
|
191
|
+
oc.operation.markObsoleteDueTo(oc.operation, self.memberName, Snapshot_1.ROOT_REV.snapshot, ROOT_HOLDER, INITIAL_CAUSE, ctx.timestamp, ctx.reactions);
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
exports.OperationController = OperationController;
|
|
195
195
|
class Operation extends Data_1.Observable {
|
|
196
|
-
constructor(controller,
|
|
196
|
+
constructor(controller, snapshot, prev) {
|
|
197
197
|
super(undefined);
|
|
198
198
|
this.margin = Operation.current ? Operation.current.margin + 1 : 1;
|
|
199
199
|
this.transaction = Transaction_1.Transaction.current;
|
|
200
200
|
this.controller = controller;
|
|
201
|
-
this.
|
|
201
|
+
this.snapshot = snapshot;
|
|
202
202
|
this.observables = new Map();
|
|
203
203
|
if (prev instanceof Operation) {
|
|
204
204
|
this.options = prev.options;
|
|
@@ -216,28 +216,24 @@ class Operation extends Data_1.Observable {
|
|
|
216
216
|
this.successor = undefined;
|
|
217
217
|
}
|
|
218
218
|
get isOperation() { return true; }
|
|
219
|
-
get selfSnapshotId() { return this.
|
|
220
|
-
hint() { return `${Snapshot_1.Dump.
|
|
219
|
+
get selfSnapshotId() { return this.snapshot.id; }
|
|
220
|
+
hint() { return `${Snapshot_1.Dump.rev2(this.controller.ownHolder, this.snapshot, this.controller.memberName)}`; }
|
|
221
221
|
get order() { return this.options.order; }
|
|
222
222
|
get ['#this']() {
|
|
223
223
|
return `Operation: ${this.why()}`;
|
|
224
224
|
}
|
|
225
225
|
why() {
|
|
226
|
-
let
|
|
227
|
-
const prev = this.revision.prev.revision.data[this.controller.memberName];
|
|
228
|
-
if (prev instanceof Operation)
|
|
229
|
-
ms = prev.started !== 0 ? Math.abs(this.started || ms) - Math.abs(prev.started) : Infinity;
|
|
230
|
-
let trigger;
|
|
226
|
+
let cause;
|
|
231
227
|
if (this.cause)
|
|
232
|
-
|
|
228
|
+
cause = ` << ${this.cause}`;
|
|
233
229
|
else if (this.controller.options.kind === Options_1.Kind.Transaction)
|
|
234
|
-
|
|
230
|
+
cause = ' << operation';
|
|
235
231
|
else
|
|
236
|
-
|
|
237
|
-
return `${this.hint()}${
|
|
232
|
+
cause = ` << T${this.snapshot.id}[${this.snapshot.hint}]`;
|
|
233
|
+
return `${this.hint()}${cause}`;
|
|
238
234
|
}
|
|
239
235
|
briefWhy() {
|
|
240
|
-
return this.
|
|
236
|
+
return this.why();
|
|
241
237
|
}
|
|
242
238
|
dependencies() {
|
|
243
239
|
throw (0, Dbg_1.misuse)('not implemented yet');
|
|
@@ -266,34 +262,33 @@ class Operation extends Data_1.Observable {
|
|
|
266
262
|
else
|
|
267
263
|
this.result = Promise.reject(this.error);
|
|
268
264
|
}
|
|
269
|
-
markObsoleteDueTo(observable,
|
|
265
|
+
markObsoleteDueTo(observable, memberName, snapshot, holder, outer, since, reactions) {
|
|
270
266
|
var _a, _b, _c;
|
|
271
267
|
if (this.observables !== undefined) {
|
|
272
268
|
const skip = !observable.isOperation &&
|
|
273
|
-
|
|
274
|
-
cause.revision.changes.has(cause.memberName);
|
|
269
|
+
snapshot === this.snapshot;
|
|
275
270
|
if (!skip) {
|
|
271
|
+
const why = `${Snapshot_1.Dump.rev2(holder, snapshot, memberName)} << ${outer}`;
|
|
276
272
|
this.unsubscribeFromAllObservables();
|
|
277
|
-
this.obsoleteDueTo =
|
|
273
|
+
this.obsoleteDueTo = why;
|
|
278
274
|
this.obsoleteSince = since;
|
|
279
275
|
const isReaction = this.options.kind === Options_1.Kind.Reaction;
|
|
280
276
|
if (Dbg_1.Dbg.isOn && (Dbg_1.Dbg.trace.obsolete || ((_a = this.options.trace) === null || _a === void 0 ? void 0 : _a.obsolete)))
|
|
281
|
-
Dbg_1.Dbg.log(Dbg_1.Dbg.trace.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', isReaction ? '█' : '▒', isReaction &&
|
|
277
|
+
Dbg_1.Dbg.log(Dbg_1.Dbg.trace.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', isReaction ? '█' : '▒', isReaction && snapshot === Snapshot_1.ROOT_REV.snapshot
|
|
282
278
|
? `${this.hint()} is a reaction and will run automatically (order ${this.options.order})`
|
|
283
|
-
: `${this.hint()} is obsolete due to ${Snapshot_1.Dump.
|
|
279
|
+
: `${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})` : ''}`);
|
|
284
280
|
if (isReaction)
|
|
285
281
|
reactions.push(this);
|
|
286
282
|
else
|
|
287
|
-
(_b = this.observers) === null || _b === void 0 ? void 0 : _b.forEach(c => c.markObsoleteDueTo(this,
|
|
283
|
+
(_b = this.observers) === null || _b === void 0 ? void 0 : _b.forEach(c => c.markObsoleteDueTo(this, this.controller.memberName, this.snapshot, this.controller.ownHolder, why, since, reactions));
|
|
288
284
|
const tran = this.transaction;
|
|
289
|
-
if (tran.snapshot ===
|
|
290
|
-
(0, Dbg_1.misuse)('not implemented: running reactions within original transaction');
|
|
285
|
+
if (tran.snapshot === snapshot) {
|
|
291
286
|
}
|
|
292
287
|
else if (!tran.isFinished && this !== observable)
|
|
293
|
-
tran.cancel(new Error(`T${tran.id}[${tran.hint}] is canceled due to obsolete ${Snapshot_1.Dump.
|
|
288
|
+
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);
|
|
294
289
|
}
|
|
295
290
|
else if (Dbg_1.Dbg.isOn && (Dbg_1.Dbg.trace.obsolete || ((_c = this.options.trace) === null || _c === void 0 ? void 0 : _c.obsolete)))
|
|
296
|
-
Dbg_1.Dbg.log(' ', 'x', `${this.hint()} is not obsolete due to its own change to ${Snapshot_1.Dump.
|
|
291
|
+
Dbg_1.Dbg.log(' ', 'x', `${this.hint()} is not obsolete due to its own change to ${Snapshot_1.Dump.rev2(holder, snapshot, memberName)}`);
|
|
297
292
|
}
|
|
298
293
|
}
|
|
299
294
|
runIfNotUpToDate(now, nothrow) {
|
|
@@ -423,7 +418,7 @@ class Operation extends Data_1.Observable {
|
|
|
423
418
|
OperationController.runWithin(undefined, Transaction_1.Transaction.runAs, options, Monitor_1.MonitorImpl.enter, mon, this.transaction);
|
|
424
419
|
}
|
|
425
420
|
monitorLeave(mon) {
|
|
426
|
-
Transaction_1.Transaction.
|
|
421
|
+
Transaction_1.Transaction.off(() => {
|
|
427
422
|
const leave = () => {
|
|
428
423
|
const options = {
|
|
429
424
|
hint: 'Monitor.leave',
|
|
@@ -449,25 +444,26 @@ class Operation extends Data_1.Observable {
|
|
|
449
444
|
static markUsed(observable, r, m, h, kind, weak) {
|
|
450
445
|
if (kind !== Options_1.Kind.Transaction) {
|
|
451
446
|
const op = Operation.current;
|
|
452
|
-
if (op && op.options.kind !== Options_1.Kind.Transaction &&
|
|
447
|
+
if (op && op.options.kind !== Options_1.Kind.Transaction &&
|
|
448
|
+
op.transaction === Transaction_1.Transaction.current && m !== Data_1.Meta.Holder) {
|
|
453
449
|
const ctx = Snapshot_1.Snapshot.current();
|
|
454
450
|
if (ctx !== r.snapshot)
|
|
455
451
|
ctx.bumpBy(r.snapshot.timestamp);
|
|
456
452
|
const t = weak ? -1 : ctx.timestamp;
|
|
457
453
|
if (!op.subscribeTo(observable, r, m, h, t))
|
|
458
|
-
op.markObsoleteDueTo(observable,
|
|
454
|
+
op.markObsoleteDueTo(observable, m, r.snapshot, h, INITIAL_CAUSE, ctx.timestamp, ctx.reactions);
|
|
459
455
|
}
|
|
460
456
|
}
|
|
461
457
|
}
|
|
462
458
|
static markEdited(oldValue, newValue, edited, r, m, h) {
|
|
463
459
|
edited ? r.changes.add(m) : r.changes.delete(m);
|
|
464
460
|
if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.write)
|
|
465
|
-
edited ? Dbg_1.Dbg.log('║', ' ✎', `${Snapshot_1.Dump.
|
|
461
|
+
edited ? Dbg_1.Dbg.log('║', ' ✎', `${Snapshot_1.Dump.rev2(h, r.snapshot, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`) : Dbg_1.Dbg.log('║', ' ✎', `${Snapshot_1.Dump.rev2(h, r.snapshot, m)} is changed from ${valueHint(oldValue, m)} to ${valueHint(newValue, m)}`, undefined, ' (same as previous)');
|
|
466
462
|
}
|
|
467
463
|
static isConflicting(oldValue, newValue) {
|
|
468
464
|
let result = oldValue !== newValue;
|
|
469
465
|
if (result)
|
|
470
|
-
result = oldValue instanceof Operation && oldValue.cause !==
|
|
466
|
+
result = oldValue instanceof Operation && oldValue.cause !== INITIAL_CAUSE;
|
|
471
467
|
return result;
|
|
472
468
|
}
|
|
473
469
|
static propagateAllChangesThroughSubscriptions(snapshot) {
|
|
@@ -493,26 +489,30 @@ class Operation extends Data_1.Observable {
|
|
|
493
489
|
if (reactions) {
|
|
494
490
|
const prev = r.prev.revision.data[m];
|
|
495
491
|
if (prev !== undefined && prev instanceof Data_1.Observable) {
|
|
496
|
-
const
|
|
492
|
+
const why = `T${r.snapshot.id}[${r.snapshot.hint}]`;
|
|
497
493
|
if (prev instanceof Operation) {
|
|
498
494
|
if ((prev.obsoleteSince === Snapshot_1.MAX_TIMESTAMP || prev.obsoleteSince <= 0)) {
|
|
499
|
-
prev.obsoleteDueTo =
|
|
495
|
+
prev.obsoleteDueTo = why;
|
|
500
496
|
prev.obsoleteSince = timestamp;
|
|
501
497
|
prev.unsubscribeFromAllObservables();
|
|
502
498
|
}
|
|
503
|
-
const
|
|
504
|
-
if (
|
|
505
|
-
|
|
499
|
+
const prevSuccessor = prev.successor;
|
|
500
|
+
if (prevSuccessor !== curr) {
|
|
501
|
+
if (prevSuccessor && !prevSuccessor.transaction.isFinished)
|
|
502
|
+
prevSuccessor.transaction.cancel(new Error(`T${prevSuccessor.transaction.id}[${prevSuccessor.transaction.hint}] is canceled by T${r.snapshot.id}[${r.snapshot.hint}] and will not run anymore`), null);
|
|
503
|
+
}
|
|
504
|
+
else
|
|
505
|
+
prev.successor = undefined;
|
|
506
506
|
}
|
|
507
|
-
(_a = prev.observers) === null || _a === void 0 ? void 0 : _a.forEach(c => c.markObsoleteDueTo(prev,
|
|
507
|
+
(_a = prev.observers) === null || _a === void 0 ? void 0 : _a.forEach(c => c.markObsoleteDueTo(prev, m, r.snapshot, h, why, timestamp, reactions));
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
510
|
if (curr instanceof Operation) {
|
|
511
|
-
if (curr.
|
|
511
|
+
if (curr.snapshot === r.snapshot && curr.observables !== undefined) {
|
|
512
512
|
if (Hooks_1.Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
513
513
|
curr.observables.forEach((hint, v) => {
|
|
514
514
|
if (hint.usageCount > Hooks_1.Hooks.repetitiveUsageWarningThreshold)
|
|
515
|
-
Dbg_1.Dbg.log('', '[!]', `${curr.hint()} uses ${Snapshot_1.Dump.
|
|
515
|
+
Dbg_1.Dbg.log('', '[!]', `${curr.hint()} uses ${Snapshot_1.Dump.rev2(hint.holder, hint.snapshot, hint.memberName)} ${hint.usageCount} times (consider remembering it in a local variable)`, 0, ' *** WARNING ***');
|
|
516
516
|
});
|
|
517
517
|
}
|
|
518
518
|
if (unsubscribe)
|
|
@@ -552,7 +552,7 @@ class Operation extends Data_1.Observable {
|
|
|
552
552
|
var _a;
|
|
553
553
|
value.observers.delete(this);
|
|
554
554
|
if (Dbg_1.Dbg.isOn && (Dbg_1.Dbg.trace.read || ((_a = this.options.trace) === null || _a === void 0 ? void 0 : _a.read)))
|
|
555
|
-
Dbg_1.Dbg.log(Dbg_1.Dbg.trace.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', '-', `${this.hint()} is unsubscribed from ${Snapshot_1.Dump.
|
|
555
|
+
Dbg_1.Dbg.log(Dbg_1.Dbg.trace.transaction && !Snapshot_1.Snapshot.current().sealed ? '║' : ' ', '-', `${this.hint()} is unsubscribed from ${Snapshot_1.Dump.rev2(hint.holder, hint.snapshot, hint.memberName)}`);
|
|
556
556
|
});
|
|
557
557
|
this.observables = undefined;
|
|
558
558
|
}
|
|
@@ -568,18 +568,18 @@ class Operation extends Data_1.Observable {
|
|
|
568
568
|
if (this.observables !== undefined) {
|
|
569
569
|
if (!observable.observers)
|
|
570
570
|
observable.observers = new Set();
|
|
571
|
-
const info = {
|
|
571
|
+
const info = { holder: h, snapshot: r.snapshot, memberName: m, usageCount: times };
|
|
572
572
|
observable.observers.add(this);
|
|
573
573
|
this.observables.set(observable, info);
|
|
574
574
|
if (Dbg_1.Dbg.isOn && (Dbg_1.Dbg.trace.read || ((_a = this.options.trace) === null || _a === void 0 ? void 0 : _a.read)))
|
|
575
|
-
Dbg_1.Dbg.log('║', ' ∞ ', `${this.hint()} is subscribed to ${Snapshot_1.Dump.
|
|
575
|
+
Dbg_1.Dbg.log('║', ' ∞ ', `${this.hint()} is subscribed to ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}${info.usageCount > 1 ? ` (${info.usageCount} times)` : ''}`);
|
|
576
576
|
}
|
|
577
577
|
else if (Dbg_1.Dbg.isOn && (Dbg_1.Dbg.trace.read || ((_b = this.options.trace) === null || _b === void 0 ? void 0 : _b.read)))
|
|
578
|
-
Dbg_1.Dbg.log('║', ' x ', `${this.hint()} is obsolete and is NOT subscribed to ${Snapshot_1.Dump.
|
|
578
|
+
Dbg_1.Dbg.log('║', ' x ', `${this.hint()} is obsolete and is NOT subscribed to ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}`);
|
|
579
579
|
}
|
|
580
580
|
else {
|
|
581
581
|
if (Dbg_1.Dbg.isOn && (Dbg_1.Dbg.trace.read || ((_c = this.options.trace) === null || _c === void 0 ? void 0 : _c.read)))
|
|
582
|
-
Dbg_1.Dbg.log('║', ' x ', `${this.hint()} is NOT subscribed to already obsolete ${Snapshot_1.Dump.
|
|
582
|
+
Dbg_1.Dbg.log('║', ' x ', `${this.hint()} is NOT subscribed to already obsolete ${Snapshot_1.Dump.rev2(h, r.snapshot, m)}`);
|
|
583
583
|
}
|
|
584
584
|
return ok;
|
|
585
585
|
}
|
|
@@ -602,7 +602,7 @@ class Operation extends Data_1.Observable {
|
|
|
602
602
|
let op = initial[m];
|
|
603
603
|
const ctl = op ? op.controller : new OperationController(ROOT_HOLDER, m);
|
|
604
604
|
const opts = op ? op.options : Hooks_1.OptionsImpl.INITIAL;
|
|
605
|
-
initial[m] = op = new Operation(ctl, Snapshot_1.ROOT_REV, new Hooks_1.OptionsImpl(getter, setter, opts, options, implicit));
|
|
605
|
+
initial[m] = op = new Operation(ctl, Snapshot_1.ROOT_REV.snapshot, new Hooks_1.OptionsImpl(getter, setter, opts, options, implicit));
|
|
606
606
|
if (op.options.kind === Options_1.Kind.Reaction && op.options.throttling < Number.MAX_SAFE_INTEGER) {
|
|
607
607
|
const reactions = Data_1.Meta.acquire(proto, Data_1.Meta.Reactions);
|
|
608
608
|
reactions[m] = op;
|
|
@@ -615,7 +615,6 @@ class Operation extends Data_1.Observable {
|
|
|
615
615
|
}
|
|
616
616
|
static init() {
|
|
617
617
|
Object.freeze(ROOT_ARGS);
|
|
618
|
-
Object.freeze(ROOT_TRIGGER);
|
|
619
618
|
Dbg_1.Dbg.getMergedTraceOptions = getMergedTraceOptions;
|
|
620
619
|
Snapshot_1.Snapshot.markUsed = Operation.markUsed;
|
|
621
620
|
Snapshot_1.Snapshot.markEdited = Operation.markEdited;
|
|
@@ -651,18 +650,6 @@ class Operation extends Data_1.Observable {
|
|
|
651
650
|
Operation.current = undefined;
|
|
652
651
|
Operation.queuedReactions = [];
|
|
653
652
|
Operation.deferredReactions = [];
|
|
654
|
-
function propagationHint(cause, full) {
|
|
655
|
-
const result = [];
|
|
656
|
-
let observable = cause.revision.data[cause.memberName];
|
|
657
|
-
while (observable instanceof Operation && observable.obsoleteDueTo) {
|
|
658
|
-
full && result.push(Snapshot_1.Dump.rev(cause.revision, cause.memberName));
|
|
659
|
-
cause = observable.obsoleteDueTo;
|
|
660
|
-
observable = cause.revision.data[cause.memberName];
|
|
661
|
-
}
|
|
662
|
-
result.push(Snapshot_1.Dump.rev(cause.revision, cause.memberName));
|
|
663
|
-
full && result.push(cause.revision.snapshot.hint);
|
|
664
|
-
return result;
|
|
665
|
-
}
|
|
666
653
|
function valueHint(value, m) {
|
|
667
654
|
let result = '';
|
|
668
655
|
if (Array.isArray(value))
|
|
@@ -672,7 +659,7 @@ function valueHint(value, m) {
|
|
|
672
659
|
else if (value instanceof Map)
|
|
673
660
|
result = `Map(${value.size})`;
|
|
674
661
|
else if (value instanceof Operation)
|
|
675
|
-
result = `${Snapshot_1.Dump.
|
|
662
|
+
result = `${Snapshot_1.Dump.rev2(value.controller.ownHolder, value.snapshot, m)}`;
|
|
676
663
|
else if (value === Data_1.Meta.Disposed)
|
|
677
664
|
result = '<disposed>';
|
|
678
665
|
else if (value !== undefined && value !== null)
|
|
@@ -43,14 +43,14 @@ export declare class Snapshot implements AbstractSnapshot {
|
|
|
43
43
|
applyOrDiscard(error?: any): Array<Observer>;
|
|
44
44
|
static sealObjectRevision(h: ObjectHolder, r: ObjectRevision): void;
|
|
45
45
|
static sealObservable(observable: Observable | symbol, m: MemberName, typeName: string): void;
|
|
46
|
-
collectGarbage(): void;
|
|
47
46
|
static freezeObjectRevision(r: ObjectRevision): ObjectRevision;
|
|
48
|
-
|
|
47
|
+
triggerGarbageCollection(): void;
|
|
49
48
|
private unlinkHistory;
|
|
50
49
|
static _init(): void;
|
|
51
50
|
}
|
|
52
51
|
export declare class Dump {
|
|
53
52
|
static obj(h: ObjectHolder | undefined, m?: MemberName | undefined, stamp?: number, op?: number, xop?: number, typeless?: boolean): string;
|
|
53
|
+
static rev2(h: ObjectHolder, s: AbstractSnapshot, m?: MemberName, value?: Observable): string;
|
|
54
54
|
static rev(r: ObjectRevision, m?: MemberName): string;
|
|
55
55
|
static conflicts(conflicts: ObjectRevision[]): string;
|
|
56
56
|
static conflictingMemberHint(m: MemberName, ours: ObjectRevision, theirs: ObjectRevision): string;
|
|
@@ -130,14 +130,14 @@ class Snapshot {
|
|
|
130
130
|
if (this.changeset.size > 0) {
|
|
131
131
|
this.changeset.forEach((r, h) => {
|
|
132
132
|
if (r.prev.revision !== h.head) {
|
|
133
|
-
const merged = Snapshot.merge(
|
|
133
|
+
const merged = Snapshot.merge(h, r);
|
|
134
134
|
if (r.conflicts.size > 0) {
|
|
135
135
|
if (!conflicts)
|
|
136
136
|
conflicts = [];
|
|
137
137
|
conflicts.push(r);
|
|
138
138
|
}
|
|
139
139
|
if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.transaction)
|
|
140
|
-
Dbg_1.Dbg.log('╠╝', '', `${Dump.
|
|
140
|
+
Dbg_1.Dbg.log('╠╝', '', `${Dump.rev2(h, r.snapshot)} is merged with ${Dump.rev2(h, h.head.snapshot)} among ${merged} properties with ${r.conflicts.size} conflicts.`);
|
|
141
141
|
}
|
|
142
142
|
});
|
|
143
143
|
if (this.options.token === undefined) {
|
|
@@ -154,8 +154,9 @@ class Snapshot {
|
|
|
154
154
|
}
|
|
155
155
|
return conflicts;
|
|
156
156
|
}
|
|
157
|
-
static merge(
|
|
157
|
+
static merge(h, ours) {
|
|
158
158
|
let counter = 0;
|
|
159
|
+
const head = h.head;
|
|
159
160
|
const disposed = head.changes.has(Data_1.Meta.Disposed);
|
|
160
161
|
const merged = Object.assign({}, head.data);
|
|
161
162
|
ours.changes.forEach((o, m) => {
|
|
@@ -164,7 +165,7 @@ class Snapshot {
|
|
|
164
165
|
if (disposed || m === Data_1.Meta.Disposed) {
|
|
165
166
|
if (disposed !== (m === Data_1.Meta.Disposed)) {
|
|
166
167
|
if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.change)
|
|
167
|
-
Dbg_1.Dbg.log('║╠', '', `${Dump.
|
|
168
|
+
Dbg_1.Dbg.log('║╠', '', `${Dump.rev2(h, ours.snapshot, m)} <> ${Dump.rev2(h, head.snapshot, m)}`, 0, ' *** CONFLICT ***');
|
|
168
169
|
ours.conflicts.set(m, head);
|
|
169
170
|
}
|
|
170
171
|
}
|
|
@@ -173,7 +174,7 @@ class Snapshot {
|
|
|
173
174
|
if (conflict)
|
|
174
175
|
ours.conflicts.set(m, head);
|
|
175
176
|
if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.change)
|
|
176
|
-
Dbg_1.Dbg.log('║╠', '', `${Dump.
|
|
177
|
+
Dbg_1.Dbg.log('║╠', '', `${Dump.rev2(h, ours.snapshot, m)} ${conflict ? '<>' : '=='} ${Dump.rev2(h, head.snapshot, m)}`, 0, conflict ? ' *** CONFLICT ***' : undefined);
|
|
177
178
|
}
|
|
178
179
|
});
|
|
179
180
|
Utils_1.Utils.copyAllMembers(merged, ours.data);
|
|
@@ -202,7 +203,7 @@ class Snapshot {
|
|
|
202
203
|
const members = [];
|
|
203
204
|
r.changes.forEach((o, m) => members.push(m.toString()));
|
|
204
205
|
const s = members.join(', ');
|
|
205
|
-
Dbg_1.Dbg.log('║', '√', `${Dump.
|
|
206
|
+
Dbg_1.Dbg.log('║', '√', `${Dump.rev2(h, r.snapshot)} (${s}) is ${r.prev.revision === exports.ROOT_REV ? 'constructed' : `applied on top of ${Dump.rev2(h, r.prev.revision.snapshot)}`}`);
|
|
206
207
|
});
|
|
207
208
|
}
|
|
208
209
|
if (Dbg_1.Dbg.trace.transaction)
|
|
@@ -231,16 +232,6 @@ class Snapshot {
|
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
234
|
}
|
|
234
|
-
collectGarbage() {
|
|
235
|
-
this.changeset = EMPTY_MAP;
|
|
236
|
-
this.reactions = EMPTY_ARRAY;
|
|
237
|
-
if (Dbg_1.Dbg.isOn) {
|
|
238
|
-
Utils_1.Utils.freezeMap(this.changeset);
|
|
239
|
-
Object.freeze(this.reactions);
|
|
240
|
-
Object.freeze(this);
|
|
241
|
-
}
|
|
242
|
-
this.triggerGarbageCollection();
|
|
243
|
-
}
|
|
244
235
|
static freezeObjectRevision(r) {
|
|
245
236
|
Object.freeze(r.data);
|
|
246
237
|
Utils_1.Utils.freezeSet(r.changes);
|
|
@@ -272,7 +263,7 @@ class Snapshot {
|
|
|
272
263
|
Dbg_1.Dbg.log('', '[G]', `Dismiss history below v${this.stamp}t${this.id} (${this.hint})`);
|
|
273
264
|
this.changeset.forEach((r, h) => {
|
|
274
265
|
if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.gc && r.prev.revision !== exports.ROOT_REV)
|
|
275
|
-
Dbg_1.Dbg.log(' ', ' ', `${Dump.
|
|
266
|
+
Dbg_1.Dbg.log(' ', ' ', `${Dump.rev2(h, r.prev.revision.snapshot)} is ready for GC because overwritten by ${Dump.rev2(h, r.snapshot)}`);
|
|
276
267
|
if (Snapshot.garbageCollectionSummaryInterval < Number.MAX_SAFE_INTEGER) {
|
|
277
268
|
if (r.prev.revision !== exports.ROOT_REV)
|
|
278
269
|
Snapshot.totalObjectRevisionCount--;
|
|
@@ -281,12 +272,16 @@ class Snapshot {
|
|
|
281
272
|
}
|
|
282
273
|
r.prev.revision = exports.ROOT_REV;
|
|
283
274
|
});
|
|
275
|
+
this.changeset = EMPTY_MAP;
|
|
276
|
+
this.reactions = EMPTY_ARRAY;
|
|
277
|
+
if (Dbg_1.Dbg.isOn)
|
|
278
|
+
Object.freeze(this);
|
|
284
279
|
}
|
|
285
280
|
static _init() {
|
|
286
281
|
const root = exports.ROOT_REV.snapshot;
|
|
287
282
|
root.acquire(root);
|
|
288
283
|
root.applyOrDiscard();
|
|
289
|
-
root.
|
|
284
|
+
root.triggerGarbageCollection();
|
|
290
285
|
Snapshot.freezeObjectRevision(exports.ROOT_REV);
|
|
291
286
|
Snapshot.idGen = 100;
|
|
292
287
|
Snapshot.stampGen = 101;
|
|
@@ -320,6 +315,9 @@ class Dump {
|
|
|
320
315
|
? `root${member}`
|
|
321
316
|
: stamp === undefined ? `${h.hint}${member} #${h.id}` : `${h.hint}${member} #${h.id}t${op}v${stamp}${xop !== undefined && xop !== 0 ? `t${xop}` : ''}`;
|
|
322
317
|
}
|
|
318
|
+
static rev2(h, s, m, value) {
|
|
319
|
+
return Dump.obj(h, m, s.timestamp, s.id, value === null || value === void 0 ? void 0 : value.selfSnapshotId);
|
|
320
|
+
}
|
|
323
321
|
static rev(r, m) {
|
|
324
322
|
const h = Data_1.Meta.get(r.data, Data_1.Meta.Holder);
|
|
325
323
|
const value = m !== undefined ? r.data[m] : undefined;
|
|
@@ -23,7 +23,7 @@ export declare abstract class Transaction implements Worker {
|
|
|
23
23
|
static create(options: SnapshotOptions | null): Transaction;
|
|
24
24
|
static run<T>(func: F<T>, ...args: any[]): T;
|
|
25
25
|
static runAs<T>(options: SnapshotOptions | null, func: F<T>, ...args: any[]): T;
|
|
26
|
-
static
|
|
26
|
+
static off<T>(func: F<T>, ...args: any[]): T;
|
|
27
27
|
static isFrameOver(everyN?: number, timeLimit?: number): boolean;
|
|
28
28
|
static requestNextFrame(sleepTime?: number): Promise<void>;
|
|
29
29
|
static get isCanceled(): boolean;
|
|
@@ -21,7 +21,7 @@ class Transaction {
|
|
|
21
21
|
static create(options) { return new TransactionImpl(options); }
|
|
22
22
|
static run(func, ...args) { return TransactionImpl.run(func, ...args); }
|
|
23
23
|
static runAs(options, func, ...args) { return TransactionImpl.runAs(options, func, ...args); }
|
|
24
|
-
static
|
|
24
|
+
static off(func, ...args) { return TransactionImpl.off(func, ...args); }
|
|
25
25
|
static isFrameOver(everyN = 1, timeLimit = 14) { return TransactionImpl.isFrameOver(everyN, timeLimit); }
|
|
26
26
|
static requestNextFrame(sleepTime = 0) { return TransactionImpl.requestNextFrame(sleepTime); }
|
|
27
27
|
static get isCanceled() { return TransactionImpl.current.isCanceled; }
|
|
@@ -125,7 +125,7 @@ class TransactionImpl extends Transaction {
|
|
|
125
125
|
let result = t.runImpl(options === null || options === void 0 ? void 0 : options.trace, func, ...args);
|
|
126
126
|
if (root) {
|
|
127
127
|
if (result instanceof Promise) {
|
|
128
|
-
result = TransactionImpl.
|
|
128
|
+
result = TransactionImpl.off(() => {
|
|
129
129
|
return t.wrapToRetry(t.wrapToWaitUntilFinish(result), func, ...args);
|
|
130
130
|
});
|
|
131
131
|
}
|
|
@@ -133,7 +133,7 @@ class TransactionImpl extends Transaction {
|
|
|
133
133
|
}
|
|
134
134
|
return result;
|
|
135
135
|
}
|
|
136
|
-
static
|
|
136
|
+
static off(func, ...args) {
|
|
137
137
|
const outer = TransactionImpl.curr;
|
|
138
138
|
try {
|
|
139
139
|
TransactionImpl.curr = TransactionImpl.none;
|
|
@@ -230,7 +230,7 @@ class TransactionImpl extends Transaction {
|
|
|
230
230
|
if (this.sealed && this.pending === 0) {
|
|
231
231
|
const reactions = this.applyOrDiscard();
|
|
232
232
|
TransactionImpl.curr = outer;
|
|
233
|
-
TransactionImpl.
|
|
233
|
+
TransactionImpl.off(Snapshot_1.Snapshot.enqueueReactionsToRun, reactions);
|
|
234
234
|
}
|
|
235
235
|
else
|
|
236
236
|
TransactionImpl.curr = outer;
|
|
@@ -264,7 +264,7 @@ class TransactionImpl extends Transaction {
|
|
|
264
264
|
if (Dbg_1.Dbg.isOn && Dbg_1.Dbg.trace.change)
|
|
265
265
|
Dbg_1.Dbg.log('╠═', '', '', undefined, 'changes');
|
|
266
266
|
reactions = this.snapshot.applyOrDiscard(this.canceled);
|
|
267
|
-
this.snapshot.
|
|
267
|
+
this.snapshot.triggerGarbageCollection();
|
|
268
268
|
if (this.promise) {
|
|
269
269
|
if (this.canceled && !this.after)
|
|
270
270
|
this.reject(this.canceled);
|