@colyseus/schema 1.1.0-alpha.3 → 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 (48) 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.js +23 -13
  8. package/lib/Reflection.js.map +1 -1
  9. package/lib/Schema.d.ts +24 -16
  10. package/lib/Schema.js +121 -165
  11. package/lib/Schema.js.map +1 -1
  12. package/lib/annotations.d.ts +23 -5
  13. package/lib/annotations.js +59 -14
  14. package/lib/annotations.js.map +1 -1
  15. package/lib/changes/ChangeTree.d.ts +4 -16
  16. package/lib/changes/ChangeTree.js +1 -72
  17. package/lib/changes/ChangeTree.js.map +1 -1
  18. package/lib/changes/ReferenceTracker.d.ts +14 -0
  19. package/lib/changes/ReferenceTracker.js +77 -0
  20. package/lib/changes/ReferenceTracker.js.map +1 -0
  21. package/lib/codegen/languages/csharp.js +39 -17
  22. package/lib/codegen/languages/csharp.js.map +1 -1
  23. package/lib/codegen/languages/ts.js +10 -1
  24. package/lib/codegen/languages/ts.js.map +1 -1
  25. package/lib/codegen/parser.js +3 -1
  26. package/lib/codegen/parser.js.map +1 -1
  27. package/lib/index.d.ts +1 -1
  28. package/lib/index.js +6 -6
  29. package/lib/index.js.map +1 -1
  30. package/lib/types/ArraySchema.d.ts +8 -5
  31. package/lib/types/ArraySchema.js +22 -19
  32. package/lib/types/ArraySchema.js.map +1 -1
  33. package/lib/types/CollectionSchema.d.ts +8 -5
  34. package/lib/types/CollectionSchema.js +17 -11
  35. package/lib/types/CollectionSchema.js.map +1 -1
  36. package/lib/types/MapSchema.d.ts +8 -5
  37. package/lib/types/MapSchema.js +20 -11
  38. package/lib/types/MapSchema.js.map +1 -1
  39. package/lib/types/SetSchema.d.ts +8 -5
  40. package/lib/types/SetSchema.js +22 -14
  41. package/lib/types/SetSchema.js.map +1 -1
  42. package/lib/types/typeRegistry.d.ts +5 -0
  43. package/lib/types/typeRegistry.js +13 -0
  44. package/lib/types/typeRegistry.js.map +1 -0
  45. package/lib/types/utils.d.ts +9 -0
  46. package/lib/types/utils.js +50 -0
  47. package/lib/types/utils.js.map +1 -0
  48. package/package.json +3 -8
@@ -87,76 +87,6 @@
87
87
  // CLEAR = 10,
88
88
  // }
89
89
 
90
- //
91
- // Root holds all schema references by unique id
92
- //
93
- var Root = /** @class */ (function () {
94
- function Root() {
95
- //
96
- // Relation of refId => Schema structure
97
- // For direct access of structures during decoding time.
98
- //
99
- this.refs = new Map();
100
- this.refCounts = {};
101
- this.deletedRefs = new Set();
102
- this.nextUniqueId = 0;
103
- }
104
- Root.prototype.getNextUniqueId = function () {
105
- return this.nextUniqueId++;
106
- };
107
- // for decoding
108
- Root.prototype.addRef = function (refId, ref, incrementCount) {
109
- if (incrementCount === void 0) { incrementCount = true; }
110
- this.refs.set(refId, ref);
111
- if (incrementCount) {
112
- this.refCounts[refId] = (this.refCounts[refId] || 0) + 1;
113
- }
114
- };
115
- // for decoding
116
- Root.prototype.removeRef = function (refId) {
117
- this.refCounts[refId] = this.refCounts[refId] - 1;
118
- this.deletedRefs.add(refId);
119
- };
120
- Root.prototype.clearRefs = function () {
121
- this.refs.clear();
122
- this.deletedRefs.clear();
123
- this.refCounts = {};
124
- };
125
- // for decoding
126
- Root.prototype.garbageCollectDeletedRefs = function () {
127
- var _this = this;
128
- this.deletedRefs.forEach(function (refId) {
129
- if (_this.refCounts[refId] <= 0) {
130
- var ref = _this.refs.get(refId);
131
- //
132
- // Ensure child schema instances have their references removed as well.
133
- //
134
- if (ref instanceof Schema) {
135
- for (var fieldName in ref['_definition'].schema) {
136
- if (typeof (ref['_definition'].schema[fieldName]) !== "string" &&
137
- ref[fieldName] &&
138
- ref[fieldName]['$changes']) {
139
- _this.removeRef(ref[fieldName]['$changes'].refId);
140
- }
141
- }
142
- }
143
- else {
144
- var definition = ref['$changes'].parent._definition;
145
- var type = definition.schema[definition.fieldsByIndex[ref['$changes'].parentIndex]];
146
- if (typeof (Object.values(type)[0]) === "function") {
147
- Array.from(ref.values())
148
- .forEach(function (child) { return _this.removeRef(child['$changes'].refId); });
149
- }
150
- }
151
- _this.refs.delete(refId);
152
- delete _this.refCounts[refId];
153
- }
154
- });
155
- // clear deleted refs.
156
- this.deletedRefs.clear();
157
- };
158
- return Root;
159
- }());
160
90
  var ChangeTree = /** @class */ (function () {
161
91
  function ChangeTree(ref, parent, root) {
162
92
  this.changed = false;
@@ -360,13 +290,49 @@
360
290
  return ChangeTree;
361
291
  }());
362
292
 
363
- //
364
- // Notes:
365
- // -----
366
- //
367
- // - The tsconfig.json of @colyseus/schema uses ES2018.
368
- // - ES2019 introduces `flatMap` / `flat`, which is not currently relevant, and caused other issues.
369
- //
293
+ function addCallback($callbacks, op, callback, existing) {
294
+ // initialize list of callbacks
295
+ if (!$callbacks[op]) {
296
+ $callbacks[op] = [];
297
+ }
298
+ $callbacks[op].push(callback);
299
+ //
300
+ // Trigger callback for existing elements
301
+ // - OPERATION.ADD
302
+ // - OPERATION.REPLACE
303
+ //
304
+ existing === null || existing === void 0 ? void 0 : existing.forEach(function (item, key) { return callback(item, key); });
305
+ return function () { return spliceOne($callbacks[op], $callbacks[op].indexOf(callback)); };
306
+ }
307
+ function removeChildRefs(changes) {
308
+ var _this = this;
309
+ var needRemoveRef = (typeof (this.$changes.getType()) !== "string");
310
+ this.$items.forEach(function (item, key) {
311
+ changes.push({
312
+ refId: _this.$changes.refId,
313
+ op: exports.OPERATION.DELETE,
314
+ field: key,
315
+ value: undefined,
316
+ previousValue: item
317
+ });
318
+ if (needRemoveRef) {
319
+ _this.$changes.root.removeRef(item['$changes'].refId);
320
+ }
321
+ });
322
+ }
323
+ function spliceOne(arr, index) {
324
+ // manually splice an array
325
+ if (index === -1 || index >= arr.length) {
326
+ return false;
327
+ }
328
+ var len = arr.length - 1;
329
+ for (var i = index; i < len; i++) {
330
+ arr[i] = arr[i + 1];
331
+ }
332
+ arr.length = len;
333
+ return true;
334
+ }
335
+
370
336
  var DEFAULT_SORT = function (a, b) {
371
337
  var A = a.toString();
372
338
  var B = b.toString();
@@ -437,8 +403,20 @@
437
403
  this.$refId = 0;
438
404
  this.push.apply(this, items);
439
405
  }
406
+ ArraySchema.prototype.onAdd = function (callback, triggerAll) {
407
+ if (triggerAll === void 0) { triggerAll = true; }
408
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
409
+ ? this.$items
410
+ : undefined);
411
+ };
412
+ ArraySchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
413
+ ArraySchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
440
414
  ArraySchema.is = function (type) {
441
- return Array.isArray(type);
415
+ return (
416
+ // type format: ["string"]
417
+ Array.isArray(type) ||
418
+ // type format: { array: "string" }
419
+ (type['array'] !== undefined));
442
420
  };
