@colyseus/bun-websockets 0.15.0 → 0.15.2
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/README.md +107 -18
- package/build/BunWebSockets.d.ts +4 -5
- package/build/BunWebSockets.js +36 -19
- package/build/BunWebSockets.js.map +3 -3
- package/build/BunWebSockets.mjs +37 -20
- package/build/BunWebSockets.mjs.map +3 -3
- package/build/WebSocketClient.d.ts +3 -3
- package/build/WebSocketClient.js +2 -5
- package/build/WebSocketClient.js.map +2 -2
- package/build/WebSocketClient.mjs +2 -5
- package/build/WebSocketClient.mjs.map +2 -2
- package/package.json +6 -9
- package/build/BunWebSocket.d.ts +0 -24
- package/build/BunWebSocket.js +0 -173
- package/build/BunWebSocket.js.map +0 -7
- package/build/BunWebSocket.mjs +0 -144
- package/build/BunWebSocket.mjs.map +0 -7
- package/build/WebSocketTransport.d.ts +0 -24
- package/build/WebSocketTransport.js +0 -173
- package/build/WebSocketTransport.js.map +0 -7
- package/build/WebSocketTransport.mjs +0 -144
- package/build/WebSocketTransport.mjs.map +0 -7
package/README.md
CHANGED
|
@@ -1,25 +1,114 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://github.com/colyseus/colyseus">
|
|
3
|
+
<img src="media/logo.svg?raw=true" width="60%" height="300" />
|
|
4
|
+
</a>
|
|
5
|
+
<br>
|
|
6
|
+
<br>
|
|
7
|
+
<a href="https://npmjs.com/package/colyseus">
|
|
8
|
+
<img src="https://img.shields.io/npm/dm/colyseus.svg?style=for-the-badge&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAHdElNRQfjAgETESWYxR33AAAAtElEQVQoz4WQMQrCQBRE38Z0QoTcwF4Qg1h4BO0sxGOk80iCtViksrIQRRBTewWxMI1mbELYjYu+4rPMDPtn12ChMT3gavb4US5Jym0tcBIta3oDHv4Gwmr7nC4QAxBrCdzM2q6XqUnm9m9r59h7Rc0n2pFv24k4ttGMUXW+sGELTJjSr7QDKuqLS6UKFChVWWuFkZw9Z2AAvAirKT+JTlppIRnd6XgaP4goefI2Shj++OnjB3tBmHYK8z9zAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE5LTAyLTAxVDE4OjE3OjM3KzAxOjAwGQQixQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOS0wMi0wMVQxODoxNzozNyswMTowMGhZmnkAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC">
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://github.com/colyseus/colyseus/discussions" title="Discuss on Forum">
|
|
11
|
+
<img src="https://img.shields.io/badge/discuss-on%20forum-brightgreen.svg?style=for-the-badge&colorB=0069b8&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QAAKqNIzIAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAHdElNRQfjAgETDROxCNUzAAABB0lEQVQoz4WRvyvEARjGP193CnWRH+dHQmGwKZtFGcSmxHAL400GN95ktIpV2dzlLzDJgsGgGNRdDAzoQueS/PgY3HXHyT3T+/Y87/s89UANBKXBdoZo5J6L4K1K5ZxHfnjnlQUf3bKvkgy57a0r9hS3cXfMO1kWJMza++tj3Ac7/LY343x1NA9cNmYMwnSS/SP8JVFuSJmr44iFqvtmpjhmhBCrOOazCesq6H4P3bPBjFoIBydOk2bUA17I080Es+wSZ51B4DIA2zgjSpYcEe44Js01G0XjRcCU+y4ZMrDeLmfc9EnVd5M/o0VMeu6nJZxWJivLmhyw1WHTvrr2b4+2OFqra+ALwouTMDcqmjMAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDItMDFUMTg6MTM6MTkrMDE6MDAC9f6fAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTAyLTAxVDE4OjEzOjE5KzAxOjAwc6hGIwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAAASUVORK5CYII=" alt="Discussion forum" />
|
|
12
|
+
</a>
|
|
13
|
+
<a href="http://chat.colyseus.io">
|
|
14
|
+
<img src="https://img.shields.io/discord/525739117951320081.svg?style=for-the-badge&colorB=7581dc&logo=discord&logoColor=white">
|
|
15
|
+
</a>
|
|
16
|
+
<h3>
|
|
17
|
+
Multiplayer Framework for Node.js. <br /><a href="https://docs.colyseus.io/">View documentation</a>
|
|
18
|
+
</h3>
|
|
19
|
+
</div>
|
|
2
20
|
|
|
3
|
-
|
|
21
|
+
Colyseus is an Authoritative Multiplayer Framework for Node.js, with clients
|
|
22
|
+
available for the Web, Unity3d, Defold, Haxe, and Cocos. ([See official clients](#%EF%B8%8F-official-client-integration))
|
|
4
23
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
24
|
+
The project focuses on providing synchronizable data structures for realtime and
|
|
25
|
+
turn-based games, matchmaking, and ease of usage both on the server-side and
|
|
26
|
+
client-side.
|
|
8
27
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
The mission of the framework is to be a standard netcode & matchmaking solution
|
|
29
|
+
for any kind of project you can think of!
|
|
30
|
+
|
|
31
|
+
## Key features:
|
|
32
|
+
|
|
33
|
+
- WebSocket-based communication
|
|
34
|
+
- Simple API in the server-side and client-side.
|
|
35
|
+
- Automatic state synchronization from server-to-client (delta compressed)
|
|
36
|
+
- Matchmaking clients into game rooms/sessions
|
|
37
|
+
- Scale vertically or horizontally
|
|
14
38
|
|
|
15
|
-
|
|
39
|
+
See [public roadmap](https://github.com/colyseus/colyseus/wiki/Public-Roadmap) for future plans.
|
|
16
40
|
|
|
17
|
-
|
|
18
|
-
import { Server } from "colyseus";
|
|
19
|
-
import { BunWebsockets } from "@colyseus/bun-websockets";
|
|
41
|
+
# 🚀 Quickstart
|
|
20
42
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
43
|
+
Create a bare-bones Colyseus server by using `npm create colyseus-app@latest`:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
npm create colyseus-app@latest my-colyseus-server
|
|
47
|
+
cd my-colyseus-server
|
|
48
|
+
npm start
|
|
25
49
|
```
|
|
50
|
+
|
|
51
|
+
# Sponsors
|
|
52
|
+
|
|
53
|
+
The sustainability of the project relies on **Colyseus Cloud** subscriptions and sponsorships. If you are not using Colyseus Cloud, please consider [sponsoring the project](https://github.com/sponsors/endel) 💖
|
|
54
|
+
|
|
55
|
+
<a href="https://cdn.jsdelivr.net/gh/colyseus/.github/sponsorkit/sponsors.svg">
|
|
56
|
+
<img src="https://cdn.jsdelivr.net/gh/colyseus/.github/sponsorkit/sponsors.svg" width="100%" />
|
|
57
|
+
</a>
|
|
58
|
+
|
|
59
|
+
# Contributors ✨
|
|
60
|
+
|
|
61
|
+
Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds/all-contributors#emoji-key)):
|
|
62
|
+
|
|
63
|
+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
64
|
+
<!-- prettier-ignore-start -->
|
|
65
|
+
<!-- markdownlint-disable -->
|
|
66
|
+
<table>
|
|
67
|
+
<tr>
|
|
68
|
+
<td align="center"><a href="https://github.com/halftheopposite/"><img src="https://avatars0.githubusercontent.com/u/5473864?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aymeric Chauvin</b></sub></a><br /><a href="#question-halftheopposite" title="Answering Questions">💬</a> <a href="#example-halftheopposite" title="Examples">💡</a></td>
|
|
69
|
+
<td align="center"><a href="https://github.com/brian-hay"><img src="https://avatars2.githubusercontent.com/u/1428000?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brian Hay</b></sub></a><br /><a href="#content-brian-hay" title="Content">🖋</a></td>
|
|
70
|
+
<td align="center"><a href="https://github.com/damian-pastorini"><img src="https://avatars2.githubusercontent.com/u/1211779?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Damian A. Pastorini</b></sub></a><br /><a href="#question-damian-pastorini" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/commits?author=damian-pastorini" title="Documentation">📖</a> <a href="https://github.com/colyseus/colyseus/issues?q=author%3Adamian-pastorini" title="Bug reports">🐛</a></td>
|
|
71
|
+
<td align="center"><a href="https://github.com/Zielak"><img src="https://avatars0.githubusercontent.com/u/625693?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Darek Greenly</b></sub></a><br /><a href="#question-Zielak" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/issues?q=author%3AZielak" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=Zielak" title="Code">💻</a></td>
|
|
72
|
+
<td align="center"><a href="https://github.com/Vidski"><img src="https://avatars.githubusercontent.com/u/36316706?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Rydwanski</b></sub></a><br /><a href="#question-Vidski" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/commits?author=Vidski" title="Code">💻</a></td>
|
|
73
|
+
<td align="center"><a href="https://github.com/drburton"><img src="https://avatars0.githubusercontent.com/u/625595?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dr. Burton</b></sub></a><br /><a href="#mentoring-drburton" title="Mentoring">🧑🏫</a></td>
|
|
74
|
+
<td align="center"><a href="https://twitter.com/endel"><img src="https://avatars3.githubusercontent.com/u/130494?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Endel Dreyer</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/commits?author=endel" title="Code">💻</a> <a href="https://github.com/colyseus/colyseus/commits?author=endel" title="Documentation">📖</a> <a href="#example-endel" title="Examples">💡</a></td>
|
|
75
|
+
</tr>
|
|
76
|
+
<tr>
|
|
77
|
+
<td align="center"><a href="https://github.com/enriqueto"><img src="https://avatars2.githubusercontent.com/u/5557196?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Enriqueto</b></sub></a><br /><a href="#business-enriqueto" title="Business development">💼</a></td>
|
|
78
|
+
<td align="center"><a href="https://github.com/fazriz"><img src="https://avatars0.githubusercontent.com/u/2628698?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fazri Zubair</b></sub></a><br /><a href="#business-fazriz" title="Business development">💼</a></td>
|
|
79
|
+
<td align="center"><a href="https://twitter.com/Federkun"><img src="https://avatars2.githubusercontent.com/u/21344385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Federico</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/issues?q=author%3AFederkun" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=Federkun" title="Code">💻</a></td>
|
|
80
|
+
<td align="center"><a href="https://github.com/mobyjames/"><img src="https://avatars0.githubusercontent.com/u/1327007?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Jacoby</b></sub></a><br /><a href="#question-mobyjames" title="Answering Questions">💬</a> <a href="#example-mobyjames" title="Examples">💡</a> <a href="#content-mobyjames" title="Content">🖋</a></td>
|
|
81
|
+
<td align="center"><a href="http://wenish.github.io/portfolio/"><img src="https://avatars0.githubusercontent.com/u/18367963?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jonas Voland</b></sub></a><br /><a href="#question-Wenish" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/issues?q=author%3AWenish" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=Wenish" title="Code">💻</a> <a href="#ideas-Wenish" title="Ideas, Planning, & Feedback">🤔</a> <a href="#example-Wenish" title="Examples">💡</a></td>
|
|
82
|
+
<td align="center"><a href="http://seiyria.com"><img src="https://avatars0.githubusercontent.com/u/763609?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kyle J. Kemp</b></sub></a><br /><a href="#question-seiyria" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/issues?q=author%3Aseiyria" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=seiyria" title="Code">💻</a> <a href="#ideas-seiyria" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
83
|
+
<td align="center"><a href="https://github.com/LukeWood/"><img src="https://avatars0.githubusercontent.com/u/12191303?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Luke Wood</b></sub></a><br /><a href="#question-LukeWood" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/issues?q=author%3ALukeWood" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=LukeWood" title="Code">💻</a></td>
|
|
84
|
+
</tr>
|
|
85
|
+
<tr>
|
|
86
|
+
<td align="center"><a href="https://github.com/doorbash"><img src="https://avatars2.githubusercontent.com/u/5982526?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Milad Doorbash</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/issues?q=author%3Adoorbash" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=doorbash" title="Code">💻</a></td>
|
|
87
|
+
<td align="center"><a href="https://github.com/TinyDobbins"><img src="https://avatars2.githubusercontent.com/u/20824844?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nikita Borisov</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/issues?q=author%3ATinyDobbins" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=TinyDobbins" title="Code">💻</a> <a href="#business-TinyDobbins" title="Business development">💼</a> <a href="#ideas-TinyDobbins" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
88
|
+
<td align="center"><a href="https://acemobe.com/"><img src="https://avatars2.githubusercontent.com/u/232101?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Phil Harvey</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/commits?author=filharvey" title="Documentation">📖</a></td>
|
|
89
|
+
<td align="center"><a href="https://github.com/serjek"><img src="https://avatars2.githubusercontent.com/u/18265157?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sergey</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/issues?q=author%3Aserjek" title="Bug reports">🐛</a> <a href="https://github.com/colyseus/colyseus/commits?author=serjek" title="Code">💻</a></td>
|
|
90
|
+
<td align="center"><a href="https://oyed.io"><img src="https://avatars0.githubusercontent.com/u/853683?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tom</b></sub></a><br /><a href="#question-oyed" title="Answering Questions">💬</a> <a href="https://github.com/colyseus/colyseus/issues?q=author%3Aoyed" title="Bug reports">🐛</a> <a href="#ideas-oyed" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
91
|
+
<td align="center"><a href="https://github.com/supertommy"><img src="https://avatars0.githubusercontent.com/u/2236153?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tommy Leung</b></sub></a><br /><a href="#mentoring-supertommy" title="Mentoring">🧑🏫</a></td>
|
|
92
|
+
<td align="center"><a href="https://github.com/digimbyte"><img src="https://avatars2.githubusercontent.com/u/6645396?v=4?s=100" width="100px;" alt=""/><br /><sub><b>digimbyte</b></sub></a><br /><a href="https://github.com/colyseus/colyseus/commits?author=digimbyte" title="Documentation">📖</a></td>
|
|
93
|
+
</tr>
|
|
94
|
+
</table>
|
|
95
|
+
|
|
96
|
+
<!-- markdownlint-restore -->
|
|
97
|
+
<!-- prettier-ignore-end -->
|
|
98
|
+
|
|
99
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
100
|
+
|
|
101
|
+
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification.
|
|
102
|
+
Contributions of any kind are welcome!
|
|
103
|
+
|
|
104
|
+
# Contributing
|
|
105
|
+
|
|
106
|
+
We encourage you to contribute to Colyseus! Please check out the [Contributing
|
|
107
|
+
guide](.github/CONTRIBUTING.md) for guidelines about how to proceed. Join us!
|
|
108
|
+
|
|
109
|
+
Everyone interacting in Colyseus and its sub-projects' codebases, issue trackers
|
|
110
|
+
and chat rooms is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
|
|
111
|
+
|
|
112
|
+
# License
|
|
113
|
+
|
|
114
|
+
MIT
|
package/build/BunWebSockets.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import Bun, { ServerWebSocket, WebSocketHandler } from "bun";
|
|
1
|
+
import { ServerWebSocket, WebSocketHandler } from "bun";
|
|
4
2
|
import { Transport } from '@colyseus/core';
|
|
5
3
|
import { WebSocketWrapper } from './WebSocketClient';
|
|
6
|
-
import { Application, Request, Response } from "express";
|
|
4
|
+
import type { Application, Request, Response } from "express";
|
|
7
5
|
export type TransportOptions = Partial<Omit<WebSocketHandler, "message" | "open" | "drain" | "close" | "ping" | "pong">>;
|
|
8
6
|
interface WebSocketData {
|
|
9
7
|
url: URL;
|
|
@@ -12,8 +10,9 @@ export declare class BunWebSockets extends Transport {
|
|
|
12
10
|
private options;
|
|
13
11
|
expressApp: Application;
|
|
14
12
|
protected clients: ServerWebSocket<WebSocketData>[];
|
|
15
|
-
protected clientWrappers: WeakMap<
|
|
13
|
+
protected clientWrappers: WeakMap<ServerWebSocket<WebSocketData>, WebSocketWrapper>;
|
|
16
14
|
private _listening;
|
|
15
|
+
private _originalRawSend;
|
|
17
16
|
constructor(options?: TransportOptions);
|
|
18
17
|
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): this;
|
|
19
18
|
shutdown(): void;
|
package/build/BunWebSockets.js
CHANGED
|
@@ -33,6 +33,9 @@ class BunWebSockets extends import_core.Transport {
|
|
|
33
33
|
constructor(options = {}) {
|
|
34
34
|
super();
|
|
35
35
|
this.options = options;
|
|
36
|
+
this.clients = [];
|
|
37
|
+
this.clientWrappers = /* @__PURE__ */ new WeakMap();
|
|
38
|
+
this._originalRawSend = null;
|
|
36
39
|
const self = this;
|
|
37
40
|
this.expressApp = (0, import_bun_serve_express.default)({
|
|
38
41
|
websocket: {
|
|
@@ -57,10 +60,6 @@ class BunWebSockets extends import_core.Transport {
|
|
|
57
60
|
this.server = new import_core.DummyServer();
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
|
-
expressApp;
|
|
61
|
-
clients = [];
|
|
62
|
-
clientWrappers = /* @__PURE__ */ new WeakMap();
|
|
63
|
-
_listening;
|
|
64
63
|
listen(port, hostname, backlog, listeningListener) {
|
|
65
64
|
this._listening = this.expressApp.listen(port, listeningListener);
|
|
66
65
|
this.expressApp.use(`/${import_core.matchMaker.controller.matchmakeRoute}`, async (req, res) => {
|
|
@@ -83,8 +82,11 @@ class BunWebSockets extends import_core.Transport {
|
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
simulateLatency(milliseconds) {
|
|
86
|
-
|
|
87
|
-
|
|
85
|
+
if (this._originalRawSend == null) {
|
|
86
|
+
this._originalRawSend = import_WebSocketClient.WebSocketClient.prototype.raw;
|
|
87
|
+
}
|
|
88
|
+
const originalRawSend = this._originalRawSend;
|
|
89
|
+
import_WebSocketClient.WebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function() {
|
|
88
90
|
setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);
|
|
89
91
|
};
|
|
90
92
|
}
|
|
@@ -109,20 +111,27 @@ class BunWebSockets extends import_core.Transport {
|
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
async handleMatchMakeRequest(req, res) {
|
|
114
|
+
const writeHeaders = (req2, res2) => {
|
|
115
|
+
if (res2.destroyed)
|
|
116
|
+
return;
|
|
117
|
+
res2.set(Object.assign(
|
|
118
|
+
{},
|
|
119
|
+
import_core.matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
120
|
+
import_core.matchMaker.controller.getCorsHeaders.call(void 0, req2)
|
|
121
|
+
));
|
|
122
|
+
return true;
|
|
123
|
+
};
|
|
112
124
|
try {
|
|
113
125
|
switch (req.method) {
|
|
114
126
|
case "OPTIONS": {
|
|
115
|
-
res
|
|
116
|
-
{},
|
|
117
|
-
import_core.matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
118
|
-
import_core.matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
119
|
-
));
|
|
127
|
+
writeHeaders(req, res);
|
|
120
128
|
res.status(200).end();
|
|
121
129
|
break;
|
|
122
130
|
}
|
|
123
131
|
case "GET": {
|
|
124
132
|
const matchedParams = req.path.match(import_core.matchMaker.controller.allowedRoomNameChars);
|
|
125
133
|
const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : "";
|
|
134
|
+
writeHeaders(req, res);
|
|
126
135
|
res.json(await import_core.matchMaker.controller.getAvailableRooms(roomName || ""));
|
|
127
136
|
break;
|
|
128
137
|
}
|
|
@@ -132,24 +141,32 @@ class BunWebSockets extends import_core.Transport {
|
|
|
132
141
|
}
|
|
133
142
|
const matchedParams = req.path.match(import_core.matchMaker.controller.allowedRoomNameChars);
|
|
134
143
|
const matchmakeIndex = matchedParams.indexOf(import_core.matchMaker.controller.matchmakeRoute);
|
|
135
|
-
|
|
136
|
-
if (clientOptions
|
|
144
|
+
let clientOptions = req.body;
|
|
145
|
+
if (clientOptions == null) {
|
|
137
146
|
throw new import_core.ServerError(500, "invalid JSON input");
|
|
138
147
|
}
|
|
148
|
+
if (typeof clientOptions === "string" && clientOptions.length > 2) {
|
|
149
|
+
clientOptions = JSON.parse(clientOptions);
|
|
150
|
+
} else if (typeof clientOptions !== "object") {
|
|
151
|
+
clientOptions = {};
|
|
152
|
+
}
|
|
139
153
|
const method = matchedParams[matchmakeIndex + 1];
|
|
140
154
|
const roomName = matchedParams[matchmakeIndex + 2] || "";
|
|
141
|
-
|
|
155
|
+
writeHeaders(req, res);
|
|
156
|
+
res.json(await import_core.matchMaker.controller.invokeMethod(
|
|
157
|
+
method,
|
|
158
|
+
roomName,
|
|
159
|
+
clientOptions,
|
|
160
|
+
{ token: (0, import_core.getBearerToken)(req.headers["authorization"]), request: req }
|
|
161
|
+
));
|
|
142
162
|
break;
|
|
143
163
|
}
|
|
144
164
|
default:
|
|
145
165
|
throw new import_core.ServerError(500, "invalid request method");
|
|
146
166
|
}
|
|
147
167
|
} catch (e) {
|
|
148
|
-
res
|
|
149
|
-
|
|
150
|
-
import_core.matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
151
|
-
import_core.matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
152
|
-
)).status(500).json({ code: e.code, error: e.message });
|
|
168
|
+
writeHeaders(req, res);
|
|
169
|
+
res.status(500).json({ code: e.code, error: e.message });
|
|
153
170
|
}
|
|
154
171
|
}
|
|
155
172
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BunWebSockets.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
6
|
-
"names": ["bunExpress"]
|
|
4
|
+
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { ServerWebSocket, WebSocketHandler } from \"bun\";\n\nimport type http from 'http';\nimport bunExpress from \"bun-serve-express\";\n\nimport { DummyServer, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError, getBearerToken } from '@colyseus/core';\nimport { WebSocketClient, WebSocketWrapper } from './WebSocketClient';\nimport type { Application, Request, Response } from \"express\";\n\nexport type TransportOptions = Partial<Omit<WebSocketHandler, \"message\" | \"open\" | \"drain\" | \"close\" | \"ping\" | \"pong\">>;\n\ninterface WebSocketData {\n url: URL;\n // query: string,\n // headers: { [key: string]: string },\n // connection: { remoteAddress: string },\n}\n\nexport class BunWebSockets extends Transport {\n public expressApp: Application;\n\n protected clients: ServerWebSocket<WebSocketData>[] = [];\n protected clientWrappers = new WeakMap<ServerWebSocket<WebSocketData>, WebSocketWrapper>();\n\n private _listening: any;\n private _originalRawSend: typeof WebSocketClient.prototype.raw | null = null;\n\n constructor(private options: TransportOptions = {}) {\n super();\n\n const self = this;\n\n this.expressApp = bunExpress({\n websocket: {\n ...this.options,\n\n async open(ws) {\n await self.onConnection(ws);\n },\n\n message(ws, message) {\n // this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n self.clientWrappers.get(ws)?.emit('message', message);\n },\n\n close(ws, code, reason) {\n // remove from client list\n spliceOne(self.clients, self.clients.indexOf(ws));\n\n const clientWrapper = self.clientWrappers.get(ws);\n if (clientWrapper) {\n self.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n }\n });\n\n // Adding a mock object for Transport.server\n if (!this.server) {\n this.server = new DummyServer();\n }\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this._listening = this.expressApp.listen(port, listeningListener);\n\n this.expressApp.use(`/${matchMaker.controller.matchmakeRoute}`, async (req, res) => {\n try {\n await this.handleMatchMakeRequest(req, res);\n } catch (e) {\n res.status(500).json({\n code: e.code,\n error: e.message\n });\n }\n });\n\n // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n // @ts-ignore\n this.server.emit(\"listening\");\n\n return this;\n }\n\n public shutdown() {\n if (this._listening) {\n this._listening.close();\n\n // @ts-ignore\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n if (this._originalRawSend == null) {\n this._originalRawSend = WebSocketClient.prototype.raw;\n }\n\n const originalRawSend = this._originalRawSend;\n WebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function () {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n };\n }\n\n protected async onConnection(rawClient: ServerWebSocket<WebSocketData>) {\n const wrapper = new WebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const parsedURL = new URL(rawClient.data.url);\n\n const sessionId = parsedURL.searchParams.get(\"sessionId\");\n const processAndRoomId = parsedURL.pathname.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new WebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, parsedURL.searchParams.get(\"reconnectionToken\") as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected async handleMatchMakeRequest(req: Request, res: Response) {\n const writeHeaders = (req: Request, res: Response) => {\n if (res.destroyed) return;\n\n res.set(Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n ));\n\n return true;\n };\n\n try {\n switch (req.method) {\n case 'OPTIONS': {\n writeHeaders(req, res);\n res.status(200).end();\n break;\n }\n\n case 'GET': {\n const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n writeHeaders(req, res);\n res.json(await matchMaker.controller.getAvailableRooms(roomName || ''));\n break;\n }\n\n case 'POST': {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.isGracefullyShuttingDown) {\n throw new ServerError(503, \"server is shutting down\");\n }\n\n const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n let clientOptions = req.body; // Bun.readableStreamToJSON(req.body);\n\n if (clientOptions == null) {\n throw new ServerError(500, \"invalid JSON input\");\n }\n\n if (typeof clientOptions === 'string' && clientOptions.length > 2) {\n clientOptions = JSON.parse(clientOptions);\n } else if (typeof clientOptions !== 'object') {\n clientOptions = {};\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n writeHeaders(req, res);\n res.json(await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n { token: getBearerToken(req.headers['authorization']), request: req },\n ));\n break;\n }\n\n default: throw new ServerError(500, \"invalid request method\");\n }\n\n } catch (e) {\n writeHeaders(req, res);\n res.status(500)\n .json({ code: e.code, error: e.message });\n }\n }\n\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,+BAAuB;AAEvB,kBAA+G;AAC/G,6BAAkD;AAY3C,MAAM,sBAAsB,sBAAU;AAAA,EAS3C,YAAoB,UAA4B,CAAC,GAAG;AAClD,UAAM;AADY;AANpB,SAAU,UAA4C,CAAC;AACvD,SAAU,iBAAiB,oBAAI,QAA0D;AAGzF,SAAQ,mBAAgE;AAKtE,UAAM,OAAO;AAEb,SAAK,iBAAa,yBAAAA,SAAW;AAAA,MAC3B,WAAW;AAAA,QACT,GAAG,KAAK;AAAA,QAER,MAAM,KAAK,IAAI;AACb,gBAAM,KAAK,aAAa,EAAE;AAAA,QAC5B;AAAA,QAEA,QAAQ,IAAI,SAAS;AAEnB,eAAK,eAAe,IAAI,EAAE,GAAG,KAAK,WAAW,OAAO;AAAA,QACtD;AAAA,QAEA,MAAM,IAAI,MAAM,QAAQ;AAEtB,qCAAU,KAAK,SAAS,KAAK,QAAQ,QAAQ,EAAE,CAAC;AAEhD,gBAAM,gBAAgB,KAAK,eAAe,IAAI,EAAE;AAChD,cAAI,eAAe;AACjB,iBAAK,eAAe,OAAO,EAAE;AAG7B,0BAAc,KAAK,SAAS,IAAI;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAGD,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS,IAAI,wBAAY;AAAA,IAChC;AAAA,EACF;AAAA,EAEO,OAAO,MAAc,UAAmB,SAAkB,mBAAgC;AAC/F,SAAK,aAAa,KAAK,WAAW,OAAO,MAAM,iBAAiB;AAEhE,SAAK,WAAW,IAAI,IAAI,uBAAW,WAAW,kBAAkB,OAAO,KAAK,QAAQ;AAClF,UAAI;AACF,cAAM,KAAK,uBAAuB,KAAK,GAAG;AAAA,MAC5C,SAAS,GAAP;AACA,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,MAAM,EAAE;AAAA,UACR,OAAO,EAAE;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAID,SAAK,OAAO,KAAK,WAAW;AAE5B,WAAO;AAAA,EACT;AAAA,EAEO,WAAW;AAChB,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,MAAM;AAGtB,WAAK,OAAO,KAAK,OAAO;AAAA,IAC1B;AAAA,EACF;AAAA,EAEO,gBAAgB,cAAsB;AAC3C,QAAI,KAAK,oBAAoB,MAAM;AACjC,WAAK,mBAAmB,uCAAgB,UAAU;AAAA,IACpD;AAEA,UAAM,kBAAkB,KAAK;AAC7B,2CAAgB,UAAU,MAAM,gBAAgB,OAAO,UAAU,kBAAkB,WAAY;AAC7F,iBAAW,MAAM,gBAAgB,MAAM,MAAM,SAAS,GAAG,YAAY;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,MAAgB,aAAa,WAA2C;AACtE,UAAM,UAAU,IAAI,wCAAiB,SAAS;AAE9C,SAAK,QAAQ,KAAK,SAAS;AAC3B,SAAK,eAAe,IAAI,WAAW,OAAO;AAE1C,UAAM,YAAY,IAAI,IAAI,UAAU,KAAK,GAAG;AAE5C,UAAM,YAAY,UAAU,aAAa,IAAI,WAAW;AACxD,UAAM,mBAAmB,UAAU,SAAS,MAAM,uCAAuC;AACzF,UAAM,SAAS,oBAAoB,iBAAiB;AAEpD,UAAM,OAAO,uBAAW,YAAY,MAAM;AAC1C,UAAM,SAAS,IAAI,uCAAgB,WAAW,OAAO;AAMrD,QAAI;AACF,UAAI,CAAC,QAAQ,CAAC,KAAK,gBAAgB,WAAW,UAAU,aAAa,IAAI,mBAAmB,CAAW,GAAG;AACxG,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AAEA,YAAM,KAAK,QAAQ,QAAQ,SAA4C;AAAA,IAEzE,SAAS,GAAP;AACA,0CAAmB,CAAC;AAGpB,aAAO,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,UAAU,MAAM,CAAC;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAgB,uBAAuB,KAAc,KAAe;AAClE,UAAM,eAAe,CAACC,MAAcC,SAAkB;AACpD,UAAIA,KAAI;AAAW;AAEnB,MAAAA,KAAI,IAAI,OAAO;AAAA,QACb,CAAC;AAAA,QACD,uBAAW,WAAW;AAAA,QACtB,uBAAW,WAAW,eAAe,KAAK,QAAWD,IAAG;AAAA,MAC1D,CAAC;AAED,aAAO;AAAA,IACT;AAEA,QAAI;AACF,cAAQ,IAAI;AAAA,aACL,WAAW;AACd,uBAAa,KAAK,GAAG;AACrB,cAAI,OAAO,GAAG,EAAE,IAAI;AACpB;AAAA,QACF;AAAA,aAEK,OAAO;AACV,gBAAM,gBAAgB,IAAI,KAAK,MAAM,uBAAW,WAAW,oBAAoB;AAC/E,gBAAM,WAAW,cAAc,SAAS,IAAI,cAAc,cAAc,SAAS,KAAK;AAEtF,uBAAa,KAAK,GAAG;AACrB,cAAI,KAAK,MAAM,uBAAW,WAAW,kBAAkB,YAAY,EAAE,CAAC;AACtE;AAAA,QACF;AAAA,aAEK,QAAQ;AAEX,cAAI,uBAAW,0BAA0B;AACvC,kBAAM,IAAI,wBAAY,KAAK,yBAAyB;AAAA,UACtD;AAEA,gBAAM,gBAAgB,IAAI,KAAK,MAAM,uBAAW,WAAW,oBAAoB;AAC/E,gBAAM,iBAAiB,cAAc,QAAQ,uBAAW,WAAW,cAAc;AACjF,cAAI,gBAAgB,IAAI;AAExB,cAAI,iBAAiB,MAAM;AACzB,kBAAM,IAAI,wBAAY,KAAK,oBAAoB;AAAA,UACjD;AAEA,cAAI,OAAO,kBAAkB,YAAY,cAAc,SAAS,GAAG;AACjE,4BAAgB,KAAK,MAAM,aAAa;AAAA,UAC1C,WAAW,OAAO,kBAAkB,UAAU;AAC5C,4BAAgB,CAAC;AAAA,UACnB;AAEA,gBAAM,SAAS,cAAc,iBAAiB;AAC9C,gBAAM,WAAW,cAAc,iBAAiB,MAAM;AAEtD,uBAAa,KAAK,GAAG;AACrB,cAAI,KAAK,MAAM,uBAAW,WAAW;AAAA,YACnC;AAAA,YACA;AAAA,YACA;AAAA,YACA,EAAE,WAAO,4BAAe,IAAI,QAAQ,gBAAgB,GAAG,SAAS,IAAI;AAAA,UACtE,CAAC;AACD;AAAA,QACF;AAAA;AAES,gBAAM,IAAI,wBAAY,KAAK,wBAAwB;AAAA;AAAA,IAGhE,SAAS,GAAP;AACA,mBAAa,KAAK,GAAG;AACrB,UAAI,OAAO,GAAG,EACX,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,QAAQ,CAAC;AAAA,IAC5C;AAAA,EACF;AAEF;",
|
|
6
|
+
"names": ["bunExpress", "req", "res"]
|
|
7
7
|
}
|
package/build/BunWebSockets.mjs
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import bunExpress from "bun-serve-express";
|
|
2
|
-
import { DummyServer, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError } from "@colyseus/core";
|
|
2
|
+
import { DummyServer, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError, getBearerToken } from "@colyseus/core";
|
|
3
3
|
import { WebSocketClient, WebSocketWrapper } from "./WebSocketClient";
|
|
4
4
|
class BunWebSockets extends Transport {
|
|
5
5
|
constructor(options = {}) {
|
|
6
6
|
super();
|
|
7
7
|
this.options = options;
|
|
8
|
+
this.clients = [];
|
|
9
|
+
this.clientWrappers = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
this._originalRawSend = null;
|
|
8
11
|
const self = this;
|
|
9
12
|
this.expressApp = bunExpress({
|
|
10
13
|
websocket: {
|
|
@@ -29,10 +32,6 @@ class BunWebSockets extends Transport {
|
|
|
29
32
|
this.server = new DummyServer();
|
|
30
33
|
}
|
|
31
34
|
}
|
|
32
|
-
expressApp;
|
|
33
|
-
clients = [];
|
|
34
|
-
clientWrappers = /* @__PURE__ */ new WeakMap();
|
|
35
|
-
_listening;
|
|
36
35
|
listen(port, hostname, backlog, listeningListener) {
|
|
37
36
|
this._listening = this.expressApp.listen(port, listeningListener);
|
|
38
37
|
this.expressApp.use(`/${matchMaker.controller.matchmakeRoute}`, async (req, res) => {
|
|
@@ -55,8 +54,11 @@ class BunWebSockets extends Transport {
|
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
56
|
simulateLatency(milliseconds) {
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
if (this._originalRawSend == null) {
|
|
58
|
+
this._originalRawSend = WebSocketClient.prototype.raw;
|
|
59
|
+
}
|
|
60
|
+
const originalRawSend = this._originalRawSend;
|
|
61
|
+
WebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function() {
|
|
60
62
|
setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);
|
|
61
63
|
};
|
|
62
64
|
}
|
|
@@ -81,20 +83,27 @@ class BunWebSockets extends Transport {
|
|
|
81
83
|
}
|
|
82
84
|
}
|
|
83
85
|
async handleMatchMakeRequest(req, res) {
|
|
86
|
+
const writeHeaders = (req2, res2) => {
|
|
87
|
+
if (res2.destroyed)
|
|
88
|
+
return;
|
|
89
|
+
res2.set(Object.assign(
|
|
90
|
+
{},
|
|
91
|
+
matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
92
|
+
matchMaker.controller.getCorsHeaders.call(void 0, req2)
|
|
93
|
+
));
|
|
94
|
+
return true;
|
|
95
|
+
};
|
|
84
96
|
try {
|
|
85
97
|
switch (req.method) {
|
|
86
98
|
case "OPTIONS": {
|
|
87
|
-
res
|
|
88
|
-
{},
|
|
89
|
-
matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
90
|
-
matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
91
|
-
));
|
|
99
|
+
writeHeaders(req, res);
|
|
92
100
|
res.status(200).end();
|
|
93
101
|
break;
|
|
94
102
|
}
|
|
95
103
|
case "GET": {
|
|
96
104
|
const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);
|
|
97
105
|
const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : "";
|
|
106
|
+
writeHeaders(req, res);
|
|
98
107
|
res.json(await matchMaker.controller.getAvailableRooms(roomName || ""));
|
|
99
108
|
break;
|
|
100
109
|
}
|
|
@@ -104,24 +113,32 @@ class BunWebSockets extends Transport {
|
|
|
104
113
|
}
|
|
105
114
|
const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);
|
|
106
115
|
const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);
|
|
107
|
-
|
|
108
|
-
if (clientOptions
|
|
116
|
+
let clientOptions = req.body;
|
|
117
|
+
if (clientOptions == null) {
|
|
109
118
|
throw new ServerError(500, "invalid JSON input");
|
|
110
119
|
}
|
|
120
|
+
if (typeof clientOptions === "string" && clientOptions.length > 2) {
|
|
121
|
+
clientOptions = JSON.parse(clientOptions);
|
|
122
|
+
} else if (typeof clientOptions !== "object") {
|
|
123
|
+
clientOptions = {};
|
|
124
|
+
}
|
|
111
125
|
const method = matchedParams[matchmakeIndex + 1];
|
|
112
126
|
const roomName = matchedParams[matchmakeIndex + 2] || "";
|
|
113
|
-
|
|
127
|
+
writeHeaders(req, res);
|
|
128
|
+
res.json(await matchMaker.controller.invokeMethod(
|
|
129
|
+
method,
|
|
130
|
+
roomName,
|
|
131
|
+
clientOptions,
|
|
132
|
+
{ token: getBearerToken(req.headers["authorization"]), request: req }
|
|
133
|
+
));
|
|
114
134
|
break;
|
|
115
135
|
}
|
|
116
136
|
default:
|
|
117
137
|
throw new ServerError(500, "invalid request method");
|
|
118
138
|
}
|
|
119
139
|
} catch (e) {
|
|
120
|
-
res
|
|
121
|
-
|
|
122
|
-
matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
123
|
-
matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
124
|
-
)).status(500).json({ code: e.code, error: e.message });
|
|
140
|
+
writeHeaders(req, res);
|
|
141
|
+
res.status(500).json({ code: e.code, error: e.message });
|
|
125
142
|
}
|
|
126
143
|
}
|
|
127
144
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BunWebSockets.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { ServerWebSocket, WebSocketHandler } from \"bun\";\n\nimport type http from 'http';\nimport bunExpress from \"bun-serve-express\";\n\nimport { DummyServer, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError, getBearerToken } from '@colyseus/core';\nimport { WebSocketClient, WebSocketWrapper } from './WebSocketClient';\nimport type { Application, Request, Response } from \"express\";\n\nexport type TransportOptions = Partial<Omit<WebSocketHandler, \"message\" | \"open\" | \"drain\" | \"close\" | \"ping\" | \"pong\">>;\n\ninterface WebSocketData {\n url: URL;\n // query: string,\n // headers: { [key: string]: string },\n // connection: { remoteAddress: string },\n}\n\nexport class BunWebSockets extends Transport {\n public expressApp: Application;\n\n protected clients: ServerWebSocket<WebSocketData>[] = [];\n protected clientWrappers = new WeakMap<ServerWebSocket<WebSocketData>, WebSocketWrapper>();\n\n private _listening: any;\n private _originalRawSend: typeof WebSocketClient.prototype.raw | null = null;\n\n constructor(private options: TransportOptions = {}) {\n super();\n\n const self = this;\n\n this.expressApp = bunExpress({\n websocket: {\n ...this.options,\n\n async open(ws) {\n await self.onConnection(ws);\n },\n\n message(ws, message) {\n // this.clientWrappers.get(ws)?.emit('message', Buffer.from(message.slice(0)));\n self.clientWrappers.get(ws)?.emit('message', message);\n },\n\n close(ws, code, reason) {\n // remove from client list\n spliceOne(self.clients, self.clients.indexOf(ws));\n\n const clientWrapper = self.clientWrappers.get(ws);\n if (clientWrapper) {\n self.clientWrappers.delete(ws);\n\n // emit 'close' on wrapper\n clientWrapper.emit('close', code);\n }\n },\n }\n });\n\n // Adding a mock object for Transport.server\n if (!this.server) {\n this.server = new DummyServer();\n }\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n this._listening = this.expressApp.listen(port, listeningListener);\n\n this.expressApp.use(`/${matchMaker.controller.matchmakeRoute}`, async (req, res) => {\n try {\n await this.handleMatchMakeRequest(req, res);\n } catch (e) {\n res.status(500).json({\n code: e.code,\n error: e.message\n });\n }\n });\n\n // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n // @ts-ignore\n this.server.emit(\"listening\");\n\n return this;\n }\n\n public shutdown() {\n if (this._listening) {\n this._listening.close();\n\n // @ts-ignore\n this.server.emit(\"close\"); // Mocking Transport.server behaviour, https://github.com/colyseus/colyseus/issues/458\n }\n }\n\n public simulateLatency(milliseconds: number) {\n if (this._originalRawSend == null) {\n this._originalRawSend = WebSocketClient.prototype.raw;\n }\n\n const originalRawSend = this._originalRawSend;\n WebSocketClient.prototype.raw = milliseconds <= Number.EPSILON ? originalRawSend : function () {\n setTimeout(() => originalRawSend.apply(this, arguments), milliseconds);\n };\n }\n\n protected async onConnection(rawClient: ServerWebSocket<WebSocketData>) {\n const wrapper = new WebSocketWrapper(rawClient);\n // keep reference to client and its wrapper\n this.clients.push(rawClient);\n this.clientWrappers.set(rawClient, wrapper);\n\n const parsedURL = new URL(rawClient.data.url);\n\n const sessionId = parsedURL.searchParams.get(\"sessionId\");\n const processAndRoomId = parsedURL.pathname.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n const room = matchMaker.getRoomById(roomId);\n const client = new WebSocketClient(sessionId, wrapper);\n\n //\n // TODO: DRY code below with all transports\n //\n\n try {\n if (!room || !room.hasReservedSeat(sessionId, parsedURL.searchParams.get(\"reconnectionToken\") as string)) {\n throw new Error('seat reservation expired.');\n }\n\n await room._onJoin(client, rawClient as unknown as http.IncomingMessage);\n\n } catch (e) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () => rawClient.close());\n }\n }\n\n protected async handleMatchMakeRequest(req: Request, res: Response) {\n const writeHeaders = (req: Request, res: Response) => {\n if (res.destroyed) return;\n\n res.set(Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n ));\n\n return true;\n };\n\n try {\n switch (req.method) {\n case 'OPTIONS': {\n writeHeaders(req, res);\n res.status(200).end();\n break;\n }\n\n case 'GET': {\n const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);\n const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : \"\";\n\n writeHeaders(req, res);\n res.json(await matchMaker.controller.getAvailableRooms(roomName || ''));\n break;\n }\n\n case 'POST': {\n // do not accept matchmaking requests if already shutting down\n if (matchMaker.isGracefullyShuttingDown) {\n throw new ServerError(503, \"server is shutting down\");\n }\n\n const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);\n const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);\n let clientOptions = req.body; // Bun.readableStreamToJSON(req.body);\n\n if (clientOptions == null) {\n throw new ServerError(500, \"invalid JSON input\");\n }\n\n if (typeof clientOptions === 'string' && clientOptions.length > 2) {\n clientOptions = JSON.parse(clientOptions);\n } else if (typeof clientOptions !== 'object') {\n clientOptions = {};\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n\n writeHeaders(req, res);\n res.json(await matchMaker.controller.invokeMethod(\n method,\n roomName,\n clientOptions,\n { token: getBearerToken(req.headers['authorization']), request: req },\n ));\n break;\n }\n\n default: throw new ServerError(500, \"invalid request method\");\n }\n\n } catch (e) {\n writeHeaders(req, res);\n res.status(500)\n .json({ code: e.code, error: e.message });\n }\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAOA,OAAO,gBAAgB;AAEvB,SAAS,aAAa,YAAY,WAAW,oBAAoB,WAAW,aAAa,sBAAsB;AAC/G,SAAS,iBAAiB,wBAAwB;AAY3C,MAAM,sBAAsB,UAAU;AAAA,EAS3C,YAAoB,UAA4B,CAAC,GAAG;AAClD,UAAM;AADY;AANpB,SAAU,UAA4C,CAAC;AACvD,SAAU,iBAAiB,oBAAI,QAA0D;AAGzF,SAAQ,mBAAgE;AAKtE,UAAM,OAAO;AAEb,SAAK,aAAa,WAAW;AAAA,MAC3B,WAAW;AAAA,QACT,GAAG,KAAK;AAAA,QAER,MAAM,KAAK,IAAI;AACb,gBAAM,KAAK,aAAa,EAAE;AAAA,QAC5B;AAAA,QAEA,QAAQ,IAAI,SAAS;AAEnB,eAAK,eAAe,IAAI,EAAE,GAAG,KAAK,WAAW,OAAO;AAAA,QACtD;AAAA,QAEA,MAAM,IAAI,MAAM,QAAQ;AAEtB,oBAAU,KAAK,SAAS,KAAK,QAAQ,QAAQ,EAAE,CAAC;AAEhD,gBAAM,gBAAgB,KAAK,eAAe,IAAI,EAAE;AAChD,cAAI,eAAe;AACjB,iBAAK,eAAe,OAAO,EAAE;AAG7B,0BAAc,KAAK,SAAS,IAAI;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAGD,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,SAAS,IAAI,YAAY;AAAA,IAChC;AAAA,EACF;AAAA,EAEO,OAAO,MAAc,UAAmB,SAAkB,mBAAgC;AAC/F,SAAK,aAAa,KAAK,WAAW,OAAO,MAAM,iBAAiB;AAEhE,SAAK,WAAW,IAAI,IAAI,WAAW,WAAW,kBAAkB,OAAO,KAAK,QAAQ;AAClF,UAAI;AACF,cAAM,KAAK,uBAAuB,KAAK,GAAG;AAAA,MAC5C,SAAS,GAAP;AACA,YAAI,OAAO,GAAG,EAAE,KAAK;AAAA,UACnB,MAAM,EAAE;AAAA,UACR,OAAO,EAAE;AAAA,QACX,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAID,SAAK,OAAO,KAAK,WAAW;AAE5B,WAAO;AAAA,EACT;AAAA,EAEO,WAAW;AAChB,QAAI,KAAK,YAAY;AACnB,WAAK,WAAW,MAAM;AAGtB,WAAK,OAAO,KAAK,OAAO;AAAA,IAC1B;AAAA,EACF;AAAA,EAEO,gBAAgB,cAAsB;AAC3C,QAAI,KAAK,oBAAoB,MAAM;AACjC,WAAK,mBAAmB,gBAAgB,UAAU;AAAA,IACpD;AAEA,UAAM,kBAAkB,KAAK;AAC7B,oBAAgB,UAAU,MAAM,gBAAgB,OAAO,UAAU,kBAAkB,WAAY;AAC7F,iBAAW,MAAM,gBAAgB,MAAM,MAAM,SAAS,GAAG,YAAY;AAAA,IACvE;AAAA,EACF;AAAA,EAEA,MAAgB,aAAa,WAA2C;AACtE,UAAM,UAAU,IAAI,iBAAiB,SAAS;AAE9C,SAAK,QAAQ,KAAK,SAAS;AAC3B,SAAK,eAAe,IAAI,WAAW,OAAO;AAE1C,UAAM,YAAY,IAAI,IAAI,UAAU,KAAK,GAAG;AAE5C,UAAM,YAAY,UAAU,aAAa,IAAI,WAAW;AACxD,UAAM,mBAAmB,UAAU,SAAS,MAAM,uCAAuC;AACzF,UAAM,SAAS,oBAAoB,iBAAiB;AAEpD,UAAM,OAAO,WAAW,YAAY,MAAM;AAC1C,UAAM,SAAS,IAAI,gBAAgB,WAAW,OAAO;AAMrD,QAAI;AACF,UAAI,CAAC,QAAQ,CAAC,KAAK,gBAAgB,WAAW,UAAU,aAAa,IAAI,mBAAmB,CAAW,GAAG;AACxG,cAAM,IAAI,MAAM,2BAA2B;AAAA,MAC7C;AAEA,YAAM,KAAK,QAAQ,QAAQ,SAA4C;AAAA,IAEzE,SAAS,GAAP;AACA,yBAAmB,CAAC;AAGpB,aAAO,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,UAAU,MAAM,CAAC;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAgB,uBAAuB,KAAc,KAAe;AAClE,UAAM,eAAe,CAACA,MAAcC,SAAkB;AACpD,UAAIA,KAAI;AAAW;AAEnB,MAAAA,KAAI,IAAI,OAAO;AAAA,QACb,CAAC;AAAA,QACD,WAAW,WAAW;AAAA,QACtB,WAAW,WAAW,eAAe,KAAK,QAAWD,IAAG;AAAA,MAC1D,CAAC;AAED,aAAO;AAAA,IACT;AAEA,QAAI;AACF,cAAQ,IAAI;AAAA,aACL,WAAW;AACd,uBAAa,KAAK,GAAG;AACrB,cAAI,OAAO,GAAG,EAAE,IAAI;AACpB;AAAA,QACF;AAAA,aAEK,OAAO;AACV,gBAAM,gBAAgB,IAAI,KAAK,MAAM,WAAW,WAAW,oBAAoB;AAC/E,gBAAM,WAAW,cAAc,SAAS,IAAI,cAAc,cAAc,SAAS,KAAK;AAEtF,uBAAa,KAAK,GAAG;AACrB,cAAI,KAAK,MAAM,WAAW,WAAW,kBAAkB,YAAY,EAAE,CAAC;AACtE;AAAA,QACF;AAAA,aAEK,QAAQ;AAEX,cAAI,WAAW,0BAA0B;AACvC,kBAAM,IAAI,YAAY,KAAK,yBAAyB;AAAA,UACtD;AAEA,gBAAM,gBAAgB,IAAI,KAAK,MAAM,WAAW,WAAW,oBAAoB;AAC/E,gBAAM,iBAAiB,cAAc,QAAQ,WAAW,WAAW,cAAc;AACjF,cAAI,gBAAgB,IAAI;AAExB,cAAI,iBAAiB,MAAM;AACzB,kBAAM,IAAI,YAAY,KAAK,oBAAoB;AAAA,UACjD;AAEA,cAAI,OAAO,kBAAkB,YAAY,cAAc,SAAS,GAAG;AACjE,4BAAgB,KAAK,MAAM,aAAa;AAAA,UAC1C,WAAW,OAAO,kBAAkB,UAAU;AAC5C,4BAAgB,CAAC;AAAA,UACnB;AAEA,gBAAM,SAAS,cAAc,iBAAiB;AAC9C,gBAAM,WAAW,cAAc,iBAAiB,MAAM;AAEtD,uBAAa,KAAK,GAAG;AACrB,cAAI,KAAK,MAAM,WAAW,WAAW;AAAA,YACnC;AAAA,YACA;AAAA,YACA;AAAA,YACA,EAAE,OAAO,eAAe,IAAI,QAAQ,gBAAgB,GAAG,SAAS,IAAI;AAAA,UACtE,CAAC;AACD;AAAA,QACF;AAAA;AAES,gBAAM,IAAI,YAAY,KAAK,wBAAwB;AAAA;AAAA,IAGhE,SAAS,GAAP;AACA,mBAAa,KAAK,GAAG;AACrB,UAAI,OAAO,GAAG,EACX,KAAK,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,QAAQ,CAAC;AAAA,IAC5C;AAAA,EACF;AAEF;",
|
|
6
|
+
"names": ["req", "res"]
|
|
7
7
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/// <reference types="
|
|
1
|
+
/// <reference types="node" />
|
|
2
2
|
import { ServerWebSocket } from "bun";
|
|
3
3
|
import EventEmitter from 'events';
|
|
4
4
|
import { Client, ClientState, ISendOptions } from '@colyseus/core';
|
|
@@ -20,11 +20,11 @@ export declare class WebSocketClient implements Client {
|
|
|
20
20
|
enqueueRaw(data: ArrayLike<number>, options?: ISendOptions): void;
|
|
21
21
|
raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void): void;
|
|
22
22
|
error(code: number, message?: string, cb?: (err?: Error) => void): void;
|
|
23
|
-
get readyState():
|
|
23
|
+
get readyState(): any;
|
|
24
24
|
leave(code?: number, data?: string): void;
|
|
25
25
|
close(code?: number, data?: string): void;
|
|
26
26
|
toJSON(): {
|
|
27
27
|
sessionId: string;
|
|
28
|
-
readyState:
|
|
28
|
+
readyState: any;
|
|
29
29
|
};
|
|
30
30
|
}
|
package/build/WebSocketClient.js
CHANGED
|
@@ -40,13 +40,10 @@ class WebSocketClient {
|
|
|
40
40
|
constructor(id, ref) {
|
|
41
41
|
this.id = id;
|
|
42
42
|
this.ref = ref;
|
|
43
|
+
this.state = import_core.ClientState.JOINING;
|
|
44
|
+
this._enqueuedMessages = [];
|
|
43
45
|
this.sessionId = id;
|
|
44
46
|
}
|
|
45
|
-
sessionId;
|
|
46
|
-
state = import_core.ClientState.JOINING;
|
|
47
|
-
_enqueuedMessages = [];
|
|
48
|
-
_afterNextPatchQueue;
|
|
49
|
-
_reconnectionToken;
|
|
50
47
|
sendBytes(type, bytes, options) {
|
|
51
48
|
(0, import_core.debugMessage)("send bytes(to %s): '%s' -> %j", this.sessionId, type, bytes);
|
|
52
49
|
this.enqueueRaw(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/WebSocketClient.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
4
|
+
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { ServerWebSocket } from \"bun\";\nimport EventEmitter from 'events';\n\nimport { Protocol, Client, ClientState, ISendOptions, getMessageBytes, logger, debugMessage } from '@colyseus/core';\nimport { Schema } from '@colyseus/schema';\n\nexport class WebSocketWrapper extends EventEmitter {\n constructor(public ws: ServerWebSocket<any>) {\n super();\n }\n}\n\nexport class WebSocketClient implements Client {\n public sessionId: string;\n public state: ClientState = ClientState.JOINING;\n public _enqueuedMessages: any[] = [];\n public _afterNextPatchQueue;\n public _reconnectionToken: string;\n\n constructor(\n public id: string,\n public ref: WebSocketWrapper,\n ) {\n this.sessionId = id;\n }\n\n public sendBytes(type: string | number, bytes: number[] | Uint8Array, options?: ISendOptions) {\n debugMessage(\"send bytes(to %s): '%s' -> %j\", this.sessionId, type, bytes);\n\n this.enqueueRaw(\n getMessageBytes.raw(Protocol.ROOM_DATA_BYTES, type, undefined, bytes),\n options,\n );\n }\n\n public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {\n debugMessage(\"send(to %s): '%s' -> %j\", this.sessionId, messageOrType, messageOrOptions);\n\n this.enqueueRaw(\n (messageOrType instanceof Schema)\n ? getMessageBytes[Protocol.ROOM_DATA_SCHEMA](messageOrType)\n : getMessageBytes.raw(Protocol.ROOM_DATA, messageOrType, messageOrOptions),\n options,\n );\n }\n\n public enqueueRaw(data: ArrayLike<number>, options?: ISendOptions) {\n // use room's afterNextPatch queue\n if (options?.afterNextPatch) {\n this._afterNextPatchQueue.push([this, arguments]);\n return;\n }\n\n if (this.state === ClientState.JOINING) {\n // sending messages during `onJoin`.\n // - the client-side cannot register \"onMessage\" callbacks at this point.\n // - enqueue the messages to be send after JOIN_ROOM message has been sent\n this._enqueuedMessages.push(data);\n return;\n }\n\n this.raw(data, options);\n }\n\n public raw(data: ArrayLike<number>, options?: ISendOptions, cb?: (err?: Error) => void) {\n // skip if client not open\n\n // WebSocket is globally available on Bun runtime\n // @ts-ignore\n if (this.ref.ws.readyState !== WebSocket.OPEN) {\n return;\n }\n\n // FIXME: can we avoid creating a new buffer here?\n this.ref.ws.sendBinary(Buffer.from(data as unknown as ArrayBufferLike));\n }\n\n public error(code: number, message: string = '', cb?: (err?: Error) => void) {\n this.raw(getMessageBytes[Protocol.ERROR](code, message), undefined, cb);\n }\n\n get readyState() {\n return this.ref.ws.readyState;\n }\n\n public leave(code?: number, data?: string) {\n this.ref.ws.close(code, data);\n }\n\n public close(code?: number, data?: string) {\n logger.warn('DEPRECATION WARNING: use client.leave() instead of client.close()');\n try {\n throw new Error();\n } catch (e) {\n logger.info(e.stack);\n }\n this.leave(code, data);\n }\n\n public toJSON() {\n return { sessionId: this.sessionId, readyState: this.readyState };\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,oBAAyB;AAEzB,kBAAmG;AACnG,oBAAuB;AAEhB,MAAM,yBAAyB,cAAAA,QAAa;AAAA,EACjD,YAAmB,IAA0B;AAC3C,UAAM;AADW;AAAA,EAEnB;AACF;AAEO,MAAM,gBAAkC;AAAA,EAO7C,YACS,IACA,KACP;AAFO;AACA;AAPT,SAAO,QAAqB,wBAAY;AACxC,SAAO,oBAA2B,CAAC;AAQjC,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,UAAU,MAAuB,OAA8B,SAAwB;AAC5F,kCAAa,iCAAiC,KAAK,WAAW,MAAM,KAAK;AAEzE,SAAK;AAAA,MACH,4BAAgB,IAAI,qBAAS,iBAAiB,MAAM,QAAW,KAAK;AAAA,MACpE;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KAAK,eAAoB,kBAAuC,SAAwB;AAC7F,kCAAa,2BAA2B,KAAK,WAAW,eAAe,gBAAgB;AAEvF,SAAK;AAAA,MACF,yBAAyB,uBACtB,4BAAgB,qBAAS,kBAAkB,aAAa,IACxD,4BAAgB,IAAI,qBAAS,WAAW,eAAe,gBAAgB;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AAAA,EAEO,WAAW,MAAyB,SAAwB;AAEjE,QAAI,SAAS,gBAAgB;AAC3B,WAAK,qBAAqB,KAAK,CAAC,MAAM,SAAS,CAAC;AAChD;AAAA,IACF;AAEA,QAAI,KAAK,UAAU,wBAAY,SAAS;AAItC,WAAK,kBAAkB,KAAK,IAAI;AAChC;AAAA,IACF;AAEA,SAAK,IAAI,MAAM,OAAO;AAAA,EACxB;AAAA,EAEO,IAAI,MAAyB,SAAwB,IAA4B;AAKtF,QAAI,KAAK,IAAI,GAAG,eAAe,UAAU,MAAM;AAC7C;AAAA,IACF;AAGA,SAAK,IAAI,GAAG,WAAW,OAAO,KAAK,IAAkC,CAAC;AAAA,EACxE;AAAA,EAEO,MAAM,MAAc,UAAkB,IAAI,IAA4B;AAC3E,SAAK,IAAI,4BAAgB,qBAAS,OAAO,MAAM,OAAO,GAAG,QAAW,EAAE;AAAA,EACxE;AAAA,EAEA,IAAI,aAAa;AACf,WAAO,KAAK,IAAI,GAAG;AAAA,EACrB;AAAA,EAEO,MAAM,MAAe,MAAe;AACzC,SAAK,IAAI,GAAG,MAAM,MAAM,IAAI;AAAA,EAC9B;AAAA,EAEO,MAAM,MAAe,MAAe;AACzC,uBAAO,KAAK,mEAAmE;AAC/E,QAAI;AACF,YAAM,IAAI,MAAM;AAAA,IAClB,SAAS,GAAP;AACA,yBAAO,KAAK,EAAE,KAAK;AAAA,IACrB;AACA,SAAK,MAAM,MAAM,IAAI;AAAA,EACvB;AAAA,EAEO,SAAS;AACd,WAAO,EAAE,WAAW,KAAK,WAAW,YAAY,KAAK,WAAW;AAAA,EAClE;AACF;",
|
|
6
6
|
"names": ["EventEmitter"]
|
|
7
7
|
}
|
|
@@ -11,13 +11,10 @@ class WebSocketClient {
|
|
|
11
11
|
constructor(id, ref) {
|
|
12
12
|
this.id = id;
|
|
13
13
|
this.ref = ref;
|
|
14
|
+
this.state = ClientState.JOINING;
|
|
15
|
+
this._enqueuedMessages = [];
|
|
14
16
|
this.sessionId = id;
|
|
15
17
|
}
|
|
16
|
-
sessionId;
|
|
17
|
-
state = ClientState.JOINING;
|
|
18
|
-
_enqueuedMessages = [];
|
|
19
|
-
_afterNextPatchQueue;
|
|
20
|
-
_reconnectionToken;
|
|
21
18
|
sendBytes(type, bytes, options) {
|
|
22
19
|
debugMessage("send bytes(to %s): '%s' -> %j", this.sessionId, type, bytes);
|
|
23
20
|
this.enqueueRaw(
|