@colyseus/schema 3.0.0-alpha.15 → 3.0.0-alpha.17

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.
@@ -1 +1 @@
1
- {"version":3,"file":"EncodeOperation.js","sourceRoot":"","sources":["../../src/encoder/EncodeOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { $changes } from \"../types/symbols\";\nimport { getType } from \"../types/registry\";\n\nimport * as encode from \"../encoding/encode\";\nimport { EncodeSchemaError, assertInstanceType, assertType } from \"../encoding/assert\";\n\nimport type { ChangeTree, Ref } from \"./ChangeTree\";\nimport type { Encoder } from \"./Encoder\";\nimport type { Schema } from \"../Schema\";\nimport type { PrimitiveType } from \"../annotations\";\n\nimport type { Iterator } from \"../encoding/decode\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\n\nexport type EncodeOperation<T extends Ref = any> = (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree<T>,\n index: number,\n operation: OPERATION,\n it: Iterator,\n isEncodeAll: boolean,\n hasView: boolean,\n) => void;\n\nexport function encodePrimitiveType(\n type: PrimitiveType,\n bytes: Buffer,\n value: any,\n klass: Schema,\n field: string | number,\n it: Iterator,\n) {\n assertType(value, type as string, klass, field);\n\n const encodeFunc = encode[type as string];\n\n if (encodeFunc) {\n encodeFunc(bytes, value, it);\n // encodeFunc(bytes, value);\n\n } else {\n throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);\n }\n};\n\nexport function encodeValue(\n encoder: Encoder,\n bytes: Buffer,\n ref: Ref,\n type: any,\n value: any,\n field: string | number,\n operation: OPERATION,\n it: Iterator,\n) {\n if (type[Symbol.metadata] !== undefined) {\n // TODO: move this to the `@type()` annotation\n assertInstanceType(value, type as typeof Schema, ref as Schema, field);\n\n //\n // Encode refId for this instance.\n // The actual instance is going to be encoded on next `changeTree` iteration.\n //\n encode.number(bytes, value[$changes].refId, it);\n\n // Try to encode inherited TYPE_ID if it's an ADD operation.\n if ((operation & OPERATION.ADD) === OPERATION.ADD) {\n encoder.tryEncodeTypeId(bytes, type as typeof Schema, value.constructor as typeof Schema, it);\n }\n\n } else if (typeof (type) === \"string\") {\n //\n // Primitive values\n //\n encodePrimitiveType(type as PrimitiveType, bytes, value, ref as Schema, field, it);\n\n } else {\n //\n // Custom type (MapSchema, ArraySchema, etc)\n //\n const definition = getType(Object.keys(type)[0]);\n\n //\n // ensure a ArraySchema has been provided\n //\n assertInstanceType(ref[field], definition.constructor, ref as Schema, field);\n\n //\n // Encode refId for this instance.\n // The actual instance is going to be encoded on next `changeTree` iteration.\n //\n encode.number(bytes, value[$changes].refId, it);\n }\n}\n\n/**\n * Used for Schema instances.\n * @private\n */\nexport const encodeSchemaOperation: EncodeOperation = function (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree<Schema>,\n index: number,\n operation: OPERATION,\n it: Iterator,\n) {\n const ref = changeTree.ref;\n const metadata = ref['constructor'][Symbol.metadata];\n\n const field = metadata[index];\n const type = metadata[field].type;\n const value = ref[field];\n\n // \"compress\" field index + operation\n bytes[it.offset++] = (index | operation) & 255;\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n // TODO: inline this function call small performance gain\n encodeValue(encoder, bytes, ref, type, value, field, operation, it);\n}\n\n/**\n * Used for collections (MapSchema, CollectionSchema, SetSchema)\n * @private\n */\nexport const encodeKeyValueOperation: EncodeOperation = function (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree,\n field: number,\n operation: OPERATION,\n it: Iterator,\n) {\n const ref = changeTree.ref;\n\n // encode operation\n bytes[it.offset++] = operation & 255;\n\n // custom operations\n if (operation === OPERATION.CLEAR) {\n return;\n }\n\n // encode index\n encode.number(bytes, field, it);\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n //\n // encode \"alias\" for dynamic fields (maps)\n //\n if ((operation & OPERATION.ADD) == OPERATION.ADD) { // ADD or DELETE_AND_ADD\n if (typeof(ref['set']) === \"function\") {\n //\n // MapSchema dynamic key\n //\n const dynamicIndex = changeTree.ref['$indexes'].get(field);\n encode.string(bytes, dynamicIndex, it);\n }\n }\n\n const type = changeTree.getType(field);\n const value = changeTree.getValue(field);\n\n // try { throw new Error(); } catch (e) {\n // // only print if not coming from Reflection.ts\n // if (!e.stack.includes(\"src/Reflection.ts\")) {\n // console.log(\"encodeKeyValueOperation -> \", {\n // ref: changeTree.ref.constructor.name,\n // field,\n // operation: OPERATION[operation],\n // value: value?.toJSON(),\n // items: ref.toJSON(),\n // });\n // }\n // }\n\n // TODO: inline this function call small performance gain\n encodeValue(encoder, bytes, ref, type, value, field, operation, it);\n}\n\n/**\n * Used for collections (MapSchema, ArraySchema, etc.)\n * @private\n */\nexport const encodeArray: EncodeOperation = function (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree<ArraySchema>,\n field: number,\n operation: OPERATION,\n it: Iterator,\n isEncodeAll: boolean,\n hasView: boolean,\n) {\n const ref = changeTree.ref;\n\n if (\n hasView &&\n operation === OPERATION.DELETE &&\n typeof (changeTree.getType(field)) !== \"string\"\n ) {\n // encode delete by refId (array of schemas)\n bytes[it.offset++] = OPERATION.DELETE_BY_REFID;\n const value = ref['tmpItems'][field];\n const refId = value[$changes].refId;\n encode.number(bytes, refId, it);\n return;\n }\n\n // encode operation\n bytes[it.offset++] = operation & 255;\n\n // custom operations\n if (operation === OPERATION.CLEAR) {\n return;\n }\n\n // encode index\n encode.number(bytes, field, it);\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n const type = changeTree.getType(field);\n const value = changeTree.getValue(field, isEncodeAll);\n\n // console.log(\"encodeArray -> \", {\n // ref: changeTree.ref.constructor.name,\n // field,\n // operation: OPERATION[operation],\n // value: value?.toJSON(),\n // items: ref.toJSON(),\n // });\n\n // TODO: inline this function call small performance gain\n encodeValue(encoder, bytes, ref, type, value, field, operation, it);\n}"]}
1
+ {"version":3,"file":"EncodeOperation.js","sourceRoot":"","sources":["../../src/encoder/EncodeOperation.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../encoding/spec\";\nimport { $changes } from \"../types/symbols\";\nimport { getType } from \"../types/registry\";\n\nimport * as encode from \"../encoding/encode\";\nimport { EncodeSchemaError, assertInstanceType, assertType } from \"../encoding/assert\";\n\nimport type { ChangeTree, Ref } from \"./ChangeTree\";\nimport type { Encoder } from \"./Encoder\";\nimport type { Schema } from \"../Schema\";\nimport type { PrimitiveType } from \"../annotations\";\n\nimport type { Iterator } from \"../encoding/decode\";\nimport type { ArraySchema } from \"../types/custom/ArraySchema\";\n\nexport type EncodeOperation<T extends Ref = any> = (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree<T>,\n index: number,\n operation: OPERATION,\n it: Iterator,\n isEncodeAll: boolean,\n hasView: boolean,\n) => void;\n\nexport function encodePrimitiveType(\n type: PrimitiveType,\n bytes: Buffer,\n value: any,\n klass: Schema,\n field: string | number,\n it: Iterator,\n) {\n assertType(value, type as string, klass, field);\n\n const encodeFunc = encode[type as string];\n\n if (encodeFunc) {\n encodeFunc(bytes, value, it);\n // encodeFunc(bytes, value);\n\n } else {\n throw new EncodeSchemaError(`a '${type}' was expected, but ${value} was provided in ${klass.constructor.name}#${field}`);\n }\n};\n\nexport function encodeValue(\n encoder: Encoder,\n bytes: Buffer,\n ref: Ref,\n type: any,\n value: any,\n field: string | number,\n operation: OPERATION,\n it: Iterator,\n) {\n if (type[Symbol.metadata] !== undefined) {\n // TODO: move this to the `@type()` annotation\n assertInstanceType(value, type as typeof Schema, ref as Schema, field);\n\n //\n // Encode refId for this instance.\n // The actual instance is going to be encoded on next `changeTree` iteration.\n //\n encode.number(bytes, value[$changes].refId, it);\n\n // Try to encode inherited TYPE_ID if it's an ADD operation.\n if ((operation & OPERATION.ADD) === OPERATION.ADD) {\n encoder.tryEncodeTypeId(bytes, type as typeof Schema, value.constructor as typeof Schema, it);\n }\n\n } else if (typeof (type) === \"string\") {\n //\n // Primitive values\n //\n encodePrimitiveType(type as PrimitiveType, bytes, value, ref as Schema, field, it);\n\n } else {\n //\n // Custom type (MapSchema, ArraySchema, etc)\n //\n const definition = getType(Object.keys(type)[0]);\n\n //\n // ensure a ArraySchema has been provided\n //\n assertInstanceType(ref[field], definition.constructor, ref as Schema, field);\n\n //\n // Encode refId for this instance.\n // The actual instance is going to be encoded on next `changeTree` iteration.\n //\n encode.number(bytes, value[$changes].refId, it);\n }\n}\n\n/**\n * Used for Schema instances.\n * @private\n */\nexport const encodeSchemaOperation: EncodeOperation = function (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree<Schema>,\n index: number,\n operation: OPERATION,\n it: Iterator,\n) {\n const ref = changeTree.ref;\n const metadata = ref['constructor'][Symbol.metadata];\n\n const field = metadata[index];\n const type = metadata[field].type;\n const value = ref[field];\n\n // \"compress\" field index + operation\n bytes[it.offset++] = (index | operation) & 255;\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n // TODO: inline this function call small performance gain\n encodeValue(encoder, bytes, ref, type, value, field, operation, it);\n}\n\n/**\n * Used for collections (MapSchema, CollectionSchema, SetSchema)\n * @private\n */\nexport const encodeKeyValueOperation: EncodeOperation = function (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree,\n field: number,\n operation: OPERATION,\n it: Iterator,\n) {\n const ref = changeTree.ref;\n\n // encode operation\n bytes[it.offset++] = operation & 255;\n\n // custom operations\n if (operation === OPERATION.CLEAR) {\n return;\n }\n\n // encode index\n encode.number(bytes, field, it);\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n //\n // encode \"alias\" for dynamic fields (maps)\n //\n if ((operation & OPERATION.ADD) == OPERATION.ADD) { // ADD or DELETE_AND_ADD\n if (typeof(ref['set']) === \"function\") {\n //\n // MapSchema dynamic key\n //\n const dynamicIndex = changeTree.ref['$indexes'].get(field);\n encode.string(bytes, dynamicIndex, it);\n }\n }\n\n const type = changeTree.getType(field);\n const value = changeTree.getValue(field);\n\n // try { throw new Error(); } catch (e) {\n // // only print if not coming from Reflection.ts\n // if (!e.stack.includes(\"src/Reflection.ts\")) {\n // console.log(\"encodeKeyValueOperation -> \", {\n // ref: changeTree.ref.constructor.name,\n // field,\n // operation: OPERATION[operation],\n // value: value?.toJSON(),\n // items: ref.toJSON(),\n // });\n // }\n // }\n\n // TODO: inline this function call small performance gain\n encodeValue(encoder, bytes, ref, type, value, field, operation, it);\n}\n\n/**\n * Used for collections (MapSchema, ArraySchema, etc.)\n * @private\n */\nexport const encodeArray: EncodeOperation = function (\n encoder: Encoder,\n bytes: Buffer,\n changeTree: ChangeTree<ArraySchema>,\n field: number,\n operation: OPERATION,\n it: Iterator,\n isEncodeAll: boolean,\n hasView: boolean,\n) {\n const ref = changeTree.ref;\n const useOperationByRefId = hasView && changeTree.isFiltered && (typeof (changeTree.getType(field)) !== \"string\");\n\n let refOrIndex: number;\n\n if (useOperationByRefId) {\n refOrIndex = ref['tmpItems'][field][$changes].refId;\n\n if (operation === OPERATION.DELETE) {\n operation = OPERATION.DELETE_BY_REFID;\n\n } else if (operation === OPERATION.ADD) {\n operation = OPERATION.ADD_BY_REFID;\n }\n\n } else {\n refOrIndex = field;\n }\n\n // encode operation\n bytes[it.offset++] = operation & 255;\n\n // custom operations\n if (operation === OPERATION.CLEAR) {\n return;\n }\n\n // encode index\n encode.number(bytes, refOrIndex, it);\n\n // Do not encode value for DELETE operations\n if (operation === OPERATION.DELETE) {\n return;\n }\n\n const type = changeTree.getType(field);\n const value = changeTree.getValue(field, isEncodeAll);\n\n // console.log(\"encodeArray -> \", {\n // ref: changeTree.ref.constructor.name,\n // field,\n // operation: OPERATION[operation],\n // value: value?.toJSON(),\n // items: ref.toJSON(),\n // });\n\n // TODO: inline this function call small performance gain\n encodeValue(encoder, bytes, ref, type, value, field, operation, it);\n}"]}
@@ -30,12 +30,18 @@ class StateView {
30
30
  console.warn("StateView#add(), invalid object:", obj);
31
31
  return this;
32
32
  }
