@colyseus/schema 3.0.0-alpha.1 → 3.0.0-alpha.10

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 (40) hide show
  1. package/build/cjs/index.js +85 -64
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +85 -64
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +85 -64
  6. package/lib/Reflection.d.ts +1 -1
  7. package/lib/Reflection.js +1 -2
  8. package/lib/Reflection.js.map +1 -1
  9. package/lib/decoder/DecodeOperation.js +2 -2
  10. package/lib/decoder/DecodeOperation.js.map +1 -1
  11. package/lib/decoder/Decoder.d.ts +1 -1
  12. package/lib/decoder/Decoder.js +4 -4
  13. package/lib/decoder/Decoder.js.map +1 -1
  14. package/lib/decoder/strategy/StateCallbacks.js +1 -1
  15. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  16. package/lib/encoder/ChangeTree.d.ts +0 -2
  17. package/lib/encoder/ChangeTree.js +2 -6
  18. package/lib/encoder/ChangeTree.js.map +1 -1
  19. package/lib/encoder/Encoder.d.ts +5 -4
  20. package/lib/encoder/Encoder.js +46 -43
  21. package/lib/encoder/Encoder.js.map +1 -1
  22. package/lib/encoder/StateView.d.ts +2 -0
  23. package/lib/encoder/StateView.js +4 -1
  24. package/lib/encoder/StateView.js.map +1 -1
  25. package/lib/encoding/decode.d.ts +21 -19
  26. package/lib/encoding/decode.js +6 -6
  27. package/lib/encoding/decode.js.map +1 -1
  28. package/lib/encoding/encode.d.ts +3 -2
  29. package/lib/encoding/encode.js +24 -22
  30. package/lib/encoding/encode.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/Reflection.ts +1 -2
  33. package/src/decoder/DecodeOperation.ts +3 -3
  34. package/src/decoder/Decoder.ts +5 -5
  35. package/src/decoder/strategy/StateCallbacks.ts +1 -1
  36. package/src/encoder/ChangeTree.ts +2 -6
  37. package/src/encoder/Encoder.ts +51 -47
  38. package/src/encoder/StateView.ts +4 -0
  39. package/src/encoding/decode.ts +24 -25
  40. package/src/encoding/encode.ts +26 -23
@@ -168,7 +168,6 @@ class Root {
168
168
  // pending changes to be encoded
169
169
  this.changes = new Map();
170
170
  this.filteredChanges = new Map();
171
- this.views = [];
172
171
  }
