@colyseus/schema 3.0.0-alpha.4 → 3.0.0-alpha.41

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.
Files changed (146) hide show
  1. package/README.md +148 -62
  2. package/bin/schema-debug +94 -0
  3. package/build/cjs/index.js +2201 -1507
  4. package/build/cjs/index.js.map +1 -1
  5. package/build/esm/index.mjs +2198 -1506
  6. package/build/esm/index.mjs.map +1 -1
  7. package/build/umd/index.js +2208 -1514
  8. package/lib/Metadata.d.ts +21 -9
  9. package/lib/Metadata.js +169 -32
  10. package/lib/Metadata.js.map +1 -1
  11. package/lib/Reflection.d.ts +19 -4
  12. package/lib/Reflection.js +66 -32
  13. package/lib/Reflection.js.map +1 -1
  14. package/lib/Schema.d.ts +4 -4
  15. package/lib/Schema.js +44 -50
  16. package/lib/Schema.js.map +1 -1
  17. package/lib/annotations.d.ts +31 -34
  18. package/lib/annotations.js +110 -160
  19. package/lib/annotations.js.map +1 -1
  20. package/lib/bench_encode.d.ts +1 -0
  21. package/lib/bench_encode.js +130 -0
  22. package/lib/bench_encode.js.map +1 -0
  23. package/lib/codegen/api.js +1 -2
  24. package/lib/codegen/api.js.map +1 -1
  25. package/lib/codegen/languages/cpp.js +1 -2
  26. package/lib/codegen/languages/cpp.js.map +1 -1
  27. package/lib/codegen/languages/csharp.js +2 -46
  28. package/lib/codegen/languages/csharp.js.map +1 -1
  29. package/lib/codegen/languages/haxe.js +1 -2
  30. package/lib/codegen/languages/haxe.js.map +1 -1
  31. package/lib/codegen/languages/java.js +1 -2
  32. package/lib/codegen/languages/java.js.map +1 -1
  33. package/lib/codegen/languages/js.js +1 -2
  34. package/lib/codegen/languages/js.js.map +1 -1
  35. package/lib/codegen/languages/lua.js +1 -2
  36. package/lib/codegen/languages/lua.js.map +1 -1
  37. package/lib/codegen/languages/ts.js +1 -2
  38. package/lib/codegen/languages/ts.js.map +1 -1
  39. package/lib/codegen/parser.js +85 -3
  40. package/lib/codegen/parser.js.map +1 -1
  41. package/lib/codegen/types.js +6 -3
  42. package/lib/codegen/types.js.map +1 -1
  43. package/lib/debug.d.ts +1 -0
  44. package/lib/debug.js +51 -0
  45. package/lib/debug.js.map +1 -0
  46. package/lib/decoder/DecodeOperation.d.ts +3 -4
  47. package/lib/decoder/DecodeOperation.js +37 -19
  48. package/lib/decoder/DecodeOperation.js.map +1 -1
  49. package/lib/decoder/Decoder.d.ts +6 -7
  50. package/lib/decoder/Decoder.js +14 -14
  51. package/lib/decoder/Decoder.js.map +1 -1
  52. package/lib/decoder/ReferenceTracker.js +3 -2
  53. package/lib/decoder/ReferenceTracker.js.map +1 -1
  54. package/lib/decoder/strategy/RawChanges.js +1 -2
  55. package/lib/decoder/strategy/RawChanges.js.map +1 -1
  56. package/lib/decoder/strategy/StateCallbacks.d.ts +44 -11
  57. package/lib/decoder/strategy/StateCallbacks.js +75 -65
  58. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  59. package/lib/encoder/ChangeTree.d.ts +27 -21
  60. package/lib/encoder/ChangeTree.js +246 -186
  61. package/lib/encoder/ChangeTree.js.map +1 -1
  62. package/lib/encoder/EncodeOperation.d.ts +3 -6
  63. package/lib/encoder/EncodeOperation.js +51 -65
  64. package/lib/encoder/EncodeOperation.js.map +1 -1
  65. package/lib/encoder/Encoder.d.ts +9 -8
  66. package/lib/encoder/Encoder.js +168 -91
  67. package/lib/encoder/Encoder.js.map +1 -1
  68. package/lib/encoder/Root.d.ts +22 -0
  69. package/lib/encoder/Root.js +81 -0
  70. package/lib/encoder/Root.js.map +1 -0
  71. package/lib/encoder/StateView.d.ts +7 -7
  72. package/lib/encoder/StateView.js +70 -74
  73. package/lib/encoder/StateView.js.map +1 -1
  74. package/lib/encoding/assert.d.ts +7 -6
  75. package/lib/encoding/assert.js +13 -5
  76. package/lib/encoding/assert.js.map +1 -1
  77. package/lib/encoding/decode.d.ts +35 -20
  78. package/lib/encoding/decode.js +43 -87
  79. package/lib/encoding/decode.js.map +1 -1
  80. package/lib/encoding/encode.d.ts +36 -17
  81. package/lib/encoding/encode.js +82 -68
  82. package/lib/encoding/encode.js.map +1 -1
  83. package/lib/encoding/spec.d.ts +4 -5
  84. package/lib/encoding/spec.js +1 -2
  85. package/lib/encoding/spec.js.map +1 -1
  86. package/lib/index.d.ts +10 -9
  87. package/lib/index.js +24 -17
  88. package/lib/index.js.map +1 -1
  89. package/lib/types/HelperTypes.d.ts +34 -2
  90. package/lib/types/HelperTypes.js.map +1 -1
  91. package/lib/types/TypeContext.d.ts +23 -0
  92. package/lib/types/TypeContext.js +111 -0
  93. package/lib/types/TypeContext.js.map +1 -0
  94. package/lib/types/custom/ArraySchema.d.ts +2 -2
  95. package/lib/types/custom/ArraySchema.js +33 -22
  96. package/lib/types/custom/ArraySchema.js.map +1 -1
  97. package/lib/types/custom/CollectionSchema.js +1 -0
  98. package/lib/types/custom/CollectionSchema.js.map +1 -1
  99. package/lib/types/custom/MapSchema.d.ts +3 -1
  100. package/lib/types/custom/MapSchema.js +12 -4
  101. package/lib/types/custom/MapSchema.js.map +1 -1
  102. package/lib/types/custom/SetSchema.js +1 -0
  103. package/lib/types/custom/SetSchema.js.map +1 -1
  104. package/lib/types/registry.d.ts +8 -1
  105. package/lib/types/registry.js +23 -6
  106. package/lib/types/registry.js.map +1 -1
  107. package/lib/types/symbols.d.ts +8 -5
  108. package/lib/types/symbols.js +9 -6
  109. package/lib/types/symbols.js.map +1 -1
  110. package/lib/types/utils.js +1 -2
  111. package/lib/types/utils.js.map +1 -1
  112. package/lib/utils.js +9 -7
  113. package/lib/utils.js.map +1 -1
  114. package/package.json +7 -6
  115. package/src/Metadata.ts +190 -42
  116. package/src/Reflection.ts +77 -39
  117. package/src/Schema.ts +59 -64
  118. package/src/annotations.ts +156 -202
  119. package/src/bench_encode.ts +108 -0
  120. package/src/codegen/languages/csharp.ts +1 -47
  121. package/src/codegen/parser.ts +107 -0
  122. package/src/codegen/types.ts +1 -0
  123. package/src/debug.ts +55 -0
  124. package/src/decoder/DecodeOperation.ts +46 -18
  125. package/src/decoder/Decoder.ts +17 -15
  126. package/src/decoder/ReferenceTracker.ts +3 -2
  127. package/src/decoder/strategy/StateCallbacks.ts +153 -82
  128. package/src/encoder/ChangeTree.ts +286 -202
  129. package/src/encoder/EncodeOperation.ts +78 -78
  130. package/src/encoder/Encoder.ts +202 -97
  131. package/src/encoder/Root.ts +93 -0
  132. package/src/encoder/StateView.ts +76 -88
  133. package/src/encoding/assert.ts +17 -8
  134. package/src/encoding/decode.ts +62 -97
  135. package/src/encoding/encode.ts +99 -65
  136. package/src/encoding/spec.ts +3 -5
  137. package/src/index.ts +12 -20
  138. package/src/types/HelperTypes.ts +54 -2
  139. package/src/types/TypeContext.ts +133 -0
  140. package/src/types/custom/ArraySchema.ts +49 -19
  141. package/src/types/custom/CollectionSchema.ts +1 -0
  142. package/src/types/custom/MapSchema.ts +18 -5
  143. package/src/types/custom/SetSchema.ts +1 -0
  144. package/src/types/registry.ts +22 -3
  145. package/src/types/symbols.ts +10 -7
  146. package/src/utils.ts +7 -3
