@colyseus/schema 1.1.0-alpha.1 → 2.0.2

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 (55) hide show
  1. package/README.md +1 -4
  2. package/build/cjs/index.js +1197 -1001
  3. package/build/cjs/index.js.map +1 -1
  4. package/build/esm/index.mjs +353 -311
  5. package/build/esm/index.mjs.map +1 -1
  6. package/build/umd/index.js +374 -335
  7. package/lib/Reflection.js +23 -13
  8. package/lib/Reflection.js.map +1 -1
  9. package/lib/Schema.d.ts +26 -18
  10. package/lib/Schema.js +121 -165
  11. package/lib/Schema.js.map +1 -1
  12. package/lib/annotations.d.ts +26 -8
  13. package/lib/annotations.js +62 -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 +11 -2
  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/codegen/types.js +14 -1
  28. package/lib/codegen/types.js.map +1 -1
  29. package/lib/events/EventEmitter.d.ts +4 -4
  30. package/lib/events/EventEmitter.js +10 -10
  31. package/lib/events/EventEmitter.js.map +1 -1
  32. package/lib/filters/index.d.ts +2 -2
  33. package/lib/filters/index.js.map +1 -1
  34. package/lib/index.d.ts +1 -1
  35. package/lib/index.js +6 -6
  36. package/lib/index.js.map +1 -1
  37. package/lib/types/ArraySchema.d.ts +8 -5
  38. package/lib/types/ArraySchema.js +22 -19
  39. package/lib/types/ArraySchema.js.map +1 -1
  40. package/lib/types/CollectionSchema.d.ts +8 -5
  41. package/lib/types/CollectionSchema.js +17 -11
  42. package/lib/types/CollectionSchema.js.map +1 -1
  43. package/lib/types/MapSchema.d.ts +8 -5
  44. package/lib/types/MapSchema.js +20 -11
  45. package/lib/types/MapSchema.js.map +1 -1
  46. package/lib/types/SetSchema.d.ts +8 -5
  47. package/lib/types/SetSchema.js +22 -14
  48. package/lib/types/SetSchema.js.map +1 -1
  49. package/lib/types/typeRegistry.d.ts +5 -0
  50. package/lib/types/typeRegistry.js +13 -0
  51. package/lib/types/typeRegistry.js.map +1 -0
  52. package/lib/types/utils.d.ts +9 -0
  53. package/lib/types/utils.js +50 -0
  54. package/lib/types/utils.js.map +1 -0
  55. 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,23 +1158,43 @@
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;
1195
+ if (!type) {
1196
+ throw new Error(constructor.name + ": @type() reference provided for \"" + field + "\" is undefined. Make sure you don't have any circular dependencies.");
1197
+ }
1190
1198
  /*
1191
1199
  * static schema
1192
1200
  */
@@ -1199,7 +1207,21 @@
1199
1207
  * skip if descriptor already exists for this field (`@deprecated()`)
1200
1208
  */
1201
1209
  if (definition.descriptors[field]) {
1202
- return;
1210
+ if (definition.deprecated[field]) {
1211
+ // do not create accessors for deprecated properties.
1212
+ return;
1213
+ }
1214
+ else {
1215
+ // trying to define same property multiple times across inheritance.
1216
+ // https://github.com/colyseus/colyseus-unity3d/issues/131#issuecomment-814308572
1217
+ try {
1218
+ throw new Error("@colyseus/schema: Duplicate '" + field + "' definition on '" + constructor.name + "'.\nCheck @type() annotation");
1219
+ }
1220
+ catch (e) {
1221
+ var definitionAtLine = e.stack.split("\n")[4].trim();
1222
+ throw new Error(e.message + " " + definitionAtLine);
1223
+ }
1224
+ }
1203
1225
  }
1204
1226
  var isArray = ArraySchema.is(type);
1205
1227
  var isMap = !isArray && MapSchema.is(type);
@@ -1212,6 +1234,15 @@
1212
1234
  context.add(childType);
1213
1235
  }
1214
1236
  }
1237
+ if (options.manual) {
1238
+ // do not declare getter/setter descriptor
1239
+ definition.descriptors[field] = {
1240
+ enumerable: true,
1241
+ configurable: true,
1242
+ writable: true,
1243
+ };
1244
+ return;
1245
+ }
1215
1246
  var fieldCached = "_" + field;
