@colyseus/schema 3.0.0-alpha.30 → 3.0.0-alpha.31

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 (73) hide show
  1. package/build/cjs/index.js +383 -341
  2. package/build/cjs/index.js.map +1 -1
  3. package/build/esm/index.mjs +383 -341
  4. package/build/esm/index.mjs.map +1 -1
  5. package/build/umd/index.js +383 -341
  6. package/lib/Metadata.d.ts +14 -5
  7. package/lib/Metadata.js +49 -20
  8. package/lib/Metadata.js.map +1 -1
  9. package/lib/Reflection.js +4 -13
  10. package/lib/Reflection.js.map +1 -1
  11. package/lib/Schema.js +26 -39
  12. package/lib/Schema.js.map +1 -1
  13. package/lib/annotations.d.ts +1 -2
  14. package/lib/annotations.js +58 -52
  15. package/lib/annotations.js.map +1 -1
  16. package/lib/bench_encode.js +33 -11
  17. package/lib/bench_encode.js.map +1 -1
  18. package/lib/decoder/DecodeOperation.js +4 -8
  19. package/lib/decoder/DecodeOperation.js.map +1 -1
  20. package/lib/decoder/ReferenceTracker.js +3 -2
  21. package/lib/decoder/ReferenceTracker.js.map +1 -1
  22. package/lib/decoder/strategy/StateCallbacks.js +4 -3
  23. package/lib/decoder/strategy/StateCallbacks.js.map +1 -1
  24. package/lib/encoder/ChangeTree.d.ts +8 -7
  25. package/lib/encoder/ChangeTree.js +128 -115
  26. package/lib/encoder/ChangeTree.js.map +1 -1
  27. package/lib/encoder/EncodeOperation.d.ts +1 -4
  28. package/lib/encoder/EncodeOperation.js +46 -46
  29. package/lib/encoder/EncodeOperation.js.map +1 -1
  30. package/lib/encoder/Encoder.js +11 -3
  31. package/lib/encoder/Encoder.js.map +1 -1
  32. package/lib/encoder/StateView.js +3 -3
  33. package/lib/encoder/StateView.js.map +1 -1
  34. package/lib/encoding/assert.d.ts +2 -1
  35. package/lib/encoding/assert.js +2 -2
  36. package/lib/encoding/assert.js.map +1 -1
  37. package/lib/index.d.ts +1 -2
  38. package/lib/index.js +11 -10
  39. package/lib/index.js.map +1 -1
  40. package/lib/types/TypeContext.js +7 -14
  41. package/lib/types/TypeContext.js.map +1 -1
  42. package/lib/types/custom/ArraySchema.js +6 -0
  43. package/lib/types/custom/ArraySchema.js.map +1 -1
  44. package/lib/types/custom/CollectionSchema.js +1 -0
  45. package/lib/types/custom/CollectionSchema.js.map +1 -1
  46. package/lib/types/custom/MapSchema.js +5 -0
  47. package/lib/types/custom/MapSchema.js.map +1 -1
  48. package/lib/types/custom/SetSchema.js +1 -0
  49. package/lib/types/custom/SetSchema.js.map +1 -1
  50. package/lib/types/symbols.d.ts +1 -0
  51. package/lib/types/symbols.js +2 -1
  52. package/lib/types/symbols.js.map +1 -1
  53. package/package.json +1 -1
  54. package/src/Metadata.ts +60 -29
  55. package/src/Reflection.ts +5 -15
  56. package/src/Schema.ts +33 -45
  57. package/src/annotations.ts +75 -67
  58. package/src/bench_encode.ts +37 -13
  59. package/src/decoder/DecodeOperation.ts +4 -10
  60. package/src/decoder/ReferenceTracker.ts +3 -2
  61. package/src/decoder/strategy/StateCallbacks.ts +4 -3
  62. package/src/encoder/ChangeTree.ts +146 -135
  63. package/src/encoder/EncodeOperation.ts +64 -58
  64. package/src/encoder/Encoder.ts +16 -4
  65. package/src/encoder/StateView.ts +4 -4
  66. package/src/encoding/assert.ts +4 -3
  67. package/src/index.ts +1 -4
  68. package/src/types/TypeContext.ts +10 -15
  69. package/src/types/custom/ArraySchema.ts +8 -0
  70. package/src/types/custom/CollectionSchema.ts +1 -0
  71. package/src/types/custom/MapSchema.ts +6 -0
  72. package/src/types/custom/SetSchema.ts +1 -0
  73. package/src/types/symbols.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"MapSchema.js","sourceRoot":"","sources":["../../../src/types/custom/MapSchema.ts"],"names":[],"mappings":"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","sourcesContent":["import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex } from \"../symbols\";\nimport { ChangeTree } from \"../../encoder/ChangeTree\";\nimport { OPERATION } from \"../../encoding/spec\";\nimport { registerType } from \"../registry\";\nimport { Collection } from \"../HelperTypes\";\nimport { decodeKeyValueOperation } from \"../../decoder/DecodeOperation\";\nimport { encodeKeyValueOperation } from \"../../encoder/EncodeOperation\";\nimport type { StateView } from \"../../encoder/StateView\";\n\nexport class MapSchema<V=any, K extends string = string> implements Map<K, V>, Collection<K, V, [K, V]> {\n protected childType: new () => V;\n\n protected $items: Map<K, V> = new Map<K, V>();\n protected $indexes: Map<number, K> = new Map<number, K>();\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: MapSchema, 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['map'] !== undefined;\n }\n\n constructor (initialValues?: Map<K, V> | Record<K, V>) {\n this[$changes] = new ChangeTree(this);\n\n if (initialValues) {\n if (\n initialValues instanceof Map ||\n initialValues instanceof MapSchema\n ) {\n initialValues.forEach((v, k) => this.set(k, v));\n\n } else {\n for (const k in initialValues) {\n this.set(k, initialValues[k]);\n }\n }\n }\n\n Object.defineProperty(this, $childType, {\n value: undefined,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n }\n\n /** Iterator */\n [Symbol.iterator](): IterableIterator<[K, V]> { return this.$items[Symbol.iterator](); }\n get [Symbol.toStringTag]() { return this.$items[Symbol.toStringTag] }\n\n static get [Symbol.species]() { return MapSchema; }\n\n set(key: K, value: V) {\n if (value === undefined || value === null) {\n throw new Error(`MapSchema#set('${key}', ${value}): trying to set ${value} value on '${key}'.`);\n }\n\n // Force \"key\" as string\n // See: https://github.com/colyseus/colyseus/issues/561#issuecomment-1646733468\n key = key.toString() as K;\n\n const changeTree = this[$changes];\n\n // get \"index\" for this value.\n const isReplace = typeof(changeTree.indexes[key]) !== \"undefined\";\n\n const index = (isReplace)\n ? changeTree.indexes[key]\n : changeTree.indexes[-1] ?? 0;\n\n let operation: OPERATION = (isReplace)\n ? OPERATION.REPLACE\n : OPERATION.ADD;\n\n const isRef = (value[$changes]) !== undefined;\n\n //\n // (encoding)\n // set a unique id to relate directly with this key/value.\n //\n if (!isReplace) {\n this.$indexes.set(index, key);\n changeTree.indexes[key] = index;\n changeTree.indexes[-1] = index + 1;\n\n } else if (\n !isRef &&\n this.$items.get(key) === value\n ) {\n // if value is the same, avoid re-encoding it.\n return;\n\n } else if (\n isRef && // if is schema, force ADD operation if value differ from previous one.\n this.$items.get(key) !== value\n ) {\n operation = OPERATION.ADD;\n }\n\n this.$items.set(key, value);\n\n changeTree.change(index, operation);\n\n //\n // set value's parent after the value is set\n // (to avoid encoding \"refId\" operations before parent's \"ADD\" operation)\n //\n if (isRef) {\n value[$changes].setParent(this, changeTree.root, index);\n }\n\n return this;\n }\n\n get(key: K): V | undefined {\n return this.$items.get(key);\n }\n\n delete(key: K) {\n const index = this[$changes].indexes[key];\n\n this[$changes].delete(index);\n\n return this.$items.delete(key);\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 (key: K) {\n return this.$items.has(key);\n }\n\n forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void) {\n this.$items.forEach(callbackfn);\n }\n\n entries () {\n return this.$items.entries();\n }\n\n keys () {\n return this.$items.keys();\n }\n\n values() {\n return this.$items.values();\n }\n\n get size () {\n return this.$items.size;\n }\n\n protected setIndex(index: number, key: K) {\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 protected [$onEncodeEnd]() {\n const changeTree = this[$changes];\n const changes = changeTree.changes.entries();\n for (const [fieldIndex, operation] of changes) {\n if (operation === OPERATION.DELETE) {\n const index = this[$getByIndex](fieldIndex) as string;\n delete changeTree.indexes[index];\n }\n }\n }\n\n toJSON() {\n const map: any = {};\n\n this.forEach((value, key) => {\n map[key] = (typeof (value['toJSON']) === \"function\")\n ? value['toJSON']()\n : value;\n });\n\n return map;\n }\n\n //\n // Decoding utilities\n //\n // @ts-ignore\n clone(isDecoding?: boolean): MapSchema<V> {\n let cloned: MapSchema<V>;\n\n if (isDecoding) {\n // client-side\n cloned = Object.assign(new MapSchema(), this);\n\n } else {\n // server-side\n cloned = new MapSchema();\n\n this.forEach((value, key) => {\n if (value[$changes]) {\n cloned.set(key, value['clone']());\n } else {\n cloned.set(key, value);\n }\n })\n\n }\n\n return cloned;\n }\n\n}\n\nregisterType(\"map\", { constructor: MapSchema });"]}
