@colyseus/schema 5.0.5 → 5.0.8

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 (69) hide show
  1. package/build/Reflection.d.ts +53 -0
  2. package/build/Schema.d.ts +26 -1
  3. package/build/annotations.d.ts +8 -1
  4. package/build/codegen/cli.cjs +74 -64
  5. package/build/codegen/cli.cjs.map +1 -1
  6. package/build/codegen/types.d.ts +0 -1
  7. package/build/decoder/Decoder.d.ts +28 -0
  8. package/build/decoder/Resync.d.ts +61 -0
  9. package/build/encoder/ChangeTree.d.ts +15 -0
  10. package/build/encoder/Encoder.d.ts +13 -0
  11. package/build/encoder/Pool.d.ts +62 -0
  12. package/build/encoder/Root.d.ts +5 -4
  13. package/build/encoder/StateView.d.ts +12 -3
  14. package/build/index.cjs +1192 -284
  15. package/build/index.cjs.map +1 -1
  16. package/build/index.d.ts +4 -1
  17. package/build/index.js +1192 -284
  18. package/build/index.mjs +1189 -285
  19. package/build/index.mjs.map +1 -1
  20. package/build/input/InputDecoder.d.ts +9 -4
  21. package/build/input/InputEncoder.d.ts +44 -53
  22. package/build/input/index.cjs +102 -7321
  23. package/build/input/index.cjs.map +1 -1
  24. package/build/input/index.mjs +97 -7316
  25. package/build/input/index.mjs.map +1 -1
  26. package/build/types/HelperTypes.d.ts +25 -0
  27. package/build/types/builder.d.ts +57 -4
  28. package/build/types/custom/ArraySchema.d.ts +11 -1
  29. package/build/types/custom/CollectionSchema.d.ts +9 -1
  30. package/build/types/custom/MapSchema.d.ts +9 -1
  31. package/build/types/custom/SetSchema.d.ts +9 -1
  32. package/build/types/custom/StreamSchema.d.ts +2 -1
  33. package/build/types/quantize.d.ts +102 -0
  34. package/build/types/symbols.d.ts +15 -0
  35. package/package.json +8 -1
  36. package/src/Metadata.ts +34 -9
  37. package/src/Reflection.ts +49 -11
  38. package/src/Schema.ts +64 -2
  39. package/src/annotations.ts +133 -51
  40. package/src/bench_churn.ts +121 -0
  41. package/src/codegen/languages/haxe.ts +0 -16
  42. package/src/codegen/parser.ts +29 -11
  43. package/src/codegen/types.ts +45 -63
  44. package/src/decoder/DecodeOperation.ts +46 -4
  45. package/src/decoder/Decoder.ts +48 -0
  46. package/src/decoder/ReferenceTracker.ts +9 -5
  47. package/src/decoder/Resync.ts +170 -0
  48. package/src/encoder/ChangeTree.ts +59 -0
  49. package/src/encoder/Encoder.ts +53 -12
  50. package/src/encoder/Pool.ts +90 -0
  51. package/src/encoder/Root.ts +22 -32
  52. package/src/encoder/StateView.ts +101 -50
  53. package/src/encoder/changeTree/liveIteration.ts +4 -0
  54. package/src/encoder/changeTree/treeAttachment.ts +28 -24
  55. package/src/index.ts +12 -2
  56. package/src/input/InputDecoder.ts +11 -5
  57. package/src/input/InputEncoder.ts +85 -126
  58. package/src/types/HelperTypes.ts +30 -0
  59. package/src/types/TypeContext.ts +7 -0
  60. package/src/types/builder.ts +62 -5
  61. package/src/types/custom/ArraySchema.ts +70 -12
  62. package/src/types/custom/CollectionSchema.ts +36 -1
  63. package/src/types/custom/MapSchema.ts +50 -1
  64. package/src/types/custom/SetSchema.ts +36 -1
  65. package/src/types/custom/StreamSchema.ts +7 -0
  66. package/src/types/quantize.ts +173 -0
  67. package/src/types/symbols.ts +16 -0
  68. package/build/encoder/RefIdAllocator.d.ts +0 -35
  69. package/src/encoder/RefIdAllocator.ts +0 -68
