reactronic 0.22.302 → 0.22.303

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.
@@ -1,13 +1,42 @@
1
1
  import { F } from '../util/Utils';
2
2
  import { MemberOptions, Kind, Reentrance } from '../Options';
3
3
  import { LoggingOptions, ProfilingOptions } from '../Logging';
4
- import { MemberName, DataHolder, StandaloneMode } from './Data';
4
+ import { MemberName, ObjectHandle, StandaloneMode } from './Data';
5
5
  import { Journal } from './Journal';
6
6
  import { Monitor } from './Monitor';
7
7
  export declare abstract class ReactiveObject {
8
8
  constructor();
9
9
  [Symbol.toStringTag](): string;
10
10
  }
11
+ export declare class ReactiveArray<T> extends ReactiveObject {
12
+ private a;
13
+ get length(): number;
14
+ set length(n: number);
15
+ get(n: number): T;
16
+ set(n: number, item: T): void;
17
+ toString(): string;
18
+ toLocaleString(): string;
19
+ pop(): T | undefined;
20
+ push(...items: T[]): number;
21
+ concat(...items: (T | ConcatArray<T>)[]): T[];
22
+ join(separator?: string): string;
23
+ reverse(): T[];
24
+ shift(): T | undefined;
25
+ slice(start?: number, end?: number): T[];
26
+ sort(compareFn?: (a: T, b: T) => number): this;
27
+ splice(start: number, deleteCount?: number): T[];
28
+ unshift(...items: T[]): number;
29
+ indexOf(searchElement: T, fromIndex?: number): number;
30
+ lastIndexOf(searchElement: T, fromIndex?: number): number;
31
+ every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
32
+ some(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
33
+ forEach(callbackfn: (value: T, index: number, array: T[]) => void, thisArg?: any): void;
34
+ map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
35
+ filter(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[];
36
+ reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
37
+ reduceRight(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;
38
+ private get mutable();
39
+ }
11
40
  export declare class OptionsImpl implements MemberOptions {
12
41
  readonly getter: Function;
13
42
  readonly setter: Function;
@@ -24,27 +53,27 @@ export declare class OptionsImpl implements MemberOptions {
24
53
  static readonly INITIAL: Readonly<OptionsImpl>;
25
54
  constructor(getter: Function | undefined, setter: Function | undefined, existing: OptionsImpl, patch: Partial<OptionsImpl>, implicit: boolean);
26
55
  }
27
- export declare class Hooks implements ProxyHandler<DataHolder> {
56
+ export declare class Hooks implements ProxyHandler<ObjectHandle> {
28
57
  static reactionsAutoStartDisabled: boolean;
29
58
  static repetitiveUsageWarningThreshold: number;
30
59
  static mainThreadBlockingWarningThreshold: number;
31
60
  static asyncActionDurationWarningThreshold: number;
32
61
  static sensitivity: boolean;
33
- static readonly proxy: Hooks;
34
- getPrototypeOf(h: DataHolder): object | null;
35
- get(h: DataHolder, m: MemberName, receiver: any): any;
36
- set(h: DataHolder, m: MemberName, value: any, receiver: any): boolean;
37
- has(h: DataHolder, m: MemberName): boolean;
38
- getOwnPropertyDescriptor(h: DataHolder, m: MemberName): PropertyDescriptor | undefined;
39
- ownKeys(h: DataHolder): Array<string | symbol>;
62
+ static readonly handler: Hooks;
63
+ getPrototypeOf(h: ObjectHandle): object | null;
64
+ get(h: ObjectHandle, m: MemberName, receiver: any): any;
65
+ set(h: ObjectHandle, m: MemberName, value: any, receiver: any): boolean;
66
+ has(h: ObjectHandle, m: MemberName): boolean;
67
+ getOwnPropertyDescriptor(h: ObjectHandle, m: MemberName): PropertyDescriptor | undefined;
68
+ ownKeys(h: ObjectHandle): Array<string | symbol>;
40
69
  static decorateData(reactive: boolean, proto: any, m: MemberName): any;
41
70
  static decorateOperation(implicit: boolean, decorator: Function, options: Partial<MemberOptions>, proto: any, member: MemberName, pd: PropertyDescriptor | undefined): any;
42
71
  static decorateOperationParametrized(decorator: Function, options: Partial<MemberOptions>): F<any>;
43
- static acquireDataHolder(obj: any): DataHolder;
44
- static createDataHolderForReactiveObject(proto: any, data: any, blank: any, hint: string): DataHolder;
72
+ static acquireHandle(obj: any): ObjectHandle;
73
+ static createHandleForReactiveObject(proto: any, data: any, blank: any, hint: string): ObjectHandle;
45
74
  static setProfilingMode(isOn: boolean, options?: Partial<ProfilingOptions>): void;
46
75
  static sensitive<T>(sensitivity: boolean, func: F<T>, ...args: any[]): T;
47
76
  static setHint<T>(obj: T, hint: string | undefined): T;
48
- static createOperation: (h: DataHolder, m: MemberName, options: OptionsImpl) => F<any>;
77
+ static createOperation: (h: ObjectHandle, m: MemberName, options: OptionsImpl) => F<any>;
49
78
  static rememberOperationOptions: (proto: any, m: MemberName, getter: Function | undefined, setter: Function | undefined, enumerable: boolean, configurable: boolean, options: Partial<MemberOptions>, implicit: boolean) => OptionsImpl;
50
79
  }
@@ -1,24 +1,63 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Hooks = exports.OptionsImpl = exports.ReactiveObject = void 0;
3
+ exports.Hooks = exports.OptionsImpl = exports.ReactiveArray = exports.ReactiveObject = void 0;
4
4
  const Utils_1 = require("../util/Utils");
5
+ const Sealant_1 = require("../util/Sealant");
5
6
  const Dbg_1 = require("../util/Dbg");
6
7
  const Options_1 = require("../Options");
7
8
  const Data_1 = require("./Data");
8
- const Snapshot_1 = require("./Snapshot");
9
+ const Changeset_1 = require("./Changeset");
9
10
  class ReactiveObject {
10
11
  constructor() {
11
12
  const proto = new.target.prototype;
12
13
  const initial = Data_1.Meta.getFrom(proto, Data_1.Meta.Initial);
13
- const h = Hooks.createDataHolderForReactiveObject(proto, this, initial, new.target.name);
14
+ const h = Hooks.createHandleForReactiveObject(proto, this, initial, new.target.name);
14
15
  return h.proxy;
15
16
  }
16
17
  [Symbol.toStringTag]() {
17
- const h = Data_1.Meta.get(this, Data_1.Meta.Holder);
18
- return Snapshot_1.Dump.obj(h);
18
+ const h = Data_1.Meta.get(this, Data_1.Meta.Handle);
19
+ return Changeset_1.Dump.obj(h);
19
20
  }
20
21
  }
21
22
  exports.ReactiveObject = ReactiveObject;
23
+ class ReactiveArray extends ReactiveObject {
24
+ constructor() {
25
+ super(...arguments);
26
+ this.a = new Array();
27
+ }
28
+ get length() { return this.a.length; }
29
+ set length(n) { this.a.length = n; }
30
+ get(n) { return this.a[n]; }
31
+ set(n, item) { this.mutable[n] = item; }
32
+ toString() { return this.a.toString(); }
33
+ toLocaleString() { return this.a.toLocaleString(); }
34
+ pop() { return this.mutable.pop(); }
35
+ push(...items) { return this.mutable.push(...items); }
36
+ concat(...items) { return this.a.concat(...items); }
37
+ join(separator) { return this.a.join(separator); }
38
+ reverse() { return this.mutable.reverse(); }
39
+ shift() { return this.mutable.shift(); }
40
+ slice(start, end) { return this.a.slice(start, end); }
41
+ sort(compareFn) { this.mutable.sort(compareFn); return this; }
42
+ splice(start, deleteCount, ...items) { return this.mutable.splice(start, deleteCount, ...items); }
43
+ unshift(...items) { return this.mutable.unshift(...items); }
44
+ indexOf(searchElement, fromIndex) { return this.a.indexOf(searchElement, fromIndex); }
45
+ lastIndexOf(searchElement, fromIndex) { return this.a.lastIndexOf(searchElement, fromIndex); }
46
+ every(predicate, thisArg) { return this.a.every(predicate, thisArg); }
47
+ some(predicate, thisArg) { return this.a.some(predicate, thisArg); }
48
+ forEach(callbackfn, thisArg) { return this.a.forEach(callbackfn, thisArg); }
49
+ map(callbackfn, thisArg) { return this.a.map(callbackfn, thisArg); }
50
+ filter(predicate, thisArg) { return this.a.filter(predicate, thisArg); }
51
+ reduce(callbackfn, initialValue) { return this.a.reduce(callbackfn, initialValue); }
52
+ reduceRight(callbackfn, initialValue) { return this.a.reduceRight(callbackfn, initialValue); }
53
+ get mutable() {
54
+ const createCopy = this.a[Sealant_1.Sealant.CreateCopy];
55
+ if (createCopy)
56
+ return this.a = createCopy.call(this.a);
57
+ return this.a;
58
+ }
59
+ }
60
+ exports.ReactiveArray = ReactiveArray;
22
61
  const DEFAULT_OPTIONS = Object.freeze({
23
62
  kind: Options_1.Kind.Plain,
24
63
  standalone: false,
@@ -60,32 +99,32 @@ class Hooks {
60
99
  }
61
100
  get(h, m, receiver) {
62
101
  let result;
63
- const r = Snapshot_1.Snapshot.current().getCurrentRevision(h, m);
64
- result = r.data[m];
102
+ const os = Changeset_1.Changeset.current().getRelevantSnapshot(h, m);
103
+ result = os.data[m];
65
104
  if (result instanceof Data_1.Subscription && !result.isOperation) {
66
- Snapshot_1.Snapshot.markUsed(result, r, m, h, Options_1.Kind.Plain, false);
105
+ Changeset_1.Changeset.markUsed(result, os, m, h, Options_1.Kind.Plain, false);
67
106
  result = result.content;
68
107
  }
69
- else if (m === Data_1.Meta.Holder) {
108
+ else if (m === Data_1.Meta.Handle) {
70
109
  }
71
110
  else
72
111
  result = Reflect.get(h.data, m, receiver);
73
112
  return result;
74
113
  }
75
114
  set(h, m, value, receiver) {
76
- const r = Snapshot_1.Snapshot.edit().getEditableRevision(h, m, value);
77
- if (r !== Snapshot_1.ROOT_REV) {
78
- let curr = r.data[m];
79
- if (curr !== undefined || (r.former.revision.snapshot === Snapshot_1.ROOT_REV.snapshot && (m in h.data) === false)) {
115
+ const os = Changeset_1.Changeset.edit().getEditableSnapshot(h, m, value);
116
+ if (os !== Changeset_1.EMPTY_SNAPSHOT) {
117
+ let curr = os.data[m];
118
+ if (curr !== undefined || (os.former.snapshot.changeset === Changeset_1.EMPTY_SNAPSHOT.changeset && (m in h.data) === false)) {
80
119
  if (curr === undefined || curr.content !== value || Hooks.sensitivity) {
81
120
  const existing = curr === null || curr === void 0 ? void 0 : curr.content;
82
- if (r.former.revision.data[m] === curr) {
83
- curr = r.data[m] = new Data_1.Subscription(value);
84
- Snapshot_1.Snapshot.markEdited(existing, value, true, r, m, h);
121
+ if (os.former.snapshot.data[m] === curr) {
122
+ curr = os.data[m] = new Data_1.Subscription(value);
123
+ Changeset_1.Changeset.markEdited(existing, value, true, os, m, h);
85
124
  }
86
125
  else {
87
126
  curr.content = value;
88
- Snapshot_1.Snapshot.markEdited(existing, value, true, r, m, h);
127
+ Changeset_1.Changeset.markEdited(existing, value, true, os, m, h);
89
128
  }
90
129
  }
91
130
  }
@@ -97,21 +136,21 @@ class Hooks {
97
136
  return true;
98
137
  }
99
138
  has(h, m) {
100
- const r = Snapshot_1.Snapshot.current().getCurrentRevision(h, m);
101
- return m in r.data || m in h.data;
139
+ const os = Changeset_1.Changeset.current().getRelevantSnapshot(h, m);
140
+ return m in os.data || m in h.data;
102
141
  }
103
142
  getOwnPropertyDescriptor(h, m) {
104
- const r = Snapshot_1.Snapshot.current().getCurrentRevision(h, m);
105
- const pd = Reflect.getOwnPropertyDescriptor(r.data, m);
143
+ const os = Changeset_1.Changeset.current().getRelevantSnapshot(h, m);
144
+ const pd = Reflect.getOwnPropertyDescriptor(os.data, m);
106
145
  if (pd)
107
146
  pd.configurable = pd.writable = true;
108
147
  return pd;
109
148
  }
110
149
  ownKeys(h) {
111
- const r = Snapshot_1.Snapshot.current().getCurrentRevision(h, Data_1.Meta.Holder);
150
+ const os = Changeset_1.Changeset.current().getRelevantSnapshot(h, Data_1.Meta.Handle);
112
151
  const result = [];
113
- for (const m of Object.getOwnPropertyNames(r.data)) {
114
- const value = r.data[m];
152
+ for (const m of Object.getOwnPropertyNames(os.data)) {
153
+ const value = os.data[m];
115
154
  if (!(value instanceof Data_1.Subscription) || !value.isOperation)
116
155
  result.push(m);
117
156
  }
@@ -120,12 +159,12 @@ class Hooks {
120
159
  static decorateData(reactive, proto, m) {
121
160
  if (reactive) {
122
161
  const get = function () {
123
- const h = Hooks.acquireDataHolder(this);
124
- return Hooks.proxy.get(h, m, this);
162
+ const h = Hooks.acquireHandle(this);
163
+ return Hooks.handler.get(h, m, this);
125
164
  };
126
165
  const set = function (value) {
127
- const h = Hooks.acquireDataHolder(this);
128
- return Hooks.proxy.set(h, m, value, this);
166
+ const h = Hooks.acquireHandle(this);
167
+ return Hooks.handler.set(h, m, value, this);
129
168
  };
130
169
  const enumerable = true;
131
170
  const configurable = false;
@@ -143,7 +182,7 @@ class Hooks {
143
182
  const opts = Hooks.rememberOperationOptions(proto, member, (_c = pd.value) !== null && _c !== void 0 ? _c : pd.get, (_d = pd.value) !== null && _d !== void 0 ? _d : pd.set, true, configurable, options, implicit);
144
183
  if (opts.getter === opts.setter) {
145
184
  const bootstrap = function () {
146
- const h = Hooks.acquireDataHolder(this);
185
+ const h = Hooks.acquireHandle(this);
147
186
  const operation = Hooks.createOperation(h, member, opts);
148
187
  Object.defineProperty(h.data, member, { value: operation, enumerable, configurable });
149
188
  return operation;
@@ -152,7 +191,7 @@ class Hooks {
152
191
  }
153
192
  else if (opts.setter === Utils_1.UNDEF) {
154
193
  const bootstrap = function () {
155
- const h = Hooks.acquireDataHolder(this);
194
+ const h = Hooks.acquireHandle(this);
156
195
  const operation = Hooks.createOperation(h, member, opts);
157
196
  Object.defineProperty(h.data, member, { get: operation, enumerable, configurable });
158
197
  return operation.call(this);
@@ -167,23 +206,24 @@ class Hooks {
167
206
  return Hooks.decorateOperation(false, decorator, options, proto, prop, pd);
168
207
  };
169
208
  }
170
- static acquireDataHolder(obj) {
171
- let h = obj[Data_1.Meta.Holder];
209
+ static acquireHandle(obj) {
210
+ let h = obj[Data_1.Meta.Handle];
172
211
  if (!h) {
173
212
  if (obj !== Object(obj) || Array.isArray(obj))
174
213
  throw (0, Dbg_1.misuse)('only objects can be reactive');
175
214
  const initial = Data_1.Meta.getFrom(Object.getPrototypeOf(obj), Data_1.Meta.Initial);
176
- const rev = new Data_1.DataRevision(Snapshot_1.ROOT_REV.snapshot, Snapshot_1.ROOT_REV, Object.assign({}, initial));
177
- Data_1.Meta.set(rev.data, Data_1.Meta.Holder, h);
178
- h = new Data_1.DataHolder(obj, obj, Hooks.proxy, rev, obj.constructor.name);
179
- Data_1.Meta.set(obj, Data_1.Meta.Holder, h);
215
+ const os = new Data_1.ObjectSnapshot(Changeset_1.EMPTY_SNAPSHOT.changeset, Changeset_1.EMPTY_SNAPSHOT, Object.assign({}, initial));
216
+ h = new Data_1.ObjectHandle(obj, obj, Hooks.handler, os, obj.constructor.name);
217
+ Data_1.Meta.set(os.data, Data_1.Meta.Handle, h);
218
+ Data_1.Meta.set(obj, Data_1.Meta.Handle, h);
219
+ Data_1.Meta.set(os.data, Data_1.Meta.Revision, new Data_1.Subscription(1));
180
220
  }
181
221
  return h;
182
222
  }
183
- static createDataHolderForReactiveObject(proto, data, blank, hint) {
184
- const ctx = Snapshot_1.Snapshot.edit();
185
- const h = new Data_1.DataHolder(data, undefined, Hooks.proxy, Snapshot_1.ROOT_REV, hint);
186
- ctx.getEditableRevision(h, Data_1.Meta.Holder, blank);
223
+ static createHandleForReactiveObject(proto, data, blank, hint) {
224
+ const ctx = Changeset_1.Changeset.edit();
225
+ const h = new Data_1.ObjectHandle(data, undefined, Hooks.handler, Changeset_1.EMPTY_SNAPSHOT, hint);
226
+ ctx.getEditableSnapshot(h, Data_1.Meta.Handle, blank);
187
227
  if (!Hooks.reactionsAutoStartDisabled)
188
228
  for (const m in Data_1.Meta.getFrom(proto, Data_1.Meta.Reactions))
189
229
  h.proxy[m][Data_1.Meta.Controller].markObsolete();
@@ -194,13 +234,13 @@ class Hooks {
194
234
  Hooks.repetitiveUsageWarningThreshold = options && options.repetitiveUsageWarningThreshold !== undefined ? options.repetitiveUsageWarningThreshold : 10;
195
235
  Hooks.mainThreadBlockingWarningThreshold = options && options.mainThreadBlockingWarningThreshold !== undefined ? options.mainThreadBlockingWarningThreshold : 14;
196
236
  Hooks.asyncActionDurationWarningThreshold = options && options.asyncActionDurationWarningThreshold !== undefined ? options.asyncActionDurationWarningThreshold : 300;
197
- Snapshot_1.Snapshot.garbageCollectionSummaryInterval = options && options.garbageCollectionSummaryInterval !== undefined ? options.garbageCollectionSummaryInterval : 100;
237
+ Changeset_1.Changeset.garbageCollectionSummaryInterval = options && options.garbageCollectionSummaryInterval !== undefined ? options.garbageCollectionSummaryInterval : 100;
198
238
  }
199
239
  else {
200
240
  Hooks.repetitiveUsageWarningThreshold = Number.MAX_SAFE_INTEGER;
201
241
  Hooks.mainThreadBlockingWarningThreshold = Number.MAX_SAFE_INTEGER;
202
242
  Hooks.asyncActionDurationWarningThreshold = Number.MAX_SAFE_INTEGER;
203
- Snapshot_1.Snapshot.garbageCollectionSummaryInterval = Number.MAX_SAFE_INTEGER;
243
+ Changeset_1.Changeset.garbageCollectionSummaryInterval = Number.MAX_SAFE_INTEGER;
204
244
  }
205
245
  }
206
246
  static sensitive(sensitivity, func, ...args) {
@@ -215,7 +255,7 @@ class Hooks {
215
255
  }
216
256
  static setHint(obj, hint) {
217
257
  if (hint) {
218
- const h = Hooks.acquireDataHolder(obj);
258
+ const h = Hooks.acquireHandle(obj);
219
259
  h.hint = hint;
220
260
  }
221
261
  return obj;
@@ -227,7 +267,7 @@ Hooks.repetitiveUsageWarningThreshold = Number.MAX_SAFE_INTEGER;
227
267
  Hooks.mainThreadBlockingWarningThreshold = Number.MAX_SAFE_INTEGER;
228
268
  Hooks.asyncActionDurationWarningThreshold = Number.MAX_SAFE_INTEGER;
229
269
  Hooks.sensitivity = false;
230
- Hooks.proxy = new Hooks();
270
+ Hooks.handler = new Hooks();
231
271
  Hooks.createOperation = function (h, m, options) {
232
272
  throw (0, Dbg_1.misuse)('createOperation should never be called');
233
273
  };
@@ -1,5 +1,5 @@
1
1
  import { ReactiveObject } from './Hooks';
2
- import { DataHolder, DataRevision, PatchSet } from './Data';
2
+ import { ObjectHandle, ObjectSnapshot, PatchSet } from './Data';
3
3
  export declare type Saver = (patch: PatchSet) => Promise<void>;
4
4
  export declare abstract class Journal extends ReactiveObject {
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, changeset: Map<DataHolder, DataRevision>): PatchSet;
31
+ static buildPatch(hint: string, items: Map<ObjectHandle, ObjectSnapshot>): PatchSet;
32
32
  static applyPatch(patch: PatchSet, undoing: boolean): void;
33
33
  mergePatchToUnsaved(patch: PatchSet, undoing: boolean): void;
34
34
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.JournalImpl = exports.Journal = void 0;
4
4
  const Hooks_1 = require("./Hooks");
5
5
  const Data_1 = require("./Data");
6
- const Snapshot_1 = require("./Snapshot");
6
+ const Changeset_1 = require("./Changeset");
7
7
  const Transaction_1 = require("./Transaction");
8
8
  const Sealant_1 = require("../util/Sealant");
9
9
  class Journal extends Hooks_1.ReactiveObject {
@@ -15,7 +15,7 @@ class JournalImpl extends Journal {
15
15
  super(...arguments);
16
16
  this._capacity = 5;
17
17
  this._edits = [];
18
- this._unsaved = { hint: 'unsaved', objects: new Map() };
18
+ this._unsaved = { hint: 'unsaved', items: new Map() };
19
19
  this._position = 0;
20
20
  }
21
21
  get capacity() { return this._capacity; }
@@ -39,7 +39,7 @@ class JournalImpl extends Journal {
39
39
  }
40
40
  saved(patch) {
41
41
  if (this._unsaved === patch)
42
- this._unsaved = { hint: 'unsaved', objects: new Map() };
42
+ this._unsaved = { hint: 'unsaved', items: new Map() };
43
43
  else
44
44
  throw new Error('not implemented');
45
45
  }
@@ -67,66 +67,77 @@ class JournalImpl extends Journal {
67
67
  this._position = i;
68
68
  });
69
69
  }
70
- static buildPatch(hint, changeset) {
71
- const patch = { hint, objects: new Map() };
72
- changeset.forEach((r, h) => {
73
- const op = { data: {}, former: {} };
74
- const former = r.former.revision !== Snapshot_1.ROOT_REV ? r.former.revision.data : undefined;
75
- r.changes.forEach(m => {
76
- op.data[m] = unseal(r.data[m]);
70
+ static buildPatch(hint, items) {
71
+ const patch = { hint, items: new Map() };
72
+ items.forEach((os, h) => {
73
+ const op = new Map();
74
+ const former = os.former.snapshot !== Changeset_1.EMPTY_SNAPSHOT ? os.former.snapshot.data : undefined;
75
+ os.changes.forEach(m => {
76
+ const vp = {
77
+ memberName: m, patchKind: 'update',
78
+ freshValue: unseal(os.data[m]), formerValue: undefined,
79
+ };
77
80
  if (former)
78
- op.former[m] = unseal(former[m]);
81
+ vp.formerValue = unseal(former[m]);
82
+ op.set(m, vp);
79
83
  });
80
84
  if (!former) {
81
- delete op.data[Data_1.Meta.Disposed];
82
- op.former[Data_1.Meta.Disposed] = Data_1.Meta.Disposed;
85
+ const vp = {
86
+ memberName: Data_1.Meta.Revision, patchKind: 'remove',
87
+ freshValue: Data_1.Meta.Undefined, formerValue: undefined,
88
+ };
89
+ op.set(Data_1.Meta.Revision, vp);
83
90
  }
84
- patch.objects.set(h.proxy, op);
91
+ patch.items.set(h.proxy, op);
85
92
  });
86
93
  return patch;
87
94
  }
88
95
  static applyPatch(patch, undoing) {
89
- const ctx = Snapshot_1.Snapshot.edit();
90
- patch.objects.forEach((dp, obj) => {
91
- const h = Data_1.Meta.get(obj, Data_1.Meta.Holder);
92
- const data = undoing ? dp.former : dp.data;
93
- if (data[Data_1.Meta.Disposed] === undefined) {
94
- for (const m in data) {
95
- const value = data[m];
96
- const r = ctx.getEditableRevision(h, m, value);
97
- if (r.snapshot === ctx) {
98
- r.data[m] = new Data_1.Subscription(value);
99
- const existing = r.former.revision.data[m];
100
- Snapshot_1.Snapshot.markEdited(existing, value, existing !== value, r, m, h);
96
+ const ctx = Changeset_1.Changeset.edit();
97
+ patch.items.forEach((op, obj) => {
98
+ const h = Data_1.Meta.get(obj, Data_1.Meta.Handle);
99
+ const rev = op.get(Data_1.Meta.Revision);
100
+ const disposed = rev && (undoing ? rev.formerValue : rev.freshValue) === Data_1.Meta.Undefined;
101
+ if (!disposed) {
102
+ op.forEach((vp, m) => {
103
+ const value = undoing ? vp.formerValue : vp.freshValue;
104
+ const os = ctx.getEditableSnapshot(h, m, value);
105
+ if (os.changeset === ctx) {
106
+ os.data[m] = new Data_1.Subscription(value);
107
+ const existing = os.former.snapshot.data[m];
108
+ Changeset_1.Changeset.markEdited(existing, value, existing !== value, os, m, h);
101
109
  }
102
- }
110
+ });
103
111
  }
104
112
  else
105
- Snapshot_1.Snapshot.doDispose(ctx, h);
113
+ Changeset_1.Changeset.doDispose(ctx, h);
106
114
  });
107
115
  }
108
116
  mergePatchToUnsaved(patch, undoing) {
109
117
  const unsaved = this._unsaved;
110
- patch.objects.forEach((dp, obj) => {
111
- let merged = unsaved.objects.get(obj);
112
- if (!merged)
113
- unsaved.objects.set(obj, merged = { data: {}, former: {} });
114
- const data = undoing ? dp.former : dp.data;
115
- const former = undoing ? dp.data : dp.former;
116
- for (const m in data) {
117
- const value = data[m];
118
- if (value !== merged.former[m]) {
119
- merged.data[m] = value;
120
- if (m in merged.former === false)
121
- merged.former[m] = former[m];
118
+ patch.items.forEach((op, obj) => {
119
+ let result = unsaved.items.get(obj);
120
+ if (!result)
121
+ unsaved.items.set(obj, result = new Map());
122
+ op.forEach((vp, m) => {
123
+ let merged = result.get(m);
124
+ if (!merged)
125
+ result.set(m, merged = {
126
+ memberName: m, patchKind: 'update',
127
+ freshValue: undefined, formerValue: undefined,
128
+ });
129
+ const value = undoing ? vp.formerValue : vp.freshValue;
130
+ const former = undoing ? vp.freshValue : vp.formerValue;
131
+ if (value !== merged.formerValue) {
132
+ merged.freshValue = value;
133
+ merged.formerValue = former;
122
134
  }
123
135
  else {
124
- delete merged.data[m];
125
- delete merged.former[m];
126
- if (Object.keys(merged.data).length === 0)
127
- unsaved.objects.delete(obj);
136
+ result.delete(m);
137
+ if (result.size === 0)
138
+ unsaved.items.delete(obj);
128
139
  }
129
- }
140
+ });
130
141
  });
131
142
  }
132
143
  }
@@ -1,7 +1,7 @@
1
1
  export declare abstract class Meta {
2
- static readonly Holder: unique symbol;
2
+ static readonly Handle: unique symbol;
3
+ static readonly Revision: unique symbol;
3
4
  static readonly Controller: unique symbol;
4
- static readonly Disposed: unique symbol;
5
5
  static readonly Initial: unique symbol;
6
6
  static readonly Reactions: unique symbol;
7
7
  static readonly Nonreactive: unique symbol;
@@ -24,10 +24,10 @@ class Meta {
24
24
  }
25
25
  }
26
26
  exports.Meta = Meta;
27
- Meta.Holder = Symbol('rxHolder');
28
- Meta.Controller = Symbol('rxController');
29
- Meta.Disposed = Symbol('rxDisposed');
30
- Meta.Initial = Symbol('rxInitial');
31
- Meta.Reactions = Symbol('rxReactions');
32
- Meta.Nonreactive = Symbol('rxNonreactive');
33
- Meta.Undefined = Symbol('rxUndefined');
27
+ Meta.Handle = Symbol('rx-handle');
28
+ Meta.Revision = Symbol('rx-revision');
29
+ Meta.Controller = Symbol('rx-controller');
30
+ Meta.Initial = Symbol('rx-initial');
31
+ Meta.Reactions = Symbol('rx-reactions');
32
+ Meta.Nonreactive = Symbol('rx-nonreactive');
33
+ Meta.Undefined = Symbol('rx-undefined');
@@ -1,11 +1,11 @@
1
1
  import { F } from '../util/Utils';
2
2
  import { MemberOptions } from '../Options';
3
3
  import { Controller } from '../Controller';
4
- import { MemberName, DataHolder, Subscription, Subscriber, SubscriptionInfo, AbstractSnapshot } from './Data';
4
+ import { MemberName, ObjectHandle, Subscription, Subscriber, SubscriptionInfo, AbstractChangeset } from './Data';
5
5
  import { Transaction } from './Transaction';
6
6
  import { OptionsImpl } from './Hooks';
7
7
  export declare class OperationController extends Controller<any> {
8
- readonly ownHolder: DataHolder;
8
+ readonly objectHandle: ObjectHandle;
9
9
  readonly memberName: MemberName;
10
10
  configure(options: Partial<MemberOptions>): MemberOptions;
11
11
  get options(): MemberOptions;
@@ -17,7 +17,7 @@ export declare class OperationController extends Controller<any> {
17
17
  get isUpToDate(): boolean;
18
18
  markObsolete(): void;
19
19
  pullLastResult(args?: any[]): any;
20
- constructor(ownHolder: DataHolder, memberName: MemberName);
20
+ constructor(h: ObjectHandle, m: MemberName);
21
21
  useOrRun(weak: boolean, args: any[] | undefined): Operation;
22
22
  static of(method: F<any>): Controller<any>;
23
23
  static configureImpl(self: OperationController | undefined, options: Partial<MemberOptions>): MemberOptions;
@@ -28,7 +28,7 @@ export declare class OperationController extends Controller<any> {
28
28
  private peek;
29
29
  private use;
30
30
  private edit;
31
- private acquireFromRevision;
31
+ private acquireFromSnapshot;
32
32
  private run;
33
33
  private static markObsolete;
34
34
  }
@@ -39,7 +39,7 @@ declare class Operation extends Subscription implements Subscriber {
39
39
  readonly margin: number;
40
40
  readonly transaction: Transaction;
41
41
  readonly controller: OperationController;
42
- readonly snapshot: AbstractSnapshot;
42
+ readonly changeset: AbstractChangeset;
43
43
  subscriptions: Map<Subscription, SubscriptionInfo> | undefined;
44
44
  options: OptionsImpl;
45
45
  cause: string | undefined;
@@ -50,7 +50,7 @@ declare class Operation extends Subscription implements Subscriber {
50
50
  obsoleteDueTo: string | undefined;
51
51
  obsoleteSince: number;
52
52
  successor: Operation | undefined;
53
- constructor(controller: OperationController, snapshot: AbstractSnapshot, former: Operation | OptionsImpl);
53
+ constructor(controller: OperationController, changeset: AbstractChangeset, former: Operation | OptionsImpl);
54
54
  get isOperation(): boolean;
55
55
  get originSnapshotId(): number;
56
56
  hint(): string;
@@ -61,7 +61,7 @@ declare class Operation extends Subscription implements Subscriber {
61
61
  dependencies(): string[];
62
62
  wrap<T>(func: F<T>): F<T>;
63
63
  run(proxy: any, args: any[] | undefined): void;
64
- markObsoleteDueTo(subscription: Subscription, memberName: MemberName, snapshot: AbstractSnapshot, holder: DataHolder, outer: string, since: number, reactions: Subscriber[]): void;
64
+ markObsoleteDueTo(subscription: Subscription, m: MemberName, changeset: AbstractChangeset, h: ObjectHandle, outer: string, since: number, reactions: Subscriber[]): void;
65
65
  runIfNotUpToDate(now: boolean, nothrow: boolean): void;
66
66
  isNotUpToDate(): boolean;
67
67
  reenterOver(head: Operation): this;