@colyseus/schema 1.1.0-alpha.0 → 2.0.0

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.
Files changed (103) hide show
  1. package/README.md +1 -4
  2. package/build/cjs/index.js +1194 -1001
  3. package/build/cjs/index.js.map +1 -1
  4. package/build/esm/index.mjs +350 -311
  5. package/build/esm/index.mjs.map +1 -1
  6. package/build/umd/index.js +371 -335
  7. package/lib/Reflection.d.ts +21 -0
  8. package/lib/Reflection.js +198 -0
  9. package/lib/Reflection.js.map +1 -0
  10. package/lib/Schema.d.ts +66 -0
  11. package/lib/Schema.js +853 -0
  12. package/lib/Schema.js.map +1 -0
  13. package/lib/annotations.d.ts +96 -0
  14. package/lib/annotations.js +316 -0
  15. package/lib/annotations.js.map +1 -0
  16. package/lib/changes/ChangeTree.d.ts +53 -0
  17. package/lib/changes/ChangeTree.js +209 -0
  18. package/lib/changes/ChangeTree.js.map +1 -0
  19. package/lib/changes/ReferenceTracker.d.ts +14 -0
  20. package/lib/changes/ReferenceTracker.js +77 -0
  21. package/lib/changes/ReferenceTracker.js.map +1 -0
  22. package/lib/codegen/api.d.ts +7 -0
  23. package/lib/codegen/api.js +36 -0
  24. package/lib/codegen/api.js.map +1 -0
  25. package/lib/codegen/argv.d.ts +6 -0
  26. package/lib/codegen/argv.js +41 -0
  27. package/lib/codegen/argv.js.map +1 -0
  28. package/lib/codegen/cli.d.ts +1 -0
  29. package/lib/codegen/cli.js +49 -0
  30. package/lib/codegen/cli.js.map +1 -0
  31. package/lib/codegen/languages/cpp.d.ts +3 -0
  32. package/lib/codegen/languages/cpp.js +213 -0
  33. package/lib/codegen/languages/cpp.js.map +1 -0
  34. package/lib/codegen/languages/csharp.d.ts +4 -0
  35. package/lib/codegen/languages/csharp.js +130 -0
  36. package/lib/codegen/languages/csharp.js.map +1 -0
  37. package/lib/codegen/languages/haxe.d.ts +3 -0
  38. package/lib/codegen/languages/haxe.js +93 -0
  39. package/lib/codegen/languages/haxe.js.map +1 -0
  40. package/lib/codegen/languages/java.d.ts +6 -0
  41. package/lib/codegen/languages/java.js +92 -0
  42. package/lib/codegen/languages/java.js.map +1 -0
  43. package/lib/codegen/languages/js.d.ts +3 -0
  44. package/lib/codegen/languages/js.js +89 -0
  45. package/lib/codegen/languages/js.js.map +1 -0
  46. package/lib/codegen/languages/lua.d.ts +3 -0
  47. package/lib/codegen/languages/lua.js +97 -0
  48. package/lib/codegen/languages/lua.js.map +1 -0
  49. package/lib/codegen/languages/ts.d.ts +3 -0
  50. package/lib/codegen/languages/ts.js +125 -0
  51. package/lib/codegen/languages/ts.js.map +1 -0
  52. package/lib/codegen/parser.d.ts +5 -0
  53. package/lib/codegen/parser.js +196 -0
  54. package/lib/codegen/parser.js.map +1 -0
  55. package/lib/codegen/types.d.ts +44 -0
  56. package/lib/codegen/types.js +122 -0
  57. package/lib/codegen/types.js.map +1 -0
  58. package/lib/encoding/decode.d.ts +48 -0
  59. package/lib/encoding/decode.js +267 -0
  60. package/lib/encoding/decode.js.map +1 -0
  61. package/lib/encoding/encode.d.ts +38 -0
  62. package/lib/encoding/encode.js +281 -0
  63. package/lib/encoding/encode.js.map +1 -0
  64. package/lib/events/EventEmitter.d.ts +13 -0
  65. package/lib/events/EventEmitter.js +62 -0
  66. package/lib/events/EventEmitter.js.map +1 -0
  67. package/lib/filters/index.d.ts +8 -0
  68. package/lib/filters/index.js +25 -0
  69. package/lib/filters/index.js.map +1 -0
  70. package/lib/index.d.ts +19 -0
  71. package/lib/index.js +46 -0
  72. package/lib/index.js.map +1 -0
  73. package/lib/spec.d.ts +13 -0
  74. package/lib/spec.js +42 -0
  75. package/lib/spec.js.map +1 -0
  76. package/lib/types/ArraySchema.d.ts +230 -0
  77. package/lib/types/ArraySchema.js +559 -0
  78. package/lib/types/ArraySchema.js.map +1 -0
  79. package/lib/types/CollectionSchema.d.ts +35 -0
  80. package/lib/types/CollectionSchema.js +158 -0
  81. package/lib/types/CollectionSchema.js.map +1 -0
  82. package/lib/types/HelperTypes.d.ts +28 -0
  83. package/lib/types/HelperTypes.js +3 -0
  84. package/lib/types/HelperTypes.js.map +1 -0
  85. package/lib/types/MapSchema.d.ts +37 -0
  86. package/lib/types/MapSchema.js +214 -0
  87. package/lib/types/MapSchema.js.map +1 -0
  88. package/lib/types/SetSchema.d.ts +32 -0
  89. package/lib/types/SetSchema.js +171 -0
  90. package/lib/types/SetSchema.js.map +1 -0
  91. package/lib/types/index.d.ts +6 -0
  92. package/lib/types/index.js +13 -0
  93. package/lib/types/index.js.map +1 -0
  94. package/lib/types/typeRegistry.d.ts +5 -0
  95. package/lib/types/typeRegistry.js +13 -0
  96. package/lib/types/typeRegistry.js.map +1 -0
  97. package/lib/types/utils.d.ts +9 -0
  98. package/lib/types/utils.js +50 -0
  99. package/lib/types/utils.js.map +1 -0
  100. package/lib/utils.d.ts +2 -0
  101. package/lib/utils.js +26 -0
  102. package/lib/utils.js.map +1 -0
  103. package/package.json +4 -8
@@ -2,9 +2,53 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ /*! *****************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+ /* global Reflect, Promise */
20
+
21
+ var extendStatics = function(d, b) {
22
+ extendStatics = Object.setPrototypeOf ||
23
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
24
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
25
+ return extendStatics(d, b);
26
+ };
27
+
28
+ function __extends(d, b) {
29
+ if (typeof b !== "function" && b !== null)
30
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
31
+ extendStatics(d, b);
32
+ function __() { this.constructor = d; }
33
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34
+ }
35
+
36
+ function __decorate(decorators, target, key, desc) {
37
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
38
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
39
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
40
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
41
+ }
42
+
43
+ function __spreadArray(to, from) {
44
+ for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
45
+ to[j] = from[i];
46
+ return to;
47
+ }
48
+
5
49
  // export const SWITCH_TO_STRUCTURE = 193; (easily collides with DELETE_AND_ADD + fieldIndex = 2)
6
- const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
7
- const TYPE_ID = 213;
50
+ var SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
51
+ var TYPE_ID = 213;
8
52
  /**
9
53
  * Encoding Schema field operations.
10
54
  */
@@ -41,75 +85,8 @@ exports.OPERATION = void 0;
41
85
  // CLEAR = 10,
42
86
  // }
43
87
 
