reactronic 0.92.25004 → 0.92.25005
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 +24 -24
- package/build/dist/source/Clock.js +3 -3
- package/build/dist/source/ReactiveSystem.d.ts +5 -3
- package/build/dist/source/ReactiveSystem.js +20 -2
- package/build/dist/source/Ref.js +2 -2
- package/build/dist/source/api.d.ts +1 -1
- package/build/dist/source/api.js +1 -1
- package/build/dist/source/core/Operation.js +2 -2
- package/build/dist/source/core/ReactiveNode.js +3 -3
- package/build/dist/source/core/Transaction.d.ts +5 -5
- package/build/dist/source/core/Transaction.js +21 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,11 +24,11 @@ Transactional reactivity is based on four fundamental concepts:
|
|
|
24
24
|
|
|
25
25
|
- **Observable Objects** - a set of objects that store data of an
|
|
26
26
|
application (state);
|
|
27
|
-
- **
|
|
27
|
+
- **Atomic Action** - a function that makes changes in observable
|
|
28
28
|
objects in atomic way ("all or nothing");
|
|
29
|
-
- **Reaction
|
|
29
|
+
- **Reaction** - a function that is executed automatically in
|
|
30
30
|
response to changes made by a transaction;
|
|
31
|
-
- **Cache
|
|
31
|
+
- **Cache** - a function which result is remembered and, if the becomes
|
|
32
32
|
obsolete, recomputed on-demand.
|
|
33
33
|
|
|
34
34
|
Demo application built with Reactronic: https://nevod.io/#/playground.
|
|
@@ -45,7 +45,7 @@ class Demo extends ObservableObject {
|
|
|
45
45
|
name: string = 'Nezaboodka Software'
|
|
46
46
|
email: string = 'contact@nezaboodka.com'
|
|
47
47
|
|
|
48
|
-
@
|
|
48
|
+
@atomicAction
|
|
49
49
|
saveContact(name: string, email: string): void {
|
|
50
50
|
this.name = name
|
|
51
51
|
this.email = email
|
|
@@ -64,10 +64,10 @@ class Demo extends ObservableObject {
|
|
|
64
64
|
In the example above, `Demo` is an observable object,
|
|
65
65
|
meaning that access to its fields are seamlessly tracked
|
|
66
66
|
to determine dependent reactions and caches. Reaction
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
response to changes of these fields made by the
|
|
70
|
-
|
|
67
|
+
`printContact` reads `name` and `email` fields, thus
|
|
68
|
+
depends on them. It is executed automatically in
|
|
69
|
+
response to changes of these fields made by the atomic
|
|
70
|
+
action `saveContact`.
|
|
71
71
|
|
|
72
72
|
Here is an example of a cached value (re-)computed on-demand:
|
|
73
73
|
|
|
@@ -115,19 +115,19 @@ In the example above, the class `MyModel` is based on Reactronic's
|
|
|
115
115
|
`ObservableObject` class and all its properties `url`, `content`,
|
|
116
116
|
and `timestamp` are hooked.
|
|
117
117
|
|
|
118
|
-
##
|
|
118
|
+
## Atomic Action
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
Atomic action makes changes in observable objects
|
|
121
121
|
in transactional (atomic) way, thus provoking execution
|
|
122
122
|
of dependent reactions and recalculation of dependent
|
|
123
|
-
caches.
|
|
124
|
-
provide transparent atomicity (by implicit
|
|
125
|
-
switching and isolation).
|
|
123
|
+
caches. Atomic action function is instrumented with
|
|
124
|
+
hooks to provide transparent atomicity (by implicit
|
|
125
|
+
context switching and isolation).
|
|
126
126
|
|
|
127
127
|
``` typescript
|
|
128
128
|
class MyModel extends ObservableObject {
|
|
129
129
|
// ...
|
|
130
|
-
@
|
|
130
|
+
@atomicAction
|
|
131
131
|
async load(url: string): Promise<void> {
|
|
132
132
|
this.url = url
|
|
133
133
|
this.content = await fetch(url)
|
|
@@ -136,11 +136,11 @@ class MyModel extends ObservableObject {
|
|
|
136
136
|
}
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
-
In the example above, the
|
|
139
|
+
In the example above, the atomic action `load` makes
|
|
140
140
|
changes to `url`, `content` and `timestamp` properties. While
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
of the
|
|
141
|
+
atomic action is running, the changes are visible only inside the
|
|
142
|
+
action itself. The new values become atomically visible outside
|
|
143
|
+
of the action only upon its completion.
|
|
144
144
|
|
|
145
145
|
Atomicity is achieved by making changes in an isolated data
|
|
146
146
|
snapshot that is not visible outside of the running transaction
|
|
@@ -168,9 +168,9 @@ of asynchronous operations is fully completed.
|
|
|
168
168
|
## Reaction & Cache
|
|
169
169
|
|
|
170
170
|
Reaction function is automatically and immediately called in
|
|
171
|
-
response to changes in observable objects made by an
|
|
171
|
+
response to changes in observable objects made by an atomic action.
|
|
172
172
|
Cache function is called on-demand to renew the value if it was
|
|
173
|
-
marked as obsolete due to changes made by an
|
|
173
|
+
marked as obsolete due to changes made by an atomic action.
|
|
174
174
|
Reaction and cache functions are instrumented with hooks
|
|
175
175
|
to seamlessly subscribe to those observable objects and
|
|
176
176
|
other cache functions (dependencies), which are used
|
|
@@ -212,7 +212,7 @@ class Component<P> extends React.Component<P> {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
componentWillUnmount(): void {
|
|
215
|
-
|
|
215
|
+
atomicAction(RxSystem.dispose, this)
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
```
|
|
@@ -256,8 +256,8 @@ of recurring changes:
|
|
|
256
256
|
- `0` - execute immediately via event loop (asynchronously with zero timeout);
|
|
257
257
|
- `>= Number.MAX_SAFE_INTEGER` - never execute (suspended reaction).
|
|
258
258
|
|
|
259
|
-
**Reentrance** option defines how to handle reentrant calls of
|
|
260
|
-
and
|
|
259
|
+
**Reentrance** option defines how to handle reentrant calls of atomic
|
|
260
|
+
actions and reactions:
|
|
261
261
|
|
|
262
262
|
- `preventWithError` - fail with error if there is an existing call in progress;
|
|
263
263
|
- `waitAndRestart` - wait for previous call to finish and then restart current one;
|
|
@@ -305,7 +305,7 @@ class ObservableObject { }
|
|
|
305
305
|
|
|
306
306
|
function observable(proto, prop) // field only
|
|
307
307
|
function unobservable(proto, prop) // field only
|
|
308
|
-
function
|
|
308
|
+
function atomicAction(proto, prop, pd) // method only
|
|
309
309
|
function reaction(proto, prop, pd) // method only
|
|
310
310
|
function cache(proto, prop, pd) // method only
|
|
311
311
|
function options(value: Partial<MemberOptions>): F<any>
|
|
@@ -8,7 +8,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
10
|
import { ObservableObject } from "./core/Mvcc.js";
|
|
11
|
-
import {
|
|
11
|
+
import { atomicAction } from "./ReactiveSystem.js";
|
|
12
12
|
export class Clock extends ObservableObject {
|
|
13
13
|
constructor(interval = 1000) {
|
|
14
14
|
super();
|
|
@@ -40,13 +40,13 @@ export class Clock extends ObservableObject {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
__decorate([
|
|
43
|
-
|
|
43
|
+
atomicAction,
|
|
44
44
|
__metadata("design:type", Function),
|
|
45
45
|
__metadata("design:paramtypes", [Boolean]),
|
|
46
46
|
__metadata("design:returntype", void 0)
|
|
47
47
|
], Clock.prototype, "pause", null);
|
|
48
48
|
__decorate([
|
|
49
|
-
|
|
49
|
+
atomicAction,
|
|
50
50
|
__metadata("design:type", Function),
|
|
51
51
|
__metadata("design:paramtypes", []),
|
|
52
52
|
__metadata("design:returntype", void 0)
|
|
@@ -18,11 +18,13 @@ export declare class ReactiveSystem {
|
|
|
18
18
|
static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void;
|
|
19
19
|
}
|
|
20
20
|
export declare function nonreactive<T>(func: F<T>, ...args: any[]): T;
|
|
21
|
+
export declare function nonreactive2<T>(options: SnapshotOptions, func: F<T>, ...args: any[]): T;
|
|
22
|
+
export declare function nonreactive2<T>(func: F<T>, ...args: any[]): T;
|
|
21
23
|
export declare function sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
|
|
22
24
|
export declare function contextually<T>(p: Promise<T>): Promise<T>;
|
|
23
|
-
export declare function
|
|
24
|
-
export declare function
|
|
25
|
-
export declare function
|
|
25
|
+
export declare function atomicAction<T>(func: F<T>, ...args: any[]): T;
|
|
26
|
+
export declare function atomicAction<T>(options: SnapshotOptions, func: F<T>, ...args: any[]): T;
|
|
27
|
+
export declare function atomicAction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
|
|
26
28
|
export declare function unobservable(proto: object, prop: PropertyKey): any;
|
|
27
29
|
export declare function observable(proto: object, prop: PropertyKey): any;
|
|
28
30
|
export declare function reaction(proto: object, prop: PropertyKey, pd: PropertyDescriptor): any;
|
|
@@ -25,13 +25,31 @@ export class ReactiveSystem {
|
|
|
25
25
|
export function nonreactive(func, ...args) {
|
|
26
26
|
return OperationImpl.proceedWithinGivenLaunch(undefined, func, ...args);
|
|
27
27
|
}
|
|
28
|
+
export function nonreactive2(p1, p2, p3) {
|
|
29
|
+
if (p1 instanceof Function) {
|
|
30
|
+
return OperationImpl.proceedWithinGivenLaunch(undefined, () => {
|
|
31
|
+
if (p2 !== undefined)
|
|
32
|
+
return Transaction.run(null, p1, ...p2);
|
|
33
|
+
else
|
|
34
|
+
return Transaction.run(null, p1);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
return OperationImpl.proceedWithinGivenLaunch(undefined, () => {
|
|
39
|
+
if (p3 !== undefined)
|
|
40
|
+
return Transaction.run(p1, p2, ...p3);
|
|
41
|
+
else
|
|
42
|
+
return Transaction.run(p1, p2);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
28
46
|
export function sensitive(sensitivity, func, ...args) {
|
|
29
47
|
return Mvcc.sensitive(sensitivity, func, ...args);
|
|
30
48
|
}
|
|
31
49
|
export function contextually(p) {
|
|
32
50
|
throw new Error("not implemented yet");
|
|
33
51
|
}
|
|
34
|
-
export function
|
|
52
|
+
export function atomicAction(p1, p2, p3) {
|
|
35
53
|
if (p1 instanceof Function) {
|
|
36
54
|
if (p2 !== undefined)
|
|
37
55
|
return Transaction.run(null, p1, ...p2);
|
|
@@ -49,7 +67,7 @@ export function apply(p1, p2, p3) {
|
|
|
49
67
|
kind: Kind.apply,
|
|
50
68
|
isolation: Isolation.joinToCurrentTransaction,
|
|
51
69
|
};
|
|
52
|
-
return Mvcc.decorateOperation(true,
|
|
70
|
+
return Mvcc.decorateOperation(true, atomicAction, opts, p1, p2, p3);
|
|
53
71
|
}
|
|
54
72
|
}
|
|
55
73
|
export function unobservable(proto, prop) {
|
package/build/dist/source/Ref.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { atomicAction, nonreactive } from "./ReactiveSystem.js";
|
|
2
2
|
export function refs(owner) {
|
|
3
3
|
return new Proxy(owner, RefGettingProxy);
|
|
4
4
|
}
|
|
@@ -52,7 +52,7 @@ export class ToggleRef extends Ref {
|
|
|
52
52
|
toggle() {
|
|
53
53
|
const o = this.owner;
|
|
54
54
|
const p = this.name;
|
|
55
|
-
|
|
55
|
+
atomicAction({ hint: `toggle ${o.constructor.name}.${p}` }, () => {
|
|
56
56
|
const v = o[p];
|
|
57
57
|
const isOn = v === this.valueOn || (v instanceof Ref && this.valueOn instanceof Ref &&
|
|
58
58
|
Ref.sameRefs(v, this.valueOn));
|
|
@@ -16,7 +16,7 @@ export { Changeset } from "./core/Changeset.js";
|
|
|
16
16
|
export { Transaction } from "./core/Transaction.js";
|
|
17
17
|
export { Indicator } from "./core/Indicator.js";
|
|
18
18
|
export { Journal } from "./core/Journal.js";
|
|
19
|
-
export { ReactiveSystem, observable, unobservable,
|
|
19
|
+
export { ReactiveSystem, observable, unobservable, atomicAction, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
|
|
20
20
|
export { Reaction } from "./Reaction.js";
|
|
21
21
|
export { ReactiveNode, Mode, Priority, BaseDriver, ReactiveNodeVariable } from "./core/ReactiveNode.js";
|
|
22
22
|
export type { Script, ScriptAsync, Handler, ReactiveNodeDecl, ReactiveNodeDriver, ReactiveNodeContext } from "./core/ReactiveNode.js";
|
package/build/dist/source/api.js
CHANGED
|
@@ -12,7 +12,7 @@ export { Changeset } from "./core/Changeset.js";
|
|
|
12
12
|
export { Transaction } from "./core/Transaction.js";
|
|
13
13
|
export { Indicator } from "./core/Indicator.js";
|
|
14
14
|
export { Journal } from "./core/Journal.js";
|
|
15
|
-
export { ReactiveSystem, observable, unobservable,
|
|
15
|
+
export { ReactiveSystem, observable, unobservable, atomicAction, reaction, cache, nonreactive, sensitive, contextually, options } from "./ReactiveSystem.js";
|
|
16
16
|
export { Reaction } from "./Reaction.js";
|
|
17
17
|
export { ReactiveNode, Mode, Priority, BaseDriver, ReactiveNodeVariable } from "./core/ReactiveNode.js";
|
|
18
18
|
export { Clock } from "./Clock.js";
|
|
@@ -744,8 +744,8 @@ function reactronicHookedThen(resolve, reject) {
|
|
|
744
744
|
resolve = launch.wrap(resolve);
|
|
745
745
|
reject = launch.wrap(reject);
|
|
746
746
|
}
|
|
747
|
-
resolve = tran.
|
|
748
|
-
reject = tran.
|
|
747
|
+
resolve = tran.wrapAsPending(resolve, false);
|
|
748
|
+
reject = tran.wrapAsPending(reject, true);
|
|
749
749
|
}
|
|
750
750
|
return ORIGINAL_PROMISE_THEN.call(this, resolve, reject);
|
|
751
751
|
}
|
|
@@ -22,7 +22,7 @@ import { emitLetters, getCallerInfo, proceedSyncOrAsync } from "../util/Utils.js
|
|
|
22
22
|
import { Isolation, Reentrance } from "../Options.js";
|
|
23
23
|
import { ObservableObject } from "../core/Mvcc.js";
|
|
24
24
|
import { Transaction } from "../core/Transaction.js";
|
|
25
|
-
import { ReactiveSystem, options, unobservable, reaction, nonreactive,
|
|
25
|
+
import { ReactiveSystem, options, unobservable, reaction, nonreactive, atomicAction } from "../ReactiveSystem.js";
|
|
26
26
|
export var Mode;
|
|
27
27
|
(function (Mode) {
|
|
28
28
|
Mode[Mode["default"] = 0] = "default";
|
|
@@ -339,7 +339,7 @@ class ReactiveNodeImpl extends ReactiveNode {
|
|
|
339
339
|
node.outer = owner;
|
|
340
340
|
else
|
|
341
341
|
node.outer = owner.outer;
|
|
342
|
-
|
|
342
|
+
atomicAction({ isolation: Isolation.joinAsNestedTransaction }, () => {
|
|
343
343
|
const ctx = node.context;
|
|
344
344
|
if (ctx) {
|
|
345
345
|
ctx.variable = variable;
|
|
@@ -546,7 +546,7 @@ function triggerFinalization(slot, isLeader, individual) {
|
|
|
546
546
|
else
|
|
547
547
|
gFirstToDispose = gLastToDispose = slot;
|
|
548
548
|
if (gFirstToDispose === slot)
|
|
549
|
-
|
|
549
|
+
atomicAction({ isolation: Isolation.disjoinForInternalDisposal, hint: `runDisposalLoop(initiator=${slot.instance.key})` }, () => {
|
|
550
550
|
void runDisposalLoop().then(NOP, error => console.log(error));
|
|
551
551
|
});
|
|
552
552
|
}
|
|
@@ -17,7 +17,7 @@ export declare abstract class Transaction implements Worker {
|
|
|
17
17
|
abstract inspect<T>(func: F<T>, ...args: any[]): T;
|
|
18
18
|
abstract apply(): void;
|
|
19
19
|
abstract seal(): this;
|
|
20
|
-
abstract
|
|
20
|
+
abstract wrapAsPending<T>(func: F<T>, secondary: boolean): F<T>;
|
|
21
21
|
abstract cancel(error: Error, retryAfterOrIgnore?: Worker | null): this;
|
|
22
22
|
abstract readonly isCanceled: boolean;
|
|
23
23
|
abstract readonly isFinished: boolean;
|
|
@@ -33,7 +33,7 @@ export declare abstract class Transaction implements Worker {
|
|
|
33
33
|
export declare class TransactionImpl extends Transaction {
|
|
34
34
|
private static readonly none;
|
|
35
35
|
private static curr;
|
|
36
|
-
private static
|
|
36
|
+
private static isInspectionMode;
|
|
37
37
|
private static frameStartTime;
|
|
38
38
|
private static frameOverCounter;
|
|
39
39
|
readonly margin: number;
|
|
@@ -57,9 +57,9 @@ export declare class TransactionImpl extends Transaction {
|
|
|
57
57
|
inspect<T>(func: F<T>, ...args: any[]): T;
|
|
58
58
|
apply(): void;
|
|
59
59
|
seal(): this;
|
|
60
|
-
|
|
61
|
-
private static
|
|
62
|
-
private static
|
|
60
|
+
wrapAsPending<T>(func: F<T>, secondary: boolean): F<T>;
|
|
61
|
+
private static preparePendingFunction;
|
|
62
|
+
private static runPendingFunction;
|
|
63
63
|
cancel(error: Error, restartAfter?: Worker | null): this;
|
|
64
64
|
get isCanceled(): boolean;
|
|
65
65
|
get isFinished(): boolean;
|
|
@@ -50,15 +50,15 @@ export class TransactionImpl extends Transaction {
|
|
|
50
50
|
return this.runImpl(undefined, func, ...args);
|
|
51
51
|
}
|
|
52
52
|
inspect(func, ...args) {
|
|
53
|
-
const
|
|
53
|
+
const outer = TransactionImpl.isInspectionMode;
|
|
54
54
|
try {
|
|
55
|
-
TransactionImpl.
|
|
55
|
+
TransactionImpl.isInspectionMode = true;
|
|
56
56
|
if (Log.isOn && Log.opt.transaction)
|
|
57
57
|
Log.write(" ", " ", `T${this.id}[${this.hint}] is being inspected by T${TransactionImpl.curr.id}[${TransactionImpl.curr.hint}]`);
|
|
58
58
|
return this.runImpl(undefined, func, ...args);
|
|
59
59
|
}
|
|
60
60
|
finally {
|
|
61
|
-
TransactionImpl.
|
|
61
|
+
TransactionImpl.isInspectionMode = outer;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
apply() {
|
|
@@ -73,27 +73,27 @@ export class TransactionImpl extends Transaction {
|
|
|
73
73
|
this.run(TransactionImpl.seal, this, undefined, undefined);
|
|
74
74
|
return this;
|
|
75
75
|
}
|
|
76
|
-
|
|
76
|
+
wrapAsPending(func, secondary) {
|
|
77
77
|
this.guard();
|
|
78
78
|
const self = this;
|
|
79
|
-
const
|
|
80
|
-
if (!
|
|
81
|
-
self.run(TransactionImpl.
|
|
79
|
+
const inspection = TransactionImpl.isInspectionMode;
|
|
80
|
+
if (!inspection)
|
|
81
|
+
self.run(TransactionImpl.preparePendingFunction, self, secondary);
|
|
82
82
|
else
|
|
83
|
-
self.inspect(TransactionImpl.
|
|
84
|
-
const
|
|
85
|
-
if (!
|
|
86
|
-
return self.runImpl(undefined, TransactionImpl.
|
|
83
|
+
self.inspect(TransactionImpl.preparePendingFunction, self, secondary);
|
|
84
|
+
const wrappedAsPendingForTransaction = (...args) => {
|
|
85
|
+
if (!inspection)
|
|
86
|
+
return self.runImpl(undefined, TransactionImpl.runPendingFunction, self, secondary, func, ...args);
|
|
87
87
|
else
|
|
88
|
-
return self.inspect(TransactionImpl.
|
|
88
|
+
return self.inspect(TransactionImpl.runPendingFunction, self, secondary, func, ...args);
|
|
89
89
|
};
|
|
90
|
-
return
|
|
90
|
+
return wrappedAsPendingForTransaction;
|
|
91
91
|
}
|
|
92
|
-
static
|
|
93
|
-
if (!
|
|
92
|
+
static preparePendingFunction(t, secondary) {
|
|
93
|
+
if (!secondary)
|
|
94
94
|
t.pending++;
|
|
95
95
|
}
|
|
96
|
-
static
|
|
96
|
+
static runPendingFunction(t, secondary, func, ...args) {
|
|
97
97
|
t.pending--;
|
|
98
98
|
const result = func(...args);
|
|
99
99
|
return result;
|
|
@@ -118,10 +118,10 @@ export class TransactionImpl extends Transaction {
|
|
|
118
118
|
}
|
|
119
119
|
static run(options, func, ...args) {
|
|
120
120
|
const t = TransactionImpl.acquire(options);
|
|
121
|
-
const
|
|
121
|
+
const isRoot = t !== TransactionImpl.curr;
|
|
122
122
|
t.guard();
|
|
123
123
|
let result = t.runImpl(options === null || options === void 0 ? void 0 : options.logging, func, ...args);
|
|
124
|
-
if (
|
|
124
|
+
if (isRoot) {
|
|
125
125
|
if (result instanceof Promise) {
|
|
126
126
|
result = TransactionImpl.outside(() => {
|
|
127
127
|
return t.wrapToRetry(t.wrapToWaitUntilFinish(result), func, ...args);
|
|
@@ -231,7 +231,7 @@ export class TransactionImpl extends Transaction {
|
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
catch (e) {
|
|
234
|
-
if (!TransactionImpl.
|
|
234
|
+
if (!TransactionImpl.isInspectionMode)
|
|
235
235
|
this.cancel(e);
|
|
236
236
|
throw e;
|
|
237
237
|
}
|
|
@@ -460,7 +460,7 @@ export class TransactionImpl extends Transaction {
|
|
|
460
460
|
return TransactionImpl.curr.changeset;
|
|
461
461
|
}
|
|
462
462
|
static getEditableChangeset() {
|
|
463
|
-
if (TransactionImpl.
|
|
463
|
+
if (TransactionImpl.isInspectionMode)
|
|
464
464
|
throw misuse("cannot make changes during transaction inspection");
|
|
465
465
|
return TransactionImpl.curr.changeset;
|
|
466
466
|
}
|
|
@@ -474,7 +474,7 @@ export class TransactionImpl extends Transaction {
|
|
|
474
474
|
}
|
|
475
475
|
TransactionImpl.none = new TransactionImpl({ hint: "<none>" });
|
|
476
476
|
TransactionImpl.curr = TransactionImpl.none;
|
|
477
|
-
TransactionImpl.
|
|
477
|
+
TransactionImpl.isInspectionMode = false;
|
|
478
478
|
TransactionImpl.frameStartTime = 0;
|
|
479
479
|
TransactionImpl.frameOverCounter = 0;
|
|
480
480
|
TransactionImpl.migrateFieldVersion = function (fv, target) {
|