1
+ {"version":3,"file":"MapSchema.js","sourceRoot":"","sources":["../../../src/types/custom/MapSchema.ts"],"names":[],"mappings":";;;;AAAA,wCAA0H;AAC1H,yDAAsD;AACtD,8CAAgD;AAChD,0CAA2C;AAE3C,mEAAwE;AACxE,mEAAwE;AAGxE,kDAA2D;AAE3D,MAAa,SAAS;aAMX,QAAU,GAAG,yCAAuB,AAA1B,CAA2B;aACrC,QAAU,GAAG,yCAAuB,AAA1B,CAA2B;IAE5C;;;;;;;;OAQG;IACH,MAAM,CAAC,OAZC,kBAAQ,OACR,kBAAQ,EAWR,iBAAO,EAAC,CAAE,GAAc,EAAE,KAAa,EAAE,IAAe;QAC5D,OAAO,CACH,CAAC,IAAI;YACL,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,CAAC,KAAK,QAAQ;YACrC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,qBAAW,CAAC,CAAC,KAAK,CAAC,CAAC,kBAAQ,CAAC,CAAC,CACpD,CAAC;IACN,CAAC;IAED,MAAM,CAAC,EAAE,CAAC,IAAS;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;IACrC,CAAC;IAED,YAAa,aAAwC;QA3B3C,WAAM,GAAc,IAAI,GAAG,EAAQ,CAAC;QACpC,aAAQ,GAAmB,IAAI,GAAG,EAAa,CAAC;QA2BtD,IAAI,CAAC,kBAAQ,CAAC,GAAG,IAAI,uBAAU,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,kBAAQ,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC;QAE5B,IAAI,aAAa,EAAE,CAAC;YAChB,IACI,aAAa,YAAY,GAAG;gBAC5B,aAAa,YAAY,SAAS,EACpC,CAAC;gBACC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAEpD,CAAC;iBAAM,CAAC;gBACJ,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;oBAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;QAED,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAU,EAAE;YACpC,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACP,CAAC;IAED,eAAe;IACf,CAAC,MAAM,CAAC,QAAQ,CAAC,KAA+B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;IACxF,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA,CAAC,CAAC;IAErE,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,OAAO,SAAS,CAAC,CAAC,CAAC;IAEnD,GAAG,CAAC,GAAM,EAAE,KAAQ;QAChB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,MAAM,KAAK,oBAAoB,KAAK,cAAc,GAAG,IAAI,CAAC,CAAC;QAEpG,CAAC;aAAM,IAAI,OAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,IAAI,IAAI,CAAC,oBAAU,CAAC,EAAE,CAAC;YACxD,IAAA,2BAAkB,EAAC,KAAY,EAAE,IAAI,CAAC,oBAAU,CAAkB,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACnF,CAAC;QAED,wBAAwB;QACxB,+EAA+E;QAC/E,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAO,CAAC;QAE1B,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC;QAElC,8BAA8B;QAC9B,MAAM,SAAS,GAAG,OAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC;QAElE,MAAM,KAAK,GAAG,CAAC,SAAS,CAAC;YACrB,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC;YACzB,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAElC,IAAI,SAAS,GAAc,CAAC,SAAS,CAAC;YAClC,CAAC,CAAC,gBAAS,CAAC,OAAO;YACnB,CAAC,CAAC,gBAAS,CAAC,GAAG,CAAC;QAEpB,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,kBAAQ,CAAC,CAAC,KAAK,SAAS,CAAC;QAE9C,EAAE;QACF,aAAa;QACb,0DAA0D;QAC1D,EAAE;QACF,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC9B,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAChC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;QAEvC,CAAC;aAAM,IACH,CAAC,KAAK;YACN,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAChC,CAAC;YACC,8CAA8C;YAC9C,OAAO;QAEX,CAAC;aAAM,IACH,KAAK,IAAI,uEAAuE;YAChF,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAChC,CAAC;YACC,SAAS,GAAG,gBAAS,CAAC,GAAG,CAAC;QAC9B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAE5B,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAEpC,EAAE;QACF,4CAA4C;QAC5C,yEAAyE;QACzE,EAAE;QACF,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,CAAC,kBAAQ,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,GAAM;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,CAAC,GAAM;QACT,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAE1C,IAAI,CAAC,kBAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE7B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,KAAK;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC;QAElC,+BAA+B;QAC/B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,UAAU,CAAC,OAAO,GAAG,EAAE,CAAC;QAExB,yBAAyB;QACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEtB,cAAc;QACd,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,UAAU,CAAC,SAAS,CAAC,gBAAS,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,GAAG,CAAE,GAAM;QACP,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,UAAsD;QAC1D,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAED,OAAO;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED,IAAI;QACA,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,MAAM;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5B,CAAC;IAES,QAAQ,CAAC,KAAa,EAAE,GAAM;QACpC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;IAES,QAAQ,CAAC,KAAa;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAES,CAAC,qBAAW,CAAC,CAAC,KAAa;QACjC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC;IAES,CAAC,wBAAc,CAAC,CAAC,KAAa;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAES,CAAC,sBAAY,CAAC;QACpB,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,IAAI,OAAO,EAAE,CAAC;YAC5C,IAAI,SAAS,KAAK,gBAAS,CAAC,MAAM,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAW,CAAC,CAAC,UAAU,CAAW,CAAC;gBACtD,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC;QACL,CAAC;IACL,CAAC;IAED,MAAM;QACF,MAAM,GAAG,GAAQ,EAAE,CAAC;QAEpB,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACxB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,UAAU,CAAC;gBAChD,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;gBACnB,CAAC,CAAC,KAAK,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,CAAC;IACf,CAAC;IAED,EAAE;IACF,qBAAqB;IACrB,EAAE;IACF,aAAa;IACb,KAAK,CAAC,UAAoB;QACtB,IAAI,MAAoB,CAAC;QAEzB,IAAI,UAAU,EAAE,CAAC;YACb,cAAc;YACd,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,EAAE,IAAI,CAAC,CAAC;QAElD,CAAC;aAAM,CAAC;YACJ,cAAc;YACd,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAEzB,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBACxB,IAAI,KAAK,CAAC,kBAAQ,CAAC,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACJ,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC3B,CAAC;YACL,CAAC,CAAC,CAAA;QAEN,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;;AAtPL,8BAwPC;AAED,IAAA,uBAAY,EAAC,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC","sourcesContent":["import { $changes, $childType, $decoder, $deleteByIndex, $onEncodeEnd, $encoder, $filter, $getByIndex } from \"../symbols\";\nimport { ChangeTree } from \"../../encoder/ChangeTree\";\nimport { OPERATION } from \"../../encoding/spec\";\nimport { registerType } from \"../registry\";\nimport { Collection } from \"../HelperTypes\";\nimport { decodeKeyValueOperation } from \"../../decoder/DecodeOperation\";\nimport { encodeKeyValueOperation } from \"../../encoder/EncodeOperation\";\nimport type { StateView } from \"../../encoder/StateView\";\nimport type { Schema } from \"../../Schema\";\nimport { assertInstanceType } from \"../../encoding/assert\";\n\nexport class MapSchema<V=any, K extends string = string> implements Map<K, V>, Collection<K, V, [K, V]> {\n protected childType: new () => V;\n\n protected $items: Map<K, V> = new Map<K, V>();\n protected $indexes: Map<number, K> = new Map<number, K>();\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: MapSchema, 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['map'] !== undefined;\n }\n\n constructor (initialValues?: Map<K, V> | Record<K, V>) {\n this[$changes] = new ChangeTree(this);\n this[$changes].indexes = {};\n\n if (initialValues) {\n if (\n initialValues instanceof Map ||\n initialValues instanceof MapSchema\n ) {\n initialValues.forEach((v, k) => this.set(k, v));\n\n } else {\n for (const k in initialValues) {\n this.set(k, initialValues[k]);\n }\n }\n }\n\n Object.defineProperty(this, $childType, {\n value: undefined,\n enumerable: false,\n writable: true,\n configurable: true,\n });\n }\n\n /** Iterator */\n [Symbol.iterator](): IterableIterator<[K, V]> { return this.$items[Symbol.iterator](); }\n get [Symbol.toStringTag]() { return this.$items[Symbol.toStringTag] }\n\n static get [Symbol.species]() { return MapSchema; }\n\n set(key: K, value: V) {\n if (value === undefined || value === null) {\n throw new Error(`MapSchema#set('${key}', ${value}): trying to set ${value} value on '${key}'.`);\n\n } else if (typeof(value) === \"object\" && this[$childType]) {\n assertInstanceType(value as any, this[$childType] as typeof Schema, this, key);\n }\n\n // Force \"key\" as string\n // See: https://github.com/colyseus/colyseus/issues/561#issuecomment-1646733468\n key = key.toString() as K;\n\n const changeTree = this[$changes];\n\n // get \"index\" for this value.\n const isReplace = typeof(changeTree.indexes[key]) !== \"undefined\";\n\n const index = (isReplace)\n ? changeTree.indexes[key]\n : changeTree.indexes[-1] ?? 0;\n\n let operation: OPERATION = (isReplace)\n ? OPERATION.REPLACE\n : OPERATION.ADD;\n\n const isRef = (value[$changes]) !== undefined;\n\n //\n // (encoding)\n // set a unique id to relate directly with this key/value.\n //\n if (!isReplace) {\n this.$indexes.set(index, key);\n changeTree.indexes[key] = index;\n changeTree.indexes[-1] = index + 1;\n\n } else if (\n !isRef &&\n this.$items.get(key) === value\n ) {\n // if value is the same, avoid re-encoding it.\n return;\n\n } else if (\n isRef && // if is schema, force ADD operation if value differ from previous one.\n this.$items.get(key) !== value\n ) {\n operation = OPERATION.ADD;\n }\n\n this.$items.set(key, value);\n\n changeTree.change(index, operation);\n\n //\n // set value's parent after the value is set\n // (to avoid encoding \"refId\" operations before parent's \"ADD\" operation)\n //\n if (isRef) {\n value[$changes].setParent(this, changeTree.root, index);\n }\n\n return this;\n }\n\n get(key: K): V | undefined {\n return this.$items.get(key);\n }\n\n delete(key: K) {\n const index = this[$changes].indexes[key];\n\n this[$changes].delete(index);\n\n return this.$items.delete(key);\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 (key: K) {\n return this.$items.has(key);\n }\n\n forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void) {\n this.$items.forEach(callbackfn);\n }\n\n entries () {\n return this.$items.entries();\n }\n\n keys () {\n return this.$items.keys();\n }\n\n values() {\n return this.$items.values();\n }\n\n get size () {\n return this.$items.size;\n }\n\n protected setIndex(index: number, key: K) {\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 protected [$onEncodeEnd]() {\n const changeTree = this[$changes];\n const changes = changeTree.changes.entries();\n for (const [fieldIndex, operation] of changes) {\n if (operation === OPERATION.DELETE) {\n const index = this[$getByIndex](fieldIndex) as string;\n delete changeTree.indexes[index];\n }\n }\n }\n\n toJSON() {\n const map: any = {};\n\n this.forEach((value, key) => {\n map[key] = (typeof (value['toJSON']) === \"function\")\n ? value['toJSON']()\n : value;\n });\n\n return map;\n }\n\n //\n // Decoding utilities\n //\n // @ts-ignore\n clone(isDecoding?: boolean): MapSchema<V> {\n let cloned: MapSchema<V>;\n\n if (isDecoding) {\n // client-side\n cloned = Object.assign(new MapSchema(), this);\n\n } else {\n // server-side\n cloned = new MapSchema();\n\n this.forEach((value, key) => {\n if (value[$changes]) {\n cloned.set(key, value['clone']());\n } else {\n cloned.set(key, value);\n }\n })\n\n }\n\n return cloned;\n }\n\n}\n\nregisterType(\"map\", { constructor: MapSchema });"]}
@@ -33,6 +33,7 @@ class SetSchema {
33
33
  this.$indexes = new Map();
34
34
  this.$refId = 0;
35
35
  this[symbols_1.$changes] = new ChangeTree_1.ChangeTree(this);
36
+ this[symbols_1.$changes].indexes = {};
36
37
  if (initialValues) {
37
38
  initialValues.forEach((v) => this.add(v));
38
39
  }
@@ -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":";;;;AAAA,8CAAgD;AAChD,0CAA2C;AAC3C,wCAA4G;AAE5G,yDAAsD;AACtD,mEAAwE;AACxE,mEAAwE;AAGxE,MAAa,SAAS;aAOX,QAAU,GAAG,yCAAuB,AAA1B,CAA2B;aACrC,QAAU,GAAG,yCAAuB,AAA1B,CAA2B;IAE5C;;;;;;;;OAQG;IACH,MAAM,CAAC,OAZC,kBAAQ,OACR,kBAAQ,EAWR,iBAAO,EAAC,CAAE,GAAc,EAAE,KAAa,EAAE,IAAe;QAC5D,OAAO,CACH,CAAC,IAAI;YACL,OAAO,CAAC,GAAG,CAAC,oBAAU,CAAC,CAAC,KAAK,QAAQ;YACrC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,qBAAW,CAAC,CAAC,KAAK,CAAC,CAAC,kBAAQ,CAAC,CAAC,CACpD,CAAC;IACN,CAAC;IAED,MAAM,CAAC,EAAE,CAAC,IAAS;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,SAAS,CAAC;IACrC,CAAC;IAED,YAAa,aAAwB;QA7B3B,WAAM,GAAmB,IAAI,GAAG,EAAa,CAAC;QAC9C,aAAQ,GAAwB,IAAI,GAAG,EAAkB,CAAC;QAE1D,WAAM,GAAW,CAAC,CAAC;QA2BzB,IAAI,CAAC,kBAAQ,CAAC,GAAG,IAAI,uBAAU,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,kBAAQ,CAAC,CAAC,OAAO,GAAG,EAAE,CAAC;QAE5B,IAAI,aAAa,EAAE,CAAC;YAChB,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,oBAAU,EAAE;YACpC,KAAK,EAAE,SAAS;YAChB,UAAU,EAAE,KAAK;YACjB,QAAQ,EAAE,IAAI;YACd,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACP,CAAC;IAED,GAAG,CAAC,KAAQ;QACR,oDAAoD;QACpD,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAC,OAAO,KAAK,CAAC;QAAC,CAAC;QAEtC,6BAA6B;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAE5B,IAAI,CAAC,KAAK,CAAC,kBAAQ,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,kBAAQ,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,kBAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,gBAAS,CAAC,GAAG,CAAC;QAErE,IAAI,CAAC,kBAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;QAEtC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAE9B,IAAI,CAAC,kBAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,OAAO;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,IAAO;QACV,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAEtC,IAAI,KAAa,CAAC;QAClB,IAAI,KAAkC,CAAC;QACvC,OAAO,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAAC,MAAM;YAAC,CAAC;YAE1B,IAAI,IAAI,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1B,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACvB,MAAM;YACV,CAAC;QACL,CAAC;QAED,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,kBAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE5B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,KAAK;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAQ,CAAC,CAAC;QAElC,+BAA+B;QAC/B,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,UAAU,CAAC,OAAO,GAAG,EAAE,CAAC;QAExB,yBAAyB;QACzB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEtB,cAAc;QACd,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAEpB,UAAU,CAAC,SAAS,CAAC,gBAAS,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED,GAAG,CAAE,KAAQ;QACT,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAEpC,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,IAAI,KAAwB,CAAC;QAE7B,OAAO,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBAAC,MAAM;YAAC,CAAC;YAC1B,IAAI,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;gBACxB,GAAG,GAAG,IAAI,CAAC;gBACX,MAAM;YACV,CAAC;QACL,CAAC;QAED,OAAO,GAAG,CAAC;IACf,CAAC;IAED,OAAO,CAAC,UAAqE;QACzE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC;IAED,MAAM;QACF,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAChC,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,eAAe;IACf,CAAC,MAAM,CAAC,QAAQ,CAAC;QACb,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAChC,CAAC;IAES,QAAQ,CAAC,KAAa,EAAE,GAAW;QACzC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClC,CAAC;IAES,QAAQ,CAAC,KAAa;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAES,CAAC,qBAAW,CAAC,CAAC,KAAa;QACjC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC;IAES,CAAC,wBAAc,CAAC,CAAC,KAAa;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACH,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,MAAM;QACF,MAAM,MAAM,GAAQ,EAAE,CAAC;QAEvB,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACxB,MAAM,CAAC,IAAI,CACP,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,KAAK,UAAU,CAAC;gBACrC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;gBACnB,CAAC,CAAC,KAAK,CACd,CAAC;QACN,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,EAAE;IACF,qBAAqB;IACrB,EAAE;IACF,KAAK,CAAC,UAAoB;QACtB,IAAI,MAAiB,CAAC;QAEtB,IAAI,UAAU,EAAE,CAAC;YACb,cAAc;YACd,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,EAAE,IAAI,CAAC,CAAC;QAElD,CAAC;aAAM,CAAC;YACJ,cAAc;YACd,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACnB,IAAI,KAAK,CAAC,kBAAQ,CAAC,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACJ,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;YACL,CAAC,CAAC,CAAA;QACN,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;;AA9ML,8BAgNC;AAED,IAAA,uBAAY,EAAC,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC","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 });"]}
@@ -4,6 +4,7 @@ export declare const $decoder: unique symbol;
4
4
  export declare const $filter: unique symbol;
