@colyseus/schema 3.0.0-alpha.24 → 3.0.0-alpha.26

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.
@@ -152,7 +152,7 @@
152
152
  // TODO: remove/refactor this...
153
153
  //
154
154
  const metadata = {};
155
- klass.constructor[Symbol.metadata] = metadata;
155
+ klass[Symbol.metadata] = metadata;
156
156
  Object.defineProperty(metadata, -1, {
157
157
  value: 0,
158
158
  enumerable: false,
@@ -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);
@@ -2419,19 +2421,25 @@
2419
2421
  return false;
2420
2422
  }
2421
2423
  this.types[typeid] = schema;
2424
+ //
2425
+ // Workaround to allow using an empty Schema (with no `@type()` fields)
2426
+ //
2427
+ if (schema[Symbol.metadata] === undefined) {
2428
+ Metadata.init(schema);
2429
+ }
2422
2430
  this.schemas.set(schema, typeid);
2423
2431
  return true;
2424
2432
  }
2425
2433
  getTypeId(klass) {
2426
2434
  return this.schemas.get(klass);
2427
2435
  }
2428
- discoverTypes(klass) {
2436
+ discoverTypes(klass, parentFieldViewTag) {
2429
2437
  if (!this.add(klass)) {
2430
2438
  return;
2431
2439
  }
2432
2440
  // add classes inherited from this base class
2433
2441
  TypeContext.inheritedTypes.get(klass)?.forEach((child) => {
2434
- this.discoverTypes(child);
2442
+ this.discoverTypes(child, parentFieldViewTag);
2435
2443
  });
2436
2444
  // skip if no fields are defined for this class.
2437
2445
  if (klass[Symbol.metadata] === undefined) {
@@ -2444,7 +2452,15 @@
2444
2452
  this.hasFilters = true;
2445
2453
  }
2446
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
+ }
2447
2462
  const fieldType = metadata[field].type;
2463
+ const viewTag = metadata[field].tag;
2448
2464
  if (typeof (fieldType) === "string") {
2449
2465
  continue;
2450
2466
  }
@@ -2453,10 +2469,10 @@
2453
2469
  if (type === "string") {
2454
2470
  continue;
2455
2471
  }
2456
- this.discoverTypes(type);
2472
+ this.discoverTypes(type, viewTag);
2457
2473
  }
2458
2474
  else if (typeof (fieldType) === "function") {
2459
- this.discoverTypes(fieldType);
2475
+ this.discoverTypes(fieldType, viewTag);
2460
2476
  }
2461
2477
  else {
2462
2478
  const type = Object.values(fieldType)[0];
@@ -2464,7 +2480,7 @@
2464
2480
  if (typeof (type) === "string") {
2465
2481
  continue;
2466
2482
  }
2467
- this.discoverTypes(type);
2483
+ this.discoverTypes(type, viewTag);
2468
2484
  }
2469
2485
  }
2470
2486
  }
@@ -3023,13 +3039,13 @@
3023
3039
  }
3024
3040
  return output;
3025
3041
  }