@@ -1 +1 @@
1
- {"version":3,"file":"SetSchema.js","sourceRoot":"","sources":["../../../src/types/custom/SetSchema.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../../encoding/spec\";\nimport { registerType } from \"../registry\";\nimport { $changes, $childType, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex } from \"../symbols\";\nimport { Collection } from \"../HelperTypes\";\nimport { ChangeTree } from \"../../encoder/ChangeTree\";\nimport { encodeKeyValueOperation } from \"../../encoder/EncodeOperation\";\nimport { decodeKeyValueOperation } from \"../../decoder/DecodeOperation\";\nimport type { StateView } from \"../../encoder/StateView\";\n\nexport class SetSchema<V=any> implements Collection<number, V> {\n\n protected $items: Map<number, V> = new Map<number, V>();\n protected $indexes: Map<number, number> = new Map<number, number>();\n\n protected $refId: number = 0;\n\n static [$encoder] = encodeKeyValueOperation;\n static [$decoder] = decodeKeyValueOperation;\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: SetSchema, index: number, view: StateView) {\n return (\n !view ||\n typeof (ref[$childType]) === \"string\" ||\n view.items.has(ref[$getByIndex](index)[$changes])\n );\n }\n\n static is(type: any) {\n return type['set'] !== undefined;\n }\n\n constructor (initialValues?: Array<V>) {\n this[$changes] = new ChangeTree(this);\n\n if (initialValues) {\n initialValues.forEach((v) => this.add(v));\n }\n\n Object.defineProperty(this, $childType, {\n value: undefined,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n }\n\n add(value: V) {\n // immediatelly return false if value already added.\n if (this.has(value)) { return false; }\n\n // set \"index\" for reference.\n const index = this.$refId++;\n\n if ((value[$changes]) !== undefined) {\n value[$changes].setParent(this, this[$changes].root, index);\n }\n\n const operation = this[$changes].indexes[index]?.op ?? OPERATION.ADD;\n\n this[$changes].indexes[index] = index;\n\n this.$indexes.set(index, index);\n this.$items.set(index, value);\n\n this[$changes].change(index, operation);\n return index;\n }\n\n entries () {\n return this.$items.entries();\n }\n\n delete(item: V) {\n const entries = this.$items.entries();\n\n let index: number;\n let entry: IteratorResult<[number, V]>;\n while (entry = entries.next()) {\n if (entry.done) { break; }\n\n if (item === entry.value[1]) {\n index = entry.value[0];\n break;\n }\n }\n\n if (index === undefined) {\n return false;\n }\n\n this[$changes].delete(index);\n this.$indexes.delete(index);\n\n return this.$items.delete(index);\n }\n\n clear() {\n const changeTree = this[$changes];\n\n // discard previous operations.\n changeTree.discard(true);\n changeTree.indexes = {};\n\n // clear previous indexes\n this.$indexes.clear();\n\n // clear items\n this.$items.clear();\n\n changeTree.operation(OPERATION.CLEAR);\n }\n\n has (value: V): boolean {\n const values = this.$items.values();\n\n let has = false;\n let entry: IteratorResult<V>;\n\n while (entry = values.next()) {\n if (entry.done) { break; }\n if (value === entry.value) {\n has = true;\n break;\n }\n }\n\n return has;\n }\n\n forEach(callbackfn: (value: V, key: number, collection: SetSchema<V>) => void) {\n this.$items.forEach((value, key, _) => callbackfn(value, key, this));\n }\n\n values() {\n return this.$items.values();\n }\n\n get size () {\n return this.$items.size;\n }\n\n /** Iterator */\n [Symbol.iterator](): IterableIterator<V> {\n return this.$items.values();\n }\n\n protected setIndex(index: number, key: number) {\n this.$indexes.set(index, key);\n }\n\n protected getIndex(index: number) {\n return this.$indexes.get(index);\n }\n\n protected [$getByIndex](index: number) {\n return this.$items.get(this.$indexes.get(index));\n }\n\n protected [$deleteByIndex](index: number) {\n const key = this.$indexes.get(index);\n this.$items.delete(key);\n this.$indexes.delete(index);\n }\n\n toArray() {\n return Array.from(this.$items.values());\n }\n\n toJSON() {\n const values: V[] = [];\n\n this.forEach((value, key) => {\n values.push(\n (typeof (value['toJSON']) === \"function\")\n ? value['toJSON']()\n : value\n );\n });\n\n return values;\n }\n\n //\n // Decoding utilities\n //\n clone(isDecoding?: boolean): SetSchema<V> {\n let cloned: SetSchema;\n\n if (isDecoding) {\n // client-side\n cloned = Object.assign(new SetSchema(), this);\n\n } else {\n // server-side\n cloned = new SetSchema();\n this.forEach((value) => {\n if (value[$changes]) {\n cloned.add(value['clone']());\n } else {\n cloned.add(value);\n }\n })\n }\n\n return cloned;\n }\n\n}\n\nregisterType(\"set\", { constructor: SetSchema });"]}
1
+ {"version":3,"file":"SetSchema.js","sourceRoot":"","sources":["../../../src/types/custom/SetSchema.ts"],"names":[],"mappings":"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","sourcesContent":["import { OPERATION } from \"../../encoding/spec\";\nimport { registerType } from \"../registry\";\nimport { $changes, $childType, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex } from \"../symbols\";\nimport { Collection } from \"../HelperTypes\";\nimport { ChangeTree } from \"../../encoder/ChangeTree\";\nimport { encodeKeyValueOperation } from \"../../encoder/EncodeOperation\";\nimport { decodeKeyValueOperation } from \"../../decoder/DecodeOperation\";\nimport type { StateView } from \"../../encoder/StateView\";\n\nexport class SetSchema<V=any> implements Collection<number, V> {\n\n protected $items: Map<number, V> = new Map<number, V>();\n protected $indexes: Map<number, number> = new Map<number, number>();\n\n protected $refId: number = 0;\n\n static [$encoder] = encodeKeyValueOperation;\n static [$decoder] = decodeKeyValueOperation;\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: SetSchema, index: number, view: StateView) {\n return (\n !view ||\n typeof (ref[$childType]) === \"string\" ||\n view.items.has(ref[$getByIndex](index)[$changes])\n );\n }\n\n static is(type: any) {\n return type['set'] !== undefined;\n }\n\n constructor (initialValues?: Array<V>) {\n this[$changes] = new ChangeTree(this);\n this[$changes].indexes = {};\n\n if (initialValues) {\n initialValues.forEach((v) => this.add(v));\n }\n\n Object.defineProperty(this, $childType, {\n value: undefined,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n }\n\n add(value: V) {\n // immediatelly return false if value already added.\n if (this.has(value)) { return false; }\n\n // set \"index\" for reference.\n const index = this.$refId++;\n\n if ((value[$changes]) !== undefined) {\n value[$changes].setParent(this, this[$changes].root, index);\n }\n\n const operation = this[$changes].indexes[index]?.op ?? OPERATION.ADD;\n\n this[$changes].indexes[index] = index;\n\n this.$indexes.set(index, index);\n this.$items.set(index, value);\n\n this[$changes].change(index, operation);\n return index;\n }\n\n entries () {\n return this.$items.entries();\n }\n\n delete(item: V) {\n const entries = this.$items.entries();\n\n let index: number;\n let entry: IteratorResult<[number, V]>;\n while (entry = entries.next()) {\n if (entry.done) { break; }\n\n if (item === entry.value[1]) {\n index = entry.value[0];\n break;\n }\n }\n\n if (index === undefined) {\n return false;\n }\n\n this[$changes].delete(index);\n this.$indexes.delete(index);\n\n return this.$items.delete(index);\n }\n\n clear() {\n const changeTree = this[$changes];\n\n // discard previous operations.\n changeTree.discard(true);\n changeTree.indexes = {};\n\n // clear previous indexes\n this.$indexes.clear();\n\n // clear items\n this.$items.clear();\n\n changeTree.operation(OPERATION.CLEAR);\n }\n\n has (value: V): boolean {\n const values = this.$items.values();\n\n let has = false;\n let entry: IteratorResult<V>;\n\n while (entry = values.next()) {\n if (entry.done) { break; }\n if (value === entry.value) {\n has = true;\n break;\n }\n }\n\n return has;\n }\n\n forEach(callbackfn: (value: V, key: number, collection: SetSchema<V>) => void) {\n this.$items.forEach((value, key, _) => callbackfn(value, key, this));\n }\n\n values() {\n return this.$items.values();\n }\n\n get size () {\n return this.$items.size;\n }\n\n /** Iterator */\n [Symbol.iterator](): IterableIterator<V> {\n return this.$items.values();\n }\n\n protected setIndex(index: number, key: number) {\n this.$indexes.set(index, key);\n }\n\n protected getIndex(index: number) {\n return this.$indexes.get(index);\n }\n\n protected [$getByIndex](index: number) {\n return this.$items.get(this.$indexes.get(index));\n }\n\n protected [$deleteByIndex](index: number) {\n const key = this.$indexes.get(index);\n this.$items.delete(key);\n this.$indexes.delete(index);\n }\n\n toArray() {\n return Array.from(this.$items.values());\n }\n\n toJSON() {\n const values: V[] = [];\n\n this.forEach((value, key) => {\n values.push(\n (typeof (value['toJSON']) === \"function\")\n ? value['toJSON']()\n : value\n );\n });\n\n return values;\n }\n\n //\n // Decoding utilities\n //\n clone(isDecoding?: boolean): SetSchema<V> {\n let cloned: SetSchema;\n\n if (isDecoding) {\n // client-side\n cloned = Object.assign(new SetSchema(), this);\n\n } else {\n // server-side\n cloned = new SetSchema();\n this.forEach((value) => {\n if (value[$changes]) {\n cloned.add(value['clone']());\n } else {\n cloned.add(value);\n }\n })\n }\n\n return cloned;\n }\n\n}\n\nregisterType(\"set\", { constructor: SetSchema });"]}
@@ -1,6 +1,13 @@
1
+ import { BufferLike } from "../encoding/encode";
2
+ import { Iterator } from "../encoding/decode";
1
3
  export interface TypeDefinition {
2
- constructor: any;
4
+ constructor?: any;
5
+ encode?: (bytes: BufferLike, value: any, it: Iterator) => any;
6
+ decode?: (bytes: BufferLike, it: Iterator) => any;
3
7
  }