5
5
  export declare const $getByIndex: unique symbol;
6
6
  export declare const $deleteByIndex: unique symbol;
7
+ export declare const $descriptors: unique symbol;
7
8
  /**
8
9
  * Used to hold ChangeTree instances whitin the structures
9
10
  */
@@ -1,12 +1,13 @@
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.$onDecodeEnd = exports.$onEncodeEnd = exports.$isNew = exports.$childType = exports.$changes = exports.$descriptors = 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");
7
7
  exports.$filter = Symbol("$filter");
8
8
  exports.$getByIndex = Symbol("$getByIndex");
9
9
  exports.$deleteByIndex = Symbol("$deleteByIndex");
10
+ exports.$descriptors = Symbol("$descriptors");
10
11
  /**
11
12
  * Used to hold ChangeTree instances whitin the structures
12
13
  */
@@ -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;AAE1C,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAEnD;;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\nexport const $descriptors = Symbol(\"$descriptors\");\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\");"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/schema",
3
- "version": "3.0.0-alpha.30",
3
+ "version": "3.0.0-alpha.31",
4
4
  "description": "Binary state serializer with delta encoding for games",
5
5
  "bin": {
6
6
  "schema-codegen": "./bin/schema-codegen"
package/src/Metadata.ts CHANGED
@@ -1,40 +1,65 @@
1
1
  import { getPropertyDescriptor, type DefinitionType } from "./annotations";
2
2
  import { getType } from "./types/registry";
3
+ import { $descriptors } from "./types/symbols";
3
4
 
4
5
  export type MetadataField = {
5
6
  type: DefinitionType,
7
+ name: string,
6
8
  index: number,
7
9
  tag?: number,
8
10
  unreliable?: boolean,
9
11
  deprecated?: boolean,
10
- descriptor?: PropertyDescriptor,
11
12
  };
12
13
 
13
14
  export type Metadata =
14
15
  { [-1]: number; } & // number of fields
15
16
  { [-2]: number[]; } & // all field indexes with "view" tag
16
17
  { [-3]: {[tag: number]: number[]}; } & // field indexes by "view" tag
17
- { [field: number]: string; } & // index => field name
18
- { [field: string]: MetadataField; } // field name => field metadata
18
+ { [-4]: number[]; } & // all field indexes containing Ref types (Schema, ArraySchema, MapSchema, etc)
19
+ { [field: number]: MetadataField; } & // index => field name
20
+ { [field: string]: number; } & // field name => field metadata
21
+ { [$descriptors]: { [field: string]: PropertyDescriptor } } // property descriptors
19
22
 
20
23
  export const Metadata = {
21
24
 
22
- addField(metadata: any, index: number, field: string, type: DefinitionType, descriptor?: PropertyDescriptor) {
25
+ addField(metadata: any, index: number, name: string, type: DefinitionType, descriptor?: PropertyDescriptor) {
23
26
  if (index > 64) {
24
- throw new Error(`Can't define field '${field}'.\nSchema instances may only have up to 64 fields.`);
27
+ throw new Error(`Can't define field '${name}'.\nSchema instances may only have up to 64 fields.`);
25
28
  }
26
29
 
27
- metadata[field] = Object.assign(
28
- metadata[field] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
30
+ metadata[index] = Object.assign(
31
+ metadata[index] || {}, // avoid overwriting previous field metadata (@owned / @deprecated)
29
32
  {
30
33
  type: (Array.isArray(type))
31
34
  ? { array: type[0] }
32
35
  : type,
33
36
  index,
34
- descriptor,
37
+ name,
35
38
  }
36
39
  );
37
40
 
41
+ // create "descriptors" map
42
+ metadata[$descriptors] ??= {};
43
+
44
+ if (descriptor) {
45
+ // for encoder
46
+ metadata[$descriptors][name] = descriptor;
47
+ metadata[$descriptors][`_${name}`] = {
48
+ value: undefined,
49
+ writable: true,
50
+ enumerable: false,
51
+ configurable: true,
52
+ };
53
+ } else {
54
+ // for decoder
55
+ metadata[$descriptors][name] = {
56
+ value: undefined,
57
+ writable: true,
58
+ enumerable: true,
59
+ configurable: true,
60
+ };
61
+ }
62
+
38
63
  // map -1 as last field index
39
64
  Object.defineProperty(metadata, -1, {
40
65
  value: index,
@@ -42,17 +67,31 @@ export const Metadata = {
42
67
  configurable: true
43
68
  });
44
69
 
45
- // map index => field name (non enumerable)
46
- Object.defineProperty(metadata, index, {
47
- value: field,
70
+ // map field name => index (non enumerable)
71
+ Object.defineProperty(metadata, name, {
72
+ value: index,
48
73
  enumerable: false,
49
74
  configurable: true,
50
75
  });
76
+
77
+ // if child Ref/complex type, add to -4
78
+ if (typeof (metadata[index].type) !== "string") {
79
+ if (metadata[-4] === undefined) {
80
+ Object.defineProperty(metadata, -4, {
81
+ value: [],
82
+ enumerable: false,
83
+ configurable: true,
84
+ });
85
+ }
86
+ metadata[-4].push(index);
87
+ }
51
88
  },
52
89
 
53
90
  setTag(metadata: Metadata, fieldName: string, tag: number) {
91
+ const index = metadata[fieldName];
92
+ const field = metadata[index];
93
+
54
94
  // add 'tag' to the field
55
- const field = metadata[fieldName];
56
95
  field.tag = tag;
57
96
 
58
97
  if (!metadata[-2]) {
@@ -71,27 +110,18 @@ export const Metadata = {
71
110
  });
72
111
  }
73
112
 
74
- metadata[-2].push(field.index);
113
+ metadata[-2].push(index);
75
114
 
76
115
  if (!metadata[-3][tag]) {
77
116
  metadata[-3][tag] = [];
78
117
  }
79
118
 
80
- metadata[-3][tag].push(field.index);
119
+ metadata[-3][tag].push(index);
81
120
  },
82
121
 
83
122
  setFields(target: any, fields: { [field: string]: DefinitionType }) {
84
123
  const metadata = (target.prototype.constructor[Symbol.metadata] ??= {});
85
124
 
86
- // target[$track] = function (changeTree, index: number, operation: OPERATION = OPERATION.ADD) {
87
- // changeTree.change(index, operation, encodeSchemaOperation);
88
- // };
89
-
90
- // target[$encoder] = encodeSchemaOperation;
91
- // target[$decoder] = decodeSchemaOperation;
92
-
93
- // if (!target.prototype.toJSON) { target.prototype.toJSON = Schema.prototype.toJSON; }
94
-
95
125
  let index = 0;
96
126
  for (const field in fields) {
97
127
  const type = fields[field];
@@ -106,7 +136,7 @@ export const Metadata = {
106
136
  index,
107
137
  field,
108
138
  type,
109
- getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass, metadata, field)
139
+ getPropertyDescriptor(`_${field}`, index, type, complexTypeKlass)
110
140
  );
111
141
 
112
142
  index++;
@@ -131,7 +161,7 @@ export const Metadata = {
131
161
  });
132
162
  },
133
163
 
134
- initialize(constructor: any, parentMetadata?: any) {
164
+ initialize(constructor: any, parentMetadata?: Metadata) {
135
165
  let metadata: Metadata = constructor[Symbol.metadata] ?? Object.create(null);
136
166
 
137
167
  // make sure inherited classes have their own metadata object.
@@ -143,8 +173,9 @@ export const Metadata = {
143
173
  Object.assign(metadata, parentMetadata);
144
174
 
145
175
  for (let i = 0; i <= parentMetadata[-1]; i++) {
146
- Object.defineProperty(metadata, i, {
147
- value: parentMetadata[i],
176
+ const fieldName = parentMetadata[i].name;
177
+ Object.defineProperty(metadata, fieldName, {
178
+ value: parentMetadata[fieldName],
148
179
  enumerable: false,
149
180
  configurable: true,
150
181
  });
@@ -172,10 +203,10 @@ export const Metadata = {
172
203
  },
173
204
 
174
205
  getFields(klass: any) {
175
- const metadata = klass[Symbol.metadata];
206
+ const metadata: Metadata = klass[Symbol.metadata];
176
207
  const fields = {};
177
208
  for (let i = 0; i <= metadata[-1]; i++) {
178
- fields[metadata[i]] = metadata[metadata[i]].type;
209
+ fields[metadata[i].name] = metadata[i].type;
179
210
  }
180
211
  return fields;
181
212
  }
package/src/Reflection.ts CHANGED
@@ -32,7 +32,10 @@ export class Reflection extends Schema {
32
32
  const encoder = new Encoder(reflection);
33
33
 
34
34
  const buildType = (currentType: ReflectionType, metadata: Metadata) => {
35
- for (const fieldName in metadata) {
35
+ for (const fieldIndex in metadata) {
36
+ const index = Number(fieldIndex);
37
+ const fieldName = metadata[index].name;
38
+
36
39
  // skip fields from parent classes
37
40
  if (!Object.prototype.hasOwnProperty.call(metadata, fieldName)) {
38
41
  continue;
@@ -43,7 +46,7 @@ export class Reflection extends Schema {
43
46
 
44
47
  let fieldType: string;
45
48
 
46
- const type = metadata[fieldName].type;
49
+ const type = metadata[index].type;
47
50
 
48
51
  if (typeof (type) === "string") {
49
52
  fieldType = type;
@@ -128,21 +131,8 @@ export class Reflection extends Schema {
128
131
  const schemaType = typeContext.get(reflectionType.id);
129
132
  const metadata = schemaType[Symbol.metadata];
130
133
 
131
- // FIXME: use metadata[-1] to get field count
132
134
  const parentFieldIndex = 0;
133
135
 
134
- // console.log("--------------------");
135
- // // console.log("reflectionType", reflectionType.toJSON());
136
- // console.log("reflectionType.fields", reflectionType.fields.toJSON());
137
- // console.log("parentFieldIndex", parentFieldIndex);
138
-
139
- //
140
- // FIXME: set fields using parentKlass as well
141
- // currently the fields are duplicated on inherited classes
142
- //
143
- // // const parentKlass = reflection.types[reflectionType.extendsId];
144
- // // parentKlass.fields
145
-
146
136
  reflectionType.fields.forEach((field, i) => {
147
137
  const fieldIndex = parentFieldIndex + i;
148
138
 
package/src/Schema.ts CHANGED
@@ -4,7 +4,7 @@ import { DEFAULT_VIEW_TAG, DefinitionType } from "./annotations";
4
4
  import { NonFunctionPropNames, ToJSON } from './types/HelperTypes';
5
5
 
6
6
  import { ChangeTree, Ref } from './encoder/ChangeTree';
7
- import { $changes, $decoder, $deleteByIndex, $encoder, $filter, $getByIndex, $track } from './types/symbols';
7
+ import { $changes, $decoder, $deleteByIndex, $descriptors, $encoder, $filter, $getByIndex, $track } from './types/symbols';
8
8
  import { StateView } from './encoder/StateView';
9
9
 
10
10
  import { encodeSchemaOperation } from './encoder/EncodeOperation';
@@ -16,7 +16,6 @@ import { getIndent } from './utils';
16
16
  * Schema encoder / decoder
17
17
  */
18
18
  export abstract class Schema {
19
-
20
19
  static [$encoder] = encodeSchemaOperation;
21
20
  static [$decoder] = decodeSchemaOperation;
22
21
 
@@ -31,37 +30,7 @@ export abstract class Schema {
31
30
  writable: true
32
31
  });
33
32
 
34
- const metadata = instance.constructor[Symbol.metadata];
35
-
36
- // Define property descriptors
37
- for (const field in metadata) {
38
- if (metadata[field].descriptor) {
39
- // for encoder
40
- Object.defineProperty(instance, `_${field}`, {
41
- value: undefined,
42
- writable: true,
43
- enumerable: false,
44
- configurable: true,
45
- });
46
- Object.defineProperty(instance, field, metadata[field].descriptor);
47
-
48
- } else {
49
- // for decoder
50
- Object.defineProperty(instance, field, {
51
- value: undefined,
52
- writable: true,
53
- enumerable: true,
54
- configurable: true,
55
- });
56
- }
57
-
58
- // Object.defineProperty(instance, field, {
59
- // ...instance.constructor[Symbol.metadata][field].descriptor
60
- // });
61
- // if (args[0]?.hasOwnProperty(field)) {
62
- // instance[field] = args[0][field];
63
- // }
64
- }
33
+ Object.defineProperties(instance, instance.constructor[Symbol.metadata]?.[$descriptors] || {});
65
34
  }
66
35
 
67
36
  static is(type: DefinitionType) {
@@ -88,7 +57,7 @@ export abstract class Schema {
88
57
  */
89
58
  static [$filter] (ref: Schema, index: number, view: StateView) {
90
59
  const metadata: Metadata = ref.constructor[Symbol.metadata];
91
- const tag = metadata[metadata[index]].tag;
60
+ const tag = metadata[index]?.tag;
92
61
 
93
62
  if (view === undefined) {
94
63
  // shared pass/encode: encode if doesn't have a tag
@@ -111,13 +80,24 @@ export abstract class Schema {
111
80
 
112
81
  // allow inherited classes to have a constructor
113
82
  constructor(...args: any[]) {
114
- Schema.initialize(this);
83
+ //
84
+ // inline
85
+ // Schema.initialize(this);
86
+ //
87
+
88
+ Object.defineProperty(this, $changes, {
89
+ value: new ChangeTree(this),
90
+ enumerable: false,
91
+ writable: true
92
+ });
93
+
94
+ Object.defineProperties(this, this.constructor[Symbol.metadata]?.[$descriptors] || {});
115
95
 
116
96
  //
117
97
  // Assign initial values
118
98
  //
119
99
  if (args[0]) {
120
- this.assign(args[0]);
100
+ Object.assign(this, args[0]);
121
101
  }
122
102
  }
123
103
 
@@ -135,21 +115,25 @@ export abstract class Schema {
135
115
  * @param operation OPERATION to perform (detected automatically)
136
116
  */
137
117
  public setDirty<K extends NonFunctionPropNames<this>>(property: K | number, operation?: OPERATION) {
118
+ const metadata: Metadata = this.constructor[Symbol.metadata];
138
119
  this[$changes].change(
139
- this.constructor[Symbol.metadata][property as string].index,
120
+ metadata[metadata[property as string]].index,
140
121
  operation
141
122
  );
142
123
  }
143
124
 
144
125
  clone (): this {
145
126
  const cloned = new ((this as any).constructor);
146
- const metadata = this.constructor[Symbol.metadata];
127
+ const metadata: Metadata = this.constructor[Symbol.metadata];
147
128
 
148
129
  //
149
130
  // TODO: clone all properties, not only annotated ones
150
131
  //
151
132
  // for (const field in this) {
152
- for (const field in metadata) {
133
+ for (const fieldIndex in metadata) {
134
+ // const field = metadata[metadata[fieldIndex]].name;
135
+ const field = metadata[fieldIndex as any as number].name;
136
+
153
137
  if (
154
138
  typeof (this[field]) === "object" &&
155
139
  typeof (this[field]?.clone) === "function"
@@ -162,15 +146,17 @@ export abstract class Schema {
162
146
  cloned[field] = this[field];
163
147
  }
164
148
  }
149
+
165
150
  return cloned;
166
151
  }
167
152
 
168
153
  toJSON () {
169
- const metadata = this.constructor[Symbol.metadata];
170
-
171
154
  const obj: unknown = {};
172
- for (const fieldName in metadata) {
173
- const field = metadata[fieldName];
155
+
156
+ const metadata = this.constructor[Symbol.metadata];
157
+ for (const index in metadata) {
158
+ const field = metadata[index];
159
+ const fieldName = field.name;
174
160
  if (!field.deprecated && this[fieldName] !== null && typeof (this[fieldName]) !== "undefined") {
175
161
  obj[fieldName] = (typeof (this[fieldName]['toJSON']) === "function")
176
162
  ? this[fieldName]['toJSON']()
@@ -185,11 +171,13 @@ export abstract class Schema {
185
171
  }
186
172
 
187
173
  protected [$getByIndex](index: number) {
188
- return this[this.constructor[Symbol.metadata][index]];
174
+ const metadata: Metadata = this.constructor[Symbol.metadata];
175
+ return this[metadata[index].name];
189
176
  }
190
177
 
191
178
  protected [$deleteByIndex](index: number) {
192
- this[this.constructor[Symbol.metadata][index]] = undefined;
179
+ const metadata: Metadata = this.constructor[Symbol.metadata];
180
+ this[metadata[index].name] = undefined;
193
181
  }
194
182
 
195
183
  static debugRefIds(instance: Ref, jsonContents: boolean = true, level: number = 0) {