@colyseus/bun-websockets 0.17.6 → 0.17.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/BunWebSockets.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// packages/transport/bun-websockets/src/BunWebSockets.ts
|
|
@@ -24,6 +34,7 @@ __export(BunWebSockets_exports, {
|
|
|
24
34
|
});
|
|
25
35
|
module.exports = __toCommonJS(BunWebSockets_exports);
|
|
26
36
|
var import_bun = require("bun");
|
|
37
|
+
var import_express = __toESM(require("express"), 1);
|
|
27
38
|
var import_core = require("@colyseus/core");
|
|
28
39
|
var import_WebSocketClient = require("./WebSocketClient.cjs");
|
|
29
40
|
var BunWebSockets = class extends import_core.Transport {
|
|
@@ -37,10 +48,7 @@ var BunWebSockets = class extends import_core.Transport {
|
|
|
37
48
|
}
|
|
38
49
|
getExpressApp() {
|
|
39
50
|
if (!this._expressApp) {
|
|
40
|
-
|
|
41
|
-
console.warn("\u274C Error: Express integration not yet implemented for BunWebSockets");
|
|
42
|
-
console.warn(" Please use bindRouter() instead or consider using uWebSocketsTransport");
|
|
43
|
-
console.warn("");
|
|
51
|
+
this._expressApp = (0, import_express.default)();
|
|
44
52
|
}
|
|
45
53
|
return this._expressApp;
|
|
46
54
|
}
|
|
@@ -171,7 +179,7 @@ var BunWebSockets = class extends import_core.Transport {
|
|
|
171
179
|
});
|
|
172
180
|
} catch (e) {
|
|
173
181
|
(0, import_core.debugAndPrintError)(e);
|
|
174
|
-
client.error(e.code, e.message, () => rawClient.close());
|
|
182
|
+
client.error(e.code, e.message, () => rawClient.close(reconnectionToken ? import_core.CloseCode.FAILED_TO_RECONNECT : import_core.CloseCode.WITH_ERROR));
|
|
175
183
|
}
|
|
176
184
|
}
|
|
177
185
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BunWebSockets.ts"],
|
|
4
|
-
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { Server, ServerWebSocket, WebSocketHandler } from 'bun';\nimport
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { Server, ServerWebSocket, WebSocketHandler } from 'bun';\nimport express, { type Application } from \"express\";\nimport type { Router } from '@colyseus/core';\n\nimport { matchMaker, Protocol, Transport, debugAndPrintError, getBearerToken, CloseCode, connectClientToRoom, spliceOne } from '@colyseus/core';\nimport { WebSocketClient, WebSocketWrapper } from './WebSocketClient.ts';\n\n// Bun global is available at runtime\ndeclare const Bun: any;\n\nexport type TransportOptions = Partial<Omit<WebSocketHandler<WebSocketData>, \"message\" | \"open\" | \"drain\" | \"close\" | \"ping\" | \"pong\">>;\n\ninterface WebSocketData {\n url: string;\n searchParams: URLSearchParams;\n headers: Headers;\n remoteAddress: string;\n}\n\nexport class BunWebSockets extends Transport {\n protected clients: ServerWebSocket<WebSocketData>[] = [];\n protected clientWrappers = new WeakMap<ServerWebSocket<WebSocketData>, WebSocketWrapper>();\n\n private _server: Server<WebSocketData> | undefined;\n private _expressApp: Application | undefined;\n private _router: Router | undefined;\n private _originalRawSend: typeof WebSocketClient.prototype.raw | null = null;\n private options: TransportOptions = {};\n\n constructor(options: TransportOptions = {}) {\n super();\n this.options = options;\n }\n\n public getExpressApp(): Application {\n if (!this._expressApp) {\n this._expressApp = express();\n }\n return this._expressApp;\n }\n\n public bindRouter(router: Router) {\n this._router = router;\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n const self = this;\n\n this._server = Bun.serve({\n port,\n hostname,\n\n async fetch(req, server) {\n const url = new URL(req.url);\n\n // Try to upgrade to WebSocket\n if (server.upgrade(req, {\n data: {\n url: url.pathname + url.search,\n searchParams: url.searchParams,\n headers: req.headers as Headers,\n remoteAddress: server.requestIP(req)?.address || 'unknown',\n }\n })) {\n return; // WebSocket upgrade successful\n }\n\n // Handle HTTP requests through router\n if (self._router) {\n try {\n // Write CORS headers\n const corsHeaders = {\n ...matchMaker.controller.DEFAULT_CORS_HEADERS,\n ...matchMaker.controller.getCorsHeaders(req.headers)\n };\n\n // Handle OPTIONS requests\n if (req.method === \"OPTIONS\") {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n const response = await self._router.handler(req);\n\n // Add CORS headers to response\n const headers = new Headers(response.headers);\n Object.entries(corsHeaders).forEach(([key, value]) => {\n if (!headers.has(key)) {\n headers.set(key, value.toString());\n }\n });\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers\n });\n\n } catch (e: any) {\n debugAndPrintError(e);\n return new Response(JSON.stringify({\n code: e.code,\n error: e.message\n }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' }\n });\n }\n }\n\n // Fallback to express app if available\n if (self._expressApp) {\n // TODO: Implement express integration for Bun\n console.warn(\"Express integration not yet implemented for BunWebSockets\");\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n\n websocket: {\n ...this.options,\n\n async open(ws) {\n await self.onConnection(ws);\n },\n\n message(ws, message) {\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 listeningListener?.();\n\n return this;\n }\n\n public shutdown() {\n if (this._server) {\n this._server.stop();\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 (...args: any[]) {\n let [buf, ...rest] = args;\n buf = Buffer.from(buf);\n // @ts-ignore\n setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), 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 url = rawClient.data.url;\n const searchParams = rawClient.data.searchParams;\n\n const sessionId = searchParams.get(\"sessionId\");\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n // If sessionId is not provided, allow ping-pong utility.\n if (!sessionId && !roomId) {\n // Disconnect automatically after 1 second if no message is received.\n const timeout = setTimeout(() => rawClient.close(CloseCode.NORMAL_CLOSURE), 1000);\n wrapper.on('message', (_) => rawClient.send(new Uint8Array([Protocol.PING])));\n wrapper.on('close', () => clearTimeout(timeout));\n return;\n }\n\n const room = matchMaker.getLocalRoomById(roomId);\n const client = new WebSocketClient(sessionId, wrapper);\n const reconnectionToken = searchParams.get(\"reconnectionToken\");\n const skipHandshake = searchParams.has(\"skipHandshake\");\n\n try {\n await connectClientToRoom(room, client, {\n token: searchParams.get(\"_authToken\") ?? getBearerToken(rawClient.data.headers['authorization']),\n headers: rawClient.data.headers,\n ip: rawClient.data.headers['x-real-ip'] ?? rawClient.data.headers['x-forwarded-for'] ?? rawClient.data.remoteAddress,\n }, {\n reconnectionToken,\n skipHandshake\n });\n\n } catch (e: any) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () =>\n rawClient.close(reconnectionToken\n ? CloseCode.FAILED_TO_RECONNECT\n : CloseCode.WITH_ERROR));\n }\n }\n\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,iBAA0D;AAC1D,qBAA2C;AAG3C,kBAA+H;AAC/H,6BAAkD;AAc3C,IAAM,gBAAN,cAA4B,sBAAU;AAAA,EAU3C,YAAY,UAA4B,CAAC,GAAG;AAC1C,UAAM;AAVR,SAAU,UAA4C,CAAC;AACvD,SAAU,iBAAiB,oBAAI,QAA0D;AAKzF,SAAQ,mBAAgE;AACxE,SAAQ,UAA4B,CAAC;AAInC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,gBAA6B;AAClC,QAAI,CAAC,KAAK,aAAa;AACrB,WAAK,kBAAc,eAAAA,SAAQ;AAAA,IAC7B;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,WAAW,QAAgB;AAChC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,OAAO,MAAc,UAAmB,SAAkB,mBAAgC;AAC/F,UAAM,OAAO;AAEb,SAAK,UAAU,IAAI,MAAM;AAAA,MACvB;AAAA,MACA;AAAA,MAEA,MAAM,MAAM,KAAK,QAAQ;AACvB,cAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAG3B,YAAI,OAAO,QAAQ,KAAK;AAAA,UACtB,MAAM;AAAA,YACJ,KAAK,IAAI,WAAW,IAAI;AAAA,YACxB,cAAc,IAAI;AAAA,YAClB,SAAS,IAAI;AAAA,YACb,eAAe,OAAO,UAAU,GAAG,GAAG,WAAW;AAAA,UACnD;AAAA,QACF,CAAC,GAAG;AACF;AAAA,QACF;AAGA,YAAI,KAAK,SAAS;AAChB,cAAI;AAEF,kBAAM,cAAc;AAAA,cAClB,GAAG,uBAAW,WAAW;AAAA,cACzB,GAAG,uBAAW,WAAW,eAAe,IAAI,OAAO;AAAA,YACrD;AAGA,gBAAI,IAAI,WAAW,WAAW;AAC5B,qBAAO,IAAI,SAAS,MAAM;AAAA,gBACxB,QAAQ;AAAA,gBACR,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAEA,kBAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,GAAG;AAG/C,kBAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,mBAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpD,kBAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACrB,wBAAQ,IAAI,KAAK,MAAM,SAAS,CAAC;AAAA,cACnC;AAAA,YACF,CAAC;AAED,mBAAO,IAAI,SAAS,SAAS,MAAM;AAAA,cACjC,QAAQ,SAAS;AAAA,cACjB,YAAY,SAAS;AAAA,cACrB;AAAA,YACF,CAAC;AAAA,UAEH,SAAS,GAAQ;AACf,gDAAmB,CAAC;AACpB,mBAAO,IAAI,SAAS,KAAK,UAAU;AAAA,cACjC,MAAM,EAAE;AAAA,cACR,OAAO,EAAE;AAAA,YACX,CAAC,GAAG;AAAA,cACF,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAChD,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,KAAK,aAAa;AAEpB,kBAAQ,KAAK,2DAA2D;AAAA,QAC1E;AAEA,eAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClD;AAAA,MAEA,WAAW;AAAA,QACT,GAAG,KAAK;AAAA,QAER,MAAM,KAAK,IAAI;AACb,gBAAM,KAAK,aAAa,EAAE;AAAA,QAC5B;AAAA,QAEA,QAAQ,IAAI,SAAS;AACnB,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;AAED,wBAAoB;AAEpB,WAAO;AAAA,EACT;AAAA,EAEO,WAAW;AAChB,QAAI,KAAK,SAAS;AAChB,WAAK,QAAQ,KAAK;AAAA,IACpB;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,YAAa,MAAa;AAC3G,UAAI,CAAC,KAAK,GAAG,IAAI,IAAI;AACrB,YAAM,OAAO,KAAK,GAAG;AAErB,iBAAW,MAAM,gBAAgB,MAAM,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,YAAY;AAAA,IAC5E;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,MAAM,UAAU,KAAK;AAC3B,UAAM,eAAe,UAAU,KAAK;AAEpC,UAAM,YAAY,aAAa,IAAI,WAAW;AAC9C,UAAM,mBAAmB,IAAI,MAAM,uCAAuC;AAC1E,UAAM,SAAS,oBAAoB,iBAAiB,CAAC;AAGrD,QAAI,CAAC,aAAa,CAAC,QAAQ;AAEzB,YAAM,UAAU,WAAW,MAAM,UAAU,MAAM,sBAAU,cAAc,GAAG,GAAI;AAChF,cAAQ,GAAG,WAAW,CAAC,MAAM,UAAU,KAAK,IAAI,WAAW,CAAC,qBAAS,IAAI,CAAC,CAAC,CAAC;AAC5E,cAAQ,GAAG,SAAS,MAAM,aAAa,OAAO,CAAC;AAC/C;AAAA,IACF;AAEA,UAAM,OAAO,uBAAW,iBAAiB,MAAM;AAC/C,UAAM,SAAS,IAAI,uCAAgB,WAAW,OAAO;AACrD,UAAM,oBAAoB,aAAa,IAAI,mBAAmB;AAC9D,UAAM,gBAAgB,aAAa,IAAI,eAAe;AAEtD,QAAI;AACF,gBAAM,iCAAoB,MAAM,QAAQ;AAAA,QACtC,OAAO,aAAa,IAAI,YAAY,SAAK,4BAAe,UAAU,KAAK,QAAQ,eAAe,CAAC;AAAA,QAC/F,SAAS,UAAU,KAAK;AAAA,QACxB,IAAI,UAAU,KAAK,QAAQ,WAAW,KAAK,UAAU,KAAK,QAAQ,iBAAiB,KAAK,UAAU,KAAK;AAAA,MACzG,GAAG;AAAA,QACD;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IAEH,SAAS,GAAQ;AACf,0CAAmB,CAAC;AAGpB,aAAO,MAAM,EAAE,MAAM,EAAE,SAAS,MAC9B,UAAU,MAAM,oBACZ,sBAAU,sBACV,sBAAU,UAAU,CAAC;AAAA,IAC7B;AAAA,EACF;AAEF;",
|
|
6
|
+
"names": ["express"]
|
|
7
7
|
}
|
package/build/BunWebSockets.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ServerWebSocket, WebSocketHandler } from 'bun';
|
|
2
|
-
import type
|
|
2
|
+
import { type Application } from "express";
|
|
3
3
|
import type { Router } from '@colyseus/core';
|
|
4
4
|
import { Transport } from '@colyseus/core';
|
|
5
5
|
import { WebSocketWrapper } from './WebSocketClient.ts';
|
package/build/BunWebSockets.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// packages/transport/bun-websockets/src/BunWebSockets.ts
|
|
2
2
|
import "bun";
|
|
3
|
+
import express from "express";
|
|
3
4
|
import { matchMaker, Protocol, Transport, debugAndPrintError, getBearerToken, CloseCode, connectClientToRoom, spliceOne } from "@colyseus/core";
|
|
4
5
|
import { WebSocketClient, WebSocketWrapper } from "./WebSocketClient.mjs";
|
|
5
6
|
var BunWebSockets = class extends Transport {
|
|
@@ -13,10 +14,7 @@ var BunWebSockets = class extends Transport {
|
|
|
13
14
|
}
|
|
14
15
|
getExpressApp() {
|
|
15
16
|
if (!this._expressApp) {
|
|
16
|
-
|
|
17
|
-
console.warn("\u274C Error: Express integration not yet implemented for BunWebSockets");
|
|
18
|
-
console.warn(" Please use bindRouter() instead or consider using uWebSocketsTransport");
|
|
19
|
-
console.warn("");
|
|
17
|
+
this._expressApp = express();
|
|
20
18
|
}
|
|
21
19
|
return this._expressApp;
|
|
22
20
|
}
|
|
@@ -147,7 +145,7 @@ var BunWebSockets = class extends Transport {
|
|
|
147
145
|
});
|
|
148
146
|
} catch (e) {
|
|
149
147
|
debugAndPrintError(e);
|
|
150
|
-
client.error(e.code, e.message, () => rawClient.close());
|
|
148
|
+
client.error(e.code, e.message, () => rawClient.close(reconnectionToken ? CloseCode.FAILED_TO_RECONNECT : CloseCode.WITH_ERROR));
|
|
151
149
|
}
|
|
152
150
|
}
|
|
153
151
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BunWebSockets.ts"],
|
|
4
|
-
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { Server, ServerWebSocket, WebSocketHandler } from 'bun';\nimport
|
|
5
|
-
"mappings": ";AAIA,OAA0D;
|
|
4
|
+
"sourcesContent": ["// <reference types=\"bun-types\" />\n\n// \"bun-types\" is currently conflicting with \"ws\" types.\n// @ts-ignore\nimport { Server, ServerWebSocket, WebSocketHandler } from 'bun';\nimport express, { type Application } from \"express\";\nimport type { Router } from '@colyseus/core';\n\nimport { matchMaker, Protocol, Transport, debugAndPrintError, getBearerToken, CloseCode, connectClientToRoom, spliceOne } from '@colyseus/core';\nimport { WebSocketClient, WebSocketWrapper } from './WebSocketClient.ts';\n\n// Bun global is available at runtime\ndeclare const Bun: any;\n\nexport type TransportOptions = Partial<Omit<WebSocketHandler<WebSocketData>, \"message\" | \"open\" | \"drain\" | \"close\" | \"ping\" | \"pong\">>;\n\ninterface WebSocketData {\n url: string;\n searchParams: URLSearchParams;\n headers: Headers;\n remoteAddress: string;\n}\n\nexport class BunWebSockets extends Transport {\n protected clients: ServerWebSocket<WebSocketData>[] = [];\n protected clientWrappers = new WeakMap<ServerWebSocket<WebSocketData>, WebSocketWrapper>();\n\n private _server: Server<WebSocketData> | undefined;\n private _expressApp: Application | undefined;\n private _router: Router | undefined;\n private _originalRawSend: typeof WebSocketClient.prototype.raw | null = null;\n private options: TransportOptions = {};\n\n constructor(options: TransportOptions = {}) {\n super();\n this.options = options;\n }\n\n public getExpressApp(): Application {\n if (!this._expressApp) {\n this._expressApp = express();\n }\n return this._expressApp;\n }\n\n public bindRouter(router: Router) {\n this._router = router;\n }\n\n public listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void) {\n const self = this;\n\n this._server = Bun.serve({\n port,\n hostname,\n\n async fetch(req, server) {\n const url = new URL(req.url);\n\n // Try to upgrade to WebSocket\n if (server.upgrade(req, {\n data: {\n url: url.pathname + url.search,\n searchParams: url.searchParams,\n headers: req.headers as Headers,\n remoteAddress: server.requestIP(req)?.address || 'unknown',\n }\n })) {\n return; // WebSocket upgrade successful\n }\n\n // Handle HTTP requests through router\n if (self._router) {\n try {\n // Write CORS headers\n const corsHeaders = {\n ...matchMaker.controller.DEFAULT_CORS_HEADERS,\n ...matchMaker.controller.getCorsHeaders(req.headers)\n };\n\n // Handle OPTIONS requests\n if (req.method === \"OPTIONS\") {\n return new Response(null, {\n status: 204,\n headers: corsHeaders\n });\n }\n\n const response = await self._router.handler(req);\n\n // Add CORS headers to response\n const headers = new Headers(response.headers);\n Object.entries(corsHeaders).forEach(([key, value]) => {\n if (!headers.has(key)) {\n headers.set(key, value.toString());\n }\n });\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers\n });\n\n } catch (e: any) {\n debugAndPrintError(e);\n return new Response(JSON.stringify({\n code: e.code,\n error: e.message\n }), {\n status: 500,\n headers: { 'Content-Type': 'application/json' }\n });\n }\n }\n\n // Fallback to express app if available\n if (self._expressApp) {\n // TODO: Implement express integration for Bun\n console.warn(\"Express integration not yet implemented for BunWebSockets\");\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n\n websocket: {\n ...this.options,\n\n async open(ws) {\n await self.onConnection(ws);\n },\n\n message(ws, message) {\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 listeningListener?.();\n\n return this;\n }\n\n public shutdown() {\n if (this._server) {\n this._server.stop();\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 (...args: any[]) {\n let [buf, ...rest] = args;\n buf = Buffer.from(buf);\n // @ts-ignore\n setTimeout(() => originalRawSend.apply(this, [buf, ...rest]), 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 url = rawClient.data.url;\n const searchParams = rawClient.data.searchParams;\n\n const sessionId = searchParams.get(\"sessionId\");\n const processAndRoomId = url.match(/\\/[a-zA-Z0-9_\\-]+\\/([a-zA-Z0-9_\\-]+)$/);\n const roomId = processAndRoomId && processAndRoomId[1];\n\n // If sessionId is not provided, allow ping-pong utility.\n if (!sessionId && !roomId) {\n // Disconnect automatically after 1 second if no message is received.\n const timeout = setTimeout(() => rawClient.close(CloseCode.NORMAL_CLOSURE), 1000);\n wrapper.on('message', (_) => rawClient.send(new Uint8Array([Protocol.PING])));\n wrapper.on('close', () => clearTimeout(timeout));\n return;\n }\n\n const room = matchMaker.getLocalRoomById(roomId);\n const client = new WebSocketClient(sessionId, wrapper);\n const reconnectionToken = searchParams.get(\"reconnectionToken\");\n const skipHandshake = searchParams.has(\"skipHandshake\");\n\n try {\n await connectClientToRoom(room, client, {\n token: searchParams.get(\"_authToken\") ?? getBearerToken(rawClient.data.headers['authorization']),\n headers: rawClient.data.headers,\n ip: rawClient.data.headers['x-real-ip'] ?? rawClient.data.headers['x-forwarded-for'] ?? rawClient.data.remoteAddress,\n }, {\n reconnectionToken,\n skipHandshake\n });\n\n } catch (e: any) {\n debugAndPrintError(e);\n\n // send error code to client then terminate\n client.error(e.code, e.message, () =>\n rawClient.close(reconnectionToken\n ? CloseCode.FAILED_TO_RECONNECT\n : CloseCode.WITH_ERROR));\n }\n }\n\n}\n"],
|
|
5
|
+
"mappings": ";AAIA,OAA0D;AAC1D,OAAO,aAAoC;AAG3C,SAAS,YAAY,UAAU,WAAW,oBAAoB,gBAAgB,WAAW,qBAAqB,iBAAiB;AAC/H,SAAS,iBAAiB,wBAAwB;AAc3C,IAAM,gBAAN,cAA4B,UAAU;AAAA,EAU3C,YAAY,UAA4B,CAAC,GAAG;AAC1C,UAAM;AAVR,SAAU,UAA4C,CAAC;AACvD,SAAU,iBAAiB,oBAAI,QAA0D;AAKzF,SAAQ,mBAAgE;AACxE,SAAQ,UAA4B,CAAC;AAInC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,gBAA6B;AAClC,QAAI,CAAC,KAAK,aAAa;AACrB,WAAK,cAAc,QAAQ;AAAA,IAC7B;AACA,WAAO,KAAK;AAAA,EACd;AAAA,EAEO,WAAW,QAAgB;AAChC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,OAAO,MAAc,UAAmB,SAAkB,mBAAgC;AAC/F,UAAM,OAAO;AAEb,SAAK,UAAU,IAAI,MAAM;AAAA,MACvB;AAAA,MACA;AAAA,MAEA,MAAM,MAAM,KAAK,QAAQ;AACvB,cAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAG3B,YAAI,OAAO,QAAQ,KAAK;AAAA,UACtB,MAAM;AAAA,YACJ,KAAK,IAAI,WAAW,IAAI;AAAA,YACxB,cAAc,IAAI;AAAA,YAClB,SAAS,IAAI;AAAA,YACb,eAAe,OAAO,UAAU,GAAG,GAAG,WAAW;AAAA,UACnD;AAAA,QACF,CAAC,GAAG;AACF;AAAA,QACF;AAGA,YAAI,KAAK,SAAS;AAChB,cAAI;AAEF,kBAAM,cAAc;AAAA,cAClB,GAAG,WAAW,WAAW;AAAA,cACzB,GAAG,WAAW,WAAW,eAAe,IAAI,OAAO;AAAA,YACrD;AAGA,gBAAI,IAAI,WAAW,WAAW;AAC5B,qBAAO,IAAI,SAAS,MAAM;AAAA,gBACxB,QAAQ;AAAA,gBACR,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAEA,kBAAM,WAAW,MAAM,KAAK,QAAQ,QAAQ,GAAG;AAG/C,kBAAM,UAAU,IAAI,QAAQ,SAAS,OAAO;AAC5C,mBAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpD,kBAAI,CAAC,QAAQ,IAAI,GAAG,GAAG;AACrB,wBAAQ,IAAI,KAAK,MAAM,SAAS,CAAC;AAAA,cACnC;AAAA,YACF,CAAC;AAED,mBAAO,IAAI,SAAS,SAAS,MAAM;AAAA,cACjC,QAAQ,SAAS;AAAA,cACjB,YAAY,SAAS;AAAA,cACrB;AAAA,YACF,CAAC;AAAA,UAEH,SAAS,GAAQ;AACf,+BAAmB,CAAC;AACpB,mBAAO,IAAI,SAAS,KAAK,UAAU;AAAA,cACjC,MAAM,EAAE;AAAA,cACR,OAAO,EAAE;AAAA,YACX,CAAC,GAAG;AAAA,cACF,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAChD,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,KAAK,aAAa;AAEpB,kBAAQ,KAAK,2DAA2D;AAAA,QAC1E;AAEA,eAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,IAAI,CAAC;AAAA,MAClD;AAAA,MAEA,WAAW;AAAA,QACT,GAAG,KAAK;AAAA,QAER,MAAM,KAAK,IAAI;AACb,gBAAM,KAAK,aAAa,EAAE;AAAA,QAC5B;AAAA,QAEA,QAAQ,IAAI,SAAS;AACnB,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;AAED,wBAAoB;AAEpB,WAAO;AAAA,EACT;AAAA,EAEO,WAAW;AAChB,QAAI,KAAK,SAAS;AAChB,WAAK,QAAQ,KAAK;AAAA,IACpB;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,YAAa,MAAa;AAC3G,UAAI,CAAC,KAAK,GAAG,IAAI,IAAI;AACrB,YAAM,OAAO,KAAK,GAAG;AAErB,iBAAW,MAAM,gBAAgB,MAAM,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,YAAY;AAAA,IAC5E;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,MAAM,UAAU,KAAK;AAC3B,UAAM,eAAe,UAAU,KAAK;AAEpC,UAAM,YAAY,aAAa,IAAI,WAAW;AAC9C,UAAM,mBAAmB,IAAI,MAAM,uCAAuC;AAC1E,UAAM,SAAS,oBAAoB,iBAAiB,CAAC;AAGrD,QAAI,CAAC,aAAa,CAAC,QAAQ;AAEzB,YAAM,UAAU,WAAW,MAAM,UAAU,MAAM,UAAU,cAAc,GAAG,GAAI;AAChF,cAAQ,GAAG,WAAW,CAAC,MAAM,UAAU,KAAK,IAAI,WAAW,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;AAC5E,cAAQ,GAAG,SAAS,MAAM,aAAa,OAAO,CAAC;AAC/C;AAAA,IACF;AAEA,UAAM,OAAO,WAAW,iBAAiB,MAAM;AAC/C,UAAM,SAAS,IAAI,gBAAgB,WAAW,OAAO;AACrD,UAAM,oBAAoB,aAAa,IAAI,mBAAmB;AAC9D,UAAM,gBAAgB,aAAa,IAAI,eAAe;AAEtD,QAAI;AACF,YAAM,oBAAoB,MAAM,QAAQ;AAAA,QACtC,OAAO,aAAa,IAAI,YAAY,KAAK,eAAe,UAAU,KAAK,QAAQ,eAAe,CAAC;AAAA,QAC/F,SAAS,UAAU,KAAK;AAAA,QACxB,IAAI,UAAU,KAAK,QAAQ,WAAW,KAAK,UAAU,KAAK,QAAQ,iBAAiB,KAAK,UAAU,KAAK;AAAA,MACzG,GAAG;AAAA,QACD;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IAEH,SAAS,GAAQ;AACf,yBAAmB,CAAC;AAGpB,aAAO,MAAM,EAAE,MAAM,EAAE,SAAS,MAC9B,UAAU,MAAM,oBACZ,UAAU,sBACV,UAAU,UAAU,CAAC;AAAA,IAC7B;AAAA,EACF;AAEF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@colyseus/bun-websockets",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"input": "./src/index.ts",
|
|
6
6
|
"main": "./build/index.cjs",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@colyseus/core": "^0.17.
|
|
24
|
+
"@colyseus/core": "^0.17.30"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"bun-types": "^1.2.0",
|
|
28
|
-
"@colyseus/core": "^0.17.
|
|
28
|
+
"@colyseus/core": "^0.17.30"
|
|
29
29
|
},
|
|
30
30
|
"author": "Endel Dreyer",
|
|
31
31
|
"license": "MIT",
|
package/src/BunWebSockets.ts
CHANGED
|
@@ -215,7 +215,10 @@ export class BunWebSockets extends Transport {
|
|
|
215
215
|
debugAndPrintError(e);
|
|
216
216
|
|
|
217
217
|
// send error code to client then terminate
|
|
218
|
-
client.error(e.code, e.message, () =>
|
|
218
|
+
client.error(e.code, e.message, () =>
|
|
219
|
+
rawClient.close(reconnectionToken
|
|
220
|
+
? CloseCode.FAILED_TO_RECONNECT
|
|
221
|
+
: CloseCode.WITH_ERROR));
|
|
219
222
|
}
|
|
220
223
|
}
|
|
221
224
|
|