@colyseus/schema 3.0.57 → 3.0.59
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.
- package/build/cjs/index.js +78 -31
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +78 -31
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +78 -31
- package/lib/decoder/Decoder.js +1 -3
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +1 -1
- package/lib/encoder/ChangeTree.js +4 -4
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Encoder.js +2 -2
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +5 -2
- package/lib/encoder/Root.js +72 -23
- package/lib/encoder/Root.js.map +1 -1
- package/package.json +1 -1
- package/src/decoder/Decoder.ts +1 -2
- package/src/encoder/ChangeTree.ts +5 -5
- package/src/encoder/Encoder.ts +3 -3
- package/src/encoder/Root.ts +81 -24
package/build/cjs/index.js
CHANGED
|
@@ -990,7 +990,7 @@ function createChangeSet(queueRootNode) {
|
|
|
990
990
|
}
|
|
991
991
|
// Linked list helper functions
|
|
992
992
|
function createChangeTreeList() {
|
|
993
|
-
return { next: undefined, tail: undefined
|
|
993
|
+
return { next: undefined, tail: undefined };
|
|
994
994
|
}
|
|
995
995
|
function setOperationAtIndex(changeSet, index) {
|
|
996
996
|
const operationsIndex = changeSet.indexes[index];
|
|
@@ -1082,11 +1082,11 @@ class ChangeTree {
|
|
|
1082
1082
|
this.forEachChild((child, index) => {
|
|
1083
1083
|
if (child.root === root) {
|
|
1084
1084
|
//
|
|
1085
|
-
// re-assigning a child of the same root, move it to
|
|
1086
|
-
//
|
|
1085
|
+
// re-assigning a child of the same root, move it next to parent
|
|
1086
|
+
// so encoding order is preserved
|
|
1087
1087
|
//
|
|
1088
1088
|
root.add(child);
|
|
1089
|
-
root.
|
|
1089
|
+
root.moveNextToParent(child);
|
|
1090
1090
|
return;
|
|
1091
1091
|
}
|
|
1092
1092
|
child.setParent(this.ref, root, index);
|
|
@@ -4013,8 +4013,8 @@ class Root {
|
|
|
4013
4013
|
this.remove(child);
|
|
4014
4014
|
}
|
|
4015
4015
|
else if (child.parentChain) {
|
|
4016
|
-
// re-assigning a child of the same root, move it to
|
|
4017
|
-
this.
|
|
4016
|
+
// re-assigning a child of the same root, move it next to parent
|
|
4017
|
+
this.moveNextToParent(child);
|
|
4018
4018
|
}
|
|
4019
4019
|
}
|
|
4020
4020
|
});
|
|
@@ -4023,34 +4023,52 @@ class Root {
|
|
|
4023
4023
|
this.refCount[changeTree.refId] = refCount;
|
|
4024
4024
|
//
|
|
4025
4025
|
// When losing a reference to an instance, it is best to move the
|
|
4026
|
-
// ChangeTree to
|
|
4026
|
+
// ChangeTree next to its parent in the encoding queue.
|
|
4027
4027
|
//
|
|
4028
4028
|
// This way, at decoding time, the instance that contains the
|
|
4029
4029
|
// ChangeTree will be available before the ChangeTree itself. If the
|
|
4030
4030
|
// containing instance is not available, the Decoder will throw
|
|
4031
4031
|
// "refId not found" error.
|
|
4032
4032
|
//
|
|
4033
|
-
this.
|
|
4034
|
-
changeTree.forEachChild((child, _) => this.moveToEndOfChanges(child));
|
|
4033
|
+
this.recursivelyMoveNextToParent(changeTree);
|
|
4035
4034
|
}
|
|
4036
4035
|
return refCount;
|
|
4037
4036
|
}
|
|
4038
|
-
|
|
4037
|
+
recursivelyMoveNextToParent(changeTree) {
|
|
4038
|
+
this.moveNextToParent(changeTree);
|
|
4039
|
+
changeTree.forEachChild((child, _) => this.recursivelyMoveNextToParent(child));
|
|
4040
|
+
}
|
|
4041
|
+
moveNextToParent(changeTree) {
|
|
4039
4042
|
if (changeTree.filteredChanges) {
|
|
4040
|
-
this.
|
|
4041
|
-
this.
|
|
4043
|
+
this.moveNextToParentInChangeTreeList("filteredChanges", changeTree);
|
|
4044
|
+
this.moveNextToParentInChangeTreeList("allFilteredChanges", changeTree);
|
|
4042
4045
|
}
|
|
4043
4046
|
else {
|
|
4044
|
-
this.
|
|
4045
|
-
this.
|
|
4047
|
+
this.moveNextToParentInChangeTreeList("changes", changeTree);
|
|
4048
|
+
this.moveNextToParentInChangeTreeList("allChanges", changeTree);
|
|
4046
4049
|
}
|
|
4047
4050
|
}
|
|
4048
|
-
|
|
4051
|
+
moveNextToParentInChangeTreeList(changeSetName, changeTree) {
|
|
4049
4052
|
const changeSet = this[changeSetName];
|
|
4050
4053
|
const node = changeTree[changeSetName].queueRootNode;
|
|
4051
|
-
if (!node
|
|
4054
|
+
if (!node)
|
|
4055
|
+
return;
|
|
4056
|
+
// Find the parent in the linked list
|
|
4057
|
+
const parent = changeTree.parent;
|
|
4058
|
+
if (!parent || !parent[$changes])
|
|
4059
|
+
return;
|
|
4060
|
+
const parentNode = parent[$changes][changeSetName]?.queueRootNode;
|
|
4061
|
+
if (!parentNode || parentNode === node)
|
|
4062
|
+
return;
|
|
4063
|
+
// Use cached positions - no iteration needed!
|
|
4064
|
+
const parentPosition = parentNode.position;
|
|
4065
|
+
const childPosition = node.position;
|
|
4066
|
+
// If child is already after parent, no need to move
|
|
4067
|
+
if (childPosition > parentPosition)
|
|
4052
4068
|
return;
|
|
4053
|
-
//
|
|
4069
|
+
// Child is before parent, so we need to move it after parent
|
|
4070
|
+
// This maintains decoding order (parent before child)
|
|
4071
|
+
// Remove node from current position
|
|
4054
4072
|
if (node.prev) {
|
|
4055
4073
|
node.prev.next = node.next;
|
|
4056
4074
|
}
|
|
@@ -4063,16 +4081,18 @@ class Root {
|
|
|
4063
4081
|
else {
|
|
4064
4082
|
changeSet.tail = node.prev;
|
|
4065
4083
|
}
|
|
4066
|
-
//
|
|
4067
|
-
node.prev =
|
|
4068
|
-
node.next =
|
|
4069
|
-
if (
|
|
4070
|
-
|
|
4084
|
+
// Insert node right after parent
|
|
4085
|
+
node.prev = parentNode;
|
|
4086
|
+
node.next = parentNode.next;
|
|
4087
|
+
if (parentNode.next) {
|
|
4088
|
+
parentNode.next.prev = node;
|
|
4071
4089
|
}
|
|
4072
4090
|
else {
|
|
4073
|
-
changeSet.
|
|
4091
|
+
changeSet.tail = node;
|
|
4074
4092
|
}
|
|
4075
|
-
|
|
4093
|
+
parentNode.next = node;
|
|
4094
|
+
// Update positions after the move
|
|
4095
|
+
this.updatePositionsAfterMove(changeSet, node, parentPosition + 1);
|
|
4076
4096
|
}
|
|
4077
4097
|
enqueueChangeTree(changeTree, changeSet, queueRootNode = changeTree[changeSet].queueRootNode) {
|
|
4078
4098
|
// skip
|
|
@@ -4083,7 +4103,12 @@ class Root {
|
|
|
4083
4103
|
changeTree[changeSet].queueRootNode = this.addToChangeTreeList(this[changeSet], changeTree);
|
|
4084
4104
|
}
|
|
4085
4105
|
addToChangeTreeList(list, changeTree) {
|
|
4086
|
-
const node = {
|
|
4106
|
+
const node = {
|
|
4107
|
+
changeTree,
|
|
4108
|
+
next: undefined,
|
|
4109
|
+
prev: undefined,
|
|
4110
|
+
position: list.tail ? list.tail.position + 1 : 0
|
|
4111
|
+
};
|
|
4087
4112
|
if (!list.next) {
|
|
4088
4113
|
list.next = node;
|
|
4089
4114
|
list.tail = node;
|
|
@@ -4093,13 +4118,35 @@ class Root {
|
|
|
4093
4118
|
list.tail.next = node;
|
|
4094
4119
|
list.tail = node;
|
|
4095
4120
|
}
|
|
4096
|
-
list.length++;
|
|
4097
4121
|
return node;
|
|
4098
4122
|
}
|
|
4123
|
+
updatePositionsAfterRemoval(list, removedPosition) {
|
|
4124
|
+
// Update positions for all nodes after the removed position
|
|
4125
|
+
let current = list.next;
|
|
4126
|
+
let position = 0;
|
|
4127
|
+
while (current) {
|
|
4128
|
+
if (position >= removedPosition) {
|
|
4129
|
+
current.position = position;
|
|
4130
|
+
}
|
|
4131
|
+
current = current.next;
|
|
4132
|
+
position++;
|
|
4133
|
+
}
|
|
4134
|
+
}
|
|
4135
|
+
updatePositionsAfterMove(list, node, newPosition) {
|
|
4136
|
+
// Recalculate all positions - this is more reliable than trying to be clever
|
|
4137
|
+
let current = list.next;
|
|
4138
|
+
let position = 0;
|
|
4139
|
+
while (current) {
|
|
4140
|
+
current.position = position;
|
|
4141
|
+
current = current.next;
|
|
4142
|
+
position++;
|
|
4143
|
+
}
|
|
4144
|
+
}
|
|
4099
4145
|
removeChangeFromChangeSet(changeSetName, changeTree) {
|
|
4100
4146
|
const changeSet = this[changeSetName];
|
|
4101
4147
|
const node = changeTree[changeSetName].queueRootNode;
|
|
4102
4148
|
if (node && node.changeTree === changeTree) {
|
|
4149
|
+
const removedPosition = node.position;
|
|
4103
4150
|
// Remove the node from the linked list
|
|
4104
4151
|
if (node.prev) {
|
|
4105
4152
|
node.prev.next = node.next;
|
|
@@ -4113,7 +4160,8 @@ class Root {
|
|
|
4113
4160
|
else {
|
|
4114
4161
|
changeSet.tail = node.prev;
|
|
4115
4162
|
}
|
|
4116
|
-
|
|
4163
|
+
// Update positions for nodes that came after the removed node
|
|
4164
|
+
this.updatePositionsAfterRemoval(changeSet, removedPosition);
|
|
4117
4165
|
// Clear ChangeTree reference
|
|
4118
4166
|
changeTree[changeSetName].queueRootNode = undefined;
|
|
4119
4167
|
return true;
|
|
@@ -4335,8 +4383,8 @@ class Encoder {
|
|
|
4335
4383
|
}
|
|
4336
4384
|
}
|
|
4337
4385
|
get hasChanges() {
|
|
4338
|
-
return (this.root.changes.
|
|
4339
|
-
this.root.filteredChanges.
|
|
4386
|
+
return (this.root.changes.next !== undefined ||
|
|
4387
|
+
this.root.filteredChanges.next !== undefined);
|
|
4340
4388
|
}
|
|
4341
4389
|
}
|
|
4342
4390
|
|
|
@@ -4519,8 +4567,7 @@ class Decoder {
|
|
|
4519
4567
|
if (!nextRef) {
|
|
4520
4568
|
// throw new Error(`"refId" not found: ${nextRefId}`);
|
|
4521
4569
|
console.error(`"refId" not found: ${nextRefId}`, { previousRef: ref, previousRefId: this.currentRefId });
|
|
4522
|
-
console.warn("Please report this to the developers.
|
|
4523
|
-
console.warn(Schema.debugRefIdsFromDecoder(this));
|
|
4570
|
+
console.warn("Please report this issue to the developers.");
|
|
4524
4571
|
this.skipCurrentStructure(bytes, it, totalBytes);
|
|
4525
4572
|
}
|
|
4526
4573
|
else {
|