33
+ // FIXME: ArraySchema/MapSchema does not have metadata
34
+ const metadata = obj.constructor[Symbol.metadata];
33
35
  let changeTree = obj[symbols_1.$changes];
34
36
  this.items.add(changeTree);
35
37
  // Add children of this ChangeTree to this view
36
- changeTree.forEachChild((change, _) => this.add(change.ref, tag));
37
- // FIXME: ArraySchema/MapSchema does not have metadata
38
- const metadata = obj.constructor[Symbol.metadata];
38
+ changeTree.forEachChild((change, index) => {
39
+ // Do not ADD children that don't have the same tag
40
+ if (metadata && metadata[metadata[index]].tag !== tag) {
41
+ return;
42
+ }
43
+ this.add(change.ref, tag);
44
+ });
39
45
  // add parent ChangeTree's, if they are invisible to this view
40
46
  // TODO: REFACTOR addParent()
41
47
  this.addParent(changeTree, tag);
@@ -62,7 +68,6 @@ class StateView {
62
68
  tags = this.tags.get(changeTree);
63
69
  }
64
70
  tags.add(tag);
65
- // console.log("BY TAG:", tag);
66
71
  // Ref: add tagged properties
67
72
  metadata?.[-3]?.[tag]?.forEach((index) => {
68
73
  if (changeTree.getChange(index) !== spec_1.OPERATION.DELETE) {
@@ -1 +1 @@
1
- {"version":3,"file":"StateView.js","sourceRoot":"","sources":["../../src/encoder/StateView.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeTree, Ref } from \"./ChangeTree\";\nimport { $changes } from \"../types/symbols\";\nimport { DEFAULT_VIEW_TAG } from \"../annotations\";\nimport { OPERATION } from \"../encoding/spec\";\nimport { Metadata } from \"../Metadata\";\nimport type { Schema } from \"../Schema\";\n\nexport function createView(root: Schema) {\n}\n\nexport class StateView {\n /**\n * List of ChangeTree's that are visible to this view\n */\n items: WeakSet<ChangeTree> = new WeakSet<ChangeTree>();\n\n /**\n * List of ChangeTree's that are invisible to this view\n */\n invisible: WeakSet<ChangeTree> = new WeakSet<ChangeTree>();\n\n tags?: WeakMap<ChangeTree, Set<number>>; // TODO: use bit manipulation instead of Set<number> ()\n\n /**\n * Manual \"ADD\" operations for changes per ChangeTree, specific to this view.\n * (This is used to force encoding a property, even if it was not changed)\n */\n changes = new Map<ChangeTree, Map<number, OPERATION>>();\n\n // TODO: allow to set multiple tags at once\n add(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {\n if (!obj[$changes]) {\n console.warn(\"StateView#add(), invalid object:\", obj);\n return this;\n }\n\n let changeTree: ChangeTree = obj[$changes];\n this.items.add(changeTree);\n\n // Add children of this ChangeTree to this view\n changeTree.forEachChild((change, _) =>\n this.add(change.ref, tag));\n\n // FIXME: ArraySchema/MapSchema does not have metadata\n const metadata: Metadata = obj.constructor[Symbol.metadata];\n\n // add parent ChangeTree's, if they are invisible to this view\n // TODO: REFACTOR addParent()\n this.addParent(changeTree, tag);\n\n //\n // TODO: when adding an item of a MapSchema, the changes may not\n // be set (only the parent's changes are set)\n //\n let changes = this.changes.get(changeTree);\n if (changes === undefined) {\n changes = new Map<number, OPERATION>();\n this.changes.set(changeTree, changes)\n }\n\n // set tag\n if (tag !== DEFAULT_VIEW_TAG) {\n if (!this.tags) {\n this.tags = new WeakMap<ChangeTree, Set<number>>();\n }\n let tags: Set<number>;\n if (!this.tags.has(changeTree)) {\n tags = new Set<number>();\n this.tags.set(changeTree, tags);\n } else {\n tags = this.tags.get(changeTree);\n }\n tags.add(tag);\n\n // console.log(\"BY TAG:\", tag);\n\n // Ref: add tagged properties\n metadata?.[-3]?.[tag]?.forEach((index) => {\n if (changeTree.getChange(index) !== OPERATION.DELETE) {\n changes.set(index, OPERATION.ADD)\n }\n });\n\n } else {\n\n // console.log(\"DEFAULT TAG\", changeTree.allChanges);\n\n // // add default tag properties\n // metadata?.[-3]?.[DEFAULT_VIEW_TAG]?.forEach((index) => {\n // if (changeTree.getChange(index) !== OPERATION.DELETE) {\n // changes.set(index, OPERATION.ADD);\n // }\n // });\n\n const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)\n ? changeTree.allFilteredChanges\n : changeTree.allChanges;\n const it = allChangesSet.keys();\n const isInvisible = this.invisible.has(changeTree);\n\n for (const index of it) {\n if (\n (isInvisible || metadata?.[metadata?.[index]].tag === tag) &&\n changeTree.getChange(index) !== OPERATION.DELETE\n ) {\n changes.set(index, OPERATION.ADD);\n }\n }\n }\n\n // TODO: avoid unnecessary iteration here\n while (\n changeTree.parent &&\n (changeTree = changeTree.parent[$changes]) &&\n (changeTree.isFiltered || changeTree.isPartiallyFiltered)\n ) {\n this.items.add(changeTree);\n }\n\n return this;\n }\n\n protected addParent(changeTree: ChangeTree, tag: number) {\n const parentRef = changeTree.parent;\n if (!parentRef) { return; }\n\n const parentChangeTree = parentRef[$changes];\n const parentIndex = changeTree.parentIndex;\n\n if (!this.invisible.has(parentChangeTree)) {\n // parent is already available, no need to add it!\n return;\n }\n\n this.addParent(parentChangeTree, tag);\n\n // add parent's tag properties\n if (parentChangeTree.getChange(parentIndex) !== OPERATION.DELETE) {\n\n let parentChanges = this.changes.get(parentChangeTree);\n if (parentChanges === undefined) {\n parentChanges = new Map<number, OPERATION>();\n this.changes.set(parentChangeTree, parentChanges);\n }\n\n // console.log(\"add parent change\", {\n // parentIndex,\n // parentChanges,\n // parentChange: (\n // parentChangeTree.getChange(parentIndex) &&\n // OPERATION[parentChangeTree.getChange(parentIndex)]\n // ),\n // })\n\n if (!this.tags) { this.tags = new WeakMap<ChangeTree, Set<number>>(); }\n let tags: Set<number>;\n if (!this.tags.has(parentChangeTree)) {\n tags = new Set<number>();\n this.tags.set(parentChangeTree, tags);\n } else {\n tags = this.tags.get(parentChangeTree);\n }\n tags.add(tag);\n\n parentChanges.set(parentIndex, OPERATION.ADD);\n }\n\n }\n\n remove(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {\n const changeTree = obj[$changes];\n if (!changeTree) {\n console.warn(\"StateView#remove(), invalid object:\", obj);\n return this;\n }\n\n this.items.delete(changeTree);\n\n const ref = changeTree.ref;\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n\n let changes = this.changes.get(changeTree);\n if (changes === undefined) {\n changes = new Map<number, OPERATION>();\n this.changes.set(changeTree, changes)\n }\n\n if (tag === DEFAULT_VIEW_TAG) {\n // parent is collection (Map/Array)\n const parent = changeTree.parent;\n if (!Metadata.isValidInstance(parent)) {\n const parentChangeTree = parent[$changes];\n let changes = this.changes.get(parentChangeTree);\n if (changes === undefined) {\n changes = new Map<number, OPERATION>();\n this.changes.set(parentChangeTree, changes)\n }\n // DELETE / DELETE BY REF ID\n changes.set(changeTree.parentIndex, OPERATION.DELETE);\n\n } else {\n // delete all \"tagged\" properties.\n metadata[-2].forEach((index) =>\n changes.set(index, OPERATION.DELETE));\n }\n\n\n } else {\n // delete only tagged properties\n metadata[-3][tag].forEach((index) =>\n changes.set(index, OPERATION.DELETE));\n }\n\n // remove tag\n if (this.tags && this.tags.has(changeTree)) {\n const tags = this.tags.get(changeTree);\n if (tag === undefined) {\n // delete all tags\n this.tags.delete(changeTree);\n } else {\n // delete specific tag\n tags.delete(tag);\n\n // if tag set is empty, delete it entirely\n if (tags.size === 0) {\n this.tags.delete(changeTree);\n }\n }\n }\n\n return this;\n }\n}"]}
1
+ {"version":3,"file":"StateView.js","sourceRoot":"","sources":["../../src/encoder/StateView.ts"],"names":[],"mappings":"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","sourcesContent":["import { ChangeTree, Ref } from \"./ChangeTree\";\nimport { $changes } from \"../types/symbols\";\nimport { DEFAULT_VIEW_TAG } from \"../annotations\";\nimport { OPERATION } from \"../encoding/spec\";\nimport { Metadata } from \"../Metadata\";\nimport type { Schema } from \"../Schema\";\n\nexport function createView(root: Schema) {\n}\n\nexport class StateView {\n /**\n * List of ChangeTree's that are visible to this view\n */\n items: WeakSet<ChangeTree> = new WeakSet<ChangeTree>();\n\n /**\n * List of ChangeTree's that are invisible to this view\n */\n invisible: WeakSet<ChangeTree> = new WeakSet<ChangeTree>();\n\n tags?: WeakMap<ChangeTree, Set<number>>; // TODO: use bit manipulation instead of Set<number> ()\n\n /**\n * Manual \"ADD\" operations for changes per ChangeTree, specific to this view.\n * (This is used to force encoding a property, even if it was not changed)\n */\n changes = new Map<ChangeTree, Map<number, OPERATION>>();\n\n // TODO: allow to set multiple tags at once\n add(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {\n if (!obj[$changes]) {\n console.warn(\"StateView#add(), invalid object:\", obj);\n return this;\n }\n\n // FIXME: ArraySchema/MapSchema does not have metadata\n const metadata: Metadata = obj.constructor[Symbol.metadata];\n\n let changeTree: ChangeTree = obj[$changes];\n this.items.add(changeTree);\n\n // Add children of this ChangeTree to this view\n changeTree.forEachChild((change, index) => {\n // Do not ADD children that don't have the same tag\n if (metadata && metadata[metadata[index]].tag !== tag) {\n return;\n }\n this.add(change.ref, tag);\n });\n\n // add parent ChangeTree's, if they are invisible to this view\n // TODO: REFACTOR addParent()\n this.addParent(changeTree, tag);\n\n //\n // TODO: when adding an item of a MapSchema, the changes may not\n // be set (only the parent's changes are set)\n //\n let changes = this.changes.get(changeTree);\n if (changes === undefined) {\n changes = new Map<number, OPERATION>();\n this.changes.set(changeTree, changes)\n }\n\n // set tag\n if (tag !== DEFAULT_VIEW_TAG) {\n if (!this.tags) {\n this.tags = new WeakMap<ChangeTree, Set<number>>();\n }\n let tags: Set<number>;\n if (!this.tags.has(changeTree)) {\n tags = new Set<number>();\n this.tags.set(changeTree, tags);\n } else {\n tags = this.tags.get(changeTree);\n }\n tags.add(tag);\n\n // Ref: add tagged properties\n metadata?.[-3]?.[tag]?.forEach((index) => {\n if (changeTree.getChange(index) !== OPERATION.DELETE) {\n changes.set(index, OPERATION.ADD)\n }\n });\n\n } else {\n\n // console.log(\"DEFAULT TAG\", changeTree.allChanges);\n\n // // add default tag properties\n // metadata?.[-3]?.[DEFAULT_VIEW_TAG]?.forEach((index) => {\n // if (changeTree.getChange(index) !== OPERATION.DELETE) {\n // changes.set(index, OPERATION.ADD);\n // }\n // });\n\n const allChangesSet = (changeTree.isFiltered || changeTree.isPartiallyFiltered)\n ? changeTree.allFilteredChanges\n : changeTree.allChanges;\n const it = allChangesSet.keys();\n const isInvisible = this.invisible.has(changeTree);\n\n for (const index of it) {\n if (\n (isInvisible || metadata?.[metadata?.[index]].tag === tag) &&\n changeTree.getChange(index) !== OPERATION.DELETE\n ) {\n changes.set(index, OPERATION.ADD);\n }\n }\n }\n\n // TODO: avoid unnecessary iteration here\n while (\n changeTree.parent &&\n (changeTree = changeTree.parent[$changes]) &&\n (changeTree.isFiltered || changeTree.isPartiallyFiltered)\n ) {\n this.items.add(changeTree);\n }\n\n return this;\n }\n\n protected addParent(changeTree: ChangeTree, tag: number) {\n const parentRef = changeTree.parent;\n if (!parentRef) { return; }\n\n const parentChangeTree = parentRef[$changes];\n const parentIndex = changeTree.parentIndex;\n\n if (!this.invisible.has(parentChangeTree)) {\n // parent is already available, no need to add it!\n return;\n }\n\n this.addParent(parentChangeTree, tag);\n\n // add parent's tag properties\n if (parentChangeTree.getChange(parentIndex) !== OPERATION.DELETE) {\n\n let parentChanges = this.changes.get(parentChangeTree);\n if (parentChanges === undefined) {\n parentChanges = new Map<number, OPERATION>();\n this.changes.set(parentChangeTree, parentChanges);\n }\n\n // console.log(\"add parent change\", {\n // parentIndex,\n // parentChanges,\n // parentChange: (\n // parentChangeTree.getChange(parentIndex) &&\n // OPERATION[parentChangeTree.getChange(parentIndex)]\n // ),\n // })\n\n if (!this.tags) { this.tags = new WeakMap<ChangeTree, Set<number>>(); }\n let tags: Set<number>;\n if (!this.tags.has(parentChangeTree)) {\n tags = new Set<number>();\n this.tags.set(parentChangeTree, tags);\n } else {\n tags = this.tags.get(parentChangeTree);\n }\n tags.add(tag);\n\n parentChanges.set(parentIndex, OPERATION.ADD);\n }\n\n }\n\n remove(obj: Ref, tag: number = DEFAULT_VIEW_TAG) {\n const changeTree = obj[$changes];\n if (!changeTree) {\n console.warn(\"StateView#remove(), invalid object:\", obj);\n return this;\n }\n\n this.items.delete(changeTree);\n\n const ref = changeTree.ref;\n const metadata: Metadata = ref.constructor[Symbol.metadata];\n\n let changes = this.changes.get(changeTree);\n if (changes === undefined) {\n changes = new Map<number, OPERATION>();\n this.changes.set(changeTree, changes)\n }\n\n if (tag === DEFAULT_VIEW_TAG) {\n // parent is collection (Map/Array)\n const parent = changeTree.parent;\n if (!Metadata.isValidInstance(parent)) {\n const parentChangeTree = parent[$changes];\n let changes = this.changes.get(parentChangeTree);\n if (changes === undefined) {\n changes = new Map<number, OPERATION>();\n this.changes.set(parentChangeTree, changes)\n }\n // DELETE / DELETE BY REF ID\n changes.set(changeTree.parentIndex, OPERATION.DELETE);\n\n } else {\n // delete all \"tagged\" properties.\n metadata[-2].forEach((index) =>\n changes.set(index, OPERATION.DELETE));\n }\n\n\n } else {\n // delete only tagged properties\n metadata[-3][tag].forEach((index) =>\n changes.set(index, OPERATION.DELETE));\n }\n\n // remove tag\n if (this.tags && this.tags.has(changeTree)) {\n const tags = this.tags.get(changeTree);\n if (tag === undefined) {\n // delete all tags\n this.tags.delete(changeTree);\n } else {\n // delete specific tag\n tags.delete(tag);\n\n // if tag set is empty, delete it entirely\n if (tags.size === 0) {\n this.tags.delete(changeTree);\n }\n }\n }\n\n return this;\n }\n}"]}
@@ -21,5 +21,6 @@ export declare enum OPERATION {
21
21
  UNSHIFT = 12,
22
22
  REVERSE = 15,
23
23
  MOVE = 32,
24
- DELETE_BY_REFID = 33
24
+ DELETE_BY_REFID = 33,// This operation is only used at ENCODING time. During DECODING, DELETE_BY_REFID is converted to DELETE
25
+ ADD_BY_REFID = 129
25
26
  }
@@ -26,5 +26,6 @@ var OPERATION;
26
26
  OPERATION[OPERATION["REVERSE"] = 15] = "REVERSE";
27
27
  OPERATION[OPERATION["MOVE"] = 32] = "MOVE";
28
28
  OPERATION[OPERATION["DELETE_BY_REFID"] = 33] = "DELETE_BY_REFID";
29
+ OPERATION[OPERATION["ADD_BY_REFID"] = 129] = "ADD_BY_REFID";
29
30
  })(OPERATION || (exports.OPERATION = OPERATION = {}));
30
31
  //# sourceMappingURL=spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/encoding/spec.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG,GAAG,CAAC,CAAC,4DAA4D;AACvF,QAAA,OAAO,GAAG,GAAG,CAAC;AAE3B;;GAEG;AACH,IAAY,SAsBX;AAtBD,WAAY,SAAS;IACjB,yCAAS,CAAA;IACT,+CAAW,CAAA;IACX,8CAAW,CAAA;IACX,gEAAoB,CAAA;IACpB,2DAAkB,CAAA;IAClB,+DAAoB,CAAA;IAEpB;;OAEG;IACH,4CAAU,CAAA;IAEV;;OAEG;IACH,0CAAS,CAAA;IACT,gDAAY,CAAA;IACZ,gDAAY,CAAA;IACZ,0CAAS,CAAA;IACT,gEAAoB,CAAA;AAExB,CAAC,EAtBW,SAAS,yBAAT,SAAS,QAsBpB","sourcesContent":["export const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)\nexport const TYPE_ID = 213;\n\n/**\n * Encoding Schema field operations.\n */\nexport enum OPERATION {\n ADD = 128, // (10000000) add new structure/primitive\n REPLACE = 0, // (00000001) replace structure/primitive\n DELETE = 64, // (01000000) delete field\n DELETE_AND_MOVE = 96, // () add new structure/primitive\n MOVE_AND_ADD = 160, // () add new structure/primitive\n DELETE_AND_ADD = 192, // (11000000) DELETE field, followed by an ADD\n\n /**\n * Collection operations\n */\n CLEAR = 10,\n\n /**\n * ArraySchema operations\n */\n PUSH = 11,\n UNSHIFT = 12,\n REVERSE = 15,\n MOVE = 32,\n DELETE_BY_REFID = 33, // This operation is only used at ENCODING time. During DECODING, DELETE_BY_REFID is converted to DELETE\n\n}\n"]}
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/encoding/spec.ts"],"names":[],"mappings":";;;AAAa,QAAA,mBAAmB,GAAG,GAAG,CAAC,CAAC,4DAA4D;AACvF,QAAA,OAAO,GAAG,GAAG,CAAC;AAE3B;;GAEG;AACH,IAAY,SAuBX;AAvBD,WAAY,SAAS;IACjB,yCAAS,CAAA;IACT,+CAAW,CAAA;IACX,8CAAW,CAAA;IACX,gEAAoB,CAAA;IACpB,2DAAkB,CAAA;IAClB,+DAAoB,CAAA;IAEpB;;OAEG;IACH,4CAAU,CAAA;IAEV;;OAEG;IACH,0CAAS,CAAA;IACT,gDAAY,CAAA;IACZ,gDAAY,CAAA;IACZ,0CAAS,CAAA;IACT,gEAAoB,CAAA;IACpB,2DAAkB,CAAA;AAEtB,CAAC,EAvBW,SAAS,yBAAT,SAAS,QAuBpB","sourcesContent":["export const SWITCH_TO_STRUCTURE = 255; // (decoding collides with DELETE_AND_ADD + fieldIndex = 63)\nexport const TYPE_ID = 213;\n\n/**\n * Encoding Schema field operations.\n */\nexport enum OPERATION {\n ADD = 128, // (10000000) add new structure/primitive\n REPLACE = 0, // (00000001) replace structure/primitive\n DELETE = 64, // (01000000) delete field\n DELETE_AND_MOVE = 96, // () add new structure/primitive\n MOVE_AND_ADD = 160, // () add new structure/primitive\n DELETE_AND_ADD = 192, // (11000000) DELETE field, followed by an ADD\n\n /**\n * Collection operations\n */\n CLEAR = 10,\n\n /**\n * ArraySchema operations\n */\n PUSH = 11,\n UNSHIFT = 12,\n REVERSE = 15,\n MOVE = 32,\n DELETE_BY_REFID = 33, // This operation is only used at ENCODING time. During DECODING, DELETE_BY_REFID is converted to DELETE\n ADD_BY_REFID = 129,\n\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/schema",
3
- "version": "3.0.0-alpha.15",
3
+ "version": "3.0.0-alpha.17",
4
4
  "description": "Binary state serializer with delta encoding for games",
5
5
  "bin": {
6
6
  "schema-codegen": "./bin/schema-codegen"
@@ -78,7 +78,7 @@
78
78
  "source-map-support": "^0.5.13",
79
79
  "ts-node": "^10.9.2",
80
80
  "tslib": "^2.1.0",
81
- "tsx": "^4.7.0",
81
+ "tsx": "^4.15.7",
82
82
  "typescript": "^5.3.3"
83
83
  },
84
84
  "nyc": {
@@ -0,0 +1,66 @@
1
+ import { nanoid } from "nanoid";
2
+ import { Schema, type, MapSchema, ArraySchema, Encoder } from ".";
3
+ import * as benchmark from "benchmark";
4
+
5
+ const suite = new benchmark.Suite();
6
+
7
+ class AttributeNew extends Schema {
8
+ @type("string") name: string;
9
+ @type("number") value: number;
10
+ }
11
+
12
+ class ItemNew extends Schema {
13
+ @type("number") price: number;
14
+ @type([ AttributeNew ]) attributes = new ArraySchema<AttributeNew>();
15
+ }
16
+
17
+ class PositionNew extends Schema {
18
+ @type("number") x: number;
19
+ @type("number") y: number;
20
+ }
21
+
22
+ class PlayerNew extends Schema {
23
+ @type(PositionNew) position = new PositionNew();
24
+ @type({ map: ItemNew }) items = new MapSchema<ItemNew>();
25
+ }
26
+
27
+ class StateNew extends Schema {
28
+ @type({ map: PlayerNew }) players = new MapSchema<PlayerNew>();
29
+ @type("string") currentTurn;
30
+ }
31
+
32
+ const state = new StateNew();
33
+
34
+ for (let i = 0; i < 50; i++) {
35
+ const player = new PlayerNew();
36
+ state.players.set(`p-${nanoid()}`, player);
37
+
38
+ player.position.x = (i + 1) * 100;
39
+ player.position.y = (i + 1) * 100;
40
+ for (let j = 0; j < 10; j++) {
41
+ const item = new ItemNew();
42
+ item.price = (i + 1) * 50;
43
+ for (let k = 0; k < 5; k++) {
44
+ const attr = new AttributeNew();
45
+ attr.name = `Attribute ${k}`;
46
+ attr.value = k;
47
+ item.attributes.push(attr);
48
+
49
+ }
50
+ player.items.set(`item-${j}`, item);
51
+ }
52
+ }
53
+
54
+
55
+ Encoder.BUFFER_SIZE = 1024 * 128;
56
+ const encoder = new Encoder(state);
57
+
58
+ // measure time to .encodeAll()
59
+
60
+ const now = Date.now();
61
+ for (let i = 0; i < 1000; i++) {
62
+ encoder.encodeAll();
63
+ }
64
+ console.log(Date.now() - now);
65
+
66
+ console.log(Array.from(encoder.encodeAll()).join(","));
@@ -251,6 +251,7 @@ export const decodeKeyValueOperation: DecodeOperation = function (
251
251
  dynamicIndex = ref['getIndex'](index);
252
252
  }
253
253
 
254
+
254
255
  const { value, previousValue } = decodeValue(
255
256
  decoder,
256
257
  operation,
@@ -303,7 +304,10 @@ export const decodeArray: DecodeOperation = function (
303
304
  allChanges: DataChange[]
304
305
  ) {
305
306
  // "uncompressed" index + operation (array/map items)
306
- const operation = bytes[it.offset++];
307
+ let operation = bytes[it.offset++];
308
+
309
+ let isSchemaChild: boolean;
310
+ let index: number;
307
311
 
308
312
  if (operation === OPERATION.CLEAR) {
309
313
  //
@@ -319,7 +323,7 @@ export const decodeArray: DecodeOperation = function (
319
323
  // TODO: refactor here, try to follow same flow as below
320
324
  const refId = decode.number(bytes, it);
321
325
  const previousValue = decoder.root.refs.get(refId);
322
- const index = ref.findIndex((value) => value === previousValue);
326
+ index = ref.findIndex((value) => value === previousValue);
323
327
  ref[$deleteByIndex](index);
324
328
  allChanges.push({
325
329
  ref,
@@ -330,10 +334,26 @@ export const decodeArray: DecodeOperation = function (
330
334
  value: undefined,
331
335
  previousValue,
332
336
  });
337
+
333
338
  return;
339
+
340
+ } else if (operation === OPERATION.ADD_BY_REFID) {
341
+ isSchemaChild = true;
342
+ // operation = OPERATION.ADD;
343
+
344
+ const refId = decode.number(bytes, it);
345
+ const itemByRefId = decoder.root.refs.get(refId);
346
+
347
+ // use existing index, or push new value
348
+ index = (itemByRefId)
349
+ ? ref.findIndex((value) => value === itemByRefId)
350
+ : ref.length;
351
+
352
+ } else {
353
+ isSchemaChild = false;
354
+ index = decode.number(bytes, it);
334
355
  }
335
356
 
336
- const index = decode.number(bytes, it);
337
357
  const type = ref[$childType];
338
358
 
339
359
  let dynamicIndex: number | string = index;
@@ -155,17 +155,7 @@ export function getStateCallbacks<T extends Schema>(decoder: Decoder<T>): GetCal
155
155
  // Handle collection of items
156
156
  //
157
157
 
158
- if (change.op === OPERATION.ADD && change.previousValue === undefined) {
159
- // triger onAdd
160
-
161
- isTriggeringOnAdd = true;
162
- const addCallbacks = $callbacks[OPERATION.ADD];
163
- for (let i = addCallbacks?.length - 1; i >= 0; i--) {
164
- addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
165
- }
166
- isTriggeringOnAdd = false;
167
-
168
- } else if ((change.op & OPERATION.DELETE) === OPERATION.DELETE) {
158
+ if ((change.op & OPERATION.DELETE) === OPERATION.DELETE) {
169
159
  //
170
160
  // FIXME: `previousValue` should always be available.
171
161
  //
@@ -185,6 +175,16 @@ export function getStateCallbacks<T extends Schema>(decoder: Decoder<T>): GetCal
185
175
  addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
186
176
  }
187
177
  }
178
+
179
+ } else if ((change.op & OPERATION.ADD) === OPERATION.ADD && change.previousValue === undefined) {
180
+ // triger onAdd
181
+
182
+ isTriggeringOnAdd = true;
183
+ const addCallbacks = $callbacks[OPERATION.ADD];
184
+ for (let i = addCallbacks?.length - 1; i >= 0; i--) {
185
+ addCallbacks[i](change.value, change.dynamicIndex ?? change.field);
186
+ }
187
+ isTriggeringOnAdd = false;
188
188
  }
189
189
 
190
190
  // trigger onChange
@@ -204,18 +204,22 @@ export const encodeArray: EncodeOperation = function (
204
204
  hasView: boolean,
205
205
  ) {
206
206
  const ref = changeTree.ref;
207
+ const useOperationByRefId = hasView && changeTree.isFiltered && (typeof (changeTree.getType(field)) !== "string");
207
208
 
208
- if (
209
- hasView &&
210
- operation === OPERATION.DELETE &&
211
- typeof (changeTree.getType(field)) !== "string"
212
- ) {
213
- // encode delete by refId (array of schemas)
214
- bytes[it.offset++] = OPERATION.DELETE_BY_REFID;
215
- const value = ref['tmpItems'][field];
216
- const refId = value[$changes].refId;
217
- encode.number(bytes, refId, it);
218
- return;
209
+ let refOrIndex: number;
210
+
211
+ if (useOperationByRefId) {
212
+ refOrIndex = ref['tmpItems'][field][$changes].refId;
213
+
214
+ if (operation === OPERATION.DELETE) {
215
+ operation = OPERATION.DELETE_BY_REFID;
216
+
217
+ } else if (operation === OPERATION.ADD) {
218
+ operation = OPERATION.ADD_BY_REFID;
219
+ }
220
+
221
+ } else {
222
+ refOrIndex = field;
219
223
  }
220
224
 
221
225
  // encode operation
@@ -227,7 +231,7 @@ export const encodeArray: EncodeOperation = function (
227
231
  }
228
232
 
229
233
  // encode index
230
- encode.number(bytes, field, it);
234
+ encode.number(bytes, refOrIndex, it);
231
235
 
232
236
  // Do not encode value for DELETE operations
233
237
  if (operation === OPERATION.DELETE) {
@@ -34,15 +34,20 @@ export class StateView {
34
34
  return this;
35
35
  }
36
36
 
37
+ // FIXME: ArraySchema/MapSchema does not have metadata
38
+ const metadata: Metadata = obj.constructor[Symbol.metadata];
39
+
37
40
  let changeTree: ChangeTree = obj[$changes];
38
41
  this.items.add(changeTree);
39
42
 
40
43
  // Add children of this ChangeTree to this view
41
- changeTree.forEachChild((change, _) =>
42
- this.add(change.ref, tag));
43
-
44
- // FIXME: ArraySchema/MapSchema does not have metadata
45
- const metadata: Metadata = obj.constructor[Symbol.metadata];
44
+ changeTree.forEachChild((change, index) => {
45
+ // Do not ADD children that don't have the same tag
46
+ if (metadata && metadata[metadata[index]].tag !== tag) {
47
+ return;
48
+ }
49
+ this.add(change.ref, tag);
50
+ });
46
51
 
47
52
  // add parent ChangeTree's, if they are invisible to this view
48
53
  // TODO: REFACTOR addParent()
@@ -72,8 +77,6 @@ export class StateView {
72
77
  }
73
78
  tags.add(tag);
74
79
 
75
- // console.log("BY TAG:", tag);
76
-
77
80
  // Ref: add tagged properties
78
81
  metadata?.[-3]?.[tag]?.forEach((index) => {
79
82
  if (changeTree.getChange(index) !== OPERATION.DELETE) {
@@ -25,5 +25,6 @@ export enum OPERATION {
25
25
  REVERSE = 15,
26
26
  MOVE = 32,
27
27
  DELETE_BY_REFID = 33, // This operation is only used at ENCODING time. During DECODING, DELETE_BY_REFID is converted to DELETE
28
+ ADD_BY_REFID = 129,
28
29
 
29
30
  }