@colyseus/schema 4.0.20 → 5.0.1

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 (96) hide show
  1. package/README.md +2 -0
  2. package/build/Metadata.d.ts +56 -2
  3. package/build/Reflection.d.ts +28 -34
  4. package/build/Schema.d.ts +70 -9
  5. package/build/annotations.d.ts +64 -17
  6. package/build/codegen/cli.cjs +84 -67
  7. package/build/codegen/cli.cjs.map +1 -1
  8. package/build/decoder/DecodeOperation.d.ts +48 -5
  9. package/build/decoder/Decoder.d.ts +2 -2
  10. package/build/decoder/strategy/Callbacks.d.ts +1 -1
  11. package/build/encoder/ChangeRecorder.d.ts +107 -0
  12. package/build/encoder/ChangeTree.d.ts +218 -69
  13. package/build/encoder/EncodeDescriptor.d.ts +63 -0
  14. package/build/encoder/EncodeOperation.d.ts +25 -2
  15. package/build/encoder/Encoder.d.ts +59 -3
  16. package/build/encoder/MapJournal.d.ts +62 -0
  17. package/build/encoder/RefIdAllocator.d.ts +35 -0
  18. package/build/encoder/Root.d.ts +94 -13
  19. package/build/encoder/StateView.d.ts +116 -8
  20. package/build/encoder/changeTree/inheritedFlags.d.ts +34 -0
  21. package/build/encoder/changeTree/liveIteration.d.ts +3 -0
  22. package/build/encoder/changeTree/parentChain.d.ts +24 -0
  23. package/build/encoder/changeTree/treeAttachment.d.ts +13 -0
  24. package/build/encoder/streaming.d.ts +73 -0
  25. package/build/encoder/subscriptions.d.ts +25 -0
  26. package/build/index.cjs +5258 -1549
  27. package/build/index.cjs.map +1 -1
  28. package/build/index.d.ts +7 -3
  29. package/build/index.js +5258 -1549
  30. package/build/index.mjs +5249 -1549
  31. package/build/index.mjs.map +1 -1
  32. package/build/input/InputDecoder.d.ts +32 -0
  33. package/build/input/InputEncoder.d.ts +117 -0
  34. package/build/input/index.cjs +7453 -0
  35. package/build/input/index.cjs.map +1 -0
  36. package/build/input/index.d.ts +3 -0
  37. package/build/input/index.mjs +7450 -0
  38. package/build/input/index.mjs.map +1 -0
  39. package/build/types/HelperTypes.d.ts +67 -9
  40. package/build/types/TypeContext.d.ts +9 -0
  41. package/build/types/builder.d.ts +192 -0
  42. package/build/types/custom/ArraySchema.d.ts +25 -4
  43. package/build/types/custom/CollectionSchema.d.ts +30 -2
  44. package/build/types/custom/MapSchema.d.ts +52 -3
  45. package/build/types/custom/SetSchema.d.ts +32 -2
  46. package/build/types/custom/StreamSchema.d.ts +114 -0
  47. package/build/types/symbols.d.ts +48 -5
  48. package/package.json +9 -3
  49. package/src/Metadata.ts +259 -31
  50. package/src/Reflection.ts +15 -13
  51. package/src/Schema.ts +176 -134
  52. package/src/annotations.ts +365 -252
  53. package/src/bench_bloat.ts +173 -0
  54. package/src/bench_decode.ts +221 -0
  55. package/src/bench_decode_mem.ts +165 -0
  56. package/src/bench_encode.ts +108 -0
  57. package/src/bench_init.ts +150 -0
  58. package/src/bench_static.ts +109 -0
  59. package/src/bench_stream.ts +295 -0
  60. package/src/bench_view_cmp.ts +142 -0
  61. package/src/codegen/languages/csharp.ts +0 -24
  62. package/src/codegen/parser.ts +83 -61
  63. package/src/decoder/DecodeOperation.ts +168 -63
  64. package/src/decoder/Decoder.ts +20 -10
  65. package/src/decoder/ReferenceTracker.ts +4 -0
  66. package/src/decoder/strategy/Callbacks.ts +30 -26
  67. package/src/decoder/strategy/getDecoderStateCallbacks.ts +16 -13
  68. package/src/encoder/ChangeRecorder.ts +276 -0
  69. package/src/encoder/ChangeTree.ts +674 -519
  70. package/src/encoder/EncodeDescriptor.ts +213 -0
  71. package/src/encoder/EncodeOperation.ts +107 -65
  72. package/src/encoder/Encoder.ts +630 -119
  73. package/src/encoder/MapJournal.ts +124 -0
  74. package/src/encoder/RefIdAllocator.ts +68 -0
  75. package/src/encoder/Root.ts +247 -120
  76. package/src/encoder/StateView.ts +592 -121
  77. package/src/encoder/changeTree/inheritedFlags.ts +217 -0
  78. package/src/encoder/changeTree/liveIteration.ts +74 -0
  79. package/src/encoder/changeTree/parentChain.ts +131 -0
  80. package/src/encoder/changeTree/treeAttachment.ts +171 -0
  81. package/src/encoder/streaming.ts +232 -0
  82. package/src/encoder/subscriptions.ts +71 -0
  83. package/src/index.ts +15 -3
  84. package/src/input/InputDecoder.ts +57 -0
  85. package/src/input/InputEncoder.ts +303 -0
  86. package/src/input/index.ts +3 -0
  87. package/src/types/HelperTypes.ts +121 -24
  88. package/src/types/TypeContext.ts +14 -2
  89. package/src/types/builder.ts +331 -0
  90. package/src/types/custom/ArraySchema.ts +210 -197
  91. package/src/types/custom/CollectionSchema.ts +115 -35
  92. package/src/types/custom/MapSchema.ts +162 -58
  93. package/src/types/custom/SetSchema.ts +128 -39
  94. package/src/types/custom/StreamSchema.ts +310 -0
  95. package/src/types/symbols.ts +93 -6
  96. package/src/utils.ts +4 -6