1216
1247
  definition.descriptors[fieldCached] = {
1217
1248
  enumerable: false,
@@ -1297,7 +1328,7 @@
1297
1328
  * `@deprecated()` flag a field as deprecated.
1298
1329
  * The previous `@type()` annotation should remain along with this one.
1299
1330
  */
1300
- function deprecated(throws, context) {
1331
+ function deprecated(throws) {
1301
1332
  if (throws === void 0) { throws = true; }
1302
1333
  return function (target, field) {
1303
1334
  var constructor = target.constructor;
@@ -1313,10 +1344,13 @@
1313
1344
  }
1314
1345
  };
1315
1346
  }
1316
- function defineTypes(target, fields, context) {
1317
- if (context === void 0) { context = target._context || globalContext; }
1347
+ function defineTypes(target, fields, options) {
1348
+ if (options === void 0) { options = {}; }
1349
+ if (!options.context) {
1350
+ options.context = target._context || options.context || globalContext;
1351
+ }
1318
1352
  for (var field in fields) {
1319
- type(fields[field], context)(target.prototype, field);
1353
+ type(fields[field], options)(target.prototype, field);
1320
1354
  }
1321
1355
  return target;
1322
1356
  }
@@ -1854,6 +1888,14 @@
1854
1888
  initialValues.forEach(function (v) { return _this.add(v); });
1855
1889
  }
1856
1890
  }
1891
+ CollectionSchema.prototype.onAdd = function (callback, triggerAll) {
1892
+ if (triggerAll === void 0) { triggerAll = true; }
1893
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
1894
+ ? this.$items
1895
+ : undefined);
1896
+ };
1897
+ CollectionSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
1898
+ CollectionSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
1857
1899
  CollectionSchema.is = function (type) {
1858
1900
  return type['collection'] !== undefined;
1859
1901
  };
@@ -1897,18 +1939,19 @@
1897
1939
  this.$indexes.delete(index);
1898
1940
  return this.$items.delete(index);
1899
1941
  };
1900
- CollectionSchema.prototype.clear = function (isDecoding) {
1901
- var _this = this;
1942
+ CollectionSchema.prototype.clear = function (changes) {
1902
1943
  // discard previous operations.
1903
1944
  this.$changes.discard(true, true);
1904
1945
  this.$changes.indexes = {};
1905
1946
  // clear previous indexes
1906
1947
  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
- });
1948
+ //
1949
+ // When decoding:
1950
+ // - enqueue items for DELETE callback.
1951
+ // - flag child items for garbage collection.
1952
+ //
1953
+ if (changes) {
1954
+ removeChildRefs.call(this, changes);
1912
1955
  }
1913
1956
  // clear items
1914
1957
  this.$items.clear();
@@ -1982,9 +2025,6 @@
1982
2025
  }
1983
2026
  return cloned;
1984
2027
  };
1985
- CollectionSchema.prototype.triggerAll = function () {
1986
- Schema.prototype.triggerAll.apply(this);
1987
- };
1988
2028
  return CollectionSchema;
1989
2029
  }());
1990
2030
 
@@ -1999,23 +2039,33 @@
1999
2039
  initialValues.forEach(function (v) { return _this.add(v); });
2000
2040
  }
2001
2041
  }
2042
+ SetSchema.prototype.onAdd = function (callback, triggerAll) {
2043
+ if (triggerAll === void 0) { triggerAll = true; }
2044
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.ADD, callback, (triggerAll)
2045
+ ? this.$items
2046
+ : undefined);
2047
+ };
2048
+ SetSchema.prototype.onRemove = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.DELETE, callback); };
2049
+ SetSchema.prototype.onChange = function (callback) { return addCallback(this.$callbacks || (this.$callbacks = []), exports.OPERATION.REPLACE, callback); };
2002
2050
  SetSchema.is = function (type) {
2003
2051
  return type['set'] !== undefined;
2004
2052
  };
