@colyseus/schema 3.0.0-alpha.0 → 3.0.0-alpha.2
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 +1181 -1390
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +35 -15
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +1181 -1390
- package/lib/encoder/ChangeTree.d.ts +0 -2
- package/lib/encoder/ChangeTree.js +0 -1
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +4 -5
- package/lib/encoder/Encoder.js +14 -14
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/StateView.d.ts +2 -0
- package/lib/encoder/StateView.js +4 -1
- package/lib/encoder/StateView.js.map +1 -1
- package/lib/encoding/encode.d.ts +18 -16
- package/lib/encoding/encode.js +2 -1
- package/lib/encoding/encode.js.map +1 -1
- package/package.json +1 -1
- package/src/encoder/ChangeTree.ts +0 -2
- package/src/encoder/Encoder.ts +17 -18
- package/src/encoder/StateView.ts +4 -0
- package/src/encoding/encode.ts +19 -16
package/build/umd/index.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.schema = {}));
|
|
5
5
|
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)
|
|
8
|
+
const TYPE_ID = 213;
|
|
9
9
|
/**
|
|
10
10
|
* Encoding Schema field operations.
|
|
11
11
|
*/
|
|
@@ -31,95 +31,40 @@
|
|
|
31
31
|
OPERATION[OPERATION["DELETE_BY_REFID"] = 33] = "DELETE_BY_REFID";
|
|
32
32
|
})(exports.OPERATION || (exports.OPERATION = {}));
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
Copyright (c) Microsoft Corporation.
|
|
36
|
-
|
|
37
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
38
|
-
purpose with or without fee is hereby granted.
|
|
39
|
-
|
|
40
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
41
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
42
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
43
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
44
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
45
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
46
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
47
|
-
***************************************************************************** */
|
|
48
|
-
/* global Reflect, Promise, SuppressedError, Symbol */
|
|
49
|
-
|
|
50
|
-
var extendStatics = function(d, b) {
|
|
51
|
-
extendStatics = Object.setPrototypeOf ||
|
|
52
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
53
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
54
|
-
return extendStatics(d, b);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
function __extends(d, b) {
|
|
58
|
-
if (typeof b !== "function" && b !== null)
|
|
59
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
60
|
-
extendStatics(d, b);
|
|
61
|
-
function __() { this.constructor = d; }
|
|
62
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function __decorate(decorators, target, key, desc) {
|
|
66
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
67
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
68
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
69
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function __spreadArray(to, from, pack) {
|
|
73
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
74
|
-
if (ar || !(i in from)) {
|
|
75
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
76
|
-
ar[i] = from[i];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
83
|
-
var e = new Error(message);
|
|
84
|
-
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
var _a$1;
|
|
88
|
-
var _b;
|
|
89
|
-
(_a$1 = (_b = Symbol).metadata) !== null && _a$1 !== void 0 ? _a$1 : (_b.metadata = Symbol.for("Symbol.metadata"));
|
|
34
|
+
Symbol.metadata ??= Symbol.for("Symbol.metadata");
|
|
90
35
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
36
|
+
const $track = Symbol("$track");
|
|
37
|
+
const $encoder = Symbol("$encoder");
|
|
38
|
+
const $decoder = Symbol("$decoder");
|
|
39
|
+
const $filter = Symbol("$filter");
|
|
40
|
+
const $getByIndex = Symbol("$getByIndex");
|
|
41
|
+
const $deleteByIndex = Symbol("$deleteByIndex");
|
|
97
42
|
/**
|
|
98
43
|
* Used to hold ChangeTree instances whitin the structures
|
|
99
44
|
*/
|
|
100
|
-
|
|
45
|
+
const $changes = Symbol('$changes');
|
|
101
46
|
/**
|
|
102
47
|
* Used to keep track of the type of the child elements of a collection
|
|
103
48
|
* (MapSchema, ArraySchema, etc.)
|
|
104
49
|
*/
|
|
105
|
-
|
|
50
|
+
const $childType = Symbol('$childType');
|
|
106
51
|
/**
|
|
107
52
|
* Special ChangeTree property to identify new instances
|
|
108
53
|
* (Once they're encoded, they're not new anymore)
|
|
109
54
|
*/
|
|
110
|
-
|
|
55
|
+
const $isNew = Symbol("$isNew");
|
|
111
56
|
/**
|
|
112
57
|
* Optional "discard" method for custom types (ArraySchema)
|
|
113
58
|
* (Discards changes for next serialization)
|
|
114
59
|
*/
|
|
115
|
-
|
|
60
|
+
const $onEncodeEnd = Symbol('$onEncodeEnd');
|
|
116
61
|
/**
|
|
117
62
|
* When decoding, this method is called after the instance is fully decoded
|
|
118
63
|
*/
|
|
119
|
-
|
|
64
|
+
const $onDecodeEnd = Symbol("$onDecodeEnd");
|
|
120
65
|
|
|
121
|
-
|
|
122
|
-
|
|
66
|
+
const registeredTypes = {};
|
|
67
|
+
const identifiers = new Map();
|
|
123
68
|
function registerType(identifier, definition) {
|
|
124
69
|
identifiers.set(definition.constructor, identifier);
|
|
125
70
|
registeredTypes[identifier] = definition;
|
|
@@ -128,18 +73,18 @@
|
|
|
128
73
|
return registeredTypes[identifier];
|
|
129
74
|
}
|
|
130
75
|
|
|
131
|
-
|
|
132
|
-
addField
|
|
76
|
+
const Metadata = {
|
|
77
|
+
addField(metadata, index, field, type, descriptor) {
|
|
133
78
|
if (index > 64) {
|
|
134
|
-
throw new Error(
|
|
79
|
+
throw new Error(`Can't define field '${field}'.\nSchema instances may only have up to 64 fields.`);
|
|
135
80
|
}
|
|
136
81
|
metadata[field] = Object.assign(metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
|
|
137
82
|
{
|
|
138
83
|
type: (Array.isArray(type))
|
|
139
84
|
? { array: type[0] }
|
|
140
85
|
: type,
|
|
141
|
-
index
|
|
142
|
-
descriptor
|
|
86
|
+
index,
|
|
87
|
+
descriptor,
|
|
143
88
|
});
|
|
144
89
|
// map -1 as last field index
|
|
145
90
|
Object.defineProperty(metadata, -1, {
|
|
@@ -154,9 +99,9 @@
|
|
|
154
99
|
configurable: true,
|
|
155
100
|
});
|
|
156
101
|
},
|
|
157
|
-
setTag
|
|
102
|
+
setTag(metadata, fieldName, tag) {
|
|
158
103
|
// add 'tag' to the field
|
|
159
|
-
|
|
104
|
+
const field = metadata[fieldName];
|
|
160
105
|
field.tag = tag;
|
|
161
106
|
if (!metadata[-2]) {
|
|
162
107
|
// -2: all field indexes with "view" tag
|
|
@@ -178,47 +123,45 @@
|
|
|
178
123
|
}
|
|
179
124
|
metadata[-3][tag].push(field.index);
|
|
180
125
|
},
|
|
181
|
-
setFields
|
|
182
|
-
|
|
183
|
-
var _b, _c;
|
|
184
|
-
var metadata = ((_a = (_b = target.prototype.constructor)[_c = Symbol.metadata]) !== null && _a !== void 0 ? _a : (_b[_c] = {}));
|
|
126
|
+
setFields(target, fields) {
|
|
127
|
+
const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});
|
|
185
128
|
// target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {
|
|
186
129
|
// changeTree.change(index, operation, encodeSchemaOperation);
|
|
187
130
|
// };
|
|
188
131
|
// target[$encoder] = encodeSchemaOperation;
|
|
189
132
|
// target[$decoder] = decodeSchemaOperation;
|
|
190
133
|
// if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }
|
|
191
|
-
|
|
192
|
-
for (
|
|
193
|
-
|
|
134
|
+
let index = 0;
|
|
135
|
+
for (const field in fields) {
|
|
136
|
+
const type = fields[field];
|
|
194
137
|
// FIXME: this code is duplicated from @type() annotation
|
|
195
|
-
|
|
138
|
+
const complexTypeKlass = (Array.isArray(type))
|
|
196
139
|
? getType("array")
|
|
197
140
|
: (typeof (Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
|
|
198
|
-
Metadata.addField(metadata, index, field, type, getPropertyDescriptor(
|
|
141
|
+
Metadata.addField(metadata, index, field, type, getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass, metadata, field));
|
|
199
142
|
index++;
|
|
200
143
|
}
|
|
201
144
|
},
|
|
202
|
-
isDeprecated
|
|
145
|
+
isDeprecated(metadata, field) {
|
|
203
146
|
return metadata[field].deprecated === true;
|
|
204
147
|
},
|
|
205
|
-
isValidInstance
|
|
148
|
+
isValidInstance(klass) {
|
|
206
149
|
return (klass.constructor[Symbol.metadata] &&
|
|
207
150
|
Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1));
|
|
208
151
|
},
|
|
209
|
-
getFields
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
for (
|
|
152
|
+
getFields(klass) {
|
|
153
|
+
const metadata = klass[Symbol.metadata];
|
|
154
|
+
const fields = {};
|
|
155
|
+
for (let i = 0; i <= metadata[-1]; i++) {
|
|
213
156
|
fields[metadata[i]] = metadata[metadata[i]].type;
|
|
214
157
|
}
|
|
215
158
|
return fields;
|
|
216
159
|
}
|
|
217
160
|
};
|
|
218
161
|
|
|
219
|
-
var _a;
|
|
220
|
-
|
|
221
|
-
|
|
162
|
+
var _a$5;
|
|
163
|
+
class Root {
|
|
164
|
+
constructor() {
|
|
222
165
|
this.nextUniqueId = 0;
|
|
223
166
|
this.refCount = new WeakMap();
|
|
224
167
|
// all changes
|
|
@@ -227,18 +170,16 @@
|
|
|
227
170
|
// pending changes to be encoded
|
|
228
171
|
this.changes = new Map();
|
|
229
172
|
this.filteredChanges = new Map();
|
|
230
|
-
this.views = [];
|
|
231
173
|
}
|
|
232
|
-
|
|
174
|
+
getNextUniqueId() {
|
|
233
175
|
return this.nextUniqueId++;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
|
|
176
|
+
}
|
|
177
|
+
add(changeTree) {
|
|
178
|
+
const refCount = this.refCount.get(changeTree) || 0;
|
|
237
179
|
this.refCount.set(changeTree, refCount + 1);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
var refCount = this.refCount.get(changeTree);
|
|
180
|
+
}
|
|
181
|
+
remove(changeTree) {
|
|
182
|
+
const refCount = this.refCount.get(changeTree);
|
|
242
183
|
if (refCount <= 1) {
|
|
243
184
|
this.allChanges.delete(changeTree);
|
|
244
185
|
this.changes.delete(changeTree);
|
|
@@ -251,27 +192,26 @@
|
|
|
251
192
|
else {
|
|
252
193
|
this.refCount.set(changeTree, refCount - 1);
|
|
253
194
|
}
|
|
254
|
-
changeTree.forEachChild(
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
};
|
|
258
|
-
Root.prototype.clear = function () {
|
|
195
|
+
changeTree.forEachChild((child, _) => this.remove(child));
|
|
196
|
+
}
|
|
197
|
+
clear() {
|
|
259
198
|
this.changes.clear();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
class ChangeTree {
|
|
202
|
+
static { _a$5 = $isNew; }
|
|
203
|
+
;
|
|
204
|
+
constructor(ref) {
|
|
265
205
|
this.indexes = {}; // TODO: remove this, only used by MapSchema/SetSchema/CollectionSchema (`encodeKeyValueOperation`)
|
|
266
206
|
this.currentOperationIndex = 0;
|
|
267
207
|
this.allChanges = new Map();
|
|
268
208
|
this.allFilteredChanges = new Map();
|
|
269
209
|
this.changes = new Map();
|
|
270
210
|
this.filteredChanges = new Map();
|
|
271
|
-
this[_a] = true;
|
|
211
|
+
this[_a$5] = true;
|
|
272
212
|
this.ref = ref;
|
|
273
213
|
}
|
|
274
|
-
|
|
214
|
+
setRoot(root) {
|
|
275
215
|
this.root = root;
|
|
276
216
|
this.root.add(this);
|
|
277
217
|
//
|
|
@@ -295,7 +235,7 @@
|
|
|
295
235
|
if (!this.isFiltered) {
|
|
296
236
|
this.root.allChanges.set(this, this.allChanges);
|
|
297
237
|
}
|
|
298
|
-
this.forEachChild(
|
|
238
|
+
this.forEachChild((changeTree, _) => {
|
|
299
239
|
changeTree.setRoot(root);
|
|
300
240
|
});
|
|
301
241
|
// this.allChanges.forEach((_, index) => {
|
|
@@ -304,9 +244,8 @@
|
|
|
304
244
|
// childRef[$changes].setRoot(root);
|
|
305
245
|
// }
|
|
306
246
|
// });
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
var _this = this;
|
|
247
|
+
}
|
|
248
|
+
setParent(parent, root, parentIndex) {
|
|
310
249
|
this.parent = parent;
|
|
311
250
|
this.parentIndex = parentIndex;
|
|
312
251
|
// avoid setting parents with empty `root`
|
|
@@ -316,8 +255,8 @@
|
|
|
316
255
|
root.add(this);
|
|
317
256
|
// skip if parent is already set
|
|
318
257
|
if (root === this.root) {
|
|
319
|
-
this.forEachChild(
|
|
320
|
-
changeTree.setParent(
|
|
258
|
+
this.forEachChild((changeTree, atIndex) => {
|
|
259
|
+
changeTree.setParent(this.ref, root, atIndex);
|
|
321
260
|
});
|
|
322
261
|
return;
|
|
323
262
|
}
|
|
@@ -334,20 +273,19 @@
|
|
|
334
273
|
this.root.allChanges.set(this, this.allChanges);
|
|
335
274
|
}
|
|
336
275
|
this.ensureRefId();
|
|
337
|
-
this.forEachChild(
|
|
338
|
-
changeTree.setParent(
|
|
276
|
+
this.forEachChild((changeTree, atIndex) => {
|
|
277
|
+
changeTree.setParent(this.ref, root, atIndex);
|
|
339
278
|
});
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
var _this = this;
|
|
279
|
+
}
|
|
280
|
+
forEachChild(callback) {
|
|
343
281
|
//
|
|
344
282
|
// assign same parent on child structures
|
|
345
283
|
//
|
|
346
284
|
if (Metadata.isValidInstance(this.ref)) {
|
|
347
|
-
|
|
285
|
+
const metadata = this.ref['constructor'][Symbol.metadata];
|
|
348
286
|
// FIXME: need to iterate over parent metadata instead.
|
|
349
|
-
for (
|
|
350
|
-
|
|
287
|
+
for (const field in metadata) {
|
|
288
|
+
const value = this.ref[field];
|
|
351
289
|
if (value && value[$changes]) {
|
|
352
290
|
callback(value[$changes], metadata[field].index);
|
|
353
291
|
}
|
|
@@ -355,29 +293,26 @@
|
|
|
355
293
|
}
|
|
356
294
|
else if (typeof (this.ref) === "object") {
|
|
357
295
|
// MapSchema / ArraySchema, etc.
|
|
358
|
-
this.ref.forEach(
|
|
296
|
+
this.ref.forEach((value, key) => {
|
|
359
297
|
if (Metadata.isValidInstance(value)) {
|
|
360
|
-
callback(value[$changes],
|
|
298
|
+
callback(value[$changes], this.ref[$changes].indexes[key]);
|
|
361
299
|
}
|
|
362
300
|
});
|
|
363
301
|
}
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
var _b;
|
|
302
|
+
}
|
|
303
|
+
operation(op) {
|
|
367
304
|
this.changes.set(--this.currentOperationIndex, op);
|
|
368
|
-
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
var isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
375
|
-
var changeSet = (isFiltered)
|
|
305
|
+
this.root?.changes.set(this, this.changes);
|
|
306
|
+
}
|
|
307
|
+
change(index, operation = exports.OPERATION.ADD) {
|
|
308
|
+
const metadata = this.ref['constructor'][Symbol.metadata];
|
|
309
|
+
const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
310
|
+
const changeSet = (isFiltered)
|
|
376
311
|
? this.filteredChanges
|
|
377
312
|
: this.changes;
|
|
378
|
-
|
|
313
|
+
const previousOperation = changeSet.get(index);
|
|
379
314
|
if (!previousOperation || previousOperation === exports.OPERATION.DELETE) {
|
|
380
|
-
|
|
315
|
+
const op = (!previousOperation)
|
|
381
316
|
? operation
|
|
382
317
|
: (previousOperation === exports.OPERATION.DELETE)
|
|
383
318
|
? exports.OPERATION.DELETE_AND_ADD
|
|
@@ -389,32 +324,30 @@
|
|
|
389
324
|
//
|
|
390
325
|
if (isFiltered) {
|
|
391
326
|
this.allFilteredChanges.set(index, exports.OPERATION.ADD);
|
|
392
|
-
|
|
327
|
+
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
393
328
|
}
|
|
394
329
|
else {
|
|
395
330
|
this.allChanges.set(index, exports.OPERATION.ADD);
|
|
396
|
-
|
|
331
|
+
this.root?.changes.set(this, this.changes);
|
|
397
332
|
}
|
|
398
|
-
}
|
|
399
|
-
|
|
333
|
+
}
|
|
334
|
+
shiftChangeIndexes(shiftIndex) {
|
|
400
335
|
//
|
|
401
336
|
// Used only during:
|
|
402
337
|
//
|
|
403
338
|
// - ArraySchema#unshift()
|
|
404
339
|
//
|
|
405
|
-
|
|
340
|
+
const changeSet = (this.isFiltered)
|
|
406
341
|
? this.filteredChanges
|
|
407
342
|
: this.changes;
|
|
408
|
-
|
|
343
|
+
const changeSetEntries = Array.from(changeSet.entries());
|
|
409
344
|
changeSet.clear();
|
|
410
345
|
// Re-insert each entry with the shifted index
|
|
411
|
-
for (
|
|
412
|
-
var _b = changeSetEntries_1[_i], index = _b[0], op = _b[1];
|
|
346
|
+
for (const [index, op] of changeSetEntries) {
|
|
413
347
|
changeSet.set(index + shiftIndex, op);
|
|
414
348
|
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
if (startIndex === void 0) { startIndex = 0; }
|
|
349
|
+
}
|
|
350
|
+
shiftAllChangeIndexes(shiftIndex, startIndex = 0) {
|
|
418
351
|
//
|
|
419
352
|
// Used only during:
|
|
420
353
|
//
|
|
@@ -427,37 +360,33 @@
|
|
|
427
360
|
else {
|
|
428
361
|
this._shiftAllChangeIndexes(shiftIndex, startIndex, this.allChanges);
|
|
429
362
|
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
Array.from(allChangeSet.entries()).forEach(function (_b) {
|
|
434
|
-
var index = _b[0], op = _b[1];
|
|
363
|
+
}
|
|
364
|
+
_shiftAllChangeIndexes(shiftIndex, startIndex = 0, allChangeSet) {
|
|
365
|
+
Array.from(allChangeSet.entries()).forEach(([index, op]) => {
|
|
435
366
|
// console.log('shiftAllChangeIndexes', index >= startIndex, { index, op, shiftIndex, startIndex })
|
|
436
367
|
if (index >= startIndex) {
|
|
437
368
|
allChangeSet.delete(index);
|
|
438
369
|
allChangeSet.set(index + shiftIndex, op);
|
|
439
370
|
}
|
|
440
371
|
});
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
var metadata = this.ref['constructor'][Symbol.metadata];
|
|
446
|
-
var isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
372
|
+
}
|
|
373
|
+
indexedOperation(index, operation, allChangesIndex = index) {
|
|
374
|
+
const metadata = this.ref['constructor'][Symbol.metadata];
|
|
375
|
+
const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
447
376
|
if (isFiltered) {
|
|
448
377
|
this.allFilteredChanges.set(allChangesIndex, exports.OPERATION.ADD);
|
|
449
378
|
this.filteredChanges.set(index, operation);
|
|
450
|
-
|
|
379
|
+
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
451
380
|
}
|
|
452
381
|
else {
|
|
453
382
|
this.allChanges.set(allChangesIndex, exports.OPERATION.ADD);
|
|
454
383
|
this.changes.set(index, operation);
|
|
455
|
-
|
|
384
|
+
this.root?.changes.set(this, this.changes);
|
|
456
385
|
}
|
|
457
|
-
}
|
|
458
|
-
|
|
386
|
+
}
|
|
387
|
+
getType(index) {
|
|
459
388
|
if (Metadata.isValidInstance(this.ref)) {
|
|
460
|
-
|
|
389
|
+
const metadata = this.ref['constructor'][Symbol.metadata];
|
|
461
390
|
return metadata[metadata[index]].type;
|
|
462
391
|
}
|
|
463
392
|
else {
|
|
@@ -469,41 +398,37 @@
|
|
|
469
398
|
//
|
|
470
399
|
return this.ref[$childType];
|
|
471
400
|
}
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
var _b;
|
|
401
|
+
}
|
|
402
|
+
getChange(index) {
|
|
475
403
|
// TODO: optimize this. avoid checking against multiple instances
|
|
476
|
-
return
|
|
477
|
-
}
|
|
404
|
+
return this.changes.get(index) ?? this.filteredChanges.get(index);
|
|
405
|
+
}
|
|
478
406
|
//
|
|
479
407
|
// used during `.encode()`
|
|
480
408
|
//
|
|
481
|
-
|
|
482
|
-
if (isEncodeAll === void 0) { isEncodeAll = false; }
|
|
409
|
+
getValue(index, isEncodeAll = false) {
|
|
483
410
|
//
|
|
484
411
|
// `isEncodeAll` param is only used by ArraySchema
|
|
485
412
|
//
|
|
486
413
|
return this.ref[$getByIndex](index, isEncodeAll);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
var _b, _c, _d;
|
|
490
|
-
if (allChangesIndex === void 0) { allChangesIndex = index; }
|
|
414
|
+
}
|
|
415
|
+
delete(index, operation, allChangesIndex = index) {
|
|
491
416
|
if (index === undefined) {
|
|
492
417
|
try {
|
|
493
|
-
throw new Error(
|
|
418
|
+
throw new Error(`@colyseus/schema ${this.ref.constructor.name}: trying to delete non-existing index '${index}'`);
|
|
494
419
|
}
|
|
495
420
|
catch (e) {
|
|
496
421
|
console.warn(e);
|
|
497
422
|
}
|
|
498
423
|
return;
|
|
499
424
|
}
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
425
|
+
const metadata = this.ref['constructor'][Symbol.metadata];
|
|
426
|
+
const isFiltered = this.isFiltered || (metadata && metadata[metadata[index]].tag !== undefined);
|
|
427
|
+
const changeSet = (isFiltered)
|
|
503
428
|
? this.filteredChanges
|
|
504
429
|
: this.changes;
|
|
505
|
-
|
|
506
|
-
changeSet.set(index, operation
|
|
430
|
+
const previousValue = this.getValue(index);
|
|
431
|
+
changeSet.set(index, operation ?? exports.OPERATION.DELETE);
|
|
507
432
|
// remove `root` reference
|
|
508
433
|
if (previousValue && previousValue[$changes]) {
|
|
509
434
|
previousValue[$changes].root = undefined;
|
|
@@ -517,37 +442,33 @@
|
|
|
517
442
|
//
|
|
518
443
|
// (the property descriptors should NOT be used at decoding time. only at encoding time.)
|
|
519
444
|
//
|
|
520
|
-
|
|
445
|
+
this.root?.remove(previousValue[$changes]);
|
|
521
446
|
}
|
|
522
447
|
//
|
|
523
448
|
// FIXME: this is looking a bit ugly (and repeated from `.change()`)
|
|
524
449
|
//
|
|
525
450
|
if (isFiltered) {
|
|
526
|
-
|
|
451
|
+
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
527
452
|
this.allFilteredChanges.delete(allChangesIndex);
|
|
528
453
|
}
|
|
529
454
|
else {
|
|
530
|
-
|
|
455
|
+
this.root?.changes.set(this, this.changes);
|
|
531
456
|
this.allChanges.delete(allChangesIndex);
|
|
532
457
|
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
var _b, _c;
|
|
458
|
+
}
|
|
459
|
+
endEncode() {
|
|
536
460
|
this.changes.clear();
|
|
537
|
-
|
|
461
|
+
this.ref[$onEncodeEnd]?.();
|
|
538
462
|
// Not a new instance anymore
|
|
539
463
|
delete this[$isNew];
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
var _this = this;
|
|
543
|
-
var _b, _c;
|
|
544
|
-
if (discardAll === void 0) { discardAll = false; }
|
|
464
|
+
}
|
|
465
|
+
discard(discardAll = false) {
|
|
545
466
|
//
|
|
546
467
|
// > MapSchema:
|
|
547
468
|
// Remove cached key to ensure ADD operations is unsed instead of
|
|
548
469
|
// REPLACE in case same key is used on next patches.
|
|
549
470
|
//
|
|
550
|
-
|
|
471
|
+
this.ref[$onEncodeEnd]?.();
|
|
551
472
|
this.changes.clear();
|
|
552
473
|
this.filteredChanges.clear();
|
|
553
474
|
// reset operation index
|
|
@@ -556,46 +477,40 @@
|
|
|
556
477
|
this.allChanges.clear();
|
|
557
478
|
this.allFilteredChanges.clear();
|
|
558
479
|
// remove children references
|
|
559
|
-
this.forEachChild(
|
|
480
|
+
this.forEachChild((changeTree, _) => this.root?.remove(changeTree));
|
|
560
481
|
}
|
|
561
|
-
}
|
|
482
|
+
}
|
|
562
483
|
/**
|
|
563
484
|
* Recursively discard all changes from this, and child structures.
|
|
564
485
|
*/
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
var value = _this.getValue(fieldIndex);
|
|
486
|
+
discardAll() {
|
|
487
|
+
this.changes.forEach((_, fieldIndex) => {
|
|
488
|
+
const value = this.getValue(fieldIndex);
|
|
569
489
|
if (value && value[$changes]) {
|
|
570
490
|
value[$changes].discardAll();
|
|
571
491
|
}
|
|
572
492
|
});
|
|
573
493
|
this.discard();
|
|
574
|
-
}
|
|
575
|
-
|
|
494
|
+
}
|
|
495
|
+
ensureRefId() {
|
|
576
496
|
// skip if refId is already set.
|
|
577
497
|
if (this.refId !== undefined) {
|
|
578
498
|
return;
|
|
579
499
|
}
|
|
580
500
|
this.refId = this.root.getNextUniqueId();
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
enumerable: false,
|
|
587
|
-
configurable: true
|
|
588
|
-
});
|
|
589
|
-
ChangeTree.prototype.checkIsFiltered = function (parent, parentIndex) {
|
|
590
|
-
var _b, _c, _d;
|
|
501
|
+
}
|
|
502
|
+
get changed() {
|
|
503
|
+
return this.changes.size > 0;
|
|
504
|
+
}
|
|
505
|
+
checkIsFiltered(parent, parentIndex) {
|
|
591
506
|
// Detect if current structure has "filters" declared
|
|
592
|
-
this.isPartiallyFiltered =
|
|
507
|
+
this.isPartiallyFiltered = this.ref['constructor']?.[Symbol.metadata]?.[-2];
|
|
593
508
|
// TODO: support "partially filtered", where the instance is visible, but only a field is not.
|
|
594
509
|
// Detect if parent has "filters" declared
|
|
595
510
|
while (parent && !this.isFiltered) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
511
|
+
const metadata = parent['constructor'][Symbol.metadata];
|
|
512
|
+
const fieldName = metadata?.[parentIndex];
|
|
513
|
+
const isParentOwned = metadata?.[fieldName]?.tag !== undefined;
|
|
599
514
|
this.isFiltered = isParentOwned || parent[$changes].isFiltered; // metadata?.[-2]
|
|
600
515
|
parent = parent[$changes].parent;
|
|
601
516
|
}
|
|
@@ -607,18 +522,16 @@
|
|
|
607
522
|
//
|
|
608
523
|
if (this.isFiltered && this.changes.size > 0) {
|
|
609
524
|
// swap changes reference
|
|
610
|
-
|
|
525
|
+
const changes = this.changes;
|
|
611
526
|
this.changes = this.filteredChanges;
|
|
612
527
|
this.filteredChanges = changes;
|
|
613
528
|
// swap "all changes" reference
|
|
614
|
-
|
|
529
|
+
const allFilteredChanges = this.allFilteredChanges;
|
|
615
530
|
this.allFilteredChanges = this.allChanges;
|
|
616
531
|
this.allChanges = allFilteredChanges;
|
|
617
532
|
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
}());
|
|
621
|
-
_a = $isNew;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
622
535
|
|
|
623
536
|
/**
|
|
624
537
|
* Copyright (c) 2018 Endel Dreyer
|
|
@@ -646,12 +559,32 @@
|
|
|
646
559
|
* msgpack implementation highly based on notepack.io
|
|
647
560
|
* https://github.com/darrachequesne/notepack
|
|
648
561
|
*/
|
|
649
|
-
|
|
562
|
+
let textEncoder;
|
|
650
563
|
// @ts-ignore
|
|
651
564
|
try {
|
|
652
565
|
textEncoder = new TextEncoder();
|
|
653
566
|
}
|
|
654
567
|
catch (e) { }
|
|
568
|
+
function utf8Length(str) {
|
|
569
|
+
var c = 0, length = 0;
|
|
570
|
+
for (var i = 0, l = str.length; i < l; i++) {
|
|
571
|
+
c = str.charCodeAt(i);
|
|
572
|
+
if (c < 0x80) {
|
|
573
|
+
length += 1;
|
|
574
|
+
}
|
|
575
|
+
else if (c < 0x800) {
|
|
576
|
+
length += 2;
|
|
577
|
+
}
|
|
578
|
+
else if (c < 0xd800 || c >= 0xe000) {
|
|
579
|
+
length += 3;
|
|
580
|
+
}
|
|
581
|
+
else {
|
|
582
|
+
i++;
|
|
583
|
+
length += 4;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return length;
|
|
587
|
+
}
|
|
655
588
|
function utf8Write(view, str, it) {
|
|
656
589
|
var c = 0;
|
|
657
590
|
for (var i = 0, l = str.length; i < l; i++) {
|
|
@@ -699,24 +632,24 @@
|
|
|
699
632
|
bytes[it.offset++] = (value >> 24) & 255;
|
|
700
633
|
}
|
|
701
634
|
function uint32$1(bytes, value, it) {
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
635
|
+
const b4 = value >> 24;
|
|
636
|
+
const b3 = value >> 16;
|
|
637
|
+
const b2 = value >> 8;
|
|
638
|
+
const b1 = value;
|
|
706
639
|
bytes[it.offset++] = b1 & 255;
|
|
707
640
|
bytes[it.offset++] = b2 & 255;
|
|
708
641
|
bytes[it.offset++] = b3 & 255;
|
|
709
642
|
bytes[it.offset++] = b4 & 255;
|
|
710
643
|
}
|
|
711
644
|
function int64$1(bytes, value, it) {
|
|
712
|
-
|
|
713
|
-
|
|
645
|
+
const high = Math.floor(value / Math.pow(2, 32));
|
|
646
|
+
const low = value >>> 0;
|
|
714
647
|
uint32$1(bytes, low, it);
|
|
715
648
|
uint32$1(bytes, high, it);
|
|
716
649
|
}
|
|
717
650
|
function uint64$1(bytes, value, it) {
|
|
718
|
-
|
|
719
|
-
|
|
651
|
+
const high = (value / Math.pow(2, 32)) >> 0;
|
|
652
|
+
const low = value >>> 0;
|
|
720
653
|
uint32$1(bytes, low, it);
|
|
721
654
|
uint32$1(bytes, high, it);
|
|
722
655
|
}
|
|
@@ -726,9 +659,9 @@
|
|
|
726
659
|
function float64$1(bytes, value, it) {
|
|
727
660
|
writeFloat64(bytes, value, it);
|
|
728
661
|
}
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
662
|
+
const _int32$1 = new Int32Array(2);
|
|
663
|
+
const _float32$1 = new Float32Array(_int32$1.buffer);
|
|
664
|
+
const _float64$1 = new Float64Array(_int32$1.buffer);
|
|
732
665
|
function writeFloat32(bytes, value, it) {
|
|
733
666
|
_float32$1[0] = value;
|
|
734
667
|
int32$1(bytes, _int32$1[0], it);
|
|
@@ -747,8 +680,8 @@
|
|
|
747
680
|
value = "";
|
|
748
681
|
}
|
|
749
682
|
// let length = utf8Length(value);
|
|
750
|
-
|
|
751
|
-
|
|
683
|
+
let length = Buffer.byteLength(value, "utf8");
|
|
684
|
+
let size = 0;
|
|
752
685
|
// fixstr
|
|
753
686
|
if (length < 0x20) {
|
|
754
687
|
bytes[it.offset++] = length | 0xa0;
|
|
@@ -858,6 +791,7 @@
|
|
|
858
791
|
|
|
859
792
|
var encode = /*#__PURE__*/Object.freeze({
|
|
860
793
|
__proto__: null,
|
|
794
|
+
utf8Length: utf8Length,
|
|
861
795
|
utf8Write: utf8Write,
|
|
862
796
|
int8: int8$1,
|
|
863
797
|
uint8: uint8$1,
|
|
@@ -876,16 +810,11 @@
|
|
|
876
810
|
number: number$1
|
|
877
811
|
});
|
|
878
812
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
function EncodeSchemaError() {
|
|
882
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
883
|
-
}
|
|
884
|
-
return EncodeSchemaError;
|
|
885
|
-
}(Error));
|
|
813
|
+
class EncodeSchemaError extends Error {
|
|
814
|
+
}
|
|
886
815
|
function assertType(value, type, klass, field) {
|
|
887
|
-
|
|
888
|
-
|
|
816
|
+
let typeofTarget;
|
|
817
|
+
let allowNull = false;
|
|
889
818
|
switch (type) {
|
|
890
819
|
case "number":
|
|
891
820
|
case "int8":
|
|
@@ -900,7 +829,7 @@
|
|
|
900
829
|
case "float64":
|
|
901
830
|
typeofTarget = "number";
|
|
902
831
|
if (isNaN(value)) {
|
|
903
|
-
console.log(
|
|
832
|
+
console.log(`trying to encode "NaN" in ${klass.constructor.name}#${field}`);
|
|
904
833
|
}
|
|
905
834
|
break;
|
|
906
835
|
case "string":
|
|
@@ -912,25 +841,25 @@
|
|
|
912
841
|
return;
|
|
913
842
|
}
|
|
914
843
|
if (typeof (value) !== typeofTarget && (!allowNull || (allowNull && value !== null))) {
|
|
915
|
-
|
|
916
|
-
throw new EncodeSchemaError(
|
|
844
|
+
let foundValue = `'${JSON.stringify(value)}'${(value && value.constructor && ` (${value.constructor.name})`) || ''}`;
|
|
845
|
+
throw new EncodeSchemaError(`a '${typeofTarget}' was expected, but ${foundValue} was provided in ${klass.constructor.name}#${field}`);
|
|
917
846
|
}
|
|
918
847
|
}
|
|
919
848
|
function assertInstanceType(value, type, klass, field) {
|
|
920
849
|
if (!(value instanceof type)) {
|
|
921
|
-
throw new EncodeSchemaError(
|
|
850
|
+
throw new EncodeSchemaError(`a '${type.name}' was expected, but '${value && value.constructor.name}' was provided in ${klass.constructor.name}#${field}`);
|
|
922
851
|
}
|
|
923
852
|
}
|
|
924
853
|
|
|
925
854
|
function encodePrimitiveType(type, bytes, value, klass, field, it) {
|
|
926
855
|
assertType(value, type, klass, field);
|
|
927
|
-
|
|
856
|
+
const encodeFunc = encode[type];
|
|
928
857
|
if (encodeFunc) {
|
|
929
858
|
encodeFunc(bytes, value, it);
|
|
930
859
|
// encodeFunc(bytes, value);
|
|
931
860
|
}
|
|
932
861
|
else {
|
|
933
|
-
throw new EncodeSchemaError(
|
|
862
|
+
throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);
|
|
934
863
|
}
|
|
935
864
|
}
|
|
936
865
|
function encodeValue(encoder, bytes, ref, type, value, field, operation, it) {
|
|
@@ -957,7 +886,7 @@
|
|
|
957
886
|
//
|
|
958
887
|
// Custom type (MapSchema, ArraySchema, etc)
|
|
959
888
|
//
|
|
960
|
-
|
|
889
|
+
const definition = getType(Object.keys(type)[0]);
|
|
961
890
|
//
|
|
962
891
|
// ensure a ArraySchema has been provided
|
|
963
892
|
//
|
|
@@ -973,12 +902,12 @@
|
|
|
973
902
|
* Used for Schema instances.
|
|
974
903
|
* @private
|
|
975
904
|
*/
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
905
|
+
const encodeSchemaOperation = function (encoder, bytes, changeTree, index, operation, it) {
|
|
906
|
+
const ref = changeTree.ref;
|
|
907
|
+
const metadata = ref['constructor'][Symbol.metadata];
|
|
908
|
+
const field = metadata[index];
|
|
909
|
+
const type = metadata[field].type;
|
|
910
|
+
const value = ref[field];
|
|
982
911
|
// "compress" field index + operation
|
|
983
912
|
bytes[it.offset++] = (index | operation) & 255;
|
|
984
913
|
// Do not encode value for DELETE operations
|
|
@@ -992,8 +921,8 @@
|
|
|
992
921
|
* Used for collections (MapSchema, CollectionSchema, SetSchema)
|
|
993
922
|
* @private
|
|
994
923
|
*/
|
|
995
|
-
|
|
996
|
-
|
|
924
|
+
const encodeKeyValueOperation = function (encoder, bytes, changeTree, field, operation, it) {
|
|
925
|
+
const ref = changeTree.ref;
|
|
997
926
|
// encode operation
|
|
998
927
|
bytes[it.offset++] = operation & 255;
|
|
999
928
|
// custom operations
|
|
@@ -1014,12 +943,12 @@
|
|
|
1014
943
|
//
|
|
1015
944
|
// MapSchema dynamic key
|
|
1016
945
|
//
|
|
1017
|
-
|
|
946
|
+
const dynamicIndex = changeTree.ref['$indexes'].get(field);
|
|
1018
947
|
string$1(bytes, dynamicIndex, it);
|
|
1019
948
|
}
|
|
1020
949
|
}
|
|
1021
|
-
|
|
1022
|
-
|
|
950
|
+
const type = changeTree.getType(field);
|
|
951
|
+
const value = changeTree.getValue(field);
|
|
1023
952
|
// TODO: inline this function call small performance gain
|
|
1024
953
|
encodeValue(encoder, bytes, ref, type, value, field, operation, it);
|
|
1025
954
|
};
|
|
@@ -1027,15 +956,15 @@
|
|
|
1027
956
|
* Used for collections (MapSchema, ArraySchema, etc.)
|
|
1028
957
|
* @private
|
|
1029
958
|
*/
|
|
1030
|
-
|
|
1031
|
-
|
|
959
|
+
const encodeArray = function (encoder, bytes, changeTree, field, operation, it, isEncodeAll, hasView) {
|
|
960
|
+
const ref = changeTree.ref;
|
|
1032
961
|
if (hasView &&
|
|
1033
962
|
operation === exports.OPERATION.DELETE &&
|
|
1034
963
|
typeof (changeTree.getType(field)) !== "string") {
|
|
1035
964
|
// encode delete by refId (array of schemas)
|
|
1036
965
|
bytes[it.offset++] = exports.OPERATION.DELETE_BY_REFID;
|
|
1037
|
-
|
|
1038
|
-
|
|
966
|
+
const value = ref['tmpItems'][field];
|
|
967
|
+
const refId = value[$changes].refId;
|
|
1039
968
|
number$1(bytes, refId, it);
|
|
1040
969
|
return;
|
|
1041
970
|
}
|
|
@@ -1051,8 +980,8 @@
|
|
|
1051
980
|
if (operation === exports.OPERATION.DELETE) {
|
|
1052
981
|
return;
|
|
1053
982
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
983
|
+
const type = changeTree.getType(field);
|
|
984
|
+
const value = changeTree.getValue(field, isEncodeAll);
|
|
1056
985
|
// console.log("encodeArray -> ", {
|
|
1057
986
|
// ref: changeTree.ref.constructor.name,
|
|
1058
987
|
// field,
|
|
@@ -1150,18 +1079,18 @@
|
|
|
1150
1079
|
return readFloat64(bytes, it);
|
|
1151
1080
|
}
|
|
1152
1081
|
function int64(bytes, it) {
|
|
1153
|
-
|
|
1154
|
-
|
|
1082
|
+
const low = uint32(bytes, it);
|
|
1083
|
+
const high = int32(bytes, it) * Math.pow(2, 32);
|
|
1155
1084
|
return high + low;
|
|
1156
1085
|
}
|
|
1157
1086
|
function uint64(bytes, it) {
|
|
1158
|
-
|
|
1159
|
-
|
|
1087
|
+
const low = uint32(bytes, it);
|
|
1088
|
+
const high = uint32(bytes, it) * Math.pow(2, 32);
|
|
1160
1089
|
return high + low;
|
|
1161
1090
|
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1091
|
+
const _int32 = new Int32Array(2);
|
|
1092
|
+
const _float32 = new Float32Array(_int32.buffer);
|
|
1093
|
+
const _float64 = new Float64Array(_int32.buffer);
|
|
1165
1094
|
function readFloat32(bytes, it) {
|
|
1166
1095
|
_int32[0] = int32(bytes, it);
|
|
1167
1096
|
return _float32[0];
|
|
@@ -1175,8 +1104,8 @@
|
|
|
1175
1104
|
return uint8(bytes, it) > 0;
|
|
1176
1105
|
}
|
|
1177
1106
|
function string(bytes, it) {
|
|
1178
|
-
|
|
1179
|
-
|
|
1107
|
+
const prefix = bytes[it.offset++];
|
|
1108
|
+
let length;
|
|
1180
1109
|
if (prefix < 0xc0) {
|
|
1181
1110
|
// fixstr
|
|
1182
1111
|
length = prefix & 0x1f;
|
|
@@ -1190,12 +1119,12 @@
|
|
|
1190
1119
|
else if (prefix === 0xdb) {
|
|
1191
1120
|
length = uint32(bytes, it);
|
|
1192
1121
|
}
|
|
1193
|
-
|
|
1122
|
+
const value = utf8Read(bytes, it.offset, length);
|
|
1194
1123
|
it.offset += length;
|
|
1195
1124
|
return value;
|
|
1196
1125
|
}
|
|
1197
1126
|
function stringCheck(bytes, it) {
|
|
1198
|
-
|
|
1127
|
+
const prefix = bytes[it.offset];
|
|
1199
1128
|
return (
|
|
1200
1129
|
// fixstr
|
|
1201
1130
|
(prefix < 0xc0 && prefix > 0xa0) ||
|
|
@@ -1207,7 +1136,7 @@
|
|
|
1207
1136
|
prefix === 0xdb);
|
|
1208
1137
|
}
|
|
1209
1138
|
function number(bytes, it) {
|
|
1210
|
-
|
|
1139
|
+
const prefix = bytes[it.offset++];
|
|
1211
1140
|
if (prefix < 0x80) {
|
|
1212
1141
|
// positive fixint
|
|
1213
1142
|
return prefix;
|
|
@@ -1258,7 +1187,7 @@
|
|
|
1258
1187
|
}
|
|
1259
1188
|
}
|
|
1260
1189
|
function numberCheck(bytes, it) {
|
|
1261
|
-
|
|
1190
|
+
const prefix = bytes[it.offset];
|
|
1262
1191
|
// positive fixint - 0x00 - 0x7f
|
|
1263
1192
|
// float 32 - 0xca
|
|
1264
1193
|
// float 64 - 0xcb
|
|
@@ -1317,14 +1246,14 @@
|
|
|
1317
1246
|
switchStructureCheck: switchStructureCheck
|
|
1318
1247
|
});
|
|
1319
1248
|
|
|
1320
|
-
|
|
1249
|
+
const DEFINITION_MISMATCH = -1;
|
|
1321
1250
|
function decodeValue(decoder, operation, ref, index, type, bytes, it, allChanges) {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1251
|
+
const $root = decoder.$root;
|
|
1252
|
+
const previousValue = ref[$getByIndex](index);
|
|
1253
|
+
let value;
|
|
1325
1254
|
if ((operation & exports.OPERATION.DELETE) === exports.OPERATION.DELETE) {
|
|
1326
1255
|
// Flag `refId` for garbage collection.
|
|
1327
|
-
|
|
1256
|
+
const previousRefId = $root.refIds.get(previousValue);
|
|
1328
1257
|
if (previousRefId !== undefined) {
|
|
1329
1258
|
$root.removeRef(previousRefId);
|
|
1330
1259
|
}
|
|
@@ -1351,10 +1280,10 @@
|
|
|
1351
1280
|
}
|
|
1352
1281
|
if (operation === exports.OPERATION.DELETE) ;
|
|
1353
1282
|
else if (Schema.is(type)) {
|
|
1354
|
-
|
|
1283
|
+
const refId = number(bytes, it);
|
|
1355
1284
|
value = $root.refs.get(refId);
|
|
1356
1285
|
if (previousValue) {
|
|
1357
|
-
|
|
1286
|
+
const previousRefId = $root.refIds.get(previousValue);
|
|
1358
1287
|
if (previousRefId &&
|
|
1359
1288
|
refId !== previousRefId &&
|
|
1360
1289
|
// FIXME: we may need to check for REPLACE operation as well
|
|
@@ -1363,7 +1292,7 @@
|
|
|
1363
1292
|
}
|
|
1364
1293
|
}
|
|
1365
1294
|
if ((operation & exports.OPERATION.ADD) === exports.OPERATION.ADD) {
|
|
1366
|
-
|
|
1295
|
+
const childType = decoder.getInstanceType(bytes, it, type);
|
|
1367
1296
|
if (!value) {
|
|
1368
1297
|
value = decoder.createInstanceOfType(childType);
|
|
1369
1298
|
}
|
|
@@ -1377,28 +1306,28 @@
|
|
|
1377
1306
|
value = decode[type](bytes, it);
|
|
1378
1307
|
}
|
|
1379
1308
|
else {
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1309
|
+
const typeDef = getType(Object.keys(type)[0]);
|
|
1310
|
+
const refId = number(bytes, it);
|
|
1311
|
+
const valueRef = ($root.refs.has(refId))
|
|
1383
1312
|
? previousValue || $root.refs.get(refId)
|
|
1384
1313
|
: new typeDef.constructor();
|
|
1385
1314
|
value = valueRef.clone(true);
|
|
1386
1315
|
value[$childType] = Object.values(type)[0]; // cache childType for ArraySchema and MapSchema
|
|
1387
1316
|
if (previousValue) {
|
|
1388
|
-
|
|
1317
|
+
let previousRefId = $root.refIds.get(previousValue);
|
|
1389
1318
|
if (previousRefId !== undefined && refId !== previousRefId) {
|
|
1390
1319
|
$root.removeRef(previousRefId);
|
|
1391
1320
|
//
|
|
1392
1321
|
// enqueue onRemove if structure has been replaced.
|
|
1393
1322
|
//
|
|
1394
|
-
|
|
1395
|
-
|
|
1323
|
+
const entries = previousValue.entries();
|
|
1324
|
+
let iter;
|
|
1396
1325
|
while ((iter = entries.next()) && !iter.done) {
|
|
1397
|
-
|
|
1326
|
+
const [key, value] = iter.value;
|
|
1398
1327
|
// if value is a schema, remove its reference
|
|
1399
1328
|
// FIXME: not sure if this is necessary, add more tests to confirm
|
|
1400
|
-
if (typeof (
|
|
1401
|
-
previousRefId = $root.refIds.get(
|
|
1329
|
+
if (typeof (value) === "object") {
|
|
1330
|
+
previousRefId = $root.refIds.get(value);
|
|
1402
1331
|
$root.removeRef(previousRefId);
|
|
1403
1332
|
}
|
|
1404
1333
|
allChanges.push({
|
|
@@ -1407,45 +1336,45 @@
|
|
|
1407
1336
|
op: exports.OPERATION.DELETE,
|
|
1408
1337
|
field: key,
|
|
1409
1338
|
value: undefined,
|
|
1410
|
-
previousValue:
|
|
1339
|
+
previousValue: value,
|
|
1411
1340
|
});
|
|
1412
1341
|
}
|
|
1413
1342
|
}
|
|
1414
1343
|
}
|
|
1415
1344
|
$root.addRef(refId, value, (valueRef !== previousValue));
|
|
1416
1345
|
}
|
|
1417
|
-
return { value
|
|
1346
|
+
return { value, previousValue };
|
|
1418
1347
|
}
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1348
|
+
const decodeSchemaOperation = function (decoder, bytes, it, ref, allChanges) {
|
|
1349
|
+
const first_byte = bytes[it.offset++];
|
|
1350
|
+
const metadata = ref['constructor'][Symbol.metadata];
|
|
1422
1351
|
// "compressed" index + operation
|
|
1423
|
-
|
|
1424
|
-
|
|
1352
|
+
const operation = (first_byte >> 6) << 6;
|
|
1353
|
+
const index = first_byte % (operation || 255);
|
|
1425
1354
|
// skip early if field is not defined
|
|
1426
|
-
|
|
1355
|
+
const field = metadata[index];
|
|
1427
1356
|
if (field === undefined) {
|
|
1428
1357
|
return DEFINITION_MISMATCH;
|
|
1429
1358
|
}
|
|
1430
|
-
|
|
1359
|
+
const { value, previousValue } = decodeValue(decoder, operation, ref, index, metadata[field].type, bytes, it, allChanges);
|
|
1431
1360
|
if (value !== null && value !== undefined) {
|
|
1432
1361
|
ref[field] = value;
|
|
1433
1362
|
}
|
|
1434
1363
|
// add change
|
|
1435
1364
|
if (previousValue !== value) {
|
|
1436
1365
|
allChanges.push({
|
|
1437
|
-
ref
|
|
1366
|
+
ref,
|
|
1438
1367
|
refId: decoder.currentRefId,
|
|
1439
1368
|
op: operation,
|
|
1440
1369
|
field: field,
|
|
1441
|
-
value
|
|
1442
|
-
previousValue
|
|
1370
|
+
value,
|
|
1371
|
+
previousValue,
|
|
1443
1372
|
});
|
|
1444
1373
|
}
|
|
1445
1374
|
};
|
|
1446
|
-
|
|
1375
|
+
const decodeKeyValueOperation = function (decoder, bytes, it, ref, allChanges) {
|
|
1447
1376
|
// "uncompressed" index + operation (array/map items)
|
|
1448
|
-
|
|
1377
|
+
const operation = bytes[it.offset++];
|
|
1449
1378
|
if (operation === exports.OPERATION.CLEAR) {
|
|
1450
1379
|
//
|
|
1451
1380
|
// When decoding:
|
|
@@ -1456,9 +1385,9 @@
|
|
|
1456
1385
|
ref.clear();
|
|
1457
1386
|
return;
|
|
1458
1387
|
}
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1388
|
+
const index = number(bytes, it);
|
|
1389
|
+
const type = ref[$childType];
|
|
1390
|
+
let dynamicIndex;
|
|
1462
1391
|
if ((operation & exports.OPERATION.ADD) === exports.OPERATION.ADD) { // ADD or DELETE_AND_ADD
|
|
1463
1392
|
if (typeof (ref['set']) === "function") {
|
|
1464
1393
|
dynamicIndex = string(bytes, it); // MapSchema
|
|
@@ -1472,7 +1401,7 @@
|
|
|
1472
1401
|
// get dynamic index from "ref"
|
|
1473
1402
|
dynamicIndex = ref['getIndex'](index);
|
|
1474
1403
|
}
|
|
1475
|
-
|
|
1404
|
+
const { value, previousValue } = decodeValue(decoder, operation, ref, index, type, bytes, it, allChanges);
|
|
1476
1405
|
if (value !== null && value !== undefined) {
|
|
1477
1406
|
if (typeof (ref['set']) === "function") {
|
|
1478
1407
|
// MapSchema
|
|
@@ -1484,28 +1413,28 @@
|
|
|
1484
1413
|
}
|
|
1485
1414
|
else if (typeof (ref['add']) === "function") {
|
|
1486
1415
|
// CollectionSchema && SetSchema
|
|
1487
|
-
|
|
1488
|
-
if (typeof (
|
|
1489
|
-
ref['setIndex'](
|
|
1416
|
+
const index = ref.add(value);
|
|
1417
|
+
if (typeof (index) === "number") {
|
|
1418
|
+
ref['setIndex'](index, index);
|
|
1490
1419
|
}
|
|
1491
1420
|
}
|
|
1492
1421
|
}
|
|
1493
1422
|
// add change
|
|
1494
1423
|
if (previousValue !== value) {
|
|
1495
1424
|
allChanges.push({
|
|
1496
|
-
ref
|
|
1425
|
+
ref,
|
|
1497
1426
|
refId: decoder.currentRefId,
|
|
1498
1427
|
op: operation,
|
|
1499
1428
|
field: "", // FIXME: remove this
|
|
1500
|
-
dynamicIndex
|
|
1501
|
-
value
|
|
1502
|
-
previousValue
|
|
1429
|
+
dynamicIndex,
|
|
1430
|
+
value,
|
|
1431
|
+
previousValue,
|
|
1503
1432
|
});
|
|
1504
1433
|
}
|
|
1505
1434
|
};
|
|
1506
|
-
|
|
1435
|
+
const decodeArray = function (decoder, bytes, it, ref, allChanges) {
|
|
1507
1436
|
// "uncompressed" index + operation (array/map items)
|
|
1508
|
-
|
|
1437
|
+
const operation = bytes[it.offset++];
|
|
1509
1438
|
if (operation === exports.OPERATION.CLEAR) {
|
|
1510
1439
|
//
|
|
1511
1440
|
// When decoding:
|
|
@@ -1518,25 +1447,25 @@
|
|
|
1518
1447
|
}
|
|
1519
1448
|
else if (operation === exports.OPERATION.DELETE_BY_REFID) {
|
|
1520
1449
|
// TODO: refactor here, try to follow same flow as below
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
ref[$deleteByIndex](
|
|
1450
|
+
const refId = number(bytes, it);
|
|
1451
|
+
const previousValue = decoder.$root.refs.get(refId);
|
|
1452
|
+
const index = ref.findIndex((value) => value === previousValue);
|
|
1453
|
+
ref[$deleteByIndex](index);
|
|
1525
1454
|
allChanges.push({
|
|
1526
|
-
ref
|
|
1455
|
+
ref,
|
|
1527
1456
|
refId: decoder.currentRefId,
|
|
1528
1457
|
op: exports.OPERATION.DELETE,
|
|
1529
1458
|
field: "", // FIXME: remove this
|
|
1530
|
-
dynamicIndex:
|
|
1459
|
+
dynamicIndex: index,
|
|
1531
1460
|
value: undefined,
|
|
1532
|
-
previousValue
|
|
1461
|
+
previousValue,
|
|
1533
1462
|
});
|
|
1534
1463
|
return;
|
|
1535
1464
|
}
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1465
|
+
const index = number(bytes, it);
|
|
1466
|
+
const type = ref[$childType];
|
|
1467
|
+
let dynamicIndex = index;
|
|
1468
|
+
const { value, previousValue } = decodeValue(decoder, operation, ref, index, type, bytes, it, allChanges);
|
|
1540
1469
|
if (value !== null && value !== undefined &&
|
|
1541
1470
|
value !== previousValue // avoid setting same value twice (if index === 0 it will result in a "unshift" for ArraySchema)
|
|
1542
1471
|
) {
|
|
@@ -1546,20 +1475,21 @@
|
|
|
1546
1475
|
// add change
|
|
1547
1476
|
if (previousValue !== value) {
|
|
1548
1477
|
allChanges.push({
|
|
1549
|
-
ref
|
|
1478
|
+
ref,
|
|
1550
1479
|
refId: decoder.currentRefId,
|
|
1551
1480
|
op: operation,
|
|
1552
1481
|
field: "", // FIXME: remove this
|
|
1553
|
-
dynamicIndex
|
|
1554
|
-
value
|
|
1555
|
-
previousValue
|
|
1482
|
+
dynamicIndex,
|
|
1483
|
+
value,
|
|
1484
|
+
previousValue,
|
|
1556
1485
|
});
|
|
1557
1486
|
}
|
|
1558
1487
|
};
|
|
1559
1488
|
|
|
1560
|
-
var
|
|
1561
|
-
|
|
1562
|
-
|
|
1489
|
+
var _a$4, _b$4;
|
|
1490
|
+
const DEFAULT_SORT = (a, b) => {
|
|
1491
|
+
const A = a.toString();
|
|
1492
|
+
const B = b.toString();
|
|
1563
1493
|
if (A < B)
|
|
1564
1494
|
return -1;
|
|
1565
1495
|
else if (A > B)
|
|
@@ -1567,13 +1497,33 @@
|
|
|
1567
1497
|
else
|
|
1568
1498
|
return 0;
|
|
1569
1499
|
};
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1500
|
+
class ArraySchema {
|
|
1501
|
+
static { this[_a$4] = encodeArray; }
|
|
1502
|
+
static { this[_b$4] = decodeArray; }
|
|
1503
|
+
/**
|
|
1504
|
+
* Determine if a property must be filtered.
|
|
1505
|
+
* - If returns false, the property is NOT going to be encoded.
|
|
1506
|
+
* - If returns true, the property is going to be encoded.
|
|
1507
|
+
*
|
|
1508
|
+
* Encoding with "filters" happens in two steps:
|
|
1509
|
+
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
1510
|
+
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
1511
|
+
*/
|
|
1512
|
+
static [(_a$4 = $encoder, _b$4 = $decoder, $filter)](ref, index, view) {
|
|
1513
|
+
// console.log("ArraSchema[$filter] VIEW??", !view)
|
|
1514
|
+
return (!view ||
|
|
1515
|
+
typeof (ref[$childType]) === "string" ||
|
|
1516
|
+
// view.items.has(ref[$getByIndex](index)[$changes])
|
|
1517
|
+
view.items.has(ref['tmpItems'][index]?.[$changes]));
|
|
1518
|
+
}
|
|
1519
|
+
static is(type) {
|
|
1520
|
+
return (
|
|
1521
|
+
// type format: ["string"]
|
|
1522
|
+
Array.isArray(type) ||
|
|
1523
|
+
// type format: { array: "string" }
|
|
1524
|
+
(type['array'] !== undefined));
|
|
1525
|
+
}
|
|
1526
|
+
constructor(...items) {
|
|
1577
1527
|
this.items = [];
|
|
1578
1528
|
this.tmpItems = [];
|
|
1579
1529
|
this.deletedIndexes = {};
|
|
@@ -1583,18 +1533,18 @@
|
|
|
1583
1533
|
writable: true,
|
|
1584
1534
|
configurable: true,
|
|
1585
1535
|
});
|
|
1586
|
-
|
|
1587
|
-
get:
|
|
1536
|
+
const proxy = new Proxy(this, {
|
|
1537
|
+
get: (obj, prop) => {
|
|
1588
1538
|
if (typeof (prop) !== "symbol" &&
|
|
1589
1539
|
!isNaN(prop) // https://stackoverflow.com/a/175787/892698
|
|
1590
1540
|
) {
|
|
1591
|
-
return
|
|
1541
|
+
return this.items[prop];
|
|
1592
1542
|
}
|
|
1593
1543
|
else {
|
|
1594
1544
|
return Reflect.get(obj, prop);
|
|
1595
1545
|
}
|
|
1596
1546
|
},
|
|
1597
|
-
set:
|
|
1547
|
+
set: (obj, key, setValue) => {
|
|
1598
1548
|
if (typeof (key) !== "symbol" && !isNaN(key)) {
|
|
1599
1549
|
if (setValue === undefined || setValue === null) {
|
|
1600
1550
|
obj.$deleteAt(key);
|
|
@@ -1603,26 +1553,26 @@
|
|
|
1603
1553
|
if (setValue[$changes]) {
|
|
1604
1554
|
if (obj.items[key] !== undefined) {
|
|
1605
1555
|
if (setValue[$changes][$isNew]) {
|
|
1606
|
-
|
|
1556
|
+
this[$changes].indexedOperation(Number(key), exports.OPERATION.MOVE_AND_ADD);
|
|
1607
1557
|
}
|
|
1608
1558
|
else {
|
|
1609
1559
|
if ((obj[$changes].getChange(Number(key)) & exports.OPERATION.DELETE) === exports.OPERATION.DELETE) {
|
|
1610
|
-
|
|
1560
|
+
this[$changes].indexedOperation(Number(key), exports.OPERATION.DELETE_AND_MOVE);
|
|
1611
1561
|
}
|
|
1612
1562
|
else {
|
|
1613
|
-
|
|
1563
|
+
this[$changes].indexedOperation(Number(key), exports.OPERATION.MOVE);
|
|
1614
1564
|
}
|
|
1615
1565
|
}
|
|
1616
1566
|
}
|
|
1617
1567
|
else if (setValue[$changes][$isNew]) {
|
|
1618
|
-
|
|
1568
|
+
this[$changes].indexedOperation(Number(key), exports.OPERATION.ADD);
|
|
1619
1569
|
}
|
|
1620
1570
|
}
|
|
1621
1571
|
else {
|
|
1622
1572
|
obj.$changeAt(Number(key), setValue);
|
|
1623
1573
|
}
|
|
1624
|
-
|
|
1625
|
-
|
|
1574
|
+
this.items[key] = setValue;
|
|
1575
|
+
this.tmpItems[key] = setValue;
|
|
1626
1576
|
}
|
|
1627
1577
|
return true;
|
|
1628
1578
|
}
|
|
@@ -1630,7 +1580,7 @@
|
|
|
1630
1580
|
return Reflect.set(obj, key, setValue);
|
|
1631
1581
|
}
|
|
1632
1582
|
},
|
|
1633
|
-
deleteProperty:
|
|
1583
|
+
deleteProperty: (obj, prop) => {
|
|
1634
1584
|
if (typeof (prop) === "number") {
|
|
1635
1585
|
obj.$deleteAt(prop);
|
|
1636
1586
|
}
|
|
@@ -1639,9 +1589,9 @@
|
|
|
1639
1589
|
}
|
|
1640
1590
|
return true;
|
|
1641
1591
|
},
|
|
1642
|
-
has:
|
|
1592
|
+
has: (obj, key) => {
|
|
1643
1593
|
if (typeof (key) !== "symbol" && !isNaN(Number(key))) {
|
|
1644
|
-
return Reflect.has(
|
|
1594
|
+
return Reflect.has(this.items, key);
|
|
1645
1595
|
}
|
|
1646
1596
|
return Reflect.has(obj, key);
|
|
1647
1597
|
}
|
|
@@ -1650,82 +1600,48 @@
|
|
|
1650
1600
|
this.push.apply(this, items);
|
|
1651
1601
|
return proxy;
|
|
1652
1602
|
}
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
return
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
ArraySchema.is = function (type) {
|
|
1671
|
-
return (
|
|
1672
|
-
// type format: ["string"]
|
|
1673
|
-
Array.isArray(type) ||
|
|
1674
|
-
// type format: { array: "string" }
|
|
1675
|
-
(type['array'] !== undefined));
|
|
1676
|
-
};
|
|
1677
|
-
Object.defineProperty(ArraySchema.prototype, "length", {
|
|
1678
|
-
get: function () {
|
|
1679
|
-
return this.items.length;
|
|
1680
|
-
},
|
|
1681
|
-
set: function (newLength) {
|
|
1682
|
-
if (newLength === 0) {
|
|
1683
|
-
this.clear();
|
|
1684
|
-
}
|
|
1685
|
-
else if (newLength < this.items.length) {
|
|
1686
|
-
this.splice(newLength, this.length - newLength);
|
|
1687
|
-
}
|
|
1688
|
-
else {
|
|
1689
|
-
console.warn("ArraySchema: can't set .length to a higher value than its length.");
|
|
1690
|
-
}
|
|
1691
|
-
},
|
|
1692
|
-
enumerable: false,
|
|
1693
|
-
configurable: true
|
|
1694
|
-
});
|
|
1695
|
-
ArraySchema.prototype.push = function () {
|
|
1696
|
-
var _this = this;
|
|
1697
|
-
var values = [];
|
|
1698
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1699
|
-
values[_i] = arguments[_i];
|
|
1700
|
-
}
|
|
1701
|
-
var length = this.tmpItems.length;
|
|
1702
|
-
values.forEach(function (value, i) {
|
|
1703
|
-
var _c;
|
|
1603
|
+
set length(newLength) {
|
|
1604
|
+
if (newLength === 0) {
|
|
1605
|
+
this.clear();
|
|
1606
|
+
}
|
|
1607
|
+
else if (newLength < this.items.length) {
|
|
1608
|
+
this.splice(newLength, this.length - newLength);
|
|
1609
|
+
}
|
|
1610
|
+
else {
|
|
1611
|
+
console.warn("ArraySchema: can't set .length to a higher value than its length.");
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
get length() {
|
|
1615
|
+
return this.items.length;
|
|
1616
|
+
}
|
|
1617
|
+
push(...values) {
|
|
1618
|
+
let length = this.tmpItems.length;
|
|
1619
|
+
values.forEach((value, i) => {
|
|
1704
1620
|
// skip null values
|
|
1705
1621
|
if (value === undefined || value === null) {
|
|
1706
1622
|
return;
|
|
1707
1623
|
}
|
|
1708
|
-
|
|
1709
|
-
changeTree.indexedOperation(length, exports.OPERATION.ADD,
|
|
1624
|
+
const changeTree = this[$changes];
|
|
1625
|
+
changeTree.indexedOperation(length, exports.OPERATION.ADD, this.items.length);
|
|
1710
1626
|
// changeTree.indexes[length] = length;
|
|
1711
|
-
|
|
1712
|
-
|
|
1627
|
+
this.items.push(value);
|
|
1628
|
+
this.tmpItems.push(value);
|
|
1713
1629
|
//
|
|
1714
1630
|
// set value's parent after the value is set
|
|
1715
1631
|
// (to avoid encoding "refId" operations before parent's "ADD" operation)
|
|
1716
1632
|
//
|
|
1717
|
-
|
|
1633
|
+
value[$changes]?.setParent(this, changeTree.root, length);
|
|
1718
1634
|
length++;
|
|
1719
1635
|
});
|
|
1720
1636
|
return length;
|
|
1721
|
-
}
|
|
1637
|
+
}
|
|
1722
1638
|
/**
|
|
1723
1639
|
* Removes the last element from an array and returns it.
|
|
1724
1640
|
*/
|
|
1725
|
-
|
|
1726
|
-
|
|
1641
|
+
pop() {
|
|
1642
|
+
let index = -1;
|
|
1727
1643
|
// find last non-undefined index
|
|
1728
|
-
for (
|
|
1644
|
+
for (let i = this.tmpItems.length - 1; i >= 0; i--) {
|
|
1729
1645
|
// if (this.tmpItems[i] !== undefined) {
|
|
1730
1646
|
if (this.deletedIndexes[i] !== true) {
|
|
1731
1647
|
index = i;
|
|
@@ -1739,16 +1655,15 @@
|
|
|
1739
1655
|
// this.tmpItems[index] = undefined;
|
|
1740
1656
|
this.deletedIndexes[index] = true;
|
|
1741
1657
|
return this.items.pop();
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1658
|
+
}
|
|
1659
|
+
at(index) {
|
|
1744
1660
|
// Allow negative indexing from the end
|
|
1745
1661
|
if (index < 0)
|
|
1746
1662
|
index += this.length;
|
|
1747
1663
|
return this.items[index];
|
|
1748
|
-
}
|
|
1664
|
+
}
|
|
1749
1665
|
// encoding only
|
|
1750
|
-
|
|
1751
|
-
var _c, _d, _e, _f;
|
|
1666
|
+
$changeAt(index, value) {
|
|
1752
1667
|
if (value === undefined || value === null) {
|
|
1753
1668
|
console.error("ArraySchema items cannot be null nor undefined; Use `deleteAt(index)` instead.");
|
|
1754
1669
|
return;
|
|
@@ -1757,21 +1672,21 @@
|
|
|
1757
1672
|
if (this.items[index] === value) {
|
|
1758
1673
|
return;
|
|
1759
1674
|
}
|
|
1760
|
-
|
|
1761
|
-
|
|
1675
|
+
const changeTree = this[$changes];
|
|
1676
|
+
const operation = changeTree.indexes?.[index]?.op ?? exports.OPERATION.ADD;
|
|
1762
1677
|
changeTree.change(index, operation);
|
|
1763
1678
|
//
|
|
1764
1679
|
// set value's parent after the value is set
|
|
1765
1680
|
// (to avoid encoding "refId" operations before parent's "ADD" operation)
|
|
1766
1681
|
//
|
|
1767
|
-
|
|
1768
|
-
}
|
|
1682
|
+
value[$changes]?.setParent(this, changeTree.root, index);
|
|
1683
|
+
}
|
|
1769
1684
|
// encoding only
|
|
1770
|
-
|
|
1685
|
+
$deleteAt(index, operation) {
|
|
1771
1686
|
this[$changes].delete(index, operation);
|
|
1772
|
-
}
|
|
1687
|
+
}
|
|
1773
1688
|
// decoding only
|
|
1774
|
-
|
|
1689
|
+
$setAt(index, value, operation) {
|
|
1775
1690
|
if (index === 0 &&
|
|
1776
1691
|
operation === exports.OPERATION.ADD &&
|
|
1777
1692
|
this.items[index] !== undefined) {
|
|
@@ -1785,17 +1700,16 @@
|
|
|
1785
1700
|
else {
|
|
1786
1701
|
this.items[index] = value;
|
|
1787
1702
|
}
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1703
|
+
}
|
|
1704
|
+
clear() {
|
|
1790
1705
|
// skip if already clear
|
|
1791
1706
|
if (this.items.length === 0) {
|
|
1792
1707
|
return;
|
|
1793
1708
|
}
|
|
1794
1709
|
// discard previous operations.
|
|
1795
|
-
|
|
1710
|
+
const changeTree = this[$changes];
|
|
1796
1711
|
// discard children
|
|
1797
|
-
changeTree.forEachChild(
|
|
1798
|
-
var _c, _d, _e;
|
|
1712
|
+
changeTree.forEachChild((changeTree, _) => {
|
|
1799
1713
|
changeTree.discard(true);
|
|
1800
1714
|
//
|
|
1801
1715
|
// TODO: add tests with instance sharing + .clear()
|
|
@@ -1803,70 +1717,64 @@
|
|
|
1803
1717
|
//
|
|
1804
1718
|
// TODO: do not use [$changes] at decoding time.
|
|
1805
1719
|
//
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1720
|
+
changeTree.root?.changes.delete(changeTree);
|
|
1721
|
+
changeTree.root?.allChanges.delete(changeTree);
|
|
1722
|
+
changeTree.root?.allFilteredChanges.delete(changeTree);
|
|
1809
1723
|
});
|
|
1810
1724
|
changeTree.discard(true);
|
|
1811
1725
|
changeTree.operation(exports.OPERATION.CLEAR);
|
|
1812
1726
|
this.items.length = 0;
|
|
1813
1727
|
this.tmpItems.length = 0;
|
|
1814
|
-
}
|
|
1728
|
+
}
|
|
1815
1729
|
/**
|
|
1816
1730
|
* Combines two or more arrays.
|
|
1817
1731
|
* @param items Additional items to add to the end of array1.
|
|
1818
1732
|
*/
|
|
1819
1733
|
// @ts-ignore
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1824
|
-
items[_i] = arguments[_i];
|
|
1825
|
-
}
|
|
1826
|
-
return new (ArraySchema.bind.apply(ArraySchema, __spreadArray([void 0], (_c = this.items).concat.apply(_c, items), false)))();
|
|
1827
|
-
};
|
|
1734
|
+
concat(...items) {
|
|
1735
|
+
return new ArraySchema(...this.items.concat(...items));
|
|
1736
|
+
}
|
|
1828
1737
|
/**
|
|
1829
1738
|
* Adds all the elements of an array separated by the specified separator string.
|
|
1830
1739
|
* @param separator A string used to separate one element of an array from the next in the resulting String. If omitted, the array elements are separated with a comma.
|
|
1831
1740
|
*/
|
|
1832
|
-
|
|
1741
|
+
join(separator) {
|
|
1833
1742
|
return this.items.join(separator);
|
|
1834
|
-
}
|
|
1743
|
+
}
|
|
1835
1744
|
/**
|
|
1836
1745
|
* Reverses the elements in an Array.
|
|
1837
1746
|
*/
|
|
1838
1747
|
// @ts-ignore
|
|
1839
|
-
|
|
1748
|
+
reverse() {
|
|
1840
1749
|
this[$changes].operation(exports.OPERATION.REVERSE);
|
|
1841
1750
|
this.items.reverse();
|
|
1842
1751
|
this.tmpItems.reverse();
|
|
1843
1752
|
return this;
|
|
1844
|
-
}
|
|
1753
|
+
}
|
|
1845
1754
|
/**
|
|
1846
1755
|
* Removes the first element from an array and returns it.
|
|
1847
1756
|
*/
|
|
1848
|
-
|
|
1849
|
-
var _this = this;
|
|
1757
|
+
shift() {
|
|
1850
1758
|
if (this.items.length === 0) {
|
|
1851
1759
|
return undefined;
|
|
1852
1760
|
}
|
|
1853
1761
|
// const index = Number(Object.keys(changeTree.indexes)[0]);
|
|
1854
|
-
|
|
1855
|
-
|
|
1762
|
+
const index = this.tmpItems.findIndex((item, i) => item === this.items[0]);
|
|
1763
|
+
const changeTree = this[$changes];
|
|
1856
1764
|
changeTree.delete(index);
|
|
1857
1765
|
changeTree.shiftAllChangeIndexes(-1, index);
|
|
1858
1766
|
return this.items.shift();
|
|
1859
|
-
}
|
|
1767
|
+
}
|
|
1860
1768
|
/**
|
|
1861
1769
|
* Returns a section of an array.
|
|
1862
1770
|
* @param start The beginning of the specified portion of the array.
|
|
1863
1771
|
* @param end The end of the specified portion of the array. This is exclusive of the element at the index 'end'.
|
|
1864
1772
|
*/
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
sliced.push
|
|
1773
|
+
slice(start, end) {
|
|
1774
|
+
const sliced = new ArraySchema();
|
|
1775
|
+
sliced.push(...this.items.slice(start, end));
|
|
1868
1776
|
return sliced;
|
|
1869
|
-
}
|
|
1777
|
+
}
|
|
1870
1778
|
/**
|
|
1871
1779
|
* Sorts an array.
|
|
1872
1780
|
* @param compareFn Function used to determine the order of the elements. It is expected to return
|
|
@@ -1876,53 +1784,45 @@
|
|
|
1876
1784
|
* [11,2,22,1].sort((a, b) => a - b)
|
|
1877
1785
|
* ```
|
|
1878
1786
|
*/
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
var sortedItems = this.items.sort(compareFn);
|
|
1787
|
+
sort(compareFn = DEFAULT_SORT) {
|
|
1788
|
+
const changeTree = this[$changes];
|
|
1789
|
+
const sortedItems = this.items.sort(compareFn);
|
|
1883
1790
|
// wouldn't OPERATION.MOVE make more sense here?
|
|
1884
|
-
sortedItems.forEach(
|
|
1791
|
+
sortedItems.forEach((_, i) => changeTree.change(i, exports.OPERATION.REPLACE));
|
|
1885
1792
|
this.tmpItems.sort(compareFn);
|
|
1886
1793
|
return this;
|
|
1887
|
-
}
|
|
1794
|
+
}
|
|
1888
1795
|
/**
|
|
1889
1796
|
* Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
|
|
1890
1797
|
* @param start The zero-based location in the array from which to start removing elements.
|
|
1891
1798
|
* @param deleteCount The number of elements to remove.
|
|
1892
1799
|
* @param insertItems Elements to insert into the array in place of the deleted elements.
|
|
1893
1800
|
*/
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
var insertItems = [];
|
|
1899
|
-
for (var _i = 2; _i < arguments.length; _i++) {
|
|
1900
|
-
insertItems[_i - 2] = arguments[_i];
|
|
1901
|
-
}
|
|
1902
|
-
var changeTree = this[$changes];
|
|
1903
|
-
var tmpItemsLength = this.tmpItems.length;
|
|
1904
|
-
var insertCount = insertItems.length;
|
|
1801
|
+
splice(start, deleteCount = this.items.length - start, ...insertItems) {
|
|
1802
|
+
const changeTree = this[$changes];
|
|
1803
|
+
const tmpItemsLength = this.tmpItems.length;
|
|
1804
|
+
const insertCount = insertItems.length;
|
|
1905
1805
|
// build up-to-date list of indexes, excluding removed values.
|
|
1906
|
-
|
|
1907
|
-
for (
|
|
1806
|
+
const indexes = [];
|
|
1807
|
+
for (let i = 0; i < tmpItemsLength; i++) {
|
|
1908
1808
|
// if (this.tmpItems[i] !== undefined) {
|
|
1909
1809
|
if (this.deletedIndexes[i] !== true) {
|
|
1910
1810
|
indexes.push(i);
|
|
1911
1811
|
}
|
|
1912
1812
|
}
|
|
1913
1813
|
// delete operations at correct index
|
|
1914
|
-
for (
|
|
1915
|
-
|
|
1814
|
+
for (let i = start; i < start + deleteCount; i++) {
|
|
1815
|
+
const index = indexes[i];
|
|
1916
1816
|
changeTree.delete(index);
|
|
1917
1817
|
// this.tmpItems[index] = undefined;
|
|
1918
1818
|
this.deletedIndexes[index] = true;
|
|
1919
1819
|
}
|
|
1920
1820
|
// force insert operations
|
|
1921
|
-
for (
|
|
1922
|
-
|
|
1821
|
+
for (let i = 0; i < insertCount; i++) {
|
|
1822
|
+
const addIndex = indexes[start] + i;
|
|
1923
1823
|
changeTree.indexedOperation(addIndex, exports.OPERATION.ADD);
|
|
1924
1824
|
// set value's parent/root
|
|
1925
|
-
|
|
1825
|
+
insertItems[i][$changes]?.setParent(this, changeTree.root, addIndex);
|
|
1926
1826
|
}
|
|
1927
1827
|
//
|
|
1928
1828
|
// delete exceeding indexes from "allChanges"
|
|
@@ -1931,19 +1831,14 @@
|
|
|
1931
1831
|
if (deleteCount > insertCount) {
|
|
1932
1832
|
changeTree.shiftAllChangeIndexes(-(deleteCount - insertCount), indexes[start + insertCount]);
|
|
1933
1833
|
}
|
|
1934
|
-
return
|
|
1935
|
-
}
|
|
1834
|
+
return this.items.splice(start, deleteCount, ...insertItems);
|
|
1835
|
+
}
|
|
1936
1836
|
/**
|
|
1937
1837
|
* Inserts new elements at the start of an array.
|
|
1938
1838
|
* @param items Elements to insert at the start of the Array.
|
|
1939
1839
|
*/
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
var items = [];
|
|
1943
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1944
|
-
items[_i] = arguments[_i];
|
|
1945
|
-
}
|
|
1946
|
-
var changeTree = this[$changes];
|
|
1840
|
+
unshift(...items) {
|
|
1841
|
+
const changeTree = this[$changes];
|
|
1947
1842
|
// shift indexes
|
|
1948
1843
|
changeTree.shiftChangeIndexes(items.length);
|
|
1949
1844
|
// new index
|
|
@@ -1954,29 +1849,28 @@
|
|
|
1954
1849
|
changeTree.allChanges.set(this.items.length, exports.OPERATION.ADD);
|
|
1955
1850
|
}
|
|
1956
1851
|
// FIXME: should we use OPERATION.MOVE here instead?
|
|
1957
|
-
items.forEach(
|
|
1852
|
+
items.forEach((_, index) => {
|
|
1958
1853
|
changeTree.change(index, exports.OPERATION.ADD);
|
|
1959
1854
|
});
|
|
1960
|
-
|
|
1961
|
-
return
|
|
1962
|
-
}
|
|
1855
|
+
this.tmpItems.unshift(...items);
|
|
1856
|
+
return this.items.unshift(...items);
|
|
1857
|
+
}
|
|
1963
1858
|
/**
|
|
1964
1859
|
* Returns the index of the first occurrence of a value in an array.
|
|
1965
1860
|
* @param searchElement The value to locate in the array.
|
|
1966
1861
|
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
|
|
1967
1862
|
*/
|
|
1968
|
-
|
|
1863
|
+
indexOf(searchElement, fromIndex) {
|
|
1969
1864
|
return this.items.indexOf(searchElement, fromIndex);
|
|
1970
|
-
}
|
|
1865
|
+
}
|
|
1971
1866
|
/**
|
|
1972
1867
|
* Returns the index of the last occurrence of a specified value in an array.
|
|
1973
1868
|
* @param searchElement The value to locate in the array.
|
|
1974
1869
|
* @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at the last index in the array.
|
|
1975
1870
|
*/
|
|
1976
|
-
|
|
1977
|
-
if (fromIndex === void 0) { fromIndex = this.length - 1; }
|
|
1871
|
+
lastIndexOf(searchElement, fromIndex = this.length - 1) {
|
|
1978
1872
|
return this.items.lastIndexOf(searchElement, fromIndex);
|
|
1979
|
-
}
|
|
1873
|
+
}
|
|
1980
1874
|
/**
|
|
1981
1875
|
* Determines whether all the members of an array satisfy the specified test.
|
|
1982
1876
|
* @param callbackfn A function that accepts up to three arguments. The every method calls
|
|
@@ -1985,9 +1879,9 @@
|
|
|
1985
1879
|
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
|
1986
1880
|
* If thisArg is omitted, undefined is used as the this value.
|
|
1987
1881
|
*/
|
|
1988
|
-
|
|
1882
|
+
every(callbackfn, thisArg) {
|
|
1989
1883
|
return this.items.every(callbackfn, thisArg);
|
|
1990
|
-
}
|
|
1884
|
+
}
|
|
1991
1885
|
/**
|
|
1992
1886
|
* Determines whether the specified callback function returns true for any element of an array.
|
|
1993
1887
|
* @param callbackfn A function that accepts up to three arguments. The some method calls
|
|
@@ -1996,44 +1890,44 @@
|
|
|
1996
1890
|
* @param thisArg An object to which the this keyword can refer in the callbackfn function.
|
|
1997
1891
|
* If thisArg is omitted, undefined is used as the this value.
|
|
1998
1892
|
*/
|
|
1999
|
-
|
|
1893
|
+
some(callbackfn, thisArg) {
|
|
2000
1894
|
return this.items.some(callbackfn, thisArg);
|
|
2001
|
-
}
|
|
1895
|
+
}
|
|
2002
1896
|
/**
|
|
2003
1897
|
* Performs the specified action for each element in an array.
|
|
2004
1898
|
* @param callbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.
|
|
2005
1899
|
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
|
|
2006
1900
|
*/
|
|
2007
|
-
|
|
1901
|
+
forEach(callbackfn, thisArg) {
|
|
2008
1902
|
return this.items.forEach(callbackfn, thisArg);
|
|
2009
|
-
}
|
|
1903
|
+
}
|
|
2010
1904
|
/**
|
|
2011
1905
|
* Calls a defined callback function on each element of an array, and returns an array that contains the results.
|
|
2012
1906
|
* @param callbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.
|
|
2013
1907
|
* @param thisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
|
|
2014
1908
|
*/
|
|
2015
|
-
|
|
1909
|
+
map(callbackfn, thisArg) {
|
|
2016
1910
|
return this.items.map(callbackfn, thisArg);
|
|
2017
|
-
}
|
|
2018
|
-
|
|
1911
|
+
}
|
|
1912
|
+
filter(callbackfn, thisArg) {
|
|
2019
1913
|
return this.items.filter(callbackfn, thisArg);
|
|
2020
|
-
}
|
|
1914
|
+
}
|
|
2021
1915
|
/**
|
|
2022
1916
|
* Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
|
|
2023
1917
|
* @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
|
|
2024
1918
|
* @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
|
|
2025
1919
|
*/
|
|
2026
|
-
|
|
1920
|
+
reduce(callbackfn, initialValue) {
|
|
2027
1921
|
return this.items.reduce(callbackfn, initialValue);
|
|
2028
|
-
}
|
|
1922
|
+
}
|
|
2029
1923
|
/**
|
|
2030
1924
|
* Calls the specified callback function for all the elements in an array, in descending order. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
|
|
2031
1925
|
* @param callbackfn A function that accepts up to four arguments. The reduceRight method calls the callbackfn function one time for each element in the array.
|
|
2032
1926
|
* @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
|
|
2033
1927
|
*/
|
|
2034
|
-
|
|
1928
|
+
reduceRight(callbackfn, initialValue) {
|
|
2035
1929
|
return this.items.reduceRight(callbackfn, initialValue);
|
|
2036
|
-
}
|
|
1930
|
+
}
|
|
2037
1931
|
/**
|
|
2038
1932
|
* Returns the value of the first element in the array where predicate is true, and undefined
|
|
2039
1933
|
* otherwise.
|
|
@@ -2043,9 +1937,9 @@
|
|
|
2043
1937
|
* @param thisArg If provided, it will be used as the this value for each invocation of
|
|
2044
1938
|
* predicate. If it is not provided, undefined is used instead.
|
|
2045
1939
|
*/
|
|
2046
|
-
|
|
1940
|
+
find(predicate, thisArg) {
|
|
2047
1941
|
return this.items.find(predicate, thisArg);
|
|
2048
|
-
}
|
|
1942
|
+
}
|
|
2049
1943
|
/**
|
|
2050
1944
|
* Returns the index of the first element in the array where predicate is true, and -1
|
|
2051
1945
|
* otherwise.
|
|
@@ -2055,9 +1949,9 @@
|
|
|
2055
1949
|
* @param thisArg If provided, it will be used as the this value for each invocation of
|
|
2056
1950
|
* predicate. If it is not provided, undefined is used instead.
|
|
2057
1951
|
*/
|
|
2058
|
-
|
|
1952
|
+
findIndex(predicate, thisArg) {
|
|
2059
1953
|
return this.items.findIndex(predicate, thisArg);
|
|
2060
|
-
}
|
|
1954
|
+
}
|
|
2061
1955
|
/**
|
|
2062
1956
|
* Returns the this object after filling the section identified by start and end with value
|
|
2063
1957
|
* @param value value to fill array section with
|
|
@@ -2066,12 +1960,12 @@
|
|
|
2066
1960
|
* @param end index to stop filling the array at. If end is negative, it is treated as
|
|
2067
1961
|
* length+end.
|
|
2068
1962
|
*/
|
|
2069
|
-
|
|
1963
|
+
fill(value, start, end) {
|
|
2070
1964
|
//
|
|
2071
1965
|
// TODO
|
|
2072
1966
|
//
|
|
2073
1967
|
throw new Error("ArraySchema#fill() not implemented");
|
|
2074
|
-
}
|
|
1968
|
+
}
|
|
2075
1969
|
/**
|
|
2076
1970
|
* Returns the this object after copying a section of the array identified by start and end
|
|
2077
1971
|
* to the same array starting at position target
|
|
@@ -2081,55 +1975,52 @@
|
|
|
2081
1975
|
* is treated as length+end.
|
|
2082
1976
|
* @param end If not specified, length of the this object is used as its default value.
|
|
2083
1977
|
*/
|
|
2084
|
-
|
|
1978
|
+
copyWithin(target, start, end) {
|
|
2085
1979
|
//
|
|
2086
1980
|
// TODO
|
|
2087
1981
|
//
|
|
2088
1982
|
throw new Error("ArraySchema#copyWithin() not implemented");
|
|
2089
|
-
}
|
|
1983
|
+
}
|
|
2090
1984
|
/**
|
|
2091
1985
|
* Returns a string representation of an array.
|
|
2092
1986
|
*/
|
|
2093
|
-
|
|
1987
|
+
toString() {
|
|
2094
1988
|
return this.items.toString();
|
|
2095
|
-
}
|
|
1989
|
+
}
|
|
2096
1990
|
/**
|
|
2097
1991
|
* Returns a string representation of an array. The elements are converted to string using their toLocalString methods.
|
|
2098
1992
|
*/
|
|
2099
|
-
|
|
1993
|
+
toLocaleString() {
|
|
2100
1994
|
return this.items.toLocaleString();
|
|
2101
|
-
}
|
|
1995
|
+
}
|
|
1996
|
+
;
|
|
2102
1997
|
/** Iterator */
|
|
2103
|
-
|
|
1998
|
+
[Symbol.iterator]() {
|
|
2104
1999
|
return this.items[Symbol.iterator]();
|
|
2105
|
-
}
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
},
|
|
2110
|
-
enumerable: false,
|
|
2111
|
-
configurable: true
|
|
2112
|
-
});
|
|
2000
|
+
}
|
|
2001
|
+
static get [Symbol.species]() {
|
|
2002
|
+
return ArraySchema;
|
|
2003
|
+
}
|
|
2113
2004
|
/**
|
|
2114
2005
|
* Returns an iterable of key, value pairs for every entry in the array
|
|
2115
2006
|
*/
|
|
2116
|
-
|
|
2007
|
+
entries() { return this.items.entries(); }
|
|
2117
2008
|
/**
|
|
2118
2009
|
* Returns an iterable of keys in the array
|
|
2119
2010
|
*/
|
|
2120
|
-
|
|
2011
|
+
keys() { return this.items.keys(); }
|
|
2121
2012
|
/**
|
|
2122
2013
|
* Returns an iterable of values in the array
|
|
2123
2014
|
*/
|
|
2124
|
-
|
|
2015
|
+
values() { return this.items.values(); }
|
|
2125
2016
|
/**
|
|
2126
2017
|
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
|
2127
2018
|
* @param searchElement The element to search for.
|
|
2128
2019
|
* @param fromIndex The position in this array at which to begin searching for searchElement.
|
|
2129
2020
|
*/
|
|
2130
|
-
|
|
2021
|
+
includes(searchElement, fromIndex) {
|
|
2131
2022
|
return this.items.includes(searchElement, fromIndex);
|
|
2132
|
-
}
|
|
2023
|
+
}
|
|
2133
2024
|
//
|
|
2134
2025
|
// ES2022
|
|
2135
2026
|
//
|
|
@@ -2144,10 +2035,10 @@
|
|
|
2144
2035
|
* thisArg is omitted, undefined is used as the this value.
|
|
2145
2036
|
*/
|
|
2146
2037
|
// @ts-ignore
|
|
2147
|
-
|
|
2038
|
+
flatMap(callback, thisArg) {
|
|
2148
2039
|
// @ts-ignore
|
|
2149
2040
|
throw new Error("ArraySchema#flatMap() is not supported.");
|
|
2150
|
-
}
|
|
2041
|
+
}
|
|
2151
2042
|
/**
|
|
2152
2043
|
* Returns a new array with all sub-array elements concatenated into it recursively up to the
|
|
2153
2044
|
* specified depth.
|
|
@@ -2155,44 +2046,43 @@
|
|
|
2155
2046
|
* @param depth The maximum recursion depth
|
|
2156
2047
|
*/
|
|
2157
2048
|
// @ts-ignore
|
|
2158
|
-
|
|
2049
|
+
flat(depth) {
|
|
2159
2050
|
throw new Error("ArraySchema#flat() is not supported.");
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2051
|
+
}
|
|
2052
|
+
findLast() {
|
|
2162
2053
|
// @ts-ignore
|
|
2163
2054
|
return this.items.findLast.apply(this.items, arguments);
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2055
|
+
}
|
|
2056
|
+
findLastIndex(...args) {
|
|
2166
2057
|
// @ts-ignore
|
|
2167
2058
|
return this.items.findLastIndex.apply(this.items, arguments);
|
|
2168
|
-
}
|
|
2059
|
+
}
|
|
2169
2060
|
//
|
|
2170
2061
|
// ES2023
|
|
2171
2062
|
//
|
|
2172
|
-
|
|
2173
|
-
|
|
2063
|
+
with(index, value) {
|
|
2064
|
+
const copy = this.items.slice();
|
|
2174
2065
|
copy[index] = value;
|
|
2175
|
-
return new
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2066
|
+
return new ArraySchema(...copy);
|
|
2067
|
+
}
|
|
2068
|
+
toReversed() {
|
|
2178
2069
|
return this.items.slice().reverse();
|
|
2179
|
-
}
|
|
2180
|
-
|
|
2070
|
+
}
|
|
2071
|
+
toSorted(compareFn) {
|
|
2181
2072
|
return this.items.slice().sort(compareFn);
|
|
2182
|
-
}
|
|
2073
|
+
}
|
|
2183
2074
|
// @ts-ignore
|
|
2184
|
-
|
|
2075
|
+
toSpliced(start, deleteCount, ...items) {
|
|
2185
2076
|
// @ts-ignore
|
|
2186
2077
|
return this.items.toSpliced.apply(copy, arguments);
|
|
2187
|
-
}
|
|
2188
|
-
|
|
2078
|
+
}
|
|
2079
|
+
[($getByIndex)](index, isEncodeAll = false) {
|
|
2189
2080
|
//
|
|
2190
2081
|
// TODO: avoid unecessary `this.tmpItems` check during decoding.
|
|
2191
2082
|
//
|
|
2192
2083
|
// ENCODING uses `this.tmpItems` (or `this.items` if `isEncodeAll` is true)
|
|
2193
2084
|
// DECODING uses `this.items`
|
|
2194
2085
|
//
|
|
2195
|
-
if (isEncodeAll === void 0) { isEncodeAll = false; }
|
|
2196
2086
|
return (isEncodeAll)
|
|
2197
2087
|
? this.items[index]
|
|
2198
2088
|
: this.deletedIndexes[index]
|
|
@@ -2201,63 +2091,79 @@
|
|
|
2201
2091
|
// return (isEncodeAll)
|
|
2202
2092
|
// ? this.items[index]
|
|
2203
2093
|
// : this.tmpItems[index] ?? this.items[index];
|
|
2204
|
-
}
|
|
2205
|
-
|
|
2094
|
+
}
|
|
2095
|
+
[$deleteByIndex](index) {
|
|
2206
2096
|
this.items[index] = undefined;
|
|
2207
|
-
}
|
|
2208
|
-
|
|
2097
|
+
}
|
|
2098
|
+
[$onEncodeEnd]() {
|
|
2209
2099
|
this.tmpItems = this.items.slice();
|
|
2210
2100
|
this.deletedIndexes = {};
|
|
2211
|
-
}
|
|
2212
|
-
|
|
2213
|
-
this.items = this.items.filter(
|
|
2214
|
-
}
|
|
2215
|
-
|
|
2101
|
+
}
|
|
2102
|
+
[$onDecodeEnd]() {
|
|
2103
|
+
this.items = this.items.filter((item) => item !== undefined);
|
|
2104
|
+
}
|
|
2105
|
+
toArray() {
|
|
2216
2106
|
return this.items.slice(0);
|
|
2217
|
-
}
|
|
2218
|
-
|
|
2219
|
-
return this.toArray().map(
|
|
2107
|
+
}
|
|
2108
|
+
toJSON() {
|
|
2109
|
+
return this.toArray().map((value) => {
|
|
2220
2110
|
return (typeof (value['toJSON']) === "function")
|
|
2221
2111
|
? value['toJSON']()
|
|
2222
2112
|
: value;
|
|
2223
2113
|
});
|
|
2224
|
-
}
|
|
2114
|
+
}
|
|
2225
2115
|
//
|
|
2226
2116
|
// Decoding utilities
|
|
2227
2117
|
//
|
|
2228
|
-
|
|
2229
|
-
|
|
2118
|
+
clone(isDecoding) {
|
|
2119
|
+
let cloned;
|
|
2230
2120
|
if (isDecoding) {
|
|
2231
2121
|
cloned = new ArraySchema();
|
|
2232
|
-
cloned.push
|
|
2122
|
+
cloned.push(...this.items);
|
|
2233
2123
|
}
|
|
2234
2124
|
else {
|
|
2235
|
-
cloned = new
|
|
2125
|
+
cloned = new ArraySchema(...this.map(item => ((item[$changes])
|
|
2236
2126
|
? item.clone()
|
|
2237
|
-
: item)
|
|
2127
|
+
: item)));
|
|
2238
2128
|
}
|
|
2239
2129
|
return cloned;
|
|
2240
|
-
}
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
ArraySchema[_b] = decodeArray;
|
|
2244
|
-
return ArraySchema;
|
|
2245
|
-
}());
|
|
2130
|
+
}
|
|
2131
|
+
;
|
|
2132
|
+
}
|
|
2246
2133
|
registerType("array", { constructor: ArraySchema });
|
|
2247
2134
|
|
|
2248
|
-
var
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2135
|
+
var _a$3, _b$3;
|
|
2136
|
+
class MapSchema {
|
|
2137
|
+
static { this[_a$3] = encodeKeyValueOperation; }
|
|
2138
|
+
static { this[_b$3] = decodeKeyValueOperation; }
|
|
2139
|
+
/**
|
|
2140
|
+
* Determine if a property must be filtered.
|
|
2141
|
+
* - If returns false, the property is NOT going to be encoded.
|
|
2142
|
+
* - If returns true, the property is going to be encoded.
|
|
2143
|
+
*
|
|
2144
|
+
* Encoding with "filters" happens in two steps:
|
|
2145
|
+
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
2146
|
+
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
2147
|
+
*/
|
|
2148
|
+
static [(_a$3 = $encoder, _b$3 = $decoder, $filter)](ref, index, view) {
|
|
2149
|
+
return (!view ||
|
|
2150
|
+
typeof (ref[$childType]) === "string" ||
|
|
2151
|
+
view.items.has(ref[$getByIndex](index)[$changes]));
|
|
2152
|
+
}
|
|
2153
|
+
static is(type) {
|
|
2154
|
+
return type['map'] !== undefined;
|
|
2155
|
+
}
|
|
2156
|
+
constructor(initialValues) {
|
|
2157
|
+
this.$items = new Map();
|
|
2158
|
+
this.$indexes = new Map();
|
|
2253
2159
|
this[$changes] = new ChangeTree(this);
|
|
2254
2160
|
if (initialValues) {
|
|
2255
2161
|
if (initialValues instanceof Map ||
|
|
2256
2162
|
initialValues instanceof MapSchema) {
|
|
2257
|
-
initialValues.forEach(
|
|
2163
|
+
initialValues.forEach((v, k) => this.set(k, v));
|
|
2258
2164
|
}
|
|
2259
2165
|
else {
|
|
2260
|
-
for (
|
|
2166
|
+
for (const k in initialValues) {
|
|
2261
2167
|
this.set(k, initialValues[k]);
|
|
2262
2168
|
}
|
|
2263
2169
|
}
|
|
@@ -2269,53 +2175,27 @@
|
|
|
2269
2175
|
configurable: true,
|
|
2270
2176
|
});
|
|
2271
2177
|
}
|
|
2272
|
-
/**
|
|
2273
|
-
* Determine if a property must be filtered.
|
|
2274
|
-
* - If returns false, the property is NOT going to be encoded.
|
|
2275
|
-
* - If returns true, the property is going to be encoded.
|
|
2276
|
-
*
|
|
2277
|
-
* Encoding with "filters" happens in two steps:
|
|
2278
|
-
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
2279
|
-
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
2280
|
-
*/
|
|
2281
|
-
MapSchema[(_a = $encoder, _b = $decoder, $filter)] = function (ref, index, view) {
|
|
2282
|
-
return (!view ||
|
|
2283
|
-
typeof (ref[$childType]) === "string" ||
|
|
2284
|
-
view.items.has(ref[$getByIndex](index)[$changes]));
|
|
2285
|
-
};
|
|
2286
|
-
MapSchema.is = function (type) {
|
|
2287
|
-
return type['map'] !== undefined;
|
|
2288
|
-
};
|
|
2289
2178
|
/** Iterator */
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
configurable: true
|
|
2295
|
-
});
|
|
2296
|
-
Object.defineProperty(MapSchema, Symbol.species, {
|
|
2297
|
-
get: function () { return MapSchema; },
|
|
2298
|
-
enumerable: false,
|
|
2299
|
-
configurable: true
|
|
2300
|
-
});
|
|
2301
|
-
MapSchema.prototype.set = function (key, value) {
|
|
2302
|
-
var _c;
|
|
2179
|
+
[Symbol.iterator]() { return this.$items[Symbol.iterator](); }
|
|
2180
|
+
get [Symbol.toStringTag]() { return this.$items[Symbol.toStringTag]; }
|
|
2181
|
+
static get [Symbol.species]() { return MapSchema; }
|
|
2182
|
+
set(key, value) {
|
|
2303
2183
|
if (value === undefined || value === null) {
|
|
2304
|
-
throw new Error(
|
|
2184
|
+
throw new Error(`MapSchema#set('${key}', ${value}): trying to set ${value} value on '${key}'.`);
|
|
2305
2185
|
}
|
|
2306
2186
|
// Force "key" as string
|
|
2307
2187
|
// See: https://github.com/colyseus/colyseus/issues/561#issuecomment-1646733468
|
|
2308
2188
|
key = key.toString();
|
|
2309
|
-
|
|
2189
|
+
const changeTree = this[$changes];
|
|
2310
2190
|
// get "index" for this value.
|
|
2311
|
-
|
|
2312
|
-
|
|
2191
|
+
const isReplace = typeof (changeTree.indexes[key]) !== "undefined";
|
|
2192
|
+
const index = (isReplace)
|
|
2313
2193
|
? changeTree.indexes[key]
|
|
2314
|
-
:
|
|
2315
|
-
|
|
2194
|
+
: changeTree.indexes[-1] ?? 0;
|
|
2195
|
+
let operation = (isReplace)
|
|
2316
2196
|
? exports.OPERATION.REPLACE
|
|
2317
2197
|
: exports.OPERATION.ADD;
|
|
2318
|
-
|
|
2198
|
+
const isRef = (value[$changes]) !== undefined;
|
|
2319
2199
|
//
|
|
2320
2200
|
// (encoding)
|
|
2321
2201
|
// set a unique id to relate directly with this key/value.
|
|
@@ -2344,17 +2224,17 @@
|
|
|
2344
2224
|
value[$changes].setParent(this, changeTree.root, index);
|
|
2345
2225
|
}
|
|
2346
2226
|
return this;
|
|
2347
|
-
}
|
|
2348
|
-
|
|
2227
|
+
}
|
|
2228
|
+
get(key) {
|
|
2349
2229
|
return this.$items.get(key);
|
|
2350
|
-
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2230
|
+
}
|
|
2231
|
+
delete(key) {
|
|
2232
|
+
const index = this[$changes].indexes[key];
|
|
2353
2233
|
this[$changes].delete(index);
|
|
2354
2234
|
return this.$items.delete(key);
|
|
2355
|
-
}
|
|
2356
|
-
|
|
2357
|
-
|
|
2235
|
+
}
|
|
2236
|
+
clear() {
|
|
2237
|
+
const changeTree = this[$changes];
|
|
2358
2238
|
// discard previous operations.
|
|
2359
2239
|
changeTree.discard(true);
|
|
2360
2240
|
changeTree.indexes = {};
|
|
@@ -2363,69 +2243,64 @@
|
|
|
2363
2243
|
// clear items
|
|
2364
2244
|
this.$items.clear();
|
|
2365
2245
|
changeTree.operation(exports.OPERATION.CLEAR);
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2246
|
+
}
|
|
2247
|
+
has(key) {
|
|
2368
2248
|
return this.$items.has(key);
|
|
2369
|
-
}
|
|
2370
|
-
|
|
2249
|
+
}
|
|
2250
|
+
forEach(callbackfn) {
|
|
2371
2251
|
this.$items.forEach(callbackfn);
|
|
2372
|
-
}
|
|
2373
|
-
|
|
2252
|
+
}
|
|
2253
|
+
entries() {
|
|
2374
2254
|
return this.$items.entries();
|
|
2375
|
-
}
|
|
2376
|
-
|
|
2255
|
+
}
|
|
2256
|
+
keys() {
|
|
2377
2257
|
return this.$items.keys();
|
|
2378
|
-
}
|
|
2379
|
-
|
|
2258
|
+
}
|
|
2259
|
+
values() {
|
|
2380
2260
|
return this.$items.values();
|
|
2381
|
-
}
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
enumerable: false,
|
|
2387
|
-
configurable: true
|
|
2388
|
-
});
|
|
2389
|
-
MapSchema.prototype.setIndex = function (index, key) {
|
|
2261
|
+
}
|
|
2262
|
+
get size() {
|
|
2263
|
+
return this.$items.size;
|
|
2264
|
+
}
|
|
2265
|
+
setIndex(index, key) {
|
|
2390
2266
|
this.$indexes.set(index, key);
|
|
2391
|
-
}
|
|
2392
|
-
|
|
2267
|
+
}
|
|
2268
|
+
getIndex(index) {
|
|
2393
2269
|
return this.$indexes.get(index);
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2270
|
+
}
|
|
2271
|
+
[$getByIndex](index) {
|
|
2396
2272
|
return this.$items.get(this.$indexes.get(index));
|
|
2397
|
-
}
|
|
2398
|
-
|
|
2399
|
-
|
|
2273
|
+
}
|
|
2274
|
+
[$deleteByIndex](index) {
|
|
2275
|
+
const key = this.$indexes.get(index);
|
|
2400
2276
|
this.$items.delete(key);
|
|
2401
2277
|
this.$indexes.delete(index);
|
|
2402
|
-
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
for (
|
|
2407
|
-
var _c = changes_1[_i], fieldIndex = _c[0], operation = _c[1];
|
|
2278
|
+
}
|
|
2279
|
+
[$onEncodeEnd]() {
|
|
2280
|
+
const changeTree = this[$changes];
|
|
2281
|
+
const changes = changeTree.changes.entries();
|
|
2282
|
+
for (const [fieldIndex, operation] of changes) {
|
|
2408
2283
|
if (operation === exports.OPERATION.DELETE) {
|
|
2409
|
-
|
|
2284
|
+
const index = this[$getByIndex](fieldIndex);
|
|
2410
2285
|
delete changeTree.indexes[index];
|
|
2411
2286
|
}
|
|
2412
2287
|
}
|
|
2413
|
-
}
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
this.forEach(
|
|
2288
|
+
}
|
|
2289
|
+
toJSON() {
|
|
2290
|
+
const map = {};
|
|
2291
|
+
this.forEach((value, key) => {
|
|
2417
2292
|
map[key] = (typeof (value['toJSON']) === "function")
|
|
2418
2293
|
? value['toJSON']()
|
|
2419
2294
|
: value;
|
|
2420
2295
|
});
|
|
2421
2296
|
return map;
|
|
2422
|
-
}
|
|
2297
|
+
}
|
|
2423
2298
|
//
|
|
2424
2299
|
// Decoding utilities
|
|
2425
2300
|
//
|
|
2426
2301
|
// @ts-ignore
|
|
2427
|
-
|
|
2428
|
-
|
|
2302
|
+
clone(isDecoding) {
|
|
2303
|
+
let cloned;
|
|
2429
2304
|
if (isDecoding) {
|
|
2430
2305
|
// client-side
|
|
2431
2306
|
cloned = Object.assign(new MapSchema(), this);
|
|
@@ -2433,7 +2308,7 @@
|
|
|
2433
2308
|
else {
|
|
2434
2309
|
// server-side
|
|
2435
2310
|
cloned = new MapSchema();
|
|
2436
|
-
this.forEach(
|
|
2311
|
+
this.forEach((value, key) => {
|
|
2437
2312
|
if (value[$changes]) {
|
|
2438
2313
|
cloned.set(key, value['clone']());
|
|
2439
2314
|
}
|
|
@@ -2443,43 +2318,43 @@
|
|
|
2443
2318
|
});
|
|
2444
2319
|
}
|
|
2445
2320
|
return cloned;
|
|
2446
|
-
}
|
|
2447
|
-
|
|
2448
|
-
MapSchema[_a] = encodeKeyValueOperation;
|
|
2449
|
-
MapSchema[_b] = decodeKeyValueOperation;
|
|
2450
|
-
return MapSchema;
|
|
2451
|
-
}());
|
|
2321
|
+
}
|
|
2322
|
+
}
|
|
2452
2323
|
registerType("map", { constructor: MapSchema });
|
|
2453
2324
|
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
}
|
|
2464
|
-
TypeContext.register = function (target) {
|
|
2465
|
-
var parent = Object.getPrototypeOf(target);
|
|
2325
|
+
const DEFAULT_VIEW_TAG = -1;
|
|
2326
|
+
class TypeContext {
|
|
2327
|
+
/**
|
|
2328
|
+
* For inheritance support
|
|
2329
|
+
* Keeps track of which classes extends which. (parent -> children)
|
|
2330
|
+
*/
|
|
2331
|
+
static { this.inheritedTypes = new Map(); }
|
|
2332
|
+
static register(target) {
|
|
2333
|
+
const parent = Object.getPrototypeOf(target);
|
|
2466
2334
|
if (parent !== Schema) {
|
|
2467
|
-
|
|
2335
|
+
let inherits = TypeContext.inheritedTypes.get(parent);
|
|
2468
2336
|
if (!inherits) {
|
|
2469
2337
|
inherits = new Set();
|
|
2470
2338
|
TypeContext.inheritedTypes.set(parent, inherits);
|
|
2471
2339
|
}
|
|
2472
2340
|
inherits.add(target);
|
|
2473
2341
|
}
|
|
2474
|
-
}
|
|
2475
|
-
|
|
2342
|
+
}
|
|
2343
|
+
constructor(rootClass) {
|
|
2344
|
+
this.types = {};
|
|
2345
|
+
this.schemas = new Map();
|
|
2346
|
+
this.hasFilters = false;
|
|
2347
|
+
if (rootClass) {
|
|
2348
|
+
this.discoverTypes(rootClass);
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
has(schema) {
|
|
2476
2352
|
return this.schemas.has(schema);
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2353
|
+
}
|
|
2354
|
+
get(typeid) {
|
|
2479
2355
|
return this.types[typeid];
|
|
2480
|
-
}
|
|
2481
|
-
|
|
2482
|
-
if (typeid === void 0) { typeid = this.schemas.size; }
|
|
2356
|
+
}
|
|
2357
|
+
add(schema, typeid = this.schemas.size) {
|
|
2483
2358
|
// skip if already registered
|
|
2484
2359
|
if (this.schemas.has(schema)) {
|
|
2485
2360
|
return false;
|
|
@@ -2487,62 +2362,54 @@
|
|
|
2487
2362
|
this.types[typeid] = schema;
|
|
2488
2363
|
this.schemas.set(schema, typeid);
|
|
2489
2364
|
return true;
|
|
2490
|
-
}
|
|
2491
|
-
|
|
2365
|
+
}
|
|
2366
|
+
getTypeId(klass) {
|
|
2492
2367
|
return this.schemas.get(klass);
|
|
2493
|
-
}
|
|
2494
|
-
|
|
2495
|
-
var _this = this;
|
|
2496
|
-
var _a;
|
|
2368
|
+
}
|
|
2369
|
+
discoverTypes(klass) {
|
|
2497
2370
|
if (!this.add(klass)) {
|
|
2498
2371
|
return;
|
|
2499
2372
|
}
|
|
2500
2373
|
// add classes inherited from this base class
|
|
2501
|
-
|
|
2502
|
-
|
|
2374
|
+
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
2375
|
+
this.discoverTypes(child);
|
|
2503
2376
|
});
|
|
2504
2377
|
// skip if no fields are defined for this class.
|
|
2505
2378
|
if (klass[Symbol.metadata] === undefined) {
|
|
2506
2379
|
klass[Symbol.metadata] = {};
|
|
2507
2380
|
}
|
|
2508
2381
|
// const metadata = Metadata.getFor(klass);
|
|
2509
|
-
|
|
2382
|
+
const metadata = klass[Symbol.metadata];
|
|
2510
2383
|
// if any schema/field has filters, mark "context" as having filters.
|
|
2511
2384
|
if (metadata[-2]) {
|
|
2512
2385
|
this.hasFilters = true;
|
|
2513
2386
|
}
|
|
2514
|
-
for (
|
|
2515
|
-
|
|
2387
|
+
for (const field in metadata) {
|
|
2388
|
+
const fieldType = metadata[field].type;
|
|
2516
2389
|
if (typeof (fieldType) === "string") {
|
|
2517
2390
|
continue;
|
|
2518
2391
|
}
|
|
2519
2392
|
if (Array.isArray(fieldType)) {
|
|
2520
|
-
|
|
2521
|
-
if (
|
|
2393
|
+
const type = fieldType[0];
|
|
2394
|
+
if (type === "string") {
|
|
2522
2395
|
continue;
|
|
2523
2396
|
}
|
|
2524
|
-
this.discoverTypes(
|
|
2397
|
+
this.discoverTypes(type);
|
|
2525
2398
|
}
|
|
2526
2399
|
else if (typeof (fieldType) === "function") {
|
|
2527
2400
|
this.discoverTypes(fieldType);
|
|
2528
2401
|
}
|
|
2529
2402
|
else {
|
|
2530
|
-
|
|
2403
|
+
const type = Object.values(fieldType)[0];
|
|
2531
2404
|
// skip primitive types
|
|
2532
|
-
if (typeof (
|
|
2405
|
+
if (typeof (type) === "string") {
|
|
2533
2406
|
continue;
|
|
2534
2407
|
}
|
|
2535
|
-
this.discoverTypes(
|
|
2408
|
+
this.discoverTypes(type);
|
|
2536
2409
|
}
|
|
2537
2410
|
}
|
|
2538
|
-
}
|
|
2539
|
-
|
|
2540
|
-
* For inheritance support
|
|
2541
|
-
* Keeps track of which classes extends which. (parent -> children)
|
|
2542
|
-
*/
|
|
2543
|
-
TypeContext.inheritedTypes = new Map();
|
|
2544
|
-
return TypeContext;
|
|
2545
|
-
}());
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2546
2413
|
/**
|
|
2547
2414
|
* [See documentation](https://docs.colyseus.io/state/schema/)
|
|
2548
2415
|
*
|
|
@@ -2685,24 +2552,21 @@
|
|
|
2685
2552
|
// };
|
|
2686
2553
|
// }
|
|
2687
2554
|
// }
|
|
2688
|
-
function view(tag) {
|
|
2689
|
-
if (tag === void 0) { tag = DEFAULT_VIEW_TAG; }
|
|
2555
|
+
function view(tag = DEFAULT_VIEW_TAG) {
|
|
2690
2556
|
return function (target, fieldName) {
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
var parentMetadata = parentClass[Symbol.metadata];
|
|
2696
|
-
var metadata = ((_a = constructor[_d = Symbol.metadata]) !== null && _a !== void 0 ? _a : (constructor[_d] = Object.assign({}, constructor[Symbol.metadata], parentMetadata !== null && parentMetadata !== void 0 ? parentMetadata : Object.create(null))));
|
|
2557
|
+
const constructor = target.constructor;
|
|
2558
|
+
const parentClass = Object.getPrototypeOf(constructor);
|
|
2559
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
2560
|
+
const metadata = (constructor[Symbol.metadata] ??= Object.assign({}, constructor[Symbol.metadata], parentMetadata ?? Object.create(null)));
|
|
2697
2561
|
if (!metadata[fieldName]) {
|
|
2698
2562
|
//
|
|
2699
2563
|
// detect index for this field, considering inheritance
|
|
2700
2564
|
//
|
|
2701
2565
|
metadata[fieldName] = {
|
|
2702
2566
|
type: undefined,
|
|
2703
|
-
index: (
|
|
2704
|
-
|
|
2705
|
-
|
|
2567
|
+
index: (metadata[-1] // current structure already has fields defined
|
|
2568
|
+
?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
|
|
2569
|
+
?? -1) + 1 // no fields defined
|
|
2706
2570
|
};
|
|
2707
2571
|
}
|
|
2708
2572
|
Metadata.setTag(metadata, fieldName, tag);
|
|
@@ -2710,18 +2574,16 @@
|
|
|
2710
2574
|
}
|
|
2711
2575
|
function type(type, options) {
|
|
2712
2576
|
return function (target, field) {
|
|
2713
|
-
|
|
2714
|
-
var _d;
|
|
2715
|
-
var constructor = target.constructor;
|
|
2577
|
+
const constructor = target.constructor;
|
|
2716
2578
|
if (!type) {
|
|
2717
|
-
throw new Error(
|
|
2579
|
+
throw new Error(`${constructor.name}: @type() reference provided for "${field}" is undefined. Make sure you don't have any circular dependencies.`);
|
|
2718
2580
|
}
|
|
2719
2581
|
// for inheritance support
|
|
2720
2582
|
TypeContext.register(constructor);
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2583
|
+
const parentClass = Object.getPrototypeOf(constructor);
|
|
2584
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
2585
|
+
const metadata = (constructor[Symbol.metadata] ??= Object.assign({}, constructor[Symbol.metadata], parentMetadata ?? Object.create(null)));
|
|
2586
|
+
let fieldIndex;
|
|
2725
2587
|
/**
|
|
2726
2588
|
* skip if descriptor already exists for this field (`@deprecated()`)
|
|
2727
2589
|
*/
|
|
@@ -2734,11 +2596,11 @@
|
|
|
2734
2596
|
// trying to define same property multiple times across inheritance.
|
|
2735
2597
|
// https://github.com/colyseus/colyseus-unity3d/issues/131#issuecomment-814308572
|
|
2736
2598
|
try {
|
|
2737
|
-
throw new Error(
|
|
2599
|
+
throw new Error(`@colyseus/schema: Duplicate '${field}' definition on '${constructor.name}'.\nCheck @type() annotation`);
|
|
2738
2600
|
}
|
|
2739
2601
|
catch (e) {
|
|
2740
|
-
|
|
2741
|
-
throw new Error(
|
|
2602
|
+
const definitionAtLine = e.stack.split("\n")[4].trim();
|
|
2603
|
+
throw new Error(`${e.message} ${definitionAtLine}`);
|
|
2742
2604
|
}
|
|
2743
2605
|
}
|
|
2744
2606
|
else {
|
|
@@ -2749,9 +2611,9 @@
|
|
|
2749
2611
|
//
|
|
2750
2612
|
// detect index for this field, considering inheritance
|
|
2751
2613
|
//
|
|
2752
|
-
fieldIndex =
|
|
2753
|
-
|
|
2754
|
-
|
|
2614
|
+
fieldIndex = metadata[-1] // current structure already has fields defined
|
|
2615
|
+
?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
|
|
2616
|
+
?? -1; // no fields defined
|
|
2755
2617
|
fieldIndex++;
|
|
2756
2618
|
}
|
|
2757
2619
|
if (options && options.manual) {
|
|
@@ -2763,13 +2625,13 @@
|
|
|
2763
2625
|
});
|
|
2764
2626
|
}
|
|
2765
2627
|
else {
|
|
2766
|
-
|
|
2628
|
+
const complexTypeKlass = (Array.isArray(type))
|
|
2767
2629
|
? getType("array")
|
|
2768
2630
|
: (typeof (Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
|
|
2769
|
-
|
|
2631
|
+
const childType = (complexTypeKlass)
|
|
2770
2632
|
? Object.values(type)[0]
|
|
2771
2633
|
: type;
|
|
2772
|
-
Metadata.addField(metadata, fieldIndex, field, type, getPropertyDescriptor(
|
|
2634
|
+
Metadata.addField(metadata, fieldIndex, field, type, getPropertyDescriptor(`_${field}`, fieldIndex, childType, complexTypeKlass, metadata, field));
|
|
2773
2635
|
}
|
|
2774
2636
|
};
|
|
2775
2637
|
}
|
|
@@ -2777,8 +2639,7 @@
|
|
|
2777
2639
|
return {
|
|
2778
2640
|
get: function () { return this[fieldCached]; },
|
|
2779
2641
|
set: function (value) {
|
|
2780
|
-
|
|
2781
|
-
var previousValue = this[fieldCached] || undefined;
|
|
2642
|
+
const previousValue = this[fieldCached] || undefined;
|
|
2782
2643
|
// skip if value is the same as cached.
|
|
2783
2644
|
if (value === previousValue) {
|
|
2784
2645
|
return;
|
|
@@ -2788,7 +2649,7 @@
|
|
|
2788
2649
|
if (complexTypeKlass) {
|
|
2789
2650
|
// automaticallty transform Array into ArraySchema
|
|
2790
2651
|
if (complexTypeKlass.constructor === ArraySchema && !(value instanceof ArraySchema)) {
|
|
2791
|
-
value = new
|
|
2652
|
+
value = new ArraySchema(...value);
|
|
2792
2653
|
}
|
|
2793
2654
|
// automaticallty transform Map into MapSchema
|
|
2794
2655
|
if (complexTypeKlass.constructor === MapSchema && !(value instanceof MapSchema)) {
|
|
@@ -2801,7 +2662,7 @@
|
|
|
2801
2662
|
// TODO: if there are other references to this instance, we should not remove it from root.
|
|
2802
2663
|
//
|
|
2803
2664
|
if (previousValue !== undefined && previousValue[$changes]) {
|
|
2804
|
-
|
|
2665
|
+
this[$changes].root?.remove(previousValue[$changes]);
|
|
2805
2666
|
}
|
|
2806
2667
|
// flag the change for encoding.
|
|
2807
2668
|
this.constructor[$track](this[$changes], fieldIndex, exports.OPERATION.ADD);
|
|
@@ -2829,33 +2690,30 @@
|
|
|
2829
2690
|
* `@deprecated()` flag a field as deprecated.
|
|
2830
2691
|
* The previous `@type()` annotation should remain along with this one.
|
|
2831
2692
|
*/
|
|
2832
|
-
function deprecated(throws) {
|
|
2833
|
-
if (throws === void 0) { throws = true; }
|
|
2693
|
+
function deprecated(throws = true) {
|
|
2834
2694
|
return function (klass, field) {
|
|
2835
|
-
var _a, _b, _c;
|
|
2836
|
-
var _d;
|
|
2837
2695
|
//
|
|
2838
2696
|
// FIXME: the following block of code is repeated across `@type()`, `@deprecated()` and `@unreliable()` decorators.
|
|
2839
2697
|
//
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2698
|
+
const constructor = klass.constructor;
|
|
2699
|
+
const parentClass = Object.getPrototypeOf(constructor);
|
|
2700
|
+
const parentMetadata = parentClass[Symbol.metadata];
|
|
2701
|
+
const metadata = (constructor[Symbol.metadata] ??= Object.assign({}, constructor[Symbol.metadata], parentMetadata ?? Object.create(null)));
|
|
2844
2702
|
if (!metadata[field]) {
|
|
2845
2703
|
//
|
|
2846
2704
|
// detect index for this field, considering inheritance
|
|
2847
2705
|
//
|
|
2848
2706
|
metadata[field] = {
|
|
2849
2707
|
type: undefined,
|
|
2850
|
-
index: (
|
|
2851
|
-
|
|
2852
|
-
|
|
2708
|
+
index: (metadata[-1] // current structure already has fields defined
|
|
2709
|
+
?? (parentMetadata && parentMetadata[-1]) // parent structure has fields defined
|
|
2710
|
+
?? -1) + 1 // no fields defined
|
|
2853
2711
|
};
|
|
2854
2712
|
}
|
|
2855
2713
|
metadata[field].deprecated = true;
|
|
2856
2714
|
if (throws) {
|
|
2857
2715
|
metadata[field].descriptor = {
|
|
2858
|
-
get: function () { throw new Error(
|
|
2716
|
+
get: function () { throw new Error(`${field} is deprecated.`); },
|
|
2859
2717
|
set: function (value) { },
|
|
2860
2718
|
enumerable: false,
|
|
2861
2719
|
configurable: true
|
|
@@ -2870,27 +2728,25 @@
|
|
|
2870
2728
|
};
|
|
2871
2729
|
}
|
|
2872
2730
|
function defineTypes(target, fields, options) {
|
|
2873
|
-
for (
|
|
2731
|
+
for (let field in fields) {
|
|
2874
2732
|
type(fields[field], options)(target.prototype, field);
|
|
2875
2733
|
}
|
|
2876
2734
|
return target;
|
|
2877
2735
|
}
|
|
2878
2736
|
|
|
2879
2737
|
function getIndent(level) {
|
|
2880
|
-
return (new Array(level).fill(0)).map(
|
|
2881
|
-
return (i === level - 1) ? "\u2514\u2500 " : " ";
|
|
2882
|
-
}).join("");
|
|
2738
|
+
return (new Array(level).fill(0)).map((_, i) => (i === level - 1) ? `└─ ` : ` `).join("");
|
|
2883
2739
|
}
|
|
2884
2740
|
function dumpChanges(schema) {
|
|
2885
|
-
|
|
2886
|
-
|
|
2741
|
+
const $root = schema[$changes].root;
|
|
2742
|
+
const dump = {
|
|
2887
2743
|
ops: {},
|
|
2888
2744
|
refs: []
|
|
2889
2745
|
};
|
|
2890
|
-
$root.changes.forEach(
|
|
2891
|
-
dump.refs.push(
|
|
2892
|
-
operations.forEach(
|
|
2893
|
-
|
|
2746
|
+
$root.changes.forEach((operations, changeTree) => {
|
|
2747
|
+
dump.refs.push(`refId#${changeTree.refId}`);
|
|
2748
|
+
operations.forEach((op, index) => {
|
|
2749
|
+
const opName = exports.OPERATION[op];
|
|
2894
2750
|
if (!dump.ops[opName]) {
|
|
2895
2751
|
dump.ops[opName] = 0;
|
|
2896
2752
|
}
|
|
@@ -2905,7 +2761,7 @@
|
|
|
2905
2761
|
return number;
|
|
2906
2762
|
}
|
|
2907
2763
|
// Find the position of the most significant bit
|
|
2908
|
-
|
|
2764
|
+
let msbPosition = 0;
|
|
2909
2765
|
while (number > 0) {
|
|
2910
2766
|
number >>= 1;
|
|
2911
2767
|
msbPosition++;
|
|
@@ -2914,40 +2770,29 @@
|
|
|
2914
2770
|
return 1 << msbPosition;
|
|
2915
2771
|
}
|
|
2916
2772
|
|
|
2773
|
+
var _a$2, _b$2;
|
|
2917
2774
|
/**
|
|
2918
2775
|
* Schema encoder / decoder
|
|
2919
2776
|
*/
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
var args = [];
|
|
2924
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
2925
|
-
args[_i] = arguments[_i];
|
|
2926
|
-
}
|
|
2927
|
-
Schema.initialize(this);
|
|
2928
|
-
//
|
|
2929
|
-
// Assign initial values
|
|
2930
|
-
//
|
|
2931
|
-
if (args[0]) {
|
|
2932
|
-
this.assign(args[0]);
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2777
|
+
class Schema {
|
|
2778
|
+
static { this[_a$2] = encodeSchemaOperation; }
|
|
2779
|
+
static { this[_b$2] = decodeSchemaOperation; }
|
|
2935
2780
|
/**
|
|
2936
2781
|
* Assign the property descriptors required to track changes on this instance.
|
|
2937
2782
|
* @param instance
|
|
2938
2783
|
*/
|
|
2939
|
-
|
|
2784
|
+
static initialize(instance) {
|
|
2940
2785
|
Object.defineProperty(instance, $changes, {
|
|
2941
2786
|
value: new ChangeTree(instance),
|
|
2942
2787
|
enumerable: false,
|
|
2943
2788
|
writable: true
|
|
2944
2789
|
});
|
|
2945
|
-
|
|
2790
|
+
const metadata = instance.constructor[Symbol.metadata];
|
|
2946
2791
|
// Define property descriptors
|
|
2947
|
-
for (
|
|
2792
|
+
for (const field in metadata) {
|
|
2948
2793
|
if (metadata[field].descriptor) {
|
|
2949
2794
|
// for encoder
|
|
2950
|
-
Object.defineProperty(instance,
|
|
2795
|
+
Object.defineProperty(instance, `_${field}`, {
|
|
2951
2796
|
value: undefined,
|
|
2952
2797
|
writable: true,
|
|
2953
2798
|
enumerable: false,
|
|
@@ -2971,19 +2816,18 @@
|
|
|
2971
2816
|
// instance[field] = args[0][field];
|
|
2972
2817
|
// }
|
|
2973
2818
|
}
|
|
2974
|
-
}
|
|
2975
|
-
|
|
2819
|
+
}
|
|
2820
|
+
static is(type) {
|
|
2976
2821
|
return typeof (type[Symbol.metadata]) === "object";
|
|
2977
2822
|
// const metadata = type[Symbol.metadata];
|
|
2978
2823
|
// return metadata && Object.prototype.hasOwnProperty.call(metadata, -1);
|
|
2979
|
-
}
|
|
2824
|
+
}
|
|
2980
2825
|
/**
|
|
2981
2826
|
* Track property changes
|
|
2982
2827
|
*/
|
|
2983
|
-
|
|
2984
|
-
if (operation === void 0) { operation = exports.OPERATION.ADD; }
|
|
2828
|
+
static [(_a$2 = $encoder, _b$2 = $decoder, $track)](changeTree, index, operation = exports.OPERATION.ADD) {
|
|
2985
2829
|
changeTree.change(index, operation);
|
|
2986
|
-
}
|
|
2830
|
+
}
|
|
2987
2831
|
/**
|
|
2988
2832
|
* Determine if a property must be filtered.
|
|
2989
2833
|
* - If returns false, the property is NOT going to be encoded.
|
|
@@ -2993,10 +2837,9 @@
|
|
|
2993
2837
|
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
2994
2838
|
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
2995
2839
|
*/
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
var tag = metadata[metadata[index]].tag;
|
|
2840
|
+
static [$filter](ref, index, view) {
|
|
2841
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
2842
|
+
const tag = metadata[metadata[index]].tag;
|
|
3000
2843
|
if (view === undefined) {
|
|
3001
2844
|
// shared pass/encode: encode if doesn't have a tag
|
|
3002
2845
|
return tag === undefined;
|
|
@@ -3011,34 +2854,43 @@
|
|
|
3011
2854
|
}
|
|
3012
2855
|
else {
|
|
3013
2856
|
// view pass: custom tag
|
|
3014
|
-
|
|
2857
|
+
const tags = view.tags?.get(ref[$changes]);
|
|
3015
2858
|
return tags && tags.has(tag);
|
|
3016
2859
|
}
|
|
3017
|
-
}
|
|
3018
|
-
|
|
2860
|
+
}
|
|
2861
|
+
// allow inherited classes to have a constructor
|
|
2862
|
+
constructor(...args) {
|
|
2863
|
+
Schema.initialize(this);
|
|
2864
|
+
//
|
|
2865
|
+
// Assign initial values
|
|
2866
|
+
//
|
|
2867
|
+
if (args[0]) {
|
|
2868
|
+
this.assign(args[0]);
|
|
2869
|
+
}
|
|
2870
|
+
}
|
|
2871
|
+
assign(props) {
|
|
3019
2872
|
Object.assign(this, props);
|
|
3020
2873
|
return this;
|
|
3021
|
-
}
|
|
2874
|
+
}
|
|
3022
2875
|
/**
|
|
3023
2876
|
* (Server-side): Flag a property to be encoded for the next patch.
|
|
3024
2877
|
* @param instance Schema instance
|
|
3025
2878
|
* @param property string representing the property name, or number representing the index of the property.
|
|
3026
2879
|
* @param operation OPERATION to perform (detected automatically)
|
|
3027
2880
|
*/
|
|
3028
|
-
|
|
2881
|
+
setDirty(property, operation) {
|
|
3029
2882
|
this[$changes].change(this.constructor[Symbol.metadata][property].index, operation);
|
|
3030
|
-
}
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
var metadata = this.constructor[Symbol.metadata];
|
|
2883
|
+
}
|
|
2884
|
+
clone() {
|
|
2885
|
+
const cloned = new (this.constructor);
|
|
2886
|
+
const metadata = this.constructor[Symbol.metadata];
|
|
3035
2887
|
//
|
|
3036
2888
|
// TODO: clone all properties, not only annotated ones
|
|
3037
2889
|
//
|
|
3038
2890
|
// for (const field in this) {
|
|
3039
|
-
for (
|
|
2891
|
+
for (const field in metadata) {
|
|
3040
2892
|
if (typeof (this[field]) === "object" &&
|
|
3041
|
-
typeof (
|
|
2893
|
+
typeof (this[field]?.clone) === "function") {
|
|
3042
2894
|
// deep clone
|
|
3043
2895
|
cloned[field] = this[field].clone();
|
|
3044
2896
|
}
|
|
@@ -3048,12 +2900,12 @@
|
|
|
3048
2900
|
}
|
|
3049
2901
|
}
|
|
3050
2902
|
return cloned;
|
|
3051
|
-
}
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
for (
|
|
3056
|
-
|
|
2903
|
+
}
|
|
2904
|
+
toJSON() {
|
|
2905
|
+
const metadata = this.constructor[Symbol.metadata];
|
|
2906
|
+
const obj = {};
|
|
2907
|
+
for (const fieldName in metadata) {
|
|
2908
|
+
const field = metadata[fieldName];
|
|
3057
2909
|
if (!field.deprecated && this[fieldName] !== null && typeof (this[fieldName]) !== "undefined") {
|
|
3058
2910
|
obj[fieldName] = (typeof (this[fieldName]['toJSON']) === "function")
|
|
3059
2911
|
? this[fieldName]['toJSON']()
|
|
@@ -3061,30 +2913,25 @@
|
|
|
3061
2913
|
}
|
|
3062
2914
|
}
|
|
3063
2915
|
return obj;
|
|
3064
|
-
}
|
|
3065
|
-
|
|
2916
|
+
}
|
|
2917
|
+
discardAllChanges() {
|
|
3066
2918
|
this[$changes].discardAll();
|
|
3067
|
-
}
|
|
3068
|
-
|
|
2919
|
+
}
|
|
2920
|
+
[$getByIndex](index) {
|
|
3069
2921
|
return this[this.constructor[Symbol.metadata][index]];
|
|
3070
|
-
}
|
|
3071
|
-
|
|
2922
|
+
}
|
|
2923
|
+
[$deleteByIndex](index) {
|
|
3072
2924
|
this[this.constructor[Symbol.metadata][index]] = undefined;
|
|
3073
|
-
}
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
var output = "";
|
|
3082
|
-
output += "".concat(getIndent(level)).concat(ref.constructor.name, " (").concat(ref[$changes].refId, ")").concat(contents, "\n");
|
|
3083
|
-
changeTree.forEachChild(function (childChangeTree) {
|
|
3084
|
-
return output += _this.debugRefIds(childChangeTree.ref, jsonContents, level + 1);
|
|
3085
|
-
});
|
|
2925
|
+
}
|
|
2926
|
+
static debugRefIds(instance, jsonContents = true, level = 0) {
|
|
2927
|
+
const ref = instance;
|
|
2928
|
+
const changeTree = ref[$changes];
|
|
2929
|
+
const contents = (jsonContents) ? ` - ${JSON.stringify(ref.toJSON())}` : "";
|
|
2930
|
+
let output = "";
|
|
2931
|
+
output += `${getIndent(level)}${ref.constructor.name} (${ref[$changes].refId})${contents}\n`;
|
|
2932
|
+
changeTree.forEachChild((childChangeTree) => output += this.debugRefIds(childChangeTree.ref, jsonContents, level + 1));
|
|
3086
2933
|
return output;
|
|
3087
|
-
}
|
|
2934
|
+
}
|
|
3088
2935
|
/**
|
|
3089
2936
|
* Return a string representation of the changes on a Schema instance.
|
|
3090
2937
|
* The list of changes is cleared after each encode.
|
|
@@ -3093,46 +2940,39 @@
|
|
|
3093
2940
|
* @param isEncodeAll Return "full encode" instead of current change set.
|
|
3094
2941
|
* @returns
|
|
3095
2942
|
*/
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
var changeSetName = (isEncodeAll) ? "allChanges" : "changes";
|
|
3102
|
-
var output = "".concat(instance.constructor.name, " (").concat(changeTree.refId, ") -> .").concat(changeSetName, ":\n");
|
|
2943
|
+
static debugChanges(instance, isEncodeAll = false) {
|
|
2944
|
+
const changeTree = instance[$changes];
|
|
2945
|
+
const changeSet = (isEncodeAll) ? changeTree.allChanges : changeTree.changes;
|
|
2946
|
+
const changeSetName = (isEncodeAll) ? "allChanges" : "changes";
|
|
2947
|
+
let output = `${instance.constructor.name} (${changeTree.refId}) -> .${changeSetName}:\n`;
|
|
3103
2948
|
function dumpChangeSet(changeSet) {
|
|
3104
2949
|
Array.from(changeSet)
|
|
3105
|
-
.sort(
|
|
3106
|
-
.forEach(
|
|
3107
|
-
var index = _c[0], operation = _c[1];
|
|
3108
|
-
return output += "- [".concat(index, "]: ").concat(exports.OPERATION[operation], " (").concat(JSON.stringify(changeTree.getValue(index, isEncodeAll)), ")\n");
|
|
3109
|
-
});
|
|
2950
|
+
.sort((a, b) => a[0] - b[0])
|
|
2951
|
+
.forEach(([index, operation]) => output += `- [${index}]: ${exports.OPERATION[operation]} (${JSON.stringify(changeTree.getValue(index, isEncodeAll))})\n`);
|
|
3110
2952
|
}
|
|
3111
2953
|
dumpChangeSet(changeSet);
|
|
3112
2954
|
// display filtered changes
|
|
3113
|
-
if (!isEncodeAll &&
|
|
3114
|
-
output +=
|
|
2955
|
+
if (!isEncodeAll && changeTree.filteredChanges?.size > 0) {
|
|
2956
|
+
output += `${instance.constructor.name} (${changeTree.refId}) -> .filteredChanges:\n`;
|
|
3115
2957
|
dumpChangeSet(changeTree.filteredChanges);
|
|
3116
2958
|
}
|
|
3117
2959
|
// display filtered changes
|
|
3118
|
-
if (isEncodeAll &&
|
|
3119
|
-
output +=
|
|
2960
|
+
if (isEncodeAll && changeTree.allFilteredChanges?.size > 0) {
|
|
2961
|
+
output += `${instance.constructor.name} (${changeTree.refId}) -> .allFilteredChanges:\n`;
|
|
3120
2962
|
dumpChangeSet(changeTree.allFilteredChanges);
|
|
3121
2963
|
}
|
|
3122
2964
|
return output;
|
|
3123
|
-
}
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
var parentChangeTrees = [];
|
|
3135
|
-
var parentChangeTree = (_c = changeTree.parent) === null || _c === void 0 ? void 0 : _c[$changes];
|
|
2965
|
+
}
|
|
2966
|
+
static debugChangesDeep(ref) {
|
|
2967
|
+
let output = "";
|
|
2968
|
+
const rootChangeTree = ref[$changes];
|
|
2969
|
+
const changeTrees = new Map();
|
|
2970
|
+
let totalInstances = 0;
|
|
2971
|
+
let totalOperations = 0;
|
|
2972
|
+
for (const [changeTree, changes] of (rootChangeTree.root.changes.entries())) {
|
|
2973
|
+
let includeChangeTree = false;
|
|
2974
|
+
let parentChangeTrees = [];
|
|
2975
|
+
let parentChangeTree = changeTree.parent?.[$changes];
|
|
3136
2976
|
if (changeTree === rootChangeTree) {
|
|
3137
2977
|
includeChangeTree = true;
|
|
3138
2978
|
}
|
|
@@ -3143,7 +2983,7 @@
|
|
|
3143
2983
|
includeChangeTree = true;
|
|
3144
2984
|
break;
|
|
3145
2985
|
}
|
|
3146
|
-
parentChangeTree =
|
|
2986
|
+
parentChangeTree = parentChangeTree.parent?.[$changes];
|
|
3147
2987
|
}
|
|
3148
2988
|
}
|
|
3149
2989
|
if (includeChangeTree) {
|
|
@@ -3153,55 +2993,36 @@
|
|
|
3153
2993
|
}
|
|
3154
2994
|
}
|
|
3155
2995
|
output += "---\n";
|
|
3156
|
-
output +=
|
|
3157
|
-
output +=
|
|
3158
|
-
output +=
|
|
2996
|
+
output += `root refId: ${rootChangeTree.refId}\n`;
|
|
2997
|
+
output += `Total instances: ${totalInstances}\n`;
|
|
2998
|
+
output += `Total changes: ${totalOperations}\n`;
|
|
3159
2999
|
output += "---\n";
|
|
3160
3000
|
// based on root.changes, display a tree of changes that has the "ref" instance as parent
|
|
3161
|
-
|
|
3162
|
-
for (
|
|
3163
|
-
|
|
3164
|
-
parentChangeTrees.forEach(function (parentChangeTree, level) {
|
|
3001
|
+
const visitedParents = new WeakSet();
|
|
3002
|
+
for (const [changeTree, parentChangeTrees] of changeTrees.entries()) {
|
|
3003
|
+
parentChangeTrees.forEach((parentChangeTree, level) => {
|
|
3165
3004
|
if (!visitedParents.has(parentChangeTree)) {
|
|
3166
|
-
output +=
|
|
3005
|
+
output += `${getIndent(level)}${parentChangeTree.ref.constructor.name} (refId: ${parentChangeTree.refId})\n`;
|
|
3167
3006
|
visitedParents.add(parentChangeTree);
|
|
3168
3007
|
}
|
|
3169
3008
|
});
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
output +=
|
|
3175
|
-
for (
|
|
3176
|
-
|
|
3177
|
-
output += "".concat(getIndent(level + 1)).concat(exports.OPERATION[operation], ": ").concat(index, "\n");
|
|
3009
|
+
const changes = changeTree.changes;
|
|
3010
|
+
const level = parentChangeTrees.length;
|
|
3011
|
+
const indent = getIndent(level);
|
|
3012
|
+
const parentIndex = (level > 0) ? `(${changeTree.parentIndex}) ` : "";
|
|
3013
|
+
output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${changes.size}\n`;
|
|
3014
|
+
for (const [index, operation] of changes) {
|
|
3015
|
+
output += `${getIndent(level + 1)}${exports.OPERATION[operation]}: ${index}\n`;
|
|
3178
3016
|
}
|
|
3179
3017
|
}
|
|
3180
|
-
return
|
|
3181
|
-
};
|
|
3182
|
-
var _a, _b;
|
|
3183
|
-
Schema[_a] = encodeSchemaOperation;
|
|
3184
|
-
Schema[_b] = decodeSchemaOperation;
|
|
3185
|
-
return Schema;
|
|
3186
|
-
}());
|
|
3187
|
-
|
|
3188
|
-
var CollectionSchema = /** @class */ (function () {
|
|
3189
|
-
function CollectionSchema(initialValues) {
|
|
3190
|
-
var _this = this;
|
|
3191
|
-
this.$items = new Map();
|
|
3192
|
-
this.$indexes = new Map();
|
|
3193
|
-
this.$refId = 0;
|
|
3194
|
-
this[$changes] = new ChangeTree(this);
|
|
3195
|
-
if (initialValues) {
|
|
3196
|
-
initialValues.forEach(function (v) { return _this.add(v); });
|
|
3197
|
-
}
|
|
3198
|
-
Object.defineProperty(this, $childType, {
|
|
3199
|
-
value: undefined,
|
|
3200
|
-
enumerable: false,
|
|
3201
|
-
writable: true,
|
|
3202
|
-
configurable: true,
|
|
3203
|
-
});
|
|
3018
|
+
return `${output}`;
|
|
3204
3019
|
}
|
|
3020
|
+
}
|
|
3021
|
+
|
|
3022
|
+
var _a$1, _b$1;
|
|
3023
|
+
class CollectionSchema {
|
|
3024
|
+
static { this[_a$1] = encodeKeyValueOperation; }
|
|
3025
|
+
static { this[_b$1] = decodeKeyValueOperation; }
|
|
3205
3026
|
/**
|
|
3206
3027
|
* Determine if a property must be filtered.
|
|
3207
3028
|
* - If returns false, the property is NOT going to be encoded.
|
|
@@ -3211,18 +3032,33 @@
|
|
|
3211
3032
|
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
3212
3033
|
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
3213
3034
|
*/
|
|
3214
|
-
|
|
3035
|
+
static [(_a$1 = $encoder, _b$1 = $decoder, $filter)](ref, index, view) {
|
|
3215
3036
|
return (!view ||
|
|
3216
3037
|
typeof (ref[$childType]) === "string" ||
|
|
3217
3038
|
view.items.has(ref[$getByIndex](index)[$changes]));
|
|
3218
|
-
}
|
|
3219
|
-
|
|
3039
|
+
}
|
|
3040
|
+
static is(type) {
|
|
3220
3041
|
return type['collection'] !== undefined;
|
|
3221
|
-
}
|
|
3222
|
-
|
|
3042
|
+
}
|
|
3043
|
+
constructor(initialValues) {
|
|
3044
|
+
this.$items = new Map();
|
|
3045
|
+
this.$indexes = new Map();
|
|
3046
|
+
this.$refId = 0;
|
|
3047
|
+
this[$changes] = new ChangeTree(this);
|
|
3048
|
+
if (initialValues) {
|
|
3049
|
+
initialValues.forEach((v) => this.add(v));
|
|
3050
|
+
}
|
|
3051
|
+
Object.defineProperty(this, $childType, {
|
|
3052
|
+
value: undefined,
|
|
3053
|
+
enumerable: false,
|
|
3054
|
+
writable: true,
|
|
3055
|
+
configurable: true,
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
add(value) {
|
|
3223
3059
|
// set "index" for reference.
|
|
3224
|
-
|
|
3225
|
-
|
|
3060
|
+
const index = this.$refId++;
|
|
3061
|
+
const isRef = (value[$changes]) !== undefined;
|
|
3226
3062
|
if (isRef) {
|
|
3227
3063
|
value[$changes].setParent(this, this[$changes].root, index);
|
|
3228
3064
|
}
|
|
@@ -3231,18 +3067,18 @@
|
|
|
3231
3067
|
this.$items.set(index, value);
|
|
3232
3068
|
this[$changes].change(index);
|
|
3233
3069
|
return index;
|
|
3234
|
-
}
|
|
3235
|
-
|
|
3236
|
-
|
|
3070
|
+
}
|
|
3071
|
+
at(index) {
|
|
3072
|
+
const key = Array.from(this.$items.keys())[index];
|
|
3237
3073
|
return this.$items.get(key);
|
|
3238
|
-
}
|
|
3239
|
-
|
|
3074
|
+
}
|
|
3075
|
+
entries() {
|
|
3240
3076
|
return this.$items.entries();
|
|
3241
|
-
}
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3077
|
+
}
|
|
3078
|
+
delete(item) {
|
|
3079
|
+
const entries = this.$items.entries();
|
|
3080
|
+
let index;
|
|
3081
|
+
let entry;
|
|
3246
3082
|
while (entry = entries.next()) {
|
|
3247
3083
|
if (entry.done) {
|
|
3248
3084
|
break;
|
|
@@ -3258,9 +3094,9 @@
|
|
|
3258
3094
|
this[$changes].delete(index);
|
|
3259
3095
|
this.$indexes.delete(index);
|
|
3260
3096
|
return this.$items.delete(index);
|
|
3261
|
-
}
|
|
3262
|
-
|
|
3263
|
-
|
|
3097
|
+
}
|
|
3098
|
+
clear() {
|
|
3099
|
+
const changeTree = this[$changes];
|
|
3264
3100
|
// discard previous operations.
|
|
3265
3101
|
changeTree.discard(true);
|
|
3266
3102
|
changeTree.indexes = {};
|
|
@@ -3269,59 +3105,54 @@
|
|
|
3269
3105
|
// clear items
|
|
3270
3106
|
this.$items.clear();
|
|
3271
3107
|
changeTree.operation(exports.OPERATION.CLEAR);
|
|
3272
|
-
}
|
|
3273
|
-
|
|
3274
|
-
return Array.from(this.$items.values()).some(
|
|
3275
|
-
}
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
CollectionSchema.prototype.values = function () {
|
|
3108
|
+
}
|
|
3109
|
+
has(value) {
|
|
3110
|
+
return Array.from(this.$items.values()).some((v) => v === value);
|
|
3111
|
+
}
|
|
3112
|
+
forEach(callbackfn) {
|
|
3113
|
+
this.$items.forEach((value, key, _) => callbackfn(value, key, this));
|
|
3114
|
+
}
|
|
3115
|
+
values() {
|
|
3281
3116
|
return this.$items.values();
|
|
3282
|
-
}
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
},
|
|
3287
|
-
enumerable: false,
|
|
3288
|
-
configurable: true
|
|
3289
|
-
});
|
|
3117
|
+
}
|
|
3118
|
+
get size() {
|
|
3119
|
+
return this.$items.size;
|
|
3120
|
+
}
|
|
3290
3121
|
/** Iterator */
|
|
3291
|
-
|
|
3122
|
+
[Symbol.iterator]() {
|
|
3292
3123
|
return this.$items.values();
|
|
3293
|
-
}
|
|
3294
|
-
|
|
3124
|
+
}
|
|
3125
|
+
setIndex(index, key) {
|
|
3295
3126
|
this.$indexes.set(index, key);
|
|
3296
|
-
}
|
|
3297
|
-
|
|
3127
|
+
}
|
|
3128
|
+
getIndex(index) {
|
|
3298
3129
|
return this.$indexes.get(index);
|
|
3299
|
-
}
|
|
3300
|
-
|
|
3130
|
+
}
|
|
3131
|
+
[$getByIndex](index) {
|
|
3301
3132
|
return this.$items.get(this.$indexes.get(index));
|
|
3302
|
-
}
|
|
3303
|
-
|
|
3304
|
-
|
|
3133
|
+
}
|
|
3134
|
+
[$deleteByIndex](index) {
|
|
3135
|
+
const key = this.$indexes.get(index);
|
|
3305
3136
|
this.$items.delete(key);
|
|
3306
3137
|
this.$indexes.delete(index);
|
|
3307
|
-
}
|
|
3308
|
-
|
|
3138
|
+
}
|
|
3139
|
+
toArray() {
|
|
3309
3140
|
return Array.from(this.$items.values());
|
|
3310
|
-
}
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
this.forEach(
|
|
3141
|
+
}
|
|
3142
|
+
toJSON() {
|
|
3143
|
+
const values = [];
|
|
3144
|
+
this.forEach((value, key) => {
|
|
3314
3145
|
values.push((typeof (value['toJSON']) === "function")
|
|
3315
3146
|
? value['toJSON']()
|
|
3316
3147
|
: value);
|
|
3317
3148
|
});
|
|
3318
3149
|
return values;
|
|
3319
|
-
}
|
|
3150
|
+
}
|
|
3320
3151
|
//
|
|
3321
3152
|
// Decoding utilities
|
|
3322
3153
|
//
|
|
3323
|
-
|
|
3324
|
-
|
|
3154
|
+
clone(isDecoding) {
|
|
3155
|
+
let cloned;
|
|
3325
3156
|
if (isDecoding) {
|
|
3326
3157
|
// client-side
|
|
3327
3158
|
cloned = Object.assign(new CollectionSchema(), this);
|
|
@@ -3329,7 +3160,7 @@
|
|
|
3329
3160
|
else {
|
|
3330
3161
|
// server-side
|
|
3331
3162
|
cloned = new CollectionSchema();
|
|
3332
|
-
this.forEach(
|
|
3163
|
+
this.forEach((value) => {
|
|
3333
3164
|
if (value[$changes]) {
|
|
3334
3165
|
cloned.add(value['clone']());
|
|
3335
3166
|
}
|
|
@@ -3339,31 +3170,14 @@
|
|
|
3339
3170
|
});
|
|
3340
3171
|
}
|
|
3341
3172
|
return cloned;
|
|
3342
|
-
}
|
|
3343
|
-
|
|
3344
|
-
CollectionSchema[_a] = encodeKeyValueOperation;
|
|
3345
|
-
CollectionSchema[_b] = decodeKeyValueOperation;
|
|
3346
|
-
return CollectionSchema;
|
|
3347
|
-
}());
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3348
3175
|
registerType("collection", { constructor: CollectionSchema, });
|
|
3349
3176
|
|
|
3350
|
-
var
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
this.$indexes = new Map();
|
|
3355
|
-
this.$refId = 0;
|
|
3356
|
-
this[$changes] = new ChangeTree(this);
|
|
3357
|
-
if (initialValues) {
|
|
3358
|
-
initialValues.forEach(function (v) { return _this.add(v); });
|
|
3359
|
-
}
|
|
3360
|
-
Object.defineProperty(this, $childType, {
|
|
3361
|
-
value: undefined,
|
|
3362
|
-
enumerable: false,
|
|
3363
|
-
writable: true,
|
|
3364
|
-
configurable: true,
|
|
3365
|
-
});
|
|
3366
|
-
}
|
|
3177
|
+
var _a, _b;
|
|
3178
|
+
class SetSchema {
|
|
3179
|
+
static { this[_a] = encodeKeyValueOperation; }
|
|
3180
|
+
static { this[_b] = decodeKeyValueOperation; }
|
|
3367
3181
|
/**
|
|
3368
3182
|
* Determine if a property must be filtered.
|
|
3369
3183
|
* - If returns false, the property is NOT going to be encoded.
|
|
@@ -3373,39 +3187,53 @@
|
|
|
3373
3187
|
* - First, the encoder iterates over all "not owned" properties and encodes them.
|
|
3374
3188
|
* - Then, the encoder iterates over all "owned" properties per instance and encodes them.
|
|
3375
3189
|
*/
|
|
3376
|
-
|
|
3190
|
+
static [(_a = $encoder, _b = $decoder, $filter)](ref, index, view) {
|
|
3377
3191
|
return (!view ||
|
|
3378
3192
|
typeof (ref[$childType]) === "string" ||
|
|
3379
3193
|
view.items.has(ref[$getByIndex](index)[$changes]));
|
|
3380
|
-
}
|
|
3381
|
-
|
|
3194
|
+
}
|
|
3195
|
+
static is(type) {
|
|
3382
3196
|
return type['set'] !== undefined;
|
|
3383
|
-
}
|
|
3384
|
-
|
|
3385
|
-
|
|
3197
|
+
}
|
|
3198
|
+
constructor(initialValues) {
|
|
3199
|
+
this.$items = new Map();
|
|
3200
|
+
this.$indexes = new Map();
|
|
3201
|
+
this.$refId = 0;
|
|
3202
|
+
this[$changes] = new ChangeTree(this);
|
|
3203
|
+
if (initialValues) {
|
|
3204
|
+
initialValues.forEach((v) => this.add(v));
|
|
3205
|
+
}
|
|
3206
|
+
Object.defineProperty(this, $childType, {
|
|
3207
|
+
value: undefined,
|
|
3208
|
+
enumerable: false,
|
|
3209
|
+
writable: true,
|
|
3210
|
+
configurable: true,
|
|
3211
|
+
});
|
|
3212
|
+
}
|
|
3213
|
+
add(value) {
|
|
3386
3214
|
// immediatelly return false if value already added.
|
|
3387
3215
|
if (this.has(value)) {
|
|
3388
3216
|
return false;
|
|
3389
3217
|
}
|
|
3390
3218
|
// set "index" for reference.
|
|
3391
|
-
|
|
3219
|
+
const index = this.$refId++;
|
|
3392
3220
|
if ((value[$changes]) !== undefined) {
|
|
3393
3221
|
value[$changes].setParent(this, this[$changes].root, index);
|
|
3394
3222
|
}
|
|
3395
|
-
|
|
3223
|
+
const operation = this[$changes].indexes[index]?.op ?? exports.OPERATION.ADD;
|
|
3396
3224
|
this[$changes].indexes[index] = index;
|
|
3397
3225
|
this.$indexes.set(index, index);
|
|
3398
3226
|
this.$items.set(index, value);
|
|
3399
3227
|
this[$changes].change(index, operation);
|
|
3400
3228
|
return index;
|
|
3401
|
-
}
|
|
3402
|
-
|
|
3229
|
+
}
|
|
3230
|
+
entries() {
|
|
3403
3231
|
return this.$items.entries();
|
|
3404
|
-
}
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3232
|
+
}
|
|
3233
|
+
delete(item) {
|
|
3234
|
+
const entries = this.$items.entries();
|
|
3235
|
+
let index;
|
|
3236
|
+
let entry;
|
|
3409
3237
|
while (entry = entries.next()) {
|
|
3410
3238
|
if (entry.done) {
|
|
3411
3239
|
break;
|
|
@@ -3421,9 +3249,9 @@
|
|
|
3421
3249
|
this[$changes].delete(index);
|
|
3422
3250
|
this.$indexes.delete(index);
|
|
3423
3251
|
return this.$items.delete(index);
|
|
3424
|
-
}
|
|
3425
|
-
|
|
3426
|
-
|
|
3252
|
+
}
|
|
3253
|
+
clear() {
|
|
3254
|
+
const changeTree = this[$changes];
|
|
3427
3255
|
// discard previous operations.
|
|
3428
3256
|
changeTree.discard(true);
|
|
3429
3257
|
changeTree.indexes = {};
|
|
@@ -3432,11 +3260,11 @@
|
|
|
3432
3260
|
// clear items
|
|
3433
3261
|
this.$items.clear();
|
|
3434
3262
|
changeTree.operation(exports.OPERATION.CLEAR);
|
|
3435
|
-
}
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3263
|
+
}
|
|
3264
|
+
has(value) {
|
|
3265
|
+
const values = this.$items.values();
|
|
3266
|
+
let has = false;
|
|
3267
|
+
let entry;
|
|
3440
3268
|
while (entry = values.next()) {
|
|
3441
3269
|
if (entry.done) {
|
|
3442
3270
|
break;
|
|
@@ -3447,56 +3275,51 @@
|
|
|
3447
3275
|
}
|
|
3448
3276
|
}
|
|
3449
3277
|
return has;
|
|
3450
|
-
}
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
SetSchema.prototype.values = function () {
|
|
3278
|
+
}
|
|
3279
|
+
forEach(callbackfn) {
|
|
3280
|
+
this.$items.forEach((value, key, _) => callbackfn(value, key, this));
|
|
3281
|
+
}
|
|
3282
|
+
values() {
|
|
3456
3283
|
return this.$items.values();
|
|
3457
|
-
}
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
},
|
|
3462
|
-
enumerable: false,
|
|
3463
|
-
configurable: true
|
|
3464
|
-
});
|
|
3284
|
+
}
|
|
3285
|
+
get size() {
|
|
3286
|
+
return this.$items.size;
|
|
3287
|
+
}
|
|
3465
3288
|
/** Iterator */
|
|
3466
|
-
|
|
3289
|
+
[Symbol.iterator]() {
|
|
3467
3290
|
return this.$items.values();
|
|
3468
|
-
}
|
|
3469
|
-
|
|
3291
|
+
}
|
|
3292
|
+
setIndex(index, key) {
|
|
3470
3293
|
this.$indexes.set(index, key);
|
|
3471
|
-
}
|
|
3472
|
-
|
|
3294
|
+
}
|
|
3295
|
+
getIndex(index) {
|
|
3473
3296
|
return this.$indexes.get(index);
|
|
3474
|
-
}
|
|
3475
|
-
|
|
3297
|
+
}
|
|
3298
|
+
[$getByIndex](index) {
|
|
3476
3299
|
return this.$items.get(this.$indexes.get(index));
|
|
3477
|
-
}
|
|
3478
|
-
|
|
3479
|
-
|
|
3300
|
+
}
|
|
3301
|
+
[$deleteByIndex](index) {
|
|
3302
|
+
const key = this.$indexes.get(index);
|
|
3480
3303
|
this.$items.delete(key);
|
|
3481
3304
|
this.$indexes.delete(index);
|
|
3482
|
-
}
|
|
3483
|
-
|
|
3305
|
+
}
|
|
3306
|
+
toArray() {
|
|
3484
3307
|
return Array.from(this.$items.values());
|
|
3485
|
-
}
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
this.forEach(
|
|
3308
|
+
}
|
|
3309
|
+
toJSON() {
|
|
3310
|
+
const values = [];
|
|
3311
|
+
this.forEach((value, key) => {
|
|
3489
3312
|
values.push((typeof (value['toJSON']) === "function")
|
|
3490
3313
|
? value['toJSON']()
|
|
3491
3314
|
: value);
|
|
3492
3315
|
});
|
|
3493
3316
|
return values;
|
|
3494
|
-
}
|
|
3317
|
+
}
|
|
3495
3318
|
//
|
|
3496
3319
|
// Decoding utilities
|
|
3497
3320
|
//
|
|
3498
|
-
|
|
3499
|
-
|
|
3321
|
+
clone(isDecoding) {
|
|
3322
|
+
let cloned;
|
|
3500
3323
|
if (isDecoding) {
|
|
3501
3324
|
// client-side
|
|
3502
3325
|
cloned = Object.assign(new SetSchema(), this);
|
|
@@ -3504,7 +3327,7 @@
|
|
|
3504
3327
|
else {
|
|
3505
3328
|
// server-side
|
|
3506
3329
|
cloned = new SetSchema();
|
|
3507
|
-
this.forEach(
|
|
3330
|
+
this.forEach((value) => {
|
|
3508
3331
|
if (value[$changes]) {
|
|
3509
3332
|
cloned.add(value['clone']());
|
|
3510
3333
|
}
|
|
@@ -3514,16 +3337,40 @@
|
|
|
3514
3337
|
});
|
|
3515
3338
|
}
|
|
3516
3339
|
return cloned;
|
|
3517
|
-
}
|
|
3518
|
-
|
|
3519
|
-
SetSchema[_a] = encodeKeyValueOperation;
|
|
3520
|
-
SetSchema[_b] = decodeKeyValueOperation;
|
|
3521
|
-
return SetSchema;
|
|
3522
|
-
}());
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3523
3342
|
registerType("set", { constructor: SetSchema });
|
|
3524
3343
|
|
|
3525
|
-
|
|
3526
|
-
|
|
3344
|
+
/******************************************************************************
|
|
3345
|
+
Copyright (c) Microsoft Corporation.
|
|
3346
|
+
|
|
3347
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
3348
|
+
purpose with or without fee is hereby granted.
|
|
3349
|
+
|
|
3350
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
3351
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
3352
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
3353
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
3354
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
3355
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
3356
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
3357
|
+
***************************************************************************** */
|
|
3358
|
+
|
|
3359
|
+
function __decorate(decorators, target, key, desc) {
|
|
3360
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3361
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
3362
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
3363
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
3367
|
+
var e = new Error(message);
|
|
3368
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
3369
|
+
};
|
|
3370
|
+
|
|
3371
|
+
class Encoder {
|
|
3372
|
+
static { this.BUFFER_SIZE = 8 * 1024; } // 8KB
|
|
3373
|
+
constructor(root) {
|
|
3527
3374
|
this.sharedBuffer = Buffer.allocUnsafeSlow(Encoder.BUFFER_SIZE);
|
|
3528
3375
|
this.setRoot(root);
|
|
3529
3376
|
//
|
|
@@ -3536,26 +3383,22 @@
|
|
|
3536
3383
|
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
3537
3384
|
// });
|
|
3538
3385
|
}
|
|
3539
|
-
|
|
3540
|
-
this
|
|
3386
|
+
setRoot(state) {
|
|
3387
|
+
this.root = new Root();
|
|
3541
3388
|
this.state = state;
|
|
3542
|
-
state[$changes].setRoot(this
|
|
3543
|
-
}
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
var ref = changeTree.ref;
|
|
3556
|
-
var ctor = ref['constructor'];
|
|
3557
|
-
var encoder = ctor[$encoder];
|
|
3558
|
-
var filter = ctor[$filter];
|
|
3389
|
+
state[$changes].setRoot(this.root);
|
|
3390
|
+
}
|
|
3391
|
+
encode(it = { offset: 0 }, view, bytes = this.sharedBuffer, changeTrees = this.root.changes) {
|
|
3392
|
+
const initialOffset = it.offset; // cache current offset in case we need to resize the buffer
|
|
3393
|
+
const isEncodeAll = this.root.allChanges === changeTrees;
|
|
3394
|
+
const hasView = (view !== undefined);
|
|
3395
|
+
const rootChangeTree = this.state[$changes];
|
|
3396
|
+
const changeTreesIterator = changeTrees.entries();
|
|
3397
|
+
for (const [changeTree, changes] of changeTreesIterator) {
|
|
3398
|
+
const ref = changeTree.ref;
|
|
3399
|
+
const ctor = ref['constructor'];
|
|
3400
|
+
const encoder = ctor[$encoder];
|
|
3401
|
+
const filter = ctor[$filter];
|
|
3559
3402
|
if (hasView) {
|
|
3560
3403
|
if (!view.items.has(changeTree)) {
|
|
3561
3404
|
view.invisible.add(changeTree);
|
|
@@ -3570,9 +3413,8 @@
|
|
|
3570
3413
|
bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;
|
|
3571
3414
|
number$1(bytes, changeTree.refId, it);
|
|
3572
3415
|
}
|
|
3573
|
-
|
|
3574
|
-
for (
|
|
3575
|
-
var _c = changesIterator_1[_b], fieldIndex = _c[0], operation = _c[1];
|
|
3416
|
+
const changesIterator = changes.entries();
|
|
3417
|
+
for (const [fieldIndex, operation] of changesIterator) {
|
|
3576
3418
|
//
|
|
3577
3419
|
// first pass (encodeAll), identify "filtered" operations without encoding them
|
|
3578
3420
|
// they will be encoded per client, based on their view.
|
|
@@ -3595,7 +3437,7 @@
|
|
|
3595
3437
|
}
|
|
3596
3438
|
}
|
|
3597
3439
|
if (it.offset > bytes.byteLength) {
|
|
3598
|
-
|
|
3440
|
+
const newSize = getNextPowerOf2(this.sharedBuffer.byteLength * 2);
|
|
3599
3441
|
console.warn("@colyseus/schema encode buffer overflow. Current buffer size: " + bytes.byteLength + ", encoding offset: " + it.offset + ", new size: " + newSize);
|
|
3600
3442
|
//
|
|
3601
3443
|
// resize buffer and re-encode (TODO: can we avoid re-encoding here?)
|
|
@@ -3616,27 +3458,25 @@
|
|
|
3616
3458
|
// return bytes;
|
|
3617
3459
|
return bytes.slice(0, it.offset);
|
|
3618
3460
|
}
|
|
3619
|
-
}
|
|
3620
|
-
|
|
3461
|
+
}
|
|
3462
|
+
encodeAll(it = { offset: 0 }) {
|
|
3621
3463
|
// console.log(`encodeAll(), this.$root.allChanges (${this.$root.allChanges.size})`);
|
|
3622
|
-
if (it === void 0) { it = { offset: 0 }; }
|
|
3623
3464
|
// Array.from(this.$root.allChanges.entries()).map((item) => {
|
|
3624
3465
|
// console.log("->", item[0].refId, item[0].ref.toJSON());
|
|
3625
3466
|
// });
|
|
3626
|
-
return this.encode(it, undefined, this.sharedBuffer, this
|
|
3627
|
-
}
|
|
3628
|
-
|
|
3629
|
-
|
|
3630
|
-
var viewOffset = it.offset;
|
|
3467
|
+
return this.encode(it, undefined, this.sharedBuffer, this.root.allChanges);
|
|
3468
|
+
}
|
|
3469
|
+
encodeAllView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
3470
|
+
const viewOffset = it.offset;
|
|
3631
3471
|
// console.log(`encodeAllView(), this.$root.allFilteredChanges (${this.$root.allFilteredChanges.size})`);
|
|
3632
3472
|
// this.debugAllFilteredChanges();
|
|
3633
3473
|
// try to encode "filtered" changes
|
|
3634
|
-
this.encode(it, view, bytes, this
|
|
3474
|
+
this.encode(it, view, bytes, this.root.allFilteredChanges);
|
|
3635
3475
|
return Buffer.concat([
|
|
3636
3476
|
bytes.slice(0, sharedOffset),
|
|
3637
3477
|
bytes.slice(viewOffset, it.offset)
|
|
3638
3478
|
]);
|
|
3639
|
-
}
|
|
3479
|
+
}
|
|
3640
3480
|
// debugAllFilteredChanges() {
|
|
3641
3481
|
// Array.from(this.$root.allFilteredChanges.entries()).map((item) => {
|
|
3642
3482
|
// console.log("->", { refId: item[0].refId }, item[0].ref.toJSON());
|
|
@@ -3647,28 +3487,25 @@
|
|
|
3647
3487
|
// }
|
|
3648
3488
|
// });
|
|
3649
3489
|
// }
|
|
3650
|
-
|
|
3651
|
-
|
|
3652
|
-
var viewOffset = it.offset;
|
|
3490
|
+
encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
3491
|
+
const viewOffset = it.offset;
|
|
3653
3492
|
// try to encode "filtered" changes
|
|
3654
|
-
this.encode(it, view, bytes, this
|
|
3493
|
+
this.encode(it, view, bytes, this.root.filteredChanges);
|
|
3655
3494
|
// encode visibility changes (add/remove for this view)
|
|
3656
|
-
|
|
3657
|
-
for (
|
|
3658
|
-
var _a = viewChangesIterator_1[_i], changeTree = _a[0], changes = _a[1];
|
|
3495
|
+
const viewChangesIterator = view.changes.entries();
|
|
3496
|
+
for (const [changeTree, changes] of viewChangesIterator) {
|
|
3659
3497
|
if (changes.size === 0) {
|
|
3660
3498
|
// FIXME: avoid having empty changes if no changes were made
|
|
3661
3499
|
// console.log("changes.size === 0", changeTree.ref.constructor.name);
|
|
3662
3500
|
continue;
|
|
3663
3501
|
}
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3502
|
+
const ref = changeTree.ref;
|
|
3503
|
+
const ctor = ref['constructor'];
|
|
3504
|
+
const encoder = ctor[$encoder];
|
|
3667
3505
|
bytes[it.offset++] = SWITCH_TO_STRUCTURE & 255;
|
|
3668
3506
|
number$1(bytes, changeTree.refId, it);
|
|
3669
|
-
|
|
3670
|
-
for (
|
|
3671
|
-
var _c = changesIterator_2[_b], fieldIndex = _c[0], operation = _c[1];
|
|
3507
|
+
const changesIterator = changes.entries();
|
|
3508
|
+
for (const [fieldIndex, operation] of changesIterator) {
|
|
3672
3509
|
// isEncodeAll = false
|
|
3673
3510
|
// hasView = true
|
|
3674
3511
|
encoder(this, bytes, changeTree, fieldIndex, operation, it, false, true);
|
|
@@ -3684,63 +3521,56 @@
|
|
|
3684
3521
|
bytes.slice(0, sharedOffset),
|
|
3685
3522
|
bytes.slice(viewOffset, it.offset)
|
|
3686
3523
|
]);
|
|
3687
|
-
}
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
for (var _i = 0, changeTreesIterator_2 = changeTreesIterator; _i < changeTreesIterator_2.length; _i++) {
|
|
3692
|
-
var _a = changeTreesIterator_2[_i], changeTree = _a[0]; _a[1];
|
|
3524
|
+
}
|
|
3525
|
+
onEndEncode(changeTrees = this.root.changes) {
|
|
3526
|
+
const changeTreesIterator = changeTrees.entries();
|
|
3527
|
+
for (const [changeTree, _] of changeTreesIterator) {
|
|
3693
3528
|
changeTree.endEncode();
|
|
3694
3529
|
}
|
|
3695
|
-
}
|
|
3696
|
-
|
|
3530
|
+
}
|
|
3531
|
+
discardChanges() {
|
|
3697
3532
|
// discard shared changes
|
|
3698
|
-
if (this
|
|
3699
|
-
this.onEndEncode(this
|
|
3700
|
-
this
|
|
3533
|
+
if (this.root.changes.size > 0) {
|
|
3534
|
+
this.onEndEncode(this.root.changes);
|
|
3535
|
+
this.root.changes.clear();
|
|
3701
3536
|
}
|
|
3702
3537
|
// discard filtered changes
|
|
3703
|
-
if (this
|
|
3704
|
-
this.onEndEncode(this
|
|
3705
|
-
this
|
|
3538
|
+
if (this.root.filteredChanges.size > 0) {
|
|
3539
|
+
this.onEndEncode(this.root.filteredChanges);
|
|
3540
|
+
this.root.filteredChanges.clear();
|
|
3706
3541
|
}
|
|
3707
|
-
}
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3542
|
+
}
|
|
3543
|
+
tryEncodeTypeId(bytes, baseType, targetType, it) {
|
|
3544
|
+
const baseTypeId = this.context.getTypeId(baseType);
|
|
3545
|
+
const targetTypeId = this.context.getTypeId(targetType);
|
|
3711
3546
|
if (baseTypeId !== targetTypeId) {
|
|
3712
3547
|
bytes[it.offset++] = TYPE_ID & 255;
|
|
3713
3548
|
number$1(bytes, targetTypeId, it);
|
|
3714
3549
|
}
|
|
3715
|
-
}
|
|
3716
|
-
|
|
3717
|
-
return Encoder;
|
|
3718
|
-
}());
|
|
3550
|
+
}
|
|
3551
|
+
}
|
|
3719
3552
|
|
|
3720
3553
|
function spliceOne(arr, index) {
|
|
3721
3554
|
// manually splice an array
|
|
3722
3555
|
if (index === -1 || index >= arr.length) {
|
|
3723
3556
|
return false;
|
|
3724
3557
|
}
|
|
3725
|
-
|
|
3726
|
-
for (
|
|
3558
|
+
const len = arr.length - 1;
|
|
3559
|
+
for (let i = index; i < len; i++) {
|
|
3727
3560
|
arr[i] = arr[i + 1];
|
|
3728
3561
|
}
|
|
3729
3562
|
arr.length = len;
|
|
3730
3563
|
return true;
|
|
3731
3564
|
}
|
|
3732
3565
|
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
}(Error));
|
|
3742
|
-
var ReferenceTracker = /** @class */ (function () {
|
|
3743
|
-
function ReferenceTracker() {
|
|
3566
|
+
class DecodingWarning extends Error {
|
|
3567
|
+
constructor(message) {
|
|
3568
|
+
super(message);
|
|
3569
|
+
this.name = "DecodingWarning";
|
|
3570
|
+
}
|
|
3571
|
+
}
|
|
3572
|
+
class ReferenceTracker {
|
|
3573
|
+
constructor() {
|
|
3744
3574
|
//
|
|
3745
3575
|
// Relation of refId => Schema structure
|
|
3746
3576
|
// For direct access of structures during decoding time.
|
|
@@ -3752,12 +3582,11 @@
|
|
|
3752
3582
|
this.callbacks = {};
|
|
3753
3583
|
this.nextUniqueId = 0;
|
|
3754
3584
|
}
|
|
3755
|
-
|
|
3585
|
+
getNextUniqueId() {
|
|
3756
3586
|
return this.nextUniqueId++;
|
|
3757
|
-
}
|
|
3587
|
+
}
|
|
3758
3588
|
// for decoding
|
|
3759
|
-
|
|
3760
|
-
if (incrementCount === void 0) { incrementCount = true; }
|
|
3589
|
+
addRef(refId, ref, incrementCount = true) {
|
|
3761
3590
|
this.refs.set(refId, ref);
|
|
3762
3591
|
this.refIds.set(ref, refId);
|
|
3763
3592
|
if (incrementCount) {
|
|
@@ -3766,10 +3595,10 @@
|
|
|
3766
3595
|
if (this.deletedRefs.has(refId)) {
|
|
3767
3596
|
this.deletedRefs.delete(refId);
|
|
3768
3597
|
}
|
|
3769
|
-
}
|
|
3598
|
+
}
|
|
3770
3599
|
// for decoding
|
|
3771
|
-
|
|
3772
|
-
|
|
3600
|
+
removeRef(refId) {
|
|
3601
|
+
const refCount = this.refCounts[refId];
|
|
3773
3602
|
if (refCount === undefined) {
|
|
3774
3603
|
try {
|
|
3775
3604
|
throw new DecodingWarning("trying to remove refId that doesn't exist");
|
|
@@ -3781,8 +3610,8 @@
|
|
|
3781
3610
|
}
|
|
3782
3611
|
if (refCount === 0) {
|
|
3783
3612
|
try {
|
|
3784
|
-
|
|
3785
|
-
throw new DecodingWarning(
|
|
3613
|
+
const ref = this.refs.get(refId);
|
|
3614
|
+
throw new DecodingWarning(`trying to remove refId '${refId}' with 0 refCount (${ref.constructor.name}: ${JSON.stringify(ref)})`);
|
|
3786
3615
|
}
|
|
3787
3616
|
catch (e) {
|
|
3788
3617
|
console.warn(e);
|
|
@@ -3792,55 +3621,53 @@
|
|
|
3792
3621
|
if ((this.refCounts[refId] = refCount - 1) <= 0) {
|
|
3793
3622
|
this.deletedRefs.add(refId);
|
|
3794
3623
|
}
|
|
3795
|
-
}
|
|
3796
|
-
|
|
3624
|
+
}
|
|
3625
|
+
clearRefs() {
|
|
3797
3626
|
this.refs.clear();
|
|
3798
3627
|
this.deletedRefs.clear();
|
|
3799
3628
|
this.refCounts = {};
|
|
3800
|
-
}
|
|
3629
|
+
}
|
|
3801
3630
|
// for decoding
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
this.deletedRefs.forEach(function (refId) {
|
|
3631
|
+
garbageCollectDeletedRefs() {
|
|
3632
|
+
this.deletedRefs.forEach((refId) => {
|
|
3805
3633
|
//
|
|
3806
3634
|
// Skip active references.
|
|
3807
3635
|
//
|
|
3808
|
-
if (
|
|
3636
|
+
if (this.refCounts[refId] > 0) {
|
|
3809
3637
|
return;
|
|
3810
3638
|
}
|
|
3811
|
-
|
|
3639
|
+
const ref = this.refs.get(refId);
|
|
3812
3640
|
//
|
|
3813
3641
|
// Ensure child schema instances have their references removed as well.
|
|
3814
3642
|
//
|
|
3815
3643
|
if (Metadata.isValidInstance(ref)) {
|
|
3816
|
-
|
|
3817
|
-
for (
|
|
3818
|
-
|
|
3644
|
+
const metadata = ref['constructor'][Symbol.metadata];
|
|
3645
|
+
for (const field in metadata) {
|
|
3646
|
+
const childRefId = typeof (ref[field]) === "object" && this.refIds.get(ref[field]);
|
|
3819
3647
|
if (childRefId) {
|
|
3820
|
-
|
|
3648
|
+
this.removeRef(childRefId);
|
|
3821
3649
|
}
|
|
3822
3650
|
}
|
|
3823
3651
|
}
|
|
3824
3652
|
else {
|
|
3825
3653
|
if (typeof (Object.values(ref[$childType])[0]) === "function") {
|
|
3826
3654
|
Array.from(ref.values())
|
|
3827
|
-
.forEach(
|
|
3655
|
+
.forEach((child) => this.removeRef(this.refIds.get(child)));
|
|
3828
3656
|
}
|
|
3829
3657
|
}
|
|
3830
|
-
|
|
3831
|
-
delete
|
|
3832
|
-
delete
|
|
3658
|
+
this.refs.delete(refId); // remove ref
|
|
3659
|
+
delete this.refCounts[refId]; // remove ref count
|
|
3660
|
+
delete this.callbacks[refId]; // remove callbacks
|
|
3833
3661
|
});
|
|
3834
3662
|
// clear deleted refs.
|
|
3835
3663
|
this.deletedRefs.clear();
|
|
3836
|
-
}
|
|
3837
|
-
|
|
3838
|
-
var _this = this;
|
|
3664
|
+
}
|
|
3665
|
+
addCallback(refId, fieldOrOperation, callback) {
|
|
3839
3666
|
if (refId === undefined) {
|
|
3840
|
-
|
|
3667
|
+
const name = (typeof (fieldOrOperation) === "number")
|
|
3841
3668
|
? exports.OPERATION[fieldOrOperation]
|
|
3842
3669
|
: fieldOrOperation;
|
|
3843
|
-
throw new Error(
|
|
3670
|
+
throw new Error(`Can't addCallback on '${name}' (refId is undefined)`);
|
|
3844
3671
|
}
|
|
3845
3672
|
if (!this.callbacks[refId]) {
|
|
3846
3673
|
this.callbacks[refId] = {};
|
|
@@ -3849,20 +3676,18 @@
|
|
|
3849
3676
|
this.callbacks[refId][fieldOrOperation] = [];
|
|
3850
3677
|
}
|
|
3851
3678
|
this.callbacks[refId][fieldOrOperation].push(callback);
|
|
3852
|
-
return
|
|
3853
|
-
}
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
var index = (_c = (_b = (_a = this.callbacks) === null || _a === void 0 ? void 0 : _a[refId]) === null || _b === void 0 ? void 0 : _b[field]) === null || _c === void 0 ? void 0 : _c.indexOf(callback);
|
|
3679
|
+
return () => this.removeCallback(refId, fieldOrOperation, callback);
|
|
3680
|
+
}
|
|
3681
|
+
removeCallback(refId, field, callback) {
|
|
3682
|
+
const index = this.callbacks?.[refId]?.[field]?.indexOf(callback);
|
|
3857
3683
|
if (index !== -1) {
|
|
3858
3684
|
spliceOne(this.callbacks[refId][field], index);
|
|
3859
3685
|
}
|
|
3860
|
-
}
|
|
3861
|
-
|
|
3862
|
-
}());
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3863
3688
|
|
|
3864
|
-
|
|
3865
|
-
|
|
3689
|
+
class Decoder {
|
|
3690
|
+
constructor(root, context) {
|
|
3866
3691
|
this.currentRefId = 0;
|
|
3867
3692
|
this.setRoot(root);
|
|
3868
3693
|
this.context = context || new TypeContext(root.constructor);
|
|
@@ -3871,19 +3696,16 @@
|
|
|
3871
3696
|
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
3872
3697
|
// });
|
|
3873
3698
|
}
|
|
3874
|
-
|
|
3699
|
+
setRoot(root) {
|
|
3875
3700
|
this.state = root;
|
|
3876
3701
|
this.$root = new ReferenceTracker();
|
|
3877
3702
|
this.$root.addRef(0, root);
|
|
3878
|
-
}
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
var $root = this.$root;
|
|
3885
|
-
var totalBytes = bytes.byteLength;
|
|
3886
|
-
var decoder = ref['constructor'][$decoder];
|
|
3703
|
+
}
|
|
3704
|
+
decode(bytes, it = { offset: 0 }, ref = this.state) {
|
|
3705
|
+
const allChanges = [];
|
|
3706
|
+
const $root = this.$root;
|
|
3707
|
+
const totalBytes = bytes.byteLength;
|
|
3708
|
+
let decoder = ref['constructor'][$decoder];
|
|
3887
3709
|
this.currentRefId = 0;
|
|
3888
3710
|
while (it.offset < totalBytes) {
|
|
3889
3711
|
//
|
|
@@ -3892,26 +3714,26 @@
|
|
|
3892
3714
|
if (bytes[it.offset] == SWITCH_TO_STRUCTURE) {
|
|
3893
3715
|
it.offset++;
|
|
3894
3716
|
this.currentRefId = number(bytes, it);
|
|
3895
|
-
|
|
3717
|
+
const nextRef = $root.refs.get(this.currentRefId);
|
|
3896
3718
|
//
|
|
3897
3719
|
// Trying to access a reference that haven't been decoded yet.
|
|
3898
3720
|
//
|
|
3899
3721
|
if (!nextRef) {
|
|
3900
|
-
throw new Error("
|
|
3722
|
+
throw new Error(`"refId" not found: ${this.currentRefId}`);
|
|
3901
3723
|
}
|
|
3902
|
-
|
|
3724
|
+
ref[$onDecodeEnd]?.();
|
|
3903
3725
|
ref = nextRef;
|
|
3904
3726
|
decoder = ref['constructor'][$decoder];
|
|
3905
3727
|
continue;
|
|
3906
3728
|
}
|
|
3907
|
-
|
|
3729
|
+
const result = decoder(this, bytes, it, ref, allChanges);
|
|
3908
3730
|
if (result === DEFINITION_MISMATCH) {
|
|
3909
3731
|
console.warn("@colyseus/schema: definition mismatch");
|
|
3910
3732
|
//
|
|
3911
3733
|
// keep skipping next bytes until reaches a known structure
|
|
3912
3734
|
// by local decoder.
|
|
3913
3735
|
//
|
|
3914
|
-
|
|
3736
|
+
const nextIterator = { offset: it.offset };
|
|
3915
3737
|
while (it.offset < totalBytes) {
|
|
3916
3738
|
if (switchStructureCheck(bytes, it)) {
|
|
3917
3739
|
nextIterator.offset = it.offset + 1;
|
|
@@ -3925,130 +3747,118 @@
|
|
|
3925
3747
|
}
|
|
3926
3748
|
}
|
|
3927
3749
|
// FIXME: DRY with SWITCH_TO_STRUCTURE block.
|
|
3928
|
-
|
|
3750
|
+
ref[$onDecodeEnd]?.();
|
|
3929
3751
|
// trigger changes
|
|
3930
|
-
|
|
3752
|
+
this.triggerChanges?.(allChanges);
|
|
3931
3753
|
// drop references of unused schemas
|
|
3932
3754
|
$root.garbageCollectDeletedRefs();
|
|
3933
3755
|
return allChanges;
|
|
3934
|
-
}
|
|
3935
|
-
|
|
3936
|
-
|
|
3756
|
+
}
|
|
3757
|
+
getInstanceType(bytes, it, defaultType) {
|
|
3758
|
+
let type;
|
|
3937
3759
|
if (bytes[it.offset] === TYPE_ID) {
|
|
3938
3760
|
it.offset++;
|
|
3939
|
-
|
|
3761
|
+
const type_id = number(bytes, it);
|
|
3940
3762
|
type = this.context.get(type_id);
|
|
3941
3763
|
}
|
|
3942
3764
|
return type || defaultType;
|
|
3943
|
-
}
|
|
3944
|
-
|
|
3765
|
+
}
|
|
3766
|
+
createInstanceOfType(type) {
|
|
3945
3767
|
// let instance: Schema = new (type as any)();
|
|
3946
3768
|
// // assign root on $changes
|
|
3947
3769
|
// instance[$changes].root = this.root[$changes].root;
|
|
3948
3770
|
// return instance;
|
|
3949
3771
|
return new type();
|
|
3950
|
-
}
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
ref.forEach(function (value, key) {
|
|
3772
|
+
}
|
|
3773
|
+
removeChildRefs(ref, allChanges) {
|
|
3774
|
+
const changeTree = ref[$changes];
|
|
3775
|
+
const needRemoveRef = typeof (ref[$childType]) !== "string";
|
|
3776
|
+
const refId = changeTree.refId;
|
|
3777
|
+
ref.forEach((value, key) => {
|
|
3957
3778
|
allChanges.push({
|
|
3958
3779
|
ref: value,
|
|
3959
|
-
refId
|
|
3780
|
+
refId,
|
|
3960
3781
|
op: exports.OPERATION.DELETE,
|
|
3961
3782
|
field: key,
|
|
3962
3783
|
value: undefined,
|
|
3963
3784
|
previousValue: value
|
|
3964
3785
|
});
|
|
3965
3786
|
if (needRemoveRef) {
|
|
3966
|
-
|
|
3787
|
+
this.$root.removeRef(this.$root.refIds.get(value));
|
|
3967
3788
|
}
|
|
3968
3789
|
});
|
|
3969
|
-
}
|
|
3970
|
-
|
|
3971
|
-
}());
|
|
3790
|
+
}
|
|
3791
|
+
}
|
|
3972
3792
|
|
|
3973
3793
|
/**
|
|
3974
3794
|
* Reflection
|
|
3975
3795
|
*/
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
|
|
3998
|
-
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
return ReflectionType;
|
|
4009
|
-
}(Schema));
|
|
4010
|
-
var Reflection = /** @class */ (function (_super) {
|
|
4011
|
-
__extends(Reflection, _super);
|
|
4012
|
-
function Reflection() {
|
|
4013
|
-
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
4014
|
-
_this.types = new ArraySchema();
|
|
4015
|
-
return _this;
|
|
4016
|
-
}
|
|
4017
|
-
Reflection.encode = function (instance, context) {
|
|
3796
|
+
class ReflectionField extends Schema {
|
|
3797
|
+
}
|
|
3798
|
+
__decorate([
|
|
3799
|
+
type("string")
|
|
3800
|
+
], ReflectionField.prototype, "name", void 0);
|
|
3801
|
+
__decorate([
|
|
3802
|
+
type("string")
|
|
3803
|
+
], ReflectionField.prototype, "type", void 0);
|
|
3804
|
+
__decorate([
|
|
3805
|
+
type("number")
|
|
3806
|
+
], ReflectionField.prototype, "referencedType", void 0);
|
|
3807
|
+
class ReflectionType extends Schema {
|
|
3808
|
+
constructor() {
|
|
3809
|
+
super(...arguments);
|
|
3810
|
+
this.fields = new ArraySchema();
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
__decorate([
|
|
3814
|
+
type("number")
|
|
3815
|
+
], ReflectionType.prototype, "id", void 0);
|
|
3816
|
+
__decorate([
|
|
3817
|
+
type("number")
|
|
3818
|
+
], ReflectionType.prototype, "extendsId", void 0);
|
|
3819
|
+
__decorate([
|
|
3820
|
+
type([ReflectionField])
|
|
3821
|
+
], ReflectionType.prototype, "fields", void 0);
|
|
3822
|
+
class Reflection extends Schema {
|
|
3823
|
+
constructor() {
|
|
3824
|
+
super(...arguments);
|
|
3825
|
+
this.types = new ArraySchema();
|
|
3826
|
+
}
|
|
3827
|
+
static encode(instance, context) {
|
|
4018
3828
|
if (!context) {
|
|
4019
3829
|
context = new TypeContext(instance.constructor);
|
|
4020
3830
|
}
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
for (
|
|
3831
|
+
const reflection = new Reflection();
|
|
3832
|
+
const encoder = new Encoder(reflection);
|
|
3833
|
+
const buildType = (currentType, metadata) => {
|
|
3834
|
+
for (const fieldName in metadata) {
|
|
4025
3835
|
// skip fields from parent classes
|
|
4026
3836
|
if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {
|
|
4027
3837
|
continue;
|
|
4028
3838
|
}
|
|
4029
|
-
|
|
3839
|
+
const field = new ReflectionField();
|
|
4030
3840
|
field.name = fieldName;
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
if (typeof (
|
|
4034
|
-
fieldType =
|
|
3841
|
+
let fieldType;
|
|
3842
|
+
const type = metadata[fieldName].type;
|
|
3843
|
+
if (typeof (type) === "string") {
|
|
3844
|
+
fieldType = type;
|
|
4035
3845
|
}
|
|
4036
3846
|
else {
|
|
4037
|
-
|
|
3847
|
+
let childTypeSchema;
|
|
4038
3848
|
//
|
|
4039
3849
|
// TODO: refactor below.
|
|
4040
3850
|
//
|
|
4041
|
-
if (Schema.is(
|
|
3851
|
+
if (Schema.is(type)) {
|
|
4042
3852
|
fieldType = "ref";
|
|
4043
|
-
childTypeSchema =
|
|
3853
|
+
childTypeSchema = type;
|
|
4044
3854
|
}
|
|
4045
3855
|
else {
|
|
4046
|
-
fieldType = Object.keys(
|
|
4047
|
-
if (typeof (
|
|
4048
|
-
fieldType += ":" +
|
|
3856
|
+
fieldType = Object.keys(type)[0];
|
|
3857
|
+
if (typeof (type[fieldType]) === "string") {
|
|
3858
|
+
fieldType += ":" + type[fieldType]; // array:string
|
|
4049
3859
|
}
|
|
4050
3860
|
else {
|
|
4051
|
-
childTypeSchema =
|
|
3861
|
+
childTypeSchema = type[fieldType];
|
|
4052
3862
|
}
|
|
4053
3863
|
}
|
|
4054
3864
|
field.referencedType = (childTypeSchema)
|
|
@@ -4060,59 +3870,53 @@
|
|
|
4060
3870
|
}
|
|
4061
3871
|
reflection.types.push(currentType);
|
|
4062
3872
|
};
|
|
4063
|
-
for (
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
3873
|
+
for (let typeid in context.types) {
|
|
3874
|
+
const klass = context.types[typeid];
|
|
3875
|
+
const type = new ReflectionType();
|
|
3876
|
+
type.id = Number(typeid);
|
|
4067
3877
|
// support inheritance
|
|
4068
|
-
|
|
3878
|
+
const inheritFrom = Object.getPrototypeOf(klass);
|
|
4069
3879
|
if (inheritFrom !== Schema) {
|
|
4070
|
-
|
|
3880
|
+
type.extendsId = context.schemas.get(inheritFrom);
|
|
4071
3881
|
}
|
|
4072
|
-
buildType(
|
|
3882
|
+
buildType(type, klass[Symbol.metadata]);
|
|
4073
3883
|
}
|
|
4074
|
-
|
|
4075
|
-
|
|
3884
|
+
const it = { offset: 0 };
|
|
3885
|
+
const buf = encoder.encodeAll(it);
|
|
4076
3886
|
return Buffer.from(buf, 0, it.offset);
|
|
4077
|
-
}
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
3887
|
+
}
|
|
3888
|
+
static decode(bytes, it) {
|
|
3889
|
+
const reflection = new Reflection();
|
|
3890
|
+
const reflectionDecoder = new Decoder(reflection);
|
|
4081
3891
|
reflectionDecoder.decode(bytes, it);
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
function _() {
|
|
4088
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
4089
|
-
}
|
|
4090
|
-
return _;
|
|
4091
|
-
}(parentKlass));
|
|
3892
|
+
const context = new TypeContext();
|
|
3893
|
+
const schemaTypes = reflection.types.reduce((types, reflectionType) => {
|
|
3894
|
+
const parentKlass = types[reflectionType.extendsId] || Schema;
|
|
3895
|
+
const schema = class _ extends parentKlass {
|
|
3896
|
+
};
|
|
4092
3897
|
// const _metadata = Object.create(_classSuper[Symbol.metadata] ?? null);
|
|
4093
|
-
|
|
3898
|
+
const _metadata = parentKlass && parentKlass[Symbol.metadata] || Object.create(null);
|
|
4094
3899
|
Object.defineProperty(schema, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
4095
3900
|
// register for inheritance support
|
|
4096
3901
|
TypeContext.register(schema);
|
|
4097
|
-
|
|
3902
|
+
const typeid = reflectionType.id;
|
|
4098
3903
|
types[typeid] = schema;
|
|
4099
3904
|
context.add(schema, typeid);
|
|
4100
3905
|
return types;
|
|
4101
3906
|
}, {});
|
|
4102
|
-
reflection.types.forEach(
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
reflectionType.fields.forEach(
|
|
4108
|
-
|
|
4109
|
-
var fieldIndex = parentFieldIndex + i;
|
|
3907
|
+
reflection.types.forEach((reflectionType) => {
|
|
3908
|
+
const schemaType = schemaTypes[reflectionType.id];
|
|
3909
|
+
const metadata = schemaType[Symbol.metadata];
|
|
3910
|
+
const parentKlass = reflection.types[reflectionType.extendsId];
|
|
3911
|
+
const parentFieldIndex = parentKlass && parentKlass.fields.length || 0;
|
|
3912
|
+
reflectionType.fields.forEach((field, i) => {
|
|
3913
|
+
const fieldIndex = parentFieldIndex + i;
|
|
4110
3914
|
if (field.referencedType !== undefined) {
|
|
4111
|
-
|
|
4112
|
-
|
|
3915
|
+
let fieldType = field.type;
|
|
3916
|
+
let refType = schemaTypes[field.referencedType];
|
|
4113
3917
|
// map or array of primitive type (-1)
|
|
4114
3918
|
if (!refType) {
|
|
4115
|
-
|
|
3919
|
+
const typeInfo = field.type.split(":");
|
|
4116
3920
|
fieldType = typeInfo[0];
|
|
4117
3921
|
refType = typeInfo[1];
|
|
4118
3922
|
}
|
|
@@ -4122,7 +3926,7 @@
|
|
|
4122
3926
|
}
|
|
4123
3927
|
else {
|
|
4124
3928
|
// type({ [fieldType]: refType } as DefinitionType)(schemaType.prototype, field.name);
|
|
4125
|
-
Metadata.addField(metadata, fieldIndex, field.name,
|
|
3929
|
+
Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType });
|
|
4126
3930
|
}
|
|
4127
3931
|
}
|
|
4128
3932
|
else {
|
|
@@ -4132,15 +3936,14 @@
|
|
|
4132
3936
|
});
|
|
4133
3937
|
});
|
|
4134
3938
|
return new (schemaTypes[0])();
|
|
4135
|
-
}
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
]
|
|
4139
|
-
|
|
4140
|
-
}(Schema));
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
__decorate([
|
|
3942
|
+
type([ReflectionType])
|
|
3943
|
+
], Reflection.prototype, "types", void 0);
|
|
4141
3944
|
|
|
4142
|
-
|
|
4143
|
-
|
|
3945
|
+
class StateView {
|
|
3946
|
+
constructor() {
|
|
4144
3947
|
/**
|
|
4145
3948
|
* List of ChangeTree's that are visible to this view
|
|
4146
3949
|
*/
|
|
@@ -4156,22 +3959,17 @@
|
|
|
4156
3959
|
this.changes = new Map();
|
|
4157
3960
|
}
|
|
4158
3961
|
// TODO: allow to set multiple tags at once
|
|
4159
|
-
|
|
4160
|
-
var _this = this;
|
|
4161
|
-
var _a, _b;
|
|
4162
|
-
if (tag === void 0) { tag = DEFAULT_VIEW_TAG; }
|
|
3962
|
+
add(obj, tag = DEFAULT_VIEW_TAG) {
|
|
4163
3963
|
if (!obj[$changes]) {
|
|
4164
3964
|
console.warn("StateView#add(), invalid object:", obj);
|
|
4165
3965
|
return this;
|
|
4166
3966
|
}
|
|
4167
|
-
|
|
3967
|
+
let changeTree = obj[$changes];
|
|
4168
3968
|
this.items.add(changeTree);
|
|
4169
3969
|
// Add children of this ChangeTree to this view
|
|
4170
|
-
changeTree.forEachChild(
|
|
4171
|
-
return _this.add(change.ref, tag);
|
|
4172
|
-
});
|
|
3970
|
+
changeTree.forEachChild((change, _) => this.add(change.ref, tag));
|
|
4173
3971
|
// FIXME: ArraySchema/MapSchema does not have metadata
|
|
4174
|
-
|
|
3972
|
+
const metadata = obj.constructor[Symbol.metadata];
|
|
4175
3973
|
// add parent ChangeTree's, if they are invisible to this view
|
|
4176
3974
|
// TODO: REFACTOR addParent()
|
|
4177
3975
|
this.addParent(changeTree, tag);
|
|
@@ -4179,7 +3977,7 @@
|
|
|
4179
3977
|
// TODO: when adding an item of a MapSchema, the changes may not
|
|
4180
3978
|
// be set (only the parent's changes are set)
|
|
4181
3979
|
//
|
|
4182
|
-
|
|
3980
|
+
let changes = this.changes.get(changeTree);
|
|
4183
3981
|
if (changes === undefined) {
|
|
4184
3982
|
changes = new Map();
|
|
4185
3983
|
this.changes.set(changeTree, changes);
|
|
@@ -4189,7 +3987,7 @@
|
|
|
4189
3987
|
if (!this.tags) {
|
|
4190
3988
|
this.tags = new WeakMap();
|
|
4191
3989
|
}
|
|
4192
|
-
|
|
3990
|
+
let tags;
|
|
4193
3991
|
if (!this.tags.has(changeTree)) {
|
|
4194
3992
|
tags = new Set();
|
|
4195
3993
|
this.tags.set(changeTree, tags);
|
|
@@ -4200,7 +3998,7 @@
|
|
|
4200
3998
|
tags.add(tag);
|
|
4201
3999
|
// console.log("BY TAG:", tag);
|
|
4202
4000
|
// Ref: add tagged properties
|
|
4203
|
-
|
|
4001
|
+
metadata?.[-3]?.[tag]?.forEach((index) => {
|
|
4204
4002
|
if (changeTree.getChange(index) !== exports.OPERATION.DELETE) {
|
|
4205
4003
|
changes.set(index, exports.OPERATION.ADD);
|
|
4206
4004
|
}
|
|
@@ -4214,14 +4012,13 @@
|
|
|
4214
4012
|
// changes.set(index, OPERATION.ADD);
|
|
4215
4013
|
// }
|
|
4216
4014
|
// });
|
|
4217
|
-
|
|
4015
|
+
const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
4218
4016
|
? changeTree.allFilteredChanges
|
|
4219
4017
|
: changeTree.allChanges;
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
for (
|
|
4223
|
-
|
|
4224
|
-
if ((isInvisible || (metadata === null || metadata === void 0 ? void 0 : metadata[metadata === null || metadata === void 0 ? void 0 : metadata[index]].tag) === tag) &&
|
|
4018
|
+
const it = allChangesSet.keys();
|
|
4019
|
+
const isInvisible = this.invisible.has(changeTree);
|
|
4020
|
+
for (const index of it) {
|
|
4021
|
+
if ((isInvisible || metadata?.[metadata?.[index]].tag === tag) &&
|
|
4225
4022
|
changeTree.getChange(index) !== exports.OPERATION.DELETE) {
|
|
4226
4023
|
changes.set(index, exports.OPERATION.ADD);
|
|
4227
4024
|
}
|
|
@@ -4234,14 +4031,14 @@
|
|
|
4234
4031
|
this.items.add(changeTree);
|
|
4235
4032
|
}
|
|
4236
4033
|
return this;
|
|
4237
|
-
}
|
|
4238
|
-
|
|
4239
|
-
|
|
4034
|
+
}
|
|
4035
|
+
addParent(changeTree, tag) {
|
|
4036
|
+
const parentRef = changeTree.parent;
|
|
4240
4037
|
if (!parentRef) {
|
|
4241
4038
|
return;
|
|
4242
4039
|
}
|
|
4243
|
-
|
|
4244
|
-
|
|
4040
|
+
const parentChangeTree = parentRef[$changes];
|
|
4041
|
+
const parentIndex = changeTree.parentIndex;
|
|
4245
4042
|
if (!this.invisible.has(parentChangeTree)) {
|
|
4246
4043
|
// parent is already available, no need to add it!
|
|
4247
4044
|
return;
|
|
@@ -4249,7 +4046,7 @@
|
|
|
4249
4046
|
this.addParent(parentChangeTree, tag);
|
|
4250
4047
|
// add parent's tag properties
|
|
4251
4048
|
if (parentChangeTree.getChange(parentIndex) !== exports.OPERATION.DELETE) {
|
|
4252
|
-
|
|
4049
|
+
let parentChanges = this.changes.get(parentChangeTree);
|
|
4253
4050
|
if (parentChanges === undefined) {
|
|
4254
4051
|
parentChanges = new Map();
|
|
4255
4052
|
this.changes.set(parentChangeTree, parentChanges);
|
|
@@ -4265,7 +4062,7 @@
|
|
|
4265
4062
|
if (!this.tags) {
|
|
4266
4063
|
this.tags = new WeakMap();
|
|
4267
4064
|
}
|
|
4268
|
-
|
|
4065
|
+
let tags;
|
|
4269
4066
|
if (!this.tags.has(parentChangeTree)) {
|
|
4270
4067
|
tags = new Set();
|
|
4271
4068
|
this.tags.set(parentChangeTree, tags);
|
|
@@ -4276,51 +4073,46 @@
|
|
|
4276
4073
|
tags.add(tag);
|
|
4277
4074
|
parentChanges.set(parentIndex, exports.OPERATION.ADD);
|
|
4278
4075
|
}
|
|
4279
|
-
}
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
var changeTree = obj[$changes];
|
|
4076
|
+
}
|
|
4077
|
+
remove(obj, tag = DEFAULT_VIEW_TAG) {
|
|
4078
|
+
const changeTree = obj[$changes];
|
|
4283
4079
|
if (!changeTree) {
|
|
4284
4080
|
console.warn("StateView#remove(), invalid object:", obj);
|
|
4285
4081
|
return this;
|
|
4286
4082
|
}
|
|
4287
4083
|
this.items.delete(changeTree);
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4084
|
+
const ref = changeTree.ref;
|
|
4085
|
+
const metadata = ref.constructor[Symbol.metadata];
|
|
4086
|
+
let changes = this.changes.get(changeTree);
|
|
4291
4087
|
if (changes === undefined) {
|
|
4292
4088
|
changes = new Map();
|
|
4293
4089
|
this.changes.set(changeTree, changes);
|
|
4294
4090
|
}
|
|
4295
4091
|
if (tag === DEFAULT_VIEW_TAG) {
|
|
4296
4092
|
// parent is collection (Map/Array)
|
|
4297
|
-
|
|
4093
|
+
const parent = changeTree.parent;
|
|
4298
4094
|
if (!Metadata.isValidInstance(parent)) {
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
if (
|
|
4302
|
-
|
|
4303
|
-
this.changes.set(parentChangeTree,
|
|
4095
|
+
const parentChangeTree = parent[$changes];
|
|
4096
|
+
let changes = this.changes.get(parentChangeTree);
|
|
4097
|
+
if (changes === undefined) {
|
|
4098
|
+
changes = new Map();
|
|
4099
|
+
this.changes.set(parentChangeTree, changes);
|
|
4304
4100
|
}
|
|
4305
4101
|
// DELETE / DELETE BY REF ID
|
|
4306
|
-
|
|
4102
|
+
changes.set(changeTree.parentIndex, exports.OPERATION.DELETE);
|
|
4307
4103
|
}
|
|
4308
4104
|
else {
|
|
4309
4105
|
// delete all "tagged" properties.
|
|
4310
|
-
metadata[-2].forEach(
|
|
4311
|
-
return changes.set(index, exports.OPERATION.DELETE);
|
|
4312
|
-
});
|
|
4106
|
+
metadata[-2].forEach((index) => changes.set(index, exports.OPERATION.DELETE));
|
|
4313
4107
|
}
|
|
4314
4108
|
}
|
|
4315
4109
|
else {
|
|
4316
4110
|
// delete only tagged properties
|
|
4317
|
-
metadata[-3][tag].forEach(
|
|
4318
|
-
return changes.set(index, exports.OPERATION.DELETE);
|
|
4319
|
-
});
|
|
4111
|
+
metadata[-3][tag].forEach((index) => changes.set(index, exports.OPERATION.DELETE));
|
|
4320
4112
|
}
|
|
4321
4113
|
// remove tag
|
|
4322
4114
|
if (this.tags && this.tags.has(changeTree)) {
|
|
4323
|
-
|
|
4115
|
+
const tags = this.tags.get(changeTree);
|
|
4324
4116
|
if (tag === undefined) {
|
|
4325
4117
|
// delete all tags
|
|
4326
4118
|
this.tags.delete(changeTree);
|
|
@@ -4335,9 +4127,8 @@
|
|
|
4335
4127
|
}
|
|
4336
4128
|
}
|
|
4337
4129
|
return this;
|
|
4338
|
-
}
|
|
4339
|
-
|
|
4340
|
-
}());
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4341
4132
|
|
|
4342
4133
|
registerType("map", { constructor: MapSchema });
|
|
4343
4134
|
registerType("array", { constructor: ArraySchema });
|