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