@@ -22,11 +22,16 @@ export declare class InputDecoder<T extends Schema = any> {
22
22
  /**
23
23
  * Walk a multi-input (unreliable) packet, decoding each length-framed
24
24
  * input into the bound instance in order and invoking `onInput` after
25
- * each decode. `onInput` receives the bound instance itself reads
26
- * must be synchronous; downstream code should apply the input to game
27
- * state, not retain the reference.
25
+ * each decode. `onInput` receives the bound instance and the framework
26
+ * **seq** of that input (decoded from the packet's base seq + position) —
27
+ * the receiver dedupes the redundancy ring on it (monotonic: drop seq ≤
28
+ * last seen). Reads of the instance must be synchronous; downstream code
29
+ * should apply the input to game state, not retain the reference.
30
+ *
31
+ * Packet layout: `[baseSeq][len][body]…[len][body]` (oldest→newest);
32
+ * slot *i* has `seq = baseSeq + i`.
28
33
  *
29
34
  * Returns the number of inputs decoded.
30
35
  */
31
- decodeAll(bytes: Uint8Array, onInput: (instance: T, index: number) => void): number;
36
+ decodeAll(bytes: Uint8Array, onInput: (instance: T, seq: number) => void): number;
32
37
  }
@@ -18,45 +18,28 @@ export interface InputEncoderOptions {
18
18
  * reliable mode (always exactly one input per packet).
19
19
  */
20
20
  historySize?: number;
21
- /**
22
- * When `true`, `encode()` emits only fields that changed since the
23
- * previous call. First call (or first after `reset()`) still emits
24
- * a full snapshot since there's no baseline to diff against.
25
- *
26
- * **Reliable mode:** returns an empty `Uint8Array` when nothing
27
- * changed — caller can skip sending.
28
- *
29
- * **Unreliable mode:** no-change ticks don't push a new ring slot
30
- * (avoids bloating the ring with empties); the existing ring is
31
- * still re-emitted for redundancy. Wire ops use absolute values so
32
- * cross-packet re-application is per-field idempotent.
33
- *
34
- * Decoder side is unchanged in either case: `(index|ADD)` wire ops
35
- * apply to the bound instance; fields absent from a packet stay at
36
- * their previously decoded value.
37
- */
38
- delta?: boolean;
39
- /**
40
- * Override the reliable-mode output buffer. Default: 256 bytes,
41
- * auto-grown on overflow.
42
- */
43
- buffer?: Uint8Array;
44
21
  }