2005
2053
  SetSchema.prototype.add = function (value) {
2054
+ var _a, _b;
2055
+ // immediatelly return false if value already added.
2006
2056
  if (this.has(value)) {
2007
2057
  return false;
2008
2058
  }
2009
2059
  // set "index" for reference.
2010
2060
  var index = this.$refId++;
2011
- var isRef = (value['$changes']) !== undefined;
2012
- if (isRef) {
2061
+ if ((value['$changes']) !== undefined) {
2013
2062
  value['$changes'].setParent(this, this.$changes.root, index);
2014
2063
  }
2064
+ 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
2065
  this.$changes.indexes[index] = index;
2016
2066
  this.$indexes.set(index, index);
2017
2067
  this.$items.set(index, value);
2018
- this.$changes.change(index);
2068
+ this.$changes.change(index, operation);
2019
2069
  return index;
2020
2070
  };
2021
2071
  SetSchema.prototype.entries = function () {
@@ -2041,18 +2091,19 @@
2041
2091
  this.$indexes.delete(index);
2042
2092
  return this.$items.delete(index);
2043
2093
  };
2044
- SetSchema.prototype.clear = function (isDecoding) {
2045
- var _this = this;
2094
+ SetSchema.prototype.clear = function (changes) {
2046
2095
  // discard previous operations.
2047
2096
  this.$changes.discard(true, true);
2048
2097
  this.$changes.indexes = {};
2049
2098
  // clear previous indexes
2050
2099
  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
- });
2100
+ //
2101
+ // When decoding:
2102
+ // - enqueue items for DELETE callback.
2103
+ // - flag child items for garbage collection.
2104
+ //
2105
+ if (changes) {
2106
+ removeChildRefs.call(this, changes);
2056
2107
  }
2057
2108
  // clear items
2058
2109
  this.$items.clear();
@@ -2138,48 +2189,9 @@
2138
2189
  }
2139
2190
  return cloned;
2140
2191
  };
2141
- SetSchema.prototype.triggerAll = function () {
2142
- Schema.prototype.triggerAll.apply(this);
2143
- };
2144
2192
  return SetSchema;
2145
2193
  }());