44
- //
45
- // Root holds all schema references by unique id
46
- //
47
- class Root {
48
- constructor() {
49
- //
50
- // Relation of refId => Schema structure
51
- // For direct access of structures during decoding time.
52
- //
53
- this.refs = new Map();
54
- this.refCounts = {};
55
- this.deletedRefs = new Set();
56
- this.nextUniqueId = 0;
57
- }
58
- getNextUniqueId() {
59
- return this.nextUniqueId++;
60
- }
61
- // for decoding
62
- addRef(refId, ref, incrementCount = true) {
63
- this.refs.set(refId, ref);
64
- if (incrementCount) {
65
- this.refCounts[refId] = (this.refCounts[refId] || 0) + 1;
66
- }
67
- }
68
- // for decoding
69
- removeRef(refId) {
70
- this.refCounts[refId] = this.refCounts[refId] - 1;
71
- this.deletedRefs.add(refId);
72
- }
73
- clearRefs() {
74
- this.refs.clear();
75
- this.deletedRefs.clear();
76
- this.refCounts = {};
77
- }
78
- // for decoding
79
- garbageCollectDeletedRefs() {
80
- this.deletedRefs.forEach((refId) => {
81
- if (this.refCounts[refId] <= 0) {
82
- const ref = this.refs.get(refId);
83
- //
84
- // Ensure child schema instances have their references removed as well.
85
- //
86
- if (ref instanceof Schema) {
87
- for (const fieldName in ref['_definition'].schema) {
88
- if (typeof (ref['_definition'].schema[fieldName]) !== "string" &&
89
- ref[fieldName] &&
90
- ref[fieldName]['$changes']) {
91
- this.removeRef(ref[fieldName]['$changes'].refId);
92
- }
93
- }
94
- }
95
- else {
96
- const definition = ref['$changes'].parent._definition;
97
- const type = definition.schema[definition.fieldsByIndex[ref['$changes'].parentIndex]];
98
- if (typeof (Object.values(type)[0]) === "function") {
99
- Array.from(ref.values())
100
- .forEach((child) => this.removeRef(child['$changes'].refId));
101
- }
102
- }
103
- this.refs.delete(refId);
104
- delete this.refCounts[refId];
105
- }
106
- });
107
- // clear deleted refs.
108
- this.deletedRefs.clear();
109
- }
110
- }
111
- class ChangeTree {
112
- constructor(ref, parent, root) {
88
+ var ChangeTree = /** @class */ (function () {
89
+ function ChangeTree(ref, parent, root) {
113
90
  this.changed = false;
114
91
  this.changes = new Map();
115
92
  this.allChanges = new Set();
@@ -119,7 +96,8 @@ class ChangeTree {
119
96
  this.ref = ref;
120
97
  this.setParent(parent, root);
121
98
  }
122
- setParent(parent, root, parentIndex) {
99
+ ChangeTree.prototype.setParent = function (parent, root, parentIndex) {
100
+ var _this = this;
123
101
  if (!this.indexes) {
124
102
  this.indexes = (this.ref instanceof Schema)
125
103
  ? this.ref['_definition'].indexes
@@ -136,34 +114,35 @@ class ChangeTree {
136
114
  // assign same parent on child structures
137
115
  //
138
116
  if (this.ref instanceof Schema) {
139
- const definition = this.ref['_definition'];
140
- for (let field in definition.schema) {
141
- const value = this.ref[field];
117
+ var definition = this.ref['_definition'];
118
+ for (var field in definition.schema) {
119
+ var value = this.ref[field];
142
120
  if (value && value['$changes']) {
143
- const parentIndex = definition.indexes[field];
144
- value['$changes'].setParent(this.ref, root, parentIndex);
121
+ var parentIndex_1 = definition.indexes[field];
122
+ value['$changes'].setParent(this.ref, root, parentIndex_1);
145
123
  }
146
124
  }
147
125
  }
148
126
  else if (typeof (this.ref) === "object") {
149
- this.ref.forEach((value, key) => {
127
+ this.ref.forEach(function (value, key) {
150
128
  if (value instanceof Schema) {
151
- const changeTreee = value['$changes'];
152
- const parentIndex = this.ref['$changes'].indexes[key];
153
- changeTreee.setParent(this.ref, this.root, parentIndex);
129
+ var changeTreee = value['$changes'];
130
+ var parentIndex_2 = _this.ref['$changes'].indexes[key];
131
+ changeTreee.setParent(_this.ref, _this.root, parentIndex_2);
154
132
  }
155
133
  });
156
134
  }
157
- }
158
- operation(op) {
135
+ };
136
+ ChangeTree.prototype.operation = function (op) {
159
137
  this.changes.set(--this.currentCustomOperation, op);
160
- }
161
- change(fieldName, operation = exports.OPERATION.ADD) {
162
- const index = (typeof (fieldName) === "number")
138
+ };
139
+ ChangeTree.prototype.change = function (fieldName, operation) {
140
+ if (operation === void 0) { operation = exports.OPERATION.ADD; }
141
+ var index = (typeof (fieldName) === "number")
163
142
  ? fieldName
164
143
  : this.indexes[fieldName];
165
144
  this.assertValidIndex(index, fieldName);
166
- const previousChange = this.changes.get(index);
145
+ var previousChange = this.changes.get(index);
167
146
  if (!previousChange ||
168
147
  previousChange.op === exports.OPERATION.DELETE ||
169
148
  previousChange.op === exports.OPERATION.TOUCH // (mazmorra.io's BattleAction issue)
@@ -175,38 +154,38 @@ class ChangeTree {
175
154
  ? exports.OPERATION.DELETE_AND_ADD
176
155
  : operation,
177
156
  // : OPERATION.REPLACE,
178
- index
157
+ index: index
179
158
  });
180
159
  }
181
160
  this.allChanges.add(index);
182
161
  this.changed = true;
183
162
  this.touchParents();
184
- }
185
- touch(fieldName) {
186
- const index = (typeof (fieldName) === "number")
163
+ };
164
+ ChangeTree.prototype.touch = function (fieldName) {
165
+ var index = (typeof (fieldName) === "number")
187
166
  ? fieldName
188
167
  : this.indexes[fieldName];
189
168
  this.assertValidIndex(index, fieldName);
190
169
  if (!this.changes.has(index)) {
191
- this.changes.set(index, { op: exports.OPERATION.TOUCH, index });
170
+ this.changes.set(index, { op: exports.OPERATION.TOUCH, index: index });
192
171
  }
193
172
  this.allChanges.add(index);
194
173
  // ensure touch is placed until the $root is found.
195
174
  this.touchParents();
196
- }
197
- touchParents() {
175
+ };
176
+ ChangeTree.prototype.touchParents = function () {
198
177
  if (this.parent) {
199
178
  this.parent['$changes'].touch(this.parentIndex);
200
179
  }
201
- }
202
- getType(index) {
180
+ };
181
+ ChangeTree.prototype.getType = function (index) {
203
182
  if (this.ref['_definition']) {
204
- const definition = this.ref['_definition'];
183
+ var definition = this.ref['_definition'];
205
184
  return definition.schema[definition.fieldsByIndex[index]];
206
185
  }
207
186
  else {
208
- const definition = this.parent['_definition'];
209
- const parentType = definition.schema[definition.fieldsByIndex[this.parentIndex]];
187
+ var definition = this.parent['_definition'];
188
+ var parentType = definition.schema[definition.fieldsByIndex[this.parentIndex]];
210
189
  //
211
190
  // Get the child type from parent structure.
212
191
  // - ["string"] => "string"
@@ -215,28 +194,28 @@ class ChangeTree {
215
194
  //
216
195
  return Object.values(parentType)[0];
217
196
  }
218
- }
219
- getChildrenFilter() {
220
- const childFilters = this.parent['_definition'].childFilters;
197
+ };
198
+ ChangeTree.prototype.getChildrenFilter = function () {
199
+ var childFilters = this.parent['_definition'].childFilters;
221
200
  return childFilters && childFilters[this.parentIndex];
222
- }
201
+ };
223
202
  //
224
203
  // used during `.encode()`
225
204
  //
226
- getValue(index) {
205
+ ChangeTree.prototype.getValue = function (index) {
227
206
  return this.ref['getByIndex'](index);
228
- }
229
- delete(fieldName) {
230
- const index = (typeof (fieldName) === "number")
207
+ };
208
+ ChangeTree.prototype.delete = function (fieldName) {
209
+ var index = (typeof (fieldName) === "number")
231
210
  ? fieldName
232
211
  : this.indexes[fieldName];
233
212
  if (index === undefined) {
234
- console.warn(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index: ${fieldName} (${index})`);
213
+ console.warn("@colyseus/schema " + this.ref.constructor.name + ": trying to delete non-existing index: " + fieldName + " (" + index + ")");
235
214
  return;
236
215
  }
237
- const previousValue = this.getValue(index);
216
+ var previousValue = this.getValue(index);
238
217
  // console.log("$changes.delete =>", { fieldName, index, previousValue });
239
- this.changes.set(index, { op: exports.OPERATION.DELETE, index });
218
+ this.changes.set(index, { op: exports.OPERATION.DELETE, index: index });
240
219
  this.allChanges.delete(index);
241
220
  // delete cache
242
221
  delete this.caches[index];
@@ -246,8 +225,11 @@ class ChangeTree {
246
225
  }
247
226
  this.changed = true;
248
227
  this.touchParents();
249
- }
250
- discard(changed = false, discardAll = false) {
228
+ };
229
+ ChangeTree.prototype.discard = function (changed, discardAll) {
230
+ var _this = this;
231
+ if (changed === void 0) { changed = false; }
232
+ if (discardAll === void 0) { discardAll = false; }
251
233
  //
252
234
  // Map, Array, etc:
253
235
  // Remove cached key to ensure ADD operations is unsed instead of
@@ -256,10 +238,10 @@ class ChangeTree {
256
238
  // TODO: refactor this. this is not relevant for Collection and Set.
257
239
  //
258
240
  if (!(this.ref instanceof Schema)) {
259
- this.changes.forEach((change) => {
241
+ this.changes.forEach(function (change) {
260
242
  if (change.op === exports.OPERATION.DELETE) {
261
- const index = this.ref['getIndex'](change.index);
262
- delete this.indexes[index];
243
+ var index = _this.ref['getIndex'](change.index);
244
+ delete _this.indexes[index];
263
245
  }
264
246
  });
265
247
  }
@@ -270,50 +252,88 @@ class ChangeTree {
270
252
  }
271
253
  // re-set `currentCustomOperation`
272
254
  this.currentCustomOperation = 0;
273
- }
255
+ };
274
256
  /**
275
257
  * Recursively discard all changes from this, and child structures.
276
258
  */
277
- discardAll() {
278
- this.changes.forEach((change) => {
279
- const value = this.getValue(change.index);
259
+ ChangeTree.prototype.discardAll = function () {
260
+ var _this = this;
261
+ this.changes.forEach(function (change) {
262
+ var value = _this.getValue(change.index);
280
263
  if (value && value['$changes']) {
281
264
  value['$changes'].discardAll();
282
265
  }
283
266
  });
284
267
  this.discard();
285
- }
268
+ };
286
269
  // cache(field: number, beginIndex: number, endIndex: number) {
287
- cache(field, cachedBytes) {
270
+ ChangeTree.prototype.cache = function (field, cachedBytes) {
288
271
  this.caches[field] = cachedBytes;
289
- }
290
- clone() {
272
+ };
273
+ ChangeTree.prototype.clone = function () {
291
274
  return new ChangeTree(this.ref, this.parent, this.root);
292
- }
293
- ensureRefId() {
275
+ };
276
+ ChangeTree.prototype.ensureRefId = function () {
294
277
  // skip if refId is already set.
295
278
  if (this.refId !== undefined) {
296
279
  return;
297
280
  }
298
281
  this.refId = this.root.getNextUniqueId();
299
- }
300
- assertValidIndex(index, fieldName) {
282
+ };
283
+ ChangeTree.prototype.assertValidIndex = function (index, fieldName) {
301
284
  if (index === undefined) {
302
- throw new Error(`ChangeTree: missing index for field "${fieldName}"`);
285
+ throw new Error("ChangeTree: missing index for field \"" + fieldName + "\"");
286
+ }
287
+ };
288
+ return ChangeTree;
289
+ }());
290
+
291
+ function addCallback($callbacks, op, callback, existing) {
292
+ // initialize list of callbacks
293
+ if (!$callbacks[op]) {
294
+ $callbacks[op] = [];
295
+ }
296
+ $callbacks[op].push(callback);
297
+ //
298
+ // Trigger callback for existing elements
299
+ // - OPERATION.ADD
300
+ // - OPERATION.REPLACE
301
+ //
302
+ existing === null || existing === void 0 ? void 0 : existing.forEach(function (item, key) { return callback(item, key); });
303
+ return function () { return spliceOne($callbacks[op], $callbacks[op].indexOf(callback)); };
304
+ }
305
+ function removeChildRefs(changes) {
306
+ var _this = this;
307
+ var needRemoveRef = (typeof (this.$changes.getType()) !== "string");
308
+ this.$items.forEach(function (item, key) {
309
+ changes.push({
310
+ refId: _this.$changes.refId,
311
+ op: exports.OPERATION.DELETE,
312
+ field: key,
313
+ value: undefined,
314
+ previousValue: item
315
+ });
316
+ if (needRemoveRef) {
317
+ _this.$changes.root.removeRef(item['$changes'].refId);
303
318
  }
319
+ });
320
+ }
321
+ function spliceOne(arr, index) {
322
+ // manually splice an array
323
+ if (index === -1 || index >= arr.length) {
324
+ return false;
304
325
  }
326
+ var len = arr.length - 1;
327
+ for (var i = index; i < len; i++) {
328
+ arr[i] = arr[i + 1];
329
+ }
330
+ arr.length = len;
331
+ return true;
305
332
  }
306
333
 
307
- //
308
- // Notes:
309
- // -----
310
- //
311
- // - The tsconfig.json of @colyseus/schema uses ES2018.
312
- // - ES2019 introduces `flatMap` / `flat`, which is not currently relevant, and caused other issues.
313
- //
314
- const DEFAULT_SORT = (a, b) => {
315
- const A = a.toString();
316
- const B = b.toString();
334
+ var DEFAULT_SORT = function (a, b) {
335
+ var A = a.toString();
336
+ var B = b.toString();
317
337
  if (A < B)
318
338
  return -1;
319
339
  else if (A > B)
@@ -330,7 +350,7 @@ function getArrayProxy(value) {
330
350
  // - allow `delete map["key"]`
331
351
  //
332
352
  value = new Proxy(value, {
333
- get: (obj, prop) => {
353
+ get: function (obj, prop) {
334
354
  if (typeof (prop) !== "symbol" &&
335
355
  !isNaN(prop) // https://stackoverflow.com/a/175787/892698
336
356
  ) {
@@ -340,11 +360,11 @@ function getArrayProxy(value) {
340
360
  return obj[prop];
341
361
  }
342
362
  },
343
- set: (obj, prop, setValue) => {
363
+ set: function (obj, prop, setValue) {
344
364
  if (typeof (prop) !== "symbol" &&
345
365
  !isNaN(prop)) {
346
- const indexes = Array.from(obj['$items'].keys());
347
- const key = parseInt(indexes[prop] || prop);
366
+ var indexes = Array.from(obj['$items'].keys());
367
+ var key = parseInt(indexes[prop] || prop);
348
368
  if (setValue === undefined || setValue === null) {
349
369
  obj.deleteAt(key);
350
370
  }
@@ -357,7 +377,7 @@ function getArrayProxy(value) {
357
377
  }
358
378
  return true;
359
379
  },
360
- deleteProperty: (obj, prop) => {
380
+ deleteProperty: function (obj, prop) {
361
381
  if (typeof (prop) === "number") {
362
382
  obj.deleteAt(prop);
363
383
  }
@@ -369,145 +389,179 @@ function getArrayProxy(value) {
369
389
  });
370
390
  return value;
371
391
  }
372
- class ArraySchema {
373
- constructor(...items) {
392
+ var ArraySchema = /** @class */ (function () {
393
+ function ArraySchema() {
394
+ var items = [];
395
+ for (var _i = 0; _i < arguments.length; _i++) {
396
+ items[_i] = arguments[_i];
397
+ }
374
398
  this.$changes = new ChangeTree(this);
375
399
  this.$items = new Map();
376
400
  this.$indexes = new Map();
377
401
  this.$refId = 0;
378
402
  this.push.apply(this, items);
379
403
  }
380
- static is(type) {
381
- return Array.isArray(type);
382
- }
383
- set length(value) {
384
- if (value === 0) {
385
- this.clear();
386
- }
387
- else {
388
- this.splice(value, this.length - value);
389
- }
390
- }
391
- get length() {
392
- return this.$items.size;
393
- }
394
- push(...values) {
395
- let lastIndex;
396
- values.forEach(value => {
404
+ ArraySchema.prototype.onAdd = function (callback, triggerAll) {
405
+ if (triggerAll === void 0) { triggerAll = true; }
406
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
407
+ ? this.$items
408
+ : undefined);
409
+ };
410
+ ArraySchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
411
+ ArraySchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
412
+ ArraySchema.is = function (type) {
413
+ return (
414
+ // type format: ["string"]
415
+ Array.isArray(type) ||
416
+ // type format: { array: "string" }
417
+ (type['array'] !== undefined));
418
+ };
419
+ Object.defineProperty(ArraySchema.prototype, "length", {
420
+ get: function () {
421
+ return this.$items.size;
422
+ },
423
+ set: function (value) {
424
+ if (value === 0) {
425
+ this.clear();
426
+ }
427
+ else {
428
+ this.splice(value, this.length - value);
429
+ }
430
+ },
431
+ enumerable: false,
432
+ configurable: true
433
+ });
434
+ ArraySchema.prototype.push = function () {
435
+ var _this = this;
436
+ var values = [];
437
+ for (var _i = 0; _i < arguments.length; _i++) {
438
+ values[_i] = arguments[_i];
439
+ }
440
+ var lastIndex;
441
+ values.forEach(function (value) {
397
442
  // set "index" for reference.
398
- lastIndex = this.$refId++;
399
- this.setAt(lastIndex, value);
443
+ lastIndex = _this.$refId++;
444
+ _this.setAt(lastIndex, value);
400
445
  });
401
446
  return lastIndex;
402
- }
447
+ };
403
448
  /**
404
449
  * Removes the last element from an array and returns it.
405
450
  */
406
- pop() {
407
- const key = Array.from(this.$indexes.values()).pop();
451
+ ArraySchema.prototype.pop = function () {
452
+ var key = Array.from(this.$indexes.values()).pop();
408
453
  if (key === undefined) {
409
454
  return undefined;
410
455
  }
411
456
  this.$changes.delete(key);
412
457
  this.$indexes.delete(key);
413
- const value = this.$items.get(key);
458
+ var value = this.$items.get(key);
414
459
  this.$items.delete(key);
415
460
  return value;
416
- }
417
- at(index) {
461
+ };
462
+ ArraySchema.prototype.at = function (index) {
418
463
  //
419
464
  // FIXME: this should be O(1)
420
465
  //
421
- const key = Array.from(this.$items.keys())[index];
466
+ var key = Array.from(this.$items.keys())[index];
422
467
  return this.$items.get(key);
423
- }
424
- setAt(index, value) {
468
+ };
469
+ ArraySchema.prototype.setAt = function (index, value) {
470
+ var _a, _b;
425
471
  if (value['$changes'] !== undefined) {
426
472
  value['$changes'].setParent(this, this.$changes.root, index);
427
473
  }
428
- const operation = this.$changes.indexes[index]?.op ?? exports.OPERATION.ADD;
474
+ var operation = (_b = (_a = this.$changes.indexes[index]) === null || _a === void 0 ? void 0 : _a.op) !== null && _b !== void 0 ? _b : exports.OPERATION.ADD;
429
475
  this.$changes.indexes[index] = index;
430
476
  this.$indexes.set(index, index);
431
477
  this.$items.set(index, value);
432
478
  this.$changes.change(index, operation);
433
- }
434
- deleteAt(index) {
435
- const key = Array.from(this.$items.keys())[index];
479
+ };
480
+ ArraySchema.prototype.deleteAt = function (index) {
481
+ var key = Array.from(this.$items.keys())[index];
436
482
  if (key === undefined) {
437
483
  return false;
438
484
  }
439
485
  return this.$deleteAt(key);
440
- }
441
- $deleteAt(index) {
486
+ };
487
+ ArraySchema.prototype.$deleteAt = function (index) {
442
488
  // delete at internal index
443
489
  this.$changes.delete(index);
444
490
  this.$indexes.delete(index);
445
491
  return this.$items.delete(index);
446
- }
447
- clear(isDecoding) {
492
+ };
493
+ ArraySchema.prototype.clear = function (changes) {
448
494
  // discard previous operations.
449
495
  this.$changes.discard(true, true);
450
496
  this.$changes.indexes = {};
451
497
  // clear previous indexes
452
498
  this.$indexes.clear();
453
- // flag child items for garbage collection.
454
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
455
- this.$items.forEach((item) => {
456
- this.$changes.root.removeRef(item['$changes'].refId);
457
- });
499
+ //
500
+ // When decoding:
501
+ // - enqueue items for DELETE callback.
502
+ // - flag child items for garbage collection.
503
+ //
504
+ if (changes) {
505
+ removeChildRefs.call(this, changes);
458
506
  }
459
507
  // clear items
460
508
  this.$items.clear();
461
509
  this.$changes.operation({ index: 0, op: exports.OPERATION.CLEAR });
462
510
  // touch all structures until reach root
463
511
  this.$changes.touchParents();
464
- }
512
+ };
465
513
  /**
466
514
  * Combines two or more arrays.
467
515
  * @param items Additional items to add to the end of array1.
468
516
  */
469
- concat(...items) {
470
- return new ArraySchema(...Array.from(this.$items.values()).concat(...items));
471
- }
517
+ ArraySchema.prototype.concat = function () {
518
+ var _a;
519
+ var items = [];
520
+ for (var _i = 0; _i < arguments.length; _i++) {
521
+ items[_i] = arguments[_i];
522
+ }
523
+ return new (ArraySchema.bind.apply(ArraySchema, __spreadArray([void 0], (_a = Array.from(this.$items.values())).concat.apply(_a, items))))();
524
+ };
472
525
  /**
473
526
  * Adds all the elements of an array separated by the specified separator string.
474
527
  * @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
475
528
  */
476
- join(separator) {
529
+ ArraySchema.prototype.join = function (separator) {
477
530
  return Array.from(this.$items.values()).join(separator);
478
- }
531
+ };
479
532
  /**
480
533
  * Reverses the elements in an Array.
481
534
  */
482
- reverse() {
483
- const indexes = Array.from(this.$items.keys());
484
- const reversedItems = Array.from(this.$items.values()).reverse();
485
- reversedItems.forEach((item, i) => {
486
- this.setAt(indexes[i], item);
535
+ ArraySchema.prototype.reverse = function () {
536
+ var _this = this;
537
+ var indexes = Array.from(this.$items.keys());
538
+ var reversedItems = Array.from(this.$items.values()).reverse();
539
+ reversedItems.forEach(function (item, i) {
540
+ _this.setAt(indexes[i], item);
487
541
  });
488
542
  return this;
489
- }
543
+ };
490
544
  /**
491
545
  * Removes the first element from an array and returns it.
492
546
  */
493
- shift() {
494
- const indexes = Array.from(this.$items.keys());
495
- const shiftAt = indexes.shift();
547
+ ArraySchema.prototype.shift = function () {
548
+ var indexes = Array.from(this.$items.keys());
549
+ var shiftAt = indexes.shift();
496
550
  if (shiftAt === undefined) {
497
551
  return undefined;
498
552
  }
499
- const value = this.$items.get(shiftAt);
553
+ var value = this.$items.get(shiftAt);
500
554
  this.$deleteAt(shiftAt);
501
555
  return value;
502
- }
556
+ };
503
557
  /**
504
558
  * Returns a section of an array.
505
559
  * @param start The beginning of the specified portion of the array.
506
560
  * @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.
507
561
  */
508
- slice(start, end) {
509
- return new ArraySchema(...Array.from(this.$items.values()).slice(start, end));
510
- }
562
+ ArraySchema.prototype.slice = function (start, end) {
563
+ return new (ArraySchema.bind.apply(ArraySchema, __spreadArray([void 0], Array.from(this.$items.values()).slice(start, end))))();
564
+ };
511
565
  /**
512
566
  * Sorts an array.
513
567
  * @param compareFn Function used to determine the order of the elements. It is expected to return
@@ -517,62 +571,75 @@ class ArraySchema {
517
571
  * [11,2,22,1].sort((a, b) => a - b)
518
572
  * ```
519
573
  */
520
- sort(compareFn = DEFAULT_SORT) {
521
- const indexes = Array.from(this.$items.keys());
522
- const sortedItems = Array.from(this.$items.values()).sort(compareFn);
523
- sortedItems.forEach((item, i) => {
524
- this.setAt(indexes[i], item);
574
+ ArraySchema.prototype.sort = function (compareFn) {
575
+ var _this = this;
576
+ if (compareFn === void 0) { compareFn = DEFAULT_SORT; }
577
+ var indexes = Array.from(this.$items.keys());
578
+ var sortedItems = Array.from(this.$items.values()).sort(compareFn);
579
+ sortedItems.forEach(function (item, i) {
580
+ _this.setAt(indexes[i], item);
525
581
  });
526
582
  return this;
527
- }
583
+ };
528
584
  /**
529
585
  * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
530
586
  * @param start The zero-based location in the array from which to start removing elements.
531
587
  * @param deleteCount The number of elements to remove.
532
588
  * @param items Elements to insert into the array in place of the deleted elements.
533
589
  */
534
- splice(start, deleteCount = this.length - start, ...items) {
535
- const indexes = Array.from(this.$items.keys());
536
- const removedItems = [];
537
- for (let i = start; i < start + deleteCount; i++) {
590
+ ArraySchema.prototype.splice = function (start, deleteCount) {
591
+ if (deleteCount === void 0) { deleteCount = this.length - start; }
592
+ var items = [];
593
+ for (var _i = 2; _i < arguments.length; _i++) {
594
+ items[_i - 2] = arguments[_i];
595
+ }
596
+ var indexes = Array.from(this.$items.keys());
597
+ var removedItems = [];
598
+ for (var i = start; i < start + deleteCount; i++) {
538
599
  removedItems.push(this.$items.get(indexes[i]));
539
600
  this.$deleteAt(indexes[i]);
540
601
  }
541
602
  return removedItems;
542
- }
603
+ };
543
604
  /**
544
605
  * Inserts new elements at the start of an array.
545
606
  * @param items Elements to insert at the start of the Array.
546
607
  */
547
- unshift(...items) {
548
- const length = this.length;
549
- const addedLength = items.length;
608
+ ArraySchema.prototype.unshift = function () {
609
+ var _this = this;
610
+ var items = [];
611
+ for (var _i = 0; _i < arguments.length; _i++) {
612
+ items[_i] = arguments[_i];
613
+ }
614
+ var length = this.length;
615
+ var addedLength = items.length;
550
616
  // const indexes = Array.from(this.$items.keys());
551
- const previousValues = Array.from(this.$items.values());
552
- items.forEach((item, i) => {
553
- this.setAt(i, item);
617
+ var previousValues = Array.from(this.$items.values());
618
+ items.forEach(function (item, i) {
619
+ _this.setAt(i, item);
554
620
  });
555
- previousValues.forEach((previousValue, i) => {
556
- this.setAt(addedLength + i, previousValue);
621
+ previousValues.forEach(function (previousValue, i) {
622
+ _this.setAt(addedLength + i, previousValue);
557
623
  });
558
624
  return length + addedLength;
559
- }
625
+ };
560
626
  /**
561
627
  * Returns the index of the first occurrence of a value in an array.
562
628
  * @param searchElement The value to locate in the array.
563
629
  * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
564
630
  */
565
- indexOf(searchElement, fromIndex) {
631
+ ArraySchema.prototype.indexOf = function (searchElement, fromIndex) {
566
632
  return Array.from(this.$items.values()).indexOf(searchElement, fromIndex);
567
- }
633
+ };
568
634
  /**
569
635
  * Returns the index of the last occurrence of a specified value in an array.
570
636
  * @param searchElement The value to locate in the array.
571
637
  * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.
572
638
  */
573
- lastIndexOf(searchElement, fromIndex = this.length - 1) {
639
+ ArraySchema.prototype.lastIndexOf = function (searchElement, fromIndex) {
640
+ if (fromIndex === void 0) { fromIndex = this.length - 1; }
574
641
  return Array.from(this.$items.values()).lastIndexOf(searchElement, fromIndex);
575
- }
642
+ };
576
643
  /**
577
644
  * Determines whether all the members of an array satisfy the specified test.
578
645
  * @param callbackfn A function that accepts up to three arguments. The every method calls
@@ -581,9 +648,9 @@ class ArraySchema {
581
648
  * @param thisArg An object to which the this keyword can refer in the callbackfn function.
582
649
  * If thisArg is omitted, undefined is used as the this value.
583
650
  */
584
- every(callbackfn, thisArg) {
651
+ ArraySchema.prototype.every = function (callbackfn, thisArg) {
585
652
  return Array.from(this.$items.values()).every(callbackfn, thisArg);
586
- }
653
+ };
587
654
  /**
588
655
  * Determines whether the specified callback function returns true for any element of an array.
589
656
  * @param callbackfn A function that accepts up to three arguments. The some method calls
@@ -592,44 +659,44 @@ class ArraySchema {
592
659
  * @param thisArg An object to which the this keyword can refer in the callbackfn function.
593
660
  * If thisArg is omitted, undefined is used as the this value.
594
661
  */
595
- some(callbackfn, thisArg) {
662
+ ArraySchema.prototype.some = function (callbackfn, thisArg) {
596
663
  return Array.from(this.$items.values()).some(callbackfn, thisArg);
597
- }
664
+ };
598
665
  /**
599
666
  * Performs the specified action for each element in an array.
600
667
  * @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
601
668
  * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
602
669
  */
603
- forEach(callbackfn, thisArg) {
670
+ ArraySchema.prototype.forEach = function (callbackfn, thisArg) {
604
671
  Array.from(this.$items.values()).forEach(callbackfn, thisArg);
605
- }
672
+ };
606
673
  /**
607
674
  * Calls a defined callback function on each element of an array, and returns an array that contains the results.
608
675
  * @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
609
676
  * @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
610
677
  */
611
- map(callbackfn, thisArg) {
678
+ ArraySchema.prototype.map = function (callbackfn, thisArg) {
612
679
  return Array.from(this.$items.values()).map(callbackfn, thisArg);
613
- }
614
- filter(callbackfn, thisArg) {
680
+ };
681
+ ArraySchema.prototype.filter = function (callbackfn, thisArg) {
615
682
  return Array.from(this.$items.values()).filter(callbackfn, thisArg);
616
- }
683
+ };
617
684
  /**
618
685
  * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
619
686
  * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
620
687
  * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
621
688
  */
622
- reduce(callbackfn, initialValue) {
689
+ ArraySchema.prototype.reduce = function (callbackfn, initialValue) {
623
690
  return Array.from(this.$items.values()).reduce(callbackfn, initialValue);
624
- }
691
+ };
625
692
  /**
626
693
  * Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
627
694
  * @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
628
695
  * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
629
696
  */
630
- reduceRight(callbackfn, initialValue) {
697
+ ArraySchema.prototype.reduceRight = function (callbackfn, initialValue) {
631
698
  return Array.from(this.$items.values()).reduceRight(callbackfn, initialValue);
632
- }
699
+ };
633
700
  /**
634
701
  * Returns the value of the first element in the array where predicate is true, and undefined
635
702
  * otherwise.
@@ -639,9 +706,9 @@ class ArraySchema {
639
706
  * @param thisArg If provided, it will be used as the this value for each invocation of
640
707
  * predicate. If it is not provided, undefined is used instead.
641
708
  */
642
- find(predicate, thisArg) {
709
+ ArraySchema.prototype.find = function (predicate, thisArg) {
643
710
  return Array.from(this.$items.values()).find(predicate, thisArg);
644
- }
711
+ };
645
712
  /**
646
713
  * Returns the index of the first element in the array where predicate is true, and -1
647
714
  * otherwise.
@@ -651,9 +718,9 @@ class ArraySchema {
651
718
  * @param thisArg If provided, it will be used as the this value for each invocation of
652
719
  * predicate. If it is not provided, undefined is used instead.
653
720
  */
654
- findIndex(predicate, thisArg) {
721
+ ArraySchema.prototype.findIndex = function (predicate, thisArg) {
655
722
  return Array.from(this.$items.values()).findIndex(predicate, thisArg);
656
- }
723
+ };
657
724
  /**
658
725
  * Returns the this object after filling the section identified by start and end with value
659
726
  * @param value value to fill array section with
@@ -662,12 +729,12 @@ class ArraySchema {
662
729
  * @param end index to stop filling the array at. If end is negative, it is treated as
663
730
  * length+end.
664
731
  */
665
- fill(value, start, end) {
732
+ ArraySchema.prototype.fill = function (value, start, end) {
666
733
  //
667
734
  // TODO
668
735
  //
669
736
  throw new Error("ArraySchema#fill() not implemented");
670
- }
737
+ };
671
738
  /**
672
739
  * Returns the this object after copying a section of the array identified by start and end
673
740
  * to the same array starting at position target
@@ -677,48 +744,47 @@ class ArraySchema {
677
744
  * is treated as length+end.
678
745
  * @param end If not specified, length of the this object is used as its default value.
679
746
  */
680
- copyWithin(target, start, end) {
747
+ ArraySchema.prototype.copyWithin = function (target, start, end) {
681
748
  //
682
749
  // TODO
683
750
  //
684
751
  throw new Error("ArraySchema#copyWithin() not implemented");
685
- }
752
+ };
686
753
  /**
687
754
  * Returns a string representation of an array.
688
755
  */
689
- toString() { return this.$items.toString(); }
756
+ ArraySchema.prototype.toString = function () { return this.$items.toString(); };
690
757
  /**
691
758
  * Returns a string representation of an array. The elements are converted to string using their toLocalString methods.
692
759
  */
693
- toLocaleString() { return this.$items.toLocaleString(); }
694
- ;
760
+ ArraySchema.prototype.toLocaleString = function () { return this.$items.toLocaleString(); };
695
761
  /** Iterator */
696
- [Symbol.iterator]() {
762
+ ArraySchema.prototype[Symbol.iterator] = function () {
697
763
  return Array.from(this.$items.values())[Symbol.iterator]();
698
- }
699
- [Symbol.unscopables]() {
764
+ };
765
+ ArraySchema.prototype[Symbol.unscopables] = function () {
700
766
  return this.$items[Symbol.unscopables]();
701
- }
767
+ };
702
768
  /**
703
769
  * Returns an iterable of key, value pairs for every entry in the array
704
770
  */
705
- entries() { return this.$items.entries(); }
771
+ ArraySchema.prototype.entries = function () { return this.$items.entries(); };
706
772
  /**
707
773
  * Returns an iterable of keys in the array
708
774
  */
709
- keys() { return this.$items.keys(); }
775
+ ArraySchema.prototype.keys = function () { return this.$items.keys(); };
710
776
  /**
711
777
  * Returns an iterable of values in the array
712
778
  */
713
- values() { return this.$items.values(); }
779
+ ArraySchema.prototype.values = function () { return this.$items.values(); };
714
780
  /**
715
781
  * Determines whether an array includes a certain element, returning true or false as appropriate.
716
782
  * @param searchElement The element to search for.
717
783
  * @param fromIndex The position in this array at which to begin searching for searchElement.
718
784
  */
719
- includes(searchElement, fromIndex) {
785
+ ArraySchema.prototype.includes = function (searchElement, fromIndex) {
720
786
  return Array.from(this.$items.values()).includes(searchElement, fromIndex);
721
- }
787
+ };
722
788
  /**
723
789
  * Calls a defined callback function on each element of an array. Then, flattens the result into
724
790
  * a new array.
@@ -730,10 +796,10 @@ class ArraySchema {
730
796
  * thisArg is omitted, undefined is used as the this value.
731
797
  */
732
798
  // @ts-ignore
733
- flatMap(callback, thisArg) {
799
+ ArraySchema.prototype.flatMap = function (callback, thisArg) {
734
800
  // @ts-ignore
735
801
  throw new Error("ArraySchema#flatMap() is not supported.");
736
- }
802
+ };
737
803
  /**
738
804
  * Returns a new array with all sub-array elements concatenated into it recursively up to the
739
805
  * specified depth.
@@ -741,62 +807,59 @@ class ArraySchema {
741
807
  * @param depth The maximum recursion depth
742
808
  */
743
809
  // @ts-ignore
744
- flat(depth) {
810
+ ArraySchema.prototype.flat = function (depth) {
745
811
  // @ts-ignore
746
812
  throw new Error("ArraySchema#flat() is not supported.");
747
- }
813
+ };
748
814
  // get size () {
749
815
  // return this.$items.size;
750
816
  // }
751
- setIndex(index, key) {
817
+ ArraySchema.prototype.setIndex = function (index, key) {
752
818
  this.$indexes.set(index, key);
753
- }
754
- getIndex(index) {
819
+ };
820
+ ArraySchema.prototype.getIndex = function (index) {
755
821
  return this.$indexes.get(index);
756
- }
757
- getByIndex(index) {
822
+ };
823
+ ArraySchema.prototype.getByIndex = function (index) {
758
824
  return this.$items.get(this.$indexes.get(index));
759
- }
760
- deleteByIndex(index) {
761
- const key = this.$indexes.get(index);
825
+ };
826
+ ArraySchema.prototype.deleteByIndex = function (index) {
827
+ var key = this.$indexes.get(index);
762
828
  this.$items.delete(key);
763
829
  this.$indexes.delete(index);
764
- }
765
- toArray() {
830
+ };
831
+ ArraySchema.prototype.toArray = function () {
766
832
  return Array.from(this.$items.values());
767
- }
768
- toJSON() {
769
- return this.toArray().map((value) => {
833
+ };
834
+ ArraySchema.prototype.toJSON = function () {
835
+ return this.toArray().map(function (value) {
770
836
  return (typeof (value['toJSON']) === "function")
771
837
  ? value['toJSON']()
772
838
  : value;
773
839
  });
774
- }
840
+ };
775
841
  //
776
842
  // Decoding utilities
777
843
  //
778
- clone(isDecoding) {
779
- let cloned;
844
+ ArraySchema.prototype.clone = function (isDecoding) {
845
+ var cloned;
780
846
  if (isDecoding) {
781
- cloned = new ArraySchema(...Array.from(this.$items.values()));
847
+ cloned = new (ArraySchema.bind.apply(ArraySchema, __spreadArray([void 0], Array.from(this.$items.values()))))();
782
848
  }
783
849
  else {
784
- cloned = new ArraySchema(...this.map(item => ((item['$changes'])
850
+ cloned = new (ArraySchema.bind.apply(ArraySchema, __spreadArray([void 0], this.map(function (item) { return ((item['$changes'])
785
851
  ? item.clone()
786
- : item)));
852
+ : item); }))))();
787
853
  }
788
854
  return cloned;
789
- }
790
- ;
791
- triggerAll() {
792
- Schema.prototype.triggerAll.apply(this);
793
- }
794
- }
855
+ };
856
+ return ArraySchema;
857
+ }());
795
858
 
796
859
  function getMapProxy(value) {
797
860
  value['$proxy'] = true;
798
861
  value = new Proxy(value, {
799
- get: (obj, prop) => {
862
+ get: function (obj, prop) {
800
863
  if (typeof (prop) !== "symbol" && // accessing properties
801
864
  typeof (obj[prop]) === "undefined") {
802
865
  return obj.get(prop);
@@ -805,7 +868,7 @@ function getMapProxy(value) {
805
868
  return obj[prop];
806
869
  }
807
870
  },
808
- set: (obj, prop, setValue) => {
871
+ set: function (obj, prop, setValue) {
809
872
  if (typeof (prop) !== "symbol" &&
810
873
  (prop.indexOf("$") === -1 &&
811
874
  prop !== "onAdd" &&
@@ -818,46 +881,62 @@ function getMapProxy(value) {
818
881
  }
819
882
  return true;
820
883
  },
821
- deleteProperty: (obj, prop) => {
884
+ deleteProperty: function (obj, prop) {
822
885
  obj.delete(prop);
823
886
  return true;
824
887
  },
825
888
  });
826
889
  return value;
827
890
  }
828
- class MapSchema {
829
- constructor(initialValues) {
891
+ var MapSchema = /** @class */ (function () {
892
+ function MapSchema(initialValues) {
893
+ var _this = this;
830
894
  this.$changes = new ChangeTree(this);
831
895
  this.$items = new Map();
832
896
  this.$indexes = new Map();
833
897
  this.$refId = 0;
834
898
  if (initialValues) {
835
899
  if (initialValues instanceof Map) {
836
- initialValues.forEach((v, k) => this.set(k, v));
900
+ initialValues.forEach(function (v, k) { return _this.set(k, v); });
837
901
  }
838
902
  else {
839
- for (const k in initialValues) {
903
+ for (var k in initialValues) {
840
904
  this.set(k, initialValues[k]);
841
905
  }
842
906
  }
843
907
  }
844
908
  }
845
- static is(type) {
909
+ MapSchema.prototype.onAdd = function (callback, triggerAll) {
910
+ if (triggerAll === void 0) { triggerAll = true; }
911
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
912
+ ? this.$items
913
+ : undefined);
914
+ };
915
+ MapSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
916
+ MapSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
917
+ MapSchema.is = function (type) {
846
918
  return type['map'] !== undefined;
847
- }
919
+ };
848
920
  /** Iterator */
849
- [Symbol.iterator]() { return this.$items[Symbol.iterator](); }
850
- get [Symbol.toStringTag]() { return this.$items[Symbol.toStringTag]; }
851
- set(key, value) {
921
+ MapSchema.prototype[Symbol.iterator] = function () { return this.$items[Symbol.iterator](); };
922
+ Object.defineProperty(MapSchema.prototype, Symbol.toStringTag, {
923
+ get: function () { return this.$items[Symbol.toStringTag]; },
924
+ enumerable: false,
925
+ configurable: true
926
+ });
927
+ MapSchema.prototype.set = function (key, value) {
928
+ if (value === undefined || value === null) {
929
+ throw new Error("MapSchema#set('" + key + "', " + value + "): trying to set " + value + " value on '" + key + "'.");
930
+ }
852
931
  // get "index" for this value.
853
- const hasIndex = typeof (this.$changes.indexes[key]) !== "undefined";
854
- const index = (hasIndex)
932
+ var hasIndex = typeof (this.$changes.indexes[key]) !== "undefined";
933
+ var index = (hasIndex)
855
934
  ? this.$changes.indexes[key]
856
935
  : this.$refId++;
857
- let operation = (hasIndex)
936
+ var operation = (hasIndex)
858
937
  ? exports.OPERATION.REPLACE
859
938
  : exports.OPERATION.ADD;
860
- const isRef = (value['$changes']) !== undefined;
939
+ var isRef = (value['$changes']) !== undefined;
861
940
  if (isRef) {
862
941
  value['$changes'].setParent(this, this.$changes.root, index);
863
942
  }
@@ -876,11 +955,11 @@ class MapSchema {
876
955
  this.$items.set(key, value);
877
956
  this.$changes.change(key, operation);
878
957
  return this;
879
- }
880
- get(key) {
958
+ };
959
+ MapSchema.prototype.get = function (key) {
881
960
  return this.$items.get(key);
882
- }
883
- delete(key) {
961
+ };
962
+ MapSchema.prototype.delete = function (key) {
884
963
  //
885
964
  // TODO: add a "purge" method after .encode() runs, to cleanup removed `$indexes`
886
965
  //
@@ -891,71 +970,77 @@ class MapSchema {
891
970
  // // this.$indexes.delete(index);
892
971
  this.$changes.delete(key);
893
972
  return this.$items.delete(key);
894
- }
895
- clear(isDecoding) {
973
+ };
974
+ MapSchema.prototype.clear = function (changes) {
896
975
  // discard previous operations.
897
976
  this.$changes.discard(true, true);
898
977
  this.$changes.indexes = {};
899
978
  // clear previous indexes
900
979
  this.$indexes.clear();
901
- // flag child items for garbage collection.
902
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
903
- this.$items.forEach((item) => {
904
- this.$changes.root.removeRef(item['$changes'].refId);
905
- });
980
+ //
981
+ // When decoding:
982
+ // - enqueue items for DELETE callback.
983
+ // - flag child items for garbage collection.
984
+ //
985
+ if (changes) {
986
+ removeChildRefs.call(this, changes);
906
987
  }
907
988
  // clear items
908
989
  this.$items.clear();
909
990
  this.$changes.operation({ index: 0, op: exports.OPERATION.CLEAR });
910
991
  // touch all structures until reach root
911
992
  this.$changes.touchParents();
912
- }
913
- has(key) {
993
+ };
994
+ MapSchema.prototype.has = function (key) {
914
995
  return this.$items.has(key);
915
- }
916
- forEach(callbackfn) {
996
+ };
997
+ MapSchema.prototype.forEach = function (callbackfn) {
917
998
  this.$items.forEach(callbackfn);
918
- }
919
- entries() {
999
+ };
1000
+ MapSchema.prototype.entries = function () {
920
1001
  return this.$items.entries();
921
- }
922
- keys() {
1002
+ };
1003
+ MapSchema.prototype.keys = function () {
923
1004
  return this.$items.keys();
924
- }
925
- values() {
1005
+ };
1006
+ MapSchema.prototype.values = function () {
926
1007
  return this.$items.values();
927
- }
928
- get size() {
929
- return this.$items.size;
930
- }
931
- setIndex(index, key) {
1008
+ };
1009
+ Object.defineProperty(MapSchema.prototype, "size", {
1010
+ get: function () {
1011
+ return this.$items.size;
1012
+ },
1013
+ enumerable: false,
1014
+ configurable: true
1015
+ });
1016
+ MapSchema.prototype.setIndex = function (index, key) {
932
1017
  this.$indexes.set(index, key);
933
- }
934
- getIndex(index) {
1018
+ };
1019
+ MapSchema.prototype.getIndex = function (index) {
935
1020
  return this.$indexes.get(index);
936
- }
937
- getByIndex(index) {
1021
+ };
1022
+ MapSchema.prototype.getByIndex = function (index) {
938
1023
  return this.$items.get(this.$indexes.get(index));
939
- }
940
- deleteByIndex(index) {
941
- const key = this.$indexes.get(index);
1024
+ };
1025
+ MapSchema.prototype.deleteByIndex = function (index) {
1026
+ var key = this.$indexes.get(index);
942
1027
  this.$items.delete(key);
943
1028
  this.$indexes.delete(index);
944
- }
945
- toJSON() {
946
- const map = {};
947
- this.forEach((value, key) => {
1029
+ };
1030
+ MapSchema.prototype.toJSON = function () {
1031
+ var map = {};
1032
+ this.forEach(function (value, key) {
948
1033
  map[key] = (typeof (value['toJSON']) === "function")
949
1034
  ? value['toJSON']()
950
1035
  : value;
951
1036
  });
952
1037
  return map;
953
- }
1038
+ };
954
1039
  //
955
1040
  // Decoding utilities
956
1041
  //
957
- clone(isDecoding) {
958
- let cloned;
1042
+ MapSchema.prototype.clone = function (isDecoding) {
1043
+ var cloned;
959
1044
  if (isDecoding) {
960
1045
  // client-side
961
1046
  cloned = Object.assign(new MapSchema(), this);
@@ -963,7 +1048,7 @@ class MapSchema {
963
1048
  else {
964
1049
  // server-side
965
1050
  cloned = new MapSchema();
966
- this.forEach((value, key) => {
1051
+ this.forEach(function (value, key) {
967
1052
  if (value['$changes']) {
968
1053
  cloned.set(key, value['clone']());
969
1054
  }
@@ -973,13 +1058,11 @@ class MapSchema {
973
1058
  });
974
1059
  }
975
1060
  return cloned;
976
- }
977
- triggerAll() {
978
- Schema.prototype.triggerAll.apply(this);
979
- }
980
- }
1061
+ };
1062
+ return MapSchema;
1063
+ }());
981
1064
 
982
- const registeredTypes = {};
1065
+ var registeredTypes = {};
983
1066
  function registerType(identifier, definition) {
984
1067
  registeredTypes[identifier] = definition;
985
1068
  }
@@ -987,8 +1070,8 @@ function getType(identifier) {
987
1070
  return registeredTypes[identifier];
988
1071
  }
989
1072
 
990
- class SchemaDefinition {
991
- constructor() {
1073
+ var SchemaDefinition = /** @class */ (function () {
1074
+ function SchemaDefinition() {
992
1075
  //
993
1076
  // TODO: use a "field" structure combining all these properties per-field.
994
1077
  //
@@ -997,8 +1080,8 @@ class SchemaDefinition {
997
1080
  this.deprecated = {};
998
1081
  this.descriptors = {};
999
1082
  }
1000
- static create(parent) {
1001
- const definition = new SchemaDefinition();
1083
+ SchemaDefinition.create = function (parent) {
1084
+ var definition = new SchemaDefinition();
1002
1085
  // support inheritance
1003
1086
  definition.schema = Object.assign({}, parent && parent.schema || {});
1004
1087
  definition.indexes = Object.assign({}, parent && parent.indexes || {});
@@ -1006,16 +1089,19 @@ class SchemaDefinition {
1006
1089
  definition.descriptors = Object.assign({}, parent && parent.descriptors || {});
1007
1090
  definition.deprecated = Object.assign({}, parent && parent.deprecated || {});
1008
1091
  return definition;
1009
- }
1010
- addField(field, type) {
1011
- const index = this.getNextFieldIndex();
1092
+ };
1093
+ SchemaDefinition.prototype.addField = function (field, type) {
1094
+ var index = this.getNextFieldIndex();
1012
1095
  this.fieldsByIndex[index] = field;
1013
1096
  this.indexes[field] = index;
1014
1097
  this.schema[field] = (Array.isArray(type))
1015
1098
  ? { array: type[0] }
1016
1099
  : type;
1017
- }
1018
- addFilter(field, cb) {
1100
+ };
1101
+ SchemaDefinition.prototype.hasField = function (field) {
1102
+ return this.indexes[field] !== undefined;
1103
+ };
1104
+ SchemaDefinition.prototype.addFilter = function (field, cb) {
1019
1105
  if (!this.filters) {
1020
1106
  this.filters = {};
1021
1107
  this.indexesWithFilters = [];
@@ -1023,10 +1109,10 @@ class SchemaDefinition {
1023
1109
  this.filters[this.indexes[field]] = cb;
1024
1110
  this.indexesWithFilters.push(this.indexes[field]);
1025
1111
  return true;
1026
- }
1027
- addChildrenFilter(field, cb) {
1028
- const index = this.indexes[field];
1029
- const type = this.schema[field];
1112
+ };
1113
+ SchemaDefinition.prototype.addChildrenFilter = function (field, cb) {
1114
+ var index = this.indexes[field];
1115
+ var type = this.schema[field];
1030
1116
  if (getType(Object.keys(type)[0])) {
1031
1117
  if (!this.childFilters) {
1032
1118
  this.childFilters = {};
@@ -1035,52 +1121,74 @@ class SchemaDefinition {
1035
1121
  return true;
1036
1122
  }
1037
1123
  else {
1038
- console.warn(`@filterChildren: field '${field}' can't have children. Ignoring filter.`);
1124
+ console.warn("@filterChildren: field '" + field + "' can't have children. Ignoring filter.");
1039
1125
  }
1040
- }
1041
- getChildrenFilter(field) {
1126
+ };
1127
+ SchemaDefinition.prototype.getChildrenFilter = function (field) {
1042
1128
  return this.childFilters && this.childFilters[this.indexes[field]];
1043
- }
1044
- getNextFieldIndex() {
1129
+ };
1130
+ SchemaDefinition.prototype.getNextFieldIndex = function () {
1045
1131
  return Object.keys(this.schema || {}).length;
1046
- }
1047
- }
1132
+ };
1133
+ return SchemaDefinition;
1134
+ }());
1048
1135
  function hasFilter(klass) {
1049
1136
  return klass._context && klass._context.useFilters;
1050
1137
  }
1051
- class Context {
1052
- constructor() {
1138
+ var Context = /** @class */ (function () {
1139
+ function Context() {
1053
1140
  this.types = {};
1054
1141
  this.schemas = new Map();
1055
1142
  this.useFilters = false;
1056
1143
  }
1057
- has(schema) {
1144
+ Context.prototype.has = function (schema) {
1058
1145
  return this.schemas.has(schema);
1059
- }
1060
- get(typeid) {
1146
+ };
1147
+ Context.prototype.get = function (typeid) {
1061
1148
  return this.types[typeid];
1062
- }
1063
- add(schema, typeid = this.schemas.size) {
1149
+ };
1150
+ Context.prototype.add = function (schema, typeid) {
1151
+ if (typeid === void 0) { typeid = this.schemas.size; }
1064
1152
  // FIXME: move this to somewhere else?
1065
1153
  // support inheritance
1066
1154
  schema._definition = SchemaDefinition.create(schema._definition);
1067
1155
  schema._typeid = typeid;
1068
1156
  this.types[typeid] = schema;
1069
1157
  this.schemas.set(schema, typeid);
1070
- }
1071
- static create(context = new Context) {
1158
+ };
1159
+ Context.create = function (options) {
1160
+ if (options === void 0) { options = {}; }
1072
1161
  return function (definition) {
1073
- return type(definition, context);
1162
+ if (!options.context) {
1163
+ options.context = new Context();
1164
+ }
1165
+ return type(definition, options);
1074
1166
  };
1075
- }
1076
- }
1077
- const globalContext = new Context();
1167
+ };
1168
+ return Context;
1169
+ }());
1170
+ var globalContext = new Context();
1078
1171
  /**
1079
- * `@type()` decorator for proxies
1172
+ * [See documentation](https://docs.colyseus.io/state/schema/)
1173
+ *
1174
+ * Annotate a Schema property to be serializeable.
1175
+ * \@type()'d fields are automatically flagged as "dirty" for the next patch.
1176
+ *
1177
+ * @example Standard usage, with automatic change tracking.
1178
+ * ```
1179
+ * \@type("string") propertyName: string;
1180
+ * ```
1181
+ *
1182
+ * @example You can provide the "manual" option if you'd like to manually control your patches via .setDirty().
1183
+ * ```
1184
+ * \@type("string", { manual: true })
1185
+ * ```
1080
1186
  */
1081
- function type(type, context = globalContext) {
1187
+ function type(type, options) {
1188
+ if (options === void 0) { options = {}; }
1082
1189
  return function (target, field) {
1083
- const constructor = target.constructor;
1190
+ var context = options.context || globalContext;
1191
+ var constructor = target.constructor;
1084
1192
  constructor._context = context;
1085
1193
  /*
1086
1194
  * static schema
@@ -1088,26 +1196,49 @@ function type(type, context = globalContext) {
1088
1196
  if (!context.has(constructor)) {
1089
1197
  context.add(constructor);
1090
1198
  }
1091
- const definition = constructor._definition;
1199
+ var definition = constructor._definition;
1092
1200
  definition.addField(field, type);
1093
1201
  /**
1094
1202
  * skip if descriptor already exists for this field (`@deprecated()`)
1095
1203
  */
1096
1204
  if (definition.descriptors[field]) {
1097
- return;
1205
+ if (definition.deprecated[field]) {
1206
+ // do not create accessors for deprecated properties.
1207
+ return;
1208
+ }
1209
+ else {
1210
+ // trying to define same property multiple times across inheritance.
1211
+ // https://github.com/colyseus/colyseus-unity3d/issues/131#issuecomment-814308572
1212
+ try {
1213
+ throw new Error("@colyseus/schema: Duplicate '" + field + "' definition on '" + constructor.name + "'.\nCheck @type() annotation");
1214
+ }
1215
+ catch (e) {
1216
+ var definitionAtLine = e.stack.split("\n")[4].trim();
1217
+ throw new Error(e.message + " " + definitionAtLine);
1218
+ }
1219
+ }
1098
1220
  }
1099
- const isArray = ArraySchema.is(type);
1100
- const isMap = !isArray && MapSchema.is(type);
1221
+ var isArray = ArraySchema.is(type);
1222
+ var isMap = !isArray && MapSchema.is(type);
1101
1223
  // TODO: refactor me.
1102
1224
  // Allow abstract intermediary classes with no fields to be serialized
1103
1225
  // (See "should support an inheritance with a Schema type without fields" test)
1104
1226
  if (typeof (type) !== "string" && !Schema.is(type)) {
1105
- const childType = Object.values(type)[0];
1227
+ var childType = Object.values(type)[0];
1106
1228
  if (typeof (childType) !== "string" && !context.has(childType)) {
1107
1229
  context.add(childType);
1108
1230
  }
1109
1231
  }
1110
- const fieldCached = `_${field}`;
1232
+ if (options.manual) {
1233
+ // do not declare getter/setter descriptor
1234
+ definition.descriptors[field] = {
1235
+ enumerable: true,
1236
+ configurable: true,
1237
+ writable: true,
1238
+ };
1239
+ return;
1240
+ }
1241
+ var fieldCached = "_" + field;
1111
1242
  definition.descriptors[fieldCached] = {
1112
1243
  enumerable: false,
1113
1244
  configurable: false,
@@ -1129,7 +1260,7 @@ function type(type, context = globalContext) {
1129
1260
  value !== null) {
1130
1261
  // automaticallty transform Array into ArraySchema
1131
1262
  if (isArray && !(value instanceof ArraySchema)) {
1132
- value = new ArraySchema(...value);
1263
+ value = new (ArraySchema.bind.apply(ArraySchema, __spreadArray([void 0], value)))();
1133
1264
  }
1134
1265
  // automaticallty transform Map into MapSchema
1135
1266
  if (isMap && !(value instanceof MapSchema)) {
@@ -1172,8 +1303,8 @@ function type(type, context = globalContext) {
1172
1303
  */
1173
1304
  function filter(cb) {
1174
1305
  return function (target, field) {
1175
- const constructor = target.constructor;
1176
- const definition = constructor._definition;
1306
+ var constructor = target.constructor;
1307
+ var definition = constructor._definition;
1177
1308
  if (definition.addFilter(field, cb)) {
1178
1309
  constructor._context.useFilters = true;
1179
1310
  }
@@ -1181,8 +1312,8 @@ function filter(cb) {
1181
1312
  }
1182
1313
  function filterChildren(cb) {
1183
1314
  return function (target, field) {
1184
- const constructor = target.constructor;
1185
- const definition = constructor._definition;
1315
+ var constructor = target.constructor;
1316
+ var definition = constructor._definition;
1186
1317
  if (definition.addChildrenFilter(field, cb)) {
1187
1318
  constructor._context.useFilters = true;
1188
1319
  }
@@ -1192,14 +1323,15 @@ function filterChildren(cb) {
1192
1323
  * `@deprecated()` flag a field as deprecated.
1193
1324
  * The previous `@type()` annotation should remain along with this one.
1194
1325
  */
1195
- function deprecated(throws = true, context = globalContext) {
1326
+ function deprecated(throws) {
1327
+ if (throws === void 0) { throws = true; }
1196
1328
  return function (target, field) {
1197
- const constructor = target.constructor;
1198
- const definition = constructor._definition;
1329
+ var constructor = target.constructor;
1330
+ var definition = constructor._definition;
1199
1331
  definition.deprecated[field] = true;
1200
1332
  if (throws) {
1201
1333
  definition.descriptors[field] = {
1202
- get: function () { throw new Error(`${field} is deprecated.`); },
1334
+ get: function () { throw new Error(field + " is deprecated."); },
1203
1335
  set: function (value) { },
1204
1336
  enumerable: false,
1205
1337
  configurable: true
@@ -1207,9 +1339,13 @@ function deprecated(throws = true, context = globalContext) {
1207
1339
  }
1208
1340
  };
1209
1341
  }
1210
- function defineTypes(target, fields, context = target._context || globalContext) {
1211
- for (let field in fields) {
1212
- type(fields[field], context)(target.prototype, field);
1342
+ function defineTypes(target, fields, options) {
1343
+ if (options === void 0) { options = {}; }
1344
+ if (!options.context) {
1345
+ options.context = target._context || options.context || globalContext;
1346
+ }
1347
+ for (var field in fields) {
1348
+ type(fields[field], options)(target.prototype, field);
1213
1349
  }
1214
1350
  return target;
1215
1351
  }
@@ -1307,24 +1443,24 @@ function int32$1(bytes, value) {
1307
1443
  bytes.push((value >> 24) & 255);
1308
1444
  }
1309
1445
  function uint32$1(bytes, value) {
1310
- const b4 = value >> 24;
1311
- const b3 = value >> 16;
1312
- const b2 = value >> 8;
1313
- const b1 = value;
1446
+ var b4 = value >> 24;
1447
+ var b3 = value >> 16;
1448
+ var b2 = value >> 8;
1449
+ var b1 = value;
1314
1450
  bytes.push(b1 & 255);
1315
1451
  bytes.push(b2 & 255);
1316
1452
  bytes.push(b3 & 255);
1317
1453
  bytes.push(b4 & 255);
1318
1454
  }
1319
1455
  function int64$1(bytes, value) {
1320
- const high = Math.floor(value / Math.pow(2, 32));
1321
- const low = value >>> 0;
1456
+ var high = Math.floor(value / Math.pow(2, 32));
1457
+ var low = value >>> 0;
1322
1458
  uint32$1(bytes, low);
1323
1459
  uint32$1(bytes, high);
1324
1460
  }
1325
1461
  function uint64$1(bytes, value) {
1326
- const high = (value / Math.pow(2, 32)) >> 0;
1327
- const low = value >>> 0;
1462
+ var high = (value / Math.pow(2, 32)) >> 0;
1463
+ var low = value >>> 0;
1328
1464
  uint32$1(bytes, low);
1329
1465
  uint32$1(bytes, high);
1330
1466
  }
@@ -1334,9 +1470,9 @@ function float32$1(bytes, value) {
1334
1470
  function float64$1(bytes, value) {
1335
1471
  writeFloat64(bytes, value);
1336
1472
  }
1337
- const _int32$1 = new Int32Array(2);
1338
- const _float32$1 = new Float32Array(_int32$1.buffer);
1339
- const _float64$1 = new Float64Array(_int32$1.buffer);
1473
+ var _int32$1 = new Int32Array(2);
1474
+ var _float32$1 = new Float32Array(_int32$1.buffer);
1475
+ var _float64$1 = new Float64Array(_int32$1.buffer);
1340
1476
  function writeFloat32(bytes, value) {
1341
1477
  _float32$1[0] = value;
1342
1478
  int32$1(bytes, _int32$1[0]);
@@ -1354,8 +1490,8 @@ function string$1(bytes, value) {
1354
1490
  if (!value) {
1355
1491
  value = "";
1356
1492
  }
1357
- let length = utf8Length(value);
1358
- let size = 0;
1493
+ var length = utf8Length(value);
1494
+ var size = 0;
1359
1495
  // fixstr
1360
1496
  if (length < 0x20) {
1361
1497
  bytes.push(length | 0xa0);
@@ -1569,18 +1705,18 @@ function float64(bytes, it) {
1569
1705
  return readFloat64(bytes, it);
1570
1706
  }
1571
1707
  function int64(bytes, it) {
1572
- const low = uint32(bytes, it);
1573
- const high = int32(bytes, it) * Math.pow(2, 32);
1708
+ var low = uint32(bytes, it);
1709
+ var high = int32(bytes, it) * Math.pow(2, 32);
1574
1710
  return high + low;
1575
1711
  }
1576
1712
  function uint64(bytes, it) {
1577
- const low = uint32(bytes, it);
1578
- const high = uint32(bytes, it) * Math.pow(2, 32);
1713
+ var low = uint32(bytes, it);
1714
+ var high = uint32(bytes, it) * Math.pow(2, 32);
1579
1715
  return high + low;
1580
1716
  }
1581
- const _int32 = new Int32Array(2);
1582
- const _float32 = new Float32Array(_int32.buffer);
1583
- const _float64 = new Float64Array(_int32.buffer);
1717
+ var _int32 = new Int32Array(2);
1718
+ var _float32 = new Float32Array(_int32.buffer);
1719
+ var _float64 = new Float64Array(_int32.buffer);
1584
1720
  function readFloat32(bytes, it) {
1585
1721
  _int32[0] = int32(bytes, it);
1586
1722
  return _float32[0];
@@ -1594,8 +1730,8 @@ function boolean(bytes, it) {
1594
1730
  return uint8(bytes, it) > 0;
1595
1731
  }
1596
1732
  function string(bytes, it) {
1597
- const prefix = bytes[it.offset++];
1598
- let length;
1733
+ var prefix = bytes[it.offset++];
1734
+ var length;
1599
1735
  if (prefix < 0xc0) {
1600
1736
  // fixstr
1601
1737
  length = prefix & 0x1f;
@@ -1609,12 +1745,12 @@ function string(bytes, it) {
1609
1745
  else if (prefix === 0xdb) {
1610
1746
  length = uint32(bytes, it);
1611
1747
  }
1612
- const value = utf8Read(bytes, it.offset, length);
1748
+ var value = utf8Read(bytes, it.offset, length);
1613
1749
  it.offset += length;
1614
1750
  return value;
1615
1751
  }
1616
1752
  function stringCheck(bytes, it) {
1617
- const prefix = bytes[it.offset];
1753
+ var prefix = bytes[it.offset];
1618
1754
  return (
1619
1755
  // fixstr
1620
1756
  (prefix < 0xc0 && prefix > 0xa0) ||
@@ -1626,7 +1762,7 @@ function stringCheck(bytes, it) {
1626
1762
  prefix === 0xdb);
1627
1763
  }
1628
1764
  function number(bytes, it) {
1629
- const prefix = bytes[it.offset++];
1765
+ var prefix = bytes[it.offset++];
1630
1766
  if (prefix < 0x80) {
1631
1767
  // positive fixint
1632
1768
  return prefix;
@@ -1677,7 +1813,7 @@ function number(bytes, it) {
1677
1813
  }
1678
1814
  }
1679
1815
  function numberCheck(bytes, it) {
1680
- const prefix = bytes[it.offset];
1816
+ var prefix = bytes[it.offset];
1681
1817
  // positive fixint - 0x00 - 0x7f
1682
1818
  // float 32 - 0xca
1683
1819
  // float 64 - 0xcb
@@ -1736,23 +1872,32 @@ var decode = /*#__PURE__*/Object.freeze({
1736
1872
  switchStructureCheck: switchStructureCheck
1737
1873
  });
1738
1874
 
1739
- class CollectionSchema {
1740
- constructor(initialValues) {
1875
+ var CollectionSchema = /** @class */ (function () {
1876
+ function CollectionSchema(initialValues) {
1877
+ var _this = this;
1741
1878
  this.$changes = new ChangeTree(this);
1742
1879
  this.$items = new Map();
1743
1880
  this.$indexes = new Map();
1744
1881
  this.$refId = 0;
1745
1882
  if (initialValues) {
1746
- initialValues.forEach((v) => this.add(v));
1883
+ initialValues.forEach(function (v) { return _this.add(v); });
1747
1884
  }
1748
1885
  }
1749
- static is(type) {
1886
+ CollectionSchema.prototype.onAdd = function (callback, triggerAll) {
1887
+ if (triggerAll === void 0) { triggerAll = true; }
1888
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
1889
+ ? this.$items
1890
+ : undefined);
1891
+ };
1892
+ CollectionSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
1893
+ CollectionSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
1894
+ CollectionSchema.is = function (type) {
1750
1895
  return type['collection'] !== undefined;
1751
- }
1752
- add(value) {
1896
+ };
1897
+ CollectionSchema.prototype.add = function (value) {
1753
1898
  // set "index" for reference.
1754
- const index = this.$refId++;
1755
- const isRef = (value['$changes']) !== undefined;
1899
+ var index = this.$refId++;
1900
+ var isRef = (value['$changes']) !== undefined;
1756
1901
  if (isRef) {
1757
1902
  value['$changes'].setParent(this, this.$changes.root, index);
1758
1903
  }
@@ -1761,18 +1906,18 @@ class CollectionSchema {
1761
1906
  this.$items.set(index, value);
1762
1907
  this.$changes.change(index);
1763
1908
  return index;
1764
- }
1765
- at(index) {
1766
- const key = Array.from(this.$items.keys())[index];
1909
+ };
1910
+ CollectionSchema.prototype.at = function (index) {
1911
+ var key = Array.from(this.$items.keys())[index];
1767
1912
  return this.$items.get(key);
1768
- }
1769
- entries() {
1913
+ };
1914
+ CollectionSchema.prototype.entries = function () {
1770
1915
  return this.$items.entries();
1771
- }
1772
- delete(item) {
1773
- const entries = this.$items.entries();
1774
- let index;
1775
- let entry;
1916
+ };
1917
+ CollectionSchema.prototype.delete = function (item) {
1918
+ var entries = this.$items.entries();
1919
+ var index;
1920
+ var entry;
1776
1921
  while (entry = entries.next()) {
1777
1922
  if (entry.done) {
1778
1923
  break;
@@ -1788,68 +1933,75 @@ class CollectionSchema {
1788
1933
  this.$changes.delete(index);
1789
1934
  this.$indexes.delete(index);
1790
1935
  return this.$items.delete(index);
1791
- }
1792
- clear(isDecoding) {
1936
+ };
1937
+ CollectionSchema.prototype.clear = function (changes) {
1793
1938
  // discard previous operations.
1794
1939
  this.$changes.discard(true, true);
1795
1940
  this.$changes.indexes = {};
1796
1941
  // clear previous indexes
1797
1942
  this.$indexes.clear();
1798
- // flag child items for garbage collection.
1799
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
1800
- this.$items.forEach((item) => {
1801
- this.$changes.root.removeRef(item['$changes'].refId);
1802
- });
1943
+ //
1944
+ // When decoding:
1945
+ // - enqueue items for DELETE callback.
1946
+ // - flag child items for garbage collection.
1947
+ //
1948
+ if (changes) {
1949
+ removeChildRefs.call(this, changes);
1803
1950
  }
1804
1951
  // clear items
1805
1952
  this.$items.clear();
1806
1953
  this.$changes.operation({ index: 0, op: exports.OPERATION.CLEAR });
1807
1954
  // touch all structures until reach root
1808
1955
  this.$changes.touchParents();
1809
- }
1810
- has(value) {
1811
- return Array.from(this.$items.values()).some((v) => v === value);
1812
- }
1813
- forEach(callbackfn) {
1814
- this.$items.forEach((value, key, _) => callbackfn(value, key, this));
1815
- }
1816
- values() {
1956
+ };
1957
+ CollectionSchema.prototype.has = function (value) {
1958
+ return Array.from(this.$items.values()).some(function (v) { return v === value; });
1959
+ };
1960
+ CollectionSchema.prototype.forEach = function (callbackfn) {
1961
+ var _this = this;
1962
+ this.$items.forEach(function (value, key, _) { return callbackfn(value, key, _this); });
1963
+ };
1964
+ CollectionSchema.prototype.values = function () {
1817
1965
  return this.$items.values();
1818
- }
1819
- get size() {
1820
- return this.$items.size;
1821
- }
1822
- setIndex(index, key) {
1966
+ };
1967
+ Object.defineProperty(CollectionSchema.prototype, "size", {
1968
+ get: function () {
1969
+ return this.$items.size;
1970
+ },
1971
+ enumerable: false,
1972
+ configurable: true
1973
+ });
1974
+ CollectionSchema.prototype.setIndex = function (index, key) {
1823
1975
  this.$indexes.set(index, key);
1824
- }
1825
- getIndex(index) {
1976
+ };
1977
+ CollectionSchema.prototype.getIndex = function (index) {
1826
1978
  return this.$indexes.get(index);
1827
- }
1828
- getByIndex(index) {
1979
+ };
1980
+ CollectionSchema.prototype.getByIndex = function (index) {
1829
1981
  return this.$items.get(this.$indexes.get(index));
1830
- }
1831
- deleteByIndex(index) {
1832
- const key = this.$indexes.get(index);
1982
+ };
1983
+ CollectionSchema.prototype.deleteByIndex = function (index) {
1984
+ var key = this.$indexes.get(index);
1833
1985
  this.$items.delete(key);
1834
1986
  this.$indexes.delete(index);
1835
- }
1836
- toArray() {
1987
+ };
1988
+ CollectionSchema.prototype.toArray = function () {
1837
1989
  return Array.from(this.$items.values());
1838
- }
1839
- toJSON() {
1840
- const values = [];
1841
- this.forEach((value, key) => {
1990
+ };
1991
+ CollectionSchema.prototype.toJSON = function () {
1992
+ var values = [];
1993
+ this.forEach(function (value, key) {
1842
1994
  values.push((typeof (value['toJSON']) === "function")
1843
1995
  ? value['toJSON']()
1844
1996
  : value);
1845
1997
  });
1846
1998
  return values;
1847
- }
1999
+ };
1848
2000
  //
1849
2001
  // Decoding utilities
1850
2002
  //
1851
- clone(isDecoding) {
1852
- let cloned;
2003
+ CollectionSchema.prototype.clone = function (isDecoding) {
2004
+ var cloned;
1853
2005
  if (isDecoding) {
1854
2006
  // client-side
1855
2007
  cloned = Object.assign(new CollectionSchema(), this);
@@ -1857,7 +2009,7 @@ class CollectionSchema {
1857
2009
  else {
1858
2010
  // server-side
1859
2011
  cloned = new CollectionSchema();
1860
- this.forEach((value) => {
2012
+ this.forEach(function (value) {
1861
2013
  if (value['$changes']) {
1862
2014
  cloned.add(value['clone']());
1863
2015
  }
@@ -1867,48 +2019,57 @@ class CollectionSchema {
1867
2019
  });
1868
2020
  }
1869
2021
  return cloned;
1870
- }
1871
- triggerAll() {
1872
- Schema.prototype.triggerAll.apply(this);
1873
- }
1874
- }
2022
+ };
2023
+ return CollectionSchema;
2024
+ }());
1875
2025
 
1876
- class SetSchema {
1877
- constructor(initialValues) {
2026
+ var SetSchema = /** @class */ (function () {
2027
+ function SetSchema(initialValues) {
2028
+ var _this = this;
1878
2029
  this.$changes = new ChangeTree(this);
1879
2030
  this.$items = new Map();
1880
2031
  this.$indexes = new Map();
1881
2032
  this.$refId = 0;
1882
2033
  if (initialValues) {
1883
- initialValues.forEach((v) => this.add(v));
2034
+ initialValues.forEach(function (v) { return _this.add(v); });
1884
2035
  }
1885
2036
  }
1886
- static is(type) {
2037
+ SetSchema.prototype.onAdd = function (callback, triggerAll) {
2038
+ if (triggerAll === void 0) { triggerAll = true; }
2039
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
2040
+ ? this.$items
2041
+ : undefined);
2042
+ };
2043
+ SetSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
2044
+ SetSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
2045
+ SetSchema.is = function (type) {
1887
2046
  return type['set'] !== undefined;
1888
- }
1889
- add(value) {
2047
+ };
2048
+ SetSchema.prototype.add = function (value) {
2049
+ var _a, _b;
2050
+ // immediatelly return false if value already added.
1890
2051
  if (this.has(value)) {
1891
2052
  return false;
1892
2053
  }
1893
2054
  // set "index" for reference.
1894
- const index = this.$refId++;
1895
- const isRef = (value['$changes']) !== undefined;
1896
- if (isRef) {
2055
+ var index = this.$refId++;
2056
+ if ((value['$changes']) !== undefined) {
1897
2057
  value['$changes'].setParent(this, this.$changes.root, index);
1898
2058
  }
2059
+ var operation = (_b = (_a = this.$changes.indexes[index]) === null || _a === void 0 ? void 0 : _a.op) !== null && _b !== void 0 ? _b : exports.OPERATION.ADD;
1899
2060
  this.$changes.indexes[index] = index;
1900
2061
  this.$indexes.set(index, index);
1901
2062
  this.$items.set(index, value);
1902
- this.$changes.change(index);
2063
+ this.$changes.change(index, operation);
1903
2064
  return index;
1904
- }
1905
- entries() {
2065
+ };
2066
+ SetSchema.prototype.entries = function () {
1906
2067
  return this.$items.entries();
1907
- }
1908
- delete(item) {
1909
- const entries = this.$items.entries();
1910
- let index;
1911
- let entry;
2068
+ };
2069
+ SetSchema.prototype.delete = function (item) {
2070
+ var entries = this.$items.entries();
2071
+ var index;
2072
+ var entry;
1912
2073
  while (entry = entries.next()) {
1913
2074
  if (entry.done) {
1914
2075
  break;
@@ -1924,29 +2085,31 @@ class SetSchema {
1924
2085
  this.$changes.delete(index);
1925
2086
  this.$indexes.delete(index);
1926
2087
  return this.$items.delete(index);
1927
- }
1928
- clear(isDecoding) {
2088
+ };
2089
+ SetSchema.prototype.clear = function (changes) {
1929
2090
  // discard previous operations.
1930
2091
  this.$changes.discard(true, true);
1931
2092
  this.$changes.indexes = {};
1932
2093
  // clear previous indexes
1933
2094
  this.$indexes.clear();
1934
- // flag child items for garbage collection.
1935
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
1936
- this.$items.forEach((item) => {
1937
- this.$changes.root.removeRef(item['$changes'].refId);
1938
- });
2095
+ //
2096
+ // When decoding:
2097
+ // - enqueue items for DELETE callback.
2098
+ // - flag child items for garbage collection.
2099
+ //
2100
+ if (changes) {
2101
+ removeChildRefs.call(this, changes);
1939
2102
  }
1940
2103
  // clear items
1941
2104
  this.$items.clear();
1942
2105
  this.$changes.operation({ index: 0, op: exports.OPERATION.CLEAR });
1943
2106
  // touch all structures until reach root
1944
2107
  this.$changes.touchParents();
1945
- }
1946
- has(value) {
1947
- const values = this.$items.values();
1948
- let has = false;
1949
- let entry;
2108
+ };
2109
+ SetSchema.prototype.has = function (value) {
2110
+ var values = this.$items.values();
2111
+ var has = false;
2112
+ var entry;
1950
2113
  while (entry = values.next()) {
1951
2114
  if (entry.done) {
1952
2115
  break;
@@ -1957,47 +2120,52 @@ class SetSchema {
1957
2120
  }
1958
2121
  }
1959
2122
  return has;
1960
- }
1961
- forEach(callbackfn) {
1962
- this.$items.forEach((value, key, _) => callbackfn(value, key, this));
1963
- }
1964
- values() {
2123
+ };
2124
+ SetSchema.prototype.forEach = function (callbackfn) {
2125
+ var _this = this;
2126
+ this.$items.forEach(function (value, key, _) { return callbackfn(value, key, _this); });
2127
+ };
2128
+ SetSchema.prototype.values = function () {
1965
2129
  return this.$items.values();
1966
- }
1967
- get size() {
1968
- return this.$items.size;
1969
- }
1970
- setIndex(index, key) {
2130
+ };
2131
+ Object.defineProperty(SetSchema.prototype, "size", {
2132
+ get: function () {
2133
+ return this.$items.size;
2134
+ },
2135
+ enumerable: false,
2136
+ configurable: true
2137
+ });
2138
+ SetSchema.prototype.setIndex = function (index, key) {
1971
2139
  this.$indexes.set(index, key);
1972
- }
1973
- getIndex(index) {
2140
+ };
2141
+ SetSchema.prototype.getIndex = function (index) {
1974
2142
  return this.$indexes.get(index);
1975
- }
1976
- getByIndex(index) {
2143
+ };
2144
+ SetSchema.prototype.getByIndex = function (index) {
1977
2145
  return this.$items.get(this.$indexes.get(index));
1978
- }
1979
- deleteByIndex(index) {
1980
- const key = this.$indexes.get(index);
2146
+ };
2147
+ SetSchema.prototype.deleteByIndex = function (index) {
2148
+ var key = this.$indexes.get(index);
1981
2149
  this.$items.delete(key);
1982
2150
  this.$indexes.delete(index);
1983
- }
1984
- toArray() {
2151
+ };
2152
+ SetSchema.prototype.toArray = function () {
1985
2153
  return Array.from(this.$items.values());
1986
- }
1987
- toJSON() {
1988
- const values = [];
1989
- this.forEach((value, key) => {
2154
+ };
2155
+ SetSchema.prototype.toJSON = function () {
2156
+ var values = [];
2157
+ this.forEach(function (value, key) {
1990
2158
  values.push((typeof (value['toJSON']) === "function")
1991
2159
  ? value['toJSON']()
1992
2160
  : value);
1993
2161
  });
1994
2162
  return values;
1995
- }
2163
+ };
1996
2164
  //
1997
2165
  // Decoding utilities
1998
2166
  //
1999
- clone(isDecoding) {
2000
- let cloned;
2167
+ SetSchema.prototype.clone = function (isDecoding) {
2168
+ var cloned;
2001
2169
  if (isDecoding) {
2002
2170
  // client-side
2003
2171
  cloned = Object.assign(new SetSchema(), this);
@@ -2005,7 +2173,7 @@ class SetSchema {
2005
2173
  else {
2006
2174
  // server-side
2007
2175
  cloned = new SetSchema();
2008
- this.forEach((value) => {
2176
+ this.forEach(function (value) {
2009
2177
  if (value['$changes']) {
2010
2178
  cloned.add(value['clone']());
2011
2179
  }
@@ -2015,64 +2183,113 @@ class SetSchema {
2015
2183
  });
2016
2184
  }
2017
2185
  return cloned;
2018
- }
2019
- triggerAll() {
2020
- Schema.prototype.triggerAll.apply(this);
2021
- }
2022
- }
2023
-
2024
- /**
2025
- * Extracted from https://www.npmjs.com/package/strong-events
2026
- */
2027
- class EventEmitter {
2028
- constructor() {
2029
- this.handlers = [];
2030
- }
2031
- register(cb, once = false) {
2032
- this.handlers.push(cb);
2033
- return this;
2034
- }
2035
- invoke(...args) {
2036
- this.handlers.forEach((handler) => handler(...args));
2037
- }
2038
- invokeAsync(...args) {
2039
- return Promise.all(this.handlers.map((handler) => handler(...args)));
2040
- }
2041
- remove(cb) {
2042
- const index = this.handlers.indexOf(cb);
2043
- this.handlers[index] = this.handlers[this.handlers.length - 1];
2044
- this.handlers.pop();
2045
- }
2046
- clear() {
2047
- this.handlers = [];
2048
- }
2049
- }
2186
+ };
2187
+ return SetSchema;
2188
+ }());
2050
2189
 
2051
- class ClientState {
2052
- constructor() {
2190
+ var ClientState = /** @class */ (function () {
2191
+ function ClientState() {
2053
2192
  this.refIds = new WeakSet();
2054
2193
  this.containerIndexes = new WeakMap();
2055
2194
  }
2056
2195
  // containerIndexes = new Map<ChangeTree, Set<number>>();
2057
- addRefId(changeTree) {
2196
+ ClientState.prototype.addRefId = function (changeTree) {
2058
2197
  if (!this.refIds.has(changeTree)) {
2059
2198
  this.refIds.add(changeTree);
2060
2199
  this.containerIndexes.set(changeTree, new Set());
2061
2200
  }
2062
- }
2063
- static get(client) {
2201
+ };
2202
+ ClientState.get = function (client) {
2064
2203
  if (client.$filterState === undefined) {
2065
2204
  client.$filterState = new ClientState();
2066
2205
  }
2067
2206
  return client.$filterState;
2207
+ };
2208
+ return ClientState;
2209
+ }());
2210
+
2211
+ var ReferenceTracker = /** @class */ (function () {
2212
+ function ReferenceTracker() {
2213
+ //
2214
+ // Relation of refId => Schema structure
2215
+ // For direct access of structures during decoding time.
2216
+ //
2217
+ this.refs = new Map();
2218
+ this.refCounts = {};
2219
+ this.deletedRefs = new Set();
2220
+ this.nextUniqueId = 0;
2068
2221
  }
2069
- }
2222
+ ReferenceTracker.prototype.getNextUniqueId = function () {
2223
+ return this.nextUniqueId++;
2224
+ };
2225
+ // for decoding
2226
+ ReferenceTracker.prototype.addRef = function (refId, ref, incrementCount) {
2227
+ if (incrementCount === void 0) { incrementCount = true; }
2228
+ this.refs.set(refId, ref);
2229
+ if (incrementCount) {
2230
+ this.refCounts[refId] = (this.refCounts[refId] || 0) + 1;
2231
+ }
2232
+ };
2233
+ // for decoding
2234
+ ReferenceTracker.prototype.removeRef = function (refId) {
2235
+ this.refCounts[refId] = this.refCounts[refId] - 1;
2236
+ this.deletedRefs.add(refId);
2237
+ };
2238
+ ReferenceTracker.prototype.clearRefs = function () {
2239
+ this.refs.clear();
2240
+ this.deletedRefs.clear();
2241
+ this.refCounts = {};
2242
+ };
2243
+ // for decoding
2244
+ ReferenceTracker.prototype.garbageCollectDeletedRefs = function () {
2245
+ var _this = this;
2246
+ this.deletedRefs.forEach(function (refId) {
2247
+ //
2248
+ // Skip active references.
2249
+ //
2250
+ if (_this.refCounts[refId] > 0) {
2251
+ return;
2252
+ }
2253
+ var ref = _this.refs.get(refId);
2254
+ //
2255
+ // Ensure child schema instances have their references removed as well.
2256
+ //
2257
+ if (ref instanceof Schema) {
2258
+ for (var fieldName in ref['_definition'].schema) {
2259
+ if (typeof (ref['_definition'].schema[fieldName]) !== "string" &&
2260
+ ref[fieldName] &&
2261
+ ref[fieldName]['$changes']) {
2262
+ _this.removeRef(ref[fieldName]['$changes'].refId);
2263
+ }
2264
+ }
2265
+ }
2266
+ else {
2267
+ var definition = ref['$changes'].parent._definition;
2268
+ var type = definition.schema[definition.fieldsByIndex[ref['$changes'].parentIndex]];
2269
+ if (typeof (Object.values(type)[0]) === "function") {
2270
+ Array.from(ref.values())
2271
+ .forEach(function (child) { return _this.removeRef(child['$changes'].refId); });
2272
+ }
2273
+ }
2274
+ _this.refs.delete(refId);
2275
+ delete _this.refCounts[refId];
2276
+ });
2277
+ // clear deleted refs.
2278
+ this.deletedRefs.clear();
2279
+ };
2280
+ return ReferenceTracker;
2281
+ }());
2070
2282
 
2071
- class EncodeSchemaError extends Error {
2072
- }
2283
+ var EncodeSchemaError = /** @class */ (function (_super) {
2284
+ __extends(EncodeSchemaError, _super);
2285
+ function EncodeSchemaError() {
2286
+ return _super !== null && _super.apply(this, arguments) || this;
2287
+ }
2288
+ return EncodeSchemaError;
2289
+ }(Error));
2073
2290
  function assertType(value, type, klass, field) {
2074
- let typeofTarget;
2075
- let allowNull = false;
2291
+ var typeofTarget;
2292
+ var allowNull = false;
2076
2293
  switch (type) {
2077
2294
  case "number":
2078
2295
  case "int8":
@@ -2087,7 +2304,7 @@ function assertType(value, type, klass, field) {
2087
2304
  case "float64":
2088
2305
  typeofTarget = "number";
2089
2306
  if (isNaN(value)) {
2090
- console.log(`trying to encode "NaN" in ${klass.constructor.name}#${field}`);
2307
+ console.log("trying to encode \"NaN\" in " + klass.constructor.name + "#" + field);
2091
2308
  }
2092
2309
  break;
2093
2310
  case "string":
@@ -2099,23 +2316,23 @@ function assertType(value, type, klass, field) {
2099
2316
  return;
2100
2317
  }
2101
2318
  if (typeof (value) !== typeofTarget && (!allowNull || (allowNull && value !== null))) {
2102
- let foundValue = `'${JSON.stringify(value)}'${(value && value.constructor && ` (${value.constructor.name})`) || ''}`;
2103
- throw new EncodeSchemaError(`a '${typeofTarget}' was expected, but ${foundValue} was provided in ${klass.constructor.name}#${field}`);
2319
+ var foundValue = "'" + JSON.stringify(value) + "'" + ((value && value.constructor && " (" + value.constructor.name + ")") || '');
2320
+ throw new EncodeSchemaError("a '" + typeofTarget + "' was expected, but " + foundValue + " was provided in " + klass.constructor.name + "#" + field);
2104
2321
  }
2105
2322
  }
2106
2323
  function assertInstanceType(value, type, klass, field) {
2107
2324
  if (!(value instanceof type)) {
2108
- throw new EncodeSchemaError(`a '${type.name}' was expected, but '${value.constructor.name}' was provided in ${klass.constructor.name}#${field}`);
2325
+ throw new EncodeSchemaError("a '" + type.name + "' was expected, but '" + value.constructor.name + "' was provided in " + klass.constructor.name + "#" + field);
2109
2326
  }
2110
2327
  }
2111
2328
  function encodePrimitiveType(type, bytes, value, klass, field) {
2112
2329
  assertType(value, type, klass, field);
2113
- const encodeFunc = encode[type];
2330
+ var encodeFunc = encode[type];
2114
2331
  if (encodeFunc) {
2115
2332
  encodeFunc(bytes, value);
2116
2333
  }
2117
2334
  else {
2118
- throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);
2335
+ throw new EncodeSchemaError("a '" + type + "' was expected, but " + value + " was provided in " + klass.constructor.name + "#" + field);
2119
2336
  }
2120
2337
  }
2121
2338
  function decodePrimitiveType(type, bytes, it) {
@@ -2124,23 +2341,32 @@ function decodePrimitiveType(type, bytes, it) {
2124
2341
  /**
2125
2342
  * Schema encoder / decoder
2126
2343
  */
2127
- class Schema {
2344
+ var Schema = /** @class */ (function () {
2128
2345
  // allow inherited classes to have a constructor
2129
- constructor(...args) {
2346
+ function Schema() {
2347
+ var args = [];
2348
+ for (var _i = 0; _i < arguments.length; _i++) {
2349
+ args[_i] = arguments[_i];
2350
+ }
2130
2351
  // fix enumerability of fields for end-user
2131
2352
  Object.defineProperties(this, {
2132
2353
  $changes: {
2133
- value: new ChangeTree(this, undefined, new Root()),
2354
+ value: new ChangeTree(this, undefined, new ReferenceTracker()),
2134
2355
  enumerable: false,
2135
2356
  writable: true
2136
2357
  },
2137
- $listeners: {
2138
- value: {},
2358
+ // $listeners: {
2359
+ // value: undefined,
2360
+ // enumerable: false,
2361
+ // writable: true
2362
+ // },
2363
+ $callbacks: {
2364
+ value: undefined,
2139
2365
  enumerable: false,
2140
2366
  writable: true
2141
2367
  },
2142
2368
  });
2143
- const descriptors = this._definition.descriptors;
2369
+ var descriptors = this._definition.descriptors;
2144
2370
  if (descriptors) {
2145
2371
  Object.defineProperties(this, descriptors);
2146
2372
  }
@@ -2151,53 +2377,74 @@ class Schema {
2151
2377
  this.assign(args[0]);
2152
2378
  }
2153
2379
  }
2154
- static onError(e) {
2380
+ Schema.onError = function (e) {
2155
2381
  console.error(e);
2156
- }
2157
- static is(type) {
2382
+ };
2383
+ Schema.is = function (type) {
2158
2384
  return (type['_definition'] &&
2159
2385
  type['_definition'].schema !== undefined);
2160
- }
2161
- assign(props) {
2386
+ };
2387
+ Schema.prototype.onChange = function (callback) {
2388
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.REPLACE, callback);
2389
+ };
2390
+ Schema.prototype.onRemove = function (callback) {
2391
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.DELETE, callback);
2392
+ };
2393
+ Schema.prototype.assign = function (props) {
2162
2394
  Object.assign(this, props);
2163
2395
  return this;
2164
- }
2165
- get _definition() { return this.constructor._definition; }
2166
- listen(attr, callback) {
2167
- if (!this.$listeners[attr]) {
2168
- this.$listeners[attr] = new EventEmitter();
2396
+ };
2397
+ Object.defineProperty(Schema.prototype, "_definition", {
2398
+ get: function () { return this.constructor._definition; },
2399
+ enumerable: false,
2400
+ configurable: true
2401
+ });
2402
+ /**
2403
+ * (Server-side): Flag a property to be encoded for the next patch.
2404
+ * @param instance Schema instance
2405
+ * @param property string representing the property name, or number representing the index of the property.
2406
+ * @param operation OPERATION to perform (detected automatically)
2407
+ */
2408
+ Schema.prototype.setDirty = function (property, operation) {
2409
+ this.$changes.change(property, operation);
2410
+ };
2411
+ Schema.prototype.listen = function (attr, callback) {
2412
+ var _this = this;
2413
+ if (!this.$callbacks) {
2414
+ this.$callbacks = {};
2415
+ }
2416
+ if (!this.$callbacks[attr]) {
2417
+ this.$callbacks[attr] = [];
2169
2418
  }
2170
- this.$listeners[attr].register(callback);
2419
+ this.$callbacks[attr].push(callback);
2171
2420
  // return un-register callback.
2172
- return () => this.$listeners[attr].remove(callback);
2173
- }
2174
- decode(bytes, it = { offset: 0 }, ref = this, allChanges = new Map()) {
2175
- const $root = this.$changes.root;
2176
- const totalBytes = bytes.length;
2177
- let refId = 0;
2178
- let changes = [];
2421
+ return function () { return spliceOne(_this.$callbacks[attr], _this.$callbacks[attr].indexOf(callback)); };
2422
+ };
2423
+ Schema.prototype.decode = function (bytes, it, ref) {
2424
+ if (it === void 0) { it = { offset: 0 }; }
2425
+ if (ref === void 0) { ref = this; }
2426
+ var allChanges = [];
2427
+ var $root = this.$changes.root;
2428
+ var totalBytes = bytes.length;
2429
+ var refId = 0;
2179
2430
  $root.refs.set(refId, this);
2180
- allChanges.set(refId, changes);
2181
2431
  while (it.offset < totalBytes) {
2182
- let byte = bytes[it.offset++];
2432
+ var byte = bytes[it.offset++];
2183
2433
  if (byte == SWITCH_TO_STRUCTURE) {
2184
2434
  refId = number(bytes, it);
2185
- const nextRef = $root.refs.get(refId);
2435
+ var nextRef = $root.refs.get(refId);
2186
2436
  //
2187
2437
  // Trying to access a reference that haven't been decoded yet.
2188
2438
  //
2189
2439
  if (!nextRef) {
2190
- throw new Error(`"refId" not found: ${refId}`);
2440
+ throw new Error("\"refId\" not found: " + refId);
2191
2441
  }
2192
2442
  ref = nextRef;
2193
- // create empty list of changes for this refId.
2194
- changes = [];
2195
- allChanges.set(refId, changes);
2196
2443
  continue;
2197
2444
  }
2198
- const changeTree = ref['$changes'];
2199
- const isSchema = (ref['_definition'] !== undefined);
2200
- const operation = (isSchema)
2445
+ var changeTree = ref['$changes'];
2446
+ var isSchema = (ref['_definition'] !== undefined);
2447
+ var operation = (isSchema)
2201
2448
  ? (byte >> 6) << 6 // "compressed" index + operation
2202
2449
  : byte; // "uncompressed" index + operation (array/map items)
2203
2450
  if (operation === exports.OPERATION.CLEAR) {
@@ -2206,19 +2453,19 @@ class Schema {
2206
2453
  // The `.clear()` method is calling `$root.removeRef(refId)` for
2207
2454
  // each item inside this collection
2208
2455
  //
2209
- ref.clear(true);
2456
+ ref.clear(allChanges);
2210
2457
  continue;
2211
2458
  }
2212
- const fieldIndex = (isSchema)
2459
+ var fieldIndex = (isSchema)
2213
2460
  ? byte % (operation || 255) // if "REPLACE" operation (0), use 255
2214
2461
  : number(bytes, it);
2215
- const fieldName = (isSchema)
2462
+ var fieldName = (isSchema)
2216
2463
  ? (ref['_definition'].fieldsByIndex[fieldIndex])
2217
2464
  : "";
2218
- let type = changeTree.getType(fieldIndex);
2219
- let value;
2220
- let previousValue;
2221
- let dynamicIndex;
2465
+ var type = changeTree.getType(fieldIndex);
2466
+ var value = void 0;
2467
+ var previousValue = void 0;
2468
+ var dynamicIndex = void 0;
2222
2469
  if (!isSchema) {
2223
2470
  previousValue = ref['getByIndex'](fieldIndex);
2224
2471
  if ((operation & exports.OPERATION.ADD) === exports.OPERATION.ADD) { // ADD or DELETE_AND_ADD
@@ -2233,7 +2480,7 @@ class Schema {
2233
2480
  }
2234
2481
  }
2235
2482
  else {
2236
- previousValue = ref[`_${fieldName}`];
2483
+ previousValue = ref["_" + fieldName];
2237
2484
  }
2238
2485
  //
2239
2486
  // Delete operations
@@ -2254,7 +2501,7 @@ class Schema {
2254
2501
  // keep skipping next bytes until reaches a known structure
2255
2502
  // by local decoder.
2256
2503
  //
2257
- const nextIterator = { offset: it.offset };
2504
+ var nextIterator = { offset: it.offset };
2258
2505
  while (it.offset < totalBytes) {
2259
2506
  if (switchStructureCheck(bytes, it)) {
2260
2507
  nextIterator.offset = it.offset + 1;
@@ -2268,24 +2515,23 @@ class Schema {
2268
2515
  }
2269
2516
  else if (operation === exports.OPERATION.DELETE) ;
2270
2517
  else if (Schema.is(type)) {
2271
- const refId = number(bytes, it);
2272
- value = $root.refs.get(refId);
2518
+ var refId_1 = number(bytes, it);
2519
+ value = $root.refs.get(refId_1);
2273
2520
  if (operation !== exports.OPERATION.REPLACE) {
2274
- const childType = this.getSchemaType(bytes, it, type);
2521
+ var childType = this.getSchemaType(bytes, it, type);
2275
2522
  if (!value) {
2276
2523
  value = this.createTypeInstance(childType);
2277
- value.$changes.refId = refId;
2524
+ value.$changes.refId = refId_1;
2278
2525
  if (previousValue) {
2279
- value.onChange = previousValue.onChange;
2280
- value.onRemove = previousValue.onRemove;
2281
- value.$listeners = previousValue.$listeners;
2526
+ value.$callbacks = previousValue.$callbacks;
2527
+ // value.$listeners = previousValue.$listeners;
2282
2528
  if (previousValue['$changes'].refId &&
2283
- refId !== previousValue['$changes'].refId) {
2529
+ refId_1 !== previousValue['$changes'].refId) {
2284
2530
  $root.removeRef(previousValue['$changes'].refId);
2285
2531
  }
2286
2532
  }
2287
2533
  }
2288
- $root.addRef(refId, value, (value !== previousValue));
2534
+ $root.addRef(refId_1, value, (value !== previousValue));
2289
2535
  }
2290
2536
  }
2291
2537
  else if (typeof (type) === "string") {
@@ -2295,49 +2541,38 @@ class Schema {
2295
2541
  value = decodePrimitiveType(type, bytes, it);
2296
2542
  }
2297
2543
  else {
2298
- const typeDef = getType(Object.keys(type)[0]);
2299
- const refId = number(bytes, it);
2300
- const valueRef = ($root.refs.has(refId))
2301
- ? previousValue || $root.refs.get(refId)
2544
+ var typeDef = getType(Object.keys(type)[0]);
2545
+ var refId_2 = number(bytes, it);
2546
+ var valueRef = ($root.refs.has(refId_2))
2547
+ ? previousValue || $root.refs.get(refId_2)
2302
2548
  : new typeDef.constructor();
2303
2549
  value = valueRef.clone(true);
2304
- value.$changes.refId = refId;
2550
+ value.$changes.refId = refId_2;
2305
2551
  // preserve schema callbacks
2306
2552
  if (previousValue) {
2307
- value.onAdd = previousValue.onAdd;
2308
- value.onRemove = previousValue.onRemove;
2309
- value.onChange = previousValue.onChange;
2553
+ value['$callbacks'] = previousValue['$callbacks'];
2310
2554
  if (previousValue['$changes'].refId &&
2311
- refId !== previousValue['$changes'].refId) {
2555
+ refId_2 !== previousValue['$changes'].refId) {
2312
2556
  $root.removeRef(previousValue['$changes'].refId);
2313
2557
  //
2314
2558
  // Trigger onRemove if structure has been replaced.
2315
2559
  //
2316
- const deletes = [];
2317
- const entries = previousValue.entries();
2318
- let iter;
2560
+ var entries = previousValue.entries();
2561
+ var iter = void 0;
2319
2562
  while ((iter = entries.next()) && !iter.done) {
2320
- const [key, value] = iter.value;
2321
- deletes.push({
2563
+ var _a = iter.value, key = _a[0], value_1 = _a[1];
2564
+ allChanges.push({
2565
+ refId: refId_2,
2322
2566
  op: exports.OPERATION.DELETE,
2323
2567
  field: key,
2324
2568
  value: undefined,
2325
- previousValue: value,
2569
+ previousValue: value_1,
2326
2570
  });
2327
2571
  }
2328
- allChanges.set(previousValue['$changes'].refId, deletes);
2329
2572
  }
2330
2573
  }
2331
- $root.addRef(refId, value, (valueRef !== previousValue));
2332
- //
2333
- // TODO: deprecate proxies on next version.
2334
- // get proxy to target value.
2335
- //
2336
- if (typeDef.getProxy) {
2337
- value = typeDef.getProxy(value);
2338
- }
2574
+ $root.addRef(refId_2, value, (valueRef !== previousValue));
2339
2575
  }
2340
- let hasChange = (previousValue !== value);
2341
2576
  if (value !== null &&
2342
2577
  value !== undefined) {
2343
2578
  if (value['$changes']) {
@@ -2345,18 +2580,11 @@ class Schema {
2345
2580
  }
2346
2581
  if (ref instanceof Schema) {
2347
2582
  ref[fieldName] = value;
2348
- //
2349
- // FIXME: use `_field` instead of `field`.
2350
- //
2351
- // `field` is going to use the setter of the PropertyDescriptor
2352
- // and create a proxy for array/map. This is only useful for
2353
- // backwards-compatibility with @colyseus/schema@0.5.x
2354
- //
2355
- // // ref[_field] = value;
2583
+ // ref[`_${fieldName}`] = value;
2356
2584
  }
2357
2585
  else if (ref instanceof MapSchema) {
2358
2586
  // const key = ref['$indexes'].get(field);
2359
- const key = dynamicIndex;
2587
+ var key = dynamicIndex;
2360
2588
  // ref.set(key, value);
2361
2589
  ref['$items'].set(key, value);
2362
2590
  }
@@ -2366,24 +2594,25 @@ class Schema {
2366
2594
  // ref[key] = value;
2367
2595
  ref.setAt(fieldIndex, value);
2368
2596
  }
2369
- else if (ref instanceof CollectionSchema ||
2370
- ref instanceof SetSchema) {
2371
- const index = ref.add(value);
2597
+ else if (ref instanceof CollectionSchema) {
2598
+ var index = ref.add(value);
2372
2599
  ref['setIndex'](fieldIndex, index);
2373
2600
  }
2601
+ else if (ref instanceof SetSchema) {
2602
+ var index = ref.add(value);
2603
+ if (index !== false) {
2604
+ ref['setIndex'](fieldIndex, index);
2605
+ }
2606
+ }
2374
2607
  }
2375
- if (hasChange
2376
- // &&
2377
- // (
2378
- // this.onChange || ref.$listeners[field]
2379
- // )
2380
- ) {
2381
- changes.push({
2608
+ if (previousValue !== value) {
2609
+ allChanges.push({
2610
+ refId: refId,
2382
2611
  op: operation,
2383
2612
  field: fieldName,
2384
- dynamicIndex,
2385
- value,
2386
- previousValue,
2613
+ dynamicIndex: dynamicIndex,
2614
+ value: value,
2615
+ previousValue: previousValue,
2387
2616
  });
2388
2617
  }
2389
2618
  }
@@ -2391,16 +2620,19 @@ class Schema {
2391
2620
  // drop references of unused schemas
2392
2621
  $root.garbageCollectDeletedRefs();
2393
2622
  return allChanges;
2394
- }
2395
- encode(encodeAll = false, bytes = [], useFilters = false) {
2396
- const rootChangeTree = this.$changes;
2397
- const refIdsVisited = new WeakSet();
2398
- const changeTrees = [rootChangeTree];
2399
- let numChangeTrees = 1;
2400
- for (let i = 0; i < numChangeTrees; i++) {
2401
- const changeTree = changeTrees[i];
2402
- const ref = changeTree.ref;
2403
- const isSchema = (ref instanceof Schema);
2623
+ };
2624
+ Schema.prototype.encode = function (encodeAll, bytes, useFilters) {
2625
+ if (encodeAll === void 0) { encodeAll = false; }
2626
+ if (bytes === void 0) { bytes = []; }
2627
+ if (useFilters === void 0) { useFilters = false; }
2628
+ var rootChangeTree = this.$changes;
2629
+ var refIdsVisited = new WeakSet();
2630
+ var changeTrees = [rootChangeTree];
2631
+ var numChangeTrees = 1;
2632
+ for (var i = 0; i < numChangeTrees; i++) {
2633
+ var changeTree = changeTrees[i];
2634
+ var ref = changeTree.ref;
2635
+ var isSchema = (ref instanceof Schema);
2404
2636
  // Generate unique refId for the ChangeTree.
2405
2637
  changeTree.ensureRefId();
2406
2638
  // mark this ChangeTree as visited.
@@ -2411,19 +2643,19 @@ class Schema {
2411
2643
  uint8$1(bytes, SWITCH_TO_STRUCTURE);
2412
2644
  number$1(bytes, changeTree.refId);
2413
2645
  }
2414
- const changes = (encodeAll)
2646
+ var changes = (encodeAll)
2415
2647
  ? Array.from(changeTree.allChanges)
2416
2648
  : Array.from(changeTree.changes.values());
2417
- for (let j = 0, cl = changes.length; j < cl; j++) {
2418
- const operation = (encodeAll)
2649
+ for (var j = 0, cl = changes.length; j < cl; j++) {
2650
+ var operation = (encodeAll)
2419
2651
  ? { op: exports.OPERATION.ADD, index: changes[j] }
2420
2652
  : changes[j];
2421
- const fieldIndex = operation.index;
2422
- const field = (isSchema)
2653
+ var fieldIndex = operation.index;
2654
+ var field = (isSchema)
2423
2655
  ? ref['_definition'].fieldsByIndex && ref['_definition'].fieldsByIndex[fieldIndex]
2424
2656
  : fieldIndex;
2425
2657
  // cache begin index if `useFilters`
2426
- const beginIndex = bytes.length;
2658
+ var beginIndex = bytes.length;
2427
2659
  // encode field index + operation
2428
2660
  if (operation.op !== exports.OPERATION.TOUCH) {
2429
2661
  if (isSchema) {
@@ -2453,7 +2685,7 @@ class Schema {
2453
2685
  //
2454
2686
  // MapSchema dynamic key
2455
2687
  //
2456
- const dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
2688
+ var dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
2457
2689
  string$1(bytes, dynamicIndex);
2458
2690
  }
2459
2691
  }
@@ -2467,9 +2699,9 @@ class Schema {
2467
2699
  continue;
2468
2700
  }
2469
2701
  // const type = changeTree.childType || ref._schema[field];
2470
- const type = changeTree.getType(fieldIndex);
2702
+ var type = changeTree.getType(fieldIndex);
2471
2703
  // const type = changeTree.getType(fieldIndex);
2472
- const value = changeTree.getValue(fieldIndex);
2704
+ var value = changeTree.getValue(fieldIndex);
2473
2705
  // Enqueue ChangeTree to be visited
2474
2706
  if (value &&
2475
2707
  value['$changes'] &&
@@ -2503,11 +2735,11 @@ class Schema {
2503
2735
  //
2504
2736
  // Custom type (MapSchema, ArraySchema, etc)
2505
2737
  //
2506
- const definition = getType(Object.keys(type)[0]);
2738
+ var definition = getType(Object.keys(type)[0]);
2507
2739
  //
2508
2740
  // ensure a ArraySchema has been provided
2509
2741
  //
2510
- assertInstanceType(ref[`_${field}`], definition.constructor, ref, field);
2742
+ assertInstanceType(ref["_" + field], definition.constructor, ref, field);
2511
2743
  //
2512
2744
  // Encode refId for this instance.
2513
2745
  // The actual instance is going to be encoded on next `changeTree` iteration.
@@ -2524,37 +2756,38 @@ class Schema {
2524
2756
  }
2525
2757
  }
2526
2758
  return bytes;
2527
- }
2528
- encodeAll(useFilters) {
2759
+ };
2760
+ Schema.prototype.encodeAll = function (useFilters) {
2529
2761
  return this.encode(true, [], useFilters);
2530
- }
2531
- applyFilters(client, encodeAll = false) {
2532
- const root = this;
2533
- const refIdsDissallowed = new Set();
2534
- const $filterState = ClientState.get(client);
2535
- const changeTrees = [this.$changes];
2536
- let numChangeTrees = 1;
2537
- let filteredBytes = [];
2538
- for (let i = 0; i < numChangeTrees; i++) {
2539
- const changeTree = changeTrees[i];
2762
+ };
2763
+ Schema.prototype.applyFilters = function (client, encodeAll) {
2764
+ var _a, _b;
2765
+ if (encodeAll === void 0) { encodeAll = false; }
2766
+ var root = this;
2767
+ var refIdsDissallowed = new Set();
2768
+ var $filterState = ClientState.get(client);
2769
+ var changeTrees = [this.$changes];
2770
+ var numChangeTrees = 1;
2771
+ var filteredBytes = [];
2772
+ var _loop_1 = function (i) {
2773
+ var changeTree = changeTrees[i];
2540
2774
  if (refIdsDissallowed.has(changeTree.refId)) {
2541
- // console.log("REFID IS NOT ALLOWED. SKIP.", { refId: changeTree.refId })
2542
- continue;
2775
+ return "continue";
2543
2776
  }
2544
- const ref = changeTree.ref;
2545
- const isSchema = ref instanceof Schema;
2777
+ var ref = changeTree.ref;
2778
+ var isSchema = ref instanceof Schema;
2546
2779
  uint8$1(filteredBytes, SWITCH_TO_STRUCTURE);
2547
2780
  number$1(filteredBytes, changeTree.refId);
2548
- const clientHasRefId = $filterState.refIds.has(changeTree);
2549
- const isEncodeAll = (encodeAll || !clientHasRefId);
2781
+ var clientHasRefId = $filterState.refIds.has(changeTree);
2782
+ var isEncodeAll = (encodeAll || !clientHasRefId);
2550
2783
  // console.log("REF:", ref.constructor.name);
2551
2784
  // console.log("Encode all?", isEncodeAll);
2552
2785
  //
2553
2786
  // include `changeTree` on list of known refIds by this client.
2554
2787
  //
2555
2788
  $filterState.addRefId(changeTree);
2556
- const containerIndexes = $filterState.containerIndexes.get(changeTree);
2557
- const changes = (isEncodeAll)
2789
+ var containerIndexes = $filterState.containerIndexes.get(changeTree);
2790
+ var changes = (isEncodeAll)
2558
2791
  ? Array.from(changeTree.allChanges)
2559
2792
  : Array.from(changeTree.changes.values());
2560
2793
  //
@@ -2564,8 +2797,8 @@ class Schema {
2564
2797
  if (!encodeAll &&
2565
2798
  isSchema &&
2566
2799
  ref._definition.indexesWithFilters) {
2567
- const indexesWithFilters = ref._definition.indexesWithFilters;
2568
- indexesWithFilters.forEach(indexWithFilter => {
2800
+ var indexesWithFilters = ref._definition.indexesWithFilters;
2801
+ indexesWithFilters.forEach(function (indexWithFilter) {
2569
2802
  if (!containerIndexes.has(indexWithFilter) &&
2570
2803
  changeTree.allChanges.has(indexWithFilter)) {
2571
2804
  if (isEncodeAll) {
@@ -2577,8 +2810,8 @@ class Schema {
2577
2810
  }
2578
2811
  });
2579
2812
  }
2580
- for (let j = 0, cl = changes.length; j < cl; j++) {
2581
- const change = (isEncodeAll)
2813
+ for (var j = 0, cl = changes.length; j < cl; j++) {
2814
+ var change = (isEncodeAll)
2582
2815
  ? { op: exports.OPERATION.ADD, index: changes[j] }
2583
2816
  : changes[j];
2584
2817
  // custom operations
@@ -2586,7 +2819,7 @@ class Schema {
2586
2819
  uint8$1(filteredBytes, change.op);
2587
2820
  continue;
2588
2821
  }
2589
- const fieldIndex = change.index;
2822
+ var fieldIndex = change.index;
2590
2823
  //
2591
2824
  // Deleting fields: encode the operation + field index
2592
2825
  //
@@ -2607,11 +2840,11 @@ class Schema {
2607
2840
  continue;
2608
2841
  }
2609
2842
  // indexed operation
2610
- const value = changeTree.getValue(fieldIndex);
2611
- const type = changeTree.getType(fieldIndex);
2843
+ var value = changeTree.getValue(fieldIndex);
2844
+ var type = changeTree.getType(fieldIndex);
2612
2845
  if (isSchema) {
2613
2846
  // Is a Schema!
2614
- const filter = (ref._definition.filters &&
2847
+ var filter = (ref._definition.filters &&
2615
2848
  ref._definition.filters[fieldIndex]);
2616
2849
  if (filter && !filter.call(ref, client, value, root)) {
2617
2850
  if (value && value['$changes']) {
@@ -2622,8 +2855,8 @@ class Schema {
2622
2855
  }
2623
2856
  else {
2624
2857
  // Is a collection! (map, array, etc.)
2625
- const parent = changeTree.parent;
2626
- const filter = changeTree.getChildrenFilter();
2858
+ var parent = changeTree.parent;
2859
+ var filter = changeTree.getChildrenFilter();
2627
2860
  if (filter && !filter.call(parent, client, ref['$indexes'].get(fieldIndex), value, root)) {
2628
2861
  if (value && value['$changes']) {
2629
2862
  refIdsDissallowed.add(value['$changes'].refId);
@@ -2647,7 +2880,7 @@ class Schema {
2647
2880
  //
2648
2881
  // use cached bytes directly if is from Schema type.
2649
2882
  //
2650
- filteredBytes = filteredBytes.concat(changeTree.caches[fieldIndex]);
2883
+ filteredBytes.push.apply(filteredBytes, (_a = changeTree.caches[fieldIndex]) !== null && _a !== void 0 ? _a : []);
2651
2884
  containerIndexes.add(fieldIndex);
2652
2885
  }
2653
2886
  else {
@@ -2655,7 +2888,7 @@ class Schema {
2655
2888
  //
2656
2889
  // use cached bytes if already has the field
2657
2890
  //
2658
- filteredBytes = filteredBytes.concat(changeTree.caches[fieldIndex]);
2891
+ filteredBytes.push.apply(filteredBytes, (_b = changeTree.caches[fieldIndex]) !== null && _b !== void 0 ? _b : []);
2659
2892
  }
2660
2893
  else {
2661
2894
  //
@@ -2668,7 +2901,7 @@ class Schema {
2668
2901
  //
2669
2902
  // MapSchema dynamic key
2670
2903
  //
2671
- const dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
2904
+ var dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
2672
2905
  string$1(filteredBytes, dynamicIndex);
2673
2906
  }
2674
2907
  if (value['$changes']) {
@@ -2695,19 +2928,22 @@ class Schema {
2695
2928
  //
2696
2929
  // MapSchema dynamic key
2697
2930
  //
2698
- const dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
2931
+ var dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
2699
2932
  string$1(filteredBytes, dynamicIndex);
2700
2933
  }
2701
2934
  number$1(filteredBytes, value['$changes'].refId);
2702
2935
  }
2703
2936
  }
2937
+ };
2938
+ for (var i = 0; i < numChangeTrees; i++) {
2939
+ _loop_1(i);
2704
2940
  }
2705
2941
  return filteredBytes;
2706
- }
2707
- clone() {
2708
- const cloned = new (this.constructor);
2709
- const schema = this._definition.schema;
2710
- for (let field in schema) {
2942
+ };
2943
+ Schema.prototype.clone = function () {
2944
+ var cloned = new (this.constructor);
2945
+ var schema = this._definition.schema;
2946
+ for (var field in schema) {
2711
2947
  if (typeof (this[field]) === "object" &&
2712
2948
  typeof (this[field].clone) === "function") {
2713
2949
  // deep clone
@@ -2719,272 +2955,222 @@ class Schema {
2719
2955
  }
2720
2956
  }
2721
2957
  return cloned;
2722
- }
2723
- triggerAll() {
2724
- // skip if haven't received any remote refs yet.
2725
- if (this.$changes.root.refs.size === 0) {
2726
- return;
2727
- }
2728
- const allChanges = new Map();
2729
- Schema.prototype._triggerAllFillChanges.call(this, this, allChanges);
2730
- try {
2731
- Schema.prototype._triggerChanges.call(this, allChanges);
2732
- }
2733
- catch (e) {
2734
- Schema.onError(e);
2735
- }
2736
- }
2737
- toJSON() {
2738
- const schema = this._definition.schema;
2739
- const deprecated = this._definition.deprecated;
2740
- const obj = {};
2741
- for (let field in schema) {
2958
+ };
2959
+ Schema.prototype.toJSON = function () {
2960
+ var schema = this._definition.schema;
2961
+ var deprecated = this._definition.deprecated;
2962
+ var obj = {};
2963
+ for (var field in schema) {
2742
2964
  if (!deprecated[field] && this[field] !== null && typeof (this[field]) !== "undefined") {
2743
2965
  obj[field] = (typeof (this[field]['toJSON']) === "function")
2744
2966
  ? this[field]['toJSON']()
2745
- : this[`_${field}`];
2967
+ : this["_" + field];
2746
2968
  }
2747
2969
  }
2748
2970
  return obj;
2749
- }
2750
- discardAllChanges() {
2971
+ };
2972
+ Schema.prototype.discardAllChanges = function () {
2751
2973
  this.$changes.discardAll();
2752
- }
2753
- getByIndex(index) {
2974
+ };
2975
+ Schema.prototype.getByIndex = function (index) {
2754
2976
  return this[this._definition.fieldsByIndex[index]];
2755
- }
2756
- deleteByIndex(index) {
2977
+ };
2978
+ Schema.prototype.deleteByIndex = function (index) {
2757
2979
  this[this._definition.fieldsByIndex[index]] = undefined;
2758
- }
2759
- tryEncodeTypeId(bytes, type, targetType) {
2980
+ };
2981
+ Schema.prototype.tryEncodeTypeId = function (bytes, type, targetType) {
2760
2982
  if (type._typeid !== targetType._typeid) {
2761
2983
  uint8$1(bytes, TYPE_ID);
2762
2984
  number$1(bytes, targetType._typeid);
2763
2985
  }
2764
- }
2765
- getSchemaType(bytes, it, defaultType) {
2766
- let type;
2986
+ };
2987
+ Schema.prototype.getSchemaType = function (bytes, it, defaultType) {
2988
+ var type;
2767
2989
  if (bytes[it.offset] === TYPE_ID) {
2768
2990
  it.offset++;
2769
2991
  type = this.constructor._context.get(number(bytes, it));
2770
2992
  }
2771
2993
  return type || defaultType;
2772
- }
2773
- createTypeInstance(type) {
2774
- let instance = new type();
2994
+ };
2995
+ Schema.prototype.createTypeInstance = function (type) {
2996
+ var instance = new type();
2775
2997
  // assign root on $changes
2776
2998
  instance.$changes.root = this.$changes.root;
2777
2999
  return instance;
2778
- }
2779
- _triggerAllFillChanges(ref, allChanges) {
2780
- if (allChanges.has(ref['$changes'].refId)) {
2781
- return;
2782
- }
2783
- const changes = [];
2784
- allChanges.set(ref['$changes'].refId || 0, changes);
2785
- if (ref instanceof Schema) {
2786
- const schema = ref._definition.schema;
2787
- for (let fieldName in schema) {
2788
- const _field = `_${fieldName}`;
2789
- const value = ref[_field];
2790
- if (value !== undefined) {
2791
- changes.push({
2792
- op: exports.OPERATION.ADD,
2793
- field: fieldName,
2794
- value,
2795
- previousValue: undefined
2796
- });
2797
- if (value['$changes'] !== undefined) {
2798
- Schema.prototype._triggerAllFillChanges.call(this, value, allChanges);
3000
+ };
3001
+ Schema.prototype._triggerChanges = function (changes) {
3002
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3003
+ var uniqueRefIds = new Set();
3004
+ var $refs = this.$changes.root.refs;
3005
+ var _loop_2 = function (i) {
3006
+ var change = changes[i];
3007
+ var refId = change.refId;
3008
+ var ref = $refs.get(refId);
3009
+ var $callbacks = ref['$callbacks'];
3010
+ //
3011
+ // trigger onRemove on child structure.
3012
+ //
3013
+ if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
3014
+ change.previousValue instanceof Schema) {
3015
+ (_b = (_a = change.previousValue['$callbacks']) === null || _a === void 0 ? void 0 : _a[exports.OPERATION.DELETE]) === null || _b === void 0 ? void 0 : _b.forEach(function (callback) { return callback(); });
3016
+ }
3017
+ // no callbacks defined, skip this structure!
3018
+ if (!$callbacks) {
3019
+ return "continue";
3020
+ }
3021
+ if (ref instanceof Schema) {
3022
+ if (!uniqueRefIds.has(refId)) {
3023
+ try {
3024
+ // trigger onChange
3025
+ (_d = (_c = $callbacks) === null || _c === void 0 ? void 0 : _c[exports.OPERATION.REPLACE]) === null || _d === void 0 ? void 0 : _d.forEach(function (callback) {
3026
+ return callback(changes);
3027
+ });
3028
+ }
3029
+ catch (e) {
3030
+ Schema.onError(e);
2799
3031
  }
2800
3032
  }
2801
- }
2802
- }
2803
- else {
2804
- const entries = ref.entries();
2805
- let iter;
2806
- while ((iter = entries.next()) && !iter.done) {
2807
- const [key, value] = iter.value;
2808
- changes.push({
2809
- op: exports.OPERATION.ADD,
2810
- field: key,
2811
- dynamicIndex: key,
2812
- value: value,
2813
- previousValue: undefined,
2814
- });
2815
- if (value['$changes'] !== undefined) {
2816
- Schema.prototype._triggerAllFillChanges.call(this, value, allChanges);
3033
+ try {
3034
+ (_e = $callbacks[change.field]) === null || _e === void 0 ? void 0 : _e.forEach(function (callback) {
3035
+ return callback(change.value, change.previousValue);
3036
+ });
3037
+ }
3038
+ catch (e) {
3039
+ Schema.onError(e);
2817
3040
  }
2818
3041
  }
2819
- }
2820
- }
2821
- _triggerChanges(allChanges) {
2822
- allChanges.forEach((changes, refId) => {
2823
- if (changes.length > 0) {
2824
- const ref = this.$changes.root.refs.get(refId);
2825
- const isSchema = ref instanceof Schema;
2826
- for (let i = 0; i < changes.length; i++) {
2827
- const change = changes[i];
2828
- const listener = ref['$listeners'] && ref['$listeners'][change.field];
2829
- if (!isSchema) {
2830
- if (change.op === exports.OPERATION.ADD && change.previousValue === undefined) {
2831
- ref.onAdd?.(change.value, change.dynamicIndex ?? change.field);
2832
- }
2833
- else if (change.op === exports.OPERATION.DELETE) {
2834
- //
2835
- // FIXME: `previousValue` should always be avaiiable.
2836
- // ADD + DELETE operations are still encoding DELETE operation.
2837
- //
2838
- if (change.previousValue !== undefined) {
2839
- ref.onRemove?.(change.previousValue, change.dynamicIndex ?? change.field);
2840
- }
2841
- }
2842
- else if (change.op === exports.OPERATION.DELETE_AND_ADD) {
2843
- if (change.previousValue !== undefined) {
2844
- ref.onRemove?.(change.previousValue, change.dynamicIndex);
2845
- }
2846
- ref.onAdd?.(change.value, change.dynamicIndex);
2847
- }
2848
- else if (change.op === exports.OPERATION.REPLACE ||
2849
- change.value !== change.previousValue) {
2850
- ref.onChange?.(change.value, change.dynamicIndex);
2851
- }
2852
- }
3042
+ else {
3043
+ // is a collection of items
3044
+ if (change.op === exports.OPERATION.ADD && change.previousValue === undefined) {
3045
+ // triger onAdd
3046
+ (_f = $callbacks[exports.OPERATION.ADD]) === null || _f === void 0 ? void 0 : _f.forEach(function (callback) { var _a; return callback(change.value, (_a = change.dynamicIndex) !== null && _a !== void 0 ? _a : change.field); });
3047
+ }
3048
+ else if (change.op === exports.OPERATION.DELETE) {
2853
3049
  //
2854
- // trigger onRemove on child structure.
3050
+ // FIXME: `previousValue` should always be available.
3051
+ // ADD + DELETE operations are still encoding DELETE operation.
2855
3052
  //
2856
- if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
2857
- change.previousValue instanceof Schema &&
2858
- change.previousValue.onRemove) {
2859
- change.previousValue.onRemove();
2860
- }
2861
- if (listener) {
2862
- try {
2863
- listener.invoke(change.value, change.previousValue);
2864
- }
2865
- catch (e) {
2866
- Schema.onError(e);
2867
- }
3053
+ if (change.previousValue !== undefined) {
3054
+ // triger onRemove
3055
+ (_g = $callbacks[exports.OPERATION.DELETE]) === null || _g === void 0 ? void 0 : _g.forEach(function (callback) { var _a; return callback(change.previousValue, (_a = change.dynamicIndex) !== null && _a !== void 0 ? _a : change.field); });
2868
3056
  }
2869
3057
  }
2870
- if (isSchema) {
2871
- if (ref.onChange) {
2872
- try {
2873
- ref.onChange(changes);
2874
- }
2875
- catch (e) {
2876
- Schema.onError(e);
2877
- }
3058
+ else if (change.op === exports.OPERATION.DELETE_AND_ADD) {
3059
+ // triger onRemove
3060
+ if (change.previousValue !== undefined) {
3061
+ (_h = $callbacks[exports.OPERATION.DELETE]) === null || _h === void 0 ? void 0 : _h.forEach(function (callback) { var _a; return callback(change.previousValue, (_a = change.dynamicIndex) !== null && _a !== void 0 ? _a : change.field); });
2878
3062
  }
3063
+ // triger onAdd
3064
+ (_j = $callbacks[exports.OPERATION.ADD]) === null || _j === void 0 ? void 0 : _j.forEach(function (callback) { var _a; return callback(change.value, (_a = change.dynamicIndex) !== null && _a !== void 0 ? _a : change.field); });
3065
+ }
3066
+ // trigger onChange
3067
+ if (change.value !== change.previousValue) {
3068
+ (_k = $callbacks[exports.OPERATION.REPLACE]) === null || _k === void 0 ? void 0 : _k.forEach(function (callback) { var _a; return callback(change.value, (_a = change.dynamicIndex) !== null && _a !== void 0 ? _a : change.field); });
2879
3069
  }
2880
3070
  }
2881
- });
2882
- }
2883
- }
2884
- Schema._definition = SchemaDefinition.create();
3071
+ uniqueRefIds.add(refId);
3072
+ };
3073
+ for (var i = 0; i < changes.length; i++) {
3074
+ _loop_2(i);
3075
+ }
3076
+ };
3077
+ Schema._definition = SchemaDefinition.create();
3078
+ return Schema;
3079
+ }());
2885
3080
 
2886
3081
  function dumpChanges(schema) {
2887
- const changeTrees = [schema['$changes']];
2888
- let numChangeTrees = 1;
2889
- const dump = {};
2890
- let currentStructure = dump;
2891
- for (let i = 0; i < numChangeTrees; i++) {
2892
- const changeTree = changeTrees[i];
2893
- changeTree.changes.forEach((change) => {
2894
- const ref = changeTree.ref;
2895
- const fieldIndex = change.index;
2896
- const field = (ref['_definition'])
3082
+ var changeTrees = [schema['$changes']];
3083
+ var numChangeTrees = 1;
3084
+ var dump = {};
3085
+ var currentStructure = dump;
3086
+ var _loop_1 = function (i) {
3087
+ var changeTree = changeTrees[i];
3088
+ changeTree.changes.forEach(function (change) {
3089
+ var ref = changeTree.ref;
3090
+ var fieldIndex = change.index;
3091
+ var field = (ref['_definition'])
2897
3092
  ? ref['_definition'].fieldsByIndex[fieldIndex]
2898
3093
  : ref['$indexes'].get(fieldIndex);
2899
3094
  currentStructure[field] = changeTree.getValue(fieldIndex);
2900
3095
  });
3096
+ };
3097
+ for (var i = 0; i < numChangeTrees; i++) {
3098
+ _loop_1(i);
2901
3099
  }
2902
3100
  return dump;
2903
3101
  }
2904
3102
 
2905
- /*! *****************************************************************************
2906
- Copyright (c) Microsoft Corporation.
2907
-
2908
- Permission to use, copy, modify, and/or distribute this software for any
2909
- purpose with or without fee is hereby granted.
2910
-
2911
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
2912
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2913
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
2914
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
2915
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
2916
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2917
- PERFORMANCE OF THIS SOFTWARE.
2918
- ***************************************************************************** */
2919
-
2920
- function __decorate(decorators, target, key, desc) {
2921
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2922
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2923
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2924
- return c > 3 && r && Object.defineProperty(target, key, r), r;
2925
- }
2926
-
2927
- const reflectionContext = new Context();
3103
+ var reflectionContext = { context: new Context() };
2928
3104
  /**
2929
3105
  * Reflection
2930
3106
  */
2931
- class ReflectionField extends Schema {
2932
- }
2933
- __decorate([
2934
- type("string", reflectionContext)
2935
- ], ReflectionField.prototype, "name", void 0);
2936
- __decorate([
2937
- type("string", reflectionContext)
2938
- ], ReflectionField.prototype, "type", void 0);
2939
- __decorate([
2940
- type("number", reflectionContext)
2941
- ], ReflectionField.prototype, "referencedType", void 0);
2942
- class ReflectionType extends Schema {
2943
- constructor() {
2944
- super(...arguments);
2945
- this.fields = new ArraySchema();
2946
- }
2947
- }
2948
- __decorate([
2949
- type("number", reflectionContext)
2950
- ], ReflectionType.prototype, "id", void 0);
2951
- __decorate([
2952
- type([ReflectionField], reflectionContext)
2953
- ], ReflectionType.prototype, "fields", void 0);
2954
- class Reflection extends Schema {
2955
- constructor() {
2956
- super(...arguments);
2957
- this.types = new ArraySchema();
2958
- }
2959
- static encode(instance) {
2960
- const rootSchemaType = instance.constructor;
2961
- const reflection = new Reflection();
3107
+ var ReflectionField = /** @class */ (function (_super) {
3108
+ __extends(ReflectionField, _super);
3109
+ function ReflectionField() {
3110
+ return _super !== null && _super.apply(this, arguments) || this;
3111
+ }
3112
+ __decorate([
3113
+ type("string", reflectionContext)
3114
+ ], ReflectionField.prototype, "name", void 0);
3115
+ __decorate([
3116
+ type("string", reflectionContext)
3117
+ ], ReflectionField.prototype, "type", void 0);
3118
+ __decorate([
3119
+ type("number", reflectionContext)
3120
+ ], ReflectionField.prototype, "referencedType", void 0);
3121
+ return ReflectionField;
3122
+ }(Schema));
3123
+ var ReflectionType = /** @class */ (function (_super) {
3124
+ __extends(ReflectionType, _super);
3125
+ function ReflectionType() {
3126
+ var _this = _super !== null && _super.apply(this, arguments) || this;
3127
+ _this.fields = new ArraySchema();
3128
+ return _this;
3129
+ }
3130
+ __decorate([
3131
+ type("number", reflectionContext)
3132
+ ], ReflectionType.prototype, "id", void 0);
3133
+ __decorate([
3134
+ type([ReflectionField], reflectionContext)
3135
+ ], ReflectionType.prototype, "fields", void 0);
3136
+ return ReflectionType;
3137
+ }(Schema));
3138
+ var Reflection = /** @class */ (function (_super) {
3139
+ __extends(Reflection, _super);
3140
+ function Reflection() {
3141
+ var _this = _super !== null && _super.apply(this, arguments) || this;
3142
+ _this.types = new ArraySchema();
3143
+ return _this;
3144
+ }
3145
+ Reflection.encode = function (instance) {
3146
+ var rootSchemaType = instance.constructor;
3147
+ var reflection = new Reflection();
2962
3148
  reflection.rootType = rootSchemaType._typeid;
2963
- const buildType = (currentType, schema) => {
2964
- for (let fieldName in schema) {
2965
- const field = new ReflectionField();
3149
+ var buildType = function (currentType, schema) {
3150
+ for (var fieldName in schema) {
3151
+ var field = new ReflectionField();
2966
3152
  field.name = fieldName;
2967
- let fieldType;
3153
+ var fieldType = void 0;
2968
3154
  if (typeof (schema[fieldName]) === "string") {
2969
3155
  fieldType = schema[fieldName];
2970
3156
  }
2971
3157
  else {
2972
- const type = schema[fieldName];
2973
- let childTypeSchema;
3158
+ var type_1 = schema[fieldName];
3159
+ var childTypeSchema = void 0;
2974
3160
  //
2975
3161
  // TODO: refactor below.
2976
3162
  //
2977
- if (Schema.is(type)) {
3163
+ if (Schema.is(type_1)) {
2978
3164
  fieldType = "ref";
2979
3165
  childTypeSchema = schema[fieldName];
2980
3166
  }
2981
3167
  else {
2982
- fieldType = Object.keys(type)[0];
2983
- if (typeof (type[fieldType]) === "string") {
2984
- fieldType += ":" + type[fieldType]; // array:string
3168
+ fieldType = Object.keys(type_1)[0];
3169
+ if (typeof (type_1[fieldType]) === "string") {
3170
+ fieldType += ":" + type_1[fieldType]; // array:string
2985
3171
  }
2986
3172
  else {
2987
- childTypeSchema = type[fieldType];
3173
+ childTypeSchema = type_1[fieldType];
2988
3174
  }
2989
3175
  }
2990
3176
  field.referencedType = (childTypeSchema)
@@ -2996,58 +3182,64 @@ class Reflection extends Schema {
2996
3182
  }
2997
3183
  reflection.types.push(currentType);
2998
3184
  };
2999
- const types = rootSchemaType._context.types;
3000
- for (let typeid in types) {
3001
- const type = new ReflectionType();
3002
- type.id = Number(typeid);
3003
- buildType(type, types[typeid]._definition.schema);
3185
+ var types = rootSchemaType._context.types;
3186
+ for (var typeid in types) {
3187
+ var type_2 = new ReflectionType();
3188
+ type_2.id = Number(typeid);
3189
+ buildType(type_2, types[typeid]._definition.schema);
3004
3190
  }
3005
3191
  return reflection.encodeAll();
3006
- }
3007
- static decode(bytes, it) {
3008
- const context = new Context();
3009
- const reflection = new Reflection();
3192
+ };
3193
+ Reflection.decode = function (bytes, it) {
3194
+ var context = new Context();
3195
+ var reflection = new Reflection();
3010
3196
  reflection.decode(bytes, it);
3011
- const schemaTypes = reflection.types.reduce((types, reflectionType) => {
3012
- const schema = class _ extends Schema {
3013
- };
3014
- const typeid = reflectionType.id;
3197
+ var schemaTypes = reflection.types.reduce(function (types, reflectionType) {
3198
+ var schema = /** @class */ (function (_super) {
3199
+ __extends(_, _super);
3200
+ function _() {
3201
+ return _super !== null && _super.apply(this, arguments) || this;
3202
+ }
3203
+ return _;
3204
+ }(Schema));
3205
+ var typeid = reflectionType.id;
3015
3206
  types[typeid] = schema;
3016
3207
  context.add(schema, typeid);
3017
3208
  return types;
3018
3209
  }, {});
3019
- reflection.types.forEach((reflectionType) => {
3020
- const schemaType = schemaTypes[reflectionType.id];
3021
- reflectionType.fields.forEach(field => {
3210
+ reflection.types.forEach(function (reflectionType) {
3211
+ var schemaType = schemaTypes[reflectionType.id];
3212
+ reflectionType.fields.forEach(function (field) {
3213
+ var _a;
3022
3214
  if (field.referencedType !== undefined) {
3023
- let fieldType = field.type;
3024
- let refType = schemaTypes[field.referencedType];
3215
+ var fieldType = field.type;
3216
+ var refType = schemaTypes[field.referencedType];
3025
3217
  // map or array of primitive type (-1)
3026
3218
  if (!refType) {
3027
- const typeInfo = field.type.split(":");
3219
+ var typeInfo = field.type.split(":");
3028
3220
  fieldType = typeInfo[0];
3029
3221
  refType = typeInfo[1];
3030
3222
  }
3031
3223
  if (fieldType === "ref") {
3032
- type(refType, context)(schemaType.prototype, field.name);
3224
+ type(refType, { context: context })(schemaType.prototype, field.name);
3033
3225
  }
3034
3226
  else {
3035
- type({ [fieldType]: refType }, context)(schemaType.prototype, field.name);
3227
+ type((_a = {}, _a[fieldType] = refType, _a), { context: context })(schemaType.prototype, field.name);
3036
3228
  }
3037
3229
  }
3038
3230
  else {
3039
- type(field.type, context)(schemaType.prototype, field.name);
3231
+ type(field.type, { context: context })(schemaType.prototype, field.name);
3040
3232
  }
3041
3233
  });
3042
3234
  });
3043
- const rootType = schemaTypes[reflection.rootType];
3044
- const rootInstance = new rootType();
3235
+ var rootType = schemaTypes[reflection.rootType];
3236
+ var rootInstance = new rootType();
3045
3237
  /**
3046
3238
  * auto-initialize referenced types on root type
3047
3239
  * to allow registering listeners immediatelly on client-side
3048
3240
  */
3049
- for (let fieldName in rootType._definition.schema) {
3050
- const fieldType = rootType._definition.schema[fieldName];
3241
+ for (var fieldName in rootType._definition.schema) {
3242
+ var fieldType = rootType._definition.schema[fieldName];
3051
3243
  if (typeof (fieldType) !== "string") {
3052
3244
  rootInstance[fieldName] = (typeof (fieldType) === "function")
3053
3245
  ? new fieldType() // is a schema reference
@@ -3055,17 +3247,18 @@ class Reflection extends Schema {
3055
3247
  }
3056
3248
  }
3057
3249
  return rootInstance;
3058
- }
3059
- }
3060
- __decorate([
3061
- type([ReflectionType], reflectionContext)
3062
- ], Reflection.prototype, "types", void 0);
3063
- __decorate([
3064
- type("number", reflectionContext)
3065
- ], Reflection.prototype, "rootType", void 0);
3250
+ };
3251
+ __decorate([
3252
+ type([ReflectionType], reflectionContext)
3253
+ ], Reflection.prototype, "types", void 0);
3254
+ __decorate([
3255
+ type("number", reflectionContext)
3256
+ ], Reflection.prototype, "rootType", void 0);
3257
+ return Reflection;
3258
+ }(Schema));
3066
3259
 
3067
- registerType("map", { constructor: MapSchema, getProxy: getMapProxy });
3068
- registerType("array", { constructor: ArraySchema, getProxy: getArrayProxy });
3260
+ registerType("map", { constructor: MapSchema });
3261
+ registerType("array", { constructor: ArraySchema });
3069
3262
  registerType("set", { constructor: SetSchema });
3070
3263
  registerType("collection", { constructor: CollectionSchema, });
3071
3264