4
8
  export declare function registerType(identifier: string, definition: TypeDefinition): void;
5
9
  export declare function getIdentifier(klass: any): string;
6
10
  export declare function getType(identifier: string): TypeDefinition;
11
+ export declare function defineCustomTypes<T extends {
12
+ [key: string]: TypeDefinition;
13
+ }>(types: T): (t: keyof T) => PropertyDecorator;
@@ -1,19 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getType = exports.getIdentifier = exports.registerType = void 0;
3
+ exports.registerType = registerType;
4
+ exports.getIdentifier = getIdentifier;
5
+ exports.getType = getType;
6
+ exports.defineCustomTypes = defineCustomTypes;
7
+ const annotations_1 = require("../annotations");
8
+ const encode_1 = require("../encoding/encode");
9
+ const decode_1 = require("../encoding/decode");
4
10
  const registeredTypes = {};
5
11
  const identifiers = new Map();
6
12
  function registerType(identifier, definition) {
7
- identifiers.set(definition.constructor, identifier);
8
- registeredTypes[identifier] = definition;
13
+ if (definition.constructor) {
14
+ identifiers.set(definition.constructor, identifier);
15
+ registeredTypes[identifier] = definition;
16
+ }
17
+ if (definition.encode) {
18
+ encode_1.encode[identifier] = definition.encode;
19
+ }
20
+ if (definition.decode) {
21
+ decode_1.decode[identifier] = definition.decode;
22
+ }
9
23
  }