173
172
  getNextUniqueId() {
174
173
  return this.nextUniqueId++;
@@ -263,14 +262,12 @@ class ChangeTree {
263
262
  this.checkIsFiltered(parent, parentIndex);
264
263
  if (!this.isFiltered) {
265
264
  this.root.changes.set(this, this.changes);
265
+ this.root.allChanges.set(this, this.allChanges);
266
266
  }
267
267
  if (this.isFiltered || this.isPartiallyFiltered) {
268
268
  this.root.filteredChanges.set(this, this.filteredChanges);
269
269
  this.root.allFilteredChanges.set(this, this.filteredChanges);
270
270
  }
271
- else {
272
- this.root.allChanges.set(this, this.allChanges);
273
- }
274
271
  this.ensureRefId();
275
272
  this.forEachChild((changeTree, atIndex) => {
276
273
  changeTree.setParent(this.ref, root, atIndex);
@@ -362,7 +359,6 @@ class ChangeTree {
362
359
  }
363
360
  _shiftAllChangeIndexes(shiftIndex, startIndex = 0, allChangeSet) {
364
361
  Array.from(allChangeSet.entries()).forEach(([index, op]) => {
365
- // console.log('shiftAllChangeIndexes', index >= startIndex, { index, op, shiftIndex, startIndex })
366
362
  if (index >= startIndex) {
367
363
  allChangeSet.delete(index);
368
364
  allChangeSet.set(index + shiftIndex, op);
@@ -503,7 +499,7 @@ class ChangeTree {
503
499
  }
504
500
  checkIsFiltered(parent, parentIndex) {
505
501
  // Detect if current structure has "filters" declared
506
- this.isPartiallyFiltered = this.ref['constructor']?.[Symbol.metadata]?.[-2];
502
+ this.isPartiallyFiltered = (this.ref['constructor']?.[Symbol.metadata]?.[-2] !== undefined);
507
503
  // TODO: support "partially filtered", where the instance is visible, but only a field is not.
508
504
  // Detect if parent has "filters" declared
509
505
  while (parent && !this.isFiltered) {
@@ -564,6 +560,29 @@ try {
564
560
  textEncoder = new TextEncoder();
565
561
  }
566
562
  catch (e) { }
563
+ const hasBufferByteLength = (typeof Buffer !== 'undefined' && Buffer.byteLength);
564
+ const utf8Length = (hasBufferByteLength)
565
+ ? Buffer.byteLength // node
566
+ : function (str, _) {
567
+ var c = 0, length = 0;
568
+ for (var i = 0, l = str.length; i < l; i++) {
569
+ c = str.charCodeAt(i);
570
+ if (c < 0x80) {
571
+ length += 1;
572
+ }
573
+ else if (c < 0x800) {
574
+ length += 2;
575
+ }
576
+ else if (c < 0xd800 || c >= 0xe000) {
577
+ length += 3;
578
+ }
579
+ else {
580
+ i++;
581
+ length += 4;
582
+ }
583
+ }
584
+ return length;
585
+ };
567
586
  function utf8Write(view, str, it) {
568
587
  var c = 0;
569
588
  for (var i = 0, l = str.length; i < l; i++) {
@@ -658,8 +677,7 @@ function string$1(bytes, value, it) {
658
677
  if (!value) {
659
678
  value = "";
660
679
  }
661
- // let length = utf8Length(value);
662
- let length = Buffer.byteLength(value, "utf8");
680
+ let length = utf8Length(value, "utf8");
663
681
  let size = 0;
664
682
  // fixstr
665
683
  if (length < 0x20) {
@@ -770,6 +788,7 @@ function number$1(bytes, value, it) {
770
788
 
771
789
  var encode = /*#__PURE__*/Object.freeze({
772
790
  __proto__: null,
791
+ utf8Length: utf8Length,
773
792
  utf8Write: utf8Write,
774
793
  int8: int8$1,
775
794
  uint8: uint8$1,
@@ -993,9 +1012,9 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
993
1012
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
994
1013
  * SOFTWARE
995
1014
  */
996
- function utf8Read(bytes, offset, length) {
1015
+ function utf8Read(bytes, it, length) {
997
1016
  var string = '', chr = 0;
998
- for (var i = offset, end = offset + length; i < end; i++) {
1017
+ for (var i = it.offset, end = it.offset + length; i < end; i++) {
999
1018
  var byte = bytes[i];
1000
1019
  if ((byte & 0x80) === 0x00) {
1001
1020
  string += String.fromCharCode(byte);
@@ -1030,6 +1049,7 @@ function utf8Read(bytes, offset, length) {
1030
1049
  // (do not throw error to avoid server/client from crashing due to hack attemps)
1031
1050
  // throw new Error('Invalid byte ' + byte.toString(16));
1032
1051
  }
1052
+ it.offset += length;
1033
1053
  return string;
1034
1054
  }
1035
1055
  function int8(bytes, it) {
@@ -1097,9 +1117,7 @@ function string(bytes, it) {
1097
1117
  else if (prefix === 0xdb) {
1098
1118
  length = uint32(bytes, it);
1099
1119
  }
1100
- const value = utf8Read(bytes, it.offset, length);
1101
- it.offset += length;
1102
- return value;
1120
+ return utf8Read(bytes, it, length);
1103
1121
  }
1104
1122
  function stringCheck(bytes, it) {
1105
1123
  const prefix = bytes[it.offset];
@@ -1203,6 +1221,7 @@ function switchStructureCheck(bytes, it) {
1203
1221
 
1204
1222
  var decode = /*#__PURE__*/Object.freeze({
1205
1223
  __proto__: null,
1224
+ utf8Read: utf8Read,
1206
1225
  int8: int8,
1207
1226
  uint8: uint8,
1208
1227
  int16: int16,
@@ -1226,7 +1245,7 @@ var decode = /*#__PURE__*/Object.freeze({
1226
1245
 
1227
1246
  const DEFINITION_MISMATCH = -1;
1228
1247
  function decodeValue(decoder, operation, ref, index, type, bytes, it, allChanges) {
1229
- const $root = decoder.$root;
1248
+ const $root = decoder.root;
1230
1249
  const previousValue = ref[$getByIndex](index);
1231
1250
  let value;
1232
1251
  if ((operation & exports.OPERATION.DELETE) === exports.OPERATION.DELETE) {
@@ -1426,7 +1445,7 @@ const decodeArray = function (decoder, bytes, it, ref, allChanges) {
1426
1445
  else if (operation === exports.OPERATION.DELETE_BY_REFID) {
1427
1446
  // TODO: refactor here, try to follow same flow as below
1428
1447
  const refId = number(bytes, it);
1429
- const previousValue = decoder.$root.refs.get(refId);
1448
+ const previousValue = decoder.root.refs.get(refId);
1430
1449
  const index = ref.findIndex((value) => value === previousValue);
1431
1450
  ref[$deleteByIndex](index);
1432
1451
  allChanges.push({
@@ -3362,13 +3381,13 @@ class Encoder {
3362
3381
  // });
3363
3382
  }
3364
3383
  setRoot(state) {
3365
- this.$root = new Root();
3384
+ this.root = new Root();
3366
3385
  this.state = state;
3367
- state[$changes].setRoot(this.$root);
3386
+ state[$changes].setRoot(this.root);
3368
3387
  }
3369
- encode(it = { offset: 0 }, view, bytes = this.sharedBuffer, changeTrees = this.$root.changes) {
3388
+ encode(it = { offset: 0 }, view, buffer = this.sharedBuffer, changeTrees = this.root.changes) {
3370
3389
  const initialOffset = it.offset; // cache current offset in case we need to resize the buffer
3371
- const isEncodeAll = this.$root.allChanges === changeTrees;
3390
+ const isEncodeAll = this.root.allChanges === changeTrees;
3372
3391
  const hasView = (view !== undefined);
3373
3392
  const rootChangeTree = this.state[$changes];
3374
3393
  const changeTreesIterator = changeTrees.entries();
@@ -3388,8 +3407,8 @@ class Encoder {
3388
3407
  }
3389
3408
  // skip root `refId` if it's the first change tree
3390
3409
  if (it.offset !== initialOffset || changeTree !== rootChangeTree) {
3391
- bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;
3392
- number$1(bytes, changeTree.refId, it);
3410
+ buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;
3411
+ number$1(buffer, changeTree.refId, it);
3393
3412
  }
3394
3413
  const changesIterator = changes.entries();
3395
3414
  for (const [fieldIndex, operation] of changesIterator) {
@@ -3411,17 +3430,21 @@ class Encoder {
3411
3430
  // fieldIndex,
3412
3431
  // operation: OPERATION[operation],
3413
3432
  // });
3414
- encoder(this, bytes, changeTree, fieldIndex, operation, it, isEncodeAll, hasView);
3433
+ encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView);
3415
3434
  }
3416
3435
  }
3417
- if (it.offset > bytes.byteLength) {
3418
- const newSize = getNextPowerOf2(this.sharedBuffer.byteLength * 2);
3419
- console.warn("@colyseus/schema encode buffer overflow. Current buffer size: " + bytes.byteLength + ", encoding offset: " + it.offset + ", new size: " + newSize);
3436
+ if (it.offset > buffer.byteLength) {
3437
+ const newSize = getNextPowerOf2(buffer.byteLength * 2);
3438
+ console.warn("@colyseus/schema encode buffer overflow. Current buffer size: " + buffer.byteLength + ", encoding offset: " + it.offset + ", new size: " + newSize);
3420
3439
  //
3421
3440
  // resize buffer and re-encode (TODO: can we avoid re-encoding here?)
3422
3441
  //
3423
- this.sharedBuffer = Buffer.allocUnsafeSlow(newSize);
3424
- return this.encode({ offset: initialOffset }, view);
3442
+ buffer = Buffer.allocUnsafeSlow(newSize);
3443
+ // assign resized buffer to local sharedBuffer
3444
+ if (buffer === this.sharedBuffer) {
3445
+ this.sharedBuffer = buffer;
3446
+ }
3447
+ return this.encode({ offset: initialOffset }, view, buffer);
3425
3448
  }
3426
3449
  else {
3427
3450
  //
@@ -3433,42 +3456,41 @@ class Encoder {
3433
3456
  //
3434
3457
  this.onEndEncode(changeTrees);
3435
3458
  }
3436
- // return bytes;
3437
- return bytes.slice(0, it.offset);
3459
+ return buffer.subarray(0, it.offset);
3438
3460
  }
3439
3461
  }
3440
- encodeAll(it = { offset: 0 }) {
3441
- // console.log(`encodeAll(), this.$root.allChanges (${this.$root.allChanges.size})`);
3442
- // Array.from(this.$root.allChanges.entries()).map((item) => {
3443
- // console.log("->", item[0].refId, item[0].ref.toJSON());
3462
+ encodeAll(it = { offset: 0 }, buffer = this.sharedBuffer) {
3463
+ // console.log(`encodeAll(), this.root.allChanges (${this.root.allChanges.size})`);
3464
+ // Array.from(this.root.allChanges.entries()).map((item) => {
3465
+ // console.log("->", { ref: item[0].ref.constructor.name, refId: item[0].refId, changes: item[1].size });
3444
3466
  // });
3445
- return this.encode(it, undefined, this.sharedBuffer, this.$root.allChanges);
3467
+ return this.encode(it, undefined, buffer, this.root.allChanges);
3446
3468
  }
3447
3469
  encodeAllView(view, sharedOffset, it, bytes = this.sharedBuffer) {
3448
3470
  const viewOffset = it.offset;
3449
- // console.log(`encodeAllView(), this.$root.allFilteredChanges (${this.$root.allFilteredChanges.size})`);
3471
+ // console.log(`encodeAllView(), this.root.allFilteredChanges (${this.root.allFilteredChanges.size})`);
3450
3472
  // this.debugAllFilteredChanges();
3451
3473
  // try to encode "filtered" changes
3452
- this.encode(it, view, bytes, this.$root.allFilteredChanges);
3474
+ this.encode(it, view, bytes, this.root.allFilteredChanges);
3453
3475
  return Buffer.concat([
3454
- bytes.slice(0, sharedOffset),
3455
- bytes.slice(viewOffset, it.offset)
3476
+ bytes.subarray(0, sharedOffset),
3477
+ bytes.subarray(viewOffset, it.offset)
3456
3478
  ]);
3457
3479
  }
3458
- // debugAllFilteredChanges() {
3459
- // Array.from(this.$root.allFilteredChanges.entries()).map((item) => {
3460
- // console.log("->", { refId: item[0].refId }, item[0].ref.toJSON());
3461
- // if (Array.isArray(item[0].ref.toJSON())) {
3462
- // item[1].forEach((op, key) => {
3463
- // console.log(" ->", { key, op: OPERATION[op] });
3464
- // })
3465
- // }
3466
- // });
3467
- // }
3480
+ debugAllFilteredChanges() {
3481
+ Array.from(this.root.allFilteredChanges.entries()).map((item) => {
3482
+ console.log("->", { refId: item[0].refId, changes: item[1].size }, item[0].ref.toJSON());
3483
+ if (Array.isArray(item[0].ref.toJSON())) {
3484
+ item[1].forEach((op, key) => {
3485
+ console.log(" ->", { key, op: exports.OPERATION[op] });
3486
+ });
3487
+ }
3488
+ });
3489
+ }
3468
3490
  encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
3469
3491
  const viewOffset = it.offset;
3470
3492
  // try to encode "filtered" changes
3471
- this.encode(it, view, bytes, this.$root.filteredChanges);
3493
+ this.encode(it, view, bytes, this.root.filteredChanges);
3472
3494
  // encode visibility changes (add/remove for this view)
3473
3495
  const viewChangesIterator = view.changes.entries();
3474
3496
  for (const [changeTree, changes] of viewChangesIterator) {
@@ -3496,11 +3518,11 @@ class Encoder {
3496
3518
  // clear "view" changes after encoding
3497
3519
  view.changes.clear();
3498
3520
  return Buffer.concat([
3499
- bytes.slice(0, sharedOffset),
3500
- bytes.slice(viewOffset, it.offset)
3521
+ bytes.subarray(0, sharedOffset),
3522
+ bytes.subarray(viewOffset, it.offset)
3501
3523
  ]);
3502
3524
  }
3503
- onEndEncode(changeTrees = this.$root.changes) {
3525
+ onEndEncode(changeTrees = this.root.changes) {
3504
3526
  const changeTreesIterator = changeTrees.entries();
3505
3527
  for (const [changeTree, _] of changeTreesIterator) {
3506
3528
  changeTree.endEncode();
@@ -3508,14 +3530,14 @@ class Encoder {
3508
3530
  }
3509
3531
  discardChanges() {
3510
3532
  // discard shared changes
3511
- if (this.$root.changes.size > 0) {
3512
- this.onEndEncode(this.$root.changes);
3513
- this.$root.changes.clear();
3533
+ if (this.root.changes.size > 0) {
3534
+ this.onEndEncode(this.root.changes);
3535
+ this.root.changes.clear();
3514
3536
  }
3515
3537
  // discard filtered changes
3516
- if (this.$root.filteredChanges.size > 0) {
3517
- this.onEndEncode(this.$root.filteredChanges);
3518
- this.$root.filteredChanges.clear();
3538
+ if (this.root.filteredChanges.size > 0) {
3539
+ this.onEndEncode(this.root.filteredChanges);
3540
+ this.root.filteredChanges.clear();
3519
3541
  }
3520
3542
  }
3521
3543
  tryEncodeTypeId(bytes, baseType, targetType, it) {
@@ -3676,12 +3698,12 @@ class Decoder {
3676
3698
  }
3677
3699
  setRoot(root) {
3678
3700
  this.state = root;
3679
- this.$root = new ReferenceTracker();
3680
- this.$root.addRef(0, root);
3701
+ this.root = new ReferenceTracker();
3702
+ this.root.addRef(0, root);
3681
3703
  }
3682
3704
  decode(bytes, it = { offset: 0 }, ref = this.state) {
3683
3705
  const allChanges = [];
3684
- const $root = this.$root;
3706
+ const $root = this.root;
3685
3707
  const totalBytes = bytes.byteLength;
3686
3708
  let decoder = ref['constructor'][$decoder];
3687
3709
  this.currentRefId = 0;
@@ -3762,7 +3784,7 @@ class Decoder {
3762
3784
  previousValue: value
3763
3785
  });
3764
3786
  if (needRemoveRef) {
3765
- this.$root.removeRef(this.$root.refIds.get(value));
3787
+ this.root.removeRef(this.root.refIds.get(value));
3766
3788
  }
3767
3789
  });
3768
3790
  }
@@ -3802,7 +3824,7 @@ class Reflection extends Schema {
3802
3824
  super(...arguments);
3803
3825
  this.types = new ArraySchema();
3804
3826
  }
3805
- static encode(instance, context) {
3827
+ static encode(instance, context, it = { offset: 0 }) {
3806
3828
  if (!context) {
3807
3829
  context = new TypeContext(instance.constructor);
3808
3830
  }
@@ -3859,7 +3881,6 @@ class Reflection extends Schema {
3859
3881
  }
3860
3882
  buildType(type, klass[Symbol.metadata]);
3861
3883
  }
3862
- const it = { offset: 0 };
3863
3884
  const buf = encoder.encodeAll(it);
3864
3885
  return Buffer.from(buf, 0, it.offset);
3865
3886
  }