reactronic 0.24.275 → 0.24.302

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.
@@ -4,22 +4,23 @@ import { Sealant } from "../util/Sealant.js";
4
4
  import { SealedArray } from "../util/SealedArray.js";
5
5
  import { SealedMap } from "../util/SealedMap.js";
6
6
  import { SealedSet } from "../util/SealedSet.js";
7
- import { ObjectSnapshot, ObjectHandle, ValueSnapshot, Meta } from "./Data.js";
7
+ import { Isolation } from "../Options.js";
8
+ import { ObjectVersion, ObjectHandle, FieldVersion, Meta } from "./Data.js";
8
9
  export const MAX_REVISION = Number.MAX_SAFE_INTEGER;
9
10
  export const UNDEFINED_REVISION = MAX_REVISION - 1;
10
11
  Object.defineProperty(ObjectHandle.prototype, "#this#", {
11
12
  configurable: false, enumerable: false,
12
13
  get() {
13
14
  const result = {};
14
- const data = Changeset.current().getObjectSnapshot(this, "#this#").data;
15
- for (const m in data) {
16
- const v = data[m];
17
- if (v instanceof ValueSnapshot)
18
- result[m] = v.content;
15
+ const data = Changeset.current().getObjectVersion(this, "#this#").data;
16
+ for (const fk in data) {
17
+ const v = data[fk];
18
+ if (v instanceof FieldVersion)
19
+ result[fk] = v.content;
19
20
  else if (v === Meta.Raw)
20
- result[m] = this.data[m];
21
+ result[fk] = this.data[fk];
21
22
  else
22
- result[m] = v;
23
+ result[fk] = v;
23
24
  }
24
25
  return result;
25
26
  },
@@ -29,56 +30,83 @@ const EMPTY_MAP = Utils.freezeMap(new Map());
29
30
  export class Changeset {
30
31
  get hint() { var _a; return (_a = this.options.hint) !== null && _a !== void 0 ? _a : "noname"; }
31
32
  get timestamp() { return this.revision; }
32
- constructor(options) {
33
+ constructor(options, parent) {
33
34
  this.id = ++Changeset.idGen;
34
35
  this.options = options !== null && options !== void 0 ? options : DefaultSnapshotOptions;
36
+ this.parent = parent;
35
37
  this.revision = UNDEFINED_REVISION;
36
38
  this.bumper = 100;
37
39
  this.items = new Map();
38
40
  this.obsolete = [];
39
41
  this.sealed = false;
40
42
  }
41
- lookupObjectSnapshot(h, m) {
42
- let os = h.editing;
43
- if (os && os.changeset !== this) {
44
- os = this.items.get(h);
45
- if (os)
46
- h.editing = os;
43
+ lookupObjectVersion(h, fk, editing) {
44
+ let ov = h.editing;
45
+ if (ov && ov.changeset !== this) {
46
+ ov = this.items.get(h);
47
+ if (ov)
48
+ h.editing = ov;
47
49
  }
48
- if (!os) {
49
- os = h.head;
50
- while (os !== EMPTY_SNAPSHOT && os.changeset.timestamp > this.timestamp)
51
- os = os.former.snapshot;
50
+ const parent = this.parent;
51
+ if (!ov) {
52
+ if (!parent) {
53
+ ov = h.applied;
54
+ while (ov !== EMPTY_OBJECT_VERSION && ov.changeset.timestamp > this.timestamp)
55
+ ov = ov.former.objectVersion;
56
+ }
57
+ else
58
+ ov = parent.lookupObjectVersion(h, fk, editing);
52
59
  }
53
- return os;
60
+ else if (!editing && parent && !ov.changes.has(fk) && ov.former.objectVersion !== EMPTY_OBJECT_VERSION)
61
+ ov = parent.lookupObjectVersion(h, fk, editing);
62
+ return ov;
54
63
  }
55
- getObjectSnapshot(h, m) {
56
- const r = this.lookupObjectSnapshot(h, m);
57
- if (r === EMPTY_SNAPSHOT)
58
- throw misuse(`${Dump.obj(h, m)} is not yet available for T${this.id}[${this.hint}] because of uncommitted ${h.editing ? `T${h.editing.changeset.id}[${h.editing.changeset.hint}]` : ""} (last committed T${h.head.changeset.id}[${h.head.changeset.hint}])`);
64
+ getObjectVersion(h, fk) {
65
+ const r = this.lookupObjectVersion(h, fk, false);
66
+ if (r === EMPTY_OBJECT_VERSION)
67
+ throw misuse(`${Dump.obj(h, fk)} is not yet available for T${this.id}[${this.hint}] because ${h.editing ? `T${h.editing.changeset.id}[${h.editing.changeset.hint}]` : ""} is not yet applied (last applied T${h.applied.changeset.id}[${h.applied.changeset.hint}])`);
59
68
  return r;
60
69
  }
61
- getEditableObjectSnapshot(h, m, value, token) {
62
- let os = this.lookupObjectSnapshot(h, m);
63
- const existing = os.data[m];
70
+ getEditableObjectVersion(h, fk, value, token) {
71
+ let ov = this.lookupObjectVersion(h, fk, true);
72
+ const existing = ov.data[fk];
64
73
  if (existing !== Meta.Raw) {
65
- if (this.isNewSnapshotRequired(h, os, m, existing, value, token)) {
66
- this.bumpBy(os.changeset.timestamp);
67
- const revision = m === Meta.Handle ? 1 : os.revision + 1;
68
- const data = Object.assign({}, m === Meta.Handle ? value : os.data);
74
+ if (this.isNewObjectVersionRequired(h, ov, fk, existing, value, token)) {
75
+ this.bumpBy(ov.changeset.timestamp);
76
+ const revision = fk === Meta.Handle ? 1 : ov.revision + 1;
77
+ const data = Object.assign({}, fk === Meta.Handle ? value : ov.data);
69
78
  Meta.set(data, Meta.Handle, h);
70
- Meta.set(data, Meta.Revision, new ValueSnapshot(revision));
71
- os = new ObjectSnapshot(this, os, data);
72
- this.items.set(h, os);
73
- h.editing = os;
79
+ Meta.set(data, Meta.Revision, new FieldVersion(revision, this.id));
80
+ ov = new ObjectVersion(this, ov, data);
81
+ this.items.set(h, ov);
82
+ h.editing = ov;
74
83
  h.editors++;
75
84
  if (Log.isOn && Log.opt.write)
76
85
  Log.write("║", " ++", `${Dump.obj(h)} - new snapshot is created (revision ${revision})`);
77
86
  }
78
87
  }
79
88
  else
80
- os = EMPTY_SNAPSHOT;
81
- return os;
89
+ ov = EMPTY_OBJECT_VERSION;
90
+ return ov;
91
+ }
92
+ setFieldContent(h, fk, ov, content, receiver, sensitivity) {
93
+ let existing = ov.data[fk];
94
+ if (existing !== undefined || (ov.former.objectVersion.changeset === EMPTY_OBJECT_VERSION.changeset && (fk in h.data) === false)) {
95
+ if (existing === undefined || existing.content !== content || sensitivity) {
96
+ const existingContent = existing === null || existing === void 0 ? void 0 : existing.content;
97
+ if (ov.former.objectVersion.data[fk] === existing) {
98
+ existing = ov.data[fk] = new FieldVersion(content, this.id);
99
+ Changeset.markEdited(existingContent, content, true, ov, fk, h);
100
+ }
101
+ else {
102
+ existing.content = content;
103
+ existing.lastEditorChangesetId = this.id;
104
+ Changeset.markEdited(existingContent, content, true, ov, fk, h);
105
+ }
106
+ }
107
+ }
108
+ else
109
+ Reflect.set(h.data, fk, content, receiver);
82
110
  }
83
111
  static takeSnapshot(obj) {
84
112
  return obj[Meta.Handle]["#this#"];
@@ -90,25 +118,23 @@ export class Changeset {
90
118
  Changeset.doDispose(ctx, h);
91
119
  }
92
120
  static doDispose(ctx, h) {
93
- const os = ctx.getEditableObjectSnapshot(h, Meta.Revision, Meta.Undefined);
94
- if (os !== EMPTY_SNAPSHOT)
95
- os.disposed = true;
96
- return os;
121
+ const ov = ctx.getEditableObjectVersion(h, Meta.Revision, Meta.Undefined);
122
+ if (ov !== EMPTY_OBJECT_VERSION)
123
+ ov.disposed = true;
124
+ return ov;
97
125
  }
98
- isNewSnapshotRequired(h, os, m, existing, value, token) {
99
- if (this.sealed && os.changeset !== EMPTY_SNAPSHOT.changeset)
100
- throw misuse(`observable property ${Dump.obj(h, m)} can only be modified inside transaction`);
101
- if (m !== Meta.Handle) {
126
+ isNewObjectVersionRequired(h, ov, fk, existing, value, token) {
127
+ if (this.sealed && ov.changeset !== EMPTY_OBJECT_VERSION.changeset)
128
+ throw misuse(`observable property ${Dump.obj(h, fk)} can only be modified inside transaction`);
129
+ if (fk !== Meta.Handle) {
102
130
  if (value !== Meta.Handle) {
103
- if (os.changeset !== this || os.former.snapshot !== EMPTY_SNAPSHOT) {
131
+ if (ov.changeset !== this || ov.former.objectVersion !== EMPTY_OBJECT_VERSION) {
104
132
  if (this.options.token !== undefined && token !== this.options.token)
105
- throw misuse(`${this.hint} should not have side effects (trying to change ${Dump.snapshot(os, m)})`);
133
+ throw misuse(`${this.hint} should not have side effects (trying to change ${Dump.snapshot(ov, fk)})`);
106
134
  }
107
135
  }
108
- if (os === EMPTY_SNAPSHOT)
109
- throw misuse(`${Dump.snapshot(os, m)} is not yet available for T${this.id}[${this.hint}] because of uncommitted ${h.editing ? `T${h.editing.changeset.id}[${h.editing.changeset.hint}]` : ""} (last committed T${h.head.changeset.id}[${h.head.changeset.hint}])`);
110
136
  }
111
- return os.changeset !== this && !this.sealed;
137
+ return ov.changeset !== this && !this.sealed;
112
138
  }
113
139
  acquire(outer) {
114
140
  if (!this.sealed && this.revision === UNDEFINED_REVISION) {
@@ -128,16 +154,17 @@ export class Changeset {
128
154
  rebase() {
129
155
  let conflicts = undefined;
130
156
  if (this.items.size > 0) {
131
- this.items.forEach((os, h) => {
132
- if (os.former.snapshot !== h.head) {
133
- const merged = this.merge(h, os);
134
- if (os.conflicts.size > 0) {
157
+ this.items.forEach((ov, h) => {
158
+ const theirs = this.parent ? this.parent.lookupObjectVersion(h, Meta.Handle, false) : h.applied;
159
+ if (ov.former.objectVersion !== theirs) {
160
+ const merged = this.merge(h, ov, theirs);
161
+ if (ov.conflicts.size > 0) {
135
162
  if (!conflicts)
136
163
  conflicts = [];
137
- conflicts.push(os);
164
+ conflicts.push(ov);
138
165
  }
139
166
  if (Log.isOn && Log.opt.transaction)
140
- Log.write("╠╝", "", `${Dump.snapshot2(h, os.changeset)} is merged with ${Dump.snapshot2(h, h.head.changeset)} among ${merged} properties with ${os.conflicts.size} conflicts.`);
167
+ Log.write("╠╝", "", `${Dump.snapshot2(h, ov.changeset)} is merged with ${Dump.snapshot2(h, theirs.changeset)} among ${merged} properties with ${ov.conflicts.size} conflicts.`);
141
168
  }
142
169
  });
143
170
  if (this.options.token === undefined) {
@@ -154,92 +181,68 @@ export class Changeset {
154
181
  }
155
182
  return conflicts;
156
183
  }
157
- merge(h, ours) {
184
+ merge(h, ours, theirs) {
158
185
  let counter = 0;
159
- const head = h.head;
160
- const headDisposed = head.disposed;
186
+ const theirsDisposed = theirs.disposed;
161
187
  const oursDisposed = ours.disposed;
162
- const merged = Object.assign({}, head.data);
163
- ours.changes.forEach((o, m) => {
188
+ const merged = Object.assign({}, theirs.data);
189
+ ours.changes.forEach((o, fk) => {
164
190
  counter++;
165
- merged[m] = ours.data[m];
166
- if (headDisposed || oursDisposed) {
167
- if (headDisposed !== oursDisposed) {
168
- if (headDisposed || this.options.separation !== "disposal") {
191
+ const ourFieldVersion = ours.data[fk];
192
+ merged[fk] = ourFieldVersion;
193
+ if (theirsDisposed || oursDisposed) {
194
+ if (theirsDisposed !== oursDisposed) {
195
+ if (theirsDisposed || this.options.isolation !== Isolation.disjoinForInternalDisposal) {
169
196
  if (Log.isOn && Log.opt.change)
170
- Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, m)} <> ${Dump.snapshot2(h, head.changeset, m)}`, 0, " *** CONFLICT ***");
171
- ours.conflicts.set(m, head);
197
+ Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, fk)} <> ${Dump.snapshot2(h, theirs.changeset, fk)}`, 0, " *** CONFLICT ***");
198
+ ours.conflicts.set(fk, theirs);
172
199
  }
173
200
  }
174
201
  }
175
202
  else {
176
- const conflict = Changeset.isConflicting(head.data[m], ours.former.snapshot.data[m]);
203
+ const conflict = Changeset.isConflicting(theirs.data[fk], ours.former.objectVersion.data[fk]);
177
204
  if (conflict)
178
- ours.conflicts.set(m, head);
205
+ ours.conflicts.set(fk, theirs);
179
206
  if (Log.isOn && Log.opt.change)
180
- Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, m)} ${conflict ? "<>" : "=="} ${Dump.snapshot2(h, head.changeset, m)}`, 0, conflict ? " *** CONFLICT ***" : undefined);
207
+ Log.write("║╠", "", `${Dump.snapshot2(h, ours.changeset, fk)} ${conflict ? "<>" : "=="} ${Dump.snapshot2(h, theirs.changeset, fk)}`, 0, conflict ? " *** CONFLICT ***" : undefined);
181
208
  }
182
209
  });
183
210
  Utils.copyAllMembers(merged, ours.data);
184
- ours.former.snapshot = head;
211
+ ours.former.objectVersion = theirs;
185
212
  return counter;
186
213
  }
187
- applyOrDiscard(error) {
214
+ seal() {
188
215
  this.sealed = true;
189
- this.items.forEach((os, h) => {
190
- Changeset.sealObjectSnapshot(h, os);
191
- h.editors--;
192
- if (h.editors === 0)
193
- h.editing = undefined;
194
- if (!error) {
195
- h.head = os;
196
- if (Changeset.garbageCollectionSummaryInterval < Number.MAX_SAFE_INTEGER) {
197
- Changeset.totalObjectSnapshotCount++;
198
- if (os.former.snapshot === EMPTY_SNAPSHOT)
199
- Changeset.totalObjectHandleCount++;
200
- }
201
- }
202
- });
203
- if (Log.isOn) {
204
- if (Log.opt.change && !error) {
205
- this.items.forEach((os, h) => {
206
- const members = [];
207
- os.changes.forEach((o, m) => members.push(m.toString()));
208
- const s = members.join(", ");
209
- Log.write("║", "√", `${Dump.snapshot2(h, os.changeset)} (${s}) is ${os.former.snapshot === EMPTY_SNAPSHOT ? "constructed" : `applied over #${h.id}t${os.former.snapshot.changeset.id}s${os.former.snapshot.changeset.timestamp}`}`);
210
- });
211
- }
212
- if (Log.opt.transaction)
213
- Log.write(this.revision < UNDEFINED_REVISION ? "╚══" : "═══", `s${this.revision}`, `${this.hint} - ${error ? "CANCEL" : "APPLY"}(${this.items.size})${error ? ` - ${error}` : ""}`);
214
- }
215
- if (!error)
216
- Changeset.propagateAllChangesThroughSubscriptions(this);
217
- return this.obsolete;
218
216
  }
219
- static sealObjectSnapshot(h, os) {
220
- if (!os.disposed)
221
- os.changes.forEach((o, m) => Changeset.sealValueSnapshot(os.data[m], m, h.proxy.constructor.name));
222
- else
223
- for (const m in os.former.snapshot.data)
224
- os.data[m] = Meta.Undefined;
225
- if (Log.isOn)
226
- Changeset.freezeObjectSnapshot(os);
217
+ sealObjectVersion(h, ov) {
218
+ if (!this.parent) {
219
+ if (!ov.disposed)
220
+ ov.changes.forEach((o, fk) => Changeset.sealFieldVersion(ov.data[fk], fk, h.proxy.constructor.name));
221
+ else
222
+ for (const fk in ov.former.objectVersion.data)
223
+ ov.data[fk] = Meta.Undefined;
224
+ if (Log.isOn)
225
+ Changeset.freezeObjectVersion(ov);
226
+ }
227
+ h.editors--;
228
+ if (h.editors === 0)
229
+ h.editing = undefined;
227
230
  }
228
- static sealValueSnapshot(o, m, typeName) {
229
- if (o instanceof ValueSnapshot) {
230
- const value = o.content;
231
- if (value !== undefined && value !== null) {
232
- const sealedType = Object.getPrototypeOf(value)[Sealant.SealedType];
231
+ static sealFieldVersion(fv, fk, typeName) {
232
+ if (fv instanceof FieldVersion) {
233
+ const content = fv.content;
234
+ if (content !== undefined && content !== null) {
235
+ const sealedType = Object.getPrototypeOf(content)[Sealant.SealedType];
233
236
  if (sealedType)
234
- o.content = Sealant.seal(value, sealedType, typeName, m);
237
+ fv.content = Sealant.seal(content, sealedType, typeName, fk);
235
238
  }
236
239
  }
237
240
  }
238
- static freezeObjectSnapshot(os) {
239
- Object.freeze(os.data);
240
- Utils.freezeSet(os.changes);
241
- Utils.freezeMap(os.conflicts);
242
- return os;
241
+ static freezeObjectVersion(ov) {
242
+ Object.freeze(ov.data);
243
+ Utils.freezeSet(ov.changes);
244
+ Utils.freezeMap(ov.conflicts);
245
+ return ov;
243
246
  }
244
247
  triggerGarbageCollection() {
245
248
  if (this.revision !== 0) {
@@ -264,16 +267,16 @@ export class Changeset {
264
267
  unlinkHistory() {
265
268
  if (Log.isOn && Log.opt.gc)
266
269
  Log.write("", "[G]", `Dismiss history below t${this.id}s${this.revision} (${this.hint})`);
267
- this.items.forEach((os, h) => {
268
- if (Log.isOn && Log.opt.gc && os.former.snapshot !== EMPTY_SNAPSHOT)
269
- Log.write(" ", " ", `${Dump.snapshot2(h, os.former.snapshot.changeset)} is ready for GC because overwritten by ${Dump.snapshot2(h, os.changeset)}`);
270
+ this.items.forEach((ov, h) => {
271
+ if (Log.isOn && Log.opt.gc && ov.former.objectVersion !== EMPTY_OBJECT_VERSION)
272
+ Log.write(" ", " ", `${Dump.snapshot2(h, ov.former.objectVersion.changeset)} is ready for GC because overwritten by ${Dump.snapshot2(h, ov.changeset)}`);
270
273
  if (Changeset.garbageCollectionSummaryInterval < Number.MAX_SAFE_INTEGER) {
271
- if (os.former.snapshot !== EMPTY_SNAPSHOT)
274
+ if (ov.former.objectVersion !== EMPTY_OBJECT_VERSION)
272
275
  Changeset.totalObjectSnapshotCount--;
273
- if (os.disposed)
276
+ if (ov.disposed)
274
277
  Changeset.totalObjectHandleCount--;
275
278
  }
276
- os.former.snapshot = EMPTY_SNAPSHOT;
279
+ ov.former.objectVersion = EMPTY_OBJECT_VERSION;
277
280
  });
278
281
  this.items = EMPTY_MAP;
279
282
  this.obsolete = EMPTY_ARRAY;
@@ -281,11 +284,11 @@ export class Changeset {
281
284
  Object.freeze(this);
282
285
  }
283
286
  static _init() {
284
- const boot = EMPTY_SNAPSHOT.changeset;
287
+ const boot = EMPTY_OBJECT_VERSION.changeset;
285
288
  boot.acquire(boot);
286
- boot.applyOrDiscard();
289
+ boot.seal();
287
290
  boot.triggerGarbageCollection();
288
- Changeset.freezeObjectSnapshot(EMPTY_SNAPSHOT);
291
+ Changeset.freezeObjectVersion(EMPTY_OBJECT_VERSION);
289
292
  Changeset.idGen = 100;
290
293
  Changeset.stampGen = 101;
291
294
  Changeset.oldest = undefined;
@@ -311,47 +314,47 @@ Changeset.propagateAllChangesThroughSubscriptions = (changeset) => { };
311
314
  Changeset.revokeAllSubscriptions = (changeset) => { };
312
315
  Changeset.enqueueReactiveFunctionsToRun = (reactive) => { };
313
316
  export class Dump {
314
- static obj(h, m, stamp, snapshotId, originSnapshotId, value) {
315
- const member = m !== undefined ? `.${m.toString()}` : "";
317
+ static obj(h, fk, stamp, changesetId, lastEditorChangesetId, value) {
318
+ const member = fk !== undefined ? `.${fk.toString()}` : "";
316
319
  let result;
317
320
  if (h !== undefined) {
318
321
  const v = value !== undefined && value !== Meta.Undefined ? `[=${Dump.valueHint(value)}]` : "";
319
322
  if (stamp === undefined)
320
323
  result = `${h.hint}${member}${v} #${h.id}`;
321
324
  else
322
- result = `${h.hint}${member}${v} #${h.id}t${snapshotId}s${stamp}${originSnapshotId !== undefined && originSnapshotId !== 0 ? `t${originSnapshotId}` : ""}`;
325
+ result = `${h.hint}${member}${v} #${h.id}t${changesetId}s${stamp}${lastEditorChangesetId !== undefined ? `e${lastEditorChangesetId}` : ""}`;
323
326
  }
324
327
  else
325
328
  result = `boot${member}`;
326
329
  return result;
327
330
  }
328
- static snapshot2(h, s, m, o) {
331
+ static snapshot2(h, s, fk, o) {
329
332
  var _a;
330
- return Dump.obj(h, m, s.timestamp, s.id, o === null || o === void 0 ? void 0 : o.originSnapshotId, (_a = o === null || o === void 0 ? void 0 : o.content) !== null && _a !== void 0 ? _a : Meta.Undefined);
333
+ return Dump.obj(h, fk, s.timestamp, s.id, o === null || o === void 0 ? void 0 : o.lastEditorChangesetId, (_a = o === null || o === void 0 ? void 0 : o.content) !== null && _a !== void 0 ? _a : Meta.Undefined);
331
334
  }
332
- static snapshot(os, m) {
333
- const h = Meta.get(os.data, Meta.Handle);
334
- const value = m !== undefined ? os.data[m] : undefined;
335
- return Dump.obj(h, m, os.changeset.timestamp, os.changeset.id, value === null || value === void 0 ? void 0 : value.originSnapshotId);
335
+ static snapshot(ov, fk) {
336
+ const h = Meta.get(ov.data, Meta.Handle);
337
+ const fv = fk !== undefined ? ov.data[fk] : undefined;
338
+ return Dump.obj(h, fk, ov.changeset.timestamp, ov.changeset.id, fv === null || fv === void 0 ? void 0 : fv.lastEditorChangesetId);
336
339
  }
337
340
  static conflicts(conflicts) {
338
341
  return conflicts.map(ours => {
339
342
  const items = [];
340
- ours.conflicts.forEach((theirs, m) => {
341
- items.push(Dump.conflictingMemberHint(m, ours, theirs));
343
+ ours.conflicts.forEach((theirs, fk) => {
344
+ items.push(Dump.conflictingMemberHint(fk, ours, theirs));
342
345
  });
343
346
  return items.join(", ");
344
347
  }).join(", ");
345
348
  }
346
- static conflictingMemberHint(m, ours, theirs) {
347
- return `${theirs.changeset.hint} (${Dump.snapshot(theirs, m)})`;
349
+ static conflictingMemberHint(fk, ours, theirs) {
350
+ return `${theirs.changeset.hint} (${Dump.snapshot(theirs, fk)})`;
348
351
  }
349
352
  }
350
353
  Dump.valueHint = (value) => "???";
351
- export const EMPTY_SNAPSHOT = new ObjectSnapshot(new Changeset({ hint: "<boot>" }), undefined, {});
354
+ export const EMPTY_OBJECT_VERSION = new ObjectVersion(new Changeset({ hint: "<boot>" }), undefined, {});
352
355
  export const DefaultSnapshotOptions = Object.freeze({
353
356
  hint: "noname",
354
- separation: false,
357
+ isolation: Isolation.joinToCurrentTransaction,
355
358
  journal: undefined,
356
359
  logging: undefined,
357
360
  token: undefined,
@@ -5,36 +5,35 @@ export type AbstractChangeset = {
5
5
  readonly timestamp: number;
6
6
  readonly sealed: boolean;
7
7
  };
8
- export declare class ValueSnapshot<T = any> {
8
+ export declare class FieldVersion<T = any> {
9
9
  content: T;
10
10
  observers?: Set<Observer>;
11
- get isOperation(): boolean;
12
- get originSnapshotId(): number | undefined;
13
- constructor(content: T);
11
+ lastEditorChangesetId: number;
12
+ get isLaunch(): boolean;
13
+ constructor(content: T, lastEditorChangesetId: number);
14
14
  }
15
- export type SeparationMode = boolean | "isolated" | "disposal";
16
15
  export type Observer = {
17
16
  readonly order: number;
18
- readonly observables: Map<ValueSnapshot, Subscription> | undefined;
17
+ readonly observables: Map<FieldVersion, Subscription> | undefined;
19
18
  readonly obsoleteSince: number;
20
19
  hint(nop?: boolean): string;
21
- markObsoleteDueTo(observable: ValueSnapshot, m: MemberName, changeset: AbstractChangeset, h: ObjectHandle, outer: string, since: number, reactive: Array<Observer>): void;
20
+ markObsoleteDueTo(observable: FieldVersion, fk: FieldKey, changeset: AbstractChangeset, h: ObjectHandle, outer: string, since: number, reactive: Array<Observer>): void;
22
21
  relaunchIfNotUpToDate(now: boolean, nothrow: boolean): void;
23
22
  };
24
- export type MemberName = PropertyKey;
23
+ export type FieldKey = PropertyKey;
25
24
  export type Subscription = {
26
25
  readonly memberHint: string;
27
26
  readonly usageCount: number;
28
27
  };
29
- export declare class ObjectSnapshot {
28
+ export declare class ObjectVersion {
30
29
  readonly changeset: AbstractChangeset;
31
30
  readonly former: {
32
- snapshot: ObjectSnapshot;
31
+ objectVersion: ObjectVersion;
33
32
  };
34
33
  readonly data: any;
35
- readonly changes: Set<MemberName>;
36
- readonly conflicts: Map<MemberName, ObjectSnapshot>;
37
- constructor(changeset: AbstractChangeset, former: ObjectSnapshot | undefined, data: object);
34
+ readonly changes: Set<FieldKey>;
35
+ readonly conflicts: Map<FieldKey, ObjectVersion>;
36
+ constructor(changeset: AbstractChangeset, former: ObjectVersion | undefined, data: object);
38
37
  get revision(): number;
39
38
  get disposed(): boolean;
40
39
  set disposed(value: boolean);
@@ -44,17 +43,17 @@ export declare class ObjectHandle {
44
43
  readonly id: number;
45
44
  readonly data: any;
46
45
  readonly proxy: any;
47
- head: ObjectSnapshot;
48
- editing?: ObjectSnapshot;
46
+ applied: ObjectVersion;
47
+ editing?: ObjectVersion;
49
48
  editors: number;
50
49
  hint: string;
51
- constructor(data: any, proxy: any, handler: ProxyHandler<ObjectHandle>, head: ObjectSnapshot, hint: string);
50
+ constructor(data: any, proxy: any, handler: ProxyHandler<ObjectHandle>, applied: ObjectVersion, hint: string);
52
51
  static getHint(obj: object, full: boolean): string | undefined;
53
52
  }
54
- export type PatchSet = Map<object, Map<MemberName, ValuePatch>>;
53
+ export type PatchSet = Map<object, Map<FieldKey, ValuePatch>>;
55
54
  export type ValuePatch = {
56
- memberName: MemberName;
55
+ fieldKey: FieldKey;
57
56
  patchKind: "update" | "add" | "remove";
58
- freshValue: any;
59
- formerValue: any;
57
+ freshContent: any;
58
+ formerContent: any;
60
59
  };
@@ -1,15 +1,14 @@
1
1
  import { Log } from "../util/Dbg.js";
2
2
  import { Meta } from "./Meta.js";
3
3
  export { Meta } from "./Meta.js";
4
- export class ValueSnapshot {
5
- get isOperation() { return false; }
6
- get originSnapshotId() { return 0; }
7
- constructor(content) { this.content = content; }
4
+ export class FieldVersion {
5
+ get isLaunch() { return false; }
6
+ constructor(content, lastEditorChangesetId) { this.content = content; this.lastEditorChangesetId = lastEditorChangesetId; }
8
7
  }
9
- export class ObjectSnapshot {
8
+ export class ObjectVersion {
10
9
  constructor(changeset, former, data) {
11
10
  this.changeset = changeset;
12
- this.former = { snapshot: former || this };
11
+ this.former = { objectVersion: former || this };
13
12
  this.data = data;
14
13
  this.changes = new Set();
15
14
  this.conflicts = new Map();
@@ -17,7 +16,8 @@ export class ObjectSnapshot {
17
16
  Object.freeze(this);
18
17
  }
19
18
  get revision() {
20
- return this.data[Meta.Revision].content;
19
+ var _a, _b;
20
+ return (_b = (_a = this.data[Meta.Revision]) === null || _a === void 0 ? void 0 : _a.content) !== null && _b !== void 0 ? _b : 0;
21
21
  }
22
22
  get disposed() { return this.revision < 0; }
23
23
  set disposed(value) {
@@ -27,11 +27,11 @@ export class ObjectSnapshot {
27
27
  }
28
28
  }
29
29
  export class ObjectHandle {
30
- constructor(data, proxy, handler, head, hint) {
30
+ constructor(data, proxy, handler, applied, hint) {
31
31
  this.id = ++ObjectHandle.generator;
32
32
  this.data = data;
33
33
  this.proxy = proxy || new Proxy(this, handler);
34
- this.head = head;
34
+ this.applied = applied;
35
35
  this.editing = undefined;
36
36
  this.editors = 0;
37
37
  this.hint = hint;
@@ -16,9 +16,9 @@ export declare class IndicatorImpl extends Indicator {
16
16
  busyDuration: number;
17
17
  readonly internals: {
18
18
  whenBusy: Promise<void> | undefined;
19
- resolveWhenBusy: ((value?: void | undefined) => void) | undefined;
19
+ resolveWhenBusy: ((value?: void) => void) | undefined;
20
20
  whenIdle: Promise<void> | undefined;
21
- resolveWhenIdle: ((value?: void | undefined) => void) | undefined;
21
+ resolveWhenIdle: ((value?: void) => void) | undefined;
22
22
  started: number;
23
23
  activationDelay: number;
24
24
  activationTimeout: undefined;
@@ -7,6 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { Isolation } from "../Options.js";
10
11
  import { ObservableObject, Mvcc } from "./Mvcc.js";
11
12
  import { Transaction } from "./Transaction.js";
12
13
  export class Indicator extends ObservableObject {
@@ -80,12 +81,12 @@ export class IndicatorImpl extends Indicator {
80
81
  mon.leave(worker);
81
82
  }
82
83
  static doCreate(hint, activationDelay, deactivationDelay, durationResolution) {
83
- const m = new IndicatorImpl();
84
- Mvcc.setHint(m, hint);
85
- m.internals.activationDelay = activationDelay;
86
- m.internals.deactivationDelay = deactivationDelay;
87
- m.internals.durationResolution = durationResolution;
88
- return m;
84
+ const ind = new IndicatorImpl();
85
+ Mvcc.setHint(ind, hint);
86
+ ind.internals.activationDelay = activationDelay;
87
+ ind.internals.deactivationDelay = deactivationDelay;
88
+ ind.internals.durationResolution = durationResolution;
89
+ return ind;
89
90
  }
90
91
  static activate(mon, delay) {
91
92
  const active = mon.counter > 0;
@@ -102,7 +103,7 @@ export class IndicatorImpl extends Indicator {
102
103
  }
103
104
  if (delay >= 0) {
104
105
  if (mon.internals.activationTimeout === undefined)
105
- mon.internals.activationTimeout = setTimeout(() => Transaction.run({ hint: "Indicator.activate", separation: "isolated" }, IndicatorImpl.activate, mon, -1), delay);
106
+ mon.internals.activationTimeout = setTimeout(() => Transaction.run({ hint: "Indicator.activate", isolation: Isolation.disjoinFromOuterAndInnerTransactions }, IndicatorImpl.activate, mon, -1), delay);
106
107
  }
107
108
  else if (active)
108
109
  mon.isBusy = true;
@@ -110,7 +111,7 @@ export class IndicatorImpl extends Indicator {
110
111
  static deactivate(mon, delay) {
111
112
  if (delay >= 0) {
112
113
  clearTimeout(mon.internals.deactivationTimeout);
113
- mon.internals.deactivationTimeout = setTimeout(() => Transaction.run({ hint: "Indicator.deactivate", separation: "isolated" }, IndicatorImpl.deactivate, mon, -1), delay);
114
+ mon.internals.deactivationTimeout = setTimeout(() => Transaction.run({ hint: "Indicator.deactivate", isolation: Isolation.disjoinFromOuterAndInnerTransactions }, IndicatorImpl.deactivate, mon, -1), delay);
114
115
  }
115
116
  else if (mon.counter <= 0) {
116
117
  mon.isBusy = false;
@@ -1,5 +1,5 @@
1
1
  import { ObservableObject } from "./Mvcc.js";
2
- import { ObjectHandle, ObjectSnapshot, PatchSet } from "./Data.js";
2
+ import { ObjectHandle, ObjectVersion, PatchSet } from "./Data.js";
3
3
  export type Saver = (patch: PatchSet) => Promise<void>;
4
4
  export declare abstract class Journal extends ObservableObject {
5
5
  abstract capacity: number;
@@ -28,7 +28,7 @@ export declare class JournalImpl extends Journal {
28
28
  saved(patch: PatchSet): void;
29
29
  undo(count?: number): void;
30
30
  redo(count?: number): void;
31
- static buildPatch(hint: string, items: Map<ObjectHandle, ObjectSnapshot>): PatchSet;
31
+ static buildPatch(hint: string, items: Map<ObjectHandle, ObjectVersion>): PatchSet;
32
32
  static applyPatch(patch: PatchSet, undoing: boolean): void;
33
33
  mergePatchToUnsaved(patch: PatchSet, undoing: boolean): void;
34
34
  }