@colyseus/schema 3.0.50 → 3.0.52
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 +53 -46
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +53 -46
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +53 -46
- package/lib/encoder/ChangeTree.d.ts +0 -2
- package/lib/encoder/ChangeTree.js +18 -45
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/EncodeOperation.js +6 -1
- package/lib/encoder/EncodeOperation.js.map +1 -1
- package/lib/encoder/Root.d.ts +4 -2
- package/lib/encoder/Root.js +24 -1
- package/lib/encoder/Root.js.map +1 -1
- package/lib/types/custom/ArraySchema.js +2 -2
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/MapSchema.js +3 -0
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/package.json +1 -1
- package/src/encoder/ChangeTree.ts +20 -50
- package/src/encoder/EncodeOperation.ts +6 -1
- package/src/encoder/Root.ts +34 -3
- package/src/types/custom/ArraySchema.ts +3 -3
- package/src/types/custom/MapSchema.ts +4 -0
|
@@ -57,8 +57,8 @@ export interface ChangeSet {
|
|
|
57
57
|
queueRootNode?: ChangeTreeNode; // direct reference to ChangeTreeNode in the linked list
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
function createChangeSet(): ChangeSet {
|
|
61
|
-
return { indexes: {}, operations: [] };
|
|
60
|
+
function createChangeSet(queueRootNode?: ChangeTreeNode): ChangeSet {
|
|
61
|
+
return { indexes: {}, operations: [], queueRootNode };
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// Linked list helper functions
|
|
@@ -66,23 +66,6 @@ export function createChangeTreeList(): ChangeTreeList {
|
|
|
66
66
|
return { next: undefined, tail: undefined, length: 0 };
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
export function addToChangeTreeList(list: ChangeTreeList, changeTree: ChangeTree): ChangeTreeNode {
|
|
70
|
-
const node: ChangeTreeNode = { changeTree, next: undefined, prev: undefined };
|
|
71
|
-
|
|
72
|
-
if (!list.next) {
|
|
73
|
-
list.next = node;
|
|
74
|
-
list.tail = node;
|
|
75
|
-
} else {
|
|
76
|
-
node.prev = list.tail;
|
|
77
|
-
list.tail!.next = node;
|
|
78
|
-
list.tail = node;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
list.length++;
|
|
82
|
-
|
|
83
|
-
return node;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
69
|
export function setOperationAtIndex(changeSet: ChangeSet, index: number) {
|
|
87
70
|
const operationsIndex = changeSet.indexes[index];
|
|
88
71
|
if (operationsIndex === undefined) {
|
|
@@ -129,22 +112,6 @@ export function debugChangeSet(label: string, changeSet: ChangeSet) {
|
|
|
129
112
|
console.log(operations.join("\n"), "\n}");
|
|
130
113
|
}
|
|
131
114
|
|
|
132
|
-
export function enqueueChangeTree(
|
|
133
|
-
root: Root,
|
|
134
|
-
changeTree: ChangeTree,
|
|
135
|
-
changeSet: 'changes' | 'filteredChanges' | 'allFilteredChanges' | 'allChanges',
|
|
136
|
-
queueRootNode = changeTree[changeSet].queueRootNode
|
|
137
|
-
) {
|
|
138
|
-
// skip
|
|
139
|
-
if (!root) { return; }
|
|
140
|
-
|
|
141
|
-
if (queueRootNode) {
|
|
142
|
-
} else {
|
|
143
|
-
// Add to linked list if not already present
|
|
144
|
-
changeTree[changeSet].queueRootNode = addToChangeTreeList(root[changeSet], changeTree);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
115
|
export interface ParentChain {
|
|
149
116
|
ref: Ref;
|
|
150
117
|
index: number;
|
|
@@ -283,11 +250,11 @@ export class ChangeTree<T extends Ref = any> {
|
|
|
283
250
|
// this is checked during .encode() time.
|
|
284
251
|
if (this.filteredChanges !== undefined) {
|
|
285
252
|
this.filteredChanges.operations.push(-op);
|
|
286
|
-
|
|
253
|
+
this.root?.enqueueChangeTree(this, 'filteredChanges');
|
|
287
254
|
|
|
288
255
|
} else {
|
|
289
256
|
this.changes.operations.push(-op);
|
|
290
|
-
|
|
257
|
+
this.root?.enqueueChangeTree(this, 'changes');
|
|
291
258
|
}
|
|
292
259
|
}
|
|
293
260
|
|
|
@@ -316,13 +283,13 @@ export class ChangeTree<T extends Ref = any> {
|
|
|
316
283
|
setOperationAtIndex(this.allFilteredChanges, index);
|
|
317
284
|
|
|
318
285
|
if (this.root) {
|
|
319
|
-
|
|
320
|
-
|
|
286
|
+
this.root.enqueueChangeTree(this, 'filteredChanges');
|
|
287
|
+
this.root.enqueueChangeTree(this, 'allFilteredChanges');
|
|
321
288
|
}
|
|
322
289
|
|
|
323
290
|
} else {
|
|
324
291
|
setOperationAtIndex(this.allChanges, index);
|
|
325
|
-
|
|
292
|
+
this.root?.enqueueChangeTree(this, 'changes');
|
|
326
293
|
}
|
|
327
294
|
}
|
|
328
295
|
|
|
@@ -385,12 +352,12 @@ export class ChangeTree<T extends Ref = any> {
|
|
|
385
352
|
if (this.filteredChanges !== undefined) {
|
|
386
353
|
setOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
387
354
|
setOperationAtIndex(this.filteredChanges, index);
|
|
388
|
-
|
|
355
|
+
this.root?.enqueueChangeTree(this, 'filteredChanges');
|
|
389
356
|
|
|
390
357
|
} else {
|
|
391
358
|
setOperationAtIndex(this.allChanges, allChangesIndex);
|
|
392
359
|
setOperationAtIndex(this.changes, index);
|
|
393
|
-
|
|
360
|
+
this.root?.enqueueChangeTree(this, 'changes');
|
|
394
361
|
}
|
|
395
362
|
}
|
|
396
363
|
|
|
@@ -461,10 +428,10 @@ export class ChangeTree<T extends Ref = any> {
|
|
|
461
428
|
//
|
|
462
429
|
if (this.filteredChanges !== undefined) {
|
|
463
430
|
deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);
|
|
464
|
-
|
|
431
|
+
this.root?.enqueueChangeTree(this, 'filteredChanges');
|
|
465
432
|
|
|
466
433
|
} else {
|
|
467
|
-
|
|
434
|
+
this.root?.enqueueChangeTree(this, 'changes');
|
|
468
435
|
}
|
|
469
436
|
|
|
470
437
|
return previousValue;
|
|
@@ -499,10 +466,11 @@ export class ChangeTree<T extends Ref = any> {
|
|
|
499
466
|
}
|
|
500
467
|
|
|
501
468
|
if (discardAll) {
|
|
502
|
-
|
|
469
|
+
// preserve queueRootNode references
|
|
470
|
+
this.allChanges = createChangeSet(this.allChanges.queueRootNode);
|
|
503
471
|
|
|
504
472
|
if (this.allFilteredChanges !== undefined) {
|
|
505
|
-
this.allFilteredChanges = createChangeSet();
|
|
473
|
+
this.allFilteredChanges = createChangeSet(this.allFilteredChanges.queueRootNode);
|
|
506
474
|
}
|
|
507
475
|
}
|
|
508
476
|
}
|
|
@@ -539,17 +507,19 @@ export class ChangeTree<T extends Ref = any> {
|
|
|
539
507
|
this._checkFilteredByParent(parent, parentIndex);
|
|
540
508
|
|
|
541
509
|
if (this.filteredChanges !== undefined) {
|
|
542
|
-
|
|
510
|
+
this.root?.enqueueChangeTree(this, 'filteredChanges');
|
|
511
|
+
|
|
543
512
|
if (isNewChangeTree) {
|
|
544
|
-
|
|
513
|
+
this.root?.enqueueChangeTree(this, 'allFilteredChanges');
|
|
545
514
|
}
|
|
546
515
|
}
|
|
547
516
|
}
|
|
548
517
|
|
|
549
518
|
if (!this.isFiltered) {
|
|
550
|
-
|
|
519
|
+
this.root?.enqueueChangeTree(this, 'changes');
|
|
520
|
+
|
|
551
521
|
if (isNewChangeTree) {
|
|
552
|
-
|
|
522
|
+
this.root?.enqueueChangeTree(this, 'allChanges');
|
|
553
523
|
}
|
|
554
524
|
}
|
|
555
525
|
}
|
|
@@ -177,7 +177,12 @@ export const encodeArray: EncodeOperation = function (
|
|
|
177
177
|
let refOrIndex: number;
|
|
178
178
|
|
|
179
179
|
if (useOperationByRefId) {
|
|
180
|
-
|
|
180
|
+
const item = ref['tmpItems'][field];
|
|
181
|
+
|
|
182
|
+
// Skip encoding if item is undefined (e.g. when clear() is called)
|
|
183
|
+
if (!item) { return; }
|
|
184
|
+
|
|
185
|
+
refOrIndex = item[$changes].refId;
|
|
181
186
|
|
|
182
187
|
if (operation === OPERATION.DELETE) {
|
|
183
188
|
operation = OPERATION.DELETE_BY_REFID;
|
package/src/encoder/Root.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { OPERATION } from "../encoding/spec";
|
|
2
2
|
import { TypeContext } from "../types/TypeContext";
|
|
3
|
-
import { ChangeTree, setOperationAtIndex, ChangeTreeList, createChangeTreeList, ChangeSetName,
|
|
3
|
+
import { ChangeTree, setOperationAtIndex, ChangeTreeList, createChangeTreeList, ChangeSetName, type ChangeTreeNode } from "./ChangeTree";
|
|
4
4
|
|
|
5
5
|
export class Root {
|
|
6
6
|
protected nextUniqueId: number = 0;
|
|
@@ -47,7 +47,7 @@ export class Root {
|
|
|
47
47
|
|
|
48
48
|
this.refCount[changeTree.refId] = (previousRefCount || 0) + 1;
|
|
49
49
|
|
|
50
|
-
// console.log("ADD", { refId: changeTree.refId, refCount: this.refCount[changeTree.refId] });
|
|
50
|
+
// console.log("ADD", { refId: changeTree.refId, ref: changeTree.ref.constructor.name, refCount: this.refCount[changeTree.refId], isNewChangeTree });
|
|
51
51
|
|
|
52
52
|
return isNewChangeTree;
|
|
53
53
|
}
|
|
@@ -55,6 +55,8 @@ export class Root {
|
|
|
55
55
|
remove(changeTree: ChangeTree) {
|
|
56
56
|
const refCount = (this.refCount[changeTree.refId]) - 1;
|
|
57
57
|
|
|
58
|
+
// console.log("REMOVE", { refId: changeTree.refId, ref: changeTree.ref.constructor.name, refCount, needRemove: refCount <= 0 });
|
|
59
|
+
|
|
58
60
|
if (refCount <= 0) {
|
|
59
61
|
//
|
|
60
62
|
// Only remove "root" reference if it's the last reference
|
|
@@ -147,7 +149,36 @@ export class Root {
|
|
|
147
149
|
changeSet.tail = node;
|
|
148
150
|
}
|
|
149
151
|
|
|
150
|
-
|
|
152
|
+
public enqueueChangeTree(
|
|
153
|
+
changeTree: ChangeTree,
|
|
154
|
+
changeSet: 'changes' | 'filteredChanges' | 'allFilteredChanges' | 'allChanges',
|
|
155
|
+
queueRootNode = changeTree[changeSet].queueRootNode
|
|
156
|
+
) {
|
|
157
|
+
// skip
|
|
158
|
+
if (queueRootNode) { return; }
|
|
159
|
+
|
|
160
|
+
// Add to linked list if not already present
|
|
161
|
+
changeTree[changeSet].queueRootNode = this.addToChangeTreeList(this[changeSet], changeTree);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
protected addToChangeTreeList(list: ChangeTreeList, changeTree: ChangeTree): ChangeTreeNode {
|
|
165
|
+
const node: ChangeTreeNode = { changeTree, next: undefined, prev: undefined };
|
|
166
|
+
|
|
167
|
+
if (!list.next) {
|
|
168
|
+
list.next = node;
|
|
169
|
+
list.tail = node;
|
|
170
|
+
} else {
|
|
171
|
+
node.prev = list.tail;
|
|
172
|
+
list.tail!.next = node;
|
|
173
|
+
list.tail = node;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
list.length++;
|
|
177
|
+
|
|
178
|
+
return node;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public removeChangeFromChangeSet(changeSetName: ChangeSetName, changeTree: ChangeTree) {
|
|
151
182
|
const changeSet = this[changeSetName];
|
|
152
183
|
const node = changeTree[changeSetName].queueRootNode;
|
|
153
184
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex, $onDecodeEnd } from "../symbols";
|
|
2
2
|
import type { Schema } from "../../Schema";
|
|
3
|
-
import { ChangeTree,
|
|
3
|
+
import { ChangeTree, setOperationAtIndex } from "../../encoder/ChangeTree";
|
|
4
4
|
import { OPERATION } from "../../encoding/spec";
|
|
5
5
|
import { registerType } from "../registry";
|
|
6
6
|
import { Collection } from "../HelperTypes";
|
|
@@ -482,10 +482,10 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
|
|
|
482
482
|
// FIXME: this code block is duplicated on ChangeTree
|
|
483
483
|
//
|
|
484
484
|
if (changeTree.filteredChanges !== undefined) {
|
|
485
|
-
|
|
485
|
+
changeTree.root?.enqueueChangeTree(changeTree, 'filteredChanges');
|
|
486
486
|
|
|
487
487
|
} else {
|
|
488
|
-
|
|
488
|
+
changeTree.root?.enqueueChangeTree(changeTree, 'changes');
|
|
489
489
|
}
|
|
490
490
|
|
|
491
491
|
return this.items.splice(start, deleteCount, ...insertItems);
|
|
@@ -118,6 +118,10 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
if (this.deletedItems[index]) {
|
|
122
|
+
delete this.deletedItems[index];
|
|
123
|
+
}
|
|
124
|
+
|
|
121
125
|
} else {
|
|
122
126
|
index = changeTree.indexes[$numFields] ?? 0;
|
|
123
127
|
operation = OPERATION.ADD;
|