45
22
  /**
46
23
  * Bound single-struct encoder for client→server input packets. Holds a
47
24
  * reference to a Schema instance and produces wire-compatible bytes.
48
25
  *
49
- * **Reliable mode** emits one snapshot per `encode()`. The bytes decode
50
- * cleanly through the standard {@link Decoder}.
26
+ * Always delta-encodes: each `encode()` emits only the fields that changed
27
+ * since the previous call (via the setter-populated ChangeTree dirty set),
28
+ * wrapping a standard {@link Encoder}. The first call (or first after
29
+ * {@link reset}) emits a full snapshot, since there's no baseline to diff
30
+ * against.
51
31
  *
52
- * **Unreliable mode** pushes each snapshot onto a ring buffer of size
53
- * `historySize` and emits the last N snapshots in one packet, each
54
- * framed with a varint length prefix. Use {@link InputDecoder.decodeAll}
55
- * to walk the framed packet on the receiving end.
32
+ * **Reliable mode** emits one delta per `encode()` or an empty
33
+ * `Uint8Array` when nothing changed (the caller decides whether to send a
34
+ * body-less keep-alive or skip the tick). The bytes decode cleanly through
35
+ * the standard {@link Decoder}.
56
36
  *
57
- * **Delta** (`delta: true`, any mode) wraps a standard {@link Encoder}
58
- * and emits only fields that changed since the last call, via the
59
- * setter-populated ChangeTree dirty set.
37
+ * **Unreliable mode** pushes each delta onto a ring buffer of size
38
+ * `historySize` and emits the last N in one packet, each framed with a
39
+ * varint length prefix. A no-change tick still pushes an (empty,
40
+ * carry-forward) slot so every tick gets a consecutive framework seq. Use
41
+ * {@link InputDecoder.decodeAll} to walk the framed packet. Wire ops use
42
+ * absolute values, so re-applying a redundant slot is per-field idempotent.
60
43
  *
61
44
  * Flat primitive fields only. Nested Schema / collection fields throw
62
45
  * at construction.
@@ -65,31 +48,33 @@ export declare class InputEncoder<T extends Schema = any> {
65
48
  readonly instance: T;
66
49
  readonly mode: InputMode;
67
50
  readonly historySize: number;
68
- readonly delta: boolean;
69
51
  private readonly _desc;
70
52
  private readonly _numFields;
71
- private _buffer;
72
- private readonly _it;
73
53
  private _slots?;
74
54
  private readonly _slotLens?;
75
55
  private _slotHead;
76
56
  private _slotCount;
77
57
  private _outBuffer?;
78
- private readonly _encoder?;
58
+ private _seq;
59
+ private readonly _encoder;
79
60
  constructor(instance: T, options?: InputEncoderOptions);
80
61
  /**
81
- * Encode the bound instance. Returns a subarray of an internal
62
+ * The framework input seq of the most recently encoded tick (unreliable
63
+ * mode): monotonic, ++ per `encode()`, kept across {@link reset}. `0` in
64
+ * reliable mode (which sequences inputs implicitly by message count). The
65
+ * client keys its reconciliation replay ring by this so the server's
66
+ * seq-value ack lines up across packet loss.
67
+ */
68
+ get seq(): number;
69
+ /**
70
+ * Encode the bound instance's delta. Returns a subarray of an internal
82
71
  * buffer — copy if retaining across calls.
83
72
  *
84
- * Output shape by configuration:
85
- * - `reliable` + full: one snapshot's worth of bytes.
86
- * - `reliable` + delta: only changed fields, or empty when nothing
87
- * changed.
88
- * - `unreliable` + full: ring of last `historySize` snapshots,
89
- * length-framed per slot.
90
- * - `unreliable` + delta: ring of last `historySize` deltas. No-
91
- * change ticks don't push a new slot but still re-emit the ring.
92
- * Empty only until the first change has been pushed.
73
+ * Output shape by mode:
74
+ * - `reliable`: only changed fields, or empty when nothing changed.
75
+ * - `unreliable`: ring of the last `historySize` deltas, length-framed
76
+ * per slot. A no-change tick pushes an empty (carry-forward) slot but
77
+ * still re-emits the ring. Empty only until the first slot is pushed.
93
78
  *
94
79
  * Buffers auto-grow on overflow; a one-time `console.warn` is
95
80
  * emitted the first time it happens.
@@ -97,19 +82,25 @@ export declare class InputEncoder<T extends Schema = any> {
97
82
  encode(): Uint8Array;
98
83
  /**
99
84
  * Reset the encoder's internal state:
100
- * - Unreliable mode: drops the ring buffer.
101
- * - Delta mode: re-marks every currently populated field as dirty,
102
- * so the next `encode()` emits a fresh full snapshot.
85
+ * - Drops the unreliable ring buffer.
86
+ * - Re-marks every currently populated field as dirty, so the next
87
+ * `encode()` emits a fresh full snapshot.
103
88
  *
104
89
  * Useful on disconnect / reconnect / scene transitions.
105
90
  */
106
91
  reset(): void;
107
- /** Write every populated primitive field into `_buffer`. */
108
- private _produceFull;
92
+ /**
93
+ * Copy the bound instance's field values into `target` (a same-type instance)
94
+ * in place — no allocation, no `Object.keys` (cf. `Schema#assign`) and no
95
+ * `clone()`. For buffering a snapshot of the just-sent input into a reused
96
+ * slot (e.g. a client reconciliation/replay ring) without the transport
97
+ * having to reach into schema internals. The codec owns this because it owns
98
+ * the field representation. The in-place / alloc-free cousin of `clone()`,
99
+ * and the inverse direction of `Schema#assign(source)`.
100
+ */
101
+ copyInto(target: T): void;
109
102
  /** Delegate to the wrapped Encoder, then clear its dirty set. */
110
103
  private _produceDelta;
111
- /** Emit every populated field as `(index|ADD)` + value. */
112
- private _writeFields;
113
104
  private _pushAndEmitRing;
114
105
  private _emitRing;
115
106
  private static _warned;