@colyseus/sdk 0.17.0

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 (133) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +27 -0
  3. package/build/cjs/3rd_party/discord.js +56 -0
  4. package/build/cjs/3rd_party/discord.js.map +1 -0
  5. package/build/cjs/Auth.js +156 -0
  6. package/build/cjs/Auth.js.map +1 -0
  7. package/build/cjs/Client.js +282 -0
  8. package/build/cjs/Client.js.map +1 -0
  9. package/build/cjs/Connection.js +48 -0
  10. package/build/cjs/Connection.js.map +1 -0
  11. package/build/cjs/HTTP.js +156 -0
  12. package/build/cjs/HTTP.js.map +1 -0
  13. package/build/cjs/Protocol.js +34 -0
  14. package/build/cjs/Protocol.js.map +1 -0
  15. package/build/cjs/Room.js +357 -0
  16. package/build/cjs/Room.js.map +1 -0
  17. package/build/cjs/Storage.js +98 -0
  18. package/build/cjs/Storage.js.map +1 -0
  19. package/build/cjs/core/nanoevents.js +50 -0
  20. package/build/cjs/core/nanoevents.js.map +1 -0
  21. package/build/cjs/core/signal.js +53 -0
  22. package/build/cjs/core/signal.js.map +1 -0
  23. package/build/cjs/core/utils.js +14 -0
  24. package/build/cjs/core/utils.js.map +1 -0
  25. package/build/cjs/errors/Errors.js +29 -0
  26. package/build/cjs/errors/Errors.js.map +1 -0
  27. package/build/cjs/index.js +43 -0
  28. package/build/cjs/index.js.map +1 -0
  29. package/build/cjs/legacy.js +34 -0
  30. package/build/cjs/legacy.js.map +1 -0
  31. package/build/cjs/serializer/NoneSerializer.js +18 -0
  32. package/build/cjs/serializer/NoneSerializer.js.map +1 -0
  33. package/build/cjs/serializer/SchemaSerializer.js +61 -0
  34. package/build/cjs/serializer/SchemaSerializer.js.map +1 -0
  35. package/build/cjs/serializer/Serializer.js +23 -0
  36. package/build/cjs/serializer/Serializer.js.map +1 -0
  37. package/build/cjs/transport/H3Transport.js +171 -0
  38. package/build/cjs/transport/H3Transport.js.map +1 -0
  39. package/build/cjs/transport/WebSocketTransport.js +50 -0
  40. package/build/cjs/transport/WebSocketTransport.js.map +1 -0
  41. package/build/esm/3rd_party/discord.mjs +53 -0
  42. package/build/esm/3rd_party/discord.mjs.map +1 -0
  43. package/build/esm/Auth.mjs +137 -0
  44. package/build/esm/Auth.mjs.map +1 -0
  45. package/build/esm/Client.mjs +272 -0
  46. package/build/esm/Client.mjs.map +1 -0
  47. package/build/esm/Connection.mjs +49 -0
  48. package/build/esm/Connection.mjs.map +1 -0
  49. package/build/esm/HTTP.mjs +159 -0
  50. package/build/esm/HTTP.mjs.map +1 -0
  51. package/build/esm/Protocol.mjs +34 -0
  52. package/build/esm/Protocol.mjs.map +1 -0
  53. package/build/esm/Room.mjs +355 -0
  54. package/build/esm/Room.mjs.map +1 -0
  55. package/build/esm/Storage.mjs +86 -0
  56. package/build/esm/Storage.mjs.map +1 -0
  57. package/build/esm/core/nanoevents.mjs +46 -0
  58. package/build/esm/core/nanoevents.mjs.map +1 -0
  59. package/build/esm/core/signal.mjs +48 -0
  60. package/build/esm/core/signal.mjs.map +1 -0
  61. package/build/esm/core/utils.mjs +12 -0
  62. package/build/esm/core/utils.mjs.map +1 -0
  63. package/build/esm/errors/Errors.mjs +28 -0
  64. package/build/esm/errors/Errors.mjs.map +1 -0
  65. package/build/esm/index.mjs +22 -0
  66. package/build/esm/index.mjs.map +1 -0
  67. package/build/esm/legacy.mjs +32 -0
  68. package/build/esm/legacy.mjs.map +1 -0
  69. package/build/esm/serializer/NoneSerializer.mjs +16 -0
  70. package/build/esm/serializer/NoneSerializer.mjs.map +1 -0
  71. package/build/esm/serializer/SchemaSerializer.mjs +60 -0
  72. package/build/esm/serializer/SchemaSerializer.mjs.map +1 -0
  73. package/build/esm/serializer/Serializer.mjs +20 -0
  74. package/build/esm/serializer/Serializer.mjs.map +1 -0
  75. package/build/esm/transport/H3Transport.mjs +170 -0
  76. package/build/esm/transport/H3Transport.mjs.map +1 -0
  77. package/build/esm/transport/WebSocketTransport.mjs +51 -0
  78. package/build/esm/transport/WebSocketTransport.mjs.map +1 -0
  79. package/dist/colyseus-cocos-creator.js +9538 -0
  80. package/dist/colyseus-cocos-creator.js.map +1 -0
  81. package/dist/colyseus.js +9537 -0
  82. package/dist/colyseus.js.map +1 -0
  83. package/dist/debug.js +2460 -0
  84. package/dist/debug.js.map +1 -0
  85. package/lib/3rd_party/discord.d.ts +33 -0
  86. package/lib/Auth.d.ts +31 -0
  87. package/lib/Client.d.ts +92 -0
  88. package/lib/Connection.d.ts +17 -0
  89. package/lib/HTTP.d.ts +113 -0
  90. package/lib/HTTP_bkp.d.ts +18 -0
  91. package/lib/Protocol.d.ts +21 -0
  92. package/lib/Room.d.ts +140 -0
  93. package/lib/Storage.d.ts +3 -0
  94. package/lib/core/http_bkp.d.ts +319 -0
  95. package/lib/core/nanoevents.d.ts +27 -0
  96. package/lib/core/signal.d.ts +17 -0
  97. package/lib/core/utils.d.ts +1 -0
  98. package/lib/debug.d.ts +1 -0
  99. package/lib/errors/Errors.d.ts +17 -0
  100. package/lib/index.d.ts +9 -0
  101. package/lib/legacy.d.ts +0 -0
  102. package/lib/serializer/FossilDeltaSerializer.d.ts +0 -0
  103. package/lib/serializer/NoneSerializer.d.ts +8 -0
  104. package/lib/serializer/SchemaSerializer.d.ts +14 -0
  105. package/lib/serializer/Serializer.d.ts +10 -0
  106. package/lib/src/3rd_party/discord.d.ts +33 -0
  107. package/lib/src/Auth.d.ts +31 -0
  108. package/lib/src/Client.d.ts +62 -0
  109. package/lib/src/Connection.d.ts +17 -0
  110. package/lib/src/HTTP.d.ts +113 -0
  111. package/lib/src/HTTP_bkp.d.ts +18 -0
  112. package/lib/src/Protocol.d.ts +28 -0
  113. package/lib/src/Room.d.ts +132 -0
  114. package/lib/src/Storage.d.ts +3 -0
  115. package/lib/src/core/http_bkp.d.ts +319 -0
  116. package/lib/src/core/nanoevents.d.ts +27 -0
  117. package/lib/src/core/signal.d.ts +17 -0
  118. package/lib/src/debug.d.ts +1 -0
  119. package/lib/src/errors/Errors.d.ts +15 -0
  120. package/lib/src/index.d.ts +9 -0
  121. package/lib/src/legacy.d.ts +0 -0
  122. package/lib/src/serializer/FossilDeltaSerializer.d.ts +0 -0
  123. package/lib/src/serializer/NoneSerializer.d.ts +8 -0
  124. package/lib/src/serializer/SchemaSerializer.d.ts +14 -0
  125. package/lib/src/serializer/Serializer.d.ts +11 -0
  126. package/lib/src/transport/H3Transport.d.ts +20 -0
  127. package/lib/src/transport/ITransport.d.ts +16 -0
  128. package/lib/src/transport/WebSocketTransport.d.ts +17 -0
  129. package/lib/transport/H3Transport.d.ts +20 -0
  130. package/lib/transport/ITransport.d.ts +16 -0
  131. package/lib/transport/WebSocketTransport.d.ts +17 -0
  132. package/lib/tsconfig.tsbuildinfo +1 -0
  133. package/package.json +108 -0