443
421
  Object.defineProperty(ArraySchema.prototype, "length", {
444
422
  get: function () {
@@ -514,18 +492,19 @@
514
492
  this.$indexes.delete(index);
515
493
  return this.$items.delete(index);
516
494
  };
517
- ArraySchema.prototype.clear = function (isDecoding) {
518
- var _this = this;
495
+ ArraySchema.prototype.clear = function (changes) {
519
496
  // discard previous operations.
520
497
  this.$changes.discard(true, true);
521
498
  this.$changes.indexes = {};
522
499
  // clear previous indexes
523
500
  this.$indexes.clear();
524
- // flag child items for garbage collection.
525
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
526
- this.$items.forEach(function (item) {
527
- _this.$changes.root.removeRef(item['$changes'].refId);
528
- });
501
+ //
502
+ // When decoding:
503
+ // - enqueue items for DELETE callback.
504
+ // - flag child items for garbage collection.
505
+ //
506
+ if (changes) {
507
+ removeChildRefs.call(this, changes);
529
508
  }
530
509
  // clear items
531
510
  this.$items.clear();
@@ -876,9 +855,6 @@
876
855
  }
877
856
  return cloned;
878
857
  };
879
- ArraySchema.prototype.triggerAll = function () {
880
- Schema.prototype.triggerAll.apply(this);
881
- };
882
858
  return ArraySchema;
883
859
  }());
884
860
 
@@ -932,6 +908,14 @@
932
908
  }
933
909
  }
934
910
  }
911
+ MapSchema.prototype.onAdd = function (callback, triggerAll) {
912
+ if (triggerAll === void 0) { triggerAll = true; }
913
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
914
+ ? this.$items
915
+ : undefined);
916
+ };
917
+ MapSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
918
+ MapSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
935
919
  MapSchema.is = function (type) {
936
920
  return type['map'] !== undefined;
937
921
  };
@@ -943,6 +927,9 @@
943
927
  configurable: true
944
928
  });
945
929
  MapSchema.prototype.set = function (key, value) {
930
+ if (value === undefined || value === null) {
931
+ throw new Error("MapSchema#set('" + key + "', " + value + "): trying to set " + value + " value on '" + key + "'.");
932
+ }
946
933
  // get "index" for this value.
947
934
  var hasIndex = typeof (this.$changes.indexes[key]) !== "undefined";
948
935
  var index = (hasIndex)
@@ -986,18 +973,19 @@
986
973
  this.$changes.delete(key);
987
974
  return this.$items.delete(key);
988
975
  };
989
- MapSchema.prototype.clear = function (isDecoding) {
990
- var _this = this;
976
+ MapSchema.prototype.clear = function (changes) {
991
977
  // discard previous operations.
992
978
  this.$changes.discard(true, true);
993
979
  this.$changes.indexes = {};
994
980
  // clear previous indexes
995
981
  this.$indexes.clear();
996
- // flag child items for garbage collection.
997
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
998
- this.$items.forEach(function (item) {
999
- _this.$changes.root.removeRef(item['$changes'].refId);
1000
- });
982
+ //
983
+ // When decoding:
984
+ // - enqueue items for DELETE callback.
985
+ // - flag child items for garbage collection.
986
+ //
987
+ if (changes) {
988
+ removeChildRefs.call(this, changes);
1001
989
  }
1002
990
  // clear items
1003
991
  this.$items.clear();
@@ -1073,9 +1061,6 @@
1073
1061
  }
1074
1062
  return cloned;
1075
1063
  };
1076
- MapSchema.prototype.triggerAll = function () {
1077
- Schema.prototype.triggerAll.apply(this);
1078
- };
1079
1064
  return MapSchema;