10
- exports.registerType = registerType;
11
24
  function getIdentifier(klass) {
12
25
  return identifiers.get(klass);
13
26
  }
14
- exports.getIdentifier = getIdentifier;
15
27
  function getType(identifier) {
16
28
  return registeredTypes[identifier];
17
29
  }
18
- exports.getType = getType;
30
+ function defineCustomTypes(types) {
31
+ for (const identifier in types) {
32
+ registerType(identifier, types[identifier]);
33
+ }
34
+ return (t) => (0, annotations_1.type)(t);
35
+ }
19
36
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/types/registry.ts"],"names":[],"mappings":";;;AAIA,MAAM,eAAe,GAA4C,EAAE,CAAC;AACpE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAe,CAAC;AAE3C,SAAgB,YAAY,CAAC,UAAkB,EAAE,UAA0B;IACvE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACpD,eAAe,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;AAC7C,CAAC;AAHD,oCAGC;AAED,SAAgB,aAAa,CAAC,KAAU;IACpC,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAFD,sCAEC;AAED,SAAgB,OAAO,CAAC,UAAkB;IACtC,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AAFD,0BAEC","sourcesContent":["export interface TypeDefinition {\n constructor: any,\n}\n\nconst registeredTypes: {[identifier: string] : TypeDefinition} = {};\nconst identifiers = new Map<any, string>();\n\nexport function registerType(identifier: string, definition: TypeDefinition) {\n identifiers.set(definition.constructor, identifier);\n registeredTypes[identifier] = definition;\n}\n\nexport function getIdentifier(klass: any): string {\n return identifiers.get(klass);\n}\n\nexport function getType(identifier: string): TypeDefinition {\n return registeredTypes[identifier];\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/types/registry.ts"],"names":[],"mappings":";;AAaA,oCAQC;AAED,sCAEC;AAED,0BAEC;AAED,8CAMC;AArCD,gDAAsD;AACtD,+CAAwD;AACxD,+CAAsD;AAQtD,MAAM,eAAe,GAA4C,EAAE,CAAC;AACpE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAe,CAAC;AAE3C,SAAgB,YAAY,CAAC,UAAkB,EAAE,UAA0B;IACvE,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;QACzB,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACpD,eAAe,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;IAC7C,CAAC;IAED,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAAC,eAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAAC,CAAC;IAClE,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QAAC,eAAM,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IAAC,CAAC;AACtE,CAAC;AAED,SAAgB,aAAa,CAAC,KAAU;IACpC,OAAO,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,OAAO,CAAC,UAAkB;IACtC,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,iBAAiB,CAA4C,KAAQ;IACjF,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;QAC7B,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,CAAC,CAAU,EAAE,EAAE,CAAC,IAAA,kBAAI,EAAC,CAAmB,CAAC,CAAC;AACrD,CAAC","sourcesContent":["import { DefinitionType, type } from \"../annotations\";\nimport { BufferLike, encode } from \"../encoding/encode\";\nimport { decode, Iterator } from \"../encoding/decode\";\n\nexport interface TypeDefinition {\n constructor?: any,\n encode?: (bytes: BufferLike, value: any, it: Iterator) => any;\n decode?: (bytes: BufferLike, it: Iterator) => any;\n}\n\nconst registeredTypes: {[identifier: string] : TypeDefinition} = {};\nconst identifiers = new Map<any, string>();\n\nexport function registerType(identifier: string, definition: TypeDefinition) {\n if (definition.constructor) {\n identifiers.set(definition.constructor, identifier);\n registeredTypes[identifier] = definition;\n }\n\n if (definition.encode) { encode[identifier] = definition.encode; }\n if (definition.decode) { decode[identifier] = definition.decode; }\n}\n\nexport function getIdentifier(klass: any): string {\n return identifiers.get(klass);\n}\n\nexport function getType(identifier: string): TypeDefinition {\n return registeredTypes[identifier];\n}\n\nexport function defineCustomTypes<T extends {[key: string]: TypeDefinition}>(types: T) {\n for (const identifier in types) {\n registerType(identifier, types[identifier]);\n }\n\n return (t: keyof T) => type(t as DefinitionType);\n}"]}
@@ -13,11 +13,6 @@ export declare const $changes: unique symbol;
13
13
  * (MapSchema, ArraySchema, etc.)
14
14
  */
15
15
  export declare const $childType: unique symbol;
16
- /**
17
- * Special ChangeTree property to identify new instances
18
- * (Once they're encoded, they're not new anymore)
19
- */
20
- export declare const $isNew: unique symbol;
21
16
  /**
22
17
  * Optional "discard" method for custom types (ArraySchema)
23
18
  * (Discards changes for next serialization)
@@ -27,3 +22,11 @@ export declare const $onEncodeEnd: unique symbol;
27
22
  * When decoding, this method is called after the instance is fully decoded
28
23
  */
29
24
  export declare const $onDecodeEnd: unique symbol;
25
+ /**
26
+ * Metadata
27
+ */
28
+ export declare const $descriptors: unique symbol;
29
+ export declare const $numFields = "$__numFields";
30
+ export declare const $refTypeFieldIndexes = "$__refTypeFieldIndexes";
31
+ export declare const $viewFieldIndexes = "$__viewFieldIndexes";
32
+ export declare const $fieldIndexesByViewTag = "$__fieldIndexesByViewTag";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.$onDecodeEnd = exports.$onEncodeEnd = exports.$isNew = exports.$childType = exports.$changes = exports.$deleteByIndex = exports.$getByIndex = exports.$filter = exports.$decoder = exports.$encoder = exports.$track = void 0;
3
+ exports.$fieldIndexesByViewTag = exports.$viewFieldIndexes = exports.$refTypeFieldIndexes = exports.$numFields = exports.$descriptors = exports.$onDecodeEnd = exports.$onEncodeEnd = exports.$childType = exports.$changes = exports.$deleteByIndex = exports.$getByIndex = exports.$filter = exports.$decoder = exports.$encoder = exports.$track = void 0;
4
4
  exports.$track = Symbol("$track");
5
5
  exports.$encoder = Symbol("$encoder");
6
6
  exports.$decoder = Symbol("$decoder");
@@ -16,11 +16,6 @@ exports.$changes = Symbol('$changes');
16
16
  * (MapSchema, ArraySchema, etc.)
17
17
  */
18
18
  exports.$childType = Symbol('$childType');
19
- /**
20
- * Special ChangeTree property to identify new instances
21
- * (Once they're encoded, they're not new anymore)
22
- */
23
- exports.$isNew = Symbol("$isNew");
24
19
  /**
25
20
  * Optional "discard" method for custom types (ArraySchema)
26
21
  * (Discards changes for next serialization)
@@ -30,4 +25,12 @@ exports.$onEncodeEnd = Symbol('$onEncodeEnd');
30
25
  * When decoding, this method is called after the instance is fully decoded
31
26
  */