@@ -0,0 +1,357 @@
1
+ // Copyright (c) 2026 Endel Dreyer.
2
+ //
3
+ // This software is released under the MIT License.
4
+ // https://opensource.org/license/MIT
5
+ //
6
+ // colyseus.js@0.17.0
7
+ 'use strict';
8
+
9
+ var tslib = require('tslib');
10
+ var schema = require('@colyseus/schema');
11
+ var msgpackr = require('@colyseus/msgpackr');
12
+ var Connection = require('./Connection.js');
13
+ var Protocol = require('./Protocol.js');
14
+ var Serializer = require('./serializer/Serializer.js');
15
+ var nanoevents = require('./core/nanoevents.js');
16
+ var signal = require('./core/signal.js');
17
+ var SchemaSerializer = require('./serializer/SchemaSerializer.js');
18
+ var Errors = require('./errors/Errors.js');
19
+ var utils = require('./core/utils.js');
20
+
21
+ var _Room_lastPingTime, _Room_pingCallback;
22
+ class Room {
23
+ constructor(name, rootSchema) {
24
+ // Public signals
25
+ this.onStateChange = signal.createSignal();
26
+ this.onError = signal.createSignal();
27
+ this.onLeave = signal.createSignal();
28
+ this.onReconnect = signal.createSignal();
29
+ this.onDrop = signal.createSignal();
30
+ this.onJoin = signal.createSignal();
31
+ // reconnection logic
32
+ this.reconnection = {
33
+ retryCount: 0,
34
+ maxRetries: 8,
35
+ delay: 100,
36
+ minDelay: 100,
37
+ maxDelay: 5000,
38
+ minUptime: 5000,
39
+ backoff: exponentialBackoff,
40
+ maxEnqueuedMessages: 10,
41
+ enqueuedMessages: [],
42
+ isReconnecting: false,
43
+ };
44
+ this.joinedAtTime = 0;
45
+ this.onMessageHandlers = nanoevents.createNanoEvents();
46
+ _Room_lastPingTime.set(this, 0);
47
+ _Room_pingCallback.set(this, void 0);
48
+ this.name = name;
49
+ this.packr = new msgpackr.Packr();
50
+ // msgpackr workaround: force buffer to be created.
51
+ this.packr.encode(undefined);
52
+ if (rootSchema) {
53
+ this.serializer = new (Serializer.getSerializer("schema"));
54
+ this.serializer.state = new rootSchema();
55
+ }
56
+ this.onError((code, message) => { var _a; return (_a = console.warn) === null || _a === void 0 ? void 0 : _a.call(console, `colyseus.js - onError => (${code}) ${message}`); });
57
+ this.onLeave(() => this.removeAllListeners());
58
+ }
59
+ connect(endpoint, options, headers) {
60
+ var _a;
61
+ this.connection = new Connection.Connection(options.protocol);
62
+ this.connection.events.onmessage = this.onMessageCallback.bind(this);
63
+ this.connection.events.onclose = (e) => {
64
+ var _a;
65
+ if (this.joinedAtTime === 0) {
66
+ (_a = console.warn) === null || _a === void 0 ? void 0 : _a.call(console, `Room connection was closed unexpectedly (${e.code}): ${e.reason}`);
67
+ this.onError.invoke(e.code, e.reason);
68
+ return;
69
+ }
70
+ if (e.code === Errors.CloseCode.NO_STATUS_RECEIVED ||
71
+ e.code === Errors.CloseCode.ABNORMAL_CLOSURE ||
72
+ e.code === Errors.CloseCode.GOING_AWAY ||
73
+ e.code === Errors.CloseCode.DEVMODE_RESTART) {
74
+ this.onDrop.invoke(e.code, e.reason);
75
+ this.handleReconnection();
76
+ }
77
+ else {
78
+ this.onLeave.invoke(e.code, e.reason);
79
+ this.destroy();
80
+ }
81
+ };
82
+ this.connection.events.onerror = (e) => {
83
+ var _a;
84
+ (_a = console.warn) === null || _a === void 0 ? void 0 : _a.call(console, `Room, onError (${e.code}): ${e.reason}`);
85
+ this.onError.invoke(e.code, e.reason);
86
+ };
87
+ /**
88
+ * if local serializer has state, it means we don't need to receive the
89
+ * handshake from the server
90
+ */
91
+ const skipHandshake = (((_a = this.serializer) === null || _a === void 0 ? void 0 : _a.getState()) !== undefined);
92
+ if (options.protocol === "h3") {
93
+ // FIXME: refactor this.
94
+ const url = new URL(endpoint);
95
+ this.connection.connect(url.origin, Object.assign(Object.assign({}, options), { skipHandshake }));
96
+ }
97
+ else {
98
+ this.connection.connect(`${endpoint}${skipHandshake ? "?skipHandshake=1" : ""}`, headers);
99
+ }
100
+ }
101
+ leave(consented = true) {
102
+ return new Promise((resolve) => {
103
+ this.onLeave((code) => resolve(code));
104
+ if (this.connection) {
105
+ if (consented) {
106
+ this.packr.buffer[0] = Protocol.Protocol.LEAVE_ROOM;
107
+ this.connection.send(this.packr.buffer.subarray(0, 1));
108
+ }
109
+ else {
110
+ this.connection.close();
111
+ }
112
+ }
113
+ else {
114
+ this.onLeave.invoke(Errors.CloseCode.CONSENTED);
115
+ }
116
+ });
117
+ }
118
+ onMessage(type, callback) {
119
+ return this.onMessageHandlers.on(this.getMessageHandlerKey(type), callback);
120
+ }
121
+ ping(callback) {
122
+ tslib.__classPrivateFieldSet(this, _Room_lastPingTime, utils.now(), "f");
123
+ tslib.__classPrivateFieldSet(this, _Room_pingCallback, callback, "f");
124
+ this.packr.buffer[0] = Protocol.Protocol.PING;
125
+ this.connection.send(this.packr.buffer.subarray(0, 1));
126
+ }
127
+ send(messageType, payload) {
128
+ const it = { offset: 1 };
129
+ this.packr.buffer[0] = Protocol.Protocol.ROOM_DATA;
130
+ if (typeof (messageType) === "string") {
131
+ schema.encode.string(this.packr.buffer, messageType, it);
132
+ }
133
+ else {
134
+ schema.encode.number(this.packr.buffer, messageType, it);
135
+ }
136
+ // force packr to use beginning of the buffer
137
+ this.packr.position = 0;
138
+ const data = (payload !== undefined)
139
+ ? this.packr.pack(payload, 2048 + it.offset) // 2048 = RESERVE_START_SPACE
140
+ : this.packr.buffer.subarray(0, it.offset);
141
+ // If connection is not open, buffer the message
142
+ if (!this.connection.isOpen) {
143
+ enqueueMessage(this, new Uint8Array(data));
144
+ }
145
+ else {
146
+ this.connection.send(data);
147
+ }
148
+ }
149
+ sendUnreliable(type, message) {
150
+ // If connection is not open, skip
151
+ if (!this.connection.isOpen) {
152
+ return;
153
+ }
154
+ const it = { offset: 1 };
155
+ this.packr.buffer[0] = Protocol.Protocol.ROOM_DATA;
156
+ if (typeof (type) === "string") {
157
+ schema.encode.string(this.packr.buffer, type, it);
158
+ }
159
+ else {
160
+ schema.encode.number(this.packr.buffer, type, it);
161
+ }
162
+ // force packr to use beginning of the buffer
163
+ this.packr.position = 0;
164
+ const data = (message !== undefined)
165
+ ? this.packr.pack(message, 2048 + it.offset) // 2048 = RESERVE_START_SPACE
166
+ : this.packr.buffer.subarray(0, it.offset);
167
+ this.connection.sendUnreliable(data);
168
+ }
169
+ sendBytes(type, bytes) {
170
+ const it = { offset: 1 };
171
+ this.packr.buffer[0] = Protocol.Protocol.ROOM_DATA_BYTES;
172
+ if (typeof (type) === "string") {
173
+ schema.encode.string(this.packr.buffer, type, it);
174
+ }
175
+ else {
176
+ schema.encode.number(this.packr.buffer, type, it);
177
+ }
178
+ // check if buffer needs to be resized
179
+ // TODO: can we avoid this?
180
+ if (bytes.byteLength + it.offset > this.packr.buffer.byteLength) {
181
+ const newBuffer = new Uint8Array(it.offset + bytes.byteLength);
182
+ newBuffer.set(this.packr.buffer);
183
+ this.packr.useBuffer(newBuffer);
184
+ }
185
+ this.packr.buffer.set(bytes, it.offset);
186
+ // If connection is not open, buffer the message
187
+ if (!this.connection.isOpen) {
188
+ enqueueMessage(this, this.packr.buffer.subarray(0, it.offset + bytes.byteLength));
189
+ }
190
+ else {
191
+ this.connection.send(this.packr.buffer.subarray(0, it.offset + bytes.byteLength));
192
+ }
193
+ }
194
+ get state() {
195
+ return this.serializer.getState();
196
+ }
197
+ removeAllListeners() {
198
+ this.onJoin.clear();
199
+ this.onStateChange.clear();
200
+ this.onError.clear();
201
+ this.onLeave.clear();
202
+ this.onMessageHandlers.events = {};
203
+ if (this.serializer instanceof SchemaSerializer.SchemaSerializer) {
204
+ // Remove callback references
205
+ this.serializer.decoder.root.callbacks = {};
206
+ }
207
+ }
208
+ onMessageCallback(event) {
209
+ var _a;
210
+ const buffer = new Uint8Array(event.data);
211
+ const it = { offset: 1 };
212
+ const code = buffer[0];
213
+ if (code === Protocol.Protocol.JOIN_ROOM) {
214
+ const reconnectionToken = schema.decode.utf8Read(buffer, it, buffer[it.offset++]);
215
+ this.serializerId = schema.decode.utf8Read(buffer, it, buffer[it.offset++]);
216
+ // Instantiate serializer if not locally available.
217
+ if (!this.serializer) {
218
+ const serializer = Serializer.getSerializer(this.serializerId);
219
+ this.serializer = new serializer();
220
+ }
221
+ // apply handshake on first join (no need to do this on reconnect)
222
+ if (buffer.byteLength > it.offset && this.serializer.handshake) {
223
+ this.serializer.handshake(buffer, it);
224
+ }
225
+ if (this.joinedAtTime === 0) {
226
+ this.joinedAtTime = Date.now();
227
+ this.onJoin.invoke();
228
+ }
229
+ else {
230
+ console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x2705)} reconnection successful!`); // ✅
231
+ this.reconnection.isReconnecting = false;
232
+ this.onReconnect.invoke();
233
+ }
234
+ this.reconnectionToken = `${this.roomId}:${reconnectionToken}`;
235
+ // acknowledge successfull JOIN_ROOM
236
+ this.packr.buffer[0] = Protocol.Protocol.JOIN_ROOM;
237
+ this.connection.send(this.packr.buffer.subarray(0, 1));
238
+ // Send any enqueued messages that were buffered while disconnected
239
+ if (this.reconnection.enqueuedMessages.length > 0) {
240
+ for (const message of this.reconnection.enqueuedMessages) {
241
+ this.connection.send(message.data);
242
+ }
243
+ // Clear the buffer after sending
244
+ this.reconnection.enqueuedMessages = [];
245
+ }
246
+ }
247
+ else if (code === Protocol.Protocol.ERROR) {
248
+ const code = schema.decode.number(buffer, it);
249
+ const message = schema.decode.string(buffer, it);
250
+ this.onError.invoke(code, message);
251
+ }
252
+ else if (code === Protocol.Protocol.LEAVE_ROOM) {
253
+ this.leave();
254
+ }
255
+ else if (code === Protocol.Protocol.ROOM_STATE) {
256
+ this.serializer.setState(buffer, it);
257
+ this.onStateChange.invoke(this.serializer.getState());
258
+ }
259
+ else if (code === Protocol.Protocol.ROOM_STATE_PATCH) {
260
+ this.serializer.patch(buffer, it);
261
+ this.onStateChange.invoke(this.serializer.getState());
262
+ }
263
+ else if (code === Protocol.Protocol.ROOM_DATA) {
264
+ const type = (schema.decode.stringCheck(buffer, it))
265
+ ? schema.decode.string(buffer, it)
266
+ : schema.decode.number(buffer, it);
267
+ const message = (buffer.byteLength > it.offset)
268
+ ? msgpackr.unpack(buffer, { start: it.offset })
269
+ : undefined;
270
+ this.dispatchMessage(type, message);
271
+ }
272
+ else if (code === Protocol.Protocol.ROOM_DATA_BYTES) {
273
+ const type = (schema.decode.stringCheck(buffer, it))
274
+ ? schema.decode.string(buffer, it)
275
+ : schema.decode.number(buffer, it);
276
+ this.dispatchMessage(type, buffer.subarray(it.offset));
277
+ }
278
+ else if (code === Protocol.Protocol.PING) {
279
+ (_a = tslib.__classPrivateFieldGet(this, _Room_pingCallback, "f")) === null || _a === void 0 ? void 0 : _a.call(this, utils.now() - tslib.__classPrivateFieldGet(this, _Room_lastPingTime, "f"));
280
+ tslib.__classPrivateFieldSet(this, _Room_pingCallback, undefined, "f");
281
+ }
282
+ }
283
+ dispatchMessage(type, message) {
284
+ var _a;
285
+ const messageType = this.getMessageHandlerKey(type);
286
+ if (this.onMessageHandlers.events[messageType]) {
287
+ this.onMessageHandlers.emit(messageType, message);
288
+ }
289
+ else if (this.onMessageHandlers.events['*']) {
290
+ this.onMessageHandlers.emit('*', type, message);
291
+ }
292
+ else if (!messageType.startsWith("__")) { // ignore internal messages
293
+ (_a = console.warn) === null || _a === void 0 ? void 0 : _a.call(console, `colyseus.js: onMessage() not registered for type '${type}'.`);
294
+ }
295
+ }
296
+ destroy() {
297
+ if (this.serializer) {
298
+ this.serializer.teardown();
299
+ }
300
+ }
301
+ getMessageHandlerKey(type) {
302
+ switch (typeof (type)) {
303
+ // string
304
+ case "string": return type;
305
+ // number
306
+ case "number": return `i${type}`;
307
+ default: throw new Error("invalid message type.");
308
+ }
309
+ }
310
+ handleReconnection() {
311
+ if (Date.now() - this.joinedAtTime < this.reconnection.minUptime) {
312
+ console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x274C)} Room has not been up for long enough for automatic reconnection. (min uptime: ${this.reconnection.minUptime}ms)`); // ❌
313
+ return;
314
+ }
315
+ if (!this.reconnection.isReconnecting) {
316
+ console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x1F504)} Re-establishing connection with roomId '${this.roomId}'...`); // 🔄
317
+ this.reconnection.retryCount = 0;
318
+ this.reconnection.isReconnecting = true;
319
+ }
320
+ this.retryReconnection();
321
+ }
322
+ retryReconnection() {
323
+ this.reconnection.retryCount++;
324
+ const delay = Math.min(this.reconnection.maxDelay, Math.max(this.reconnection.minDelay, this.reconnection.backoff(this.reconnection.retryCount, this.reconnection.delay)));
325
+ console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x1F504)} will retry in ${delay}ms... (${this.reconnection.retryCount} out of ${this.reconnection.maxRetries})`); // 🔄
326
+ // Wait before attempting reconnection
327
+ setTimeout(() => {
328
+ try {
329
+ this.connection.reconnect({
330
+ reconnectionToken: this.reconnectionToken.split(":")[1],
331
+ skipHandshake: true, // we already applied the handshake on first join
332
+ });
333
+ }
334
+ catch (e) {
335
+ if (this.reconnection.retryCount < this.reconnection.maxRetries) {
336
+ this.retryReconnection();
337
+ }
338
+ else {
339
+ console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x274C)} Failed to reconnect. Is your server running? Please check server logs.`); // ❌
340
+ }
341
+ }
342
+ }, delay);
343
+ }
344
+ }
345
+ _Room_lastPingTime = new WeakMap(), _Room_pingCallback = new WeakMap();
346
+ const exponentialBackoff = (attempt, delay) => {
347
+ return Math.floor(Math.pow(2, attempt) * delay);
348
+ };
349
+ function enqueueMessage(room, message) {
350
+ room.reconnection.enqueuedMessages.push({ data: message });
351
+ if (room.reconnection.enqueuedMessages.length > room.reconnection.maxEnqueuedMessages) {
352
+ room.reconnection.enqueuedMessages.shift();
353
+ }
354
+ }
355
+
356
+ exports.Room = Room;
357
+ //# sourceMappingURL=Room.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Room.js","sources":["../../src/Room.ts"],"sourcesContent":["import { type Room as ServerRoom, type ExtractMessageType } from '@colyseus/core';\nimport { decode, Decoder, encode, Iterator, schema, Schema, SchemaType } from '@colyseus/schema';\n\nimport { Packr, unpack } from '@colyseus/msgpackr';\n\nimport { Connection } from './Connection.ts';\nimport { Protocol } from './Protocol.ts';\nimport { getSerializer, Serializer } from './serializer/Serializer.ts';\n\n// The unused imports here are important for better `.d.ts` file generation\n// (Later merged with `dts-bundle-generator`)\nimport { createNanoEvents } from './core/nanoevents.ts';\nimport { createSignal } from './core/signal.ts';\n\nimport { SchemaConstructor, SchemaSerializer } from './serializer/SchemaSerializer.ts';\n\nimport { CloseCode } from './errors/Errors.ts';\nimport { now } from './core/utils.ts';\n\n// Infer serializer type based on State: SchemaSerializer for Schema types, Serializer otherwise\nexport type InferSerializer<State> = [State] extends [Schema]\n ? SchemaSerializer<State>\n : Serializer<State>;\n\nexport interface RoomAvailable<Metadata = any> {\n name: string;\n roomId: string;\n clients: number;\n maxClients: number;\n metadata?: Metadata;\n}\n\nexport interface ReconnectionOptions {\n /**\n * The maximum number of reconnection attempts.\n */\n maxRetries: number;\n\n /**\n * The minimum delay between reconnection attempts.\n */\n minDelay: number;\n\n /**\n * The maximum delay between reconnection attempts.\n */\n maxDelay: number;\n\n /**\n * The minimum uptime of the room before reconnection attempts can be made.\n */\n minUptime: number;\n\n /**\n * The current number of reconnection attempts.\n */\n retryCount: number;\n\n /**\n * The initial delay between reconnection attempts.\n */\n delay: number;\n\n /**\n * The function to calculate the delay between reconnection attempts.\n * @param attempt - The current attempt number.\n * @param delay - The initial delay between reconnection attempts.\n * @returns The delay between reconnection attempts.\n */\n backoff: (attempt: number, delay: number) => number;\n\n /**\n * The maximum number of enqueued messages to buffer.\n */\n maxEnqueuedMessages: number;\n\n /**\n * Buffer for messages sent while connection is not open.\n * These messages will be sent once the connection is re-established.\n */\n enqueuedMessages: Array<{ data: Uint8Array }>;\n\n /**\n * Whether the room is currently reconnecting.\n */\n isReconnecting: boolean;\n}\n\nexport class Room<\n RoomType extends typeof ServerRoom = any,\n State = RoomType['prototype']['state'],\n> {\n public roomId: string;\n public sessionId: string;\n public reconnectionToken: string;\n\n public name: string;\n public connection: Connection;\n\n // Public signals\n public onStateChange = createSignal<(state: State) => void>();\n public onError = createSignal<(code: number, message?: string) => void>();\n public onLeave = createSignal<(code: number, reason?: string) => void>();\n\n public onReconnect = createSignal<() => void>();\n public onDrop = createSignal<(code: number, reason?: string) => void>();\n\n protected onJoin = createSignal();\n\n public serializerId: string;\n public serializer: InferSerializer<State>;\n\n // reconnection logic\n public reconnection: ReconnectionOptions = {\n retryCount: 0,\n maxRetries: 8,\n delay: 100,\n minDelay: 100,\n maxDelay: 5000,\n minUptime: 5000,\n backoff: exponentialBackoff,\n maxEnqueuedMessages: 10,\n enqueuedMessages: [],\n isReconnecting: false,\n };\n\n protected joinedAtTime: number = 0;\n\n protected onMessageHandlers = createNanoEvents();\n\n protected packr: Packr;\n\n #lastPingTime: number = 0;\n #pingCallback: (ms: number) => void;\n\n constructor(name: string, rootSchema?: SchemaConstructor<State>) {\n this.name = name;\n\n this.packr = new Packr();\n\n // msgpackr workaround: force buffer to be created.\n this.packr.encode(undefined);\n\n if (rootSchema) {\n this.serializer = new (getSerializer(\"schema\"));\n (this.serializer as SchemaSerializer).state = new rootSchema();\n }\n\n this.onError((code, message) => console.warn?.(`colyseus.js - onError => (${code}) ${message}`));\n this.onLeave(() => this.removeAllListeners());\n }\n\n public connect(endpoint: string, options?: any, headers?: any) {\n this.connection = new Connection(options.protocol);\n this.connection.events.onmessage = this.onMessageCallback.bind(this);\n this.connection.events.onclose = (e: CloseEvent) => {\n if (this.joinedAtTime === 0) {\n console.warn?.(`Room connection was closed unexpectedly (${e.code}): ${e.reason}`);\n this.onError.invoke(e.code, e.reason);\n return;\n }\n\n if (\n e.code === CloseCode.NO_STATUS_RECEIVED ||\n e.code === CloseCode.ABNORMAL_CLOSURE ||\n e.code === CloseCode.GOING_AWAY ||\n e.code === CloseCode.DEVMODE_RESTART\n ) {\n this.onDrop.invoke(e.code, e.reason);\n this.handleReconnection();\n\n } else {\n this.onLeave.invoke(e.code, e.reason);\n this.destroy();\n }\n };\n\n this.connection.events.onerror = (e: CloseEvent) => {\n console.warn?.(`Room, onError (${e.code}): ${e.reason}`);\n this.onError.invoke(e.code, e.reason);\n };\n\n /**\n * if local serializer has state, it means we don't need to receive the\n * handshake from the server\n */\n const skipHandshake = (this.serializer?.getState() !== undefined);\n\n if (options.protocol === \"h3\") {\n // FIXME: refactor this.\n const url = new URL(endpoint);\n this.connection.connect(url.origin, { ...options, skipHandshake });\n\n } else {\n this.connection.connect(`${endpoint}${skipHandshake ? \"?skipHandshake=1\" : \"\"}`, headers);\n }\n\n }\n\n public leave(consented: boolean = true): Promise<number> {\n return new Promise((resolve) => {\n this.onLeave((code) => resolve(code));\n\n if (this.connection) {\n if (consented) {\n this.packr.buffer[0] = Protocol.LEAVE_ROOM;\n this.connection.send(this.packr.buffer.subarray(0, 1));\n\n } else {\n this.connection.close();\n }\n\n } else {\n this.onLeave.invoke(CloseCode.CONSENTED);\n }\n });\n }\n\n public onMessage<MessageType extends keyof RoomType['prototype']['~client']['~messages']>(\n message: MessageType,\n callback: (payload: RoomType['prototype']['~client']['~messages'][MessageType]) => void\n )\n public onMessage<T = any>(type: \"*\", callback: (messageType: string | number, payload: T) => void)\n public onMessage<T = any>(type: string | number, callback: (payload: T) => void)\n public onMessage(type: '*' | string | number, callback: (...args: any[]) => void) {\n return this.onMessageHandlers.on(this.getMessageHandlerKey(type), callback);\n }\n\n public ping(callback: (ms: number) => void) {\n this.#lastPingTime = now();\n this.#pingCallback = callback;\n this.packr.buffer[0] = Protocol.PING;\n this.connection.send(this.packr.buffer.subarray(0, 1));\n }\n\n public send<MessageType extends keyof RoomType['prototype']['messages']>(\n messageType: MessageType,\n payload?: ExtractMessageType<RoomType['prototype']['messages'][MessageType]>\n )\n public send<T = any>(messageType: string | number, payload?: T): void {\n const it: Iterator = { offset: 1 };\n this.packr.buffer[0] = Protocol.ROOM_DATA;\n\n if (typeof(messageType) === \"string\") {\n encode.string(this.packr.buffer as Buffer, messageType, it);\n\n } else {\n encode.number(this.packr.buffer as Buffer, messageType, it);\n }\n\n // force packr to use beginning of the buffer\n this.packr.position = 0;\n\n const data = (payload !== undefined)\n ? this.packr.pack(payload, 2048 + it.offset) // 2048 = RESERVE_START_SPACE\n : this.packr.buffer.subarray(0, it.offset);\n\n // If connection is not open, buffer the message\n if (!this.connection.isOpen) {\n enqueueMessage(this, new Uint8Array(data));\n } else {\n this.connection.send(data);\n }\n }\n\n public sendUnreliable<T = any>(type: string | number, message?: T): void {\n // If connection is not open, skip\n if (!this.connection.isOpen) { return; }\n\n const it: Iterator = { offset: 1 };\n this.packr.buffer[0] = Protocol.ROOM_DATA;\n\n if (typeof(type) === \"string\") {\n encode.string(this.packr.buffer as Buffer, type, it);\n\n } else {\n encode.number(this.packr.buffer as Buffer, type, it);\n }\n\n // force packr to use beginning of the buffer\n this.packr.position = 0;\n\n const data = (message !== undefined)\n ? this.packr.pack(message, 2048 + it.offset) // 2048 = RESERVE_START_SPACE\n : this.packr.buffer.subarray(0, it.offset);\n\n this.connection.sendUnreliable(data);\n }\n\n public sendBytes(type: string | number, bytes: Uint8Array) {\n const it: Iterator = { offset: 1 };\n this.packr.buffer[0] = Protocol.ROOM_DATA_BYTES;\n\n if (typeof(type) === \"string\") {\n encode.string(this.packr.buffer as Buffer, type, it);\n\n } else {\n encode.number(this.packr.buffer as Buffer, type, it);\n }\n\n // check if buffer needs to be resized\n // TODO: can we avoid this?\n if (bytes.byteLength + it.offset > this.packr.buffer.byteLength) {\n const newBuffer = new Uint8Array(it.offset + bytes.byteLength);\n newBuffer.set(this.packr.buffer);\n this.packr.useBuffer(newBuffer);\n }\n\n this.packr.buffer.set(bytes, it.offset);\n\n // If connection is not open, buffer the message\n if (!this.connection.isOpen) {\n enqueueMessage(this, this.packr.buffer.subarray(0, it.offset + bytes.byteLength));\n } else {\n this.connection.send(this.packr.buffer.subarray(0, it.offset + bytes.byteLength));\n }\n\n }\n\n public get state (): State {\n return this.serializer.getState();\n }\n\n public removeAllListeners() {\n this.onJoin.clear();\n this.onStateChange.clear();\n this.onError.clear();\n this.onLeave.clear();\n this.onMessageHandlers.events = {};\n\n if (this.serializer instanceof SchemaSerializer) {\n // Remove callback references\n this.serializer.decoder.root.callbacks = {};\n }\n }\n\n protected onMessageCallback(event: MessageEvent) {\n const buffer = new Uint8Array(event.data);\n\n const it: Iterator = { offset: 1 };\n const code = buffer[0];\n\n if (code === Protocol.JOIN_ROOM) {\n const reconnectionToken = decode.utf8Read(buffer as Buffer, it, buffer[it.offset++]);\n this.serializerId = decode.utf8Read(buffer as Buffer, it, buffer[it.offset++]);\n\n // Instantiate serializer if not locally available.\n if (!this.serializer) {\n const serializer = getSerializer(this.serializerId);\n this.serializer = new serializer();\n }\n\n // apply handshake on first join (no need to do this on reconnect)\n if (buffer.byteLength > it.offset && this.serializer.handshake) {\n this.serializer.handshake(buffer, it);\n }\n\n if (this.joinedAtTime === 0) {\n this.joinedAtTime = Date.now();\n this.onJoin.invoke();\n\n } else {\n console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x2705)} reconnection successful!`); // ✅\n this.reconnection.isReconnecting = false;\n this.onReconnect.invoke();\n }\n\n this.reconnectionToken = `${this.roomId}:${reconnectionToken}`;\n\n // acknowledge successfull JOIN_ROOM\n this.packr.buffer[0] = Protocol.JOIN_ROOM;\n this.connection.send(this.packr.buffer.subarray(0, 1));\n\n // Send any enqueued messages that were buffered while disconnected\n if (this.reconnection.enqueuedMessages.length > 0) {\n for (const message of this.reconnection.enqueuedMessages) {\n this.connection.send(message.data);\n }\n // Clear the buffer after sending\n this.reconnection.enqueuedMessages = [];\n }\n\n } else if (code === Protocol.ERROR) {\n const code = decode.number(buffer as Buffer, it);\n const message = decode.string(buffer as Buffer, it);\n\n this.onError.invoke(code, message);\n\n } else if (code === Protocol.LEAVE_ROOM) {\n this.leave();\n\n } else if (code === Protocol.ROOM_STATE) {\n this.serializer.setState(buffer, it);\n this.onStateChange.invoke(this.serializer.getState());\n\n } else if (code === Protocol.ROOM_STATE_PATCH) {\n this.serializer.patch(buffer, it);\n this.onStateChange.invoke(this.serializer.getState());\n\n } else if (code === Protocol.ROOM_DATA) {\n const type = (decode.stringCheck(buffer as Buffer, it))\n ? decode.string(buffer as Buffer, it)\n : decode.number(buffer as Buffer, it);\n\n const message = (buffer.byteLength > it.offset)\n ? unpack(buffer as Buffer, { start: it.offset })\n : undefined;\n\n this.dispatchMessage(type, message);\n\n } else if (code === Protocol.ROOM_DATA_BYTES) {\n const type = (decode.stringCheck(buffer as Buffer, it))\n ? decode.string(buffer as Buffer, it)\n : decode.number(buffer as Buffer, it);\n\n this.dispatchMessage(type, buffer.subarray(it.offset));\n } else if (code === Protocol.PING) {\n this.#pingCallback?.(now() - this.#lastPingTime);\n this.#pingCallback = undefined;\n }\n }\n\n private dispatchMessage(type: string | number, message: any) {\n const messageType = this.getMessageHandlerKey(type);\n\n if (this.onMessageHandlers.events[messageType]) {\n this.onMessageHandlers.emit(messageType, message);\n\n } else if (this.onMessageHandlers.events['*']) {\n this.onMessageHandlers.emit('*', type, message);\n\n } else if (!messageType.startsWith(\"__\")) { // ignore internal messages\n console.warn?.(`colyseus.js: onMessage() not registered for type '${type}'.`);\n }\n }\n\n private destroy () {\n if (this.serializer) {\n this.serializer.teardown();\n }\n }\n\n private getMessageHandlerKey(type: string | number): string {\n switch (typeof(type)) {\n // string\n case \"string\": return type;\n\n // number\n case \"number\": return `i${type}`;\n\n default: throw new Error(\"invalid message type.\");\n }\n }\n\n private handleReconnection() {\n if (Date.now() - this.joinedAtTime < this.reconnection.minUptime) {\n console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x274C)} Room has not been up for long enough for automatic reconnection. (min uptime: ${this.reconnection.minUptime}ms)`); // ❌\n return;\n }\n\n if (!this.reconnection.isReconnecting) {\n console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x1F504)} Re-establishing connection with roomId '${this.roomId}'...`); // 🔄\n this.reconnection.retryCount = 0;\n this.reconnection.isReconnecting = true;\n }\n\n this.retryReconnection();\n }\n\n private retryReconnection() {\n this.reconnection.retryCount++;\n\n const delay = Math.min(this.reconnection.maxDelay, Math.max(this.reconnection.minDelay, this.reconnection.backoff(this.reconnection.retryCount, this.reconnection.delay)));\n\n console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x1F504)} will retry in ${delay}ms... (${this.reconnection.retryCount} out of ${this.reconnection.maxRetries})`); // 🔄\n\n // Wait before attempting reconnection\n setTimeout(() => {\n try {\n this.connection.reconnect({\n reconnectionToken: this.reconnectionToken.split(\":\")[1],\n skipHandshake: true, // we already applied the handshake on first join\n });\n\n } catch (e) {\n if (this.reconnection.retryCount < this.reconnection.maxRetries) {\n this.retryReconnection();\n } else {\n console.info(`[Colyseus reconnection]: ${String.fromCodePoint(0x274C)} Failed to reconnect. Is your server running? Please check server logs.`); // ❌\n }\n }\n }, delay);\n }\n}\n\nconst exponentialBackoff = (attempt: number, delay: number) => {\n return Math.floor(Math.pow(2, attempt) * delay);\n}\n\nfunction enqueueMessage(room: Room, message: Uint8Array) {\n room.reconnection.enqueuedMessages.push({ data: message });\n if (room.reconnection.enqueuedMessages.length > room.reconnection.maxEnqueuedMessages) {\n room.reconnection.enqueuedMessages.shift();\n }\n}"],"names":["createSignal","createNanoEvents","Packr","getSerializer","Connection","CloseCode","Protocol","__classPrivateFieldSet","now","encode","SchemaSerializer","decode","unpack","__classPrivateFieldGet"],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ // Copyright (c) 2026 Endel Dreyer.
2
+ //
3
+ // This software is released under the MIT License.
4
+ // https://opensource.org/license/MIT
5
+ //
6
+ // colyseus.js@0.17.0
7
+ 'use strict';
8
+
9
+ var tslib = require('tslib');
10
+
11
+ /// <reference path="../typings/cocos-creator.d.ts" />
12
+ /**
13
+ * We do not assign 'storage' to window.localStorage immediatelly for React
14
+ * Native compatibility. window.localStorage is not present when this module is
15
+ * loaded.
16
+ */
17
+ let storage;
18
+ function getStorage() {
19
+ if (!storage) {
20
+ try {
21
+ storage = (typeof (cc) !== 'undefined' && cc.sys && cc.sys.localStorage)
22
+ ? cc.sys.localStorage // compatibility with cocos creator
23
+ : window.localStorage; // RN does have window object at this point, but localStorage is not defined
24
+ }
25
+ catch (e) {
26
+ // ignore error
27
+ }
28
+ }
29
+ if (!storage && typeof (globalThis.indexedDB) !== 'undefined') {
30
+ storage = new IndexedDBStorage();
31
+ }
32
+ if (!storage) {
33
+ // mock localStorage if not available (Node.js or RN environment)
34
+ storage = {
35
+ cache: {},
36
+ setItem: function (key, value) { this.cache[key] = value; },
37
+ getItem: function (key) { this.cache[key]; },
38
+ removeItem: function (key) { delete this.cache[key]; },
39
+ };
40
+ }
41
+ return storage;
42
+ }
43
+ function setItem(key, value) {
44
+ getStorage().setItem(key, value);
45
+ }
46
+ function removeItem(key) {
47
+ getStorage().removeItem(key);
48
+ }
49
+ function getItem(key, callback) {
50
+ const value = getStorage().getItem(key);
51
+ if (typeof (Promise) === 'undefined' || // old browsers
52
+ !(value instanceof Promise)) {
53
+ // browser has synchronous return
54
+ callback(value);
55
+ }
56
+ else {
57
+ // react-native is asynchronous
58
+ value.then((id) => callback(id));
59
+ }
60
+ }
61
+ /**
62
+ * When running in a Web Worker, we need to use IndexedDB to store data.
63
+ */
64
+ class IndexedDBStorage {
65
+ constructor() {
66
+ this.dbPromise = new Promise((resolve) => {
67
+ const request = indexedDB.open('_colyseus_storage', 1);
68
+ request.onupgradeneeded = () => request.result.createObjectStore('store');
69
+ request.onsuccess = () => resolve(request.result);
70
+ });
71
+ }
72
+ tx(mode, fn) {
73
+ return tslib.__awaiter(this, void 0, void 0, function* () {
74
+ const db = yield this.dbPromise;
75
+ const store = db.transaction('store', mode).objectStore('store');
76
+ return fn(store);
77
+ });
78
+ }
79
+ setItem(key, value) {
80
+ return this.tx('readwrite', store => store.put(value, key)).then();
81
+ }
82
+ getItem(key) {
83
+ return tslib.__awaiter(this, void 0, void 0, function* () {
84
+ const request = yield this.tx('readonly', store => store.get(key));
85
+ return new Promise((resolve) => {
86
+ request.onsuccess = () => resolve(request.result);
87
+ });
88
+ });
89
+ }
90
+ removeItem(key) {
91
+ return this.tx('readwrite', store => store.delete(key)).then();
92
+ }
93
+ }
94
+
95
+ exports.getItem = getItem;
96
+ exports.removeItem = removeItem;
97
+ exports.setItem = setItem;
98
+ //# sourceMappingURL=Storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Storage.js","sources":["../../src/Storage.ts"],"sourcesContent":["/// <reference path=\"../typings/cocos-creator.d.ts\" />\n\n/**\n * We do not assign 'storage' to window.localStorage immediatelly for React\n * Native compatibility. window.localStorage is not present when this module is\n * loaded.\n */\n\nlet storage: any;\n\nfunction getStorage(): Storage {\n if (!storage) {\n try {\n storage = (typeof (cc) !== 'undefined' && cc.sys && cc.sys.localStorage)\n ? cc.sys.localStorage // compatibility with cocos creator\n : window.localStorage; // RN does have window object at this point, but localStorage is not defined\n\n } catch (e) {\n // ignore error\n }\n }\n\n if (!storage && typeof (globalThis.indexedDB) !== 'undefined') {\n storage = new IndexedDBStorage();\n }\n\n if (!storage) {\n // mock localStorage if not available (Node.js or RN environment)\n storage = {\n cache: {},\n setItem: function (key, value) { this.cache[key] = value; },\n getItem: function (key) { this.cache[key]; },\n removeItem: function (key) { delete this.cache[key]; },\n };\n }\n\n return storage;\n}\n\nexport function setItem(key: string, value: string) {\n getStorage().setItem(key, value);\n}\n\nexport function removeItem(key: string) {\n getStorage().removeItem(key);\n}\n\nexport function getItem(key: string, callback: Function) {\n const value: any = getStorage().getItem(key);\n\n if (\n typeof (Promise) === 'undefined' || // old browsers\n !(value instanceof Promise)\n ) {\n // browser has synchronous return\n callback(value);\n\n } else {\n // react-native is asynchronous\n value.then((id) => callback(id));\n }\n}\n\n/**\n * When running in a Web Worker, we need to use IndexedDB to store data.\n */\nclass IndexedDBStorage {\n private dbPromise: Promise<IDBDatabase> = new Promise((resolve) => {\n const request = indexedDB.open('_colyseus_storage', 1);\n request.onupgradeneeded = () => request.result.createObjectStore('store');\n request.onsuccess = () => resolve(request.result);\n });\n\n private async tx(mode: IDBTransactionMode, fn: (store: IDBObjectStore) => IDBRequest) {\n const db = await this.dbPromise;\n const store = db.transaction('store', mode).objectStore('store');\n return fn(store);\n }\n\n setItem(key: string, value: string) {\n return this.tx('readwrite', store => store.put(value, key)).then();\n }\n\n async getItem(key: string) {\n const request = await this.tx('readonly', store => store.get(key));\n return new Promise<string | undefined>((resolve) => {\n request.onsuccess = () => resolve(request.result);\n });\n }\n\n removeItem(key: string) {\n return this.tx('readwrite', store => store.delete(key)).then();\n }\n}"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ // Copyright (c) 2026 Endel Dreyer.
2
+ //
3
+ // This software is released under the MIT License.
4
+ // https://opensource.org/license/MIT
5
+ //
6
+ // colyseus.js@0.17.0
7
+ 'use strict';
8
+
9
+ /**
10
+ * The MIT License (MIT)
11
+ *
12
+ * Copyright 2016 Andrey Sitnik <andrey@sitnik.ru>
13
+ *
14
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
15
+ * this software and associated documentation files (the "Software"), to deal in
16
+ * the Software without restriction, including without limitation the rights to
17
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
18
+ * the Software, and to permit persons to whom the Software is furnished to do so,
19
+ * subject to the following conditions:
20
+ *
21
+ * The above copyright notice and this permission notice shall be included in all
22
+ * copies or substantial portions of the Software.
23
+ *
24
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
26
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
27
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
28
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
+ */
31
+ const createNanoEvents = () => ({
32
+ emit(event, ...args) {
33
+ let callbacks = this.events[event] || [];
34
+ for (let i = 0, length = callbacks.length; i < length; i++) {
35
+ callbacks[i](...args);
36
+ }
37
+ },
38
+ events: {},
39
+ on(event, cb) {
40
+ var _a;
41
+ ((_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.push(cb)) || (this.events[event] = [cb]);
42
+ return () => {
43
+ var _a;
44
+ this.events[event] = (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.filter(i => cb !== i);
45
+ };
46
+ }
47
+ });
48
+
49
+ exports.createNanoEvents = createNanoEvents;
50
+ //# sourceMappingURL=nanoevents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nanoevents.js","sources":["../../../src/core/nanoevents.ts"],"sourcesContent":["/**\n * The MIT License (MIT)\n *\n * Copyright 2016 Andrey Sitnik <andrey@sitnik.ru>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of\n * this software and associated documentation files (the \"Software\"), to deal in\n * the Software without restriction, including without limitation the rights to\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n * the Software, and to permit persons to whom the Software is furnished to do so,\n * subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\nexport const createNanoEvents = () => ({\n emit(event: string, ...args: any[]) {\n let callbacks = this.events[event] || []\n for (let i = 0, length = callbacks.length; i < length; i++) {\n callbacks[i](...args)\n }\n },\n events: {},\n on(event: string, cb: (...args: any[]) => void) {\n this.events[event]?.push(cb) || (this.events[event] = [cb])\n return () => {\n this.events[event] = this.events[event]?.filter(i => cb !== i)\n }\n }\n});"],"names":[],"mappings":";;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;AAqBG;AAEI,MAAM,gBAAgB,GAAG,OAAO;AACnC,IAAA,IAAI,CAAC,KAAa,EAAE,GAAG,IAAW,EAAA;QAC9B,IAAI,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE;AACxC,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE;AACxD,YAAA,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;QACzB;IACJ,CAAC;AACD,IAAA,MAAM,EAAE,EAAE;IACV,EAAE,CAAC,KAAa,EAAE,EAA4B,EAAA;;QAC1C,CAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,IAAI,CAAC,EAAE,CAAC,MAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC3D,QAAA,OAAO,MAAK;;YACR,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAClE,QAAA,CAAC;IACL;AACH,CAAA;;;;"}
@@ -0,0 +1,53 @@
1
+ // Copyright (c) 2026 Endel Dreyer.
2
+ //
3
+ // This software is released under the MIT License.
4
+ // https://opensource.org/license/MIT
5
+ //
6
+ // colyseus.js@0.17.0
7
+ 'use strict';
8
+
9
+ class EventEmitter {
10
+ constructor() {
11
+ this.handlers = [];
12
+ }
13
+ register(cb, once = false) {
14
+ this.handlers.push(cb);
15
+ return this;
16
+ }
17
+ invoke(...args) {
18
+ this.handlers.forEach((handler) => handler.apply(this, args));
19
+ }
20
+ invokeAsync(...args) {
21
+ return Promise.all(this.handlers.map((handler) => handler.apply(this, args)));
22
+ }
23
+ remove(cb) {
24
+ const index = this.handlers.indexOf(cb);
25
+ this.handlers[index] = this.handlers[this.handlers.length - 1];
26
+ this.handlers.pop();
27
+ }
28
+ clear() {
29
+ this.handlers = [];
30
+ }
31
+ }
32
+ function createSignal() {
33
+ const emitter = new EventEmitter();
34
+ function register(cb) {
35
+ return emitter.register(cb, this === null);
36
+ }
37
+ register.once = (cb) => {
38
+ const callback = function (...args) {
39
+ cb.apply(this, args);
40
+ emitter.remove(callback);
41
+ };
42
+ emitter.register(callback);
43
+ };
44
+ register.remove = (cb) => emitter.remove(cb);
45
+ register.invoke = (...args) => emitter.invoke(...args);
46
+ register.invokeAsync = (...args) => emitter.invokeAsync(...args);
47
+ register.clear = () => emitter.clear();
48
+ return register;
49
+ }
50
+
51
+ exports.EventEmitter = EventEmitter;
52
+ exports.createSignal = createSignal;
53
+ //# sourceMappingURL=signal.js.map