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