@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
@@ -164,7 +164,6 @@ class Root {
164
164
  // pending changes to be encoded
165
165
  this.changes = new Map();
166
166
  this.filteredChanges = new Map();
167
- this.views = [];
168
167
  }
169
168
  getNextUniqueId() {
170
169
  return this.nextUniqueId++;
@@ -259,14 +258,12 @@ class ChangeTree {
259
258
  this.checkIsFiltered(parent, parentIndex);
260
259
  if (!this.isFiltered) {
261
260
  this.root.changes.set(this, this.changes);
261
+ this.root.allChanges.set(this, this.allChanges);
262
262
  }
263
263
  if (this.isFiltered || this.isPartiallyFiltered) {
264
264
  this.root.filteredChanges.set(this, this.filteredChanges);
265
265
  this.root.allFilteredChanges.set(this, this.filteredChanges);
266
266
  }
267
- else {
268
- this.root.allChanges.set(this, this.allChanges);
269
- }
270
267
  this.ensureRefId();
271
268
  this.forEachChild((changeTree, atIndex) => {
272
269
  changeTree.setParent(this.ref, root, atIndex);
@@ -358,7 +355,6 @@ class ChangeTree {
358
355
  }
359
356
  _shiftAllChangeIndexes(shiftIndex, startIndex = 0, allChangeSet) {
360
357
  Array.from(allChangeSet.entries()).forEach(([index, op]) => {
361
- // console.log('shiftAllChangeIndexes', index >= startIndex, { index, op, shiftIndex, startIndex })
362
358
  if (index >= startIndex) {
363
359
  allChangeSet.delete(index);
364
360
  allChangeSet.set(index + shiftIndex, op);
@@ -499,7 +495,7 @@ class ChangeTree {
499
495
  }
500
496
  checkIsFiltered(parent, parentIndex) {
501
497
  // Detect if current structure has "filters" declared
502
- this.isPartiallyFiltered = this.ref['constructor']?.[Symbol.metadata]?.[-2];
498
+ this.isPartiallyFiltered = (this.ref['constructor']?.[Symbol.metadata]?.[-2] !== undefined);
503
499
  // TODO: support "partially filtered", where the instance is visible, but only a field is not.
504
500
  // Detect if parent has "filters" declared
505
501
  while (parent && !this.isFiltered) {
@@ -560,6 +556,29 @@ try {
560
556
  textEncoder = new TextEncoder();
561
557
  }
562
558
  catch (e) { }
559
+ const hasBufferByteLength = (typeof Buffer !== 'undefined' && Buffer.byteLength);
560
+ const utf8Length = (hasBufferByteLength)
561
+ ? Buffer.byteLength // node
562
+ : function (str, _) {
563
+ var c = 0, length = 0;
564
+ for (var i = 0, l = str.length; i < l; i++) {
565
+ c = str.charCodeAt(i);
566
+ if (c < 0x80) {
567
+ length += 1;
568
+ }
569
+ else if (c < 0x800) {
570
+ length += 2;
571
+ }
572
+ else if (c < 0xd800 || c >= 0xe000) {
573
+ length += 3;
574
+ }
575
+ else {
576
+ i++;
577
+ length += 4;
578
+ }
579
+ }
580
+ return length;
581
+ };
563
582
  function utf8Write(view, str, it) {
564
583
  var c = 0;
565
584
  for (var i = 0, l = str.length; i < l; i++) {
@@ -654,8 +673,7 @@ function string$1(bytes, value, it) {
654
673
  if (!value) {
655
674
  value = "";
656
675
  }
657
- // let length = utf8Length(value);
658
- let length = Buffer.byteLength(value, "utf8");
676
+ let length = utf8Length(value, "utf8");
659
677
  let size = 0;
660
678
  // fixstr
661
679
  if (length < 0x20) {
@@ -766,6 +784,7 @@ function number$1(bytes, value, it) {
766
784
 
767
785
  var encode = /*#__PURE__*/Object.freeze({
768
786
  __proto__: null,
787
+ utf8Length: utf8Length,
769
788
  utf8Write: utf8Write,
770
789
  int8: int8$1,
771
790
  uint8: uint8$1,
@@ -989,9 +1008,9 @@ const encodeArray = function (encoder, bytes, changeTree, field, operation, it,
989
1008
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
990
1009
  * SOFTWARE
991
1010
  */
992
- function utf8Read(bytes, offset, length) {
1011
+ function utf8Read(bytes, it, length) {
993
1012
  var string = '', chr = 0;
994
- for (var i = offset, end = offset + length; i < end; i++) {
1013
+ for (var i = it.offset, end = it.offset + length; i < end; i++) {
995
1014
  var byte = bytes[i];
996
1015
  if ((byte & 0x80) === 0x00) {
997
1016
  string += String.fromCharCode(byte);
@@ -1026,6 +1045,7 @@ function utf8Read(bytes, offset, length) {
1026
1045
  // (do not throw error to avoid server/client from crashing due to hack attemps)
1027
1046
  // throw new Error('Invalid byte ' + byte.toString(16));
1028
1047
  }
1048
+ it.offset += length;
1029
1049
  return string;
1030
1050
  }
1031
1051
  function int8(bytes, it) {
@@ -1093,9 +1113,7 @@ function string(bytes, it) {
1093
1113
  else if (prefix === 0xdb) {
1094
1114
  length = uint32(bytes, it);
1095
1115
  }
1096
- const value = utf8Read(bytes, it.offset, length);
1097
- it.offset += length;
1098
- return value;
1116
+ return utf8Read(bytes, it, length);
1099
1117
  }
1100
1118
  function stringCheck(bytes, it) {
1101
1119
  const prefix = bytes[it.offset];
@@ -1199,6 +1217,7 @@ function switchStructureCheck(bytes, it) {
1199
1217
 
1200
1218
  var decode = /*#__PURE__*/Object.freeze({
1201
1219
  __proto__: null,
1220
+ utf8Read: utf8Read,
1202
1221
  int8: int8,
1203
1222
  uint8: uint8,
1204
1223
  int16: int16,
@@ -1222,7 +1241,7 @@ var decode = /*#__PURE__*/Object.freeze({
1222
1241
 
1223
1242
  const DEFINITION_MISMATCH = -1;
1224
1243
  function decodeValue(decoder, operation, ref, index, type, bytes, it, allChanges) {
1225
- const $root = decoder.$root;
1244
+ const $root = decoder.root;
1226
1245
  const previousValue = ref[$getByIndex](index);
1227
1246
  let value;
1228
1247
  if ((operation & OPERATION.DELETE) === OPERATION.DELETE) {
@@ -1422,7 +1441,7 @@ const decodeArray = function (decoder, bytes, it, ref, allChanges) {
1422
1441
  else if (operation === OPERATION.DELETE_BY_REFID) {
1423
1442
  // TODO: refactor here, try to follow same flow as below
1424
1443
  const refId = number(bytes, it);
1425
- const previousValue = decoder.$root.refs.get(refId);
1444
+ const previousValue = decoder.root.refs.get(refId);
1426
1445
  const index = ref.findIndex((value) => value === previousValue);
1427
1446
  ref[$deleteByIndex](index);
1428
1447
  allChanges.push({
@@ -3358,13 +3377,13 @@ class Encoder {
3358
3377
  // });
3359
3378
  }
3360
3379
  setRoot(state) {
3361
- this.$root = new Root();
3380
+ this.root = new Root();
3362
3381
  this.state = state;
3363
- state[$changes].setRoot(this.$root);
3382
+ state[$changes].setRoot(this.root);
3364
3383
  }
3365
- encode(it = { offset: 0 }, view, bytes = this.sharedBuffer, changeTrees = this.$root.changes) {
3384
+ encode(it = { offset: 0 }, view, buffer = this.sharedBuffer, changeTrees = this.root.changes) {
3366
3385
  const initialOffset = it.offset; // cache current offset in case we need to resize the buffer
3367
- const isEncodeAll = this.$root.allChanges === changeTrees;
3386
+ const isEncodeAll = this.root.allChanges === changeTrees;
3368
3387
  const hasView = (view !== undefined);
3369
3388
  const rootChangeTree = this.state[$changes];
3370
3389
  const changeTreesIterator = changeTrees.entries();
@@ -3384,8 +3403,8 @@ class Encoder {
3384
3403
  }
3385
3404
  // skip root `refId` if it's the first change tree
3386
3405
  if (it.offset !== initialOffset || changeTree !== rootChangeTree) {
3387
- bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;
3388
- number$1(bytes, changeTree.refId, it);
3406
+ buffer[it.offset++] = SWITCH_TO_STRUCTURE & 255;
3407
+ number$1(buffer, changeTree.refId, it);
3389
3408
  }
3390
3409
  const changesIterator = changes.entries();
3391
3410
  for (const [fieldIndex, operation] of changesIterator) {
@@ -3407,17 +3426,21 @@ class Encoder {
3407
3426
  // fieldIndex,
3408
3427
  // operation: OPERATION[operation],
3409
3428
  // });
3410
- encoder(this, bytes, changeTree, fieldIndex, operation, it, isEncodeAll, hasView);
3429
+ encoder(this, buffer, changeTree, fieldIndex, operation, it, isEncodeAll, hasView);
3411
3430
  }
3412
3431
  }
3413
- if (it.offset > bytes.byteLength) {
3414
- const newSize = getNextPowerOf2(this.sharedBuffer.byteLength * 2);
3415
- console.warn("@colyseus/schema encode buffer overflow. Current buffer size: " + bytes.byteLength + ", encoding offset: " + it.offset + ", new size: " + newSize);
3432
+ if (it.offset > buffer.byteLength) {
3433
+ const newSize = getNextPowerOf2(buffer.byteLength * 2);
3434
+ console.warn("@colyseus/schema encode buffer overflow. Current buffer size: " + buffer.byteLength + ", encoding offset: " + it.offset + ", new size: " + newSize);
3416
3435
  //
3417
3436
  // resize buffer and re-encode (TODO: can we avoid re-encoding here?)
3418
3437
  //
3419
- this.sharedBuffer = Buffer.allocUnsafeSlow(newSize);
3420
- return this.encode({ offset: initialOffset }, view);
3438
+ buffer = Buffer.allocUnsafeSlow(newSize);
3439
+ // assign resized buffer to local sharedBuffer
3440
+ if (buffer === this.sharedBuffer) {
3441
+ this.sharedBuffer = buffer;
3442
+ }
3443
+ return this.encode({ offset: initialOffset }, view, buffer);
3421
3444
  }
3422
3445
  else {
3423
3446
  //
@@ -3429,42 +3452,41 @@ class Encoder {
3429
3452
  //
3430
3453
  this.onEndEncode(changeTrees);
3431
3454
  }
3432
- // return bytes;
3433
- return bytes.slice(0, it.offset);
3455
+ return buffer.subarray(0, it.offset);
3434
3456
  }
3435
3457
  }
3436
- encodeAll(it = { offset: 0 }) {
3437
- // console.log(`encodeAll(), this.$root.allChanges (${this.$root.allChanges.size})`);
3438
- // Array.from(this.$root.allChanges.entries()).map((item) => {
3439
- // console.log("->", item[0].refId, item[0].ref.toJSON());
3458
+ encodeAll(it = { offset: 0 }, buffer = this.sharedBuffer) {
3459
+ // console.log(`encodeAll(), this.root.allChanges (${this.root.allChanges.size})`);
3460
+ // Array.from(this.root.allChanges.entries()).map((item) => {
3461
+ // console.log("->", { ref: item[0].ref.constructor.name, refId: item[0].refId, changes: item[1].size });
3440
3462
  // });
3441
- return this.encode(it, undefined, this.sharedBuffer, this.$root.allChanges);
3463
+ return this.encode(it, undefined, buffer, this.root.allChanges);
3442
3464
  }
3443
3465
  encodeAllView(view, sharedOffset, it, bytes = this.sharedBuffer) {
3444
3466
  const viewOffset = it.offset;
3445
- // console.log(`encodeAllView(), this.$root.allFilteredChanges (${this.$root.allFilteredChanges.size})`);
3467
+ // console.log(`encodeAllView(), this.root.allFilteredChanges (${this.root.allFilteredChanges.size})`);
3446
3468
  // this.debugAllFilteredChanges();
3447
3469
  // try to encode "filtered" changes
3448
- this.encode(it, view, bytes, this.$root.allFilteredChanges);
3470
+ this.encode(it, view, bytes, this.root.allFilteredChanges);
3449
3471
  return Buffer.concat([
3450
- bytes.slice(0, sharedOffset),
3451
- bytes.slice(viewOffset, it.offset)
3472
+ bytes.subarray(0, sharedOffset),
3473
+ bytes.subarray(viewOffset, it.offset)
3452
3474
  ]);
3453
3475
  }
3454
- // debugAllFilteredChanges() {
3455
- // Array.from(this.$root.allFilteredChanges.entries()).map((item) => {
3456
- // console.log("->", { refId: item[0].refId }, item[0].ref.toJSON());
3457
- // if (Array.isArray(item[0].ref.toJSON())) {
3458
- // item[1].forEach((op, key) => {
3459
- // console.log(" ->", { key, op: OPERATION[op] });
3460
- // })
3461
- // }
3462
- // });
3463
- // }
3476
+ debugAllFilteredChanges() {
3477
+ Array.from(this.root.allFilteredChanges.entries()).map((item) => {
3478
+ console.log("->", { refId: item[0].refId, changes: item[1].size }, item[0].ref.toJSON());
3479
+ if (Array.isArray(item[0].ref.toJSON())) {
3480
+ item[1].forEach((op, key) => {
3481
+ console.log(" ->", { key, op: OPERATION[op] });
3482
+ });
3483
+ }
3484
+ });
3485
+ }
3464
3486
  encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
3465
3487
  const viewOffset = it.offset;
3466
3488
  // try to encode "filtered" changes
3467
- this.encode(it, view, bytes, this.$root.filteredChanges);
3489
+ this.encode(it, view, bytes, this.root.filteredChanges);
3468
3490
  // encode visibility changes (add/remove for this view)
3469
3491
  const viewChangesIterator = view.changes.entries();
3470
3492
  for (const [changeTree, changes] of viewChangesIterator) {
@@ -3492,11 +3514,11 @@ class Encoder {
3492
3514
  // clear "view" changes after encoding
3493
3515
  view.changes.clear();
3494
3516
  return Buffer.concat([
3495
- bytes.slice(0, sharedOffset),
3496
- bytes.slice(viewOffset, it.offset)
3517
+ bytes.subarray(0, sharedOffset),
3518
+ bytes.subarray(viewOffset, it.offset)
3497
3519
  ]);
3498
3520
  }
3499
- onEndEncode(changeTrees = this.$root.changes) {
3521
+ onEndEncode(changeTrees = this.root.changes) {
3500
3522
  const changeTreesIterator = changeTrees.entries();
3501
3523
  for (const [changeTree, _] of changeTreesIterator) {
3502
3524
  changeTree.endEncode();
@@ -3504,14 +3526,14 @@ class Encoder {
3504
3526
  }
3505
3527
  discardChanges() {
3506
3528
  // discard shared changes
3507
- if (this.$root.changes.size > 0) {
3508
- this.onEndEncode(this.$root.changes);
3509
- this.$root.changes.clear();
3529
+ if (this.root.changes.size > 0) {
3530
+ this.onEndEncode(this.root.changes);
3531
+ this.root.changes.clear();
3510
3532
  }
3511
3533
  // discard filtered changes
3512
- if (this.$root.filteredChanges.size > 0) {
3513
- this.onEndEncode(this.$root.filteredChanges);
3514
- this.$root.filteredChanges.clear();
3534
+ if (this.root.filteredChanges.size > 0) {
3535
+ this.onEndEncode(this.root.filteredChanges);
3536
+ this.root.filteredChanges.clear();
3515
3537
  }
3516
3538
  }
3517
3539
  tryEncodeTypeId(bytes, baseType, targetType, it) {
@@ -3672,12 +3694,12 @@ class Decoder {
3672
3694
  }
3673
3695
  setRoot(root) {
3674
3696
  this.state = root;
3675
- this.$root = new ReferenceTracker();
3676
- this.$root.addRef(0, root);
3697
+ this.root = new ReferenceTracker();
3698
+ this.root.addRef(0, root);
3677
3699
  }
3678
3700
  decode(bytes, it = { offset: 0 }, ref = this.state) {
3679
3701
  const allChanges = [];
3680
- const $root = this.$root;
3702
+ const $root = this.root;
3681
3703
  const totalBytes = bytes.byteLength;
3682
3704
  let decoder = ref['constructor'][$decoder];
3683
3705
  this.currentRefId = 0;
@@ -3758,7 +3780,7 @@ class Decoder {
3758
3780
  previousValue: value
3759
3781
  });
3760
3782
  if (needRemoveRef) {
3761
- this.$root.removeRef(this.$root.refIds.get(value));
3783
+ this.root.removeRef(this.root.refIds.get(value));
3762
3784
  }
3763
3785
  });
3764
3786
  }
@@ -3798,7 +3820,7 @@ class Reflection extends Schema {
3798
3820
  super(...arguments);
3799
3821
  this.types = new ArraySchema();
3800
3822
  }
3801
- static encode(instance, context) {
3823
+ static encode(instance, context, it = { offset: 0 }) {
3802
3824
  if (!context) {
3803
3825
  context = new TypeContext(instance.constructor);
3804
3826
  }
@@ -3855,7 +3877,6 @@ class Reflection extends Schema {
3855
3877
  }
3856
3878
  buildType(type, klass[Symbol.metadata]);
3857
3879
  }
3858
- const it = { offset: 0 };
3859
3880
  const buf = encoder.encodeAll(it);
3860
3881
  return Buffer.from(buf, 0, it.offset);
3861
3882
  }