@colyseus/bun-websockets 0.15.0-alpha.4 → 0.15.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.
- package/README.md +18 -4
- package/build/BunWebSockets.js +8 -6
- package/build/BunWebSockets.js.map +3 -3
- package/build/BunWebSockets.mjs +9 -7
- package/build/BunWebSockets.mjs.map +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,11 +1,25 @@
|
|
|
1
|
-
# @colyseus/bun-websockets
|
|
1
|
+
# @colyseus/bun-websockets
|
|
2
|
+
|
|
3
|
+
From your `app.config.ts`:
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import config from "@colyseus/tools";
|
|
7
|
+
import { BunWebSockets } from "@colyseus/bun-websockets";
|
|
8
|
+
|
|
9
|
+
export default config({
|
|
10
|
+
initializeTransport: () => new BunWebSockets(),
|
|
11
|
+
// ...
|
|
12
|
+
});
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Alternatively, if you instantiate the `Server` yourself:
|
|
2
16
|
|
|
3
17
|
```typescript
|
|
4
|
-
import { Server } from "
|
|
5
|
-
import { BunWebsockets } from "@colyseus/
|
|
18
|
+
import { Server } from "colyseus";
|
|
19
|
+
import { BunWebsockets } from "@colyseus/bun-websockets";
|
|
6
20
|
|
|
7
21
|
const gameServer = new Server({
|
|
8
22
|
transport: new BunWebsockets(),
|
|
9
23
|
// ...
|
|
10
24
|
})
|
|
11
|
-
```
|
|
25
|
+
```
|
package/build/BunWebSockets.js
CHANGED
|
@@ -26,7 +26,6 @@ __export(BunWebSockets_exports, {
|
|
|
26
26
|
BunWebSockets: () => BunWebSockets
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(BunWebSockets_exports);
|
|
29
|
-
var import_bun = __toESM(require("bun"));
|
|
30
29
|
var import_bun_serve_express = __toESM(require("bun-serve-express"));
|
|
31
30
|
var import_core = require("@colyseus/core");
|
|
32
31
|
var import_WebSocketClient = require("./WebSocketClient");
|
|
@@ -68,7 +67,7 @@ class BunWebSockets extends import_core.Transport {
|
|
|
68
67
|
try {
|
|
69
68
|
await this.handleMatchMakeRequest(req, res);
|
|
70
69
|
} catch (e) {
|
|
71
|
-
res.status(
|
|
70
|
+
res.status(500).json({
|
|
72
71
|
code: e.code,
|
|
73
72
|
error: e.message
|
|
74
73
|
});
|
|
@@ -119,11 +118,13 @@ class BunWebSockets extends import_core.Transport {
|
|
|
119
118
|
import_core.matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
120
119
|
));
|
|
121
120
|
res.status(200).end();
|
|
121
|
+
break;
|
|
122
122
|
}
|
|
123
123
|
case "GET": {
|
|
124
124
|
const matchedParams = req.path.match(import_core.matchMaker.controller.allowedRoomNameChars);
|
|
125
125
|
const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : "";
|
|
126
126
|
res.json(await import_core.matchMaker.controller.getAvailableRooms(roomName || ""));
|
|
127
|
+
break;
|
|
127
128
|
}
|
|
128
129
|
case "POST": {
|
|
129
130
|
if (import_core.matchMaker.isGracefullyShuttingDown) {
|
|
@@ -131,23 +132,24 @@ class BunWebSockets extends import_core.Transport {
|
|
|
131
132
|
}
|
|
132
133
|
const matchedParams = req.path.match(import_core.matchMaker.controller.allowedRoomNameChars);
|
|
133
134
|
const matchmakeIndex = matchedParams.indexOf(import_core.matchMaker.controller.matchmakeRoute);
|
|
134
|
-
const clientOptions =
|
|
135
|
+
const clientOptions = req.body;
|
|
135
136
|
if (clientOptions === void 0) {
|
|
136
|
-
throw new
|
|
137
|
+
throw new import_core.ServerError(500, "invalid JSON input");
|
|
137
138
|
}
|
|
138
139
|
const method = matchedParams[matchmakeIndex + 1];
|
|
139
140
|
const roomName = matchedParams[matchmakeIndex + 2] || "";
|
|
140
141
|
res.json(await import_core.matchMaker.controller.invokeMethod(method, roomName, clientOptions));
|
|
142
|
+
break;
|
|
141
143
|
}
|
|
142
144
|
default:
|
|
143
|
-
throw new
|
|
145
|
+
throw new import_core.ServerError(500, "invalid request method");
|
|
144
146
|
}
|
|
145
147
|
} catch (e) {
|
|
146
148
|
res.set(Object.assign(
|
|
147
149
|
{},
|
|
148
150
|
import_core.matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
149
151
|
import_core.matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
150
|
-
)).status(
|
|
152
|
+
)).status(500).json({ code: e.code, error: e.message });
|
|
151
153
|
}
|
|
152
154
|
}
|
|
153
155
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BunWebSockets.ts"],
|
|
4
|
-
"sourcesContent": ["/// <reference types=\"bun-types\" />\nimport Bun, {
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
6
|
-
"names": ["bunExpress"
|
|
4
|
+
"sourcesContent": ["/// <reference types=\"bun-types\" />\nimport Bun, { ServerWebSocket, WebSocketHandler } from \"bun\";\n\nimport http from 'http';\nimport bunExpress from \"bun-serve-express\";\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError } from '@colyseus/core';\nimport { WebSocketClient, WebSocketWrapper } from './WebSocketClient';\nimport { 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\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 const originalRawSend = WebSocketClient.prototype.raw;\n WebSocketClient.prototype.raw = 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 try {\n switch (req.method) {\n case 'OPTIONS': {\n res.set(Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n ));\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 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 const clientOptions = req.body; // Bun.readableStreamToJSON(req.body);\n\n if (clientOptions === undefined) {\n throw new ServerError(500, \"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n res.json(await matchMaker.controller.invokeMethod(method, roomName, clientOptions));\n break;\n }\n\n default: throw new ServerError(500, \"invalid request method\");\n }\n\n } catch (e) {\n res\n .set(Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n ))\n .status(500)\n .json({ code: e.code, error: e.message });\n }\n\n }\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["bunExpress"]
|
|
7
7
|
}
|
package/build/BunWebSockets.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import Bun from "bun";
|
|
2
1
|
import bunExpress from "bun-serve-express";
|
|
3
|
-
import { DummyServer,
|
|
2
|
+
import { DummyServer, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError } from "@colyseus/core";
|
|
4
3
|
import { WebSocketClient, WebSocketWrapper } from "./WebSocketClient";
|
|
5
4
|
class BunWebSockets extends Transport {
|
|
6
5
|
constructor(options = {}) {
|
|
@@ -40,7 +39,7 @@ class BunWebSockets extends Transport {
|
|
|
40
39
|
try {
|
|
41
40
|
await this.handleMatchMakeRequest(req, res);
|
|
42
41
|
} catch (e) {
|
|
43
|
-
res.status(
|
|
42
|
+
res.status(500).json({
|
|
44
43
|
code: e.code,
|
|
45
44
|
error: e.message
|
|
46
45
|
});
|
|
@@ -91,11 +90,13 @@ class BunWebSockets extends Transport {
|
|
|
91
90
|
matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
92
91
|
));
|
|
93
92
|
res.status(200).end();
|
|
93
|
+
break;
|
|
94
94
|
}
|
|
95
95
|
case "GET": {
|
|
96
96
|
const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);
|
|
97
97
|
const roomName = matchedParams.length > 1 ? matchedParams[matchedParams.length - 1] : "";
|
|
98
98
|
res.json(await matchMaker.controller.getAvailableRooms(roomName || ""));
|
|
99
|
+
break;
|
|
99
100
|
}
|
|
100
101
|
case "POST": {
|
|
101
102
|
if (matchMaker.isGracefullyShuttingDown) {
|
|
@@ -103,23 +104,24 @@ class BunWebSockets extends Transport {
|
|
|
103
104
|
}
|
|
104
105
|
const matchedParams = req.path.match(matchMaker.controller.allowedRoomNameChars);
|
|
105
106
|
const matchmakeIndex = matchedParams.indexOf(matchMaker.controller.matchmakeRoute);
|
|
106
|
-
const clientOptions =
|
|
107
|
+
const clientOptions = req.body;
|
|
107
108
|
if (clientOptions === void 0) {
|
|
108
|
-
throw new
|
|
109
|
+
throw new ServerError(500, "invalid JSON input");
|
|
109
110
|
}
|
|
110
111
|
const method = matchedParams[matchmakeIndex + 1];
|
|
111
112
|
const roomName = matchedParams[matchmakeIndex + 2] || "";
|
|
112
113
|
res.json(await matchMaker.controller.invokeMethod(method, roomName, clientOptions));
|
|
114
|
+
break;
|
|
113
115
|
}
|
|
114
116
|
default:
|
|
115
|
-
throw new
|
|
117
|
+
throw new ServerError(500, "invalid request method");
|
|
116
118
|
}
|
|
117
119
|
} catch (e) {
|
|
118
120
|
res.set(Object.assign(
|
|
119
121
|
{},
|
|
120
122
|
matchMaker.controller.DEFAULT_CORS_HEADERS,
|
|
121
123
|
matchMaker.controller.getCorsHeaders.call(void 0, req)
|
|
122
|
-
)).status(
|
|
124
|
+
)).status(500).json({ code: e.code, error: e.message });
|
|
123
125
|
}
|
|
124
126
|
}
|
|
125
127
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BunWebSockets.ts"],
|
|
4
|
-
"sourcesContent": ["/// <reference types=\"bun-types\" />\nimport Bun, {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["/// <reference types=\"bun-types\" />\nimport Bun, { ServerWebSocket, WebSocketHandler } from \"bun\";\n\nimport http from 'http';\nimport bunExpress from \"bun-serve-express\";\n\nimport { DummyServer, ErrorCode, matchMaker, Transport, debugAndPrintError, spliceOne, ServerError } from '@colyseus/core';\nimport { WebSocketClient, WebSocketWrapper } from './WebSocketClient';\nimport { 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\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 const originalRawSend = WebSocketClient.prototype.raw;\n WebSocketClient.prototype.raw = 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 try {\n switch (req.method) {\n case 'OPTIONS': {\n res.set(Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n ));\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 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 const clientOptions = req.body; // Bun.readableStreamToJSON(req.body);\n\n if (clientOptions === undefined) {\n throw new ServerError(500, \"invalid JSON input\");\n }\n\n const method = matchedParams[matchmakeIndex + 1];\n const roomName = matchedParams[matchmakeIndex + 2] || '';\n res.json(await matchMaker.controller.invokeMethod(method, roomName, clientOptions));\n break;\n }\n\n default: throw new ServerError(500, \"invalid request method\");\n }\n\n } catch (e) {\n res\n .set(Object.assign(\n {},\n matchMaker.controller.DEFAULT_CORS_HEADERS,\n matchMaker.controller.getCorsHeaders.call(undefined, req)\n ))\n .status(500)\n .json({ code: e.code, error: e.message });\n }\n\n }\n\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/bun-websockets",
|
|
3
|
-
"version": "0.15.0
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"input": "./src/index.ts",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"module": "./build/index.mjs",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "45e71fef81d12583a6e925982567aa4e7aca215f"
|
|
41
41
|
}
|