@@ -213,7 +213,53 @@ function getInheritanceTree(klass, allClasses, includeSelf = true) {
213
213
  let currentStructure;
214
214
  let currentProperty;
215
215
  let globalContext;
216
+ const BUILDER_COLLECTION_KINDS = new Set(["array", "map", "set", "collection"]);
217
+ /**
218
+ * For a t.*().chain().calls() expression, walk down to the base `t.X(...)`
219
+ * call and return its method name and first argument. Returns null if the
220
+ * node does not look like a builder chain.
221
+ */
222
+ function extractBuilderBase(node) {
223
+ let current = node;
224
+ while (true) {
225
+ const expr = current.expression;
226
+ if (!ts__namespace.isPropertyAccessExpression(expr)) {
227
+ return null;
228
+ }
229
+ if (ts__namespace.isCallExpression(expr.expression)) {
230
+ // Chained modifier, e.g. .default() / .view() — walk deeper.
231
+ current = expr.expression;
232
+ continue;
233
+ }
234
+ return {
235
+ methodName: expr.name.text,
236
+ firstArg: current.arguments[0],
237
+ };
238
+ }
239
+ }
216
240
  function defineProperty(property, initializer) {
241
+ // Builder-style: t.number(), t.array(Item), t.map(Item).view(), etc.
242
+ if (ts__namespace.isCallExpression(initializer)) {
243
+ const base = extractBuilderBase(initializer);
244
+ if (base) {
245
+ if (BUILDER_COLLECTION_KINDS.has(base.methodName)) {
246
+ property.type = base.methodName;
247
+ if (base.firstArg) {
248
+ property.childType = base.firstArg.text ?? base.firstArg.getText();
249
+ }
250
+ }
251
+ else if (base.methodName === "ref") {
252
+ property.type = "ref";
253
+ if (base.firstArg) {
254
+ property.childType = base.firstArg.text ?? base.firstArg.getText();
255
+ }
256
+ }
257
+ else {
258
+ property.type = base.methodName;
259
+ }
260
+ return;
261
+ }
262
+ }
217
263
  if (ts__namespace.isIdentifier(initializer)) {
218
264
  property.type = "ref";
219
265
  property.childType = initializer.text;
@@ -377,30 +423,6 @@ function inspectNode(node, context, decoratorName) {
377
423
  defineProperty(property, prop.initializer);
378
424
  }
379
425
  }
380
- else if (node.getText() === "defineTypes" &&
381
- (node.parent.kind === ts__namespace.SyntaxKind.CallExpression ||
382
- node.parent.kind === ts__namespace.SyntaxKind.PropertyAccessExpression)) {
383
- /**
384
- * JavaScript source file (`.js`)
385
- * Using `defineTypes()`
386
- */
387
- const callExpression = (node.parent.kind === ts__namespace.SyntaxKind.PropertyAccessExpression)
388
- ? node.parent.parent
389
- : node.parent;
390
- if (callExpression.kind !== ts__namespace.SyntaxKind.CallExpression) {
391
- break;
392
- }
393
- const className = callExpression.arguments[0].getText();
394
- currentStructure.name = className;
395
- const types = callExpression.arguments[1];
396
- for (let i = 0; i < types.properties.length; i++) {
397
- const prop = types.properties[i];
398
- const property = currentProperty || new Property();
399
- property.name = prop.name.escapedText;
400
- currentStructure.addProperty(property);
401
- defineProperty(property, prop.initializer);
402
- }
403
- }
404
426
  if (node.parent.kind === ts__namespace.SyntaxKind.ClassDeclaration) {
405
427
  currentStructure.name = node.getText();
406
428
  }
@@ -408,45 +430,63 @@ function inspectNode(node, context, decoratorName) {
408
430
  break;
409
431
  case ts__namespace.SyntaxKind.CallExpression:
410
432
  /**
411
- * Defining schema via `schema.schema({ ... })`
412
- * - schema.schema({})
413
- * - schema({})
414
- * - ClassName.extends({})
433
+ * Defining schema via:
434
+ * - schema({ ... })
435
+ * - schema({ ... }, 'Name')
436
+ * - schema.schema({ ... }, 'Name')
437
+ * - ParentClass.extend({ ... }, 'Name')
415
438
  */
416
- if (((node.expression?.getText() === "schema.schema" ||
417
- node.expression?.getText() === "schema") ||
418
- (node.expression?.getText().indexOf(".extends") !== -1)) &&
419
- node.arguments[0].kind === ts__namespace.SyntaxKind.ObjectLiteralExpression) {
439
+ {
420
440
  const callExpression = node;
421
- let className = callExpression.arguments[1]?.getText();
441
+ const callee = callExpression.expression?.getText?.();
442
+ if (!callee)
443
+ break;
444
+ const isSchemaCall = callee === "schema" || callee === "schema.schema";
445
+ const isExtendCall = callee.indexOf(".extend") !== -1 && !callee.endsWith(".extends");
446
+ if (!isSchemaCall && !isExtendCall)
447
+ break;
448
+ // Signature: (fields, name?)
449
+ const fieldsArg = callExpression.arguments[0];
450
+ const nameArg = callExpression.arguments[1];
451
+ if (!fieldsArg || fieldsArg.kind !== ts__namespace.SyntaxKind.ObjectLiteralExpression) {
452
+ break;
453
+ }
454
+ let className;
455
+ if (nameArg) {
456
+ if (nameArg.kind === ts__namespace.SyntaxKind.StringLiteral) {
457
+ className = nameArg.text;
458
+ }
459
+ else {
460
+ className = nameArg.getText();
461
+ }
462
+ }
422
463
  if (!className && callExpression.parent.kind === ts__namespace.SyntaxKind.VariableDeclaration) {
423
464
  className = callExpression.parent.name?.getText();
424
465
  }
425
- // skip if no className is provided
426
- if (!className) {
466
+ if (!className)
427
467
  break;
428
- }
429
468
  if (currentStructure?.name !== className) {
430
469
  currentStructure = new Class();
431
470
  context.addStructure(currentStructure);
432
471
  }
433
- if (node.expression?.getText().indexOf(".extends") !== -1) {
434
- // if it's using `.extends({})`
472
+ if (isExtendCall) {
435
473
  const extendsClass = node.expression?.expression?.escapedText;
436
- // skip if no extendsClass is provided
437
- if (!extendsClass) {
474
+ if (!extendsClass)
438
475
  break;
439
- }
440
476
  currentStructure.extends = extendsClass;
441
477
  }
442
478
  else {
443
- // if it's using `schema({})`
444
- currentStructure.extends = "Schema"; // force extends to Schema
479
+ currentStructure.extends = "Schema";
445
480
  }
446
481
  currentStructure.name = className;
447
- const types = callExpression.arguments[0];
482
+ const types = fieldsArg;
448
483
  for (let i = 0; i < types.properties.length; i++) {
449
484
  const prop = types.properties[i];
485
+ // Skip methods declared inside the fields object.
486
+ if (prop.kind === ts__namespace.SyntaxKind.MethodDeclaration)
487
+ continue;
488
+ if (!prop.initializer)
489
+ continue;
450
490
  const property = currentProperty || new Property();
451
491
  property.name = prop.name.escapedText;
452
492
  currentStructure.addProperty(property);
@@ -643,33 +683,10 @@ ${generateClassBody$8(klass, indent)}
643
683
  ${namespace ? "}" : ""}
644
684
  `;
645
685
  }
646
- /**
647
- * Check if all enum members resolve to non-negative integers,
648
- * allowing emission as a native C# `enum` (which only supports integral types).
649
- */
650
- function canUseNativeEnum(_enum) {
651
- return _enum.properties.every((prop) => {
652
- if (!prop.type)
653
- return true;
654
- const n = Number(prop.type);
655
- return Number.isInteger(n) && n >= 0;
656
- });
657
- }
658
686
  /**
659
687
  * Generate just the enum body (without imports/namespace) for bundling
660
688
  */
661
689
  function generateEnumBody$1(_enum, indent = "") {
662
- if (canUseNativeEnum(_enum)) {
663
- const members = _enum.properties
664
- .map((prop, i) => {
665
- const value = prop.type ? Number(prop.type) : i;
666
- return `${indent}\t${prop.name} = ${value},`;
667
- })
668
- .join("\n");
669
- return `${indent}public enum ${_enum.name} : int {
670
- ${members}
671
- ${indent}}`;
672
- }
673
690
  return `${indent}public struct ${_enum.name} {
674
691
 
675
692
  ${_enum.properties