3026
- static debugChangesDeep(ref) {
3042
+ static debugChangesDeep(ref, changeSetName = "changes") {
3027
3043
  let output = "";
3028
3044
  const rootChangeTree = ref[$changes];
3029
3045
  const changeTrees = new Map();
3030
3046
  let totalInstances = 0;
3031
3047
  let totalOperations = 0;
3032
- for (const [changeTree, changes] of (rootChangeTree.root.changes.entries())) {
3048
+ for (const [changeTree, changes] of (rootChangeTree.root[changeSetName].entries())) {
3033
3049
  let includeChangeTree = false;
3034
3050
  let parentChangeTrees = [];
3035
3051
  let parentChangeTree = changeTree.parent?.[$changes];
@@ -3432,30 +3448,26 @@
3432
3448
 
3433
3449
  class Encoder {
3434
3450
  static { this.BUFFER_SIZE = 8 * 1024; } // 8KB
3435
- constructor(root) {
3451
+ constructor(state) {
3436
3452
  this.sharedBuffer = Buffer.allocUnsafeSlow(Encoder.BUFFER_SIZE);
3437
- this.setRoot(root);
3453
+ this.root = new Root();
3438
3454
  //
3439
3455
  // TODO: cache and restore "Context" based on root schema
3440
3456
  // (to avoid creating a new context for every new room)
3441
3457
  //
3442
- this.context = new TypeContext(root.constructor);
3458
+ this.context = new TypeContext(state.constructor);
3459
+ this.setState(state);
3443
3460
  // console.log(">>>>>>>>>>>>>>>> Encoder types");
3444
3461
  // this.context.schemas.forEach((id, schema) => {
3445
3462
  // console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
3446
3463
  // });
3447
3464
  }
3448
- setRoot(state) {
3449
- this.root = new Root();
3465
+ setState(state) {
3450
3466
  this.state = state;
3451
- // Workaround to allow using an empty Schema.
3452
- if (state.constructor[Symbol.metadata] === undefined) {
3453
- Metadata.init(state);
3454
- }
3455
- state[$changes].setRoot(this.root);
3467
+ this.state[$changes].setRoot(this.root);
3456
3468
  }
3457
- encode(it = { offset: 0 }, view, buffer = this.sharedBuffer, changeTrees = this.root.changes, isEncodeAll = this.root.allChanges === changeTrees) {
3458
- const initialOffset = it.offset; // cache current offset in case we need to resize the buffer
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
+ ) {
3459
3471
  const hasView = (view !== undefined);
3460
3472
  const rootChangeTree = this.state[$changes];
3461
3473
  const changeTreesIterator = changeTrees.entries();
@@ -3494,7 +3506,6 @@
3494
3506
  // TODO: avoid checking if no view tags were defined
3495
3507
  //
3496
3508
  if (filter && !filter(ref, fieldIndex, view)) {
3497
- // console.log("SKIP FIELD:", { ref: changeTree.ref.constructor.name, fieldIndex, })
3498
3509
  // console.log("ADD AS INVISIBLE:", fieldIndex, changeTree.ref.constructor.name)
3499
3510
  // view?.invisible.add(changeTree);
3500
3511
  continue;
@@ -3572,8 +3583,6 @@
3572
3583
  }
3573
3584
  encodeView(view, sharedOffset, it, bytes = this.sharedBuffer) {
3574
3585
  const viewOffset = it.offset;
3575
- // try to encode "filtered" changes
3576
- this.encode(it, view, bytes, this.root.filteredChanges);
3577
3586
  // encode visibility changes (add/remove for this view)
3578
3587
  const viewChangesIterator = view.changes.entries();
3579
3588
  for (const [changeTree, changes] of viewChangesIterator) {
@@ -3600,6 +3609,8 @@
3600
3609
  //
3601
3610
  // clear "view" changes after encoding
3602
3611
  view.changes.clear();
3612
+ // try to encode "filtered" changes
3613
+ this.encode(it, view, bytes, this.root.filteredChanges, false, viewOffset);
3603
3614
  return Buffer.concat([
3604
3615
  bytes.subarray(0, sharedOffset),
3605
3616
  bytes.subarray(viewOffset, it.offset)
@@ -3772,14 +3783,14 @@
3772
3783
  class Decoder {
3773
3784
  constructor(root, context) {
3774
3785
  this.currentRefId = 0;
3775
- this.setRoot(root);
3786
+ this.setState(root);
3776
3787
  this.context = context || new TypeContext(root.constructor);
3777
3788
  // console.log(">>>>>>>>>>>>>>>> Decoder types");
3778
3789
  // this.context.schemas.forEach((id, schema) => {
3779
3790
  // console.log("type:", id, schema.name, Object.keys(schema[Symbol.metadata]));
3780
3791
  // });
3781
3792
  }
3782
- setRoot(root) {
3793
+ setState(root) {
3783
3794
  this.state = root;
3784
3795
  this.root = new ReferenceTracker();
3785
3796
  this.root.addRef(0, root);
@@ -3908,9 +3919,7 @@
3908
3919
  this.types = new ArraySchema();
3909
3920
  }
3910
3921
  static encode(instance, context, it = { offset: 0 }) {
3911
- if (!context) {
3912
- context = new TypeContext(instance.constructor);
3913
- }
3922
+ context ??= new TypeContext(instance.constructor);
3914
3923
  const reflection = new Reflection();
3915
3924
  const encoder = new Encoder(reflection);
3916
3925
  const buildType = (currentType, metadata) => {
@@ -4292,26 +4301,21 @@
4292
4301
  this.changes = new Map();
4293
4302
  }
4294
4303
  // TODO: allow to set multiple tags at once
4295
- add(obj, tag = DEFAULT_VIEW_TAG) {
4304
+ add(obj, tag = DEFAULT_VIEW_TAG, checkIncludeParent = true) {
4296
4305
  if (!obj[$changes]) {
4297
4306
  console.warn("StateView#add(), invalid object:", obj);
4298
4307
  return this;
4299
4308
  }
4300
4309
  // FIXME: ArraySchema/MapSchema does not have metadata
4301
4310
  const metadata = obj.constructor[Symbol.metadata];
4302
- let changeTree = obj[$changes];
4311
+ const changeTree = obj[$changes];
4303
4312
  this.items.add(changeTree);
4304
- // Add children of this ChangeTree to this view
4305
- changeTree.forEachChild((change, index) => {
4306
- // Do not ADD children that don't have the same tag
4307
- if (metadata && metadata[metadata[index]].tag !== tag) {
4308
- return;
4309
- }
4310
- this.add(change.ref, tag);
4311
- });
4312
- // add parent ChangeTree's, if they are invisible to this view
4313
- // TODO: REFACTOR addParent()
4314
- this.addParent(changeTree, tag);
4313
+ // add parent ChangeTree's
4314
+ // - if it was invisible to this view
4315
+ // - if it were previously filtered out
4316
+ if (checkIncludeParent && changeTree.parent) {
4317
+ this.addParent(changeTree.parent[$changes], changeTree.parentIndex, tag);
4318
+ }
4315
4319
  //
4316
4320
  // TODO: when adding an item of a MapSchema, the changes may not
4317
4321
  // be set (only the parent's changes are set)
@@ -4343,73 +4347,63 @@
4343
4347
  });
4344
4348
  }
4345
4349
  else {
4346
- // console.log("DEFAULT TAG", changeTree.allChanges);
4347
- // // add default tag properties
4348
- // metadata?.[-3]?.[DEFAULT_VIEW_TAG]?.forEach((index) => {
4349
- // if (changeTree.getChange(index) !== OPERATION.DELETE) {
4350
- // changes.set(index, OPERATION.ADD);
4351
- // }
4352
- // });
4353
- const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
4350
+ const isInvisible = this.invisible.has(changeTree);
4351
+ const changeSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)
4354
4352
  ? changeTree.allFilteredChanges
4355
4353
  : changeTree.allChanges;
4356
- const it = allChangesSet.keys();
4357
- const isInvisible = this.invisible.has(changeTree);
4358
- for (const index of it) {
4359
- if ((isInvisible || metadata?.[metadata?.[index]].tag === tag) &&
4360
- changeTree.getChange(index) !== exports.OPERATION.DELETE) {
4361
- changes.set(index, exports.OPERATION.ADD);
4354
+ changeSet.forEach((op, index) => {
4355
+ const tagAtIndex = metadata?.[metadata?.[index]].tag;
4356
+ if ((isInvisible || // if "invisible", include all
4357
+ tagAtIndex === undefined || // "all change" with no tag
4358
+ tagAtIndex === tag // tagged property
4359
+ ) &&
4360
+ op !== exports.OPERATION.DELETE) {
4361
+ changes.set(index, op);
4362
4362
  }
4363
- }
4364
- }
4365
- // TODO: avoid unnecessary iteration here
4366
- while (changeTree.parent &&
4367
- (changeTree = changeTree.parent[$changes]) &&
4368
- (changeTree.isFiltered || changeTree.isPartiallyFiltered)) {
4369
- this.items.add(changeTree);
4363
+ });
4370
4364
  }
4365
+ // Add children of this ChangeTree to this view
4366
+ changeTree.forEachChild((change, index) => {
4367
+ // Do not ADD children that don't have the same tag
4368
+ if (metadata && metadata[metadata[index]].tag !== tag) {
4369
+ return;
4370
+ }
4371
+ this.add(change.ref, tag, false);
4372
+ });
4371
4373
  return this;
4372
4374
  }
4373
- addParent(changeTree, tag) {
4374
- const parentRef = changeTree.parent;
4375
- if (!parentRef) {
4376
- return;
4375
+ addParent(changeTree, parentIndex, tag) {
4376
+ // view must have all "changeTree" parent tree
4377
+ this.items.add(changeTree);
4378
+ // add parent's parent
4379
+ const parentChangeTree = changeTree.parent?.[$changes];
4380
+ if (parentChangeTree && (parentChangeTree.isFiltered || parentChangeTree.isPartiallyFiltered)) {
4381
+ this.addParent(parentChangeTree, changeTree.parentIndex, tag);
4377
4382
  }
4378
- const parentChangeTree = parentRef[$changes];
4379
- const parentIndex = changeTree.parentIndex;
4380
- if (!this.invisible.has(parentChangeTree)) {
4381
- // parent is already available, no need to add it!
4383
+ // parent is already available, no need to add it!
4384
+ if (!this.invisible.has(changeTree)) {
4382
4385
  return;
4383
4386
  }
4384
- this.addParent(parentChangeTree, tag);
4385
4387
  // add parent's tag properties
4386
- if (parentChangeTree.getChange(parentIndex) !== exports.OPERATION.DELETE) {
4387
- let parentChanges = this.changes.get(parentChangeTree);
4388
- if (parentChanges === undefined) {
4389
- parentChanges = new Map();
4390
- this.changes.set(parentChangeTree, parentChanges);
4388
+ if (changeTree.getChange(parentIndex) !== exports.OPERATION.DELETE) {
4389
+ let changes = this.changes.get(changeTree);
4390
+ if (changes === undefined) {
4391
+ changes = new Map();
4392
+ this.changes.set(changeTree, changes);
4391
4393
  }
4392
- // console.log("add parent change", {
4393
- // parentIndex,
4394
- // parentChanges,
4395
- // parentChange: (
4396
- // parentChangeTree.getChange(parentIndex) &&
4397
- // OPERATION[parentChangeTree.getChange(parentIndex)]
4398
- // ),
4399
- // })
4400
4394
  if (!this.tags) {
4401
4395
  this.tags = new WeakMap();
4402
4396
  }
4403
4397
  let tags;
4404
- if (!this.tags.has(parentChangeTree)) {
4398
+ if (!this.tags.has(changeTree)) {
4405
4399
  tags = new Set();
4406
- this.tags.set(parentChangeTree, tags);
4400
+ this.tags.set(changeTree, tags);
4407
4401
  }
4408
4402
  else {
4409
- tags = this.tags.get(parentChangeTree);
4403
+ tags = this.tags.get(changeTree);
4410
4404
  }
4411
4405
  tags.add(tag);
4412
- parentChanges.set(parentIndex, exports.OPERATION.ADD);
4406
+ changes.set(parentIndex, exports.OPERATION.ADD);
4413
4407
  }
4414
4408
  }
4415
4409
  remove(obj, tag = DEFAULT_VIEW_TAG) {
package/lib/Metadata.js CHANGED
@@ -81,7 +81,7 @@ exports.Metadata = {
81
81
  // TODO: remove/refactor this...
82
82
  //
83
83
  const metadata = {};
84
- klass.constructor[Symbol.metadata] = metadata;
84
+ klass[Symbol.metadata] = metadata;
85
85
  Object.defineProperty(metadata, -1, {
86
86
  value: 0,
87
87
  enumerable: false,
@@ -1 +1 @@
1
- {"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../src/Metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPropertyDescriptor, type DefinitionType } from \"./annotations\";\nimport { getType } from \"./types/registry\";\n\nexport type MetadataField = {\n type: DefinitionType,\n index: number,\n tag?: number,\n unreliable?: boolean,\n deprecated?: boolean,\n descriptor?: PropertyDescriptor,\n};\n\nexport type Metadata =\n { [-1]: number; } & // number of fields\n { [-2]: number[]; } & // all field indexes with \"view\" tag\n { [-3]: {[tag: number]: number[]}; } & // field indexes by \"view\" tag\n { [field: number]: string; } & // index => field name\n { [field: string]: MetadataField; } // field name => field metadata\n\nexport const Metadata = {\n\n addField(metadata: any, index: number, field: string, type: DefinitionType, descriptor?: PropertyDescriptor) {\n if (index > 64) {\n throw new Error(`Can't define field '${field}'.\\nSchema instances may only have up to 64 fields.`);\n }\n\n metadata[field] = Object.assign(\n metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)\n {\n type: (Array.isArray(type))\n ? { array: type[0] }\n : type,\n index,\n descriptor,\n }\n );\n\n // map -1 as last field index\n Object.defineProperty(metadata, -1, {\n value: index,\n enumerable: false,\n configurable: true\n });\n\n // map index => field name (non enumerable)\n Object.defineProperty(metadata, index, {\n value: field,\n enumerable: false,\n configurable: true,\n });\n },\n\n setTag(metadata: Metadata, fieldName: string, tag: number) {\n // add 'tag' to the field\n const field = metadata[fieldName];\n field.tag = tag;\n\n if (!metadata[-2]) {\n // -2: all field indexes with \"view\" tag\n Object.defineProperty(metadata, -2, {\n value: [],\n enumerable: false,\n configurable: true\n });\n\n // -3: field indexes by \"view\" tag\n Object.defineProperty(metadata, -3, {\n value: {},\n enumerable: false,\n configurable: true\n });\n }\n\n metadata[-2].push(field.index);\n\n if (!metadata[-3][tag]) {\n metadata[-3][tag] = [];\n }\n\n metadata[-3][tag].push(field.index);\n },\n\n setFields(target: any, fields: { [field: string]: DefinitionType }) {\n const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});\n\n // target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {\n // changeTree.change(index, operation, encodeSchemaOperation);\n // };\n\n // target[$encoder] = encodeSchemaOperation;\n // target[$decoder] = decodeSchemaOperation;\n\n // if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }\n\n let index = 0;\n for (const field in fields) {\n const type = fields[field];\n\n // FIXME: this code is duplicated from @type() annotation\n const complexTypeKlass = (Array.isArray(type))\n ? getType(\"array\")\n : (typeof(Object.keys(type)[0]) === \"string\") && getType(Object.keys(type)[0]);\n\n Metadata.addField(\n metadata,\n index,\n field,\n type,\n getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass, metadata, field)\n );\n\n index++;\n }\n },\n\n isDeprecated(metadata: any, field: string) {\n return metadata[field].deprecated === true;\n },\n\n init(klass: any) {\n //\n // Used only to initialize an empty Schema (Encoder#constructor)\n // TODO: remove/refactor this...\n //\n const metadata = {};\n klass.constructor[Symbol.metadata] = metadata;\n Object.defineProperty(metadata, -1, {\n value: 0,\n enumerable: false,\n configurable: true,\n });\n },\n\n initialize(constructor: any, parentMetadata?: any) {\n let metadata: Metadata = constructor[Symbol.metadata] ?? Object.create(null);\n\n // make sure inherited classes have their own metadata object.\n if (constructor[Symbol.metadata] === parentMetadata) {\n metadata = Object.create(null);\n\n if (parentMetadata) {\n // assign parent metadata to current\n Object.assign(metadata, parentMetadata);\n\n for (let i = 0; i <= parentMetadata[-1]; i++) {\n Object.defineProperty(metadata, i, {\n value: parentMetadata[i],\n enumerable: false,\n configurable: true,\n });\n }\n\n Object.defineProperty(metadata, -1, {\n value: parentMetadata[-1],\n enumerable: false,\n configurable: true,\n writable: true,\n });\n }\n }\n\n constructor[Symbol.metadata] = metadata;\n\n return metadata;\n },\n\n isValidInstance(klass: any) {\n return (\n klass.constructor[Symbol.metadata] &&\n Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1) as boolean\n );\n },\n\n getFields(klass: any) {\n const metadata = klass[Symbol.metadata];\n const fields = {};\n for (let i = 0; i <= metadata[-1]; i++) {\n fields[metadata[i]] = metadata[metadata[i]].type;\n }\n return fields;\n }\n}"]}
1
+ {"version":3,"file":"Metadata.js","sourceRoot":"","sources":["../src/Metadata.ts"],"names":[],"mappings":"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","sourcesContent":["import { getPropertyDescriptor, type DefinitionType } from \"./annotations\";\nimport { getType } from \"./types/registry\";\n\nexport type MetadataField = {\n type: DefinitionType,\n index: number,\n tag?: number,\n unreliable?: boolean,\n deprecated?: boolean,\n descriptor?: PropertyDescriptor,\n};\n\nexport type Metadata =\n { [-1]: number; } & // number of fields\n { [-2]: number[]; } & // all field indexes with \"view\" tag\n { [-3]: {[tag: number]: number[]}; } & // field indexes by \"view\" tag\n { [field: number]: string; } & // index => field name\n { [field: string]: MetadataField; } // field name => field metadata\n\nexport const Metadata = {\n\n addField(metadata: any, index: number, field: string, type: DefinitionType, descriptor?: PropertyDescriptor) {\n if (index > 64) {\n throw new Error(`Can't define field '${field}'.\\nSchema instances may only have up to 64 fields.`);\n }\n\n metadata[field] = Object.assign(\n metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)\n {\n type: (Array.isArray(type))\n ? { array: type[0] }\n : type,\n index,\n descriptor,\n }\n );\n\n // map -1 as last field index\n Object.defineProperty(metadata, -1, {\n value: index,\n enumerable: false,\n configurable: true\n });\n\n // map index => field name (non enumerable)\n Object.defineProperty(metadata, index, {\n value: field,\n enumerable: false,\n configurable: true,\n });\n },\n\n setTag(metadata: Metadata, fieldName: string, tag: number) {\n // add 'tag' to the field\n const field = metadata[fieldName];\n field.tag = tag;\n\n if (!metadata[-2]) {\n // -2: all field indexes with \"view\" tag\n Object.defineProperty(metadata, -2, {\n value: [],\n enumerable: false,\n configurable: true\n });\n\n // -3: field indexes by \"view\" tag\n Object.defineProperty(metadata, -3, {\n value: {},\n enumerable: false,\n configurable: true\n });\n }\n\n metadata[-2].push(field.index);\n\n if (!metadata[-3][tag]) {\n metadata[-3][tag] = [];\n }\n\n metadata[-3][tag].push(field.index);\n },\n\n setFields(target: any, fields: { [field: string]: DefinitionType }) {\n const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});\n\n // target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {\n // changeTree.change(index, operation, encodeSchemaOperation);\n // };\n\n // target[$encoder] = encodeSchemaOperation;\n // target[$decoder] = decodeSchemaOperation;\n\n // if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }\n\n let index = 0;\n for (const field in fields) {\n const type = fields[field];\n\n // FIXME: this code is duplicated from @type() annotation\n const complexTypeKlass = (Array.isArray(type))\n ? getType(\"array\")\n : (typeof(Object.keys(type)[0]) === \"string\") && getType(Object.keys(type)[0]);\n\n Metadata.addField(\n metadata,\n index,\n field,\n type,\n getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass, metadata, field)\n );\n\n index++;\n }\n },\n\n isDeprecated(metadata: any, field: string) {\n return metadata[field].deprecated === true;\n },\n\n init(klass: any) {\n //\n // Used only to initialize an empty Schema (Encoder#constructor)\n // TODO: remove/refactor this...\n //\n const metadata = {};\n klass[Symbol.metadata] = metadata;\n Object.defineProperty(metadata, -1, {\n value: 0,\n enumerable: false,\n configurable: true,\n });\n },\n\n initialize(constructor: any, parentMetadata?: any) {\n let metadata: Metadata = constructor[Symbol.metadata] ?? Object.create(null);\n\n // make sure inherited classes have their own metadata object.\n if (constructor[Symbol.metadata] === parentMetadata) {\n metadata = Object.create(null);\n\n if (parentMetadata) {\n // assign parent metadata to current\n Object.assign(metadata, parentMetadata);\n\n for (let i = 0; i <= parentMetadata[-1]; i++) {\n Object.defineProperty(metadata, i, {\n value: parentMetadata[i],\n enumerable: false,\n configurable: true,\n });\n }\n\n Object.defineProperty(metadata, -1, {\n value: parentMetadata[-1],\n enumerable: false,\n configurable: true,\n writable: true,\n });\n }\n }\n\n constructor[Symbol.metadata] = metadata;\n\n return metadata;\n },\n\n isValidInstance(klass: any) {\n return (\n klass.constructor[Symbol.metadata] &&\n Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1) as boolean\n );\n },\n\n getFields(klass: any) {\n const metadata = klass[Symbol.metadata];\n const fields = {};\n for (let i = 0; i <= metadata[-1]; i++) {\n fields[metadata[i]] = metadata[metadata[i]].type;\n }\n return fields;\n }\n}"]}
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
- if (!context) {
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) => {
@@ -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.changes.entries())) {
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"]}