32
27
  exports.$onDecodeEnd = Symbol("$onDecodeEnd");
28
+ /**
29
+ * Metadata
30
+ */
31
+ exports.$descriptors = Symbol("$descriptors");
32
+ exports.$numFields = "$__numFields";
33
+ exports.$refTypeFieldIndexes = "$__refTypeFieldIndexes";
34
+ exports.$viewFieldIndexes = "$__viewFieldIndexes";
35
+ exports.$fieldIndexesByViewTag = "$__fieldIndexesByViewTag";
33
36
  //# sourceMappingURL=symbols.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/types/symbols.ts"],"names":[],"mappings":";;;AAAa,QAAA,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,QAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAC9B,QAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAE9B,QAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAE5B,QAAA,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AACpC,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;GAEG;AACU,QAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAE3C;;;GAGG;AACU,QAAA,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAE/C;;;GAGG;AACU,QAAA,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEvC;;;GAGG;AACU,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnD;;GAEG;AACU,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC","sourcesContent":["export const $track = Symbol(\"$track\");\nexport const $encoder = Symbol(\"$encoder\");\nexport const $decoder = Symbol(\"$decoder\");\n\nexport const $filter = Symbol(\"$filter\");\n\nexport const $getByIndex = Symbol(\"$getByIndex\");\nexport const $deleteByIndex = Symbol(\"$deleteByIndex\");\n\n/**\n * Used to hold ChangeTree instances whitin the structures\n */\nexport const $changes = Symbol('$changes');\n\n/**\n * Used to keep track of the type of the child elements of a collection\n * (MapSchema, ArraySchema, etc.)\n */\nexport const $childType = Symbol('$childType');\n\n/**\n * Special ChangeTree property to identify new instances\n * (Once they're encoded, they're not new anymore)\n */\nexport const $isNew = Symbol(\"$isNew\");\n\n/**\n * Optional \"discard\" method for custom types (ArraySchema)\n * (Discards changes for next serialization)\n */\nexport const $onEncodeEnd = Symbol('$onEncodeEnd');\n\n/**\n * When decoding, this method is called after the instance is fully decoded\n */\nexport const $onDecodeEnd = Symbol(\"$onDecodeEnd\");"]}
