@colyseus/schema 2.0.4 → 2.0.6
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/README.md +0 -4
- package/build/cjs/index.js +48 -48
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +130 -104
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +50 -50
- package/lib/Reflection.js +87 -119
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.js +195 -257
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.d.ts +6 -6
- package/lib/annotations.js +64 -92
- package/lib/annotations.js.map +1 -1
- package/lib/changes/ChangeTree.d.ts +1 -1
- package/lib/changes/ChangeTree.js +63 -70
- package/lib/changes/ChangeTree.js.map +1 -1
- package/lib/changes/ReferenceTracker.js +24 -27
- package/lib/changes/ReferenceTracker.js.map +1 -1
- package/lib/codegen/api.js +9 -9
- package/lib/codegen/api.js.map +1 -1
- package/lib/codegen/argv.d.ts +1 -1
- package/lib/codegen/argv.js +11 -11
- package/lib/codegen/argv.js.map +1 -1
- package/lib/codegen/cli.js +21 -10
- package/lib/codegen/cli.js.map +1 -1
- package/lib/codegen/languages/cpp.js +126 -77
- package/lib/codegen/languages/cpp.js.map +1 -1
- package/lib/codegen/languages/csharp.js +121 -62
- package/lib/codegen/languages/csharp.js.map +1 -1
- package/lib/codegen/languages/haxe.js +34 -26
- package/lib/codegen/languages/haxe.js.map +1 -1
- package/lib/codegen/languages/java.js +39 -27
- package/lib/codegen/languages/java.js.map +1 -1
- package/lib/codegen/languages/js.js +48 -32
- package/lib/codegen/languages/js.js.map +1 -1
- package/lib/codegen/languages/lua.js +35 -24
- package/lib/codegen/languages/lua.js.map +1 -1
- package/lib/codegen/languages/ts.js +63 -68
- package/lib/codegen/languages/ts.js.map +1 -1
- package/lib/codegen/parser.d.ts +9 -1
- package/lib/codegen/parser.js +88 -46
- package/lib/codegen/parser.js.map +1 -1
- package/lib/codegen/types.d.ts +8 -0
- package/lib/codegen/types.js +64 -54
- package/lib/codegen/types.js.map +1 -1
- package/lib/encoding/decode.js +15 -15
- package/lib/encoding/decode.js.map +1 -1
- package/lib/encoding/encode.js +14 -14
- package/lib/encoding/encode.js.map +1 -1
- package/lib/events/EventEmitter.d.ts +1 -1
- package/lib/events/EventEmitter.js +16 -47
- package/lib/events/EventEmitter.js.map +1 -1
- package/lib/filters/index.js +7 -8
- package/lib/filters/index.js.map +1 -1
- package/lib/index.js +11 -11
- package/lib/index.js.map +1 -1
- package/lib/types/ArraySchema.d.ts +1 -1
- package/lib/types/ArraySchema.js +161 -219
- package/lib/types/ArraySchema.js.map +1 -1
- package/lib/types/CollectionSchema.d.ts +1 -1
- package/lib/types/CollectionSchema.js +63 -71
- package/lib/types/CollectionSchema.js.map +1 -1
- package/lib/types/HelperTypes.d.ts +9 -9
- package/lib/types/MapSchema.d.ts +16 -16
- package/lib/types/MapSchema.js +68 -78
- package/lib/types/MapSchema.js.map +1 -1
- package/lib/types/SetSchema.js +62 -71
- package/lib/types/SetSchema.js.map +1 -1
- package/lib/types/index.js +1 -1
- package/lib/types/index.js.map +1 -1
- package/lib/types/typeRegistry.js +1 -1
- package/lib/types/typeRegistry.js.map +1 -1
- package/lib/types/utils.js +9 -10
- package/lib/types/utils.js.map +1 -1
- package/lib/utils.js +10 -13
- package/lib/utils.js.map +1 -1
- package/package.json +18 -15
- package/src/Reflection.ts +159 -0
- package/src/Schema.ts +1024 -0
- package/src/annotations.ts +400 -0
- package/src/changes/ChangeTree.ts +295 -0
- package/src/changes/ReferenceTracker.ts +81 -0
- package/src/codegen/api.ts +46 -0
- package/src/codegen/argv.ts +40 -0
- package/src/codegen/cli.ts +65 -0
- package/src/codegen/languages/cpp.ts +297 -0
- package/src/codegen/languages/csharp.ts +208 -0
- package/src/codegen/languages/haxe.ts +110 -0
- package/src/codegen/languages/java.ts +115 -0
- package/src/codegen/languages/js.ts +115 -0
- package/src/codegen/languages/lua.ts +125 -0
- package/src/codegen/languages/ts.ts +129 -0
- package/src/codegen/parser.ts +299 -0
- package/src/codegen/types.ts +177 -0
- package/src/encoding/decode.ts +278 -0
- package/src/encoding/encode.ts +283 -0
- package/src/filters/index.ts +23 -0
- package/src/index.ts +59 -0
- package/src/spec.ts +49 -0
- package/src/types/ArraySchema.ts +612 -0
- package/src/types/CollectionSchema.ts +199 -0
- package/src/types/HelperTypes.ts +34 -0
- package/src/types/MapSchema.ts +268 -0
- package/src/types/SetSchema.ts +208 -0
- package/src/types/typeRegistry.ts +19 -0
- package/src/types/utils.ts +62 -0
- package/src/utils.ts +28 -0
package/lib/Schema.js
CHANGED
|
@@ -1,60 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __read = (this && this.__read) || function (o, n) {
|
|
18
|
-
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
19
|
-
if (!m) return o;
|
|
20
|
-
var i = m.call(o), r, ar = [], e;
|
|
21
|
-
try {
|
|
22
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
23
|
-
}
|
|
24
|
-
catch (error) { e = { error: error }; }
|
|
25
|
-
finally {
|
|
26
|
-
try {
|
|
27
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
28
|
-
}
|
|
29
|
-
finally { if (e) throw e.error; }
|
|
30
|
-
}
|
|
31
|
-
return ar;
|
|
32
|
-
};
|
|
33
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
3
|
exports.Schema = void 0;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
function EncodeSchemaError() {
|
|
51
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
52
|
-
}
|
|
53
|
-
return EncodeSchemaError;
|
|
54
|
-
}(Error));
|
|
4
|
+
const spec_1 = require("./spec");
|
|
5
|
+
const annotations_1 = require("./annotations");
|
|
6
|
+
const encode = require("./encoding/encode");
|
|
7
|
+
const decode = require("./encoding/decode");
|
|
8
|
+
const ArraySchema_1 = require("./types/ArraySchema");
|
|
9
|
+
const MapSchema_1 = require("./types/MapSchema");
|
|
10
|
+
const CollectionSchema_1 = require("./types/CollectionSchema");
|
|
11
|
+
const SetSchema_1 = require("./types/SetSchema");
|
|
12
|
+
const ChangeTree_1 = require("./changes/ChangeTree");
|
|
13
|
+
const filters_1 = require("./filters");
|
|
14
|
+
const typeRegistry_1 = require("./types/typeRegistry");
|
|
15
|
+
const ReferenceTracker_1 = require("./changes/ReferenceTracker");
|
|
16
|
+
const utils_1 = require("./types/utils");
|
|
17
|
+
class EncodeSchemaError extends Error {
|
|
18
|
+
}
|
|
55
19
|
function assertType(value, type, klass, field) {
|
|
56
|
-
|
|
57
|
-
|
|
20
|
+
let typeofTarget;
|
|
21
|
+
let allowNull = false;
|
|
58
22
|
switch (type) {
|
|
59
23
|
case "number":
|
|
60
24
|
case "int8":
|
|
@@ -69,7 +33,7 @@ function assertType(value, type, klass, field) {
|
|
|
69
33
|
case "float64":
|
|
70
34
|
typeofTarget = "number";
|
|
71
35
|
if (isNaN(value)) {
|
|
72
|
-
console.log(
|
|
36
|
+
console.log(`trying to encode "NaN" in ${klass.constructor.name}#${field}`);
|
|
73
37
|
}
|
|
74
38
|
break;
|
|
75
39
|
case "string":
|
|
@@ -81,23 +45,23 @@ function assertType(value, type, klass, field) {
|
|
|
81
45
|
return;
|
|
82
46
|
}
|
|
83
47
|
if (typeof (value) !== typeofTarget && (!allowNull || (allowNull && value !== null))) {
|
|
84
|
-
|
|
85
|
-
throw new EncodeSchemaError(
|
|
48
|
+
let foundValue = `'${JSON.stringify(value)}'${(value && value.constructor && ` (${value.constructor.name})`) || ''}`;
|
|
49
|
+
throw new EncodeSchemaError(`a '${typeofTarget}' was expected, but ${foundValue} was provided in ${klass.constructor.name}#${field}`);
|
|
86
50
|
}
|
|
87
51
|
}
|
|
88
52
|
function assertInstanceType(value, type, klass, field) {
|
|
89
53
|
if (!(value instanceof type)) {
|
|
90
|
-
throw new EncodeSchemaError(
|
|
54
|
+
throw new EncodeSchemaError(`a '${type.name}' was expected, but '${value.constructor.name}' was provided in ${klass.constructor.name}#${field}`);
|
|
91
55
|
}
|
|
92
56
|
}
|
|
93
57
|
function encodePrimitiveType(type, bytes, value, klass, field) {
|
|
94
58
|
assertType(value, type, klass, field);
|
|
95
|
-
|
|
59
|
+
const encodeFunc = encode[type];
|
|
96
60
|
if (encodeFunc) {
|
|
97
61
|
encodeFunc(bytes, value);
|
|
98
62
|
}
|
|
99
63
|
else {
|
|
100
|
-
throw new EncodeSchemaError(
|
|
64
|
+
throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);
|
|
101
65
|
}
|
|
102
66
|
}
|
|
103
67
|
function decodePrimitiveType(type, bytes, it) {
|
|
@@ -106,13 +70,23 @@ function decodePrimitiveType(type, bytes, it) {
|
|
|
106
70
|
/**
|
|
107
71
|
* Schema encoder / decoder
|
|
108
72
|
*/
|
|
109
|
-
|
|
73
|
+
class Schema {
|
|
74
|
+
static { this._definition = annotations_1.SchemaDefinition.create(); }
|
|
75
|
+
static onError(e) {
|
|
76
|
+
console.error(e);
|
|
77
|
+
}
|
|
78
|
+
static is(type) {
|
|
79
|
+
return (type['_definition'] &&
|
|
80
|
+
type['_definition'].schema !== undefined);
|
|
81
|
+
}
|
|
82
|
+
onChange(callback) {
|
|
83
|
+
return (0, utils_1.addCallback)((this.$callbacks || (this.$callbacks = [])), spec_1.OPERATION.REPLACE, callback);
|
|
84
|
+
}
|
|
85
|
+
onRemove(callback) {
|
|
86
|
+
return (0, utils_1.addCallback)((this.$callbacks || (this.$callbacks = [])), spec_1.OPERATION.DELETE, callback);
|
|
87
|
+
}
|
|
110
88
|
// allow inherited classes to have a constructor
|
|
111
|
-
|
|
112
|
-
var args = [];
|
|
113
|
-
for (var _i = 0; _i < arguments.length; _i++) {
|
|
114
|
-
args[_i] = arguments[_i];
|
|
115
|
-
}
|
|
89
|
+
constructor(...args) {
|
|
116
90
|
// fix enumerability of fields for end-user
|
|
117
91
|
Object.defineProperties(this, {
|
|
118
92
|
$changes: {
|
|
@@ -131,7 +105,7 @@ var Schema = /** @class */ (function () {
|
|
|
131
105
|
writable: true
|
|
132
106
|
},
|
|
133
107
|
});
|
|
134
|
-
|
|
108
|
+
const descriptors = this._definition.descriptors;
|
|
135
109
|
if (descriptors) {
|
|
136
110
|
Object.defineProperties(this, descriptors);
|
|
137
111
|
}
|
|
@@ -142,39 +116,21 @@ var Schema = /** @class */ (function () {
|
|
|
142
116
|
this.assign(args[0]);
|
|
143
117
|
}
|
|
144
118
|
}
|
|
145
|
-
|
|
146
|
-
console.error(e);
|
|
147
|
-
};
|
|
148
|
-
Schema.is = function (type) {
|
|
149
|
-
return (type['_definition'] &&
|
|
150
|
-
type['_definition'].schema !== undefined);
|
|
151
|
-
};
|
|
152
|
-
Schema.prototype.onChange = function (callback) {
|
|
153
|
-
return utils_1.addCallback((this.$callbacks || (this.$callbacks = [])), spec_1.OPERATION.REPLACE, callback);
|
|
154
|
-
};
|
|
155
|
-
Schema.prototype.onRemove = function (callback) {
|
|
156
|
-
return utils_1.addCallback((this.$callbacks || (this.$callbacks = [])), spec_1.OPERATION.DELETE, callback);
|
|
157
|
-
};
|
|
158
|
-
Schema.prototype.assign = function (props) {
|
|
119
|
+
assign(props) {
|
|
159
120
|
Object.assign(this, props);
|
|
160
121
|
return this;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
get: function () { return this.constructor._definition; },
|
|
164
|
-
enumerable: false,
|
|
165
|
-
configurable: true
|
|
166
|
-
});
|
|
122
|
+
}
|
|
123
|
+
get _definition() { return this.constructor._definition; }
|
|
167
124
|
/**
|
|
168
125
|
* (Server-side): Flag a property to be encoded for the next patch.
|
|
169
126
|
* @param instance Schema instance
|
|
170
127
|
* @param property string representing the property name, or number representing the index of the property.
|
|
171
128
|
* @param operation OPERATION to perform (detected automatically)
|
|
172
129
|
*/
|
|
173
|
-
|
|
130
|
+
setDirty(property, operation) {
|
|
174
131
|
this.$changes.change(property, operation);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
var _this = this;
|
|
132
|
+
}
|
|
133
|
+
listen(attr, callback) {
|
|
178
134
|
if (!this.$callbacks) {
|
|
179
135
|
this.$callbacks = {};
|
|
180
136
|
}
|
|
@@ -183,33 +139,31 @@ var Schema = /** @class */ (function () {
|
|
|
183
139
|
}
|
|
184
140
|
this.$callbacks[attr].push(callback);
|
|
185
141
|
// return un-register callback.
|
|
186
|
-
return
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
var totalBytes = bytes.length;
|
|
194
|
-
var refId = 0;
|
|
142
|
+
return () => (0, utils_1.spliceOne)(this.$callbacks[attr], this.$callbacks[attr].indexOf(callback));
|
|
143
|
+
}
|
|
144
|
+
decode(bytes, it = { offset: 0 }, ref = this) {
|
|
145
|
+
const allChanges = [];
|
|
146
|
+
const $root = this.$changes.root;
|
|
147
|
+
const totalBytes = bytes.length;
|
|
148
|
+
let refId = 0;
|
|
195
149
|
$root.refs.set(refId, this);
|
|
196
150
|
while (it.offset < totalBytes) {
|
|
197
|
-
|
|
151
|
+
let byte = bytes[it.offset++];
|
|
198
152
|
if (byte == spec_1.SWITCH_TO_STRUCTURE) {
|
|
199
153
|
refId = decode.number(bytes, it);
|
|
200
|
-
|
|
154
|
+
const nextRef = $root.refs.get(refId);
|
|
201
155
|
//
|
|
202
156
|
// Trying to access a reference that haven't been decoded yet.
|
|
203
157
|
//
|
|
204
158
|
if (!nextRef) {
|
|
205
|
-
throw new Error("
|
|
159
|
+
throw new Error(`"refId" not found: ${refId}`);
|
|
206
160
|
}
|
|
207
161
|
ref = nextRef;
|
|
208
162
|
continue;
|
|
209
163
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
164
|
+
const changeTree = ref['$changes'];
|
|
165
|
+
const isSchema = (ref['_definition'] !== undefined);
|
|
166
|
+
const operation = (isSchema)
|
|
213
167
|
? (byte >> 6) << 6 // "compressed" index + operation
|
|
214
168
|
: byte; // "uncompressed" index + operation (array/map items)
|
|
215
169
|
if (operation === spec_1.OPERATION.CLEAR) {
|
|
@@ -221,16 +175,16 @@ var Schema = /** @class */ (function () {
|
|
|
221
175
|
ref.clear(allChanges);
|
|
222
176
|
continue;
|
|
223
177
|
}
|
|
224
|
-
|
|
178
|
+
const fieldIndex = (isSchema)
|
|
225
179
|
? byte % (operation || 255) // if "REPLACE" operation (0), use 255
|
|
226
180
|
: decode.number(bytes, it);
|
|
227
|
-
|
|
181
|
+
const fieldName = (isSchema)
|
|
228
182
|
? (ref['_definition'].fieldsByIndex[fieldIndex])
|
|
229
183
|
: "";
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
184
|
+
let type = changeTree.getType(fieldIndex);
|
|
185
|
+
let value;
|
|
186
|
+
let previousValue;
|
|
187
|
+
let dynamicIndex;
|
|
234
188
|
if (!isSchema) {
|
|
235
189
|
previousValue = ref['getByIndex'](fieldIndex);
|
|
236
190
|
if ((operation & spec_1.OPERATION.ADD) === spec_1.OPERATION.ADD) { // ADD or DELETE_AND_ADD
|
|
@@ -245,7 +199,7 @@ var Schema = /** @class */ (function () {
|
|
|
245
199
|
}
|
|
246
200
|
}
|
|
247
201
|
else {
|
|
248
|
-
previousValue = ref[
|
|
202
|
+
previousValue = ref[`_${fieldName}`];
|
|
249
203
|
}
|
|
250
204
|
//
|
|
251
205
|
// Delete operations
|
|
@@ -266,7 +220,7 @@ var Schema = /** @class */ (function () {
|
|
|
266
220
|
// keep skipping next bytes until reaches a known structure
|
|
267
221
|
// by local decoder.
|
|
268
222
|
//
|
|
269
|
-
|
|
223
|
+
const nextIterator = { offset: it.offset };
|
|
270
224
|
while (it.offset < totalBytes) {
|
|
271
225
|
if (decode.switchStructureCheck(bytes, it)) {
|
|
272
226
|
nextIterator.offset = it.offset + 1;
|
|
@@ -285,23 +239,23 @@ var Schema = /** @class */ (function () {
|
|
|
285
239
|
//
|
|
286
240
|
}
|
|
287
241
|
else if (Schema.is(type)) {
|
|
288
|
-
|
|
289
|
-
value = $root.refs.get(
|
|
242
|
+
const refId = decode.number(bytes, it);
|
|
243
|
+
value = $root.refs.get(refId);
|
|
290
244
|
if (operation !== spec_1.OPERATION.REPLACE) {
|
|
291
|
-
|
|
245
|
+
const childType = this.getSchemaType(bytes, it, type);
|
|
292
246
|
if (!value) {
|
|
293
247
|
value = this.createTypeInstance(childType);
|
|
294
|
-
value.$changes.refId =
|
|
248
|
+
value.$changes.refId = refId;
|
|
295
249
|
if (previousValue) {
|
|
296
250
|
value.$callbacks = previousValue.$callbacks;
|
|
297
251
|
// value.$listeners = previousValue.$listeners;
|
|
298
252
|
if (previousValue['$changes'].refId &&
|
|
299
|
-
|
|
253
|
+
refId !== previousValue['$changes'].refId) {
|
|
300
254
|
$root.removeRef(previousValue['$changes'].refId);
|
|
301
255
|
}
|
|
302
256
|
}
|
|
303
257
|
}
|
|
304
|
-
$root.addRef(
|
|
258
|
+
$root.addRef(refId, value, (value !== previousValue));
|
|
305
259
|
}
|
|
306
260
|
}
|
|
307
261
|
else if (typeof (type) === "string") {
|
|
@@ -311,37 +265,37 @@ var Schema = /** @class */ (function () {
|
|
|
311
265
|
value = decodePrimitiveType(type, bytes, it);
|
|
312
266
|
}
|
|
313
267
|
else {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
? previousValue || $root.refs.get(
|
|
268
|
+
const typeDef = (0, typeRegistry_1.getType)(Object.keys(type)[0]);
|
|
269
|
+
const refId = decode.number(bytes, it);
|
|
270
|
+
const valueRef = ($root.refs.has(refId))
|
|
271
|
+
? previousValue || $root.refs.get(refId)
|
|
318
272
|
: new typeDef.constructor();
|
|
319
273
|
value = valueRef.clone(true);
|
|
320
|
-
value.$changes.refId =
|
|
274
|
+
value.$changes.refId = refId;
|
|
321
275
|
// preserve schema callbacks
|
|
322
276
|
if (previousValue) {
|
|
323
277
|
value['$callbacks'] = previousValue['$callbacks'];
|
|
324
278
|
if (previousValue['$changes'].refId &&
|
|
325
|
-
|
|
279
|
+
refId !== previousValue['$changes'].refId) {
|
|
326
280
|
$root.removeRef(previousValue['$changes'].refId);
|
|
327
281
|
//
|
|
328
282
|
// Trigger onRemove if structure has been replaced.
|
|
329
283
|
//
|
|
330
|
-
|
|
331
|
-
|
|
284
|
+
const entries = previousValue.entries();
|
|
285
|
+
let iter;
|
|
332
286
|
while ((iter = entries.next()) && !iter.done) {
|
|
333
|
-
|
|
287
|
+
const [key, value] = iter.value;
|
|
334
288
|
allChanges.push({
|
|
335
|
-
refId
|
|
289
|
+
refId,
|
|
336
290
|
op: spec_1.OPERATION.DELETE,
|
|
337
291
|
field: key,
|
|
338
292
|
value: undefined,
|
|
339
|
-
previousValue:
|
|
293
|
+
previousValue: value,
|
|
340
294
|
});
|
|
341
295
|
}
|
|
342
296
|
}
|
|
343
297
|
}
|
|
344
|
-
$root.addRef(
|
|
298
|
+
$root.addRef(refId, value, (valueRef !== previousValue));
|
|
345
299
|
}
|
|
346
300
|
if (value !== null &&
|
|
347
301
|
value !== undefined) {
|
|
@@ -354,9 +308,10 @@ var Schema = /** @class */ (function () {
|
|
|
354
308
|
}
|
|
355
309
|
else if (ref instanceof MapSchema_1.MapSchema) {
|
|
356
310
|
// const key = ref['$indexes'].get(field);
|
|
357
|
-
|
|
311
|
+
const key = dynamicIndex;
|
|
358
312
|
// ref.set(key, value);
|
|
359
313
|
ref['$items'].set(key, value);
|
|
314
|
+
ref['$changes'].allChanges.add(fieldIndex);
|
|
360
315
|
}
|
|
361
316
|
else if (ref instanceof ArraySchema_1.ArraySchema) {
|
|
362
317
|
// const key = ref['$indexes'][field];
|
|
@@ -365,11 +320,11 @@ var Schema = /** @class */ (function () {
|
|
|
365
320
|
ref.setAt(fieldIndex, value);
|
|
366
321
|
}
|
|
367
322
|
else if (ref instanceof CollectionSchema_1.CollectionSchema) {
|
|
368
|
-
|
|
323
|
+
const index = ref.add(value);
|
|
369
324
|
ref['setIndex'](fieldIndex, index);
|
|
370
325
|
}
|
|
371
326
|
else if (ref instanceof SetSchema_1.SetSchema) {
|
|
372
|
-
|
|
327
|
+
const index = ref.add(value);
|
|
373
328
|
if (index !== false) {
|
|
374
329
|
ref['setIndex'](fieldIndex, index);
|
|
375
330
|
}
|
|
@@ -377,12 +332,12 @@ var Schema = /** @class */ (function () {
|
|
|
377
332
|
}
|
|
378
333
|
if (previousValue !== value) {
|
|
379
334
|
allChanges.push({
|
|
380
|
-
refId
|
|
335
|
+
refId,
|
|
381
336
|
op: operation,
|
|
382
337
|
field: fieldName,
|
|
383
|
-
dynamicIndex
|
|
384
|
-
value
|
|
385
|
-
previousValue
|
|
338
|
+
dynamicIndex,
|
|
339
|
+
value,
|
|
340
|
+
previousValue,
|
|
386
341
|
});
|
|
387
342
|
}
|
|
388
343
|
}
|
|
@@ -390,19 +345,16 @@ var Schema = /** @class */ (function () {
|
|
|
390
345
|
// drop references of unused schemas
|
|
391
346
|
$root.garbageCollectDeletedRefs();
|
|
392
347
|
return allChanges;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
var changeTree = changeTrees[i];
|
|
404
|
-
var ref = changeTree.ref;
|
|
405
|
-
var isSchema = (ref instanceof Schema);
|
|
348
|
+
}
|
|
349
|
+
encode(encodeAll = false, bytes = [], useFilters = false) {
|
|
350
|
+
const rootChangeTree = this.$changes;
|
|
351
|
+
const refIdsVisited = new WeakSet();
|
|
352
|
+
const changeTrees = [rootChangeTree];
|
|
353
|
+
let numChangeTrees = 1;
|
|
354
|
+
for (let i = 0; i < numChangeTrees; i++) {
|
|
355
|
+
const changeTree = changeTrees[i];
|
|
356
|
+
const ref = changeTree.ref;
|
|
357
|
+
const isSchema = (ref instanceof Schema);
|
|
406
358
|
// Generate unique refId for the ChangeTree.
|
|
407
359
|
changeTree.ensureRefId();
|
|
408
360
|
// mark this ChangeTree as visited.
|
|
@@ -413,19 +365,19 @@ var Schema = /** @class */ (function () {
|
|
|
413
365
|
encode.uint8(bytes, spec_1.SWITCH_TO_STRUCTURE);
|
|
414
366
|
encode.number(bytes, changeTree.refId);
|
|
415
367
|
}
|
|
416
|
-
|
|
368
|
+
const changes = (encodeAll)
|
|
417
369
|
? Array.from(changeTree.allChanges)
|
|
418
370
|
: Array.from(changeTree.changes.values());
|
|
419
|
-
for (
|
|
420
|
-
|
|
371
|
+
for (let j = 0, cl = changes.length; j < cl; j++) {
|
|
372
|
+
const operation = (encodeAll)
|
|
421
373
|
? { op: spec_1.OPERATION.ADD, index: changes[j] }
|
|
422
374
|
: changes[j];
|
|
423
|
-
|
|
424
|
-
|
|
375
|
+
const fieldIndex = operation.index;
|
|
376
|
+
const field = (isSchema)
|
|
425
377
|
? ref['_definition'].fieldsByIndex && ref['_definition'].fieldsByIndex[fieldIndex]
|
|
426
378
|
: fieldIndex;
|
|
427
379
|
// cache begin index if `useFilters`
|
|
428
|
-
|
|
380
|
+
const beginIndex = bytes.length;
|
|
429
381
|
// encode field index + operation
|
|
430
382
|
if (operation.op !== spec_1.OPERATION.TOUCH) {
|
|
431
383
|
if (isSchema) {
|
|
@@ -455,7 +407,7 @@ var Schema = /** @class */ (function () {
|
|
|
455
407
|
//
|
|
456
408
|
// MapSchema dynamic key
|
|
457
409
|
//
|
|
458
|
-
|
|
410
|
+
const dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
|
|
459
411
|
encode.string(bytes, dynamicIndex);
|
|
460
412
|
}
|
|
461
413
|
}
|
|
@@ -469,9 +421,9 @@ var Schema = /** @class */ (function () {
|
|
|
469
421
|
continue;
|
|
470
422
|
}
|
|
471
423
|
// const type = changeTree.childType || ref._schema[field];
|
|
472
|
-
|
|
424
|
+
const type = changeTree.getType(fieldIndex);
|
|
473
425
|
// const type = changeTree.getType(fieldIndex);
|
|
474
|
-
|
|
426
|
+
const value = changeTree.getValue(fieldIndex);
|
|
475
427
|
// Enqueue ChangeTree to be visited
|
|
476
428
|
if (value &&
|
|
477
429
|
value['$changes'] &&
|
|
@@ -505,11 +457,11 @@ var Schema = /** @class */ (function () {
|
|
|
505
457
|
//
|
|
506
458
|
// Custom type (MapSchema, ArraySchema, etc)
|
|
507
459
|
//
|
|
508
|
-
|
|
460
|
+
const definition = (0, typeRegistry_1.getType)(Object.keys(type)[0]);
|
|
509
461
|
//
|
|
510
462
|
// ensure a ArraySchema has been provided
|
|
511
463
|
//
|
|
512
|
-
assertInstanceType(ref[
|
|
464
|
+
assertInstanceType(ref[`_${field}`], definition.constructor, ref, field);
|
|
513
465
|
//
|
|
514
466
|
// Encode refId for this instance.
|
|
515
467
|
// The actual instance is going to be encoded on next `changeTree` iteration.
|
|
@@ -526,38 +478,37 @@ var Schema = /** @class */ (function () {
|
|
|
526
478
|
}
|
|
527
479
|
}
|
|
528
480
|
return bytes;
|
|
529
|
-
}
|
|
530
|
-
|
|
481
|
+
}
|
|
482
|
+
encodeAll(useFilters) {
|
|
531
483
|
return this.encode(true, [], useFilters);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
var _loop_1 = function (i) {
|
|
543
|
-
var changeTree = changeTrees[i];
|
|
484
|
+
}
|
|
485
|
+
applyFilters(client, encodeAll = false) {
|
|
486
|
+
const root = this;
|
|
487
|
+
const refIdsDissallowed = new Set();
|
|
488
|
+
const $filterState = filters_1.ClientState.get(client);
|
|
489
|
+
const changeTrees = [this.$changes];
|
|
490
|
+
let numChangeTrees = 1;
|
|
491
|
+
let filteredBytes = [];
|
|
492
|
+
for (let i = 0; i < numChangeTrees; i++) {
|
|
493
|
+
const changeTree = changeTrees[i];
|
|
544
494
|
if (refIdsDissallowed.has(changeTree.refId)) {
|
|
545
|
-
|
|
495
|
+
// console.log("REFID IS NOT ALLOWED. SKIP.", { refId: changeTree.refId })
|
|
496
|
+
continue;
|
|
546
497
|
}
|
|
547
|
-
|
|
548
|
-
|
|
498
|
+
const ref = changeTree.ref;
|
|
499
|
+
const isSchema = ref instanceof Schema;
|
|
549
500
|
encode.uint8(filteredBytes, spec_1.SWITCH_TO_STRUCTURE);
|
|
550
501
|
encode.number(filteredBytes, changeTree.refId);
|
|
551
|
-
|
|
552
|
-
|
|
502
|
+
const clientHasRefId = $filterState.refIds.has(changeTree);
|
|
503
|
+
const isEncodeAll = (encodeAll || !clientHasRefId);
|
|
553
504
|
// console.log("REF:", ref.constructor.name);
|
|
554
505
|
// console.log("Encode all?", isEncodeAll);
|
|
555
506
|
//
|
|
556
507
|
// include `changeTree` on list of known refIds by this client.
|
|
557
508
|
//
|
|
558
509
|
$filterState.addRefId(changeTree);
|
|
559
|
-
|
|
560
|
-
|
|
510
|
+
const containerIndexes = $filterState.containerIndexes.get(changeTree);
|
|
511
|
+
const changes = (isEncodeAll)
|
|
561
512
|
? Array.from(changeTree.allChanges)
|
|
562
513
|
: Array.from(changeTree.changes.values());
|
|
563
514
|
//
|
|
@@ -567,8 +518,8 @@ var Schema = /** @class */ (function () {
|
|
|
567
518
|
if (!encodeAll &&
|
|
568
519
|
isSchema &&
|
|
569
520
|
ref._definition.indexesWithFilters) {
|
|
570
|
-
|
|
571
|
-
indexesWithFilters.forEach(
|
|
521
|
+
const indexesWithFilters = ref._definition.indexesWithFilters;
|
|
522
|
+
indexesWithFilters.forEach(indexWithFilter => {
|
|
572
523
|
if (!containerIndexes.has(indexWithFilter) &&
|
|
573
524
|
changeTree.allChanges.has(indexWithFilter)) {
|
|
574
525
|
if (isEncodeAll) {
|
|
@@ -580,8 +531,8 @@ var Schema = /** @class */ (function () {
|
|
|
580
531
|
}
|
|
581
532
|
});
|
|
582
533
|
}
|
|
583
|
-
for (
|
|
584
|
-
|
|
534
|
+
for (let j = 0, cl = changes.length; j < cl; j++) {
|
|
535
|
+
const change = (isEncodeAll)
|
|
585
536
|
? { op: spec_1.OPERATION.ADD, index: changes[j] }
|
|
586
537
|
: changes[j];
|
|
587
538
|
// custom operations
|
|
@@ -589,7 +540,7 @@ var Schema = /** @class */ (function () {
|
|
|
589
540
|
encode.uint8(filteredBytes, change.op);
|
|
590
541
|
continue;
|
|
591
542
|
}
|
|
592
|
-
|
|
543
|
+
const fieldIndex = change.index;
|
|
593
544
|
//
|
|
594
545
|
// Deleting fields: encode the operation + field index
|
|
595
546
|
//
|
|
@@ -610,11 +561,11 @@ var Schema = /** @class */ (function () {
|
|
|
610
561
|
continue;
|
|
611
562
|
}
|
|
612
563
|
// indexed operation
|
|
613
|
-
|
|
614
|
-
|
|
564
|
+
const value = changeTree.getValue(fieldIndex);
|
|
565
|
+
const type = changeTree.getType(fieldIndex);
|
|
615
566
|
if (isSchema) {
|
|
616
567
|
// Is a Schema!
|
|
617
|
-
|
|
568
|
+
const filter = (ref._definition.filters &&
|
|
618
569
|
ref._definition.filters[fieldIndex]);
|
|
619
570
|
if (filter && !filter.call(ref, client, value, root)) {
|
|
620
571
|
if (value && value['$changes']) {
|
|
@@ -626,8 +577,8 @@ var Schema = /** @class */ (function () {
|
|
|
626
577
|
}
|
|
627
578
|
else {
|
|
628
579
|
// Is a collection! (map, array, etc.)
|
|
629
|
-
|
|
630
|
-
|
|
580
|
+
const parent = changeTree.parent;
|
|
581
|
+
const filter = changeTree.getChildrenFilter();
|
|
631
582
|
if (filter && !filter.call(parent, client, ref['$indexes'].get(fieldIndex), value, root)) {
|
|
632
583
|
if (value && value['$changes']) {
|
|
633
584
|
refIdsDissallowed.add(value['$changes'].refId);
|
|
@@ -651,7 +602,7 @@ var Schema = /** @class */ (function () {
|
|
|
651
602
|
//
|
|
652
603
|
// use cached bytes directly if is from Schema type.
|
|
653
604
|
//
|
|
654
|
-
filteredBytes.push.apply(filteredBytes,
|
|
605
|
+
filteredBytes.push.apply(filteredBytes, changeTree.caches[fieldIndex] ?? []);
|
|
655
606
|
containerIndexes.add(fieldIndex);
|
|
656
607
|
}
|
|
657
608
|
else {
|
|
@@ -659,7 +610,7 @@ var Schema = /** @class */ (function () {
|
|
|
659
610
|
//
|
|
660
611
|
// use cached bytes if already has the field
|
|
661
612
|
//
|
|
662
|
-
filteredBytes.push.apply(filteredBytes,
|
|
613
|
+
filteredBytes.push.apply(filteredBytes, changeTree.caches[fieldIndex] ?? []);
|
|
663
614
|
}
|
|
664
615
|
else {
|
|
665
616
|
//
|
|
@@ -672,7 +623,7 @@ var Schema = /** @class */ (function () {
|
|
|
672
623
|
//
|
|
673
624
|
// MapSchema dynamic key
|
|
674
625
|
//
|
|
675
|
-
|
|
626
|
+
const dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
|
|
676
627
|
encode.string(filteredBytes, dynamicIndex);
|
|
677
628
|
}
|
|
678
629
|
if (value['$changes']) {
|
|
@@ -699,25 +650,22 @@ var Schema = /** @class */ (function () {
|
|
|
699
650
|
//
|
|
700
651
|
// MapSchema dynamic key
|
|
701
652
|
//
|
|
702
|
-
|
|
653
|
+
const dynamicIndex = changeTree.ref['$indexes'].get(fieldIndex);
|
|
703
654
|
encode.string(filteredBytes, dynamicIndex);
|
|
704
655
|
}
|
|
705
656
|
encode.number(filteredBytes, value['$changes'].refId);
|
|
706
657
|
}
|
|
707
658
|
}
|
|
708
659
|
;
|
|
709
|
-
};
|
|
710
|
-
for (var i = 0; i < numChangeTrees; i++) {
|
|
711
|
-
_loop_1(i);
|
|
712
660
|
}
|
|
713
661
|
return filteredBytes;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
for (
|
|
662
|
+
}
|
|
663
|
+
clone() {
|
|
664
|
+
const cloned = new (this.constructor);
|
|
665
|
+
const schema = this._definition.schema;
|
|
666
|
+
for (let field in schema) {
|
|
719
667
|
if (typeof (this[field]) === "object" &&
|
|
720
|
-
typeof (this[field]
|
|
668
|
+
typeof (this[field]?.clone) === "function") {
|
|
721
669
|
// deep clone
|
|
722
670
|
cloned[field] = this[field].clone();
|
|
723
671
|
}
|
|
@@ -727,76 +675,73 @@ var Schema = /** @class */ (function () {
|
|
|
727
675
|
}
|
|
728
676
|
}
|
|
729
677
|
return cloned;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
for (
|
|
678
|
+
}
|
|
679
|
+
toJSON() {
|
|
680
|
+
const schema = this._definition.schema;
|
|
681
|
+
const deprecated = this._definition.deprecated;
|
|
682
|
+
const obj = {};
|
|
683
|
+
for (let field in schema) {
|
|
736
684
|
if (!deprecated[field] && this[field] !== null && typeof (this[field]) !== "undefined") {
|
|
737
685
|
obj[field] = (typeof (this[field]['toJSON']) === "function")
|
|
738
686
|
? this[field]['toJSON']()
|
|
739
|
-
: this[
|
|
687
|
+
: this[`_${field}`];
|
|
740
688
|
}
|
|
741
689
|
}
|
|
742
690
|
return obj;
|
|
743
|
-
}
|
|
744
|
-
|
|
691
|
+
}
|
|
692
|
+
discardAllChanges() {
|
|
745
693
|
this.$changes.discardAll();
|
|
746
|
-
}
|
|
747
|
-
|
|
694
|
+
}
|
|
695
|
+
getByIndex(index) {
|
|
748
696
|
return this[this._definition.fieldsByIndex[index]];
|
|
749
|
-
}
|
|
750
|
-
|
|
697
|
+
}
|
|
698
|
+
deleteByIndex(index) {
|
|
751
699
|
this[this._definition.fieldsByIndex[index]] = undefined;
|
|
752
|
-
}
|
|
753
|
-
|
|
700
|
+
}
|
|
701
|
+
tryEncodeTypeId(bytes, type, targetType) {
|
|
754
702
|
if (type._typeid !== targetType._typeid) {
|
|
755
703
|
encode.uint8(bytes, spec_1.TYPE_ID);
|
|
756
704
|
encode.number(bytes, targetType._typeid);
|
|
757
705
|
}
|
|
758
|
-
}
|
|
759
|
-
|
|
760
|
-
|
|
706
|
+
}
|
|
707
|
+
getSchemaType(bytes, it, defaultType) {
|
|
708
|
+
let type;
|
|
761
709
|
if (bytes[it.offset] === spec_1.TYPE_ID) {
|
|
762
710
|
it.offset++;
|
|
763
711
|
type = this.constructor._context.get(decode.number(bytes, it));
|
|
764
712
|
}
|
|
765
713
|
return type || defaultType;
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
|
|
714
|
+
}
|
|
715
|
+
createTypeInstance(type) {
|
|
716
|
+
let instance = new type();
|
|
769
717
|
// assign root on $changes
|
|
770
718
|
instance.$changes.root = this.$changes.root;
|
|
771
719
|
return instance;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
var $callbacks = ref['$callbacks'];
|
|
720
|
+
}
|
|
721
|
+
_triggerChanges(changes) {
|
|
722
|
+
const uniqueRefIds = new Set();
|
|
723
|
+
const $refs = this.$changes.root.refs;
|
|
724
|
+
for (let i = 0; i < changes.length; i++) {
|
|
725
|
+
const change = changes[i];
|
|
726
|
+
const refId = change.refId;
|
|
727
|
+
const ref = $refs.get(refId);
|
|
728
|
+
const $callbacks = ref['$callbacks'];
|
|
782
729
|
//
|
|
783
730
|
// trigger onRemove on child structure.
|
|
784
731
|
//
|
|
785
732
|
if ((change.op & spec_1.OPERATION.DELETE) === spec_1.OPERATION.DELETE &&
|
|
786
733
|
change.previousValue instanceof Schema) {
|
|
787
|
-
|
|
734
|
+
change.previousValue['$callbacks']?.[spec_1.OPERATION.DELETE]?.forEach(callback => callback());
|
|
788
735
|
}
|
|
789
736
|
// no callbacks defined, skip this structure!
|
|
790
737
|
if (!$callbacks) {
|
|
791
|
-
|
|
738
|
+
continue;
|
|
792
739
|
}
|
|
793
740
|
if (ref instanceof Schema) {
|
|
794
741
|
if (!uniqueRefIds.has(refId)) {
|
|
795
742
|
try {
|
|
796
743
|
// trigger onChange
|
|
797
|
-
|
|
798
|
-
return callback(changes);
|
|
799
|
-
});
|
|
744
|
+
$callbacks?.[spec_1.OPERATION.REPLACE]?.forEach(callback => callback(changes));
|
|
800
745
|
}
|
|
801
746
|
catch (e) {
|
|
802
747
|
Schema.onError(e);
|
|
@@ -804,9 +749,7 @@ var Schema = /** @class */ (function () {
|
|
|
804
749
|
}
|
|
805
750
|
try {
|
|
806
751
|
if ($callbacks.hasOwnProperty(change.field)) {
|
|
807
|
-
|
|
808
|
-
return callback(change.value, change.previousValue);
|
|
809
|
-
});
|
|
752
|
+
$callbacks[change.field]?.forEach((callback) => callback(change.value, change.previousValue));
|
|
810
753
|
}
|
|
811
754
|
}
|
|
812
755
|
catch (e) {
|
|
@@ -817,7 +760,7 @@ var Schema = /** @class */ (function () {
|
|
|
817
760
|
// is a collection of items
|
|
818
761
|
if (change.op === spec_1.OPERATION.ADD && change.previousValue === undefined) {
|
|
819
762
|
// triger onAdd
|
|
820
|
-
|
|
763
|
+
$callbacks[spec_1.OPERATION.ADD]?.forEach(callback => callback(change.value, change.dynamicIndex ?? change.field));
|
|
821
764
|
}
|
|
822
765
|
else if (change.op === spec_1.OPERATION.DELETE) {
|
|
823
766
|
//
|
|
@@ -826,30 +769,25 @@ var Schema = /** @class */ (function () {
|
|
|
826
769
|
//
|
|
827
770
|
if (change.previousValue !== undefined) {
|
|
828
771
|
// triger onRemove
|
|
829
|
-
|
|
772
|
+
$callbacks[spec_1.OPERATION.DELETE]?.forEach(callback => callback(change.previousValue, change.dynamicIndex ?? change.field));
|
|
830
773
|
}
|
|
831
774
|
}
|
|
832
775
|
else if (change.op === spec_1.OPERATION.DELETE_AND_ADD) {
|
|
833
776
|
// triger onRemove
|
|
834
777
|
if (change.previousValue !== undefined) {
|
|
835
|
-
|
|
778
|
+
$callbacks[spec_1.OPERATION.DELETE]?.forEach(callback => callback(change.previousValue, change.dynamicIndex ?? change.field));
|
|
836
779
|
}
|
|
837
780
|
// triger onAdd
|
|
838
|
-
|
|
781
|
+
$callbacks[spec_1.OPERATION.ADD]?.forEach(callback => callback(change.value, change.dynamicIndex ?? change.field));
|
|
839
782
|
}
|
|
840
783
|
// trigger onChange
|
|
841
784
|
if (change.value !== change.previousValue) {
|
|
842
|
-
|
|
785
|
+
$callbacks[spec_1.OPERATION.REPLACE]?.forEach(callback => callback(change.value, change.dynamicIndex ?? change.field));
|
|
843
786
|
}
|
|
844
787
|
}
|
|
845
788
|
uniqueRefIds.add(refId);
|
|
846
|
-
};
|
|
847
|
-
for (var i = 0; i < changes.length; i++) {
|
|
848
|
-
_loop_2(i);
|
|
849
789
|
}
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
return Schema;
|
|
853
|
-
}());
|
|
790
|
+
}
|
|
791
|
+
}
|
|
854
792
|
exports.Schema = Schema;
|
|
855
793
|
//# sourceMappingURL=Schema.js.map
|