1080
1065
  }());
1081
1066
 
@@ -1115,6 +1100,9 @@
1115
1100
  ? { array: type[0] }
1116
1101
  : type;
1117
1102
  };
1103
+ SchemaDefinition.prototype.hasField = function (field) {
1104
+ return this.indexes[field] !== undefined;
1105
+ };
1118
1106
  SchemaDefinition.prototype.addFilter = function (field, cb) {
1119
1107
  if (!this.filters) {
1120
1108
  this.filters = {};
@@ -1170,21 +1158,38 @@
1170
1158
  this.types[typeid] = schema;
1171
1159
  this.schemas.set(schema, typeid);
1172
1160
  };
1173
- Context.create = function (context) {
1174
- if (context === void 0) { context = new Context; }
1161
+ Context.create = function (options) {
1162
+ if (options === void 0) { options = {}; }
1175
1163
  return function (definition) {
1176
- return type(definition, context);
1164
+ if (!options.context) {
1165
+ options.context = new Context();
1166
+ }
1167
+ return type(definition, options);
1177
1168
  };
1178
1169
  };
1179
1170
  return Context;
1180
1171
  }());
1181
1172
  var globalContext = new Context();
1182
1173
  /**
1183
- * `@type()` decorator for proxies
1174
+ * [See documentation](https://docs.colyseus.io/state/schema/)
1175
+ *
1176
+ * Annotate a Schema property to be serializeable.
1177
+ * \@type()'d fields are automatically flagged as "dirty" for the next patch.
1178
+ *
1179
+ * @example Standard usage, with automatic change tracking.
1180
+ * ```
1181
+ * \@type("string") propertyName: string;
1182
+ * ```
1183
+ *
1184
+ * @example You can provide the "manual" option if you'd like to manually control your patches via .setDirty().
1185
+ * ```
1186
+ * \@type("string", { manual: true })
1187
+ * ```
1184
1188
  */
1185
- function type(type, context) {
1186
- if (context === void 0) { context = globalContext; }
1189
+ function type(type, options) {
1190
+ if (options === void 0) { options = {}; }
1187
1191
  return function (target, field) {
1192
+ var context = options.context || globalContext;
1188
1193
  var constructor = target.constructor;
1189
1194
  constructor._context = context;
1190
1195
  /*
@@ -1199,7 +1204,21 @@
1199
1204
  * skip if descriptor already exists for this field (`@deprecated()`)
1200
1205
  */
1201
1206
  if (definition.descriptors[field]) {
1202
- return;
1207
+ if (definition.deprecated[field]) {
1208
+ // do not create accessors for deprecated properties.
1209
+ return;
1210
+ }
1211
+ else {
1212
+ // trying to define same property multiple times across inheritance.
1213
+ // https://github.com/colyseus/colyseus-unity3d/issues/131#issuecomment-814308572
1214
+ try {
1215
+ throw new Error("@colyseus/schema: Duplicate '" + field + "' definition on '" + constructor.name + "'.\nCheck @type() annotation");
1216
+ }
1217
+ catch (e) {
1218
+ var definitionAtLine = e.stack.split("\n")[4].trim();
1219
+ throw new Error(e.message + " " + definitionAtLine);
1220
+ }
1221
+ }
1203
1222
  }
1204
1223
  var isArray = ArraySchema.is(type);
1205
1224
  var isMap = !isArray && MapSchema.is(type);
@@ -1212,6 +1231,15 @@
1212
1231
  context.add(childType);
1213
1232
  }
1214
1233
  }
1234
+ if (options.manual) {
1235
+ // do not declare getter/setter descriptor
1236
+ definition.descriptors[field] = {
1237
+ enumerable: true,
1238
+ configurable: true,
1239
+ writable: true,
1240
+ };
1241
+ return;
1242
+ }
1215
1243
  var fieldCached = "_" + field;
1216
1244
  definition.descriptors[fieldCached] = {
1217
1245
  enumerable: false,
@@ -1297,7 +1325,7 @@
1297
1325
  * `@deprecated()` flag a field as deprecated.
1298
1326
  * The previous `@type()` annotation should remain along with this one.
1299
1327
  */
1300
- function deprecated(throws, context) {
1328
+ function deprecated(throws) {
1301
1329
  if (throws === void 0) { throws = true; }
1302
1330
  return function (target, field) {
1303
1331
  var constructor = target.constructor;
@@ -1313,10 +1341,13 @@
1313
1341
  }
1314
1342
  };
1315
1343
  }
1316
- function defineTypes(target, fields, context) {
1317
- if (context === void 0) { context = target._context || globalContext; }
1344
+ function defineTypes(target, fields, options) {
1345
+ if (options === void 0) { options = {}; }
1346
+ if (!options.context) {
1347
+ options.context = target._context || options.context || globalContext;
1348
+ }
1318
1349
  for (var field in fields) {
1319
- type(fields[field], context)(target.prototype, field);
1350
+ type(fields[field], options)(target.prototype, field);
1320
1351
  }
1321
1352
  return target;
1322
1353
  }
@@ -1854,6 +1885,14 @@
1854
1885
  initialValues.forEach(function (v) { return _this.add(v); });
1855
1886
  }
1856
1887
  }
1888
+ CollectionSchema.prototype.onAdd = function (callback, triggerAll) {
1889
+ if (triggerAll === void 0) { triggerAll = true; }
1890
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
1891
+ ? this.$items
1892
+ : undefined);
1893
+ };
1894
+ CollectionSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
1895
+ CollectionSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
1857
1896
  CollectionSchema.is = function (type) {
1858
1897
  return type['collection'] !== undefined;
1859
1898
  };
@@ -1897,18 +1936,19 @@
1897
1936
  this.$indexes.delete(index);
1898
1937
  return this.$items.delete(index);
1899
1938
  };
