reactronic 0.93.25026 → 0.94.25027
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 +32 -32
- package/build/dist/source/Enums.d.ts +32 -0
- package/build/dist/source/Enums.js +37 -0
- package/build/dist/source/OperationEx.d.ts +7 -0
- package/build/dist/source/{ReactiveLoop.js → OperationEx.js} +8 -8
- package/build/dist/source/Options.d.ts +7 -27
- package/build/dist/source/Options.js +0 -24
- package/build/dist/source/Pipe.d.ts +2 -2
- package/build/dist/source/Pipe.js +2 -2
- package/build/dist/source/Ref.js +1 -1
- package/build/dist/source/{ReactiveSystem.d.ts → System.d.ts} +9 -10
- package/build/dist/source/{ReactiveSystem.js → System.js} +20 -15
- package/build/dist/source/api.d.ts +12 -10
- package/build/dist/source/api.js +10 -8
- package/build/dist/source/core/Changeset.d.ts +8 -7
- package/build/dist/source/core/Changeset.js +18 -18
- package/build/dist/source/core/Data.d.ts +6 -6
- package/build/dist/source/core/Data.js +2 -2
- package/build/dist/source/core/Indicator.d.ts +2 -2
- package/build/dist/source/core/Indicator.js +3 -3
- package/build/dist/source/core/Journal.d.ts +2 -2
- package/build/dist/source/core/Journal.js +7 -7
- package/build/dist/source/core/Meta.d.ts +1 -1
- package/build/dist/source/core/Meta.js +1 -1
- package/build/dist/source/core/Mvcc.d.ts +17 -16
- package/build/dist/source/core/Mvcc.js +30 -30
- package/build/dist/source/core/MvccArray.d.ts +3 -3
- package/build/dist/source/core/MvccArray.js +4 -4
- package/build/dist/source/core/MvccMap.d.ts +3 -3
- package/build/dist/source/core/MvccMap.js +4 -4
- package/build/dist/source/core/MvccMergeList.d.ts +2 -2
- package/build/dist/source/core/MvccMergeList.js +2 -2
- package/build/dist/source/core/Operation.d.ts +25 -25
- package/build/dist/source/core/Operation.js +205 -205
- package/build/dist/source/core/Transaction.d.ts +3 -3
- package/build/dist/source/core/Transaction.js +72 -72
- package/build/dist/source/core/Tree.d.ts +26 -0
- package/build/dist/source/core/Tree.js +120 -0
- package/build/dist/source/core/TreeNode.d.ts +117 -0
- package/build/dist/source/core/{ReactiveNode.js → TreeNode.js} +49 -177
- package/package.json +1 -1
- package/build/dist/source/ReactiveLoop.d.ts +0 -7
- package/build/dist/source/core/ReactiveNode.d.ts +0 -107
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Log, misuse } from "../util/Dbg.js";
|
|
2
|
-
import { Kind, Reentrance, Isolation } from "../
|
|
3
|
-
import { ObjectHandle,
|
|
2
|
+
import { Kind, Reentrance, Isolation } from "../Enums.js";
|
|
3
|
+
import { ObjectHandle, ContentFootprint, Meta } from "./Data.js";
|
|
4
4
|
import { Changeset, Dump, EMPTY_OBJECT_VERSION, MAX_REVISION } from "./Changeset.js";
|
|
5
5
|
import { Transaction, TransactionImpl } from "./Transaction.js";
|
|
6
6
|
import { IndicatorImpl } from "./Indicator.js";
|
|
@@ -8,17 +8,17 @@ import { Mvcc, OptionsImpl } from "./Mvcc.js";
|
|
|
8
8
|
import { JournalImpl } from "./Journal.js";
|
|
9
9
|
const BOOT_ARGS = [];
|
|
10
10
|
const BOOT_CAUSE = "<boot>";
|
|
11
|
-
const EMPTY_HANDLE = new ObjectHandle(undefined, undefined, Mvcc.
|
|
12
|
-
export class
|
|
13
|
-
configure(options) { return
|
|
14
|
-
get options() { return this.peek(undefined).
|
|
15
|
-
get nonreactive() { return this.peek(undefined).
|
|
16
|
-
get args() { return this.use().
|
|
11
|
+
const EMPTY_HANDLE = new ObjectHandle(undefined, undefined, Mvcc.observable, EMPTY_OBJECT_VERSION, "<boot>");
|
|
12
|
+
export class ReactiveOperationImpl {
|
|
13
|
+
configure(options) { return ReactiveOperationImpl.configureImpl(this, options); }
|
|
14
|
+
get options() { return this.peek(undefined).footprint.options; }
|
|
15
|
+
get nonreactive() { return this.peek(undefined).footprint.content; }
|
|
16
|
+
get args() { return this.use().footprint.args; }
|
|
17
17
|
get result() { return this.reuseOrRelaunch(true, undefined).content; }
|
|
18
|
-
get error() { return this.use().
|
|
18
|
+
get error() { return this.use().footprint.error; }
|
|
19
19
|
get stamp() { return this.use().objectVersion.changeset.timestamp; }
|
|
20
20
|
get isReusable() { return this.use().isReusable; }
|
|
21
|
-
markObsolete() { Transaction.run({ hint: Log.isOn ? `markObsolete(${Dump.obj(this.ownerHandle, this.fieldKey)})` : "markObsolete()" },
|
|
21
|
+
markObsolete() { Transaction.run({ hint: Log.isOn ? `markObsolete(${Dump.obj(this.ownerHandle, this.fieldKey)})` : "markObsolete()" }, ReactiveOperationImpl.markObsolete, this); }
|
|
22
22
|
pullLastResult(args) { return this.reuseOrRelaunch(true, args).content; }
|
|
23
23
|
constructor(h, fk) {
|
|
24
24
|
this.ownerHandle = h;
|
|
@@ -27,87 +27,87 @@ export class OperationImpl {
|
|
|
27
27
|
reuseOrRelaunch(weak, args) {
|
|
28
28
|
let ror = this.peek(args);
|
|
29
29
|
const ctx = ror.changeset;
|
|
30
|
-
const
|
|
31
|
-
const opts =
|
|
30
|
+
const footprint = ror.footprint;
|
|
31
|
+
const opts = footprint.options;
|
|
32
32
|
if (!ror.isReusable && !ror.objectVersion.disposed
|
|
33
|
-
&& (!weak ||
|
|
34
|
-
|
|
33
|
+
&& (!weak || footprint.cause === BOOT_CAUSE || !footprint.successor ||
|
|
34
|
+
footprint.successor.transaction.isFinished)) {
|
|
35
35
|
const isolation = !weak ? opts.isolation : Isolation.disjoinFromOuterTransaction;
|
|
36
36
|
const token = opts.noSideEffects ? this : undefined;
|
|
37
37
|
const ror2 = this.relaunch(ror, isolation, opts, token, args);
|
|
38
|
-
const ctx2 = ror2.
|
|
38
|
+
const ctx2 = ror2.footprint.changeset;
|
|
39
39
|
if (!weak || ctx === ctx2 || (ctx2.sealed && ctx.timestamp >= ctx2.timestamp))
|
|
40
40
|
ror = ror2;
|
|
41
41
|
}
|
|
42
42
|
else if (Log.isOn && Log.opt.operation && (opts.logging === undefined ||
|
|
43
43
|
opts.logging.operation === undefined || opts.logging.operation === true))
|
|
44
|
-
Log.write(Transaction.current.isFinished ? "" : "║", " (=)", `${Dump.snapshot2(ror.
|
|
45
|
-
const t = ror.
|
|
44
|
+
Log.write(Transaction.current.isFinished ? "" : "║", " (=)", `${Dump.snapshot2(ror.footprint.descriptor.ownerHandle, ror.changeset, this.fieldKey)} result is reused from T${ror.footprint.transaction.id}[${ror.footprint.transaction.hint}]`);
|
|
45
|
+
const t = ror.footprint;
|
|
46
46
|
Changeset.markUsed(t, ror.objectVersion, this.fieldKey, this.ownerHandle, t.options.kind, weak);
|
|
47
47
|
return t;
|
|
48
48
|
}
|
|
49
|
-
static
|
|
50
|
-
const ctl = Meta.get(method, Meta.
|
|
49
|
+
static manageReactiveOperation(method) {
|
|
50
|
+
const ctl = Meta.get(method, Meta.Descriptor);
|
|
51
51
|
if (!ctl)
|
|
52
52
|
throw misuse(`given method is not decorated as reactronic one: ${method.name}`);
|
|
53
53
|
return ctl;
|
|
54
54
|
}
|
|
55
55
|
static configureImpl(self, options) {
|
|
56
|
-
let
|
|
56
|
+
let footprint;
|
|
57
57
|
if (self)
|
|
58
|
-
|
|
58
|
+
footprint = self.edit().footprint;
|
|
59
59
|
else
|
|
60
|
-
|
|
61
|
-
if (!
|
|
60
|
+
footprint = OperationFootprintImpl.current;
|
|
61
|
+
if (!footprint)
|
|
62
62
|
throw misuse("reactronic decorator is only applicable to methods");
|
|
63
|
-
|
|
63
|
+
footprint.options = new OptionsImpl(footprint.options.getter, footprint.options.setter, footprint.options, options, false);
|
|
64
64
|
if (Log.isOn && Log.opt.write)
|
|
65
|
-
Log.write("║", " =", `${
|
|
66
|
-
return
|
|
65
|
+
Log.write("║", " =", `${footprint.hint()}.options are changed`);
|
|
66
|
+
return footprint.options;
|
|
67
67
|
}
|
|
68
|
-
static proceedWithinGivenLaunch(
|
|
68
|
+
static proceedWithinGivenLaunch(footprint, func, ...args) {
|
|
69
69
|
let result = undefined;
|
|
70
|
-
const outer =
|
|
70
|
+
const outer = OperationFootprintImpl.current;
|
|
71
71
|
try {
|
|
72
|
-
|
|
72
|
+
OperationFootprintImpl.current = footprint;
|
|
73
73
|
result = func(...args);
|
|
74
74
|
}
|
|
75
75
|
catch (e) {
|
|
76
|
-
if (
|
|
77
|
-
|
|
76
|
+
if (footprint)
|
|
77
|
+
footprint.error = e;
|
|
78
78
|
throw e;
|
|
79
79
|
}
|
|
80
80
|
finally {
|
|
81
|
-
|
|
81
|
+
OperationFootprintImpl.current = outer;
|
|
82
82
|
}
|
|
83
83
|
return result;
|
|
84
84
|
}
|
|
85
85
|
static why() {
|
|
86
86
|
var _a, _b;
|
|
87
|
-
return (_b = (_a =
|
|
87
|
+
return (_b = (_a = OperationFootprintImpl.current) === null || _a === void 0 ? void 0 : _a.why()) !== null && _b !== void 0 ? _b : BOOT_CAUSE;
|
|
88
88
|
}
|
|
89
89
|
static briefWhy() {
|
|
90
90
|
var _a, _b;
|
|
91
|
-
return (_b = (_a =
|
|
91
|
+
return (_b = (_a = OperationFootprintImpl.current) === null || _a === void 0 ? void 0 : _a.briefWhy()) !== null && _b !== void 0 ? _b : BOOT_CAUSE;
|
|
92
92
|
}
|
|
93
93
|
static dependencies() {
|
|
94
|
-
const l =
|
|
94
|
+
const l = OperationFootprintImpl.current;
|
|
95
95
|
return l ? l.dependencies() : ["RxSystem.dependencies should be called from inside of reactive method"];
|
|
96
96
|
}
|
|
97
97
|
peek(args) {
|
|
98
98
|
const ctx = Changeset.current();
|
|
99
99
|
const ov = ctx.lookupObjectVersion(this.ownerHandle, this.fieldKey, false);
|
|
100
|
-
const
|
|
100
|
+
const footprint = this.acquireFromObjectVersion(ov, args);
|
|
101
101
|
const applied = this.ownerHandle.applied.data[this.fieldKey];
|
|
102
|
-
const isReusable =
|
|
103
|
-
(ctx ===
|
|
104
|
-
(!
|
|
105
|
-
|
|
106
|
-
return {
|
|
102
|
+
const isReusable = footprint.options.kind !== Kind.atomic && footprint.cause !== BOOT_CAUSE &&
|
|
103
|
+
(ctx === footprint.changeset || ctx.timestamp < footprint.obsoleteSince || applied.obsoleteDueTo === undefined) &&
|
|
104
|
+
(!footprint.options.observableArgs || args === undefined ||
|
|
105
|
+
footprint.args.length === args.length && footprint.args.every((t, i) => t === args[i])) || ov.disposed;
|
|
106
|
+
return { footprint, isReusable, changeset: ctx, objectVersion: ov };
|
|
107
107
|
}
|
|
108
108
|
use() {
|
|
109
109
|
const ror = this.peek(undefined);
|
|
110
|
-
Changeset.markUsed(ror.
|
|
110
|
+
Changeset.markUsed(ror.footprint, ror.objectVersion, this.fieldKey, this.ownerHandle, ror.footprint.options.kind, true);
|
|
111
111
|
return ror;
|
|
112
112
|
}
|
|
113
113
|
edit() {
|
|
@@ -115,94 +115,94 @@ export class OperationImpl {
|
|
|
115
115
|
const fk = this.fieldKey;
|
|
116
116
|
const ctx = Changeset.edit();
|
|
117
117
|
const ov = ctx.getEditableObjectVersion(h, fk, Meta.Handle, this);
|
|
118
|
-
let
|
|
119
|
-
if (
|
|
120
|
-
const
|
|
121
|
-
ov.data[fk] =
|
|
118
|
+
let footprint = this.acquireFromObjectVersion(ov, undefined);
|
|
119
|
+
if (footprint.changeset !== ov.changeset) {
|
|
120
|
+
const newFootprint = new OperationFootprintImpl(Transaction.current, this, ov.changeset, footprint, false);
|
|
121
|
+
ov.data[fk] = newFootprint.reenterOver(footprint);
|
|
122
122
|
ctx.bumpBy(ov.former.objectVersion.changeset.timestamp);
|
|
123
|
-
Changeset.markEdited(
|
|
124
|
-
|
|
123
|
+
Changeset.markEdited(footprint, newFootprint, true, ov, fk, h);
|
|
124
|
+
footprint = newFootprint;
|
|
125
125
|
}
|
|
126
|
-
return {
|
|
126
|
+
return { footprint, isReusable: true, changeset: ctx, objectVersion: ov };
|
|
127
127
|
}
|
|
128
128
|
acquireFromObjectVersion(ov, args) {
|
|
129
129
|
const fk = this.fieldKey;
|
|
130
|
-
let
|
|
131
|
-
if (
|
|
130
|
+
let footprint = ov.data[fk];
|
|
131
|
+
if (footprint.descriptor !== this) {
|
|
132
132
|
if (ov.changeset !== EMPTY_OBJECT_VERSION.changeset) {
|
|
133
|
-
const hint = Log.isOn ? `${Dump.obj(this.ownerHandle, fk)}/init` : "
|
|
133
|
+
const hint = Log.isOn ? `${Dump.obj(this.ownerHandle, fk)}/init` : "OperationDescriptor/init";
|
|
134
134
|
const isolation = Isolation.joinToCurrentTransaction;
|
|
135
|
-
|
|
135
|
+
footprint = Transaction.run({ hint, isolation, token: this }, () => {
|
|
136
136
|
const h = this.ownerHandle;
|
|
137
137
|
let r = Changeset.current().getObjectVersion(h, fk);
|
|
138
|
-
let
|
|
139
|
-
if (
|
|
138
|
+
let newFootprint = r.data[fk];
|
|
139
|
+
if (newFootprint.descriptor !== this) {
|
|
140
140
|
r = Changeset.edit().getEditableObjectVersion(h, fk, Meta.Handle, this);
|
|
141
|
-
const t = new
|
|
141
|
+
const t = new OperationFootprintImpl(Transaction.current, this, r.changeset, newFootprint, false);
|
|
142
142
|
if (args)
|
|
143
143
|
t.args = args;
|
|
144
144
|
t.cause = BOOT_CAUSE;
|
|
145
145
|
r.data[fk] = t;
|
|
146
|
-
Changeset.markEdited(
|
|
147
|
-
|
|
146
|
+
Changeset.markEdited(newFootprint, t, true, r, fk, h);
|
|
147
|
+
newFootprint = t;
|
|
148
148
|
}
|
|
149
|
-
return
|
|
149
|
+
return newFootprint;
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
152
|
else {
|
|
153
|
-
const
|
|
153
|
+
const initialFootprint = new OperationFootprintImpl(Transaction.current, this, ov.changeset, footprint, false);
|
|
154
154
|
if (args)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
ov.data[fk] =
|
|
158
|
-
|
|
155
|
+
initialFootprint.args = args;
|
|
156
|
+
initialFootprint.cause = BOOT_CAUSE;
|
|
157
|
+
ov.data[fk] = initialFootprint;
|
|
158
|
+
footprint = initialFootprint;
|
|
159
159
|
if (Log.isOn && Log.opt.write)
|
|
160
160
|
Log.write("║", " ++", `${Dump.obj(this.ownerHandle, fk)} is initialized (revision ${ov.revision})`);
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
return
|
|
163
|
+
return footprint;
|
|
164
164
|
}
|
|
165
165
|
relaunch(existing, isolation, options, token, args) {
|
|
166
166
|
const hint = Log.isOn ? `${Dump.obj(this.ownerHandle, this.fieldKey)}${args && args.length > 0 && (typeof args[0] === "number" || typeof args[0] === "string") ? ` - ${args[0]}` : ""}` : `${Dump.obj(this.ownerHandle, this.fieldKey)}`;
|
|
167
167
|
let ror = existing;
|
|
168
168
|
const opts = { hint, isolation, journal: options.journal, logging: options.logging, token };
|
|
169
169
|
const result = Transaction.run(opts, (argsx) => {
|
|
170
|
-
if (!ror.
|
|
170
|
+
if (!ror.footprint.transaction.isCanceled) {
|
|
171
171
|
ror = this.edit();
|
|
172
172
|
if (Log.isOn && Log.opt.operation)
|
|
173
|
-
Log.write("║", " o", `${ror.
|
|
174
|
-
ror.
|
|
173
|
+
Log.write("║", " o", `${ror.footprint.why()}`);
|
|
174
|
+
ror.footprint.proceed(this.ownerHandle.proxy, argsx);
|
|
175
175
|
}
|
|
176
176
|
else {
|
|
177
177
|
ror = this.peek(argsx);
|
|
178
|
-
if (ror.
|
|
178
|
+
if (ror.footprint.options.kind === Kind.atomic || !ror.isReusable) {
|
|
179
179
|
ror = this.edit();
|
|
180
180
|
if (Log.isOn && Log.opt.operation)
|
|
181
|
-
Log.write("║", " o", `${ror.
|
|
182
|
-
ror.
|
|
181
|
+
Log.write("║", " o", `${ror.footprint.why()}`);
|
|
182
|
+
ror.footprint.proceed(this.ownerHandle.proxy, argsx);
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
return ror.
|
|
185
|
+
return ror.footprint.result;
|
|
186
186
|
}, args);
|
|
187
|
-
ror.
|
|
187
|
+
ror.footprint.result = result;
|
|
188
188
|
return ror;
|
|
189
189
|
}
|
|
190
190
|
static markObsolete(self) {
|
|
191
191
|
const ror = self.peek(undefined);
|
|
192
192
|
const ctx = ror.changeset;
|
|
193
|
-
const obsolete = ror.
|
|
194
|
-
ror.
|
|
193
|
+
const obsolete = ror.footprint.transaction.isFinished ? ctx.obsolete : ror.footprint.transaction.changeset.obsolete;
|
|
194
|
+
ror.footprint.markObsoleteDueTo(ror.footprint, self.fieldKey, EMPTY_OBJECT_VERSION.changeset, EMPTY_HANDLE, BOOT_CAUSE, ctx.timestamp, obsolete);
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
-
class
|
|
198
|
-
constructor(transaction,
|
|
197
|
+
class OperationFootprintImpl extends ContentFootprint {
|
|
198
|
+
constructor(transaction, descriptor, changeset, former, clone) {
|
|
199
199
|
super(undefined, 0);
|
|
200
|
-
this.margin =
|
|
200
|
+
this.margin = OperationFootprintImpl.current ? OperationFootprintImpl.current.margin + 1 : 1;
|
|
201
201
|
this.transaction = transaction;
|
|
202
|
-
this.
|
|
202
|
+
this.descriptor = descriptor;
|
|
203
203
|
this.changeset = changeset;
|
|
204
|
-
this.
|
|
205
|
-
if (former instanceof
|
|
204
|
+
this.observables = new Map();
|
|
205
|
+
if (former instanceof OperationFootprintImpl) {
|
|
206
206
|
this.options = former.options;
|
|
207
207
|
this.cause = former.obsoleteDueTo;
|
|
208
208
|
this.args = former.args;
|
|
@@ -238,20 +238,20 @@ class Launch extends FieldVersion {
|
|
|
238
238
|
this.successor = undefined;
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
|
-
get
|
|
242
|
-
hint() { return `${Dump.snapshot2(this.
|
|
241
|
+
get isComputed() { return true; }
|
|
242
|
+
hint() { return `${Dump.snapshot2(this.descriptor.ownerHandle, this.changeset, this.descriptor.fieldKey, this)}`; }
|
|
243
243
|
get order() { return this.options.order; }
|
|
244
244
|
get ["#this#"]() {
|
|
245
245
|
return `Operation: ${this.why()}`;
|
|
246
246
|
}
|
|
247
247
|
clone(t, cs) {
|
|
248
|
-
return new
|
|
248
|
+
return new OperationFootprintImpl(t, this.descriptor, cs, this, true);
|
|
249
249
|
}
|
|
250
250
|
why() {
|
|
251
251
|
let cause;
|
|
252
252
|
if (this.cause)
|
|
253
253
|
cause = ` ◀◀ ${this.cause}`;
|
|
254
|
-
else if (this.
|
|
254
|
+
else if (this.descriptor.options.kind === Kind.atomic)
|
|
255
255
|
cause = " ◀◀ operation";
|
|
256
256
|
else
|
|
257
257
|
cause = ` ◀◀ T${this.changeset.id}[${this.changeset.hint}]`;
|
|
@@ -268,7 +268,7 @@ class Launch extends FieldVersion {
|
|
|
268
268
|
if (Log.isOn && Log.opt.step && this.result)
|
|
269
269
|
Log.writeAs({ margin2: this.margin }, "║", "‾\\", `${this.hint()} - step in `, 0, " │");
|
|
270
270
|
const started = Date.now();
|
|
271
|
-
const result =
|
|
271
|
+
const result = ReactiveOperationImpl.proceedWithinGivenLaunch(this, func, ...args);
|
|
272
272
|
const ms = Date.now() - started;
|
|
273
273
|
if (Log.isOn && Log.opt.step && this.result)
|
|
274
274
|
Log.writeAs({ margin2: this.margin }, "║", "_/", `${this.hint()} - step out `, 0, this.started > 0 ? " │" : "");
|
|
@@ -283,37 +283,37 @@ class Launch extends FieldVersion {
|
|
|
283
283
|
this.args = args;
|
|
284
284
|
this.obsoleteSince = MAX_REVISION;
|
|
285
285
|
if (!this.error)
|
|
286
|
-
|
|
286
|
+
ReactiveOperationImpl.proceedWithinGivenLaunch(this, OperationFootprintImpl.proceed, this, proxy);
|
|
287
287
|
else
|
|
288
288
|
this.result = Promise.reject(this.error);
|
|
289
289
|
}
|
|
290
|
-
markObsoleteDueTo(
|
|
290
|
+
markObsoleteDueTo(footprint, fk, changeset, h, outer, since, collector) {
|
|
291
291
|
var _a, _b, _c;
|
|
292
|
-
if (this.
|
|
293
|
-
const skip = !
|
|
292
|
+
if (this.observables !== undefined) {
|
|
293
|
+
const skip = !footprint.isComputed &&
|
|
294
294
|
changeset.id === this.lastEditorChangesetId;
|
|
295
295
|
if (!skip) {
|
|
296
|
-
const why = `${Dump.snapshot2(h, changeset, fk,
|
|
297
|
-
const
|
|
296
|
+
const why = `${Dump.snapshot2(h, changeset, fk, footprint)} ◀◀ ${outer}`;
|
|
297
|
+
const isReactive = this.options.kind === Kind.reactive;
|
|
298
298
|
this.obsoleteDueTo = why;
|
|
299
299
|
this.obsoleteSince = since;
|
|
300
300
|
if (Log.isOn && (Log.opt.obsolete || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.obsolete)))
|
|
301
|
-
Log.write(Log.opt.transaction && !Changeset.current().sealed ? "║" : " ",
|
|
301
|
+
Log.write(Log.opt.transaction && !Changeset.current().sealed ? "║" : " ", isReactive ? "█" : "▒", isReactive && changeset === EMPTY_OBJECT_VERSION.changeset
|
|
302
302
|
? `${this.hint()} is reactive and will run automatically (order ${this.options.order})`
|
|
303
|
-
: `${this.hint()} is obsolete due to ${Dump.snapshot2(h, changeset, fk)} since s${since}${
|
|
304
|
-
this.
|
|
305
|
-
if (
|
|
303
|
+
: `${this.hint()} is obsolete due to ${Dump.snapshot2(h, changeset, fk)} since s${since}${isReactive ? ` and will run automatically (order ${this.options.order})` : ""}`);
|
|
304
|
+
this.unsubscribeFromAllObservables();
|
|
305
|
+
if (isReactive)
|
|
306
306
|
collector.push(this);
|
|
307
307
|
else
|
|
308
|
-
(_b = this.
|
|
308
|
+
(_b = this.subscribers) === null || _b === void 0 ? void 0 : _b.forEach(s => s.markObsoleteDueTo(this, this.descriptor.fieldKey, this.changeset, this.descriptor.ownerHandle, why, since, collector));
|
|
309
309
|
const tran = this.transaction;
|
|
310
310
|
if (tran.changeset === changeset) {
|
|
311
311
|
}
|
|
312
|
-
else if (!tran.isFinished && this !==
|
|
312
|
+
else if (!tran.isFinished && this !== footprint && !this.options.allowObsoleteToFinish)
|
|
313
313
|
tran.cancel(new Error(`T${tran.id}[${tran.hint}] is canceled due to obsolete ${Dump.snapshot2(h, changeset, fk)} changed by T${changeset.id}[${changeset.hint}]`), null);
|
|
314
314
|
}
|
|
315
315
|
else if (Log.isOn && (Log.opt.obsolete || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.obsolete)))
|
|
316
|
-
Log.write(" ", "x", `${this.hint()} is not obsolete due to its own change to ${Dump.snapshot2(h, changeset, fk,
|
|
316
|
+
Log.write(" ", "x", `${this.hint()} is not obsolete due to its own change to ${Dump.snapshot2(h, changeset, fk, footprint)}`);
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
relaunchIfNotUpToDate(now, nothrow) {
|
|
@@ -323,17 +323,17 @@ class Launch extends FieldVersion {
|
|
|
323
323
|
if (now || hold < 0) {
|
|
324
324
|
if (this.isNotUpToDate()) {
|
|
325
325
|
try {
|
|
326
|
-
const
|
|
327
|
-
if (
|
|
328
|
-
|
|
329
|
-
if (
|
|
330
|
-
misuse(`reactive function ${
|
|
326
|
+
const footprint = this.descriptor.reuseOrRelaunch(false, undefined);
|
|
327
|
+
if (footprint.result instanceof Promise)
|
|
328
|
+
footprint.result.catch(error => {
|
|
329
|
+
if (footprint.options.kind === Kind.reactive)
|
|
330
|
+
misuse(`reactive function ${footprint.hint()} failed and will not run anymore: ${error}`, error);
|
|
331
331
|
});
|
|
332
332
|
}
|
|
333
333
|
catch (e) {
|
|
334
334
|
if (!nothrow)
|
|
335
335
|
throw e;
|
|
336
|
-
else if (this.options.kind === Kind.
|
|
336
|
+
else if (this.options.kind === Kind.reactive)
|
|
337
337
|
misuse(`reactive ${this.hint()} failed and will not run anymore: ${e}`, e);
|
|
338
338
|
}
|
|
339
339
|
}
|
|
@@ -384,22 +384,22 @@ class Launch extends FieldVersion {
|
|
|
384
384
|
this.error = error;
|
|
385
385
|
return this;
|
|
386
386
|
}
|
|
387
|
-
static proceed(
|
|
388
|
-
|
|
387
|
+
static proceed(footprint, proxy) {
|
|
388
|
+
footprint.enter();
|
|
389
389
|
try {
|
|
390
|
-
if (
|
|
390
|
+
if (footprint.options.getter === undefined)
|
|
391
391
|
console.log("(!)");
|
|
392
|
-
|
|
392
|
+
footprint.result = footprint.options.getter.call(proxy, ...footprint.args);
|
|
393
393
|
}
|
|
394
394
|
finally {
|
|
395
|
-
|
|
395
|
+
footprint.leaveOrAsync();
|
|
396
396
|
}
|
|
397
397
|
}
|
|
398
398
|
enter() {
|
|
399
399
|
if (this.options.indicator)
|
|
400
400
|
this.indicatorEnter(this.options.indicator);
|
|
401
401
|
if (Log.isOn && Log.opt.operation)
|
|
402
|
-
Log.write("║", "‾\\", `${this.hint()} - enter`, undefined, ` [ ${Dump.obj(this.
|
|
402
|
+
Log.write("║", "‾\\", `${this.hint()} - enter`, undefined, ` [ ${Dump.obj(this.descriptor.ownerHandle, this.descriptor.fieldKey)} ]`);
|
|
403
403
|
this.started = Date.now();
|
|
404
404
|
}
|
|
405
405
|
leaveOrAsync() {
|
|
@@ -442,7 +442,7 @@ class Launch extends FieldVersion {
|
|
|
442
442
|
isolation: Isolation.disjoinFromOuterAndInnerTransactions,
|
|
443
443
|
logging: Log.isOn && Log.opt.indicator ? undefined : Log.global
|
|
444
444
|
};
|
|
445
|
-
|
|
445
|
+
ReactiveOperationImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options, IndicatorImpl.enter, mon, this.transaction);
|
|
446
446
|
}
|
|
447
447
|
indicatorLeave(mon) {
|
|
448
448
|
Transaction.outside(() => {
|
|
@@ -452,33 +452,33 @@ class Launch extends FieldVersion {
|
|
|
452
452
|
isolation: Isolation.disjoinFromOuterAndInnerTransactions,
|
|
453
453
|
logging: Log.isOn && Log.opt.indicator ? undefined : Log.DefaultLevel
|
|
454
454
|
};
|
|
455
|
-
|
|
455
|
+
ReactiveOperationImpl.proceedWithinGivenLaunch(undefined, Transaction.run, options, IndicatorImpl.leave, mon, this.transaction);
|
|
456
456
|
};
|
|
457
457
|
this.transaction.whenFinished().then(leave, leave);
|
|
458
458
|
});
|
|
459
459
|
}
|
|
460
460
|
addToDeferredReactiveFunctions() {
|
|
461
|
-
|
|
462
|
-
if (
|
|
463
|
-
setTimeout(
|
|
461
|
+
OperationFootprintImpl.deferredReactions.push(this);
|
|
462
|
+
if (OperationFootprintImpl.deferredReactions.length === 1)
|
|
463
|
+
setTimeout(OperationFootprintImpl.processDeferredReactions, 0);
|
|
464
464
|
}
|
|
465
|
-
static
|
|
466
|
-
const deferred =
|
|
467
|
-
|
|
465
|
+
static processDeferredReactions() {
|
|
466
|
+
const deferred = OperationFootprintImpl.deferredReactions;
|
|
467
|
+
OperationFootprintImpl.deferredReactions = [];
|
|
468
468
|
for (const x of deferred)
|
|
469
469
|
x.relaunchIfNotUpToDate(true, true);
|
|
470
470
|
}
|
|
471
|
-
static markUsed(
|
|
471
|
+
static markUsed(footprint, ov, fk, h, kind, weak) {
|
|
472
472
|
if (kind !== Kind.atomic) {
|
|
473
|
-
const
|
|
474
|
-
if (
|
|
475
|
-
|
|
473
|
+
const subscriber = OperationFootprintImpl.current;
|
|
474
|
+
if (subscriber && subscriber.options.kind !== Kind.atomic &&
|
|
475
|
+
subscriber.transaction === Transaction.current && fk !== Meta.Handle) {
|
|
476
476
|
const ctx = Changeset.current();
|
|
477
477
|
if (ctx !== ov.changeset)
|
|
478
478
|
ctx.bumpBy(ov.changeset.timestamp);
|
|
479
479
|
const t = weak ? -1 : ctx.timestamp;
|
|
480
|
-
if (!
|
|
481
|
-
|
|
480
|
+
if (!subscriber.subscribeTo(footprint, ov, fk, h, t))
|
|
481
|
+
subscriber.markObsoleteDueTo(footprint, fk, h.applied.changeset, h, BOOT_CAUSE, ctx.timestamp, ctx.obsolete);
|
|
482
482
|
}
|
|
483
483
|
}
|
|
484
484
|
}
|
|
@@ -491,11 +491,11 @@ class Launch extends FieldVersion {
|
|
|
491
491
|
let isResolved = theirValue === ourFormerValue;
|
|
492
492
|
let resolvedValue = ourValue;
|
|
493
493
|
if (!isResolved) {
|
|
494
|
-
if (ourValue instanceof
|
|
494
|
+
if (ourValue instanceof OperationFootprintImpl && ourValue.obsoleteDueTo === undefined) {
|
|
495
495
|
isResolved = true;
|
|
496
496
|
resolvedValue = ourValue;
|
|
497
497
|
}
|
|
498
|
-
else if (theirValue instanceof
|
|
498
|
+
else if (theirValue instanceof OperationFootprintImpl && (theirValue.obsoleteDueTo === undefined || theirValue.cause === BOOT_CAUSE)) {
|
|
499
499
|
isResolved = true;
|
|
500
500
|
resolvedValue = theirValue;
|
|
501
501
|
}
|
|
@@ -507,20 +507,20 @@ class Launch extends FieldVersion {
|
|
|
507
507
|
const since = changeset.timestamp;
|
|
508
508
|
const obsolete = changeset.obsolete;
|
|
509
509
|
changeset.items.forEach((ov, h) => {
|
|
510
|
-
|
|
510
|
+
OperationFootprintImpl.propagateFieldChangeThroughSubscriptions(false, since, ov, Meta.Revision, h, obsolete);
|
|
511
511
|
if (!ov.disposed)
|
|
512
|
-
ov.changes.forEach((o, fk) =>
|
|
512
|
+
ov.changes.forEach((o, fk) => OperationFootprintImpl.propagateFieldChangeThroughSubscriptions(false, since, ov, fk, h, obsolete));
|
|
513
513
|
else
|
|
514
514
|
for (const fk in ov.former.objectVersion.data)
|
|
515
|
-
|
|
515
|
+
OperationFootprintImpl.propagateFieldChangeThroughSubscriptions(true, since, ov, fk, h, obsolete);
|
|
516
516
|
});
|
|
517
517
|
obsolete.sort(compareReactionsByOrder);
|
|
518
518
|
(_a = changeset.options.journal) === null || _a === void 0 ? void 0 : _a.edited(JournalImpl.buildPatch(changeset.hint, changeset.items));
|
|
519
519
|
}
|
|
520
520
|
static revokeAllSubscriptions(changeset) {
|
|
521
521
|
changeset.items.forEach((ov, h) => {
|
|
522
|
-
|
|
523
|
-
ov.changes.forEach((o, fk) =>
|
|
522
|
+
OperationFootprintImpl.propagateFieldChangeThroughSubscriptions(true, changeset.timestamp, ov, Meta.Revision, h, undefined);
|
|
523
|
+
ov.changes.forEach((o, fk) => OperationFootprintImpl.propagateFieldChangeThroughSubscriptions(true, changeset.timestamp, ov, fk, h, undefined));
|
|
524
524
|
});
|
|
525
525
|
}
|
|
526
526
|
static propagateFieldChangeThroughSubscriptions(unsubscribe, timestamp, ov, fk, h, collector) {
|
|
@@ -528,13 +528,13 @@ class Launch extends FieldVersion {
|
|
|
528
528
|
const curr = ov.data[fk];
|
|
529
529
|
if (collector !== undefined) {
|
|
530
530
|
const former = ov.former.objectVersion.data[fk];
|
|
531
|
-
if (former !== undefined && former instanceof
|
|
531
|
+
if (former !== undefined && former instanceof ContentFootprint) {
|
|
532
532
|
const why = `T${ov.changeset.id}[${ov.changeset.hint}]`;
|
|
533
|
-
if (former instanceof
|
|
533
|
+
if (former instanceof OperationFootprintImpl) {
|
|
534
534
|
if ((former.obsoleteSince === MAX_REVISION || former.obsoleteSince <= 0)) {
|
|
535
535
|
former.obsoleteDueTo = why;
|
|
536
536
|
former.obsoleteSince = timestamp;
|
|
537
|
-
former.
|
|
537
|
+
former.unsubscribeFromAllObservables();
|
|
538
538
|
}
|
|
539
539
|
const formerSuccessor = former.successor;
|
|
540
540
|
if (formerSuccessor !== curr) {
|
|
@@ -544,163 +544,163 @@ class Launch extends FieldVersion {
|
|
|
544
544
|
else
|
|
545
545
|
former.successor = undefined;
|
|
546
546
|
}
|
|
547
|
-
(_a = former.
|
|
547
|
+
(_a = former.subscribers) === null || _a === void 0 ? void 0 : _a.forEach(s => {
|
|
548
548
|
const t = s.transaction;
|
|
549
549
|
const o = t.isFinished ? collector : t.changeset.obsolete;
|
|
550
550
|
return s.markObsoleteDueTo(former, fk, ov.changeset, h, why, timestamp, o);
|
|
551
551
|
});
|
|
552
552
|
}
|
|
553
553
|
}
|
|
554
|
-
if (curr instanceof
|
|
555
|
-
if (curr.changeset === ov.changeset && curr.
|
|
554
|
+
if (curr instanceof OperationFootprintImpl) {
|
|
555
|
+
if (curr.changeset === ov.changeset && curr.observables !== undefined) {
|
|
556
556
|
if (Mvcc.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
557
|
-
curr.
|
|
557
|
+
curr.observables.forEach((info, v) => {
|
|
558
558
|
if (info.usageCount > Mvcc.repetitiveUsageWarningThreshold)
|
|
559
559
|
Log.write("", "[!]", `${curr.hint()} uses ${info.memberHint} ${info.usageCount} times (consider remembering it in a local variable)`, 0, " *** WARNING ***");
|
|
560
560
|
});
|
|
561
561
|
}
|
|
562
562
|
if (unsubscribe)
|
|
563
|
-
curr.
|
|
563
|
+
curr.unsubscribeFromAllObservables();
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
|
-
else if (curr instanceof
|
|
566
|
+
else if (curr instanceof ContentFootprint && curr.subscribers) {
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
static enqueueReactionsToRun(reactions) {
|
|
570
|
-
const queue =
|
|
570
|
+
const queue = OperationFootprintImpl.queuedReactions;
|
|
571
571
|
const isKickOff = queue.length === 0;
|
|
572
572
|
for (const r of reactions)
|
|
573
573
|
queue.push(r);
|
|
574
574
|
if (isKickOff)
|
|
575
|
-
|
|
575
|
+
ReactiveOperationImpl.proceedWithinGivenLaunch(undefined, OperationFootprintImpl.processQueuedReactions);
|
|
576
576
|
}
|
|
577
|
-
static
|
|
577
|
+
static migrateContentFootprint(cf, target) {
|
|
578
578
|
let result;
|
|
579
|
-
if (
|
|
580
|
-
result = new
|
|
579
|
+
if (cf instanceof OperationFootprintImpl)
|
|
580
|
+
result = new OperationFootprintImpl(target, cf.descriptor, target.changeset, cf, true);
|
|
581
581
|
else
|
|
582
|
-
result = new
|
|
582
|
+
result = new ContentFootprint(cf.content, cf.lastEditorChangesetId);
|
|
583
583
|
return result;
|
|
584
584
|
}
|
|
585
585
|
static processQueuedReactions() {
|
|
586
|
-
const queue =
|
|
586
|
+
const queue = OperationFootprintImpl.queuedReactions;
|
|
587
587
|
let i = 0;
|
|
588
588
|
while (i < queue.length) {
|
|
589
589
|
const reactive = queue[i];
|
|
590
590
|
reactive.relaunchIfNotUpToDate(false, true);
|
|
591
591
|
i++;
|
|
592
592
|
}
|
|
593
|
-
|
|
593
|
+
OperationFootprintImpl.queuedReactions = [];
|
|
594
594
|
}
|
|
595
|
-
|
|
595
|
+
unsubscribeFromAllObservables() {
|
|
596
596
|
var _a;
|
|
597
|
-
(_a = this.
|
|
597
|
+
(_a = this.observables) === null || _a === void 0 ? void 0 : _a.forEach((info, value) => {
|
|
598
598
|
var _a;
|
|
599
|
-
value.
|
|
599
|
+
value.subscribers.delete(this);
|
|
600
600
|
if (Log.isOn && (Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
601
601
|
Log.write(Log.opt.transaction && !Changeset.current().sealed ? "║" : " ", "-", `${this.hint()} is unsubscribed from ${info.memberHint}`);
|
|
602
602
|
});
|
|
603
|
-
this.
|
|
603
|
+
this.observables = undefined;
|
|
604
604
|
}
|
|
605
|
-
subscribeTo(
|
|
605
|
+
subscribeTo(footprint, ov, fk, h, timestamp) {
|
|
606
606
|
var _a, _b, _c;
|
|
607
607
|
const parent = this.transaction.changeset.parent;
|
|
608
|
-
const ok =
|
|
608
|
+
const ok = OperationFootprintImpl.canSubscribeTo(footprint, ov, parent, fk, h, timestamp);
|
|
609
609
|
if (ok) {
|
|
610
610
|
let times = 0;
|
|
611
611
|
if (Mvcc.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
|
|
612
|
-
const existing = this.
|
|
612
|
+
const existing = this.observables.get(footprint);
|
|
613
613
|
times = existing ? existing.usageCount + 1 : 1;
|
|
614
614
|
}
|
|
615
|
-
if (this.
|
|
616
|
-
if (!
|
|
617
|
-
|
|
615
|
+
if (this.observables !== undefined) {
|
|
616
|
+
if (!footprint.subscribers)
|
|
617
|
+
footprint.subscribers = new Set();
|
|
618
618
|
const subscription = { memberHint: Dump.snapshot2(h, ov.changeset, fk), usageCount: times };
|
|
619
|
-
|
|
620
|
-
this.
|
|
619
|
+
footprint.subscribers.add(this);
|
|
620
|
+
this.observables.set(footprint, subscription);
|
|
621
621
|
if (Log.isOn && (Log.opt.read || ((_a = this.options.logging) === null || _a === void 0 ? void 0 : _a.read)))
|
|
622
|
-
Log.write("║", " ∞", `${this.hint()} is subscribed to ${Dump.snapshot2(h, ov.changeset, fk,
|
|
622
|
+
Log.write("║", " ∞", `${this.hint()} is subscribed to ${Dump.snapshot2(h, ov.changeset, fk, footprint)}${subscription.usageCount > 1 ? ` (${subscription.usageCount} times)` : ""}`);
|
|
623
623
|
}
|
|
624
624
|
else if (Log.isOn && (Log.opt.read || ((_b = this.options.logging) === null || _b === void 0 ? void 0 : _b.read)))
|
|
625
|
-
Log.write("║", " x", `${this.hint()} is obsolete and is NOT subscribed to ${Dump.snapshot2(h, ov.changeset, fk,
|
|
625
|
+
Log.write("║", " x", `${this.hint()} is obsolete and is NOT subscribed to ${Dump.snapshot2(h, ov.changeset, fk, footprint)}`);
|
|
626
626
|
}
|
|
627
627
|
else {
|
|
628
628
|
if (Log.isOn && (Log.opt.read || ((_c = this.options.logging) === null || _c === void 0 ? void 0 : _c.read)))
|
|
629
|
-
Log.write("║", " x", `${this.hint()} is NOT subscribed to already obsolete ${Dump.snapshot2(h, ov.changeset, fk,
|
|
629
|
+
Log.write("║", " x", `${this.hint()} is NOT subscribed to already obsolete ${Dump.snapshot2(h, ov.changeset, fk, footprint)}`);
|
|
630
630
|
}
|
|
631
631
|
return ok;
|
|
632
632
|
}
|
|
633
|
-
static canSubscribeTo(
|
|
633
|
+
static canSubscribeTo(footprint, ov, parent, fk, h, timestamp) {
|
|
634
634
|
const parentSnapshot = parent ? parent.lookupObjectVersion(h, fk, false) : h.applied;
|
|
635
|
-
const
|
|
636
|
-
let result =
|
|
635
|
+
const parentFootprint = parentSnapshot.data[fk];
|
|
636
|
+
let result = footprint === parentFootprint || (!ov.changeset.sealed && ov.former.objectVersion.data[fk] === parentFootprint);
|
|
637
637
|
if (result && timestamp !== -1)
|
|
638
|
-
result = !(
|
|
638
|
+
result = !(footprint instanceof OperationFootprintImpl && timestamp >= footprint.obsoleteSince);
|
|
639
639
|
return result;
|
|
640
640
|
}
|
|
641
|
-
static
|
|
642
|
-
const
|
|
641
|
+
static createOperationDescriptor(h, fk, options) {
|
|
642
|
+
const ctl = new ReactiveOperationImpl(h, fk);
|
|
643
643
|
const operation = (...args) => {
|
|
644
|
-
return
|
|
644
|
+
return ctl.reuseOrRelaunch(false, args).result;
|
|
645
645
|
};
|
|
646
|
-
Meta.set(operation, Meta.
|
|
646
|
+
Meta.set(operation, Meta.Descriptor, ctl);
|
|
647
647
|
return operation;
|
|
648
648
|
}
|
|
649
649
|
static rememberOperationOptions(proto, fk, getter, setter, enumerable, configurable, options, implicit) {
|
|
650
650
|
const initial = Meta.acquire(proto, Meta.Initial);
|
|
651
|
-
let
|
|
652
|
-
const
|
|
653
|
-
const opts =
|
|
654
|
-
initial[fk] =
|
|
655
|
-
if (
|
|
651
|
+
let footprint = initial[fk];
|
|
652
|
+
const ctl = footprint ? footprint.descriptor : new ReactiveOperationImpl(EMPTY_HANDLE, fk);
|
|
653
|
+
const opts = footprint ? footprint.options : OptionsImpl.INITIAL;
|
|
654
|
+
initial[fk] = footprint = new OperationFootprintImpl(Transaction.current, ctl, EMPTY_OBJECT_VERSION.changeset, new OptionsImpl(getter, setter, opts, options, implicit), false);
|
|
655
|
+
if (footprint.options.kind === Kind.reactive && footprint.options.throttling < Number.MAX_SAFE_INTEGER) {
|
|
656
656
|
const reactive = Meta.acquire(proto, Meta.Reactive);
|
|
657
|
-
reactive[fk] =
|
|
657
|
+
reactive[fk] = footprint;
|
|
658
658
|
}
|
|
659
|
-
else if (
|
|
659
|
+
else if (footprint.options.kind === Kind.reactive && footprint.options.throttling >= Number.MAX_SAFE_INTEGER) {
|
|
660
660
|
const reactive = Meta.getFrom(proto, Meta.Reactive);
|
|
661
661
|
delete reactive[fk];
|
|
662
662
|
}
|
|
663
|
-
return
|
|
663
|
+
return footprint.options;
|
|
664
664
|
}
|
|
665
665
|
static init() {
|
|
666
666
|
Object.freeze(BOOT_ARGS);
|
|
667
667
|
Log.getMergedLoggingOptions = getMergedLoggingOptions;
|
|
668
668
|
Dump.valueHint = valueHint;
|
|
669
|
-
Changeset.markUsed =
|
|
670
|
-
Changeset.markEdited =
|
|
671
|
-
Changeset.tryResolveConflict =
|
|
672
|
-
Changeset.propagateAllChangesThroughSubscriptions =
|
|
673
|
-
Changeset.revokeAllSubscriptions =
|
|
674
|
-
Changeset.enqueueReactionsToRun =
|
|
675
|
-
TransactionImpl.
|
|
676
|
-
Mvcc.
|
|
677
|
-
Mvcc.rememberOperationOptions =
|
|
669
|
+
Changeset.markUsed = OperationFootprintImpl.markUsed;
|
|
670
|
+
Changeset.markEdited = OperationFootprintImpl.markEdited;
|
|
671
|
+
Changeset.tryResolveConflict = OperationFootprintImpl.tryResolveConflict;
|
|
672
|
+
Changeset.propagateAllChangesThroughSubscriptions = OperationFootprintImpl.propagateAllChangesThroughSubscriptions;
|
|
673
|
+
Changeset.revokeAllSubscriptions = OperationFootprintImpl.revokeAllSubscriptions;
|
|
674
|
+
Changeset.enqueueReactionsToRun = OperationFootprintImpl.enqueueReactionsToRun;
|
|
675
|
+
TransactionImpl.migrateContentFootprint = OperationFootprintImpl.migrateContentFootprint;
|
|
676
|
+
Mvcc.createOperationDescriptor = OperationFootprintImpl.createOperationDescriptor;
|
|
677
|
+
Mvcc.rememberOperationOptions = OperationFootprintImpl.rememberOperationOptions;
|
|
678
678
|
Promise.prototype.then = reactronicHookedThen;
|
|
679
679
|
try {
|
|
680
680
|
Object.defineProperty(globalThis, "rWhy", {
|
|
681
|
-
get:
|
|
681
|
+
get: ReactiveOperationImpl.why, configurable: false, enumerable: false,
|
|
682
682
|
});
|
|
683
683
|
Object.defineProperty(globalThis, "rBriefWhy", {
|
|
684
|
-
get:
|
|
684
|
+
get: ReactiveOperationImpl.briefWhy, configurable: false, enumerable: false,
|
|
685
685
|
});
|
|
686
686
|
}
|
|
687
687
|
catch (e) {
|
|
688
688
|
}
|
|
689
689
|
try {
|
|
690
690
|
Object.defineProperty(global, "rWhy", {
|
|
691
|
-
get:
|
|
691
|
+
get: ReactiveOperationImpl.why, configurable: false, enumerable: false,
|
|
692
692
|
});
|
|
693
693
|
Object.defineProperty(global, "rBriefWhy", {
|
|
694
|
-
get:
|
|
694
|
+
get: ReactiveOperationImpl.briefWhy, configurable: false, enumerable: false,
|
|
695
695
|
});
|
|
696
696
|
}
|
|
697
697
|
catch (e) {
|
|
698
698
|
}
|
|
699
699
|
}
|
|
700
700
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
701
|
+
OperationFootprintImpl.current = undefined;
|
|
702
|
+
OperationFootprintImpl.queuedReactions = [];
|
|
703
|
+
OperationFootprintImpl.deferredReactions = [];
|
|
704
704
|
function valueHint(value) {
|
|
705
705
|
let result = "";
|
|
706
706
|
if (Array.isArray(value))
|
|
@@ -709,8 +709,8 @@ function valueHint(value) {
|
|
|
709
709
|
result = `Set(${value.size})`;
|
|
710
710
|
else if (value instanceof Map)
|
|
711
711
|
result = `Map(${value.size})`;
|
|
712
|
-
else if (value instanceof
|
|
713
|
-
result = `#${value.
|
|
712
|
+
else if (value instanceof OperationFootprintImpl)
|
|
713
|
+
result = `#${value.descriptor.ownerHandle.id}t${value.changeset.id}s${value.changeset.timestamp}${value.lastEditorChangesetId !== undefined && value.lastEditorChangesetId !== 0 ? `t${value.lastEditorChangesetId}` : ""}`;
|
|
714
714
|
else if (value === Meta.Undefined)
|
|
715
715
|
result = "undefined";
|
|
716
716
|
else if (typeof (value) === "string")
|
|
@@ -725,8 +725,8 @@ function getMergedLoggingOptions(local) {
|
|
|
725
725
|
const t = Transaction.current;
|
|
726
726
|
let res = Log.merge(t.options.logging, t.id > 1 ? 31 + t.id % 6 : 37, t.id > 1 ? `T${t.id}` : `-${Changeset.idGen.toString().replace(/[0-9]/g, "-")}`, Log.global);
|
|
727
727
|
res = Log.merge({ margin1: t.margin }, undefined, undefined, res);
|
|
728
|
-
if (
|
|
729
|
-
res = Log.merge({ margin2:
|
|
728
|
+
if (OperationFootprintImpl.current)
|
|
729
|
+
res = Log.merge({ margin2: OperationFootprintImpl.current.margin }, undefined, undefined, res);
|
|
730
730
|
if (local)
|
|
731
731
|
res = Log.merge(local, undefined, undefined, res);
|
|
732
732
|
return res;
|
|
@@ -739,10 +739,10 @@ function reactronicHookedThen(resolve, reject) {
|
|
|
739
739
|
resolve = resolveReturn;
|
|
740
740
|
if (!reject)
|
|
741
741
|
reject = rejectRethrow;
|
|
742
|
-
const
|
|
743
|
-
if (
|
|
744
|
-
resolve =
|
|
745
|
-
reject =
|
|
742
|
+
const footprint = OperationFootprintImpl.current;
|
|
743
|
+
if (footprint) {
|
|
744
|
+
resolve = footprint.wrap(resolve);
|
|
745
|
+
reject = footprint.wrap(reject);
|
|
746
746
|
}
|
|
747
747
|
resolve = tran.wrapAsPending(resolve, false);
|
|
748
748
|
reject = tran.wrapAsPending(reject, true);
|
|
@@ -758,4 +758,4 @@ export function resolveReturn(value) {
|
|
|
758
758
|
export function rejectRethrow(error) {
|
|
759
759
|
throw error;
|
|
760
760
|
}
|
|
761
|
-
|
|
761
|
+
OperationFootprintImpl.init();
|