@colyseus/core 0.18.17 → 0.18.18

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.
package/build/Room.cjs CHANGED
@@ -69,6 +69,7 @@ var NOOP = () => {
69
69
  };
70
70
  var noneSerializer = new import_NoneSerializer.NoneSerializer();
71
71
  var AFTER_PATCH_OPTS = Object.freeze({ afterNextPatch: true });
72
+ var ROOM_ACCESSORS = ["state", "maxClients", "autoDispose", "patchRate", "unreliablePatchRate"];
72
73
  var DEFAULT_SEAT_RESERVATION_TIME = Number(process.env.COLYSEUS_SEAT_RESERVATION_TIME || 15);
73
74
  function validate(format, handler) {
74
75
  return { format, handler };
@@ -86,53 +87,10 @@ var Room = class _Room {
86
87
  */
87
88
  this.clock = new import_timer.ClockTimer();
88
89
  this.#_onLeaveConcurrent = 0;
89
- // number of onLeave calls in progress
90
- /**
91
- * Maximum number of clients allowed to connect into the room. When room reaches this limit,
92
- * it is locked automatically. Unless the room was explicitly locked by you via `lock()` method,
93
- * the room will be unlocked as soon as a client disconnects from it.
94
- */
95
- this.maxClients = Infinity;
96
90
  this.#_maxClientsReached = false;
97
- /**
98
- * Automatically dispose the room when last client disconnects.
99
- *
100
- * @default true
101
- */
102
- this.autoDispose = true;
103
- /**
104
- * Frequency to send the room state to connected clients, in milliseconds.
105
- *
106
- * @default 50ms (20fps)
107
- */
108
- this.patchRate = DEFAULT_PATCH_RATE;
109
- /**
110
- * Frequency to flush `@unreliable` state fields, in milliseconds.
111
- *
112
- * Those fields never ride a state patch — they go out over the transport's
113
- * unreliable channel (a WebTransport datagram), so a dropped frame costs one
114
- * stale value instead of stalling the reliable stream behind a retransmit.
115
- * Setting this decouples them from {@link patchRate}, which is the point:
116
- * 60Hz movement over a 20Hz structural patch.
117
- *
118
- * KNOWN COST of a rate faster than {@link patchRate}: an entity's ADD travels
119
- * the reliable channel, so datagrams sent between patches can reference a
120
- * refId the client hasn't been told about yet. Those frames are skipped by the
121
- * client's decoder — safe (the ref graph can't desync, since `@unreliable` is
122
- * primitives-only) but each one logs `"refId" not found`, and that entity's
123
- * first value lands one mutation later. Measured at `patchRate/this` reports
124
- * per mid-session spawn. Leave this unset and the flush rides
125
- * {@link broadcastPatch}, which ships the ADD first and avoids it entirely.
126
- *
127
- * Requires a transport with a datagram channel — today only
128
- * `@colyseus/h3-transport` (WebTransport), which is **experimental**. Every
129
- * WebSocket transport lacks one, and those clients are skipped entirely (the
130
- * room warns once), so `@unreliable` fields keep their join-time value there.
131
- *
132
- * @default null — flush alongside every {@link broadcastPatch}, and only when
133
- * the state actually declares an `@unreliable` field.
134
- */
135
- this.unreliablePatchRate = null;
91
+ this.#_maxClients = Infinity;
92
+ this.#_autoDispose = true;
93
+ this.#_patchRate = DEFAULT_PATCH_RATE;
136
94
  this.#_unreliablePatchRate = null;
137
95
  /**
138
96
  * The unreliable flush, called unconditionally at the end of every
@@ -149,6 +107,8 @@ var Room = class _Room {
149
107
  * @default Infinity
150
108
  */
151
109
  this.maxMessagesPerSecond = Infinity;
110
+ /** Until `__init()`, the prototype accessor setters only store the value. */
111
+ this.#_ready = false;
152
112
  /**
153
113
  * The array of connected clients.
154
114
  *
@@ -239,6 +199,7 @@ var Room = class _Room {
239
199
  #_unreliablePatchRate;
240
200
  #_unreliablePatchInterval;
241
201
  #_state;
202
+ #_ready;
242
203
  #_messages;
243
204
  // Re-expose the registry for @colyseus/playground introspection and
244
205
  // @colyseus/testing handler-swapping (both reach in via bracket access).
@@ -251,21 +212,19 @@ var Room = class _Room {
251
212
  #pendingFrameClients;
252
213
  #afterPatchBroadcasts;
253
214
  #_locked;
254
- /**
255
- * This method is called by the MatchMaker before onCreate()
256
- * @internal
257
- */
258
- __init() {
259
- this.#_state = this.state;
260
- this.#_autoDispose = this.autoDispose;
261
- this.#_patchRate = this.patchRate;
262
- this.#_unreliablePatchRate = this.unreliablePatchRate;
263
- this.#_maxClients = this.maxClients;
264
- Object.defineProperties(this, {
215
+ static {
216
+ Object.defineProperties(this.prototype, {
265
217
  state: {
266
218
  enumerable: true,
267
- get: () => this.#_state,
268
- set: (newState) => {
219
+ configurable: true,
220
+ get() {
221
+ return this.#_state;
222
+ },
223
+ set(newState) {
224
+ if (!this.#_ready) {
225
+ this.#_state = newState;
226
+ return;
227
+ }
269
228
  if (newState?.constructor[Symbol.metadata] !== void 0 || newState[import_schema.$changes] !== void 0) {
270
229
  this.setSerializer(new import_SchemaSerializer.SchemaSerializer());
271
230
  } else if ("_definition" in newState) {
@@ -280,15 +239,29 @@ var Room = class _Room {
280
239
  },
281
240
  maxClients: {
282
241
  enumerable: true,
283
- get: () => this.#_maxClients,
284
- set: (value) => {
242
+ configurable: true,
243
+ get() {
244
+ return this.#_maxClients;
245
+ },
246
+ set(value) {
247
+ if (!this.#_ready) {
248
+ this.#_maxClients = value;
249
+ return;
250
+ }
285
251
  this.setMatchmaking({ maxClients: value });
286
252
  }
287
253
  },
288
254
  autoDispose: {
289
255
  enumerable: true,
290
- get: () => this.#_autoDispose,
291
- set: (value) => {
256
+ configurable: true,
257
+ get() {
258
+ return this.#_autoDispose;
259
+ },
260
+ set(value) {
261
+ if (!this.#_ready) {
262
+ this.#_autoDispose = value;
263
+ return;
264
+ }
292
265
  if (value !== this.#_autoDispose && this._internalState !== RoomInternalState.DISPOSING) {
293
266
  this.#_autoDispose = value;
294
267
  this.resetAutoDisposeTimeout();
@@ -297,9 +270,15 @@ var Room = class _Room {
297
270
  },
298
271
  patchRate: {
299
272
  enumerable: true,
300
- get: () => this.#_patchRate,
301
- set: (milliseconds) => {
273
+ configurable: true,
274
+ get() {
275
+ return this.#_patchRate;
276
+ },
277
+ set(milliseconds) {
302
278
  this.#_patchRate = milliseconds;
279
+ if (!this.#_ready) {
280
+ return;
281
+ }
303
282
  if (this.#_patchInterval) {
304
283
  clearInterval(this.#_patchInterval);
305
284
  this.#_patchInterval = void 0;
@@ -313,13 +292,35 @@ var Room = class _Room {
313
292
  },
314
293
  unreliablePatchRate: {
315
294
  enumerable: true,
316
- get: () => this.#_unreliablePatchRate,
317
- set: (milliseconds) => {
295
+ configurable: true,
296
+ get() {
297
+ return this.#_unreliablePatchRate;
298
+ },
299
+ set(milliseconds) {
318
300
  this.#_unreliablePatchRate = milliseconds;
301
+ if (!this.#_ready) {
302
+ return;
303
+ }
319
304
  this._armUnreliablePatches();
320
305
  }
321
306
  }
322
307
  });
308
+ }
309
+ /**
310
+ * This method is called by the MatchMaker before onCreate()
311
+ * @internal
312
+ */
313
+ __init() {
314
+ for (let i = 0; i < ROOM_ACCESSORS.length; i++) {
315
+ const key = ROOM_ACCESSORS[i];
316
+ if (!Object.hasOwn(this, key)) {
317
+ continue;
318
+ }
319
+ const value = this[key];
320
+ Object.defineProperty(this, key, Object.getOwnPropertyDescriptor(_Room.prototype, key));
321
+ this[key] = value;
322
+ }
323
+ this.#_ready = true;
323
324
  this.patchRate = this.#_patchRate;
324
325
  if (this.#_state) {
325
326
  this.state = this.#_state;
@@ -1453,7 +1454,7 @@ var Room = class _Room {
1453
1454
  if (client._enqueuedMessages.length > 0) {
1454
1455
  client._enqueuedMessages.forEach((enqueued) => client.raw(enqueued));
1455
1456
  }
1456
- delete client._enqueuedMessages;
1457
+ client._enqueuedMessages = void 0;
1457
1458
  } else if (code === import_shared_types.Protocol.PING) {
1458
1459
  client.raw(import_Protocol.getMessageBytes[import_shared_types.Protocol.PING]());
1459
1460
  } else if (code === import_shared_types.Protocol.LEAVE_ROOM) {