@colyseus/schema 3.0.21 → 3.0.23

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.
@@ -1831,7 +1831,7 @@ class ArraySchema {
1831
1831
  return (!view ||
1832
1832
  typeof (ref[$childType]) === "string" ||
1833
1833
  // view.items.has(ref[$getByIndex](index)[$changes])
1834
- view.items.has(ref['tmpItems'][index]?.[$changes]));
1834
+ view.visible.has(ref['tmpItems'][index]?.[$changes]));
1835
1835
  }
1836
1836
  static is(type) {
1837
1837
  return (
@@ -2487,7 +2487,7 @@ class MapSchema {
2487
2487
  static [(_a$3 = $encoder, _b$3 = $decoder, $filter)](ref, index, view) {
2488
2488
  return (!view ||
2489
2489
  typeof (ref[$childType]) === "string" ||
2490
- view.items.has((ref[$getByIndex](index) ?? ref.deletedItems[index])[$changes]));
2490
+ view.visible.has((ref[$getByIndex](index) ?? ref.deletedItems[index])[$changes]));
2491
2491
  }
2492
2492
  static is(type) {
2493
2493
  return type['map'] !== undefined;
@@ -3104,7 +3104,7 @@ class Schema {
3104
3104
  }
3105
3105
  else if (tag === DEFAULT_VIEW_TAG) {
3106
3106
  // view pass: default tag
3107
- return view.items.has(ref[$changes]);
3107
+ return view.visible.has(ref[$changes]);
3108
3108
  }
3109
3109
  else {
3110
3110
  // view pass: custom tag
@@ -3317,7 +3317,7 @@ class CollectionSchema {
3317
3317
  static [(_a$1 = $encoder, _b$1 = $decoder, $filter)](ref, index, view) {
3318
3318
  return (!view ||
3319
3319
  typeof (ref[$childType]) === "string" ||
3320
- view.items.has((ref[$getByIndex](index) ?? ref.deletedItems[index])[$changes]));
3320
+ view.visible.has((ref[$getByIndex](index) ?? ref.deletedItems[index])[$changes]));
3321
3321
  }
3322
3322
  static is(type) {
3323
3323
  return type['collection'] !== undefined;
@@ -3477,7 +3477,7 @@ class SetSchema {
3477
3477
  static [(_a = $encoder, _b = $decoder, $filter)](ref, index, view) {
3478
3478
  return (!view ||
3479
3479
  typeof (ref[$childType]) === "string" ||
3480
- view.items.has((ref[$getByIndex](index) ?? ref.deletedItems[index])[$changes]));
3480
+ view.visible.has((ref[$getByIndex](index) ?? ref.deletedItems[index])[$changes]));
3481
3481
  }
3482
3482
  static is(type) {
3483
3483
  return type['set'] !== undefined;
@@ -3797,7 +3797,7 @@ class Encoder {
3797
3797
  for (let i = 0, numChangeTrees = changeTrees.length; i < numChangeTrees; i++) {
3798
3798
  const changeTree = changeTrees[i];
3799
3799
  if (hasView) {
3800
- if (!view.items.has(changeTree)) {
3800
+ if (!view.visible.has(changeTree)) {
3801
3801
  view.invisible.add(changeTree);
3802
3802
  continue; // skip this change tree
3803
3803
  }
@@ -3923,13 +3923,14 @@ class Encoder {
3923
3923
  const changeTree = this.root.changeTrees[refId];
3924
3924
  if (changeTree === undefined) {
3925
3925
  // detached instance, remove from view and skip.
3926
+ // console.log("detached instance, remove from view and skip.", refId);
3926
3927
  view.changes.delete(refId);
3927
3928
  continue;
3928
3929
  }
3929
3930
  const keys = Object.keys(changes);
3930
3931
  if (keys.length === 0) {
3931
3932
  // FIXME: avoid having empty changes if no changes were made
3932
- // console.log("changes.size === 0, skip", changeTree.ref.constructor.name);
3933
+ // console.log("changes.size === 0, skip", refId, changeTree.ref.constructor.name);
3933
3934
  continue;
3934
3935
  }
3935
3936
  const ref = changeTree.ref;
@@ -4075,7 +4076,7 @@ class ReferenceTracker {
4075
4076
  //
4076
4077
  // Ensure child schema instances have their references removed as well.
4077
4078
  //
4078
- if (Metadata.isValidInstance(ref)) {
4079
+ if (ref.constructor[Symbol.metadata] !== undefined) {
4079
4080
  const metadata = ref.constructor[Symbol.metadata];
4080
4081
  for (const index in metadata) {
4081
4082
  const field = metadata[index].name;
@@ -4086,7 +4087,7 @@ class ReferenceTracker {
4086
4087
  }
4087
4088
  }
4088
4089
  else {
4089
- if (typeof (Object.values(ref[$childType])[0]) === "function") {
4090
+ if (typeof (ref[$childType]) === "function") {
4090
4091
  Array.from(ref.values())
4091
4092
  .forEach((child) => {
4092
4093
  const childRefId = this.refIds.get(child);
@@ -4712,11 +4713,12 @@ function getRawChangesCallback(decoder, callback) {
4712
4713
  }
4713
4714
 
4714
4715
  class StateView {
4715
- constructor() {
4716
+ constructor(iterable = false) {
4717
+ this.iterable = iterable;
4716
4718
  /**
4717
4719
  * List of ChangeTree's that are visible to this view
4718
4720
  */
4719
- this.items = new WeakSet();
4721
+ this.visible = new WeakSet();
4720
4722
  /**
4721
4723
  * List of ChangeTree's that are invisible to this view
4722
4724
  */
@@ -4726,17 +4728,24 @@ class StateView {
4726
4728
  * (This is used to force encoding a property, even if it was not changed)
4727
4729
  */
4728
4730
  this.changes = new Map();
4731
+ if (iterable) {
4732
+ this.items = [];
4733
+ }
4729
4734
  }
4730
4735
  // TODO: allow to set multiple tags at once
4731
4736
  add(obj, tag = DEFAULT_VIEW_TAG, checkIncludeParent = true) {
4732
- if (!obj[$changes]) {
4737
+ if (!obj?.[$changes]) {
4733
4738
  console.warn("StateView#add(), invalid object:", obj);
4734
4739
  return this;
4735
4740
  }
4736
4741
  // FIXME: ArraySchema/MapSchema do not have metadata
4737
4742
  const metadata = obj.constructor[Symbol.metadata];
4738
4743
  const changeTree = obj[$changes];
4739
- this.items.add(changeTree);
4744
+ this.visible.add(changeTree);
4745
+ // add to iterable list (only the explicitly added items)
4746
+ if (this.iterable && checkIncludeParent) {
4747
+ this.items.push(obj);
4748
+ }
4740
4749
  // add parent ChangeTree's
4741
4750
  // - if it was invisible to this view
4742
4751
  // - if it were previously filtered out
@@ -4810,9 +4819,9 @@ class StateView {
4810
4819
  addParentOf(childChangeTree, tag) {
4811
4820
  const changeTree = childChangeTree.parent[$changes];
4812
4821
  const parentIndex = childChangeTree.parentIndex;
4813
- if (!this.items.has(changeTree)) {
4822
+ if (!this.visible.has(changeTree)) {
4814
4823
  // view must have all "changeTree" parent tree
4815
- this.items.add(changeTree);
4824
+ this.visible.add(changeTree);
4816
4825
  // add parent's parent
4817
4826
  const parentChangeTree = changeTree.parent?.[$changes];
4818
4827
  if (parentChangeTree && (parentChangeTree.filteredChanges !== undefined)) {
@@ -4843,15 +4852,21 @@ class StateView {
4843
4852
  changes[parentIndex] = exports.OPERATION.ADD;
4844
4853
  }
4845
4854
  }
4846
- remove(obj, tag = DEFAULT_VIEW_TAG) {
4855
+ remove(obj, tag = DEFAULT_VIEW_TAG, _isClear = false) {
4847
4856
  const changeTree = obj[$changes];
4848
4857
  if (!changeTree) {
4849
4858
  console.warn("StateView#remove(), invalid object:", obj);
4850
4859
  return this;
4851
4860
  }
4852
- this.items.delete(changeTree);
4861
+ this.visible.delete(changeTree);
4862
+ // remove from iterable list
4863
+ if (this.iterable &&
4864
+ !_isClear // no need to remove during clear(), as it will be cleared entirely
4865
+ ) {
4866
+ spliceOne(this.items, this.items.indexOf(obj));
4867
+ }
4853
4868
  const ref = changeTree.ref;
4854
- const metadata = ref.constructor[Symbol.metadata];
4869
+ const metadata = ref.constructor[Symbol.metadata]; // ArraySchema/MapSchema do not have metadata
4855
4870
  let changes = this.changes.get(changeTree.refId);
4856
4871
  if (changes === undefined) {
4857
4872
  changes = {};
@@ -4872,12 +4887,12 @@ class StateView {
4872
4887
  }
4873
4888
  else {
4874
4889
  // delete all "tagged" properties.
4875
- metadata[$viewFieldIndexes].forEach((index) => changes[index] = exports.OPERATION.DELETE);
4890
+ metadata?.[$viewFieldIndexes].forEach((index) => changes[index] = exports.OPERATION.DELETE);
4876
4891
  }
4877
4892
  }
4878
4893
  else {
4879
4894
  // delete only tagged properties
4880
- metadata[$fieldIndexesByViewTag][tag].forEach((index) => changes[index] = exports.OPERATION.DELETE);
4895
+ metadata?.[$fieldIndexesByViewTag][tag].forEach((index) => changes[index] = exports.OPERATION.DELETE);
4881
4896
  }
4882
4897
  // remove tag
4883
4898
  if (this.tags && this.tags.has(changeTree)) {
@@ -4898,12 +4913,22 @@ class StateView {
4898
4913
  return this;
4899
4914
  }
4900
4915
  has(obj) {
4901
- return this.items.has(obj[$changes]);
4916
+ return this.visible.has(obj[$changes]);
4902
4917
  }
4903
4918
  hasTag(ob, tag = DEFAULT_VIEW_TAG) {
4904
4919
  const tags = this.tags?.get(ob[$changes]);
4905
4920
  return tags?.has(tag) ?? false;
4906
4921
  }
4922
+ clear() {
4923
+ if (!this.iterable) {
4924
+ throw new Error("StateView#clear() is only available for iterable StateView's. Use StateView(iterable: true) constructor.");
4925
+ }
4926
+ for (let i = 0, l = this.items.length; i < l; i++) {
4927
+ this.remove(this.items[i], DEFAULT_VIEW_TAG, true);
4928
+ }
4929
+ // clear items array
4930
+ this.items.length = 0;
4931
+ }
4907
4932
  }
4908
4933
 
4909
4934
  registerType("map", { constructor: MapSchema });