1
+ {"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/types/symbols.ts"],"names":[],"mappings":";;;AAAa,QAAA,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC1B,QAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAC9B,QAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAE9B,QAAA,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;AAE5B,QAAA,WAAW,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;AACpC,QAAA,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAEvD;;GAEG;AACU,QAAA,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAE3C;;;GAGG;AACU,QAAA,UAAU,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAE/C;;;GAGG;AACU,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnD;;GAEG;AACU,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnD;;GAEG;AACU,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AACtC,QAAA,UAAU,GAAG,cAAc,CAAC;AAC5B,QAAA,oBAAoB,GAAG,wBAAwB,CAAC;AAChD,QAAA,iBAAiB,GAAG,qBAAqB,CAAC;AAC1C,QAAA,sBAAsB,GAAG,0BAA0B,CAAC","sourcesContent":["export const $track = Symbol(\"$track\");\nexport const $encoder = Symbol(\"$encoder\");\nexport const $decoder = Symbol(\"$decoder\");\n\nexport const $filter = Symbol(\"$filter\");\n\nexport const $getByIndex = Symbol(\"$getByIndex\");\nexport const $deleteByIndex = Symbol(\"$deleteByIndex\");\n\n/**\n * Used to hold ChangeTree instances whitin the structures\n */\nexport const $changes = Symbol('$changes');\n\n/**\n * Used to keep track of the type of the child elements of a collection\n * (MapSchema, ArraySchema, etc.)\n */\nexport const $childType = Symbol('$childType');\n\n/**\n * Optional \"discard\" method for custom types (ArraySchema)\n * (Discards changes for next serialization)\n */\nexport const $onEncodeEnd = Symbol('$onEncodeEnd');\n\n/**\n * When decoding, this method is called after the instance is fully decoded\n */\nexport const $onDecodeEnd = Symbol(\"$onDecodeEnd\");\n\n/**\n * Metadata\n */\nexport const $descriptors = Symbol(\"$descriptors\");\nexport const $numFields = \"$__numFields\";\nexport const $refTypeFieldIndexes = \"$__refTypeFieldIndexes\";\nexport const $viewFieldIndexes = \"$__viewFieldIndexes\";\nexport const $fieldIndexesByViewTag = \"$__fieldIndexesByViewTag\";\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.spliceOne = void 0;
3
+ exports.spliceOne = spliceOne;
4
4
  function spliceOne(arr, index) {
5
5
  // manually splice an array
6
6
  if (index === -1 || index >= arr.length) {
@@ -13,5 +13,4 @@ function spliceOne(arr, index) {
13
13
  arr.length = len;
14
14
  return true;
15
15
  }
16
- exports.spliceOne = spliceOne;
17
16
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/types/utils.ts"],"names":[],"mappings":";;;AAAA,SAAgB,SAAS,CAAC,GAAU,EAAE,KAAa;IAC/C,2BAA2B;IAC3B,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;IAEjB,OAAO,IAAI,CAAC;AAChB,CAAC;AAfD,8BAeC","sourcesContent":["export function spliceOne(arr: any[], index: number): boolean {\n // manually splice an array\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n\n return true;\n}"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/types/utils.ts"],"names":[],"mappings":";;AAAA,8BAeC;AAfD,SAAgB,SAAS,CAAC,GAAU,EAAE,KAAa;IAC/C,2BAA2B;IAC3B,IAAI,KAAK,KAAK,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAE3B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,CAAC;IAED,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;IAEjB,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["export function spliceOne(arr: any[], index: number): boolean {\n // manually splice an array\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n\n return true;\n}"]}
package/lib/utils.js CHANGED
@@ -1,31 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNextPowerOf2 = exports.dumpChanges = exports.getIndent = void 0;
3
+ exports.getIndent = getIndent;
4
+ exports.dumpChanges = dumpChanges;
5
+ exports.getNextPowerOf2 = getNextPowerOf2;
4
6
  const spec_1 = require("./encoding/spec");
5
7
  const symbols_1 = require("./types/symbols");
6
8
  function getIndent(level) {
7
9
  return (new Array(level).fill(0)).map((_, i) => (i === level - 1) ? `└─ ` : ` `).join("");
8
10
  }
9
- exports.getIndent = getIndent;
10
11
  function dumpChanges(schema) {
11
12
  const $root = schema[symbols_1.$changes].root;
12
13
  const dump = {
13
14
  ops: {},
14
15
  refs: []
15
16
  };
16
- $root.changes.forEach((operations, changeTree) => {
17
+ // for (const refId in $root.changes) {
18
+ $root.changes.forEach(changeTree => {
19
+ const changes = changeTree.indexedOperations;
17
20
  dump.refs.push(`refId#${changeTree.refId}`);
18
- operations.forEach((op, index) => {
21
+ for (const index in changes) {
22
+ const op = changes[index];
19
23
  const opName = spec_1.OPERATION[op];
20
24
  if (!dump.ops[opName]) {
21
25
  dump.ops[opName] = 0;
22
26
  }
23
27
  dump.ops[spec_1.OPERATION[op]]++;
24
- });
28
+ }
25
29
  });
26
30
  return dump;
27
31
  }
28
- exports.dumpChanges = dumpChanges;
29
32
  function getNextPowerOf2(number) {
30
33
  // If number is already a power of 2, return it
31
34
  if ((number & (number - 1)) === 0) {
@@ -40,5 +43,4 @@ function getNextPowerOf2(number) {
40
43
  // Return the next power of 2
41
44
  return 1 << msbPosition;
42
45
  }
43
- exports.getNextPowerOf2 = getNextPowerOf2;
44
46
  //# sourceMappingURL=utils.js.map
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;;AACA,0CAA4C;AAC5C,6CAA2C;AAa3C,SAAgB,SAAS,CAAC,KAAa;IACnC,OAAO,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC3C,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CACpC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACf,CAAC;AAJD,8BAIC;AAED,SAAgB,WAAW,CAAC,MAAc;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAQ,CAAC,CAAC,IAAI,CAAC;IAEpC,MAAM,IAAI,GAAe;QACrB,GAAG,EAAE,EAAE;QACP,IAAI,EAAE,EAAE;KACX,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE;QAC7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,UAAU,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YAC7B,MAAM,MAAM,GAAG,gBAAS,CAAC,EAAE,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,gBAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9B,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AAChB,CAAC;AAlBD,kCAkBC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC1C,+CAA+C;IAC/C,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,gDAAgD;IAChD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC,CAAC;QACb,WAAW,EAAE,CAAC;IAClB,CAAC;IAED,6BAA6B;IAC7B,OAAO,CAAC,IAAI,WAAW,CAAC;AAC5B,CAAC;AAfD,0CAeC","sourcesContent":["import type { Schema } from \"./Schema\";\nimport { OPERATION } from \"./encoding/spec\";\nimport { $changes } from \"./types/symbols\";\n\ntype ChangeItem = [string, number | string, any?];\n\ninterface ChangeDump {\n ops: {\n ADD?: number;\n REMOVE?: number;\n REPLACE?: number;\n },\n refs: string[],\n}\n\nexport function getIndent(level: number) {\n return (new Array(level).fill(0)).map((_, i) =>\n (i === level - 1) ? `└─ ` : ` `\n ).join(\"\");\n}\n\nexport function dumpChanges(schema: Schema) {\n const $root = schema[$changes].root;\n\n const dump: ChangeDump = {\n ops: {},\n refs: []\n };\n\n $root.changes.forEach((operations, changeTree) => {\n dump.refs.push(`refId#${changeTree.refId}`);\n operations.forEach((op, index) => {\n const opName = OPERATION[op];\n if (!dump.ops[opName]) { dump.ops[opName] = 0; }\n dump.ops[OPERATION[op]]++;\n });\n });\n\n return dump;\n}\n\nexport function getNextPowerOf2(number: number) {\n // If number is already a power of 2, return it\n if ((number & (number - 1)) === 0) {\n return number;\n }\n\n // Find the position of the most significant bit\n let msbPosition = 0;\n while (number > 0) {\n number >>= 1;\n msbPosition++;\n }\n\n // Return the next power of 2\n return 1 << msbPosition;\n}"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAeA,8BAIC;AAED,kCAsBC;AAED,0CAeC;AA3DD,0CAA4C;AAC5C,6CAA2C;AAa3C,SAAgB,SAAS,CAAC,KAAa;IACnC,OAAO,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC3C,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CACpC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,WAAW,CAAC,MAAc;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAQ,CAAC,CAAC,IAAI,CAAC;IAEpC,MAAM,IAAI,GAAe;QACrB,GAAG,EAAE,EAAE;QACP,IAAI,EAAE,EAAE;KACX,CAAC;IAEF,uCAAuC;IACvC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;QAC/B,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC;QAE7C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,gBAAS,CAAC,EAAE,CAAC,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAC,CAAC;YAChD,IAAI,CAAC,GAAG,CAAC,gBAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAgB,eAAe,CAAC,MAAc;IAC1C,+CAA+C;IAC/C,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,gDAAgD;IAChD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,KAAK,CAAC,CAAC;QACb,WAAW,EAAE,CAAC;IAClB,CAAC;IAED,6BAA6B;IAC7B,OAAO,CAAC,IAAI,WAAW,CAAC;AAC5B,CAAC","sourcesContent":["import type { Schema } from \"./Schema\";\nimport { OPERATION } from \"./encoding/spec\";\nimport { $changes } from \"./types/symbols\";\n\ntype ChangeItem = [string, number | string, any?];\n\ninterface ChangeDump {\n ops: {\n ADD?: number;\n REMOVE?: number;\n REPLACE?: number;\n },\n refs: string[],\n}\n\nexport function getIndent(level: number) {\n return (new Array(level).fill(0)).map((_, i) =>\n (i === level - 1) ? `└─ ` : ` `\n ).join(\"\");\n}\n\nexport function dumpChanges(schema: Schema) {\n const $root = schema[$changes].root;\n\n const dump: ChangeDump = {\n ops: {},\n refs: []\n };\n\n // for (const refId in $root.changes) {\n $root.changes.forEach(changeTree => {\n const changes = changeTree.indexedOperations;\n\n dump.refs.push(`refId#${changeTree.refId}`);\n for (const index in changes) {\n const op = changes[index];\n const opName = OPERATION[op];\n if (!dump.ops[opName]) { dump.ops[opName] = 0; }\n dump.ops[OPERATION[op]]++;\n }\n });\n\n return dump;\n}\n\nexport function getNextPowerOf2(number: number) {\n // If number is already a power of 2, return it\n if ((number & (number - 1)) === 0) {\n return number;\n }\n\n // Find the position of the most significant bit\n let msbPosition = 0;\n while (number > 0) {\n number >>= 1;\n msbPosition++;\n }\n\n // Return the next power of 2\n return 1 << msbPosition;\n}"]}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@colyseus/schema",
3
- "version": "3.0.0-alpha.4",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Binary state serializer with delta encoding for games",
5
5
  "bin": {
6
- "schema-codegen": "./bin/schema-codegen"
6
+ "schema-codegen": "./bin/schema-codegen",
7
+ "schema-debug": "./bin/schema-debug"
7
8
  },
8
9
  "scripts": {
9
- "build": "tsc && rollup -c rollup.config.js",
10
+ "build": "tsc && rollup -c rollup.config.mjs",
10
11
  "watch": "tsc -w",
11
12
  "test": "mocha --require ts-node/register test/*.test.ts test/**/*.test.ts",
12
13
  "coverage": "nyc mocha --require ts-node/register --require source-map-support/register --recursive test/**Test.ts",
@@ -73,13 +74,13 @@
73
74
  "nanoid": "^3.1.10",
74
75
  "nyc": "^14.1.1",
75
76
  "rimraf": "^3.0.0",
76
- "rollup": "^2.40.0",
77
+ "rollup": "^4.18.0",
77
78
  "sinon": "^7.2.2",
78
79
  "source-map-support": "^0.5.13",
79
80
  "ts-node": "^10.9.2",
80
81
  "tslib": "^2.1.0",
81
- "tsx": "^4.7.0",
82
- "typescript": "^5.3.3"
82
+ "tsx": "^3.13.0",
83
+ "typescript": "^5.4.5"
83
84
  },
84
85
  "nyc": {
85
86
  "extension": [
package/src/Metadata.ts CHANGED
@@ -1,134 +1,282 @@
1
- import { getPropertyDescriptor, type DefinitionType } from "./annotations";
1
+ import { Definition, DefinitionType, getPropertyDescriptor } from "./annotations";
2
+ import { Schema } from "./Schema";
2
3
  import { getType } from "./types/registry";
4
+ import { $decoder, $descriptors, $encoder, $fieldIndexesByViewTag, $numFields, $refTypeFieldIndexes, $track, $viewFieldIndexes } from "./types/symbols";
5
+ import { TypeContext } from "./types/TypeContext";
3
6
 
4
7
  export type MetadataField = {
5
8
  type: DefinitionType,
9
+ name: string,
6
10
  index: number,
7
11
  tag?: number,
8
12
  unreliable?: boolean,
9
13
  deprecated?: boolean,
10
- descriptor?: PropertyDescriptor,
11
14
  };
12
15
 
13
16
  export type Metadata =
14
- { [-1]: number; } & // number of fields
15
- { [-2]: number[]; } & // all field indexes with "view" tag
16
- { [-3]: {[tag: number]: number[]}; } & // field indexes by "view" tag
17
- { [field: number]: string; } & // index => field name
18
- { [field: string]: MetadataField; } // field name => field metadata
17
+ { [$numFields]: number; } & // number of fields
18
+ { [$viewFieldIndexes]: number[]; } & // all field indexes with "view" tag
19
+ { [$fieldIndexesByViewTag]: {[tag: number]: number[]}; } & // field indexes by "view" tag
20
+ { [$refTypeFieldIndexes]: number[]; } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)
21
+ { [field: number]: MetadataField; } & // index => field name
22
+ { [field: string]: number; } & // field name => field metadata
23
+ { [$descriptors]: { [field: string]: PropertyDescriptor } } // property descriptors
24
+
25
+ export function getNormalizedType(type: DefinitionType): DefinitionType {
26
+ return (Array.isArray(type))
27
+ ? { array: type[0] }
28
+ : (typeof(type['type']) !== "undefined")
29
+ ? type['type']
30
+ : type;
31
+ }
19
32
 
20
33
  export const Metadata = {
21
34
 
22
- addField(metadata: any, index: number, field: string, type: DefinitionType, descriptor?: PropertyDescriptor) {
35
+ addField(metadata: any, index: number, name: string, type: DefinitionType, descriptor?: PropertyDescriptor) {
23
36
  if (index > 64) {
24
- throw new Error(`Can't define field '${field}'.\nSchema instances may only have up to 64 fields.`);
37
+ throw new Error(`Can't define field '${name}'.\nSchema instances may only have up to 64 fields.`);
25
38
  }
26
39
 
27
- metadata[field] = Object.assign(
28
- metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
40
+ metadata[index] = Object.assign(
41
+ metadata[index] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
29
42
  {
30
- type: (Array.isArray(type))
31
- ? { array: type[0] }
32
- : type,
43
+ type: getNormalizedType(type),
33
44
  index,
34
- descriptor,
45
+ name,
35
46
  }
36
47
  );
37
48
 
49
+ // create "descriptors" map
50
+ Object.defineProperty(metadata, $descriptors, {
51
+ value: metadata[$descriptors] || {},
52
+ enumerable: false,
53
+ configurable: true,
54
+ });
55
+
56
+ if (descriptor) {
57
+ // for encoder
58
+ metadata[$descriptors][name] = descriptor;
59
+ metadata[$descriptors][`_${name}`] = {
60
+ value: undefined,
61
+ writable: true,
62
+ enumerable: false,
63
+ configurable: true,
64
+ };
65
+ } else {
66
+ // for decoder
67
+ metadata[$descriptors][name] = {
68
+ value: undefined,
69
+ writable: true,
70
+ enumerable: true,
71
+ configurable: true,
72
+ };
73
+ }
74
+
38
75
  // map -1 as last field index
39
- Object.defineProperty(metadata, -1, {
76
+ Object.defineProperty(metadata, $numFields, {
40
77
  value: index,
41
78
  enumerable: false,
42
79
  configurable: true
43
80
  });
44
81
 
45
- // map index => field name (non enumerable)
46
- Object.defineProperty(metadata, index, {
47
- value: field,
82
+ // map field name => index (non enumerable)
83
+ Object.defineProperty(metadata, name, {
84
+ value: index,
48
85
  enumerable: false,
49
86
  configurable: true,
50
87
  });
88
+
89
+ // if child Ref/complex type, add to -4
90
+ if (typeof (metadata[index].type) !== "string") {
91
+ if (metadata[$refTypeFieldIndexes] === undefined) {
92
+ Object.defineProperty(metadata, $refTypeFieldIndexes, {
93
+ value: [],
94
+ enumerable: false,
95
+ configurable: true,
96
+ });
97
+ }
98
+ metadata[$refTypeFieldIndexes].push(index);
99
+ }
51
100
  },
52
101
 
53
102
  setTag(metadata: Metadata, fieldName: string, tag: number) {
103
+ const index = metadata[fieldName];
104
+ const field = metadata[index];
105
+
54
106
  // add 'tag' to the field
55
- const field = metadata[fieldName];
56
107
  field.tag = tag;
57
108
 
58
- if (!metadata[-2]) {
109
+ if (!metadata[$viewFieldIndexes]) {
59
110
  // -2: all field indexes with "view" tag
60
- Object.defineProperty(metadata, -2, {
111
+ Object.defineProperty(metadata, $viewFieldIndexes, {
61
112
  value: [],
62
113
  enumerable: false,
63
114
  configurable: true
64
115
  });
65
116
 
66
117
  // -3: field indexes by "view" tag
67
- Object.defineProperty(metadata, -3, {
118
+ Object.defineProperty(metadata, $fieldIndexesByViewTag, {
68
119
  value: {},
69
120
  enumerable: false,
70
121
  configurable: true
71
122
  });
72
123
  }
73
124
 
74
- metadata[-2].push(field.index);
125
+ metadata[$viewFieldIndexes].push(index);
75
126
 
76
- if (!metadata[-3][tag]) {
77
- metadata[-3][tag] = [];
127
+ if (!metadata[$fieldIndexesByViewTag][tag]) {
128
+ metadata[$fieldIndexesByViewTag][tag] = [];
78
129
  }
79
130
 
80
- metadata[-3][tag].push(field.index);
131
+ metadata[$fieldIndexesByViewTag][tag].push(index);
81
132
  },
82
133
 
83
134
  setFields(target: any, fields: { [field: string]: DefinitionType }) {
84
- const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});
135
+ // for inheritance support
136
+ const constructor = target.prototype.constructor;
137
+ TypeContext.register(constructor);
138
+
139
+ const parentClass = Object.getPrototypeOf(constructor);
140
+ const parentMetadata = parentClass && parentClass[Symbol.metadata];
141
+ const metadata = Metadata.initialize(constructor);
85
142
 
86
- // target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {
87
- // changeTree.change(index, operation, encodeSchemaOperation);
88
- // };
143
+ // Use Schema's methods if not defined in the class
144
+ if (!constructor[$track]) { constructor[$track] = Schema[$track]; }
145
+ if (!constructor[$encoder]) { constructor[$encoder] = Schema[$encoder]; }
146
+ if (!constructor[$decoder]) { constructor[$decoder] = Schema[$decoder]; }
147
+ if (!constructor.prototype.toJSON) { constructor.prototype.toJSON = Schema.prototype.toJSON; }
89
148
 
90
- // target[$encoder] = encodeSchemaOperation;
91
- // target[$decoder] = decodeSchemaOperation;
149
+ //
150
+ // detect index for this field, considering inheritance
151
+ //
152
+ let fieldIndex = metadata[$numFields] // current structure already has fields defined
153
+ ?? (parentMetadata && parentMetadata[$numFields]) // parent structure has fields defined
154
+ ?? -1; // no fields defined
92
155
 
93
- // if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }
156
+ fieldIndex++;
94
157
 
95
- let index = 0;
96
158
  for (const field in fields) {
97
159
  const type = fields[field];
160
+ const normalizedType = getNormalizedType(type);
98
161
 
99
162
  // FIXME: this code is duplicated from @type() annotation
100
163
  const complexTypeKlass = (Array.isArray(type))
101
164
  ? getType("array")
102
165
  : (typeof(Object.keys(type)[0]) === "string") && getType(Object.keys(type)[0]);
103
166
 
167
+ const childType = (complexTypeKlass)
168
+ ? Object.values(type)[0]
169
+ : normalizedType;
170
+
104
171
  Metadata.addField(
105
172
  metadata,
106
- index,
173
+ fieldIndex,
107
174
  field,
108
175
  type,
109
- getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass, metadata, field)
176
+ getPropertyDescriptor(`_${field}`, fieldIndex, childType, complexTypeKlass)
110
177
  );
111
178
 
112
- index++;
179
+ fieldIndex++;
113
180
  }
181
+
182
+ return target;
114
183
  },
115
184
 
116
185
  isDeprecated(metadata: any, field: string) {
117
186
  return metadata[field].deprecated === true;
118
187
  },
119
188
 
189
+ init(klass: any) {
190
+ //
191
+ // Used only to initialize an empty Schema (Encoder#constructor)
192
+ // TODO: remove/refactor this...
193
+ //
194
+ const metadata = {};
195
+ klass[Symbol.metadata] = metadata;
196
+ Object.defineProperty(metadata, $numFields, {
197
+ value: 0,
198
+ enumerable: false,
199
+ configurable: true,
200
+ });
201
+ },
202
+
203
+ initialize(constructor: any) {
204
+ const parentClass = Object.getPrototypeOf(constructor);
205
+ const parentMetadata: Metadata = parentClass[Symbol.metadata];
206
+
207
+ let metadata: Metadata = constructor[Symbol.metadata] ?? Object.create(null);
208
+
209
+ // make sure inherited classes have their own metadata object.
210
+ if (parentClass !== Schema && metadata === parentMetadata) {
211
+ metadata = Object.create(null);
212
+
213
+ if (parentMetadata) {
214
+ //
215
+ // assign parent metadata to current
216
+ //
217
+ Object.setPrototypeOf(metadata, parentMetadata);
218
+
219
+ // $numFields
220
+ Object.defineProperty(metadata, $numFields, {
221
+ value: parentMetadata[$numFields],
222
+ enumerable: false,
223
+ configurable: true,
224
+ writable: true,
225
+ });
226
+
227
+ // $viewFieldIndexes / $fieldIndexesByViewTag
228
+ if (parentMetadata[$viewFieldIndexes] !== undefined) {
229
+ Object.defineProperty(metadata, $viewFieldIndexes, {
230
+ value: [...parentMetadata[$viewFieldIndexes]],
231
+ enumerable: false,
232
+ configurable: true,
233
+ writable: true,
234
+ });
235
+ Object.defineProperty(metadata, $fieldIndexesByViewTag, {
236
+ value: { ...parentMetadata[$fieldIndexesByViewTag] },
237
+ enumerable: false,
238
+ configurable: true,
239
+ writable: true,
240
+ });
241
+ }
242
+
243
+ // $refTypeFieldIndexes
244
+ if (parentMetadata[$refTypeFieldIndexes] !== undefined) {
245
+ Object.defineProperty(metadata, $refTypeFieldIndexes, {
246
+ value: [...parentMetadata[$refTypeFieldIndexes]],
247
+ enumerable: false,
248
+ configurable: true,
249
+ writable: true,
250
+ });
251
+ }
252
+
253
+ // $descriptors
254
+ Object.defineProperty(metadata, $descriptors, {
255
+ value: { ...parentMetadata[$descriptors] },
256
+ enumerable: false,
257
+ configurable: true,
258
+ writable: true,
259
+ });
260
+ }
261
+ }
262
+
263
+ constructor[Symbol.metadata] = metadata;
264
+
265
+ return metadata;
266
+ },
267
+
120
268
  isValidInstance(klass: any) {
121
269
  return (
122
270
  klass.constructor[Symbol.metadata] &&
123
- Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], -1) as boolean
271
+ Object.prototype.hasOwnProperty.call(klass.constructor[Symbol.metadata], $numFields) as boolean
124
272
  );
125
273
  },
126
274
 
127
275
  getFields(klass: any) {
128
- const metadata = klass[Symbol.metadata];
276
+ const metadata: Metadata = klass[Symbol.metadata];
129
277
  const fields = {};
130
- for (let i = 0; i <= metadata[-1]; i++) {
131
- fields[metadata[i]] = metadata[metadata[i]].type;
278
+ for (let i = 0; i <= metadata[$numFields]; i++) {
279
+ fields[metadata[i].name] = metadata[i].type;
132
280
  }
133
281
  return fields;
134
282
  }