1900
- CollectionSchema.prototype.clear = function (isDecoding) {
1901
- var _this = this;
1939
+ CollectionSchema.prototype.clear = function (changes) {
1902
1940
  // discard previous operations.
1903
1941
  this.$changes.discard(true, true);
1904
1942
  this.$changes.indexes = {};
1905
1943
  // clear previous indexes
1906
1944
  this.$indexes.clear();
1907
- // flag child items for garbage collection.
1908
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
1909
- this.$items.forEach(function (item) {
1910
- _this.$changes.root.removeRef(item['$changes'].refId);
1911
- });
1945
+ //
1946
+ // When decoding:
1947
+ // - enqueue items for DELETE callback.
1948
+ // - flag child items for garbage collection.
1949
+ //
1950
+ if (changes) {
1951
+ removeChildRefs.call(this, changes);
1912
1952
  }
1913
1953
  // clear items
1914
1954
  this.$items.clear();
@@ -1982,9 +2022,6 @@
1982
2022
  }
1983
2023
  return cloned;
1984
2024
  };
1985
- CollectionSchema.prototype.triggerAll = function () {
1986
- Schema.prototype.triggerAll.apply(this);
1987
- };
1988
2025
  return CollectionSchema;
1989
2026
  }());
1990
2027
 
@@ -1999,23 +2036,33 @@
1999
2036
  initialValues.forEach(function (v) { return _this.add(v); });
2000
2037
  }
2001
2038
  }
2039
+ SetSchema.prototype.onAdd = function (callback, triggerAll) {
2040
+ if (triggerAll === void 0) { triggerAll = true; }
2041
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
2042
+ ? this.$items
2043
+ : undefined);
2044
+ };
2045
+ SetSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
2046
+ SetSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
2002
2047
  SetSchema.is = function (type) {
2003
2048
  return type['set'] !== undefined;
2004
2049
  };
2005
2050
  SetSchema.prototype.add = function (value) {
2051
+ var _a, _b;
2052
+ // immediatelly return false if value already added.
2006
2053
  if (this.has(value)) {
2007
2054
  return false;
2008
2055
  }
2009
2056
  // set "index" for reference.
2010
2057
  var index = this.$refId++;
2011
- var isRef = (value['$changes']) !== undefined;
2012
- if (isRef) {
2058
+ if ((value['$changes']) !== undefined) {
2013
2059
  value['$changes'].setParent(this, this.$changes.root, index);
2014
2060
  }
2061
+ var operation = (_b = (_a = this.$changes.indexes[index]) === null || _a === void 0 ? void 0 : _a.op) !== null && _b !== void 0 ? _b : exports.OPERATION.ADD;
2015
2062
  this.$changes.indexes[index] = index;
2016
2063
  this.$indexes.set(index, index);
2017
2064
  this.$items.set(index, value);
2018
- this.$changes.change(index);
2065
+ this.$changes.change(index, operation);
2019
2066
  return index;
2020
2067
  };
2021
2068
  SetSchema.prototype.entries = function () {
@@ -2041,18 +2088,19 @@
2041
2088
  this.$indexes.delete(index);
2042
2089
  return this.$items.delete(index);
2043
2090
  };
2044
- SetSchema.prototype.clear = function (isDecoding) {
2045
- var _this = this;
2091
+ SetSchema.prototype.clear = function (changes) {
2046
2092
  // discard previous operations.
2047
2093
  this.$changes.discard(true, true);
2048
2094
  this.$changes.indexes = {};
2049
2095
  // clear previous indexes
2050
2096
  this.$indexes.clear();
2051
- // flag child items for garbage collection.
2052
- if (isDecoding && typeof (this.$changes.getType()) !== "string") {
2053
- this.$items.forEach(function (item) {
2054
- _this.$changes.root.removeRef(item['$changes'].refId);
2055
- });
2097
+ //
2098
+ // When decoding:
2099
+ // - enqueue items for DELETE callback.
2100
+ // - flag child items for garbage collection.
2101
+ //
2102
+ if (changes) {
2103
+ removeChildRefs.call(this, changes);
2056
2104
  }
2057
2105
  // clear items
2058
2106
  this.$items.clear();
@@ -2138,48 +2186,9 @@
2138
2186
  }
2139
2187
  return cloned;
2140
2188
  };
2141
- SetSchema.prototype.triggerAll = function () {
2142
- Schema.prototype.triggerAll.apply(this);
2143
- };
2144
2189
  return SetSchema;
2145
2190
  }());
2146
2191
 
