@colyseus/schema 3.0.0-alpha.25 → 3.0.0-alpha.27
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 +97 -102
- package/build/cjs/index.js.map +1 -1
- package/build/esm/index.mjs +97 -102
- package/build/esm/index.mjs.map +1 -1
- package/build/umd/index.js +97 -102
- package/lib/Reflection.js +1 -3
- package/lib/Reflection.js.map +1 -1
- package/lib/Schema.d.ts +1 -1
- package/lib/Schema.js +2 -2
- package/lib/Schema.js.map +1 -1
- package/lib/annotations.js +13 -5
- package/lib/annotations.js.map +1 -1
- package/lib/decoder/DecodeOperation.js +1 -0
- package/lib/decoder/DecodeOperation.js.map +1 -1
- package/lib/decoder/Decoder.d.ts +1 -1
- package/lib/decoder/Decoder.js +2 -2
- package/lib/decoder/Decoder.js.map +1 -1
- package/lib/decoder/strategy/StateCallbacks.js +20 -17
- package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
- package/lib/encoder/ChangeTree.js +3 -2
- package/lib/encoder/ChangeTree.js.map +1 -1
- package/lib/encoder/Encoder.d.ts +3 -3
- package/lib/encoder/Encoder.js +10 -11
- package/lib/encoder/Encoder.js.map +1 -1
- package/lib/encoder/StateView.d.ts +2 -2
- package/lib/encoder/StateView.js +45 -60
- package/lib/encoder/StateView.js.map +1 -1
- package/package.json +1 -1
- package/src/Reflection.ts +1 -3
- package/src/Schema.ts +2 -2
- package/src/annotations.ts +16 -5
- package/src/decoder/DecodeOperation.ts +4 -1
- package/src/decoder/Decoder.ts +3 -2
- package/src/decoder/strategy/StateCallbacks.ts +30 -20
- package/src/encoder/ChangeTree.ts +4 -2
- package/src/encoder/Encoder.ts +11 -13
- package/src/encoder/StateView.ts +50 -69
package/build/umd/index.js
CHANGED
|
@@ -333,7 +333,7 @@
|
|
|
333
333
|
// MapSchema / ArraySchema, etc.
|
|
334
334
|
this.ref.forEach((value, key) => {
|
|
335
335
|
if (Metadata.isValidInstance(value)) {
|
|
336
|
-
callback(value[$changes], this.ref[$changes].indexes[key]);
|
|
336
|
+
callback(value[$changes], this.ref[$changes].indexes[key] ?? key);
|
|
337
337
|
}
|
|
338
338
|
});
|
|
339
339
|
}
|
|
@@ -361,8 +361,9 @@
|
|
|
361
361
|
// TODO: are DELETE operations being encoded as ADD here ??
|
|
362
362
|
//
|
|
363
363
|
if (isFiltered) {
|
|
364
|
-
this.allFilteredChanges.set(index, exports.OPERATION.ADD);
|
|
365
364
|
this.root?.filteredChanges.set(this, this.filteredChanges);
|
|
365
|
+
this.allFilteredChanges.set(index, exports.OPERATION.ADD);
|
|
366
|
+
this.root?.allFilteredChanges.set(this, this.allFilteredChanges);
|
|
366
367
|
}
|
|
367
368
|
else {
|
|
368
369
|
this.allChanges.set(index, exports.OPERATION.ADD);
|
|
@@ -1409,6 +1410,7 @@
|
|
|
1409
1410
|
// skip early if field is not defined
|
|
1410
1411
|
const field = metadata[index];
|
|
1411
1412
|
if (field === undefined) {
|
|
1413
|
+
console.warn("@colyseus/schema: field not defined at", { index, ref: ref.constructor.name, metadata });
|
|
1412
1414
|
return DEFINITION_MISMATCH;
|
|
1413
1415
|
}
|
|
1414
1416
|
const { value, previousValue } = decodeValue(decoder, operation, ref, index, metadata[field].type, bytes, it, allChanges);
|
|
@@ -2431,13 +2433,13 @@
|
|
|
2431
2433
|
getTypeId(klass) {
|
|
2432
2434
|
return this.schemas.get(klass);
|
|
2433
2435
|
}
|
|
2434
|
-
discoverTypes(klass) {
|
|
2436
|
+
discoverTypes(klass, parentFieldViewTag) {
|
|
2435
2437
|
if (!this.add(klass)) {
|
|
2436
2438
|
return;
|
|
2437
2439
|
}
|
|
2438
2440
|
// add classes inherited from this base class
|
|
2439
2441
|
TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
|
|
2440
|
-
this.discoverTypes(child);
|
|
2442
|
+
this.discoverTypes(child, parentFieldViewTag);
|
|
2441
2443
|
});
|
|
2442
2444
|
// skip if no fields are defined for this class.
|
|
2443
2445
|
if (klass[Symbol.metadata] === undefined) {
|
|
@@ -2450,7 +2452,15 @@
|
|
|
2450
2452
|
this.hasFilters = true;
|
|
2451
2453
|
}
|
|
2452
2454
|
for (const field in metadata) {
|
|
2455
|
+
//
|
|
2456
|
+
// Modify the field's metadata to include the parent field's view tag
|
|
2457
|
+
//
|
|
2458
|
+
if (parentFieldViewTag !== undefined &&
|
|
2459
|
+
metadata[field].tag === undefined) {
|
|
2460
|
+
metadata[field].tag = parentFieldViewTag;
|
|
2461
|
+
}
|
|
2453
2462
|
const fieldType = metadata[field].type;
|
|
2463
|
+
const viewTag = metadata[field].tag;
|
|
2454
2464
|
if (typeof (fieldType) === "string") {
|
|
2455
2465
|
continue;
|
|
2456
2466
|
}
|
|
@@ -2459,10 +2469,10 @@
|
|
|
2459
2469
|
if (type === "string") {
|
|
2460
2470
|
continue;
|
|
2461
2471
|
}
|
|
2462
|
-
this.discoverTypes(type);
|
|
2472
|
+
this.discoverTypes(type, viewTag);
|
|
2463
2473
|
}
|
|
2464
2474
|
else if (typeof (fieldType) === "function") {
|
|
2465
|
-
this.discoverTypes(fieldType);
|
|
2475
|
+
this.discoverTypes(fieldType, viewTag);
|
|
2466
2476
|
}
|
|
2467
2477
|
else {
|
|
2468
2478
|
const type = Object.values(fieldType)[0];
|
|
@@ -2470,7 +2480,7 @@
|
|
|
2470
2480
|
if (typeof (type) === "string") {
|
|
2471
2481
|
continue;
|
|
2472
2482
|
}
|
|
2473
|
-
this.discoverTypes(type);
|
|
2483
|
+
this.discoverTypes(type, viewTag);
|
|
2474
2484
|
}
|
|
2475
2485
|
}
|
|
2476
2486
|
}
|
|
@@ -3029,13 +3039,13 @@
|
|
|
3029
3039
|
}
|
|
3030
3040
|
return output;
|
|
3031
3041
|
}
|
|
3032
|
-
static debugChangesDeep(ref) {
|
|
3042
|
+
static debugChangesDeep(ref, changeSetName = "changes") {
|
|
3033
3043
|
let output = "";
|
|
3034
3044
|
const rootChangeTree = ref[$changes];
|
|
3035
3045
|
const changeTrees = new Map();
|
|
3036
3046
|
let totalInstances = 0;
|
|
3037
3047
|
let totalOperations = 0;
|
|
3038
|
-
for (const [changeTree, changes] of (rootChangeTree.root.
|
|
3048
|
+
for (const [changeTree, changes] of (rootChangeTree.root[changeSetName].entries())) {
|
|
3039
3049
|
let includeChangeTree = false;
|
|
3040
3050
|
let parentChangeTrees = [];
|
|
3041
3051
|
let parentChangeTree = changeTree.parent?.[$changes];
|
|
@@ -3438,26 +3448,26 @@
|
|
|
3438
3448
|
|
|
3439
3449
|
class Encoder {
|
|
3440
3450
|
static { this.BUFFER_SIZE = 8 * 1024; } // 8KB
|
|
3441
|
-
constructor(
|
|
3451
|
+
constructor(state) {
|
|
3442
3452
|
this.sharedBuffer = Buffer.allocUnsafeSlow(Encoder.BUFFER_SIZE);
|
|
3453
|
+
this.root = new Root();
|
|
3443
3454
|
//
|
|
3444
3455
|
// TODO: cache and restore "Context" based on root schema
|
|
3445
3456
|
// (to avoid creating a new context for every new room)
|
|
3446
3457
|
//
|
|
3447
|
-
this.context = new TypeContext(
|
|
3448
|
-
this.
|
|
3458
|
+
this.context = new TypeContext(state.constructor);
|
|
3459
|
+
this.setState(state);
|
|
3449
3460
|
// console.log(">>>>>>>>>>>>>>>> Encoder types");
|
|
3450
3461
|
// this.context.schemas.forEach((id, schema) => {
|
|
3451
3462
|
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
3452
3463
|
// });
|
|
3453
3464
|
}
|
|
3454
|
-
|
|
3455
|
-
this.root = new Root();
|
|
3465
|
+
setState(state) {
|
|
3456
3466
|
this.state = state;
|
|
3457
|
-
state[$changes].setRoot(this.root);
|
|
3467
|
+
this.state[$changes].setRoot(this.root);
|
|
3458
3468
|
}
|
|
3459
|
-
encode(it = { offset: 0 }, view, buffer = this.sharedBuffer, changeTrees = this.root.changes, isEncodeAll = this.root.allChanges === changeTrees
|
|
3460
|
-
|
|
3469
|
+
encode(it = { offset: 0 }, view, buffer = this.sharedBuffer, changeTrees = this.root.changes, isEncodeAll = this.root.allChanges === changeTrees, initialOffset = it.offset // cache current offset in case we need to resize the buffer
|
|
3470
|
+
) {
|
|
3461
3471
|
const hasView = (view !== undefined);
|
|
3462
3472
|
const rootChangeTree = this.state[$changes];
|
|
3463
3473
|
const changeTreesIterator = changeTrees.entries();
|
|
@@ -3496,7 +3506,6 @@
|
|
|
3496
3506
|
// TODO: avoid checking if no view tags were defined
|
|
3497
3507
|
//
|
|
3498
3508
|
if (filter && !filter(ref, fieldIndex, view)) {
|
|
3499
|
-
// console.log("SKIP FIELD:", { ref: changeTree.ref.constructor.name, fieldIndex, })
|
|
3500
3509
|
// console.log("ADD AS INVISIBLE:", fieldIndex, changeTree.ref.constructor.name)
|
|
3501
3510
|
// view?.invisible.add(changeTree);
|
|
3502
3511
|
continue;
|
|
@@ -3574,8 +3583,6 @@
|
|
|
3574
3583
|
}
|
|
3575
3584
|
encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
|
|
3576
3585
|
const viewOffset = it.offset;
|
|
3577
|
-
// try to encode "filtered" changes
|
|
3578
|
-
this.encode(it, view, bytes, this.root.filteredChanges);
|
|
3579
3586
|
// encode visibility changes (add/remove for this view)
|
|
3580
3587
|
const viewChangesIterator = view.changes.entries();
|
|
3581
3588
|
for (const [changeTree, changes] of viewChangesIterator) {
|
|
@@ -3602,6 +3609,8 @@
|
|
|
3602
3609
|
//
|
|
3603
3610
|
// clear "view" changes after encoding
|
|
3604
3611
|
view.changes.clear();
|
|
3612
|
+
// try to encode "filtered" changes
|
|
3613
|
+
this.encode(it, view, bytes, this.root.filteredChanges, false, viewOffset);
|
|
3605
3614
|
return Buffer.concat([
|
|
3606
3615
|
bytes.subarray(0, sharedOffset),
|
|
3607
3616
|
bytes.subarray(viewOffset, it.offset)
|
|
@@ -3774,14 +3783,14 @@
|
|
|
3774
3783
|
class Decoder {
|
|
3775
3784
|
constructor(root, context) {
|
|
3776
3785
|
this.currentRefId = 0;
|
|
3777
|
-
this.
|
|
3786
|
+
this.setState(root);
|
|
3778
3787
|
this.context = context || new TypeContext(root.constructor);
|
|
3779
3788
|
// console.log(">>>>>>>>>>>>>>>> Decoder types");
|
|
3780
3789
|
// this.context.schemas.forEach((id, schema) => {
|
|
3781
3790
|
// console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
|
|
3782
3791
|
// });
|
|
3783
3792
|
}
|
|
3784
|
-
|
|
3793
|
+
setState(root) {
|
|
3785
3794
|
this.state = root;
|
|
3786
3795
|
this.root = new ReferenceTracker();
|
|
3787
3796
|
this.root.addRef(0, root);
|
|
@@ -3910,9 +3919,7 @@
|
|
|
3910
3919
|
this.types = new ArraySchema();
|
|
3911
3920
|
}
|
|
3912
3921
|
static encode(instance, context, it = { offset: 0 }) {
|
|
3913
|
-
|
|
3914
|
-
context = new TypeContext(instance.constructor);
|
|
3915
|
-
}
|
|
3922
|
+
context ??= new TypeContext(instance.constructor);
|
|
3916
3923
|
const reflection = new Reflection();
|
|
3917
3924
|
const encoder = new Encoder(reflection);
|
|
3918
3925
|
const buildType = (currentType, metadata) => {
|
|
@@ -4036,7 +4043,8 @@
|
|
|
4036
4043
|
function getDecoderStateCallbacks(decoder) {
|
|
4037
4044
|
const $root = decoder.root;
|
|
4038
4045
|
const callbacks = $root.callbacks;
|
|
4039
|
-
|
|
4046
|
+
const onAddCalls = new WeakMap();
|
|
4047
|
+
let currentOnAddCallback;
|
|
4040
4048
|
decoder.triggerChanges = function (allChanges) {
|
|
4041
4049
|
const uniqueRefIds = new Set();
|
|
4042
4050
|
for (let i = 0, l = allChanges.length; i < l; i++) {
|
|
@@ -4099,7 +4107,6 @@
|
|
|
4099
4107
|
}
|
|
4100
4108
|
}
|
|
4101
4109
|
// Handle DELETE_AND_ADD operations
|
|
4102
|
-
// FIXME: should we set "isTriggeringOnAdd" here?
|
|
4103
4110
|
if ((change.op & exports.OPERATION.ADD) === exports.OPERATION.ADD) {
|
|
4104
4111
|
const addCallbacks = $callbacks[exports.OPERATION.ADD];
|
|
4105
4112
|
for (let i = addCallbacks?.length - 1; i >= 0; i--) {
|
|
@@ -4109,12 +4116,10 @@
|
|
|
4109
4116
|
}
|
|
4110
4117
|
else if ((change.op & exports.OPERATION.ADD) === exports.OPERATION.ADD && change.previousValue === undefined) {
|
|
4111
4118
|
// triger onAdd
|
|
4112
|
-
isTriggeringOnAdd = true;
|
|
4113
4119
|
const addCallbacks = $callbacks[exports.OPERATION.ADD];
|
|
4114
4120
|
for (let i = addCallbacks?.length - 1; i >= 0; i--) {
|
|
4115
4121
|
addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
|
|
4116
4122
|
}
|
|
4117
|
-
isTriggeringOnAdd = false;
|
|
4118
4123
|
}
|
|
4119
4124
|
// trigger onChange
|
|
4120
4125
|
if (change.value !== change.previousValue) {
|
|
@@ -4136,7 +4141,7 @@
|
|
|
4136
4141
|
// immediate trigger
|
|
4137
4142
|
if (immediate &&
|
|
4138
4143
|
context.instance[prop] !== undefined &&
|
|
4139
|
-
!
|
|
4144
|
+
!onAddCalls.has(callback) // Workaround for https://github.com/colyseus/schema/issues/147
|
|
4140
4145
|
) {
|
|
4141
4146
|
callback(context.instance[prop], undefined);
|
|
4142
4147
|
}
|
|
@@ -4162,10 +4167,11 @@
|
|
|
4162
4167
|
onChange: function onChange(callback) {
|
|
4163
4168
|
return $root.addCallback($root.refIds.get(context.instance), exports.OPERATION.REPLACE, callback);
|
|
4164
4169
|
},
|
|
4170
|
+
//
|
|
4171
|
+
// TODO: refactor `bindTo()` implementation.
|
|
4172
|
+
// There is room for improvement.
|
|
4173
|
+
//
|
|
4165
4174
|
bindTo: function bindTo(targetObject, properties) {
|
|
4166
|
-
//
|
|
4167
|
-
// TODO: refactor this implementation. There is room for improvement here.
|
|
4168
|
-
//
|
|
4169
4175
|
if (!properties) {
|
|
4170
4176
|
properties = Object.keys(metadata);
|
|
4171
4177
|
}
|
|
@@ -4192,7 +4198,8 @@
|
|
|
4192
4198
|
}
|
|
4193
4199
|
});
|
|
4194
4200
|
return getProxy(metadata[prop].type, {
|
|
4195
|
-
instance
|
|
4201
|
+
// make sure refId is available, otherwise need to wait for the instance to be available.
|
|
4202
|
+
instance: ($root.refIds.get(instance) && instance),
|
|
4196
4203
|
parentInstance: context.instance,
|
|
4197
4204
|
onInstanceAvailable,
|
|
4198
4205
|
});
|
|
@@ -4216,7 +4223,12 @@
|
|
|
4216
4223
|
if (immediate) {
|
|
4217
4224
|
ref.forEach((v, k) => callback(v, k));
|
|
4218
4225
|
}
|
|
4219
|
-
return $root.addCallback($root.refIds.get(ref), exports.OPERATION.ADD,
|
|
4226
|
+
return $root.addCallback($root.refIds.get(ref), exports.OPERATION.ADD, (value, key) => {
|
|
4227
|
+
onAddCalls.set(callback, true);
|
|
4228
|
+
currentOnAddCallback = callback;
|
|
4229
|
+
callback(value, key);
|
|
4230
|
+
onAddCalls.delete(callback);
|
|
4231
|
+
});
|
|
4220
4232
|
};
|
|
4221
4233
|
const onRemove = function (ref, callback) {
|
|
4222
4234
|
return $root.addCallback($root.refIds.get(ref), exports.OPERATION.DELETE, callback);
|
|
@@ -4227,19 +4239,17 @@
|
|
|
4227
4239
|
// https://github.com/colyseus/schema/issues/147
|
|
4228
4240
|
// If parent instance has "onAdd" registered, avoid triggering immediate callback.
|
|
4229
4241
|
//
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4242
|
+
if (context.instance) {
|
|
4243
|
+
return onAdd(context.instance, callback, immediate && !onAddCalls.has(currentOnAddCallback));
|
|
4244
|
+
}
|
|
4245
|
+
else if (context.onInstanceAvailable) {
|
|
4233
4246
|
// collection instance not received yet
|
|
4234
4247
|
let detachCallback = () => { };
|
|
4235
4248
|
context.onInstanceAvailable((ref, existing) => {
|
|
4236
|
-
detachCallback = onAdd(ref, callback, immediate && existing && !
|
|
4249
|
+
detachCallback = onAdd(ref, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback));
|
|
4237
4250
|
});
|
|
4238
4251
|
return () => detachCallback();
|
|
4239
4252
|
}
|
|
4240
|
-
else if (context.instance) {
|
|
4241
|
-
return onAdd(context.instance, callback, immediate && !isTriggeringOnAdd);
|
|
4242
|
-
}
|
|
4243
4253
|
},
|
|
4244
4254
|
onRemove: function (callback) {
|
|
4245
4255
|
if (context.onInstanceAvailable) {
|
|
@@ -4294,26 +4304,21 @@
|
|
|
4294
4304
|
this.changes = new Map();
|
|
4295
4305
|
}
|
|
4296
4306
|
// TODO: allow to set multiple tags at once
|
|
4297
|
-
add(obj, tag = DEFAULT_VIEW_TAG) {
|
|
4307
|
+
add(obj, tag = DEFAULT_VIEW_TAG, checkIncludeParent = true) {
|
|
4298
4308
|
if (!obj[$changes]) {
|
|
4299
4309
|
console.warn("StateView#add(), invalid object:", obj);
|
|
4300
4310
|
return this;
|
|
4301
4311
|
}
|
|
4302
4312
|
// FIXME: ArraySchema/MapSchema does not have metadata
|
|
4303
4313
|
const metadata = obj.constructor[Symbol.metadata];
|
|
4304
|
-
|
|
4314
|
+
const changeTree = obj[$changes];
|
|
4305
4315
|
this.items.add(changeTree);
|
|
4306
|
-
//
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
this.add(change.ref, tag);
|
|
4313
|
-
});
|
|
4314
|
-
// add parent ChangeTree's, if they are invisible to this view
|
|
4315
|
-
// TODO: REFACTOR addParent()
|
|
4316
|
-
this.addParent(changeTree, tag);
|
|
4316
|
+
// add parent ChangeTree's
|
|
4317
|
+
// - if it was invisible to this view
|
|
4318
|
+
// - if it were previously filtered out
|
|
4319
|
+
if (checkIncludeParent && changeTree.parent) {
|
|
4320
|
+
this.addParent(changeTree.parent[$changes], changeTree.parentIndex, tag);
|
|
4321
|
+
}
|
|
4317
4322
|
//
|
|
4318
4323
|
// TODO: when adding an item of a MapSchema, the changes may not
|
|
4319
4324
|
// be set (only the parent's changes are set)
|
|
@@ -4345,73 +4350,63 @@
|
|
|
4345
4350
|
});
|
|
4346
4351
|
}
|
|
4347
4352
|
else {
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
// metadata?.[-3]?.[DEFAULT_VIEW_TAG]?.forEach((index) => {
|
|
4351
|
-
// if (changeTree.getChange(index) !== OPERATION.DELETE) {
|
|
4352
|
-
// changes.set(index, OPERATION.ADD);
|
|
4353
|
-
// }
|
|
4354
|
-
// });
|
|
4355
|
-
const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
4353
|
+
const isInvisible = this.invisible.has(changeTree);
|
|
4354
|
+
const changeSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
|
|
4356
4355
|
? changeTree.allFilteredChanges
|
|
4357
4356
|
: changeTree.allChanges;
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4357
|
+
changeSet.forEach((op, index) => {
|
|
4358
|
+
const tagAtIndex = metadata?.[metadata?.[index]].tag;
|
|
4359
|
+
if ((isInvisible || // if "invisible", include all
|
|
4360
|
+
tagAtIndex === undefined || // "all change" with no tag
|
|
4361
|
+
tagAtIndex === tag // tagged property
|
|
4362
|
+
) &&
|
|
4363
|
+
op !== exports.OPERATION.DELETE) {
|
|
4364
|
+
changes.set(index, op);
|
|
4364
4365
|
}
|
|
4365
|
-
}
|
|
4366
|
-
}
|
|
4367
|
-
// TODO: avoid unnecessary iteration here
|
|
4368
|
-
while (changeTree.parent &&
|
|
4369
|
-
(changeTree = changeTree.parent[$changes]) &&
|
|
4370
|
-
(changeTree.isFiltered || changeTree.isPartiallyFiltered)) {
|
|
4371
|
-
this.items.add(changeTree);
|
|
4366
|
+
});
|
|
4372
4367
|
}
|
|
4368
|
+
// Add children of this ChangeTree to this view
|
|
4369
|
+
changeTree.forEachChild((change, index) => {
|
|
4370
|
+
// Do not ADD children that don't have the same tag
|
|
4371
|
+
if (metadata && metadata[metadata[index]].tag !== tag) {
|
|
4372
|
+
return;
|
|
4373
|
+
}
|
|
4374
|
+
this.add(change.ref, tag, false);
|
|
4375
|
+
});
|
|
4373
4376
|
return this;
|
|
4374
4377
|
}
|
|
4375
|
-
addParent(changeTree, tag) {
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4378
|
+
addParent(changeTree, parentIndex, tag) {
|
|
4379
|
+
// view must have all "changeTree" parent tree
|
|
4380
|
+
this.items.add(changeTree);
|
|
4381
|
+
// add parent's parent
|
|
4382
|
+
const parentChangeTree = changeTree.parent?.[$changes];
|
|
4383
|
+
if (parentChangeTree && (parentChangeTree.isFiltered || parentChangeTree.isPartiallyFiltered)) {
|
|
4384
|
+
this.addParent(parentChangeTree, changeTree.parentIndex, tag);
|
|
4379
4385
|
}
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
if (!this.invisible.has(parentChangeTree)) {
|
|
4383
|
-
// parent is already available, no need to add it!
|
|
4386
|
+
// parent is already available, no need to add it!
|
|
4387
|
+
if (!this.invisible.has(changeTree)) {
|
|
4384
4388
|
return;
|
|
4385
4389
|
}
|
|
4386
|
-
this.addParent(parentChangeTree, tag);
|
|
4387
4390
|
// add parent's tag properties
|
|
4388
|
-
if (
|
|
4389
|
-
let
|
|
4390
|
-
if (
|
|
4391
|
-
|
|
4392
|
-
this.changes.set(
|
|
4391
|
+
if (changeTree.getChange(parentIndex) !== exports.OPERATION.DELETE) {
|
|
4392
|
+
let changes = this.changes.get(changeTree);
|
|
4393
|
+
if (changes === undefined) {
|
|
4394
|
+
changes = new Map();
|
|
4395
|
+
this.changes.set(changeTree, changes);
|
|
4393
4396
|
}
|
|
4394
|
-
// console.log("add parent change", {
|
|
4395
|
-
// parentIndex,
|
|
4396
|
-
// parentChanges,
|
|
4397
|
-
// parentChange: (
|
|
4398
|
-
// parentChangeTree.getChange(parentIndex) &&
|
|
4399
|
-
// OPERATION[parentChangeTree.getChange(parentIndex)]
|
|
4400
|
-
// ),
|
|
4401
|
-
// })
|
|
4402
4397
|
if (!this.tags) {
|
|
4403
4398
|
this.tags = new WeakMap();
|
|
4404
4399
|
}
|
|
4405
4400
|
let tags;
|
|
4406
|
-
if (!this.tags.has(
|
|
4401
|
+
if (!this.tags.has(changeTree)) {
|
|
4407
4402
|
tags = new Set();
|
|
4408
|
-
this.tags.set(
|
|
4403
|
+
this.tags.set(changeTree, tags);
|
|
4409
4404
|
}
|
|
4410
4405
|
else {
|
|
4411
|
-
tags = this.tags.get(
|
|
4406
|
+
tags = this.tags.get(changeTree);
|
|
4412
4407
|
}
|
|
4413
4408
|
tags.add(tag);
|
|
4414
|
-
|
|
4409
|
+
changes.set(parentIndex, exports.OPERATION.ADD);
|
|
4415
4410
|
}
|
|
4416
4411
|
}
|
|
4417
4412
|
remove(obj, tag = DEFAULT_VIEW_TAG) {
|
package/lib/Reflection.js
CHANGED
|
@@ -50,9 +50,7 @@ class Reflection extends Schema_1.Schema {
|
|
|
50
50
|
this.types = new ArraySchema_1.ArraySchema();
|
|
51
51
|
}
|
|
52
52
|
static encode(instance, context, it = { offset: 0 }) {
|
|
53
|
-
|
|
54
|
-
context = new annotations_1.TypeContext(instance.constructor);
|
|
55
|
-
}
|
|
53
|
+
context ??= new annotations_1.TypeContext(instance.constructor);
|
|
56
54
|
const reflection = new Reflection();
|
|
57
55
|
const encoder = new Encoder_1.Encoder(reflection);
|
|
58
56
|
const buildType = (currentType, metadata) => {
|
package/lib/Reflection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Reflection.js","sourceRoot":"","sources":["../src/Reflection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type, PrimitiveType, DefinitionType, TypeContext } from \"./annotations\";\nimport { Metadata } from \"./Metadata\";\nimport { ArraySchema } from \"./types/custom/ArraySchema\";\nimport { Iterator } from \"./encoding/decode\";\nimport { Encoder } from \"./encoder/Encoder\";\nimport { Decoder } from \"./decoder/Decoder\";\nimport { Schema } from \"./Schema\";\n\n/**\n * Reflection\n */\nexport class ReflectionField extends Schema {\n @type(\"string\") name: string;\n @type(\"string\") type: string;\n @type(\"number\") referencedType: number;\n}\n\nexport class ReflectionType extends Schema {\n @type(\"number\") id: number;\n @type(\"number\") extendsId: number;\n @type([ ReflectionField ]) fields = new ArraySchema<ReflectionField>();\n}\n\nexport class Reflection extends Schema {\n @type([ ReflectionType ]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();\n\n static encode(instance: Schema, context?: TypeContext, it: Iterator = { offset: 0 }) {\n if (!context) {\n context = new TypeContext(instance.constructor as typeof Schema);\n }\n\n const reflection = new Reflection();\n const encoder = new Encoder(reflection);\n\n const buildType = (currentType: ReflectionType, metadata: Metadata) => {\n for (const fieldName in metadata) {\n // skip fields from parent classes\n if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {\n continue;\n }\n\n const field = new ReflectionField();\n field.name = fieldName;\n\n let fieldType: string;\n\n const type = metadata[fieldName].type;\n\n if (typeof (type) === \"string\") {\n fieldType = type;\n\n } else {\n let childTypeSchema: typeof Schema;\n\n //\n // TODO: refactor below.\n //\n if (Schema.is(type)) {\n fieldType = \"ref\";\n childTypeSchema = type as typeof Schema;\n\n } else {\n fieldType = Object.keys(type)[0];\n\n if (typeof(type[fieldType]) === \"string\") {\n fieldType += \":\" + type[fieldType]; // array:string\n\n } else {\n childTypeSchema = type[fieldType];\n }\n }\n\n field.referencedType = (childTypeSchema)\n ? context.getTypeId(childTypeSchema)\n : -1;\n }\n\n field.type = fieldType;\n currentType.fields.push(field);\n }\n\n reflection.types.push(currentType);\n }\n\n for (let typeid in context.types) {\n const klass = context.types[typeid];\n const type = new ReflectionType();\n type.id = Number(typeid);\n\n // support inheritance\n const inheritFrom = Object.getPrototypeOf(klass);\n if (inheritFrom !== Schema) {\n type.extendsId = context.schemas.get(inheritFrom);\n }\n\n buildType(type, klass[Symbol.metadata]);\n }\n\n const buf = encoder.encodeAll(it);\n return Buffer.from(buf, 0, it.offset);\n }\n\n static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): T {\n const reflection = new Reflection();\n\n const reflectionDecoder = new Decoder(reflection);\n reflectionDecoder.decode(bytes, it);\n\n const typeContext = new TypeContext();\n\n // 1st pass, initialize metadata + inheritance\n reflection.types.forEach((reflectionType) => {\n const parentClass: typeof Schema = typeContext.get(reflectionType.extendsId) ?? Schema;\n const schema: typeof Schema = class _ extends parentClass {};\n\n const parentMetadata = parentClass[Symbol.metadata];\n\n // register for inheritance support\n TypeContext.register(schema);\n\n // for inheritance support\n Metadata.initialize(schema, parentMetadata);\n\n typeContext.add(schema, reflectionType.id);\n }, {});\n\n // 2nd pass, set fields\n reflection.types.forEach((reflectionType) => {\n const schemaType = typeContext.get(reflectionType.id);\n const metadata = schemaType[Symbol.metadata];\n\n // FIXME: use metadata[-1] to get field count\n const parentFieldIndex = 0;\n\n // console.log(\"--------------------\");\n // // console.log(\"reflectionType\", reflectionType.toJSON());\n // console.log(\"reflectionType.fields\", reflectionType.fields.toJSON());\n // console.log(\"parentFieldIndex\", parentFieldIndex);\n\n //\n // FIXME: set fields using parentKlass as well\n // currently the fields are duplicated on inherited classes\n //\n // // const parentKlass = reflection.types[reflectionType.extendsId];\n // // parentKlass.fields\n\n reflectionType.fields.forEach((field, i) => {\n const fieldIndex = parentFieldIndex + i;\n\n if (field.referencedType !== undefined) {\n let fieldType = field.type;\n let refType: PrimitiveType = typeContext.get(field.referencedType);\n\n // map or array of primitive type (-1)\n if (!refType) {\n const typeInfo = field.type.split(\":\");\n fieldType = typeInfo[0];\n refType = typeInfo[1] as PrimitiveType; // string\n }\n\n if (fieldType === \"ref\") {\n Metadata.addField(metadata, fieldIndex, field.name, refType);\n\n } else {\n Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType } as DefinitionType);\n }\n\n } else {\n Metadata.addField(metadata, fieldIndex, field.name, field.type as PrimitiveType);\n }\n });\n });\n\n // @ts-ignore\n return new (typeContext.get(0))();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Reflection.js","sourceRoot":"","sources":["../src/Reflection.ts"],"names":[],"mappings":"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","sourcesContent":["import { type, PrimitiveType, DefinitionType, TypeContext } from \"./annotations\";\nimport { Metadata } from \"./Metadata\";\nimport { ArraySchema } from \"./types/custom/ArraySchema\";\nimport { Iterator } from \"./encoding/decode\";\nimport { Encoder } from \"./encoder/Encoder\";\nimport { Decoder } from \"./decoder/Decoder\";\nimport { Schema } from \"./Schema\";\n\n/**\n * Reflection\n */\nexport class ReflectionField extends Schema {\n @type(\"string\") name: string;\n @type(\"string\") type: string;\n @type(\"number\") referencedType: number;\n}\n\nexport class ReflectionType extends Schema {\n @type(\"number\") id: number;\n @type(\"number\") extendsId: number;\n @type([ ReflectionField ]) fields = new ArraySchema<ReflectionField>();\n}\n\nexport class Reflection extends Schema {\n @type([ ReflectionType ]) types: ArraySchema<ReflectionType> = new ArraySchema<ReflectionType>();\n\n static encode(instance: Schema, context?: TypeContext, it: Iterator = { offset: 0 }) {\n context ??= new TypeContext(instance.constructor as typeof Schema);\n\n const reflection = new Reflection();\n const encoder = new Encoder(reflection);\n\n const buildType = (currentType: ReflectionType, metadata: Metadata) => {\n for (const fieldName in metadata) {\n // skip fields from parent classes\n if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {\n continue;\n }\n\n const field = new ReflectionField();\n field.name = fieldName;\n\n let fieldType: string;\n\n const type = metadata[fieldName].type;\n\n if (typeof (type) === \"string\") {\n fieldType = type;\n\n } else {\n let childTypeSchema: typeof Schema;\n\n //\n // TODO: refactor below.\n //\n if (Schema.is(type)) {\n fieldType = \"ref\";\n childTypeSchema = type as typeof Schema;\n\n } else {\n fieldType = Object.keys(type)[0];\n\n if (typeof(type[fieldType]) === \"string\") {\n fieldType += \":\" + type[fieldType]; // array:string\n\n } else {\n childTypeSchema = type[fieldType];\n }\n }\n\n field.referencedType = (childTypeSchema)\n ? context.getTypeId(childTypeSchema)\n : -1;\n }\n\n field.type = fieldType;\n currentType.fields.push(field);\n }\n\n reflection.types.push(currentType);\n }\n\n for (let typeid in context.types) {\n const klass = context.types[typeid];\n const type = new ReflectionType();\n type.id = Number(typeid);\n\n // support inheritance\n const inheritFrom = Object.getPrototypeOf(klass);\n if (inheritFrom !== Schema) {\n type.extendsId = context.schemas.get(inheritFrom);\n }\n\n buildType(type, klass[Symbol.metadata]);\n }\n\n const buf = encoder.encodeAll(it);\n return Buffer.from(buf, 0, it.offset);\n }\n\n static decode<T extends Schema = Schema>(bytes: Buffer, it?: Iterator): T {\n const reflection = new Reflection();\n\n const reflectionDecoder = new Decoder(reflection);\n reflectionDecoder.decode(bytes, it);\n\n const typeContext = new TypeContext();\n\n // 1st pass, initialize metadata + inheritance\n reflection.types.forEach((reflectionType) => {\n const parentClass: typeof Schema = typeContext.get(reflectionType.extendsId) ?? Schema;\n const schema: typeof Schema = class _ extends parentClass {};\n\n const parentMetadata = parentClass[Symbol.metadata];\n\n // register for inheritance support\n TypeContext.register(schema);\n\n // for inheritance support\n Metadata.initialize(schema, parentMetadata);\n\n typeContext.add(schema, reflectionType.id);\n }, {});\n\n // 2nd pass, set fields\n reflection.types.forEach((reflectionType) => {\n const schemaType = typeContext.get(reflectionType.id);\n const metadata = schemaType[Symbol.metadata];\n\n // FIXME: use metadata[-1] to get field count\n const parentFieldIndex = 0;\n\n // console.log(\"--------------------\");\n // // console.log(\"reflectionType\", reflectionType.toJSON());\n // console.log(\"reflectionType.fields\", reflectionType.fields.toJSON());\n // console.log(\"parentFieldIndex\", parentFieldIndex);\n\n //\n // FIXME: set fields using parentKlass as well\n // currently the fields are duplicated on inherited classes\n //\n // // const parentKlass = reflection.types[reflectionType.extendsId];\n // // parentKlass.fields\n\n reflectionType.fields.forEach((field, i) => {\n const fieldIndex = parentFieldIndex + i;\n\n if (field.referencedType !== undefined) {\n let fieldType = field.type;\n let refType: PrimitiveType = typeContext.get(field.referencedType);\n\n // map or array of primitive type (-1)\n if (!refType) {\n const typeInfo = field.type.split(\":\");\n fieldType = typeInfo[0];\n refType = typeInfo[1] as PrimitiveType; // string\n }\n\n if (fieldType === \"ref\") {\n Metadata.addField(metadata, fieldIndex, field.name, refType);\n\n } else {\n Metadata.addField(metadata, fieldIndex, field.name, { [fieldType]: refType } as DefinitionType);\n }\n\n } else {\n Metadata.addField(metadata, fieldIndex, field.name, field.type as PrimitiveType);\n }\n });\n });\n\n // @ts-ignore\n return new (typeContext.get(0))();\n }\n}\n"]}
|
package/lib/Schema.d.ts
CHANGED
|
@@ -56,5 +56,5 @@ export declare abstract class Schema {
|
|
|
56
56
|
* @returns
|
|
57
57
|
*/
|
|
58
58
|
static debugChanges(instance: Ref, isEncodeAll?: boolean): string;
|
|
59
|
-
static debugChangesDeep(ref: Ref): string;
|
|
59
|
+
static debugChangesDeep(ref: Ref, changeSetName?: "changes" | "allChanges" | "allFilteredChanges" | "filteredChanges"): string;
|
|
60
60
|
}
|
package/lib/Schema.js
CHANGED
|
@@ -201,13 +201,13 @@ class Schema {
|
|
|
201
201
|
}
|
|
202
202
|
return output;
|
|
203
203
|
}
|
|
204
|
-
static debugChangesDeep(ref) {
|
|
204
|
+
static debugChangesDeep(ref, changeSetName = "changes") {
|
|
205
205
|
let output = "";
|
|
206
206
|
const rootChangeTree = ref[symbols_1.$changes];
|
|
207
207
|
const changeTrees = new Map();
|
|
208
208
|
let totalInstances = 0;
|
|
209
209
|
let totalOperations = 0;
|
|
210
|
-
for (const [changeTree, changes] of (rootChangeTree.root.
|
|
210
|
+
for (const [changeTree, changes] of (rootChangeTree.root[changeSetName].entries())) {
|
|
211
211
|
let includeChangeTree = false;
|
|
212
212
|
let parentChangeTrees = [];
|
|
213
213
|
let parentChangeTree = changeTree.parent?.[symbols_1.$changes];
|
package/lib/Schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Schema.js","sourceRoot":"","sources":["../src/Schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from './encoding/spec';\nimport { DEFAULT_VIEW_TAG, DefinitionType } from \"./annotations\";\n\nimport { NonFunctionPropNames, ToJSON } from './types/HelperTypes';\n\nimport { ChangeTree, Ref } from './encoder/ChangeTree';\nimport { $changes, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex, $track } from './types/symbols';\nimport { StateView } from './encoder/StateView';\n\nimport { encodeSchemaOperation } from './encoder/EncodeOperation';\nimport { decodeSchemaOperation } from './decoder/DecodeOperation';\nimport type { Metadata } from './Metadata';\nimport { getIndent } from './utils';\n\n/**\n * Schema encoder / decoder\n */\nexport abstract class Schema {\n\n static [$encoder] = encodeSchemaOperation;\n static [$decoder] = decodeSchemaOperation;\n\n /**\n * Assign the property descriptors required to track changes on this instance.\n * @param instance\n */\n static initialize(instance: any) {\n Object.defineProperty(instance, $changes, {\n value: new ChangeTree(instance),\n enumerable: false,\n writable: true\n });\n\n const metadata = instance.constructor[Symbol.metadata];\n\n // Define property descriptors\n for (const field in metadata) {\n if (metadata[field].descriptor) {\n // for encoder\n Object.defineProperty(instance, `_${field}`, {\n value: undefined,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n Object.defineProperty(instance, field, metadata[field].descriptor);\n\n } else {\n // for decoder\n Object.defineProperty(instance, field, {\n value: undefined,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n // Object.defineProperty(instance, field, {\n // ...instance.constructor[Symbol.metadata][field].descriptor\n // });\n // if (args[0]?.hasOwnProperty(field)) {\n // instance[field] = args[0][field];\n // }\n }\n }\n\n static is(type: DefinitionType) {\n return typeof(type[Symbol.metadata]) === \"object\";\n // const metadata = type[Symbol.metadata];\n // return metadata && Object.prototype.hasOwnProperty.call(metadata, -1);\n }\n\n /**\n * Track property changes\n */\n static [$track] (changeTree: ChangeTree, index: number, operation: OPERATION = OPERATION.ADD) {\n changeTree.change(index, operation);\n }\n\n /**\n * Determine if a property must be filtered.\n * - If returns false, the property is NOT going to be encoded.\n * - If returns true, the property is going to be encoded.\n *\n * Encoding with \"filters\" happens in two steps:\n * - First, the encoder iterates over all \"not owned\" properties and encodes them.\n * - Then, the encoder iterates over all \"owned\" properties per instance and encodes them.\n */\n static [$filter] (ref: Schema, index: number, view: StateView) {\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n const tag = metadata[metadata[index]].tag;\n\n if (view === undefined) {\n // shared pass/encode: encode if doesn't have a tag\n return tag === undefined;\n\n } else if (tag === undefined) {\n // view pass: no tag\n return true;\n\n } else if (tag === DEFAULT_VIEW_TAG) {\n // view pass: default tag\n return view.items.has(ref[$changes]);\n\n } else {\n // view pass: custom tag\n const tags = view.tags?.get(ref[$changes]);\n return tags && tags.has(tag);\n }\n }\n\n // allow inherited classes to have a constructor\n constructor(...args: any[]) {\n Schema.initialize(this);\n\n //\n // Assign initial values\n //\n if (args[0]) {\n this.assign(args[0]);\n }\n }\n\n public assign(\n props: { [prop in NonFunctionPropNames<this>]?: this[prop] } | ToJSON<this>,\n ) {\n Object.assign(this, props);\n return this;\n }\n\n /**\n * (Server-side): Flag a property to be encoded for the next patch.\n * @param instance Schema instance\n * @param property string representing the property name, or number representing the index of the property.\n * @param operation OPERATION to perform (detected automatically)\n */\n public setDirty<K extends NonFunctionPropNames<this>>(property: K | number, operation?: OPERATION) {\n this[$changes].change(\n this.constructor[Symbol.metadata][property as string].index,\n operation\n );\n }\n\n clone (): this {\n const cloned = new ((this as any).constructor);\n const metadata = this.constructor[Symbol.metadata];\n\n //\n // TODO: clone all properties, not only annotated ones\n //\n // for (const field in this) {\n for (const field in metadata) {\n if (\n typeof (this[field]) === \"object\" &&\n typeof (this[field]?.clone) === \"function\"\n ) {\n // deep clone\n cloned[field] = this[field].clone();\n\n } else {\n // primitive values\n cloned[field] = this[field];\n }\n }\n return cloned;\n }\n\n toJSON () {\n const metadata = this.constructor[Symbol.metadata];\n\n const obj: unknown = {};\n for (const fieldName in metadata) {\n const field = metadata[fieldName];\n if (!field.deprecated && this[fieldName] !== null && typeof (this[fieldName]) !== \"undefined\") {\n obj[fieldName] = (typeof (this[fieldName]['toJSON']) === \"function\")\n ? this[fieldName]['toJSON']()\n : this[fieldName];\n }\n }\n return obj as ToJSON<typeof this>;\n }\n\n discardAllChanges() {\n this[$changes].discardAll();\n }\n\n protected [$getByIndex](index: number) {\n return this[this.constructor[Symbol.metadata][index]];\n }\n\n protected [$deleteByIndex](index: number) {\n this[this.constructor[Symbol.metadata][index]] = undefined;\n }\n\n static debugRefIds(instance: Ref, jsonContents: boolean = true, level: number = 0) {\n const ref = instance;\n const changeTree = ref[$changes];\n\n const contents = (jsonContents) ? ` - ${JSON.stringify(ref.toJSON())}` : \"\";\n\n let output = \"\";\n output += `${getIndent(level)}${ref.constructor.name} (${ref[$changes].refId})${contents}\\n`;\n\n changeTree.forEachChild((childChangeTree) =>\n output += this.debugRefIds(childChangeTree.ref, jsonContents, level + 1));\n\n return output;\n }\n\n /**\n * Return a string representation of the changes on a Schema instance.\n * The list of changes is cleared after each encode.\n *\n * @param instance Schema instance\n * @param isEncodeAll Return \"full encode\" instead of current change set.\n * @returns\n */\n static debugChanges(instance: Ref, isEncodeAll: boolean = false) {\n const changeTree = instance[$changes];\n\n const changeSet = (isEncodeAll) ? changeTree.allChanges : changeTree.changes;\n const changeSetName = (isEncodeAll) ? \"allChanges\" : \"changes\";\n\n let output = `${instance.constructor.name} (${changeTree.refId}) -> .${changeSetName}:\\n`;\n\n function dumpChangeSet(changeSet: Map<number, OPERATION>) {\n Array.from(changeSet)\n .sort((a, b) => a[0] - b[0])\n .forEach(([index, operation]) =>\n output += `- [${index}]: ${OPERATION[operation]} (${JSON.stringify(changeTree.getValue(index, isEncodeAll))})\\n`\n );\n }\n\n dumpChangeSet(changeSet);\n\n // display filtered changes\n if (!isEncodeAll && changeTree.filteredChanges?.size > 0) {\n output += `${instance.constructor.name} (${changeTree.refId}) -> .filteredChanges:\\n`;\n dumpChangeSet(changeTree.filteredChanges);\n }\n\n // display filtered changes\n if (isEncodeAll && changeTree.allFilteredChanges?.size > 0) {\n output += `${instance.constructor.name} (${changeTree.refId}) -> .allFilteredChanges:\\n`;\n dumpChangeSet(changeTree.allFilteredChanges);\n }\n\n return output;\n }\n\n static debugChangesDeep(ref: Ref) {\n let output = \"\";\n\n const rootChangeTree = ref[$changes];\n const changeTrees: Map<ChangeTree, ChangeTree[]> = new Map();\n\n let totalInstances = 0;\n let totalOperations = 0;\n\n for (const [changeTree, changes] of (rootChangeTree.root.changes.entries())) {\n let includeChangeTree = false;\n let parentChangeTrees: ChangeTree[] = [];\n let parentChangeTree = changeTree.parent?.[$changes];\n\n if (changeTree === rootChangeTree) {\n includeChangeTree = true;\n\n } else {\n while (parentChangeTree !== undefined) {\n parentChangeTrees.push(parentChangeTree);\n if (parentChangeTree.ref === ref) {\n includeChangeTree = true;\n break;\n }\n parentChangeTree = parentChangeTree.parent?.[$changes];\n }\n }\n\n if (includeChangeTree) {\n totalInstances += 1;\n totalOperations += changes.size;\n changeTrees.set(changeTree, parentChangeTrees.reverse());\n }\n }\n\n output += \"---\\n\"\n output += `root refId: ${rootChangeTree.refId}\\n`;\n output += `Total instances: ${totalInstances}\\n`;\n output += `Total changes: ${totalOperations}\\n`;\n output += \"---\\n\"\n\n // based on root.changes, display a tree of changes that has the \"ref\" instance as parent\n const visitedParents = new WeakSet<ChangeTree>();\n for (const [changeTree, parentChangeTrees] of changeTrees.entries()) {\n parentChangeTrees.forEach((parentChangeTree, level) => {\n if (!visitedParents.has(parentChangeTree)) {\n output += `${getIndent(level)}${parentChangeTree.ref.constructor.name} (refId: ${parentChangeTree.refId})\\n`;\n visitedParents.add(parentChangeTree);\n }\n });\n\n const changes = changeTree.changes;\n const level = parentChangeTrees.length;\n const indent = getIndent(level);\n\n const parentIndex = (level > 0) ? `(${changeTree.parentIndex}) ` : \"\";\n output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${changes.size}\\n`;\n\n for (const [index, operation] of changes) {\n output += `${getIndent(level + 1)}${OPERATION[operation]}: ${index}\\n`;\n }\n\n }\n\n return `${output}`;\n }\n\n\n}\n\n"]}
|
|
1
|
+
{"version":3,"file":"Schema.js","sourceRoot":"","sources":["../src/Schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from './encoding/spec';\nimport { DEFAULT_VIEW_TAG, DefinitionType } from \"./annotations\";\n\nimport { NonFunctionPropNames, ToJSON } from './types/HelperTypes';\n\nimport { ChangeTree, Ref } from './encoder/ChangeTree';\nimport { $changes, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex, $track } from './types/symbols';\nimport { StateView } from './encoder/StateView';\n\nimport { encodeSchemaOperation } from './encoder/EncodeOperation';\nimport { decodeSchemaOperation } from './decoder/DecodeOperation';\nimport type { Metadata } from './Metadata';\nimport { getIndent } from './utils';\n\n/**\n * Schema encoder / decoder\n */\nexport abstract class Schema {\n\n static [$encoder] = encodeSchemaOperation;\n static [$decoder] = decodeSchemaOperation;\n\n /**\n * Assign the property descriptors required to track changes on this instance.\n * @param instance\n */\n static initialize(instance: any) {\n Object.defineProperty(instance, $changes, {\n value: new ChangeTree(instance),\n enumerable: false,\n writable: true\n });\n\n const metadata = instance.constructor[Symbol.metadata];\n\n // Define property descriptors\n for (const field in metadata) {\n if (metadata[field].descriptor) {\n // for encoder\n Object.defineProperty(instance, `_${field}`, {\n value: undefined,\n writable: true,\n enumerable: false,\n configurable: true,\n });\n Object.defineProperty(instance, field, metadata[field].descriptor);\n\n } else {\n // for decoder\n Object.defineProperty(instance, field, {\n value: undefined,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n }\n\n // Object.defineProperty(instance, field, {\n // ...instance.constructor[Symbol.metadata][field].descriptor\n // });\n // if (args[0]?.hasOwnProperty(field)) {\n // instance[field] = args[0][field];\n // }\n }\n }\n\n static is(type: DefinitionType) {\n return typeof(type[Symbol.metadata]) === \"object\";\n // const metadata = type[Symbol.metadata];\n // return metadata && Object.prototype.hasOwnProperty.call(metadata, -1);\n }\n\n /**\n * Track property changes\n */\n static [$track] (changeTree: ChangeTree, index: number, operation: OPERATION = OPERATION.ADD) {\n changeTree.change(index, operation);\n }\n\n /**\n * Determine if a property must be filtered.\n * - If returns false, the property is NOT going to be encoded.\n * - If returns true, the property is going to be encoded.\n *\n * Encoding with \"filters\" happens in two steps:\n * - First, the encoder iterates over all \"not owned\" properties and encodes them.\n * - Then, the encoder iterates over all \"owned\" properties per instance and encodes them.\n */\n static [$filter] (ref: Schema, index: number, view: StateView) {\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n const tag = metadata[metadata[index]].tag;\n\n if (view === undefined) {\n // shared pass/encode: encode if doesn't have a tag\n return tag === undefined;\n\n } else if (tag === undefined) {\n // view pass: no tag\n return true;\n\n } else if (tag === DEFAULT_VIEW_TAG) {\n // view pass: default tag\n return view.items.has(ref[$changes]);\n\n } else {\n // view pass: custom tag\n const tags = view.tags?.get(ref[$changes]);\n return tags && tags.has(tag);\n }\n }\n\n // allow inherited classes to have a constructor\n constructor(...args: any[]) {\n Schema.initialize(this);\n\n //\n // Assign initial values\n //\n if (args[0]) {\n this.assign(args[0]);\n }\n }\n\n public assign(\n props: { [prop in NonFunctionPropNames<this>]?: this[prop] } | ToJSON<this>,\n ) {\n Object.assign(this, props);\n return this;\n }\n\n /**\n * (Server-side): Flag a property to be encoded for the next patch.\n * @param instance Schema instance\n * @param property string representing the property name, or number representing the index of the property.\n * @param operation OPERATION to perform (detected automatically)\n */\n public setDirty<K extends NonFunctionPropNames<this>>(property: K | number, operation?: OPERATION) {\n this[$changes].change(\n this.constructor[Symbol.metadata][property as string].index,\n operation\n );\n }\n\n clone (): this {\n const cloned = new ((this as any).constructor);\n const metadata = this.constructor[Symbol.metadata];\n\n //\n // TODO: clone all properties, not only annotated ones\n //\n // for (const field in this) {\n for (const field in metadata) {\n if (\n typeof (this[field]) === \"object\" &&\n typeof (this[field]?.clone) === \"function\"\n ) {\n // deep clone\n cloned[field] = this[field].clone();\n\n } else {\n // primitive values\n cloned[field] = this[field];\n }\n }\n return cloned;\n }\n\n toJSON () {\n const metadata = this.constructor[Symbol.metadata];\n\n const obj: unknown = {};\n for (const fieldName in metadata) {\n const field = metadata[fieldName];\n if (!field.deprecated && this[fieldName] !== null && typeof (this[fieldName]) !== \"undefined\") {\n obj[fieldName] = (typeof (this[fieldName]['toJSON']) === \"function\")\n ? this[fieldName]['toJSON']()\n : this[fieldName];\n }\n }\n return obj as ToJSON<typeof this>;\n }\n\n discardAllChanges() {\n this[$changes].discardAll();\n }\n\n protected [$getByIndex](index: number) {\n return this[this.constructor[Symbol.metadata][index]];\n }\n\n protected [$deleteByIndex](index: number) {\n this[this.constructor[Symbol.metadata][index]] = undefined;\n }\n\n static debugRefIds(instance: Ref, jsonContents: boolean = true, level: number = 0) {\n const ref = instance;\n const changeTree = ref[$changes];\n\n const contents = (jsonContents) ? ` - ${JSON.stringify(ref.toJSON())}` : \"\";\n\n let output = \"\";\n output += `${getIndent(level)}${ref.constructor.name} (${ref[$changes].refId})${contents}\\n`;\n\n changeTree.forEachChild((childChangeTree) =>\n output += this.debugRefIds(childChangeTree.ref, jsonContents, level + 1));\n\n return output;\n }\n\n /**\n * Return a string representation of the changes on a Schema instance.\n * The list of changes is cleared after each encode.\n *\n * @param instance Schema instance\n * @param isEncodeAll Return \"full encode\" instead of current change set.\n * @returns\n */\n static debugChanges(instance: Ref, isEncodeAll: boolean = false) {\n const changeTree = instance[$changes];\n\n const changeSet = (isEncodeAll) ? changeTree.allChanges : changeTree.changes;\n const changeSetName = (isEncodeAll) ? \"allChanges\" : \"changes\";\n\n let output = `${instance.constructor.name} (${changeTree.refId}) -> .${changeSetName}:\\n`;\n\n function dumpChangeSet(changeSet: Map<number, OPERATION>) {\n Array.from(changeSet)\n .sort((a, b) => a[0] - b[0])\n .forEach(([index, operation]) =>\n output += `- [${index}]: ${OPERATION[operation]} (${JSON.stringify(changeTree.getValue(index, isEncodeAll))})\\n`\n );\n }\n\n dumpChangeSet(changeSet);\n\n // display filtered changes\n if (!isEncodeAll && changeTree.filteredChanges?.size > 0) {\n output += `${instance.constructor.name} (${changeTree.refId}) -> .filteredChanges:\\n`;\n dumpChangeSet(changeTree.filteredChanges);\n }\n\n // display filtered changes\n if (isEncodeAll && changeTree.allFilteredChanges?.size > 0) {\n output += `${instance.constructor.name} (${changeTree.refId}) -> .allFilteredChanges:\\n`;\n dumpChangeSet(changeTree.allFilteredChanges);\n }\n\n return output;\n }\n\n static debugChangesDeep(ref: Ref, changeSetName: \"changes\" | \"allChanges\" | \"allFilteredChanges\" | \"filteredChanges\" = \"changes\") {\n let output = \"\";\n\n const rootChangeTree = ref[$changes];\n const changeTrees: Map<ChangeTree, ChangeTree[]> = new Map();\n\n let totalInstances = 0;\n let totalOperations = 0;\n\n for (const [changeTree, changes] of (rootChangeTree.root[changeSetName].entries())) {\n let includeChangeTree = false;\n let parentChangeTrees: ChangeTree[] = [];\n let parentChangeTree = changeTree.parent?.[$changes];\n\n if (changeTree === rootChangeTree) {\n includeChangeTree = true;\n\n } else {\n while (parentChangeTree !== undefined) {\n parentChangeTrees.push(parentChangeTree);\n if (parentChangeTree.ref === ref) {\n includeChangeTree = true;\n break;\n }\n parentChangeTree = parentChangeTree.parent?.[$changes];\n }\n }\n\n if (includeChangeTree) {\n totalInstances += 1;\n totalOperations += changes.size;\n changeTrees.set(changeTree, parentChangeTrees.reverse());\n }\n }\n\n output += \"---\\n\"\n output += `root refId: ${rootChangeTree.refId}\\n`;\n output += `Total instances: ${totalInstances}\\n`;\n output += `Total changes: ${totalOperations}\\n`;\n output += \"---\\n\"\n\n // based on root.changes, display a tree of changes that has the \"ref\" instance as parent\n const visitedParents = new WeakSet<ChangeTree>();\n for (const [changeTree, parentChangeTrees] of changeTrees.entries()) {\n parentChangeTrees.forEach((parentChangeTree, level) => {\n if (!visitedParents.has(parentChangeTree)) {\n output += `${getIndent(level)}${parentChangeTree.ref.constructor.name} (refId: ${parentChangeTree.refId})\\n`;\n visitedParents.add(parentChangeTree);\n }\n });\n\n const changes = changeTree.changes;\n const level = parentChangeTrees.length;\n const indent = getIndent(level);\n\n const parentIndex = (level > 0) ? `(${changeTree.parentIndex}) ` : \"\";\n output += `${indent}${parentIndex}${changeTree.ref.constructor.name} (refId: ${changeTree.refId}) - changes: ${changes.size}\\n`;\n\n for (const [index, operation] of changes) {\n output += `${getIndent(level + 1)}${OPERATION[operation]}: ${index}\\n`;\n }\n\n }\n\n return `${output}`;\n }\n\n\n}\n\n"]}
|