@colyseus/schema 3.0.41 → 3.0.43
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 +334 -185
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +334 -185
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +334 -185
- package/lib/Schema.d.ts +2 -1
- package/lib/Schema.js +21 -3
- package/lib/Schema.js.map +1 -1
- package/lib/bench_encode.d.ts +1 -0
- package/lib/bench_encode.js +130 -0
- package/lib/bench_encode.js.map +1 -0
- package/lib/debug.d.ts +1 -0
- package/lib/debug.js +51 -0
- package/lib/debug.js.map +1 -0
- package/lib/decoder/Decoder.js +7 -8
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/encoder/ChangeTree.d.ts +57 -7
- package/lib/encoder/ChangeTree.js +171 -106
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Encoder.js +19 -20
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/Root.d.ts +8 -7
- package/lib/encoder/Root.js +81 -26
- package/lib/encoder/Root.js.map +1 -1
- package/lib/encoder/StateView.js +7 -0
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/types/custom/ArraySchema.js +5 -3
- package/lib/types/custom/ArraySchema.js.map +1 -1
- package/lib/types/custom/MapSchema.js +7 -2
- package/lib/types/custom/MapSchema.js.map +1 -1
- package/lib/types/symbols.d.ts +14 -14
- package/lib/types/symbols.js +14 -14
- package/lib/types/symbols.js.map +1 -1
- package/lib/utils.js +7 -3
- package/lib/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/Schema.ts +21 -5
- package/src/bench_encode.ts +108 -0
- package/src/debug.ts +55 -0
- package/src/decoder/Decoder.ts +8 -12
- package/src/encoder/ChangeTree.ts +201 -115
- package/src/encoder/Encoder.ts +21 -19
- package/src/encoder/Root.ts +87 -28
- package/src/encoder/StateView.ts +8 -0
- package/src/types/custom/ArraySchema.ts +6 -4
- package/src/types/custom/MapSchema.ts +8 -2
- package/src/types/symbols.ts +14 -14
- package/src/utils.ts +9 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ChangeTree = void 0;
|
|
4
|
+
exports.createChangeTreeList = createChangeTreeList;
|
|
5
|
+
exports.addToChangeTreeList = addToChangeTreeList;
|
|
4
6
|
exports.setOperationAtIndex = setOperationAtIndex;
|
|
5
7
|
exports.deleteOperationAtIndex = deleteOperationAtIndex;
|
|
6
8
|
exports.debugChangeSet = debugChangeSet;
|
|
@@ -11,6 +13,24 @@ const Metadata_1 = require("../Metadata");
|
|
|
11
13
|
function createChangeSet() {
|
|
12
14
|
return { indexes: {}, operations: [] };
|
|
13
15
|
}
|
|
16
|
+
// Linked list helper functions
|
|
17
|
+
function createChangeTreeList() {
|
|
18
|
+
return { next: undefined, tail: undefined, length: 0 };
|
|
19
|
+
}
|
|
20
|
+
function addToChangeTreeList(list, changeTree) {
|
|
21
|
+
const node = { changeTree, next: undefined, prev: undefined };
|
|
22
|
+
if (!list.next) {
|
|
23
|
+
list.next = node;
|
|
24
|
+
list.tail = node;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
node.prev = list.tail;
|
|
28
|
+
list.tail.next = node;
|
|
29
|
+
list.tail = node;
|
|
30
|
+
}
|
|
31
|
+
list.length++;
|
|
32
|
+
return node;
|
|
33
|
+
}
|
|
14
34
|
function setOperationAtIndex(changeSet, index) {
|
|
15
35
|
const operationsIndex = changeSet.indexes[index];
|
|
16
36
|
if (operationsIndex === undefined) {
|
|
@@ -52,13 +72,16 @@ function debugChangeSet(label, changeSet) {
|
|
|
52
72
|
console.log(`operations (${changeSet.operations.filter(op => op !== undefined).length}) {`);
|
|
53
73
|
console.log(operations.join("\n"), "\n}");
|
|
54
74
|
}
|
|
55
|
-
function enqueueChangeTree(root, changeTree, changeSet,
|
|
75
|
+
function enqueueChangeTree(root, changeTree, changeSet, queueRootNode = changeTree[changeSet].queueRootNode) {
|
|
76
|
+
// skip
|
|
56
77
|
if (!root) {
|
|
57
|
-
// skip
|
|
58
78
|
return;
|
|
59
79
|
}
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
if (queueRootNode) {
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// Add to linked list if not already present
|
|
84
|
+
changeTree[changeSet].queueRootNode = addToChangeTreeList(root[changeSet], changeTree);
|
|
62
85
|
}
|
|
63
86
|
}
|
|
64
87
|
class ChangeTree {
|
|
@@ -82,83 +105,58 @@ class ChangeTree {
|
|
|
82
105
|
*/
|
|
83
106
|
this.isNew = true;
|
|
84
107
|
this.ref = ref;
|
|
108
|
+
this.metadata = ref.constructor[Symbol.metadata];
|
|
85
109
|
//
|
|
86
110
|
// Does this structure have "filters" declared?
|
|
87
111
|
//
|
|
88
|
-
|
|
89
|
-
if (metadata?.[symbols_1.$viewFieldIndexes]) {
|
|
112
|
+
if (this.metadata?.[symbols_1.$viewFieldIndexes]) {
|
|
90
113
|
this.allFilteredChanges = { indexes: {}, operations: [] };
|
|
91
114
|
this.filteredChanges = { indexes: {}, operations: [] };
|
|
92
115
|
}
|
|
93
116
|
}
|
|
94
117
|
setRoot(root) {
|
|
95
118
|
this.root = root;
|
|
96
|
-
this.
|
|
97
|
-
|
|
98
|
-
// TODO: refactor and possibly unify .setRoot() and .setParent()
|
|
99
|
-
//
|
|
119
|
+
const isNewChangeTree = this.root.add(this);
|
|
120
|
+
this.checkIsFiltered(this.parent, this.parentIndex, isNewChangeTree);
|
|
100
121
|
// Recursively set root on child structures
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const changeTree = this.ref[field.name]?.[symbols_1.$changes];
|
|
106
|
-
if (changeTree) {
|
|
107
|
-
if (changeTree.root !== root) {
|
|
108
|
-
changeTree.setRoot(root);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
root.add(changeTree); // increment refCount
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
else if (this.ref[symbols_1.$childType] && typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
117
|
-
// MapSchema / ArraySchema, etc.
|
|
118
|
-
this.ref.forEach((value, key) => {
|
|
119
|
-
const changeTree = value[symbols_1.$changes];
|
|
120
|
-
if (changeTree.root !== root) {
|
|
121
|
-
changeTree.setRoot(root);
|
|
122
|
+
if (isNewChangeTree) {
|
|
123
|
+
this.forEachChild((child, _) => {
|
|
124
|
+
if (child.root !== root) {
|
|
125
|
+
child.setRoot(root);
|
|
122
126
|
}
|
|
123
127
|
else {
|
|
124
|
-
root.add(
|
|
128
|
+
root.add(child); // increment refCount
|
|
125
129
|
}
|
|
126
130
|
});
|
|
127
131
|
}
|
|
128
132
|
}
|
|
129
133
|
setParent(parent, root, parentIndex) {
|
|
130
|
-
this.parent
|
|
131
|
-
this.parentIndex = parentIndex;
|
|
134
|
+
this.addParent(parent, parentIndex);
|
|
132
135
|
// avoid setting parents with empty `root`
|
|
133
136
|
if (!root) {
|
|
134
137
|
return;
|
|
135
138
|
}
|
|
139
|
+
const isNewChangeTree = root.add(this);
|
|
136
140
|
// skip if parent is already set
|
|
137
141
|
if (root !== this.root) {
|
|
138
142
|
this.root = root;
|
|
139
|
-
this.checkIsFiltered(parent, parentIndex);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
root.add(this);
|
|
143
|
+
this.checkIsFiltered(parent, parentIndex, isNewChangeTree);
|
|
143
144
|
}
|
|
144
145
|
// assign same parent on child structures
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
this.ref.forEach((value, key) => {
|
|
158
|
-
const changeTree = value[symbols_1.$changes];
|
|
159
|
-
if (changeTree.root !== root) {
|
|
160
|
-
changeTree.setParent(this.ref, root, this.indexes[key] ?? key);
|
|
146
|
+
if (isNewChangeTree) {
|
|
147
|
+
//
|
|
148
|
+
// assign same parent on child structures
|
|
149
|
+
//
|
|
150
|
+
this.forEachChild((child, index) => {
|
|
151
|
+
if (child.root === root) {
|
|
152
|
+
//
|
|
153
|
+
// re-assigning a child of the same root, move it to the end
|
|
154
|
+
// of the changes queue so encoding order is preserved
|
|
155
|
+
//
|
|
156
|
+
root.moveToEndOfChanges(child);
|
|
157
|
+
return;
|
|
161
158
|
}
|
|
159
|
+
child.setParent(this.ref, root, index);
|
|
162
160
|
});
|
|
163
161
|
}
|
|
164
162
|
}
|
|
@@ -166,21 +164,24 @@ class ChangeTree {
|
|
|
166
164
|
//
|
|
167
165
|
// assign same parent on child structures
|
|
168
166
|
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
if (value) {
|
|
175
|
-
callback(value[symbols_1.$changes], index);
|
|
167
|
+
if (this.ref[symbols_1.$childType]) {
|
|
168
|
+
if (typeof (this.ref[symbols_1.$childType]) !== "string") {
|
|
169
|
+
// MapSchema / ArraySchema, etc.
|
|
170
|
+
for (const [key, value] of this.ref.entries()) {
|
|
171
|
+
callback(value[symbols_1.$changes], key);
|
|
176
172
|
}
|
|
177
|
-
|
|
173
|
+
;
|
|
174
|
+
}
|
|
178
175
|
}
|
|
179
|
-
else
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
else {
|
|
177
|
+
for (const index of this.metadata?.[symbols_1.$refTypeFieldIndexes] ?? []) {
|
|
178
|
+
const field = this.metadata[index];
|
|
179
|
+
const value = this.ref[field.name];
|
|
180
|
+
if (!value) {
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
callback(value[symbols_1.$changes], index);
|
|
184
|
+
}
|
|
184
185
|
}
|
|
185
186
|
}
|
|
186
187
|
operation(op) {
|
|
@@ -196,8 +197,7 @@ class ChangeTree {
|
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
change(index, operation = spec_1.OPERATION.ADD) {
|
|
199
|
-
const
|
|
200
|
-
const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);
|
|
200
|
+
const isFiltered = this.isFiltered || (this.metadata?.[index]?.tag !== undefined);
|
|
201
201
|
const changeSet = (isFiltered)
|
|
202
202
|
? this.filteredChanges
|
|
203
203
|
: this.changes;
|
|
@@ -287,19 +287,16 @@ class ChangeTree {
|
|
|
287
287
|
}
|
|
288
288
|
}
|
|
289
289
|
getType(index) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
//
|
|
299
|
-
|
|
300
|
-
//
|
|
301
|
-
return this.ref[symbols_1.$childType];
|
|
302
|
-
}
|
|
290
|
+
return (
|
|
291
|
+
//
|
|
292
|
+
// Get the child type from parent structure.
|
|
293
|
+
// - ["string"] => "string"
|
|
294
|
+
// - { map: "string" } => "string"
|
|
295
|
+
// - { set: "string" } => "string"
|
|
296
|
+
//
|
|
297
|
+
this.ref[symbols_1.$childType] || // ArraySchema | MapSchema | SetSchema | CollectionSchema
|
|
298
|
+
this.metadata[index].type // Schema
|
|
299
|
+
);
|
|
303
300
|
}
|
|
304
301
|
getChange(index) {
|
|
305
302
|
return this.indexedOperations[index];
|
|
@@ -359,9 +356,7 @@ class ChangeTree {
|
|
|
359
356
|
endEncode(changeSetName) {
|
|
360
357
|
this.indexedOperations = {};
|
|
361
358
|
// clear changeset
|
|
362
|
-
this[changeSetName]
|
|
363
|
-
this[changeSetName].operations.length = 0;
|
|
364
|
-
this[changeSetName].queueRootIndex = undefined;
|
|
359
|
+
this[changeSetName] = createChangeSet();
|
|
365
360
|
// ArraySchema and MapSchema have a custom "encode end" method
|
|
366
361
|
this.ref[symbols_1.$onEncodeEnd]?.();
|
|
367
362
|
// Not a new instance anymore
|
|
@@ -375,20 +370,14 @@ class ChangeTree {
|
|
|
375
370
|
//
|
|
376
371
|
this.ref[symbols_1.$onEncodeEnd]?.();
|
|
377
372
|
this.indexedOperations = {};
|
|
378
|
-
this.changes
|
|
379
|
-
this.changes.operations.length = 0;
|
|
380
|
-
this.changes.queueRootIndex = undefined;
|
|
373
|
+
this.changes = createChangeSet();
|
|
381
374
|
if (this.filteredChanges !== undefined) {
|
|
382
|
-
this.filteredChanges
|
|
383
|
-
this.filteredChanges.operations.length = 0;
|
|
384
|
-
this.filteredChanges.queueRootIndex = undefined;
|
|
375
|
+
this.filteredChanges = createChangeSet();
|
|
385
376
|
}
|
|
386
377
|
if (discardAll) {
|
|
387
|
-
this.allChanges
|
|
388
|
-
this.allChanges.operations.length = 0;
|
|
378
|
+
this.allChanges = createChangeSet();
|
|
389
379
|
if (this.allFilteredChanges !== undefined) {
|
|
390
|
-
this.allFilteredChanges
|
|
391
|
-
this.allFilteredChanges.operations.length = 0;
|
|
380
|
+
this.allFilteredChanges = createChangeSet();
|
|
392
381
|
}
|
|
393
382
|
}
|
|
394
383
|
}
|
|
@@ -406,18 +395,10 @@ class ChangeTree {
|
|
|
406
395
|
}
|
|
407
396
|
this.discard();
|
|
408
397
|
}
|
|
409
|
-
ensureRefId() {
|
|
410
|
-
// skip if refId is already set.
|
|
411
|
-
if (this.refId !== undefined) {
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
this.refId = this.root.getNextUniqueId();
|
|
415
|
-
}
|
|
416
398
|
get changed() {
|
|
417
399
|
return (Object.entries(this.indexedOperations).length > 0);
|
|
418
400
|
}
|
|
419
|
-
checkIsFiltered(parent, parentIndex) {
|
|
420
|
-
const isNewChangeTree = this.root.add(this);
|
|
401
|
+
checkIsFiltered(parent, parentIndex, isNewChangeTree) {
|
|
421
402
|
if (this.root.types.hasFilters) {
|
|
422
403
|
//
|
|
423
404
|
// At Schema initialization, the "root" structure might not be available
|
|
@@ -429,14 +410,14 @@ class ChangeTree {
|
|
|
429
410
|
if (this.filteredChanges !== undefined) {
|
|
430
411
|
enqueueChangeTree(this.root, this, 'filteredChanges');
|
|
431
412
|
if (isNewChangeTree) {
|
|
432
|
-
this.root
|
|
413
|
+
enqueueChangeTree(this.root, this, 'allFilteredChanges');
|
|
433
414
|
}
|
|
434
415
|
}
|
|
435
416
|
}
|
|
436
417
|
if (!this.isFiltered) {
|
|
437
418
|
enqueueChangeTree(this.root, this, 'changes');
|
|
438
419
|
if (isNewChangeTree) {
|
|
439
|
-
this.root
|
|
420
|
+
enqueueChangeTree(this.root, this, 'allChanges');
|
|
440
421
|
}
|
|
441
422
|
}
|
|
442
423
|
}
|
|
@@ -493,6 +474,90 @@ class ChangeTree {
|
|
|
493
474
|
}
|
|
494
475
|
}
|
|
495
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Get the immediate parent
|
|
479
|
+
*/
|
|
480
|
+
get parent() {
|
|
481
|
+
return this.parentChain?.ref;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Get the immediate parent index
|
|
485
|
+
*/
|
|
486
|
+
get parentIndex() {
|
|
487
|
+
return this.parentChain?.index;
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Add a parent to the chain
|
|
491
|
+
*/
|
|
492
|
+
addParent(parent, index) {
|
|
493
|
+
// Check if this parent already exists in the chain
|
|
494
|
+
if (this.hasParent((p, i) => p === parent && i === index)) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
this.parentChain = {
|
|
498
|
+
ref: parent,
|
|
499
|
+
index,
|
|
500
|
+
next: this.parentChain
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Remove a parent from the chain
|
|
505
|
+
* @param parent - The parent to remove
|
|
506
|
+
* @returns true if parent was removed
|
|
507
|
+
*/
|
|
508
|
+
removeParent(parent) {
|
|
509
|
+
let current = this.parentChain;
|
|
510
|
+
let previous = null;
|
|
511
|
+
while (current) {
|
|
512
|
+
//
|
|
513
|
+
// FIXME: it is required to check against `$changes` here because
|
|
514
|
+
// ArraySchema is instance of Proxy
|
|
515
|
+
//
|
|
516
|
+
if (current.ref[symbols_1.$changes] === parent[symbols_1.$changes]) {
|
|
517
|
+
if (previous) {
|
|
518
|
+
previous.next = current.next;
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
this.parentChain = current.next;
|
|
522
|
+
}
|
|
523
|
+
return true;
|
|
524
|
+
}
|
|
525
|
+
previous = current;
|
|
526
|
+
current = current.next;
|
|
527
|
+
}
|
|
528
|
+
return this.parentChain === undefined;
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Find a specific parent in the chain
|
|
532
|
+
*/
|
|
533
|
+
findParent(predicate) {
|
|
534
|
+
let current = this.parentChain;
|
|
535
|
+
while (current) {
|
|
536
|
+
if (predicate(current.ref, current.index)) {
|
|
537
|
+
return current;
|
|
538
|
+
}
|
|
539
|
+
current = current.next;
|
|
540
|
+
}
|
|
541
|
+
return undefined;
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Check if this ChangeTree has a specific parent
|
|
545
|
+
*/
|
|
546
|
+
hasParent(predicate) {
|
|
547
|
+
return this.findParent(predicate) !== undefined;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* Get all parents as an array (for debugging/testing)
|
|
551
|
+
*/
|
|
552
|
+
getAllParents() {
|
|
553
|
+
const parents = [];
|
|
554
|
+
let current = this.parentChain;
|
|
555
|
+
while (current) {
|
|
556
|
+
parents.push({ ref: current.ref, index: current.index });
|
|
557
|
+
current = current.next;
|
|
558
|
+
}
|
|
559
|
+
return parents;
|
|
560
|
+
}
|
|
496
561
|
}
|
|
497
562
|
exports.ChangeTree = ChangeTree;
|
|
498
563
|
//# sourceMappingURL=ChangeTree.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChangeTree.js","sourceRoot":"","sources":["../../src/encoder/ChangeTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Schema } from \"../Schema\";\nimport { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $refTypeFieldIndexes, $viewFieldIndexes } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\nimport type { SetSchema } from \"../types/custom/SetSchema\";\n\nimport { Root } from \"./Root\";\nimport { Metadata } from \"../Metadata\";\nimport type { EncodeOperation } from \"./EncodeOperation\";\nimport type { DecodeOperation } from \"../decoder/DecodeOperation\";\n\ndeclare global {\n interface Object {\n // FIXME: not a good practice to extend globals here\n [$changes]?: ChangeTree;\n [$encoder]?: EncodeOperation,\n [$decoder]?: DecodeOperation,\n }\n}\n\nexport type Ref = Schema\n | ArraySchema\n | MapSchema\n | CollectionSchema\n | SetSchema;\n\nexport type ChangeSetName = \"changes\"\n | \"allChanges\"\n | \"filteredChanges\"\n | \"allFilteredChanges\";\n\nexport interface IndexedOperations {\n [index: number]: OPERATION;\n}\n\nexport interface ChangeSet {\n // field index -> operation index\n indexes: { [index: number]: number };\n operations: number[];\n queueRootIndex?: number; // index of ChangeTree structure in `root.changes` or `root.filteredChanges`\n}\n\nfunction createChangeSet(): ChangeSet {\n return { indexes: {}, operations: [] };\n}\n\nexport function setOperationAtIndex(changeSet: ChangeSet, index: number) {\n const operationsIndex = changeSet.indexes[index];\n if (operationsIndex === undefined) {\n changeSet.indexes[index] = changeSet.operations.push(index) - 1;\n } else {\n changeSet.operations[operationsIndex] = index;\n }\n}\n\nexport function deleteOperationAtIndex(changeSet: ChangeSet, index: number | string) {\n let operationsIndex = changeSet.indexes[index];\n if (operationsIndex === undefined) {\n //\n // if index is not found, we need to find the last operation\n // FIXME: this is not very efficient\n //\n // > See \"should allow consecutive splices (same place)\" tests\n //\n operationsIndex = Object.values(changeSet.indexes).at(-1);\n index = Object.entries(changeSet.indexes).find(([_, value]) => value === operationsIndex)?.[0];\n }\n changeSet.operations[operationsIndex] = undefined;\n delete changeSet.indexes[index];\n}\n\nexport function debugChangeSet(label: string, changeSet: ChangeSet) {\n let indexes: string[] = [];\n let operations: string[] = [];\n\n for (const index in changeSet.indexes) {\n indexes.push(`\\t${index} => [${changeSet.indexes[index]}]`);\n }\n\n for (let i = 0; i < changeSet.operations.length; i++) {\n const index = changeSet.operations[i];\n if (index !== undefined) {\n operations.push(`\\t[${i}] => ${index}`);\n }\n }\n\n console.log(`${label} =>\\nindexes (${Object.keys(changeSet.indexes).length}) {`);\n console.log(indexes.join(\"\\n\"), \"\\n}\");\n console.log(`operations (${changeSet.operations.filter(op => op !== undefined).length}) {`);\n console.log(operations.join(\"\\n\"), \"\\n}\");\n}\n\nexport function enqueueChangeTree(\n root: Root,\n changeTree: ChangeTree,\n changeSet: 'changes' | 'filteredChanges' | 'allFilteredChanges',\n queueRootIndex = changeTree[changeSet].queueRootIndex\n) {\n if (!root) {\n // skip\n return;\n\n } else if (root[changeSet][queueRootIndex] !== changeTree) {\n changeTree[changeSet].queueRootIndex = root[changeSet].push(changeTree) - 1;\n }\n}\n\nexport class ChangeTree<T extends Ref=any> {\n ref: T;\n refId: number;\n\n root?: Root;\n parent?: Ref;\n parentIndex?: number;\n\n /**\n * Whether this structure is parent of a filtered structure.\n */\n isFiltered: boolean = false;\n isVisibilitySharedWithParent?: boolean; // See test case: 'should not be required to manually call view.add() items to child arrays without @view() tag'\n\n indexedOperations: IndexedOperations = {};\n\n //\n // TODO:\n // try storing the index + operation per item.\n // example: 1024 & 1025 => ADD, 1026 => DELETE\n //\n // => https://chatgpt.com/share/67107d0c-bc20-8004-8583-83b17dd7c196\n //\n changes: ChangeSet = { indexes: {}, operations: [] };\n allChanges: ChangeSet = { indexes: {}, operations: [] };\n filteredChanges: ChangeSet;\n allFilteredChanges: ChangeSet;\n\n indexes: {[index: string]: any}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)\n\n /**\n * Is this a new instance? Used on ArraySchema to determine OPERATION.MOVE_AND_ADD operation.\n */\n isNew = true;\n\n constructor(ref: T) {\n this.ref = ref;\n\n //\n // Does this structure have \"filters\" declared?\n //\n const metadata = ref.constructor[Symbol.metadata];\n if (metadata?.[$viewFieldIndexes]) {\n this.allFilteredChanges = { indexes: {}, operations: [] };\n this.filteredChanges = { indexes: {}, operations: [] };\n }\n }\n\n setRoot(root: Root) {\n this.root = root;\n this.checkIsFiltered(this.parent, this.parentIndex);\n\n //\n // TODO: refactor and possibly unify .setRoot() and .setParent()\n //\n\n // Recursively set root on child structures\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n if (metadata) {\n metadata[$refTypeFieldIndexes]?.forEach((index) => {\n const field = metadata[index as any as number];\n const changeTree: ChangeTree = this.ref[field.name]?.[$changes];\n if (changeTree) {\n if (changeTree.root !== root) {\n changeTree.setRoot(root);\n } else {\n root.add(changeTree); // increment refCount\n }\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n const changeTree: ChangeTree = value[$changes];\n if (changeTree.root !== root) {\n changeTree.setRoot(root);\n } else {\n root.add(changeTree); // increment refCount\n }\n });\n }\n }\n\n setParent(\n parent: Ref,\n root?: Root,\n parentIndex?: number,\n ) {\n this.parent = parent;\n this.parentIndex = parentIndex;\n\n // avoid setting parents with empty `root`\n if (!root) { return; }\n\n // skip if parent is already set\n if (root !== this.root) {\n this.root = root;\n this.checkIsFiltered(parent, parentIndex);\n\n } else {\n root.add(this);\n }\n\n // assign same parent on child structures\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n if (metadata) {\n metadata[$refTypeFieldIndexes]?.forEach((index) => {\n const field = metadata[index as any as number];\n const changeTree: ChangeTree = this.ref[field.name]?.[$changes];\n if (changeTree && changeTree.root !== root) {\n changeTree.setParent(this.ref, root, index);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n const changeTree: ChangeTree = value[$changes];\n if (changeTree.root !== root) {\n changeTree.setParent(this.ref, root, this.indexes[key] ?? key);\n }\n });\n }\n\n }\n\n forEachChild(callback: (change: ChangeTree, atIndex: number) => void) {\n //\n // assign same parent on child structures\n //\n const metadata: Metadata = this.ref.constructor[Symbol.metadata];\n if (metadata) {\n metadata[$refTypeFieldIndexes]?.forEach((index) => {\n const field = metadata[index as any as number];\n const value = this.ref[field.name];\n if (value) {\n callback(value[$changes], index);\n }\n });\n\n } else if (this.ref[$childType] && typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n (this.ref as MapSchema).forEach((value, key) => {\n callback(value[$changes], this.indexes[key] ?? key);\n });\n }\n }\n\n operation(op: OPERATION) {\n // operations without index use negative values to represent them\n // this is checked during .encode() time.\n if (this.filteredChanges !== undefined) {\n this.filteredChanges.operations.push(-op);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n this.changes.operations.push(-op);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n change(index: number, operation: OPERATION = OPERATION.ADD) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n\n const isFiltered = this.isFiltered || (metadata?.[index]?.tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousOperation = this.indexedOperations[index];\n if (!previousOperation || previousOperation === OPERATION.DELETE) {\n const op = (!previousOperation)\n ? operation\n : (previousOperation === OPERATION.DELETE)\n ? OPERATION.DELETE_AND_ADD\n : operation\n //\n // TODO: are DELETE operations being encoded as ADD here ??\n //\n this.indexedOperations[index] = op;\n }\n\n setOperationAtIndex(changeSet, index);\n\n if (isFiltered) {\n setOperationAtIndex(this.allFilteredChanges, index);\n\n if (this.root) {\n enqueueChangeTree(this.root, this, 'filteredChanges');\n enqueueChangeTree(this.root, this, 'allFilteredChanges');\n }\n\n } else {\n setOperationAtIndex(this.allChanges, index);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n shiftChangeIndexes(shiftIndex: number) {\n //\n // Used only during:\n //\n // - ArraySchema#unshift()\n //\n const changeSet = (this.isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const newIndexedOperations = {};\n const newIndexes = {};\n for (const index in this.indexedOperations) {\n newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];\n newIndexes[Number(index) + shiftIndex] = changeSet.indexes[index];\n }\n this.indexedOperations = newIndexedOperations;\n changeSet.indexes = newIndexes;\n\n changeSet.operations = changeSet.operations.map((index) => index + shiftIndex);\n }\n\n shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0) {\n //\n // Used only during:\n //\n // - ArraySchema#splice()\n //\n if (this.filteredChanges !== undefined) {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n\n } else {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n }\n }\n\n private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, changeSet: ChangeSet) {\n const newIndexes = {};\n let newKey = 0;\n for (const key in changeSet.indexes) {\n newIndexes[newKey++] = changeSet.indexes[key];\n }\n changeSet.indexes = newIndexes;\n\n for (let i = 0; i < changeSet.operations.length; i++) {\n const index = changeSet.operations[i];\n if (index > startIndex) {\n changeSet.operations[i] = index + shiftIndex;\n }\n }\n }\n\n indexedOperation(index: number, operation: OPERATION, allChangesIndex: number = index) {\n this.indexedOperations[index] = operation;\n\n if (this.filteredChanges !== undefined) {\n setOperationAtIndex(this.allFilteredChanges, allChangesIndex);\n setOperationAtIndex(this.filteredChanges, index);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n setOperationAtIndex(this.allChanges, allChangesIndex);\n setOperationAtIndex(this.changes, index);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n getType(index?: number) {\n if (Metadata.isValidInstance(this.ref)) {\n const metadata = this.ref.constructor[Symbol.metadata] as Metadata;\n return metadata[index].type;\n\n } else {\n //\n // Get the child type from parent structure.\n // - [\"string\"] => \"string\"\n // - { map: \"string\" } => \"string\"\n // - { set: \"string\" } => \"string\"\n //\n return this.ref[$childType];\n }\n }\n\n getChange(index: number) {\n return this.indexedOperations[index];\n }\n\n //\n // used during `.encode()`\n //\n getValue(index: number, isEncodeAll: boolean = false) {\n //\n // `isEncodeAll` param is only used by ArraySchema\n //\n return this.ref[$getByIndex](index, isEncodeAll);\n }\n\n delete(index: number, operation?: OPERATION, allChangesIndex = index) {\n if (index === undefined) {\n try {\n throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n const changeSet = (this.filteredChanges !== undefined)\n ? this.filteredChanges\n : this.changes;\n\n this.indexedOperations[index] = operation ?? OPERATION.DELETE;\n setOperationAtIndex(changeSet, index);\n deleteOperationAtIndex(this.allChanges, allChangesIndex);\n\n const previousValue = this.getValue(index);\n\n // remove `root` reference\n if (previousValue && previousValue[$changes]) {\n //\n // FIXME: this.root is \"undefined\"\n //\n // This method is being called at decoding time when a DELETE operation is found.\n //\n // - This is due to using the concrete Schema class at decoding time.\n // - \"Reflected\" structures do not have this problem.\n //\n // (The property descriptors should NOT be used at decoding time. only at encoding time.)\n //\n this.root?.remove(previousValue[$changes]);\n }\n\n //\n // FIXME: this is looking a ugly and repeated\n //\n if (this.filteredChanges !== undefined) {\n deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n enqueueChangeTree(this.root, this, 'changes');\n }\n\n return previousValue;\n }\n\n endEncode(changeSetName: ChangeSetName) {\n this.indexedOperations = {};\n\n // clear changeset\n this[changeSetName].indexes = {};\n this[changeSetName].operations.length = 0;\n this[changeSetName].queueRootIndex = undefined;\n\n // ArraySchema and MapSchema have a custom \"encode end\" method\n this.ref[$onEncodeEnd]?.();\n\n // Not a new instance anymore\n this.isNew = false;\n }\n\n discard(discardAll: boolean = false) {\n //\n // > MapSchema:\n // Remove cached key to ensure ADD operations is unsed instead of\n // REPLACE in case same key is used on next patches.\n //\n this.ref[$onEncodeEnd]?.();\n\n this.indexedOperations = {};\n\n this.changes.indexes = {};\n this.changes.operations.length = 0;\n this.changes.queueRootIndex = undefined;\n\n if (this.filteredChanges !== undefined) {\n this.filteredChanges.indexes = {};\n this.filteredChanges.operations.length = 0;\n this.filteredChanges.queueRootIndex = undefined;\n }\n\n if (discardAll) {\n this.allChanges.indexes = {};\n this.allChanges.operations.length = 0;\n\n if (this.allFilteredChanges !== undefined) {\n this.allFilteredChanges.indexes = {};\n this.allFilteredChanges.operations.length = 0;\n }\n }\n }\n\n /**\n * Recursively discard all changes from this, and child structures.\n * (Used in tests only)\n */\n discardAll() {\n const keys = Object.keys(this.indexedOperations);\n for (let i = 0, len = keys.length; i < len; i++) {\n const value = this.getValue(Number(keys[i]));\n\n if (value && value[$changes]) {\n value[$changes].discardAll();\n }\n }\n\n this.discard();\n }\n\n ensureRefId() {\n // skip if refId is already set.\n if (this.refId !== undefined) {\n return;\n }\n\n this.refId = this.root.getNextUniqueId();\n }\n\n get changed() {\n return (Object.entries(this.indexedOperations).length > 0);\n }\n\n protected checkIsFiltered(parent: Ref, parentIndex: number) {\n const isNewChangeTree = this.root.add(this);\n\n if (this.root.types.hasFilters) {\n //\n // At Schema initialization, the \"root\" structure might not be available\n // yet, as it only does once the \"Encoder\" has been set up.\n //\n // So the \"parent\" may be already set without a \"root\".\n //\n this._checkFilteredByParent(parent, parentIndex);\n\n if (this.filteredChanges !== undefined) {\n enqueueChangeTree(this.root, this, 'filteredChanges');\n if (isNewChangeTree) {\n this.root.allFilteredChanges.push(this);\n }\n }\n }\n\n if (!this.isFiltered) {\n enqueueChangeTree(this.root, this, 'changes');\n if (isNewChangeTree) {\n this.root.allChanges.push(this);\n }\n }\n }\n\n protected _checkFilteredByParent(parent: Ref, parentIndex: number) {\n // skip if parent is not set\n if (!parent) { return; }\n\n //\n // ArraySchema | MapSchema - get the child type\n // (if refType is typeof string, the parentFiltered[key] below will always be invalid)\n //\n const refType = Metadata.isValidInstance(this.ref)\n ? this.ref.constructor\n : this.ref[$childType];\n\n let parentChangeTree: ChangeTree;\n\n let parentIsCollection = !Metadata.isValidInstance(parent);\n if (parentIsCollection) {\n parentChangeTree = parent[$changes];\n parent = parentChangeTree.parent;\n parentIndex = parentChangeTree.parentIndex;\n\n } else {\n parentChangeTree = parent[$changes]\n }\n\n const parentConstructor = parent.constructor as typeof Schema;\n\n let key = `${this.root.types.getTypeId(refType as typeof Schema)}`;\n if (parentConstructor) {\n key += `-${this.root.types.schemas.get(parentConstructor)}`;\n }\n key += `-${parentIndex}`;\n\n const fieldHasViewTag = Metadata.hasViewTagAtIndex(parentConstructor?.[Symbol.metadata], parentIndex);\n\n this.isFiltered = parent[$changes].isFiltered // in case parent is already filtered\n || this.root.types.parentFiltered[key]\n || fieldHasViewTag;\n\n //\n // \"isFiltered\" may not be imedialely available during `change()` due to the instance not being attached to the root yet.\n // when it's available, we need to enqueue the \"changes\" changeset into the \"filteredChanges\" changeset.\n //\n if (this.isFiltered) {\n\n this.isVisibilitySharedWithParent = (\n parentChangeTree.isFiltered &&\n typeof (refType) !== \"string\" &&\n !fieldHasViewTag &&\n parentIsCollection\n );\n\n if (!this.filteredChanges) {\n this.filteredChanges = createChangeSet();\n this.allFilteredChanges = createChangeSet();\n }\n\n if (this.changes.operations.length > 0) {\n this.changes.operations.forEach((index) =>\n setOperationAtIndex(this.filteredChanges, index));\n\n this.allChanges.operations.forEach((index) =>\n setOperationAtIndex(this.allFilteredChanges, index));\n\n this.changes = createChangeSet();\n this.allChanges = createChangeSet();\n }\n }\n }\n\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ChangeTree.js","sourceRoot":"","sources":["../../src/encoder/ChangeTree.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { Schema } from \"../Schema\";\nimport { $changes, $childType, $decoder, $onEncodeEnd, $encoder, $getByIndex, $refTypeFieldIndexes, $viewFieldIndexes } from \"../types/symbols\";\n\nimport type { MapSchema } from \"../types/custom/MapSchema\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\nimport type { CollectionSchema } from \"../types/custom/CollectionSchema\";\nimport type { SetSchema } from \"../types/custom/SetSchema\";\n\nimport { Root } from \"./Root\";\nimport { Metadata } from \"../Metadata\";\nimport type { EncodeOperation } from \"./EncodeOperation\";\nimport type { DecodeOperation } from \"../decoder/DecodeOperation\";\n\ndeclare global {\n interface Object {\n // FIXME: not a good practice to extend globals here\n [$changes]?: ChangeTree;\n [$encoder]?: EncodeOperation,\n [$decoder]?: DecodeOperation,\n }\n}\n\nexport type Ref = Schema\n | ArraySchema\n | MapSchema\n | CollectionSchema\n | SetSchema;\n\nexport type ChangeSetName = \"changes\"\n | \"allChanges\"\n | \"filteredChanges\"\n | \"allFilteredChanges\";\n\nexport interface IndexedOperations {\n [index: number]: OPERATION;\n}\n\n// Linked list node for change trees\nexport interface ChangeTreeNode {\n changeTree: ChangeTree;\n next?: ChangeTreeNode;\n prev?: ChangeTreeNode;\n}\n\n// Linked list for change trees\nexport interface ChangeTreeList {\n next?: ChangeTreeNode;\n tail?: ChangeTreeNode;\n length: number;\n}\n\nexport interface ChangeSet {\n // field index -> operation index\n indexes: { [index: number]: number };\n operations: number[];\n queueRootNode?: ChangeTreeNode; // direct reference to ChangeTreeNode in the linked list\n}\n\nfunction createChangeSet(): ChangeSet {\n return { indexes: {}, operations: [] };\n}\n\n// Linked list helper functions\nexport function createChangeTreeList(): ChangeTreeList {\n return { next: undefined, tail: undefined, length: 0 };\n}\n\nexport function addToChangeTreeList(list: ChangeTreeList, changeTree: ChangeTree): ChangeTreeNode {\n const node: ChangeTreeNode = { changeTree, next: undefined, prev: undefined };\n\n if (!list.next) {\n list.next = node;\n list.tail = node;\n } else {\n node.prev = list.tail;\n list.tail!.next = node;\n list.tail = node;\n }\n\n list.length++;\n\n return node;\n}\n\nexport function setOperationAtIndex(changeSet: ChangeSet, index: number) {\n const operationsIndex = changeSet.indexes[index];\n if (operationsIndex === undefined) {\n changeSet.indexes[index] = changeSet.operations.push(index) - 1;\n } else {\n changeSet.operations[operationsIndex] = index;\n }\n}\n\nexport function deleteOperationAtIndex(changeSet: ChangeSet, index: number | string) {\n let operationsIndex = changeSet.indexes[index];\n if (operationsIndex === undefined) {\n //\n // if index is not found, we need to find the last operation\n // FIXME: this is not very efficient\n //\n // > See \"should allow consecutive splices (same place)\" tests\n //\n operationsIndex = Object.values(changeSet.indexes).at(-1);\n index = Object.entries(changeSet.indexes).find(([_, value]) => value === operationsIndex)?.[0];\n }\n changeSet.operations[operationsIndex] = undefined;\n delete changeSet.indexes[index];\n}\n\nexport function debugChangeSet(label: string, changeSet: ChangeSet) {\n let indexes: string[] = [];\n let operations: string[] = [];\n\n for (const index in changeSet.indexes) {\n indexes.push(`\\t${index} => [${changeSet.indexes[index]}]`);\n }\n\n for (let i = 0; i < changeSet.operations.length; i++) {\n const index = changeSet.operations[i];\n if (index !== undefined) {\n operations.push(`\\t[${i}] => ${index}`);\n }\n }\n\n console.log(`${label} =>\\nindexes (${Object.keys(changeSet.indexes).length}) {`);\n console.log(indexes.join(\"\\n\"), \"\\n}\");\n console.log(`operations (${changeSet.operations.filter(op => op !== undefined).length}) {`);\n console.log(operations.join(\"\\n\"), \"\\n}\");\n}\n\nexport function enqueueChangeTree(\n root: Root,\n changeTree: ChangeTree,\n changeSet: 'changes' | 'filteredChanges' | 'allFilteredChanges' | 'allChanges',\n queueRootNode = changeTree[changeSet].queueRootNode\n) {\n // skip\n if (!root) { return; }\n\n if (queueRootNode) {\n } else {\n // Add to linked list if not already present\n changeTree[changeSet].queueRootNode = addToChangeTreeList(root[changeSet], changeTree);\n }\n}\n\nexport interface ParentChain {\n ref: Ref;\n index: number;\n next?: ParentChain;\n}\n\nexport class ChangeTree<T extends Ref=any> {\n ref: T;\n refId: number;\n metadata: Metadata;\n\n root?: Root;\n parentChain?: ParentChain; // Linked list for tracking parents\n\n /**\n * Whether this structure is parent of a filtered structure.\n */\n isFiltered: boolean = false;\n isVisibilitySharedWithParent?: boolean; // See test case: 'should not be required to manually call view.add() items to child arrays without @view() tag'\n\n indexedOperations: IndexedOperations = {};\n\n //\n // TODO:\n // try storing the index + operation per item.\n // example: 1024 & 1025 => ADD, 1026 => DELETE\n //\n // => https://chatgpt.com/share/67107d0c-bc20-8004-8583-83b17dd7c196\n //\n changes: ChangeSet = { indexes: {}, operations: [] };\n allChanges: ChangeSet = { indexes: {}, operations: [] };\n filteredChanges: ChangeSet;\n allFilteredChanges: ChangeSet;\n\n indexes: {[index: string]: any}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)\n\n /**\n * Is this a new instance? Used on ArraySchema to determine OPERATION.MOVE_AND_ADD operation.\n */\n isNew = true;\n\n constructor(ref: T) {\n this.ref = ref;\n this.metadata = ref.constructor[Symbol.metadata];\n\n //\n // Does this structure have \"filters\" declared?\n //\n if (this.metadata?.[$viewFieldIndexes]) {\n this.allFilteredChanges = { indexes: {}, operations: [] };\n this.filteredChanges = { indexes: {}, operations: [] };\n }\n }\n\n setRoot(root: Root) {\n this.root = root;\n\n const isNewChangeTree = this.root.add(this);\n\n this.checkIsFiltered(this.parent, this.parentIndex, isNewChangeTree);\n\n // Recursively set root on child structures\n if (isNewChangeTree) {\n this.forEachChild((child, _) => {\n if (child.root !== root) {\n child.setRoot(root);\n } else {\n root.add(child); // increment refCount\n }\n });\n }\n }\n\n setParent(\n parent: Ref,\n root?: Root,\n parentIndex?: number,\n ) {\n this.addParent(parent, parentIndex);\n\n // avoid setting parents with empty `root`\n if (!root) { return; }\n\n const isNewChangeTree = root.add(this);\n\n // skip if parent is already set\n if (root !== this.root) {\n this.root = root;\n this.checkIsFiltered(parent, parentIndex, isNewChangeTree);\n }\n\n // assign same parent on child structures\n if (isNewChangeTree) {\n //\n // assign same parent on child structures\n //\n this.forEachChild((child, index) => {\n if (child.root === root) {\n //\n // re-assigning a child of the same root, move it to the end\n // of the changes queue so encoding order is preserved\n //\n root.moveToEndOfChanges(child);\n return;\n }\n child.setParent(this.ref, root, index);\n });\n }\n }\n\n forEachChild(callback: (change: ChangeTree, at: any) => void) {\n //\n // assign same parent on child structures\n //\n if (this.ref[$childType]) {\n if (typeof(this.ref[$childType]) !== \"string\") {\n // MapSchema / ArraySchema, etc.\n for (const [key, value] of (this.ref as MapSchema).entries()) {\n callback(value[$changes], key);\n };\n }\n\n } else {\n for (const index of this.metadata?.[$refTypeFieldIndexes] ?? []) {\n const field = this.metadata[index as any as number];\n const value = this.ref[field.name];\n if (!value) { continue; }\n callback(value[$changes], index);\n }\n }\n }\n\n operation(op: OPERATION) {\n // operations without index use negative values to represent them\n // this is checked during .encode() time.\n if (this.filteredChanges !== undefined) {\n this.filteredChanges.operations.push(-op);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n this.changes.operations.push(-op);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n change(index: number, operation: OPERATION = OPERATION.ADD) {\n const isFiltered = this.isFiltered || (this.metadata?.[index]?.tag !== undefined);\n const changeSet = (isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const previousOperation = this.indexedOperations[index];\n if (!previousOperation || previousOperation === OPERATION.DELETE) {\n const op = (!previousOperation)\n ? operation\n : (previousOperation === OPERATION.DELETE)\n ? OPERATION.DELETE_AND_ADD\n : operation\n //\n // TODO: are DELETE operations being encoded as ADD here ??\n //\n this.indexedOperations[index] = op;\n }\n\n setOperationAtIndex(changeSet, index);\n\n if (isFiltered) {\n setOperationAtIndex(this.allFilteredChanges, index);\n\n if (this.root) {\n enqueueChangeTree(this.root, this, 'filteredChanges');\n enqueueChangeTree(this.root, this, 'allFilteredChanges');\n }\n\n } else {\n setOperationAtIndex(this.allChanges, index);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n shiftChangeIndexes(shiftIndex: number) {\n //\n // Used only during:\n //\n // - ArraySchema#unshift()\n //\n const changeSet = (this.isFiltered)\n ? this.filteredChanges\n : this.changes;\n\n const newIndexedOperations = {};\n const newIndexes = {};\n for (const index in this.indexedOperations) {\n newIndexedOperations[Number(index) + shiftIndex] = this.indexedOperations[index];\n newIndexes[Number(index) + shiftIndex] = changeSet.indexes[index];\n }\n this.indexedOperations = newIndexedOperations;\n changeSet.indexes = newIndexes;\n\n changeSet.operations = changeSet.operations.map((index) => index + shiftIndex);\n }\n\n shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0) {\n //\n // Used only during:\n //\n // - ArraySchema#splice()\n //\n if (this.filteredChanges !== undefined) {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allFilteredChanges);\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n\n } else {\n this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);\n }\n }\n\n private _shiftAllChangeIndexes(shiftIndex: number, startIndex: number = 0, changeSet: ChangeSet) {\n const newIndexes = {};\n let newKey = 0;\n for (const key in changeSet.indexes) {\n newIndexes[newKey++] = changeSet.indexes[key];\n }\n changeSet.indexes = newIndexes;\n\n for (let i = 0; i < changeSet.operations.length; i++) {\n const index = changeSet.operations[i];\n if (index > startIndex) {\n changeSet.operations[i] = index + shiftIndex;\n }\n }\n }\n\n indexedOperation(index: number, operation: OPERATION, allChangesIndex: number = index) {\n this.indexedOperations[index] = operation;\n\n if (this.filteredChanges !== undefined) {\n setOperationAtIndex(this.allFilteredChanges, allChangesIndex);\n setOperationAtIndex(this.filteredChanges, index);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n setOperationAtIndex(this.allChanges, allChangesIndex);\n setOperationAtIndex(this.changes, index);\n enqueueChangeTree(this.root, this, 'changes');\n }\n }\n\n getType(index?: number) {\n return (\n //\n // Get the child type from parent structure.\n // - [\"string\"] => \"string\"\n // - { map: \"string\" } => \"string\"\n // - { set: \"string\" } => \"string\"\n //\n this.ref[$childType] || // ArraySchema | MapSchema | SetSchema | CollectionSchema\n this.metadata[index].type // Schema\n );\n }\n\n getChange(index: number) {\n return this.indexedOperations[index];\n }\n\n //\n // used during `.encode()`\n //\n getValue(index: number, isEncodeAll: boolean = false) {\n //\n // `isEncodeAll` param is only used by ArraySchema\n //\n return this.ref[$getByIndex](index, isEncodeAll);\n }\n\n delete(index: number, operation?: OPERATION, allChangesIndex = index) {\n if (index === undefined) {\n try {\n throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);\n } catch (e) {\n console.warn(e);\n }\n return;\n }\n\n const changeSet = (this.filteredChanges !== undefined)\n ? this.filteredChanges\n : this.changes;\n\n this.indexedOperations[index] = operation ?? OPERATION.DELETE;\n setOperationAtIndex(changeSet, index);\n deleteOperationAtIndex(this.allChanges, allChangesIndex);\n\n const previousValue = this.getValue(index);\n\n // remove `root` reference\n if (previousValue && previousValue[$changes]) {\n //\n // FIXME: this.root is \"undefined\"\n //\n // This method is being called at decoding time when a DELETE operation is found.\n //\n // - This is due to using the concrete Schema class at decoding time.\n // - \"Reflected\" structures do not have this problem.\n //\n // (The property descriptors should NOT be used at decoding time. only at encoding time.)\n //\n this.root?.remove(previousValue[$changes]);\n }\n\n //\n // FIXME: this is looking a ugly and repeated\n //\n if (this.filteredChanges !== undefined) {\n deleteOperationAtIndex(this.allFilteredChanges, allChangesIndex);\n enqueueChangeTree(this.root, this, 'filteredChanges');\n\n } else {\n enqueueChangeTree(this.root, this, 'changes');\n }\n\n return previousValue;\n }\n\n endEncode(changeSetName: ChangeSetName) {\n this.indexedOperations = {};\n\n // clear changeset\n this[changeSetName] = createChangeSet();\n\n // ArraySchema and MapSchema have a custom \"encode end\" method\n this.ref[$onEncodeEnd]?.();\n\n // Not a new instance anymore\n this.isNew = false;\n }\n\n discard(discardAll: boolean = false) {\n //\n // > MapSchema:\n // Remove cached key to ensure ADD operations is unsed instead of\n // REPLACE in case same key is used on next patches.\n //\n this.ref[$onEncodeEnd]?.();\n\n this.indexedOperations = {};\n this.changes = createChangeSet();\n\n if (this.filteredChanges !== undefined) {\n this.filteredChanges = createChangeSet();\n }\n\n if (discardAll) {\n this.allChanges = createChangeSet();\n\n if (this.allFilteredChanges !== undefined) {\n this.allFilteredChanges = createChangeSet();\n }\n }\n }\n\n /**\n * Recursively discard all changes from this, and child structures.\n * (Used in tests only)\n */\n discardAll() {\n const keys = Object.keys(this.indexedOperations);\n for (let i = 0, len = keys.length; i < len; i++) {\n const value = this.getValue(Number(keys[i]));\n\n if (value && value[$changes]) {\n value[$changes].discardAll();\n }\n }\n\n this.discard();\n }\n\n get changed() {\n return (Object.entries(this.indexedOperations).length > 0);\n }\n\n protected checkIsFiltered(parent: Ref, parentIndex: number, isNewChangeTree: boolean) {\n if (this.root.types.hasFilters) {\n //\n // At Schema initialization, the \"root\" structure might not be available\n // yet, as it only does once the \"Encoder\" has been set up.\n //\n // So the \"parent\" may be already set without a \"root\".\n //\n this._checkFilteredByParent(parent, parentIndex);\n\n if (this.filteredChanges !== undefined) {\n enqueueChangeTree(this.root, this, 'filteredChanges');\n if (isNewChangeTree) {\n enqueueChangeTree(this.root, this, 'allFilteredChanges');\n }\n }\n }\n\n if (!this.isFiltered) {\n enqueueChangeTree(this.root, this, 'changes');\n if (isNewChangeTree) {\n enqueueChangeTree(this.root, this, 'allChanges');\n }\n }\n }\n\n protected _checkFilteredByParent(parent: Ref, parentIndex: number) {\n // skip if parent is not set\n if (!parent) { return; }\n\n //\n // ArraySchema | MapSchema - get the child type\n // (if refType is typeof string, the parentFiltered[key] below will always be invalid)\n //\n const refType = Metadata.isValidInstance(this.ref)\n ? this.ref.constructor\n : this.ref[$childType];\n\n let parentChangeTree: ChangeTree;\n\n let parentIsCollection = !Metadata.isValidInstance(parent);\n if (parentIsCollection) {\n parentChangeTree = parent[$changes];\n parent = parentChangeTree.parent;\n parentIndex = parentChangeTree.parentIndex;\n\n } else {\n parentChangeTree = parent[$changes]\n }\n\n const parentConstructor = parent.constructor as typeof Schema;\n\n let key = `${this.root.types.getTypeId(refType as typeof Schema)}`;\n if (parentConstructor) {\n key += `-${this.root.types.schemas.get(parentConstructor)}`;\n }\n key += `-${parentIndex}`;\n\n const fieldHasViewTag = Metadata.hasViewTagAtIndex(parentConstructor?.[Symbol.metadata], parentIndex);\n\n this.isFiltered = parent[$changes].isFiltered // in case parent is already filtered\n || this.root.types.parentFiltered[key]\n || fieldHasViewTag;\n\n //\n // \"isFiltered\" may not be imedialely available during `change()` due to the instance not being attached to the root yet.\n // when it's available, we need to enqueue the \"changes\" changeset into the \"filteredChanges\" changeset.\n //\n if (this.isFiltered) {\n\n this.isVisibilitySharedWithParent = (\n parentChangeTree.isFiltered &&\n typeof (refType) !== \"string\" &&\n !fieldHasViewTag &&\n parentIsCollection\n );\n\n if (!this.filteredChanges) {\n this.filteredChanges = createChangeSet();\n this.allFilteredChanges = createChangeSet();\n }\n\n if (this.changes.operations.length > 0) {\n this.changes.operations.forEach((index) =>\n setOperationAtIndex(this.filteredChanges, index));\n\n this.allChanges.operations.forEach((index) =>\n setOperationAtIndex(this.allFilteredChanges, index));\n\n this.changes = createChangeSet();\n this.allChanges = createChangeSet();\n }\n }\n }\n\n /**\n * Get the immediate parent\n */\n get parent(): Ref | undefined {\n return this.parentChain?.ref;\n }\n\n /**\n * Get the immediate parent index\n */\n get parentIndex(): number | undefined {\n return this.parentChain?.index;\n }\n\n /**\n * Add a parent to the chain\n */\n addParent(parent: Ref, index: number) {\n // Check if this parent already exists in the chain\n if (this.hasParent((p, i) => p === parent && i === index)) {\n return;\n }\n\n this.parentChain = {\n ref: parent,\n index,\n next: this.parentChain\n };\n }\n\n /**\n * Remove a parent from the chain\n * @param parent - The parent to remove\n * @returns true if parent was removed\n */\n removeParent(parent: Ref): boolean {\n let current = this.parentChain;\n let previous = null;\n while (current) {\n //\n // FIXME: it is required to check against `$changes` here because\n // ArraySchema is instance of Proxy\n //\n if (current.ref[$changes] === parent[$changes]) {\n if (previous) {\n previous.next = current.next;\n } else {\n this.parentChain = current.next;\n }\n return true;\n }\n previous = current;\n current = current.next;\n }\n return this.parentChain === undefined;\n }\n\n /**\n * Find a specific parent in the chain\n */\n findParent(predicate: (parent: Ref, index: number) => boolean): ParentChain | undefined {\n let current = this.parentChain;\n while (current) {\n if (predicate(current.ref, current.index)) {\n return current;\n }\n current = current.next;\n }\n return undefined;\n }\n\n /**\n * Check if this ChangeTree has a specific parent\n */\n hasParent(predicate: (parent: Ref, index: number) => boolean): boolean {\n return this.findParent(predicate) !== undefined;\n }\n\n /**\n * Get all parents as an array (for debugging/testing)\n */\n getAllParents(): Array<{ref: Ref, index: number}> {\n const parents: Array<{ref: Ref, index: number}> = [];\n let current = this.parentChain;\n while (current) {\n parents.push({ref: current.ref, index: current.index});\n current = current.next;\n }\n return parents;\n }\n\n}"]}
|