2147
- /**
2148
- * Extracted from https://www.npmjs.com/package/strong-events
2149
- */
2150
- var EventEmitter = /** @class */ (function () {
2151
- function EventEmitter() {
2152
- this.handlers = [];
2153
- }
2154
- EventEmitter.prototype.register = function (cb, once) {
2155
- this.handlers.push(cb);
2156
- return this;
2157
- };
2158
- EventEmitter.prototype.invoke = function () {
2159
- var args = [];
2160
- for (var _i = 0; _i < arguments.length; _i++) {
2161
- args[_i] = arguments[_i];
2162
- }
2163
- this.handlers.forEach(function (handler) { return handler.apply(void 0, args); });
2164
- };
2165
- EventEmitter.prototype.invokeAsync = function () {
2166
- var args = [];
2167
- for (var _i = 0; _i < arguments.length; _i++) {
2168
- args[_i] = arguments[_i];
2169
- }
2170
- return Promise.all(this.handlers.map(function (handler) { return handler.apply(void 0, args); }));
2171
- };
2172
- EventEmitter.prototype.remove = function (cb) {
2173
- var index = this.handlers.indexOf(cb);
2174
- this.handlers[index] = this.handlers[this.handlers.length - 1];
2175
- this.handlers.pop();
2176
- };
2177
- EventEmitter.prototype.clear = function () {
2178
- this.handlers = [];
2179
- };
2180
- return EventEmitter;
2181
- }());
2182
-
2183
2192
  var ClientState = /** @class */ (function () {
2184
2193
  function ClientState() {
2185
2194
  this.refIds = new WeakSet();
@@ -2201,6 +2210,78 @@
2201
2210
  return ClientState;
2202
2211
  }());
2203
2212
 
2213
+ var ReferenceTracker = /** @class */ (function () {
2214
+ function ReferenceTracker() {
2215
+ //
2216
+ // Relation of refId => Schema structure
2217
+ // For direct access of structures during decoding time.
2218
+ //
2219
+ this.refs = new Map();
2220
+ this.refCounts = {};
2221
+ this.deletedRefs = new Set();
2222
+ this.nextUniqueId = 0;
2223
+ }
2224
+ ReferenceTracker.prototype.getNextUniqueId = function () {
2225
+ return this.nextUniqueId++;
2226
+ };
2227
+ // for decoding
2228
+ ReferenceTracker.prototype.addRef = function (refId, ref, incrementCount) {
2229
+ if (incrementCount === void 0) { incrementCount = true; }
2230
+ this.refs.set(refId, ref);
2231
+ if (incrementCount) {
2232
+ this.refCounts[refId] = (this.refCounts[refId] || 0) + 1;
2233
+ }
2234
+ };
2235
+ // for decoding
2236
+ ReferenceTracker.prototype.removeRef = function (refId) {
2237
+ this.refCounts[refId] = this.refCounts[refId] - 1;
2238
+ this.deletedRefs.add(refId);
2239
+ };
2240
+ ReferenceTracker.prototype.clearRefs = function () {
2241
+ this.refs.clear();
2242
+ this.deletedRefs.clear();
2243
+ this.refCounts = {};
2244
+ };
2245
+ // for decoding
2246
+ ReferenceTracker.prototype.garbageCollectDeletedRefs = function () {
2247
+ var _this = this;
2248
+ this.deletedRefs.forEach(function (refId) {
2249
+ //
2250
+ // Skip active references.
2251
+ //
2252
+ if (_this.refCounts[refId] > 0) {
2253
+ return;
2254
+ }
2255
+ var ref = _this.refs.get(refId);
2256
+ //
2257
+ // Ensure child schema instances have their references removed as well.
2258
+ //
2259
+ if (ref instanceof Schema) {
2260
+ for (var fieldName in ref['_definition'].schema) {
2261
+ if (typeof (ref['_definition'].schema[fieldName]) !== "string" &&
2262
+ ref[fieldName] &&
2263
+ ref[fieldName]['$changes']) {
2264
+ _this.removeRef(ref[fieldName]['$changes'].refId);
2265
+ }
2266
+ }
2267
+ }
2268
+ else {
2269
+ var definition = ref['$changes'].parent._definition;
2270
+ var type = definition.schema[definition.fieldsByIndex[ref['$changes'].parentIndex]];
2271
+ if (typeof (Object.values(type)[0]) === "function") {
2272
+ Array.from(ref.values())
2273
+ .forEach(function (child) { return _this.removeRef(child['$changes'].refId); });
2274
+ }
2275
+ }
2276
+ _this.refs.delete(refId);
2277
+ delete _this.refCounts[refId];
2278
+ });
2279
+ // clear deleted refs.
2280
+ this.deletedRefs.clear();
2281
+ };
2282
+ return ReferenceTracker;
2283
+ }());
2284
+
2204
2285
  var EncodeSchemaError = /** @class */ (function (_super) {
2205
2286
  __extends(EncodeSchemaError, _super);
2206
2287
  function EncodeSchemaError() {
@@ -2272,12 +2353,17 @@
2272
2353
  // fix enumerability of fields for end-user
2273
2354
  Object.defineProperties(this, {
2274
2355
  $changes: {
2275
- value: new ChangeTree(this, undefined, new Root()),
2356
+ value: new ChangeTree(this, undefined, new ReferenceTracker()),
2276
2357
  enumerable: false,
2277
2358
  writable: true
2278
2359
  },
2279
- $listeners: {
2280
- value: {},
2360
+ // $listeners: {
2361
+ // value: undefined,
2362
+ // enumerable: false,
2363
+ // writable: true
2364
+ // },
2365
+ $callbacks: {
2366
+ value: undefined,
2281
2367
  enumerable: false,
2282
2368
  writable: true
2283
2369
  },
@@ -2300,6 +2386,12 @@
2300
2386
  return (type['_definition'] &&
2301
2387
  type['_definition'].schema !== undefined);
2302
2388
  };
2389
+ Schema.prototype.onChange = function (callback) {
2390
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.REPLACE, callback);
2391
+ };
2392
+ Schema.prototype.onRemove = function (callback) {
2393
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.DELETE, callback);
2394
+ };
2303
2395
  Schema.prototype.assign = function (props) {
2304
2396
  Object.assign(this, props);
2305
2397
  return this;
@@ -2309,27 +2401,35 @@
2309
2401
  enumerable: false,
2310
2402
  configurable: true
2311
2403
  });
2404
+ /**
2405
+ * (Server-side): Flag a property to be encoded for the next patch.
2406
+ * @param instance Schema instance
2407
+ * @param property string representing the property name, or number representing the index of the property.
2408
+ * @param operation OPERATION to perform (detected automatically)
2409
+ */
2410
+ Schema.prototype.setDirty = function (property, operation) {
2411
+ this.$changes.change(property, operation);
2412
+ };
2312
2413
  Schema.prototype.listen = function (attr, callback) {
2313
2414
  var _this = this;
2314
- if (!this.$listeners[attr]) {
2315
- this.$listeners[attr] = new EventEmitter();
2415
+ if (!this.$callbacks) {
2416
+ this.$callbacks = {};
2417
+ }
2418
+ if (!this.$callbacks[attr]) {
2419
+ this.$callbacks[attr] = [];
2316
2420
  }
2317
- this.$listeners[attr].register(callback);
2421
+ this.$callbacks[attr].push(callback);
2318
2422
  // return un-register callback.
2319
- return function () {
2320
- return _this.$listeners[attr].remove(callback);
2321
- };
2423
+ return function () { return spliceOne(_this.$callbacks[attr], _this.$callbacks[attr].indexOf(callback)); };
2322
2424
  };
2323
- Schema.prototype.decode = function (bytes, it, ref, allChanges) {
2425
+ Schema.prototype.decode = function (bytes, it, ref) {
2324
2426
  if (it === void 0) { it = { offset: 0 }; }
2325
2427
  if (ref === void 0) { ref = this; }
2326
- if (allChanges === void 0) { allChanges = new Map(); }
2428
+ var allChanges = [];
2327
2429
  var $root = this.$changes.root;
2328
2430
  var totalBytes = bytes.length;
2329
2431
  var refId = 0;
2330
- var changes = [];
2331
2432
  $root.refs.set(refId, this);
2332
- allChanges.set(refId, changes);
2333
2433
  while (it.offset < totalBytes) {
2334
2434
  var byte = bytes[it.offset++];
2335
2435
  if (byte == SWITCH_TO_STRUCTURE) {
@@ -2342,9 +2442,6 @@
2342
2442
  throw new Error("\"refId\" not found: " + refId);
2343
2443
  }
2344
2444
  ref = nextRef;
2345
- // create empty list of changes for this refId.
2346
- changes = [];
2347
- allChanges.set(refId, changes);
2348
2445
  continue;
2349
2446
  }
2350
2447
  var changeTree = ref['$changes'];
@@ -2358,7 +2455,7 @@
2358
2455
  // The `.clear()` method is calling `$root.removeRef(refId)` for
2359
2456
  // each item inside this collection
2360
2457
  //
2361
- ref.clear(true);
2458
+ ref.clear(allChanges);
2362
2459
  continue;
2363
2460
  }
2364
2461
  var fieldIndex = (isSchema)
@@ -2428,9 +2525,8 @@
2428
2525
  value = this.createTypeInstance(childType);
2429
2526
  value.$changes.refId = refId_1;
2430
2527
  if (previousValue) {
2431
- value.onChange = previousValue.onChange;
2432
- value.onRemove = previousValue.onRemove;
2433
- value.$listeners = previousValue.$listeners;
2528
+ value.$callbacks = previousValue.$callbacks;
2529
+ // value.$listeners = previousValue.$listeners;
2434
2530
  if (previousValue['$changes'].refId &&
2435
2531
  refId_1 !== previousValue['$changes'].refId) {
2436
2532
  $root.removeRef(previousValue['$changes'].refId);
@@ -2456,40 +2552,29 @@
2456
2552
  value.$changes.refId = refId_2;
2457
2553
  // preserve schema callbacks
2458
2554
  if (previousValue) {
2459
- value.onAdd = previousValue.onAdd;
2460
- value.onRemove = previousValue.onRemove;
2461
- value.onChange = previousValue.onChange;
2555
+ value['$callbacks'] = previousValue['$callbacks'];
2462
2556
  if (previousValue['$changes'].refId &&
2463
2557
  refId_2 !== previousValue['$changes'].refId) {
2464
2558
  $root.removeRef(previousValue['$changes'].refId);
2465
2559
  //
2466
2560
  // Trigger onRemove if structure has been replaced.
2467
2561
  //
2468
- var deletes = [];
2469
2562
  var entries = previousValue.entries();
2470
2563
  var iter = void 0;
2471
2564
  while ((iter = entries.next()) && !iter.done) {
2472
2565
  var _a = iter.value, key = _a[0], value_1 = _a[1];
2473
- deletes.push({
2566
+ allChanges.push({
2567
+ refId: refId_2,
2474
2568
  op: exports.OPERATION.DELETE,
2475
2569
  field: key,
2476
2570
  value: undefined,
2477
2571
  previousValue: value_1,
2478
2572
  });
2479
2573
  }
2480
- allChanges.set(previousValue['$changes'].refId, deletes);
2481
2574
  }
2482
2575
  }
2483
2576
  $root.addRef(refId_2, value, (valueRef !== previousValue));
2484
- //
2485
- // TODO: deprecate proxies on next version.
2486
- // get proxy to target value.
2487
- //
2488
- if (typeDef.getProxy) {
2489
- value = typeDef.getProxy(value);
2490
- }
2491
2577
  }
2492
- var hasChange = (previousValue !== value);
2493
2578
  if (value !== null &&
2494
2579
  value !== undefined) {
2495
2580
  if (value['$changes']) {
@@ -2497,14 +2582,7 @@
2497
2582
  }
2498
2583
  if (ref instanceof Schema) {
2499
2584
  ref[fieldName] = value;
2500
- //
2501
- // FIXME: use `_field` instead of `field`.
2502
- //
2503
- // `field` is going to use the setter of the PropertyDescriptor
2504
- // and create a proxy for array/map. This is only useful for
2505
- // backwards-compatibility with @colyseus/schema@0.5.x
2506
- //
2507
- // // ref[_field] = value;
2585
+ // ref[`_${fieldName}`] = value;
2508
2586
  }
2509
2587
  else if (ref instanceof MapSchema) {
2510
2588
  // const key = ref['$indexes'].get(field);
@@ -2518,19 +2596,20 @@
2518
2596
  // ref[key] = value;
2519
2597
  ref.setAt(fieldIndex, value);
2520
2598
  }
2521
- else if (ref instanceof CollectionSchema ||
2522
- ref instanceof SetSchema) {
2599
+ else if (ref instanceof CollectionSchema) {
2523
2600
  var index = ref.add(value);
2524
2601
  ref['setIndex'](fieldIndex, index);
2525
2602
  }
2603
+ else if (ref instanceof SetSchema) {
2604
+ var index = ref.add(value);
2605
+ if (index !== false) {
2606
+ ref['setIndex'](fieldIndex, index);
2607
+ }
2608
+ }
2526
2609
  }
2527
- if (hasChange
2528
- // &&
2529
- // (
2530
- // this.onChange || ref.$listeners[field]
2531
- // )
2532
- ) {
2533
- changes.push({
2610
+ if (previousValue !== value) {
2611
+ allChanges.push({
2612
+ refId: refId,
2534
2613
  op: operation,
2535
2614
  field: fieldName,
2536
2615
  dynamicIndex: dynamicIndex,
@@ -2684,6 +2763,7 @@
2684
2763
  return this.encode(true, [], useFilters);
2685
2764
  };
2686
2765
  Schema.prototype.applyFilters = function (client, encodeAll) {
2766
+ var _a, _b;
2687
2767
  if (encodeAll === void 0) { encodeAll = false; }
2688
2768
  var root = this;
2689
2769
  var refIdsDissallowed = new Set();
@@ -2802,7 +2882,7 @@
2802
2882
  //
2803
2883
  // use cached bytes directly if is from Schema type.
2804
2884
  //
2805
- filteredBytes = filteredBytes.concat(changeTree.caches[fieldIndex]);
2885
+ filteredBytes.push.apply(filteredBytes, (_a = changeTree.caches[fieldIndex]) !== null && _a !== void 0 ? _a : []);
2806
2886
  containerIndexes.add(fieldIndex);
2807
2887
  }
2808
2888
  else {
@@ -2810,7 +2890,7 @@
2810
2890
  //
2811
2891
  // use cached bytes if already has the field
2812
2892
  //
2813
- filteredBytes = filteredBytes.concat(changeTree.caches[fieldIndex]);
2893
+ filteredBytes.push.apply(filteredBytes, (_b = changeTree.caches[fieldIndex]) !== null && _b !== void 0 ? _b : []);
2814
2894
  }
2815
2895
  else {
2816
2896
  //
@@ -2878,20 +2958,6 @@
2878
2958
  }
2879
2959
  return cloned;
2880
2960
  };
2881
- Schema.prototype.triggerAll = function () {
2882
- // skip if haven't received any remote refs yet.
2883
- if (this.$changes.root.refs.size === 0) {
2884
- return;
2885
- }
2886
- var allChanges = new Map();
2887
- Schema.prototype._triggerAllFillChanges.call(this, this, allChanges);
2888
- try {
2889
- Schema.prototype._triggerChanges.call(this, allChanges);
2890
- }
2891
- catch (e) {
2892
- Schema.onError(e);
2893
- }
2894
- };
2895
2961
  Schema.prototype.toJSON = function () {
2896
2962
  var schema = this._definition.schema;
2897
2963
  var deprecated = this._definition.deprecated;
@@ -2934,111 +3000,81 @@
2934
3000
  instance.$changes.root = this.$changes.root;
2935
3001
  return instance;
2936
3002
  };
2937
- Schema.prototype._triggerAllFillChanges = function (ref, allChanges) {
2938
- if (allChanges.has(ref['$changes'].refId)) {
2939
- return;
2940
- }
2941
- var changes = [];
2942
- allChanges.set(ref['$changes'].refId || 0, changes);
2943
- if (ref instanceof Schema) {
2944
- var schema = ref._definition.schema;
2945
- for (var fieldName in schema) {
2946
- var _field = "_" + fieldName;
2947
- var value = ref[_field];
2948
- if (value !== undefined) {
2949
- changes.push({
2950
- op: exports.OPERATION.ADD,
2951
- field: fieldName,
2952
- value: value,
2953
- previousValue: undefined
2954
- });
2955
- if (value['$changes'] !== undefined) {
2956
- Schema.prototype._triggerAllFillChanges.call(this, value, allChanges);
3003
+ Schema.prototype._triggerChanges = function (changes) {
3004
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3005
+ var uniqueRefIds = new Set();
3006
+ var $refs = this.$changes.root.refs;
3007
+ var _loop_2 = function (i) {
3008
+ var change = changes[i];
3009
+ var refId = change.refId;
3010
+ var ref = $refs.get(refId);
3011
+ var $callbacks = ref['$callbacks'];
3012
+ //
3013
+ // trigger onRemove on child structure.
3014
+ //
3015
+ if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
3016
+ change.previousValue instanceof Schema) {
3017
+ (_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(); });
3018
+ }
3019
+ // no callbacks defined, skip this structure!
3020
+ if (!$callbacks) {
3021
+ return "continue";
3022
+ }
3023
+ if (ref instanceof Schema) {
3024
+ if (!uniqueRefIds.has(refId)) {
3025
+ try {
3026
+ // trigger onChange
3027
+ (_d = (_c = $callbacks) === null || _c === void 0 ? void 0 : _c[exports.OPERATION.REPLACE]) === null || _d === void 0 ? void 0 : _d.forEach(function (callback) {
3028
+ return callback(changes);
3029
+ });
3030
+ }
3031
+ catch (e) {
3032
+ Schema.onError(e);
2957
3033
  }
2958
3034
  }
2959
- }
2960
- }
2961
- else {
2962
- var entries = ref.entries();
2963
- var iter = void 0;
2964
- while ((iter = entries.next()) && !iter.done) {
2965
- var _a = iter.value, key = _a[0], value = _a[1];
2966
- changes.push({
2967
- op: exports.OPERATION.ADD,
2968
- field: key,
2969
- dynamicIndex: key,
2970
- value: value,
2971
- previousValue: undefined,
2972
- });
2973
- if (value['$changes'] !== undefined) {
2974
- Schema.prototype._triggerAllFillChanges.call(this, value, allChanges);
3035
+ try {
3036
+ (_e = $callbacks[change.field]) === null || _e === void 0 ? void 0 : _e.forEach(function (callback) {
3037
+ return callback(change.value, change.previousValue);
3038
+ });
3039
+ }
3040
+ catch (e) {
3041
+ Schema.onError(e);
2975
3042
  }
2976
3043
  }
2977
- }
2978
- };
2979
- Schema.prototype._triggerChanges = function (allChanges) {
2980
- var _this = this;
2981
- allChanges.forEach(function (changes, refId) {
2982
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
2983
- if (changes.length > 0) {
2984
- var ref = _this.$changes.root.refs.get(refId);
2985
- var isSchema = ref instanceof Schema;
2986
- for (var i = 0; i < changes.length; i++) {
2987
- var change = changes[i];
2988
- var listener = ref['$listeners'] && ref['$listeners'][change.field];
2989
- if (!isSchema) {
2990
- if (change.op === exports.OPERATION.ADD && change.previousValue === undefined) {
2991
- (_b = (_a = ref).onAdd) === null || _b === void 0 ? void 0 : _b.call(_a, change.value, (_c = change.dynamicIndex) !== null && _c !== void 0 ? _c : change.field);
2992
- }
2993
- else if (change.op === exports.OPERATION.DELETE) {
2994
- //
2995
- // FIXME: `previousValue` should always be avaiiable.
2996
- // ADD + DELETE operations are still encoding DELETE operation.
2997
- //
2998
- if (change.previousValue !== undefined) {
2999
- (_e = (_d = ref).onRemove) === null || _e === void 0 ? void 0 : _e.call(_d, change.previousValue, (_f = change.dynamicIndex) !== null && _f !== void 0 ? _f : change.field);
3000
- }
3001
- }
3002
- else if (change.op === exports.OPERATION.DELETE_AND_ADD) {
3003
- if (change.previousValue !== undefined) {
3004
- (_h = (_g = ref).onRemove) === null || _h === void 0 ? void 0 : _h.call(_g, change.previousValue, change.dynamicIndex);
3005
- }
3006
- (_k = (_j = ref).onAdd) === null || _k === void 0 ? void 0 : _k.call(_j, change.value, change.dynamicIndex);
3007
- }
3008
- else if (change.op === exports.OPERATION.REPLACE ||
3009
- change.value !== change.previousValue) {
3010
- (_m = (_l = ref).onChange) === null || _m === void 0 ? void 0 : _m.call(_l, change.value, change.dynamicIndex);
3011
- }
3012
- }
3044
+ else {
3045
+ // is a collection of items
3046
+ if (change.op === exports.OPERATION.ADD && change.previousValue === undefined) {
3047
+ // triger onAdd
3048
+ (_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); });
3049
+ }
3050
+ else if (change.op === exports.OPERATION.DELETE) {
3013
3051
  //
3014
- // trigger onRemove on child structure.
3052
+ // FIXME: `previousValue` should always be available.
3053
+ // ADD + DELETE operations are still encoding DELETE operation.
3015
3054
  //
3016
- if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
3017
- change.previousValue instanceof Schema &&
3018
- change.previousValue.onRemove) {
3019
- change.previousValue.onRemove();
3020
- }
3021
- if (listener) {
3022
- try {
3023
- listener.invoke(change.value, change.previousValue);
3024
- }
3025
- catch (e) {
3026
- Schema.onError(e);
3027
- }
3055
+ if (change.previousValue !== undefined) {
3056
+ // triger onRemove
3057
+ (_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); });
3028
3058
  }
3029
3059
  }
3030
- if (isSchema) {
3031
- if (ref.onChange) {
3032
- try {
3033
- ref.onChange(changes);
3034
- }
3035
- catch (e) {
3036
- Schema.onError(e);
3037
- }
3060
+ else if (change.op === exports.OPERATION.DELETE_AND_ADD) {
3061
+ // triger onRemove
3062
+ if (change.previousValue !== undefined) {
3063
+ (_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); });
3038
3064
  }
3065
+ // triger onAdd
3066
+ (_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); });
3067
+ }
3068
+ // trigger onChange
3069
+ if (change.value !== change.previousValue) {
3070
+ (_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); });
3039
3071
  }
3040
3072
  }
3041
- });
3073
+ uniqueRefIds.add(refId);
3074
+ };
3075
+ for (var i = 0; i < changes.length; i++) {
3076
+ _loop_2(i);
3077
+ }
3042
3078
  };
3043
3079
  Schema._definition = SchemaDefinition.create();
3044
3080
  return Schema;
@@ -3066,7 +3102,7 @@
3066
3102
  return dump;
3067
3103
  }
3068
3104
 
3069
- var reflectionContext = new Context();
3105
+ var reflectionContext = { context: new Context() };
3070
3106
  /**
3071
3107
  * Reflection
3072
3108
  */
@@ -3187,14 +3223,14 @@
3187
3223
  refType = typeInfo[1];
3188
3224
  }
3189
3225
  if (fieldType === "ref") {
3190
- type(refType, context)(schemaType.prototype, field.name);
3226
+ type(refType, { context: context })(schemaType.prototype, field.name);
3191
3227
  }
3192
3228
  else {
3193
- type((_a = {}, _a[fieldType] = refType, _a), context)(schemaType.prototype, field.name);
3229
+ type((_a = {}, _a[fieldType] = refType, _a), { context: context })(schemaType.prototype, field.name);
3194
3230
  }
3195
3231
  }
3196
3232
  else {
3197
- type(field.type, context)(schemaType.prototype, field.name);
3233
+ type(field.type, { context: context })(schemaType.prototype, field.name);
3198
3234
  }
3199
3235
  });
3200
3236
  });
@@ -3223,8 +3259,8 @@
3223
3259
  return Reflection;
3224
3260
  }(Schema));
3225
3261
 
3226
- registerType("map", { constructor: MapSchema, getProxy: getMapProxy });
3227
- registerType("array", { constructor: ArraySchema, getProxy: getArrayProxy });
3262
+ registerType("map", { constructor: MapSchema });
3263
+ registerType("array", { constructor: ArraySchema });
3228
3264
  registerType("set", { constructor: SetSchema });
3229
3265
  registerType("collection", { constructor: CollectionSchema, });
3230
3266