2146
2194
 
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
2195
  var ClientState = /** @class */ (function () {
2184
2196
  function ClientState() {
2185
2197
  this.refIds = new WeakSet();
@@ -2201,6 +2213,78 @@
2201
2213
  return ClientState;
2202
2214
  }());
2203
2215
 
2216
+ var ReferenceTracker = /** @class */ (function () {
2217
+ function ReferenceTracker() {
2218
+ //
2219
+ // Relation of refId => Schema structure
2220
+ // For direct access of structures during decoding time.
2221
+ //
2222
+ this.refs = new Map();
2223
+ this.refCounts = {};
2224
+ this.deletedRefs = new Set();
2225
+ this.nextUniqueId = 0;
2226
+ }
2227
+ ReferenceTracker.prototype.getNextUniqueId = function () {
2228
+ return this.nextUniqueId++;
2229
+ };
2230
+ // for decoding
2231
+ ReferenceTracker.prototype.addRef = function (refId, ref, incrementCount) {
2232
+ if (incrementCount === void 0) { incrementCount = true; }
2233
+ this.refs.set(refId, ref);
2234
+ if (incrementCount) {
2235
+ this.refCounts[refId] = (this.refCounts[refId] || 0) + 1;
2236
+ }
2237
+ };
2238
+ // for decoding
2239
+ ReferenceTracker.prototype.removeRef = function (refId) {
2240
+ this.refCounts[refId] = this.refCounts[refId] - 1;
2241
+ this.deletedRefs.add(refId);
2242
+ };
2243
+ ReferenceTracker.prototype.clearRefs = function () {
2244
+ this.refs.clear();
2245
+ this.deletedRefs.clear();
2246
+ this.refCounts = {};
2247
+ };
2248
+ // for decoding
2249
+ ReferenceTracker.prototype.garbageCollectDeletedRefs = function () {
2250
+ var _this = this;
2251
+ this.deletedRefs.forEach(function (refId) {
2252
+ //
2253
+ // Skip active references.
2254
+ //
2255
+ if (_this.refCounts[refId] > 0) {
2256
+ return;
2257
+ }
2258
+ var ref = _this.refs.get(refId);
2259
+ //
2260
+ // Ensure child schema instances have their references removed as well.
2261
+ //
2262
+ if (ref instanceof Schema) {
2263
+ for (var fieldName in ref['_definition'].schema) {
2264
+ if (typeof (ref['_definition'].schema[fieldName]) !== "string" &&
2265
+ ref[fieldName] &&
2266
+ ref[fieldName]['$changes']) {
2267
+ _this.removeRef(ref[fieldName]['$changes'].refId);
2268
+ }
2269
+ }
2270
+ }
2271
+ else {
2272
+ var definition = ref['$changes'].parent._definition;
2273
+ var type = definition.schema[definition.fieldsByIndex[ref['$changes'].parentIndex]];
2274
+ if (typeof (Object.values(type)[0]) === "function") {
2275
+ Array.from(ref.values())
2276
+ .forEach(function (child) { return _this.removeRef(child['$changes'].refId); });
2277
+ }
2278
+ }
2279
+ _this.refs.delete(refId);
2280
+ delete _this.refCounts[refId];
2281
+ });
2282
+ // clear deleted refs.
2283
+ this.deletedRefs.clear();
2284
+ };
2285
+ return ReferenceTracker;
2286
+ }());
2287
+
2204
2288
  var EncodeSchemaError = /** @class */ (function (_super) {
2205
2289
  __extends(EncodeSchemaError, _super);
2206
2290
  function EncodeSchemaError() {
@@ -2272,12 +2356,17 @@
2272
2356
  // fix enumerability of fields for end-user
2273
2357
  Object.defineProperties(this, {
2274
2358
  $changes: {
2275
- value: new ChangeTree(this, undefined, new Root()),
2359
+ value: new ChangeTree(this, undefined, new ReferenceTracker()),
2276
2360
  enumerable: false,
2277
2361
  writable: true
2278
2362
  },
2279
- $listeners: {
2280
- value: {},
2363
+ // $listeners: {
2364
+ // value: undefined,
2365
+ // enumerable: false,
2366
+ // writable: true
2367
+ // },
2368
+ $callbacks: {
2369
+ value: undefined,
2281
2370
  enumerable: false,
2282
2371
  writable: true
2283
2372
  },
@@ -2300,6 +2389,12 @@
2300
2389
  return (type['_definition'] &&
2301
2390
  type['_definition'].schema !== undefined);
2302
2391
  };
2392
+ Schema.prototype.onChange = function (callback) {
2393
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.REPLACE, callback);
2394
+ };
2395
+ Schema.prototype.onRemove = function (callback) {
2396
+ return addCallback((this.$callbacks || (this.$callbacks = [])), exports.OPERATION.DELETE, callback);
2397
+ };
2303
2398
  Schema.prototype.assign = function (props) {
2304
2399
  Object.assign(this, props);
2305
2400
  return this;
@@ -2309,27 +2404,35 @@
2309
2404
  enumerable: false,
2310
2405
  configurable: true
2311
2406
  });
2407
+ /**
2408
+ * (Server-side): Flag a property to be encoded for the next patch.
2409
+ * @param instance Schema instance
2410
+ * @param property string representing the property name, or number representing the index of the property.
2411
+ * @param operation OPERATION to perform (detected automatically)
2412
+ */
2413
+ Schema.prototype.setDirty = function (property, operation) {
2414
+ this.$changes.change(property, operation);
2415
+ };
2312
2416
  Schema.prototype.listen = function (attr, callback) {
2313
2417
  var _this = this;
2314
- if (!this.$listeners[attr]) {
2315
- this.$listeners[attr] = new EventEmitter();
2418
+ if (!this.$callbacks) {
2419
+ this.$callbacks = {};
2420
+ }
2421
+ if (!this.$callbacks[attr]) {
2422
+ this.$callbacks[attr] = [];
2316
2423
  }
2317
- this.$listeners[attr].register(callback);
2424
+ this.$callbacks[attr].push(callback);
2318
2425
  // return un-register callback.
2319
- return function () {
2320
- return _this.$listeners[attr].remove(callback);
2321
- };
2426
+ return function () { return spliceOne(_this.$callbacks[attr], _this.$callbacks[attr].indexOf(callback)); };
2322
2427
  };
2323
- Schema.prototype.decode = function (bytes, it, ref, allChanges) {
2428
+ Schema.prototype.decode = function (bytes, it, ref) {
2324
2429
  if (it === void 0) { it = { offset: 0 }; }
2325
2430
  if (ref === void 0) { ref = this; }
2326
- if (allChanges === void 0) { allChanges = new Map(); }
2431
+ var allChanges = [];
2327
2432
  var $root = this.$changes.root;
2328
2433
  var totalBytes = bytes.length;
2329
2434
  var refId = 0;
2330
- var changes = [];
2331
2435
  $root.refs.set(refId, this);
2332
- allChanges.set(refId, changes);
2333
2436
  while (it.offset < totalBytes) {
2334
2437
  var byte = bytes[it.offset++];
2335
2438
  if (byte == SWITCH_TO_STRUCTURE) {
@@ -2342,9 +2445,6 @@
2342
2445
  throw new Error("\"refId\" not found: " + refId);
2343
2446
  }
2344
2447
  ref = nextRef;
2345
- // create empty list of changes for this refId.
2346
- changes = [];
2347
- allChanges.set(refId, changes);
2348
2448
  continue;
2349
2449
  }
2350
2450
  var changeTree = ref['$changes'];
@@ -2358,7 +2458,7 @@
2358
2458
  // The `.clear()` method is calling `$root.removeRef(refId)` for
2359
2459
  // each item inside this collection
2360
2460
  //
2361
- ref.clear(true);
2461
+ ref.clear(allChanges);
2362
2462
  continue;
2363
2463
  }
2364
2464
  var fieldIndex = (isSchema)
@@ -2428,9 +2528,8 @@
2428
2528
  value = this.createTypeInstance(childType);
2429
2529
  value.$changes.refId = refId_1;
2430
2530
  if (previousValue) {
2431
- value.onChange = previousValue.onChange;
2432
- value.onRemove = previousValue.onRemove;
2433
- value.$listeners = previousValue.$listeners;
2531
+ value.$callbacks = previousValue.$callbacks;
2532
+ // value.$listeners = previousValue.$listeners;
2434
2533
  if (previousValue['$changes'].refId &&
2435
2534
  refId_1 !== previousValue['$changes'].refId) {
2436
2535
  $root.removeRef(previousValue['$changes'].refId);
@@ -2456,40 +2555,29 @@
2456
2555
  value.$changes.refId = refId_2;
2457
2556
  // preserve schema callbacks
2458
2557
  if (previousValue) {
2459
- value.onAdd = previousValue.onAdd;
2460
- value.onRemove = previousValue.onRemove;
2461
- value.onChange = previousValue.onChange;
2558
+ value['$callbacks'] = previousValue['$callbacks'];
2462
2559
  if (previousValue['$changes'].refId &&
2463
2560
  refId_2 !== previousValue['$changes'].refId) {
2464
2561
  $root.removeRef(previousValue['$changes'].refId);
2465
2562
  //
2466
2563
  // Trigger onRemove if structure has been replaced.
2467
2564
  //
2468
- var deletes = [];
2469
2565
  var entries = previousValue.entries();
2470
2566
  var iter = void 0;
2471
2567
  while ((iter = entries.next()) && !iter.done) {
2472
2568
  var _a = iter.value, key = _a[0], value_1 = _a[1];
2473
- deletes.push({
2569
+ allChanges.push({
2570
+ refId: refId_2,
2474
2571
  op: exports.OPERATION.DELETE,
2475
2572
  field: key,
2476
2573
  value: undefined,
2477
2574
  previousValue: value_1,
2478
2575
  });
2479
2576
  }
2480
- allChanges.set(previousValue['$changes'].refId, deletes);
2481
2577
  }
2482
2578
  }
2483
2579
  $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
2580
  }
2492
- var hasChange = (previousValue !== value);
2493
2581
  if (value !== null &&
2494
2582
  value !== undefined) {
2495
2583
  if (value['$changes']) {
@@ -2497,14 +2585,7 @@
2497
2585
  }
2498
2586
  if (ref instanceof Schema) {
2499
2587
  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;
2588
+ // ref[`_${fieldName}`] = value;
2508
2589
  }
2509
2590
  else if (ref instanceof MapSchema) {
2510
2591
  // const key = ref['$indexes'].get(field);
@@ -2518,19 +2599,20 @@
2518
2599
  // ref[key] = value;
2519
2600
  ref.setAt(fieldIndex, value);
2520
2601
  }
2521
- else if (ref instanceof CollectionSchema ||
2522
- ref instanceof SetSchema) {
2602
+ else if (ref instanceof CollectionSchema) {
2523
2603
  var index = ref.add(value);
2524
2604
  ref['setIndex'](fieldIndex, index);
2525
2605
  }
2606
+ else if (ref instanceof SetSchema) {
2607
+ var index = ref.add(value);
2608
+ if (index !== false) {
2609
+ ref['setIndex'](fieldIndex, index);
2610
+ }
2611
+ }
2526
2612
  }
2527
- if (hasChange
2528
- // &&
2529
- // (
2530
- // this.onChange || ref.$listeners[field]
2531
- // )
2532
- ) {
2533
- changes.push({
2613
+ if (previousValue !== value) {
2614
+ allChanges.push({
2615
+ refId: refId,
2534
2616
  op: operation,
2535
2617
  field: fieldName,
2536
2618
  dynamicIndex: dynamicIndex,
@@ -2684,6 +2766,7 @@
2684
2766
  return this.encode(true, [], useFilters);
2685
2767
  };
2686
2768
  Schema.prototype.applyFilters = function (client, encodeAll) {
2769
+ var _a, _b;
2687
2770
  if (encodeAll === void 0) { encodeAll = false; }
2688
2771
  var root = this;
2689
2772
  var refIdsDissallowed = new Set();
@@ -2802,7 +2885,7 @@
2802
2885
  //
2803
2886
  // use cached bytes directly if is from Schema type.
2804
2887
  //
2805
- filteredBytes = filteredBytes.concat(changeTree.caches[fieldIndex]);
2888
+ filteredBytes.push.apply(filteredBytes, (_a = changeTree.caches[fieldIndex]) !== null && _a !== void 0 ? _a : []);
2806
2889
  containerIndexes.add(fieldIndex);
2807
2890
  }
2808
2891
  else {
@@ -2810,7 +2893,7 @@
2810
2893
  //
2811
2894
  // use cached bytes if already has the field
2812
2895
  //
2813
- filteredBytes = filteredBytes.concat(changeTree.caches[fieldIndex]);
2896
+ filteredBytes.push.apply(filteredBytes, (_b = changeTree.caches[fieldIndex]) !== null && _b !== void 0 ? _b : []);
2814
2897
  }
2815
2898
  else {
2816
2899
  //
@@ -2878,20 +2961,6 @@
2878
2961
  }
2879
2962
  return cloned;
2880
2963
  };
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
2964
  Schema.prototype.toJSON = function () {
2896
2965
  var schema = this._definition.schema;
2897
2966
  var deprecated = this._definition.deprecated;
@@ -2934,111 +3003,81 @@
2934
3003
  instance.$changes.root = this.$changes.root;
2935
3004
  return instance;
2936
3005
  };
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);
3006
+ Schema.prototype._triggerChanges = function (changes) {
3007
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
3008
+ var uniqueRefIds = new Set();
3009
+ var $refs = this.$changes.root.refs;
3010
+ var _loop_2 = function (i) {
3011
+ var change = changes[i];
3012
+ var refId = change.refId;
3013
+ var ref = $refs.get(refId);
3014
+ var $callbacks = ref['$callbacks'];
3015
+ //
3016
+ // trigger onRemove on child structure.
3017
+ //
3018
+ if ((change.op & exports.OPERATION.DELETE) === exports.OPERATION.DELETE &&
3019
+ change.previousValue instanceof Schema) {
3020
+ (_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(); });
3021
+ }
3022
+ // no callbacks defined, skip this structure!
3023
+ if (!$callbacks) {
3024
+ return "continue";
3025
+ }
3026
+ if (ref instanceof Schema) {
3027
+ if (!uniqueRefIds.has(refId)) {
3028
+ try {
3029
+ // trigger onChange
3030
+ (_d = (_c = $callbacks) === null || _c === void 0 ? void 0 : _c[exports.OPERATION.REPLACE]) === null || _d === void 0 ? void 0 : _d.forEach(function (callback) {
3031
+ return callback(changes);
3032
+ });
3033
+ }
3034
+ catch (e) {
3035
+ Schema.onError(e);
2957
3036
  }
2958
3037
  }
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);
3038
+ try {
3039
+ (_e = $callbacks[change.op]) === null || _e === void 0 ? void 0 : _e.forEach(function (callback) {
3040
+ return callback(change.value, change.previousValue);
3041
+ });
3042
+ }
3043
+ catch (e) {
3044
+ Schema.onError(e);
2975
3045
  }
2976
3046
  }
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
- }
3047
+ else {
3048
+ // is a collection of items
3049
+ if (change.op === exports.OPERATION.ADD && change.previousValue === undefined) {
3050
+ // triger onAdd
3051
+ (_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); });
3052
+ }
3053
+ else if (change.op === exports.OPERATION.DELETE) {
3013
3054
  //
3014
- // trigger onRemove on child structure.
3055
+ // FIXME: `previousValue` should always be available.
3056
+ // ADD + DELETE operations are still encoding DELETE operation.
3015
3057
  //
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
- }
3058
+ if (change.previousValue !== undefined) {
3059
+ // triger onRemove
3060
+ (_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
3061
  }
3029
3062
  }
3030
- if (isSchema) {
3031
- if (ref.onChange) {
3032
- try {
3033
- ref.onChange(changes);
3034
- }
3035
- catch (e) {
3036
- Schema.onError(e);
3037
- }
3063
+ else if (change.op === exports.OPERATION.DELETE_AND_ADD) {
3064
+ // triger onRemove
3065
+ if (change.previousValue !== undefined) {
3066
+ (_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
3067
  }
3068
+ // triger onAdd
3069
+ (_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); });
3070
+ }
3071
+ // trigger onChange
3072
+ if (change.value !== change.previousValue) {
3073
+ (_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
3074
  }
3040
3075
  }
3041
- });
3076
+ uniqueRefIds.add(refId);
3077
+ };
3078
+ for (var i = 0; i < changes.length; i++) {
3079
+ _loop_2(i);
3080
+ }
3042
3081
  };
3043
3082
  Schema._definition = SchemaDefinition.create();
3044
3083
  return Schema;
@@ -3066,7 +3105,7 @@
3066
3105
  return dump;
3067
3106
  }
3068
3107
 
3069
- var reflectionContext = new Context();
3108
+ var reflectionContext = { context: new Context() };
3070
3109
  /**
3071
3110
  * Reflection
3072
3111
  */
@@ -3187,14 +3226,14 @@
3187
3226
  refType = typeInfo[1];
3188
3227
  }
3189
3228
  if (fieldType === "ref") {
3190
- type(refType, context)(schemaType.prototype, field.name);
3229
+ type(refType, { context: context })(schemaType.prototype, field.name);
3191
3230
  }
3192
3231
  else {
3193
- type((_a = {}, _a[fieldType] = refType, _a), context)(schemaType.prototype, field.name);
3232
+ type((_a = {}, _a[fieldType] = refType, _a), { context: context })(schemaType.prototype, field.name);
3194
3233
  }
3195
3234
  }
3196
3235
  else {
3197
- type(field.type, context)(schemaType.prototype, field.name);
3236
+ type(field.type, { context: context })(schemaType.prototype, field.name);
3198
3237
  }
3199
3238
  });
3200
3239
  });
@@ -3223,8 +3262,8 @@
3223
3262
  return Reflection;
3224
3263
  }(Schema));
3225
3264
 
3226
- registerType("map", { constructor: MapSchema, getProxy: getMapProxy });
3227
- registerType("array", { constructor: ArraySchema, getProxy: getArrayProxy });
3265
+ registerType("map", { constructor: MapSchema });
3266
+ registerType("array", { constructor: ArraySchema });
3228
3267
  registerType("set", { constructor: SetSchema });
3229
3268
  registerType("collection", { constructor: CollectionSchema, });
3230
3269