@colyseus/core 0.17.33 → 0.17.35
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 +11 -10
- package/build/router/default_routes.d.ts +120 -12
- package/build/router/index.cjs +6 -5
- package/build/router/index.cjs.map +2 -2
- package/build/router/index.d.ts +96 -0
- package/build/router/index.mjs +6 -5
- package/build/router/index.mjs.map +2 -2
- package/build/utils/Utils.cjs +2 -1
- package/build/utils/Utils.cjs.map +2 -2
- package/build/utils/Utils.mjs +2 -1
- package/build/utils/Utils.mjs.map +2 -2
- package/package.json +7 -7
- package/src/router/index.ts +9 -9
- package/src/utils/Utils.ts +5 -1
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
Colyseus is an Authoritative Multiplayer Framework for Node.js, with SDKs
|
|
22
|
-
available for the Web, Unity, Defold, Haxe, Cocos and Construct3. ([See official SDKs](https://docs.colyseus.io/
|
|
22
|
+
available for the Web, Unity, Defold, Haxe, Cocos and Construct3. ([See official SDKs](https://docs.colyseus.io/getting-started))
|
|
23
23
|
|
|
24
24
|
The project focuses on providing synchronizable data structures for realtime and
|
|
25
25
|
turn-based games, matchmaking, and ease of usage both on the server-side and
|
|
@@ -28,23 +28,24 @@ client-side.
|
|
|
28
28
|
The mission of the framework is to be a standard netcode & matchmaking solution
|
|
29
29
|
for any kind of project you can think of!
|
|
30
30
|
|
|
31
|
-
##
|
|
31
|
+
## Why developers choose Colyseus:
|
|
32
32
|
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
33
|
+
- ⚡️ **Real-time state sync that just works** → Define your state on the server and it automatically synchronizes to all clients, delta-compressed and binary-encoded.
|
|
34
|
+
- ⚔️ **Built-in matchmaking** → Room-based architecture with filtering, queuing, and reconnection support out of the box.
|
|
35
|
+
- 📈 **Scalable** → Go from 10 to 10,000+ CCU by scaling vertically or horizontally with Redis and load balancers.
|
|
36
|
+
- 🛡️ **Cheat-proof by design** → Authoritative server model ensures game logic runs on the server, not the client.
|
|
37
|
+
- 🛠️ **Use the tools you already know** → Built on Node.js and TypeScript with a simple, familiar API on both server and client.
|
|
38
|
+
- 💙 **Free forever** → MIT licensed, even for commercial games.
|
|
38
39
|
|
|
39
40
|
See [public roadmap](https://docs.colyseus.io/roadmap) for version 1.0.
|
|
40
41
|
|
|
41
42
|
# 🚀 Quickstart
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
Set up your own Colyseus server project for your game using `npm create colyseus-app@latest`:
|
|
44
45
|
|
|
45
46
|
```
|
|
46
|
-
npm create colyseus-app@latest my-
|
|
47
|
-
cd my-
|
|
47
|
+
npm create colyseus-app@latest ./my-server
|
|
48
|
+
cd my-server
|
|
48
49
|
npm start
|
|
49
50
|
```
|
|
50
51
|
|
|
@@ -1,94 +1,202 @@
|
|
|
1
|
-
export declare const postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
1
|
+
export declare const postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
2
2
|
method: "POST";
|
|
3
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
3
4
|
}, any>;
|
|
4
5
|
export declare function getDefaultRouter(): {
|
|
5
6
|
handler: (request: Request) => Promise<Response>;
|
|
6
7
|
endpoints: {
|
|
7
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
8
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
8
9
|
method: "POST";
|
|
10
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
9
11
|
}, any>;
|
|
10
12
|
};
|
|
11
13
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
14
|
+
findRoute: (method: string, path: string) => {
|
|
15
|
+
data: import("@colyseus/better-call").Endpoint & {
|
|
16
|
+
path: string;
|
|
17
|
+
};
|
|
18
|
+
params: Record<string, string>;
|
|
19
|
+
};
|
|
12
20
|
extend: <NE extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE) => {
|
|
13
21
|
handler: (request: Request) => Promise<Response>;
|
|
14
22
|
endpoints: {
|
|
15
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
23
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
16
24
|
method: "POST";
|
|
25
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
17
26
|
}, any>;
|
|
18
27
|
} & NE;
|
|
19
28
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
29
|
+
findRoute: (method: string, path: string) => {
|
|
30
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
31
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
32
|
+
path: string;
|
|
33
|
+
} & {
|
|
34
|
+
path: string;
|
|
35
|
+
};
|
|
36
|
+
params: Record<string, string>;
|
|
37
|
+
};
|
|
20
38
|
extend: <NE_1 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_1) => {
|
|
21
39
|
handler: (request: Request) => Promise<Response>;
|
|
22
40
|
endpoints: {
|
|
23
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
41
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
24
42
|
method: "POST";
|
|
43
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
25
44
|
}, any>;
|
|
26
45
|
} & NE & NE_1;
|
|
27
46
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
47
|
+
findRoute: (method: string, path: string) => {
|
|
48
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
49
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
50
|
+
path: string;
|
|
51
|
+
} & {
|
|
52
|
+
path: string;
|
|
53
|
+
};
|
|
54
|
+
params: Record<string, string>;
|
|
55
|
+
};
|
|
28
56
|
extend: <NE_2 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_2) => {
|
|
29
57
|
handler: (request: Request) => Promise<Response>;
|
|
30
58
|
endpoints: {
|
|
31
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
59
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
32
60
|
method: "POST";
|
|
61
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
33
62
|
}, any>;
|
|
34
63
|
} & NE & NE_1 & NE_2;
|
|
35
64
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
65
|
+
findRoute: (method: string, path: string) => {
|
|
66
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
67
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
68
|
+
path: string;
|
|
69
|
+
} & {
|
|
70
|
+
path: string;
|
|
71
|
+
};
|
|
72
|
+
params: Record<string, string>;
|
|
73
|
+
};
|
|
36
74
|
extend: <NE_3 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_3) => {
|
|
37
75
|
handler: (request: Request) => Promise<Response>;
|
|
38
76
|
endpoints: {
|
|
39
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
77
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
40
78
|
method: "POST";
|
|
79
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
41
80
|
}, any>;
|
|
42
81
|
} & NE & NE_1 & NE_2 & NE_3;
|
|
43
82
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
83
|
+
findRoute: (method: string, path: string) => {
|
|
84
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
85
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
86
|
+
path: string;
|
|
87
|
+
} & {
|
|
88
|
+
path: string;
|
|
89
|
+
};
|
|
90
|
+
params: Record<string, string>;
|
|
91
|
+
};
|
|
44
92
|
extend: <NE_4 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_4) => {
|
|
45
93
|
handler: (request: Request) => Promise<Response>;
|
|
46
94
|
endpoints: {
|
|
47
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
95
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
48
96
|
method: "POST";
|
|
97
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
49
98
|
}, any>;
|
|
50
99
|
} & NE & NE_1 & NE_2 & NE_3 & NE_4;
|
|
51
100
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
101
|
+
findRoute: (method: string, path: string) => {
|
|
102
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
103
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
104
|
+
path: string;
|
|
105
|
+
} & {
|
|
106
|
+
path: string;
|
|
107
|
+
};
|
|
108
|
+
params: Record<string, string>;
|
|
109
|
+
};
|
|
52
110
|
extend: <NE_5 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_5) => {
|
|
53
111
|
handler: (request: Request) => Promise<Response>;
|
|
54
112
|
endpoints: {
|
|
55
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
113
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
56
114
|
method: "POST";
|
|
115
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
57
116
|
}, any>;
|
|
58
117
|
} & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5;
|
|
59
118
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
119
|
+
findRoute: (method: string, path: string) => {
|
|
120
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
121
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
122
|
+
path: string;
|
|
123
|
+
} & {
|
|
124
|
+
path: string;
|
|
125
|
+
};
|
|
126
|
+
params: Record<string, string>;
|
|
127
|
+
};
|
|
60
128
|
extend: <NE_6 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_6) => {
|
|
61
129
|
handler: (request: Request) => Promise<Response>;
|
|
62
130
|
endpoints: {
|
|
63
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
131
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
64
132
|
method: "POST";
|
|
133
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
65
134
|
}, any>;
|
|
66
135
|
} & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6;
|
|
67
136
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
137
|
+
findRoute: (method: string, path: string) => {
|
|
138
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
139
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
140
|
+
path: string;
|
|
141
|
+
} & {
|
|
142
|
+
path: string;
|
|
143
|
+
};
|
|
144
|
+
params: Record<string, string>;
|
|
145
|
+
};
|
|
68
146
|
extend: <NE_7 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_7) => {
|
|
69
147
|
handler: (request: Request) => Promise<Response>;
|
|
70
148
|
endpoints: {
|
|
71
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
149
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
72
150
|
method: "POST";
|
|
151
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
73
152
|
}, any>;
|
|
74
153
|
} & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7;
|
|
75
154
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
155
|
+
findRoute: (method: string, path: string) => {
|
|
156
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
157
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
158
|
+
path: string;
|
|
159
|
+
} & {
|
|
160
|
+
path: string;
|
|
161
|
+
};
|
|
162
|
+
params: Record<string, string>;
|
|
163
|
+
};
|
|
76
164
|
extend: <NE_8 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_8) => {
|
|
77
165
|
handler: (request: Request) => Promise<Response>;
|
|
78
166
|
endpoints: {
|
|
79
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
167
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
80
168
|
method: "POST";
|
|
169
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
81
170
|
}, any>;
|
|
82
171
|
} & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7 & NE_8;
|
|
83
172
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
173
|
+
findRoute: (method: string, path: string) => {
|
|
174
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
175
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
176
|
+
path: string;
|
|
177
|
+
} & {
|
|
178
|
+
path: string;
|
|
179
|
+
};
|
|
180
|
+
params: Record<string, string>;
|
|
181
|
+
};
|
|
84
182
|
extend: <NE_9 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_9) => {
|
|
85
183
|
handler: (request: Request) => Promise<Response>;
|
|
86
184
|
endpoints: {
|
|
87
|
-
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {
|
|
185
|
+
postMatchmakeMethod: import("@colyseus/better-call").StrictEndpoint<"/matchmake/:method/:roomName", {} & {
|
|
88
186
|
method: "POST";
|
|
187
|
+
body: import("@colyseus/better-call").StandardSchemaV1<unknown, unknown>;
|
|
89
188
|
}, any>;
|
|
90
189
|
} & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7 & NE_8 & NE_9;
|
|
91
190
|
addEndpoint: (endpoint: import("@colyseus/better-call").Endpoint) => void;
|
|
191
|
+
findRoute: (method: string, path: string) => {
|
|
192
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
193
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
194
|
+
path: string;
|
|
195
|
+
} & {
|
|
196
|
+
path: string;
|
|
197
|
+
};
|
|
198
|
+
params: Record<string, string>;
|
|
199
|
+
};
|
|
92
200
|
extend: <NE_10 extends Record<string, import("@colyseus/better-call").Endpoint>>(newEndpoints: NE_10) => any;
|
|
93
201
|
};
|
|
94
202
|
};
|
package/build/router/index.cjs
CHANGED
|
@@ -69,13 +69,14 @@ function bindRouterToTransport(transport, router) {
|
|
|
69
69
|
if (expressApp) {
|
|
70
70
|
server.removeListener("request", expressApp);
|
|
71
71
|
next = async (req, res) => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
if (router.findRoute(req.method, req.url) !== void 0) {
|
|
73
|
+
const protocol = req.headers["x-forwarded-proto"] || (req.socket.encrypted ? "https" : "http");
|
|
74
|
+
const base = `${protocol}://${req.headers[":authority"] || req.headers.host}`;
|
|
75
|
+
const response = await router.handler((0, import_node.getRequest)({ base, request: req }));
|
|
76
|
+
return (0, import_node.setResponse)(res, response);
|
|
77
|
+
} else {
|
|
76
78
|
return expressApp["handle"](req, res);
|
|
77
79
|
}
|
|
78
|
-
return (0, import_node.setResponse)(res, response);
|
|
79
80
|
};
|
|
80
81
|
} else {
|
|
81
82
|
next = (0, import_node.toNodeHandler)(router.handler);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/router/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type express from \"express\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler, getRequest, setResponse } from \"@colyseus/better-call/node\";\nimport { Transport } from \"../Transport.ts\";\nimport { controller } from \"../matchmaker/controller.ts\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\nexport {\n createEndpoint,\n createMiddleware,\n createInternalContext,\n\n // Re-export types needed for declaration emit\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointHandler,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToTransport(transport: Transport, router: Router) {\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"OK\", { status: 200 });\n }));\n\n // check if the server is bound to an express app\n const expressApp = transport.getExpressApp() as express.Application;\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = (\n // check if express app has a root route\n expressRootRoute(expressApp) !== undefined ||\n\n // check if router has a root route\n Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\")\n );\n\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n const server = transport.server;\n\n // use custom bindRouter method if provided\n if (!server && transport.bindRouter) {\n transport.bindRouter(router);\n return;\n }\n\n // which route handler to use\n // (router + fallback to express, or just router)\n let next: any;\n\n if (expressApp) {\n server.removeListener('request', expressApp);\n\n //
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAsH;AACtH,kBAAuD;AACvD,uBAA0B;AAC1B,wBAA2B;AAC3B,qBAAgB;AAEhB,IAAAA,sBAaO;AAIA,SAAS,sBAAsB,WAAsB,QAAgB;AAE1E,SAAO,gBAAY,mCAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3C,CAAC,CAAC;AAGF,QAAM,aAAa,UAAU,cAAc;AAG3C,QAAM;AAAA;AAAA,IAEJ,iBAAiB,UAAU,MAAM;AAAA,IAGjC,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAAA;AAGxE,MAAI,CAAC,cAAc;AACjB,WAAO,gBAAY,mCAAe,KAAK,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACvE,aAAO,IAAI,SAAS,YAAY,eAAAC,QAAI,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAChE,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,SAAS,UAAU;AAGzB,MAAI,CAAC,UAAU,UAAU,YAAY;AACnC,cAAU,WAAW,MAAM;AAC3B;AAAA,EACF;AAIA,MAAI;AAEJ,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;
|
|
4
|
+
"sourcesContent": ["import type express from \"express\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler, getRequest, setResponse } from \"@colyseus/better-call/node\";\nimport { Transport } from \"../Transport.ts\";\nimport { controller } from \"../matchmaker/controller.ts\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\nexport {\n createEndpoint,\n createMiddleware,\n createInternalContext,\n\n // Re-export types needed for declaration emit\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointHandler,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToTransport(transport: Transport, router: Router) {\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"OK\", { status: 200 });\n }));\n\n // check if the server is bound to an express app\n const expressApp = transport.getExpressApp() as express.Application;\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = (\n // check if express app has a root route\n expressRootRoute(expressApp) !== undefined ||\n\n // check if router has a root route\n Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\")\n );\n\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n const server = transport.server;\n\n // use custom bindRouter method if provided\n if (!server && transport.bindRouter) {\n transport.bindRouter(router);\n return;\n }\n\n // which route handler to use\n // (router + fallback to express, or just router)\n let next: any;\n\n if (expressApp) {\n server.removeListener('request', expressApp);\n\n next = async (req: IncomingMessage, res: ServerResponse) => {\n // check if the route is defined in the router\n // if so, use the router handler, otherwise fallback to express\n if (router.findRoute(req.method, req.url) !== undefined) {\n const protocol = req.headers[\"x-forwarded-proto\"] || ((req.socket as any).encrypted ? \"https\" : \"http\");\n const base = `${protocol}://${req.headers[\":authority\"] || req.headers.host}`;\n const response = await router.handler(getRequest({ base, request: req }));\n return setResponse(res, response);\n\n } else {\n return expressApp['handle'](req, res);\n }\n };\n\n } else {\n next = toNodeHandler(router.handler);\n }\n\n // handle cors headers for all requests by default\n server.prependListener('request', (req: IncomingMessage, res: ServerResponse) => {\n const corsHeaders = {\n ...controller.DEFAULT_CORS_HEADERS,\n ...controller.getCorsHeaders(new Headers(req.headers as any)),\n };\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204, corsHeaders);\n res.end();\n return;\n }\n\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n next(req, res);\n });\n}\n\nfunction expressRootRoute(expressApp: express.Application) {\n //\n // express v5 uses `app.router`, express v4 uses `app._router`\n // check for `app._router` first, then `app.router`\n //\n // (express v4 will show a warning if `app.router` is used)\n //\n const stack = (expressApp as any)?._router?.stack ?? (expressApp as any)?.router?.stack;\n\n if (!stack) {\n return false;\n }\n\n return stack.find((layer: any) => layer.match('/') && !['query', 'expressInit'].includes(layer.name));\n}\n\n/**\n * Do not use this directly. This is used internally by `@colyseus/playground`.\n * TODO: refactor. Avoid using globals.\n * @internal\n */\nexport let __globalEndpoints: Record<string, Endpoint> = {};\n\nexport function createRouter<\n E extends Record<string, Endpoint>,\n Config extends RouterConfig\n>(endpoints: E, config: Config = {} as Config) {\n // TODO: refactor. Avoid using globals.\n __globalEndpoints = endpoints;\n\n return createBetterCallRouter({ ...endpoints }, config);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAAsH;AACtH,kBAAuD;AACvD,uBAA0B;AAC1B,wBAA2B;AAC3B,qBAAgB;AAEhB,IAAAA,sBAaO;AAIA,SAAS,sBAAsB,WAAsB,QAAgB;AAE1E,SAAO,gBAAY,mCAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3C,CAAC,CAAC;AAGF,QAAM,aAAa,UAAU,cAAc;AAG3C,QAAM;AAAA;AAAA,IAEJ,iBAAiB,UAAU,MAAM;AAAA,IAGjC,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAAA;AAGxE,MAAI,CAAC,cAAc;AACjB,WAAO,gBAAY,mCAAe,KAAK,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACvE,aAAO,IAAI,SAAS,YAAY,eAAAC,QAAI,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAChE,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,SAAS,UAAU;AAGzB,MAAI,CAAC,UAAU,UAAU,YAAY;AACnC,cAAU,WAAW,MAAM;AAC3B;AAAA,EACF;AAIA,MAAI;AAEJ,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;AAE3C,WAAO,OAAO,KAAsB,QAAwB;AAG1D,UAAI,OAAO,UAAU,IAAI,QAAQ,IAAI,GAAG,MAAM,QAAW;AACvD,cAAM,WAAW,IAAI,QAAQ,mBAAmB,MAAO,IAAI,OAAe,YAAY,UAAU;AAChG,cAAM,OAAO,GAAG,QAAQ,MAAM,IAAI,QAAQ,YAAY,KAAK,IAAI,QAAQ,IAAI;AAC3E,cAAM,WAAW,MAAM,OAAO,YAAQ,wBAAW,EAAE,MAAM,SAAS,IAAI,CAAC,CAAC;AACxE,mBAAO,yBAAY,KAAK,QAAQ;AAAA,MAElC,OAAO;AACL,eAAO,WAAW,QAAQ,EAAE,KAAK,GAAG;AAAA,MACtC;AAAA,IACF;AAAA,EAEF,OAAO;AACL,eAAO,2BAAc,OAAO,OAAO;AAAA,EACrC;AAGA,SAAO,gBAAgB,WAAW,CAAC,KAAsB,QAAwB;AAC/E,UAAM,cAAc;AAAA,MAClB,GAAG,6BAAW;AAAA,MACd,GAAG,6BAAW,eAAe,IAAI,QAAQ,IAAI,OAAc,CAAC;AAAA,IAC9D;AAEA,QAAI,IAAI,WAAW,WAAW;AAC5B,UAAI,UAAU,KAAK,WAAW;AAC9B,UAAI,IAAI;AACR;AAAA,IACF;AAEA,WAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpD,UAAI,UAAU,KAAK,KAAK;AAAA,IAC1B,CAAC;AAED,SAAK,KAAK,GAAG;AAAA,EACf,CAAC;AACH;AAEA,SAAS,iBAAiB,YAAiC;AAOzD,QAAM,QAAS,YAAoB,SAAS,SAAU,YAAoB,QAAQ;AAElF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,KAAK,CAAC,UAAe,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,SAAS,MAAM,IAAI,CAAC;AACtG;AAOO,IAAI,oBAA8C,CAAC;AAEnD,SAAS,aAGd,WAAc,SAAiB,CAAC,GAAa;AAE7C,sBAAoB;AAEpB,aAAO,mBAAAC,cAAuB,EAAE,GAAG,UAAU,GAAG,MAAM;AACxD;",
|
|
6
6
|
"names": ["import_better_call", "pkg", "createBetterCallRouter"]
|
|
7
7
|
}
|
package/build/router/index.d.ts
CHANGED
|
@@ -14,46 +14,142 @@ export declare function createRouter<E extends Record<string, Endpoint>, Config
|
|
|
14
14
|
handler: (request: Request) => Promise<Response>;
|
|
15
15
|
endpoints: E;
|
|
16
16
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
17
|
+
findRoute: (method: string, path: string) => {
|
|
18
|
+
data: Endpoint & {
|
|
19
|
+
path: string;
|
|
20
|
+
};
|
|
21
|
+
params: Record<string, string>;
|
|
22
|
+
};
|
|
17
23
|
extend: <NE extends Record<string, Endpoint>>(newEndpoints: NE) => {
|
|
18
24
|
handler: (request: Request) => Promise<Response>;
|
|
19
25
|
endpoints: E & NE;
|
|
20
26
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
27
|
+
findRoute: (method: string, path: string) => {
|
|
28
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
29
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
30
|
+
path: string;
|
|
31
|
+
} & {
|
|
32
|
+
path: string;
|
|
33
|
+
};
|
|
34
|
+
params: Record<string, string>;
|
|
35
|
+
};
|
|
21
36
|
extend: <NE_1 extends Record<string, Endpoint>>(newEndpoints: NE_1) => {
|
|
22
37
|
handler: (request: Request) => Promise<Response>;
|
|
23
38
|
endpoints: E & NE & NE_1;
|
|
24
39
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
40
|
+
findRoute: (method: string, path: string) => {
|
|
41
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
42
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
43
|
+
path: string;
|
|
44
|
+
} & {
|
|
45
|
+
path: string;
|
|
46
|
+
};
|
|
47
|
+
params: Record<string, string>;
|
|
48
|
+
};
|
|
25
49
|
extend: <NE_2 extends Record<string, Endpoint>>(newEndpoints: NE_2) => {
|
|
26
50
|
handler: (request: Request) => Promise<Response>;
|
|
27
51
|
endpoints: E & NE & NE_1 & NE_2;
|
|
28
52
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
53
|
+
findRoute: (method: string, path: string) => {
|
|
54
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
55
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
56
|
+
path: string;
|
|
57
|
+
} & {
|
|
58
|
+
path: string;
|
|
59
|
+
};
|
|
60
|
+
params: Record<string, string>;
|
|
61
|
+
};
|
|
29
62
|
extend: <NE_3 extends Record<string, Endpoint>>(newEndpoints: NE_3) => {
|
|
30
63
|
handler: (request: Request) => Promise<Response>;
|
|
31
64
|
endpoints: E & NE & NE_1 & NE_2 & NE_3;
|
|
32
65
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
66
|
+
findRoute: (method: string, path: string) => {
|
|
67
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
68
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
69
|
+
path: string;
|
|
70
|
+
} & {
|
|
71
|
+
path: string;
|
|
72
|
+
};
|
|
73
|
+
params: Record<string, string>;
|
|
74
|
+
};
|
|
33
75
|
extend: <NE_4 extends Record<string, Endpoint>>(newEndpoints: NE_4) => {
|
|
34
76
|
handler: (request: Request) => Promise<Response>;
|
|
35
77
|
endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4;
|
|
36
78
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
79
|
+
findRoute: (method: string, path: string) => {
|
|
80
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
81
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
82
|
+
path: string;
|
|
83
|
+
} & {
|
|
84
|
+
path: string;
|
|
85
|
+
};
|
|
86
|
+
params: Record<string, string>;
|
|
87
|
+
};
|
|
37
88
|
extend: <NE_5 extends Record<string, Endpoint>>(newEndpoints: NE_5) => {
|
|
38
89
|
handler: (request: Request) => Promise<Response>;
|
|
39
90
|
endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5;
|
|
40
91
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
92
|
+
findRoute: (method: string, path: string) => {
|
|
93
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
94
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
95
|
+
path: string;
|
|
96
|
+
} & {
|
|
97
|
+
path: string;
|
|
98
|
+
};
|
|
99
|
+
params: Record<string, string>;
|
|
100
|
+
};
|
|
41
101
|
extend: <NE_6 extends Record<string, Endpoint>>(newEndpoints: NE_6) => {
|
|
42
102
|
handler: (request: Request) => Promise<Response>;
|
|
43
103
|
endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6;
|
|
44
104
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
105
|
+
findRoute: (method: string, path: string) => {
|
|
106
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
107
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
108
|
+
path: string;
|
|
109
|
+
} & {
|
|
110
|
+
path: string;
|
|
111
|
+
};
|
|
112
|
+
params: Record<string, string>;
|
|
113
|
+
};
|
|
45
114
|
extend: <NE_7 extends Record<string, Endpoint>>(newEndpoints: NE_7) => {
|
|
46
115
|
handler: (request: Request) => Promise<Response>;
|
|
47
116
|
endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7;
|
|
48
117
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
118
|
+
findRoute: (method: string, path: string) => {
|
|
119
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
120
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
121
|
+
path: string;
|
|
122
|
+
} & {
|
|
123
|
+
path: string;
|
|
124
|
+
};
|
|
125
|
+
params: Record<string, string>;
|
|
126
|
+
};
|
|
49
127
|
extend: <NE_8 extends Record<string, Endpoint>>(newEndpoints: NE_8) => {
|
|
50
128
|
handler: (request: Request) => Promise<Response>;
|
|
51
129
|
endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7 & NE_8;
|
|
52
130
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
131
|
+
findRoute: (method: string, path: string) => {
|
|
132
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
133
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
134
|
+
path: string;
|
|
135
|
+
} & {
|
|
136
|
+
path: string;
|
|
137
|
+
};
|
|
138
|
+
params: Record<string, string>;
|
|
139
|
+
};
|
|
53
140
|
extend: <NE_9 extends Record<string, Endpoint>>(newEndpoints: NE_9) => {
|
|
54
141
|
handler: (request: Request) => Promise<Response>;
|
|
55
142
|
endpoints: E & NE & NE_1 & NE_2 & NE_3 & NE_4 & NE_5 & NE_6 & NE_7 & NE_8 & NE_9;
|
|
56
143
|
addEndpoint: (endpoint: Endpoint) => void;
|
|
144
|
+
findRoute: (method: string, path: string) => {
|
|
145
|
+
data: ((inputCtx: any) => Promise<any>) & {
|
|
146
|
+
options: import("@colyseus/better-call").EndpointOptions;
|
|
147
|
+
path: string;
|
|
148
|
+
} & {
|
|
149
|
+
path: string;
|
|
150
|
+
};
|
|
151
|
+
params: Record<string, string>;
|
|
152
|
+
};
|
|
57
153
|
extend: <NE_10 extends Record<string, Endpoint>>(newEndpoints: NE_10) => any;
|
|
58
154
|
};
|
|
59
155
|
};
|
package/build/router/index.mjs
CHANGED
|
@@ -33,13 +33,14 @@ function bindRouterToTransport(transport, router) {
|
|
|
33
33
|
if (expressApp) {
|
|
34
34
|
server.removeListener("request", expressApp);
|
|
35
35
|
next = async (req, res) => {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
if (router.findRoute(req.method, req.url) !== void 0) {
|
|
37
|
+
const protocol = req.headers["x-forwarded-proto"] || (req.socket.encrypted ? "https" : "http");
|
|
38
|
+
const base = `${protocol}://${req.headers[":authority"] || req.headers.host}`;
|
|
39
|
+
const response = await router.handler(getRequest({ base, request: req }));
|
|
40
|
+
return setResponse(res, response);
|
|
41
|
+
} else {
|
|
40
42
|
return expressApp["handle"](req, res);
|
|
41
43
|
}
|
|
42
|
-
return setResponse(res, response);
|
|
43
44
|
};
|
|
44
45
|
} else {
|
|
45
46
|
next = toNodeHandler(router.handler);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/router/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type express from \"express\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler, getRequest, setResponse } from \"@colyseus/better-call/node\";\nimport { Transport } from \"../Transport.ts\";\nimport { controller } from \"../matchmaker/controller.ts\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\nexport {\n createEndpoint,\n createMiddleware,\n createInternalContext,\n\n // Re-export types needed for declaration emit\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointHandler,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToTransport(transport: Transport, router: Router) {\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"OK\", { status: 200 });\n }));\n\n // check if the server is bound to an express app\n const expressApp = transport.getExpressApp() as express.Application;\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = (\n // check if express app has a root route\n expressRootRoute(expressApp) !== undefined ||\n\n // check if router has a root route\n Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\")\n );\n\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n const server = transport.server;\n\n // use custom bindRouter method if provided\n if (!server && transport.bindRouter) {\n transport.bindRouter(router);\n return;\n }\n\n // which route handler to use\n // (router + fallback to express, or just router)\n let next: any;\n\n if (expressApp) {\n server.removeListener('request', expressApp);\n\n //
|
|
5
|
-
"mappings": ";AAEA,SAAwD,gBAAgB,wBAAwB,sBAAsB;AACtH,SAAS,eAAe,YAAY,mBAAmB;AACvD,OAA0B;AAC1B,SAAS,kBAAkB;AAC3B,OAAO,SAAS,qBAAqB,KAAK,EAAE,MAAM,OAAO;AAEzD;AAAA,EACE,kBAAAA;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AAIA,SAAS,sBAAsB,WAAsB,QAAgB;AAE1E,SAAO,YAAY,eAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3C,CAAC,CAAC;AAGF,QAAM,aAAa,UAAU,cAAc;AAG3C,QAAM;AAAA;AAAA,IAEJ,iBAAiB,UAAU,MAAM;AAAA,IAGjC,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAAA;AAGxE,MAAI,CAAC,cAAc;AACjB,WAAO,YAAY,eAAe,KAAK,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACvE,aAAO,IAAI,SAAS,YAAY,IAAI,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAChE,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,SAAS,UAAU;AAGzB,MAAI,CAAC,UAAU,UAAU,YAAY;AACnC,cAAU,WAAW,MAAM;AAC3B;AAAA,EACF;AAIA,MAAI;AAEJ,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;
|
|
4
|
+
"sourcesContent": ["import type express from \"express\";\nimport type { IncomingMessage, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler, getRequest, setResponse } from \"@colyseus/better-call/node\";\nimport { Transport } from \"../Transport.ts\";\nimport { controller } from \"../matchmaker/controller.ts\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\n\nexport {\n createEndpoint,\n createMiddleware,\n createInternalContext,\n\n // Re-export types needed for declaration emit\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointHandler,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToTransport(transport: Transport, router: Router) {\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"OK\", { status: 200 });\n }));\n\n // check if the server is bound to an express app\n const expressApp = transport.getExpressApp() as express.Application;\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = (\n // check if express app has a root route\n expressRootRoute(expressApp) !== undefined ||\n\n // check if router has a root route\n Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\")\n );\n\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n const server = transport.server;\n\n // use custom bindRouter method if provided\n if (!server && transport.bindRouter) {\n transport.bindRouter(router);\n return;\n }\n\n // which route handler to use\n // (router + fallback to express, or just router)\n let next: any;\n\n if (expressApp) {\n server.removeListener('request', expressApp);\n\n next = async (req: IncomingMessage, res: ServerResponse) => {\n // check if the route is defined in the router\n // if so, use the router handler, otherwise fallback to express\n if (router.findRoute(req.method, req.url) !== undefined) {\n const protocol = req.headers[\"x-forwarded-proto\"] || ((req.socket as any).encrypted ? \"https\" : \"http\");\n const base = `${protocol}://${req.headers[\":authority\"] || req.headers.host}`;\n const response = await router.handler(getRequest({ base, request: req }));\n return setResponse(res, response);\n\n } else {\n return expressApp['handle'](req, res);\n }\n };\n\n } else {\n next = toNodeHandler(router.handler);\n }\n\n // handle cors headers for all requests by default\n server.prependListener('request', (req: IncomingMessage, res: ServerResponse) => {\n const corsHeaders = {\n ...controller.DEFAULT_CORS_HEADERS,\n ...controller.getCorsHeaders(new Headers(req.headers as any)),\n };\n\n if (req.method === \"OPTIONS\") {\n res.writeHead(204, corsHeaders);\n res.end();\n return;\n }\n\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n next(req, res);\n });\n}\n\nfunction expressRootRoute(expressApp: express.Application) {\n //\n // express v5 uses `app.router`, express v4 uses `app._router`\n // check for `app._router` first, then `app.router`\n //\n // (express v4 will show a warning if `app.router` is used)\n //\n const stack = (expressApp as any)?._router?.stack ?? (expressApp as any)?.router?.stack;\n\n if (!stack) {\n return false;\n }\n\n return stack.find((layer: any) => layer.match('/') && !['query', 'expressInit'].includes(layer.name));\n}\n\n/**\n * Do not use this directly. This is used internally by `@colyseus/playground`.\n * TODO: refactor. Avoid using globals.\n * @internal\n */\nexport let __globalEndpoints: Record<string, Endpoint> = {};\n\nexport function createRouter<\n E extends Record<string, Endpoint>,\n Config extends RouterConfig\n>(endpoints: E, config: Config = {} as Config) {\n // TODO: refactor. Avoid using globals.\n __globalEndpoints = endpoints;\n\n return createBetterCallRouter({ ...endpoints }, config);\n}\n"],
|
|
5
|
+
"mappings": ";AAEA,SAAwD,gBAAgB,wBAAwB,sBAAsB;AACtH,SAAS,eAAe,YAAY,mBAAmB;AACvD,OAA0B;AAC1B,SAAS,kBAAkB;AAC3B,OAAO,SAAS,qBAAqB,KAAK,EAAE,MAAM,OAAO;AAEzD;AAAA,EACE,kBAAAA;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AAIA,SAAS,sBAAsB,WAAsB,QAAgB;AAE1E,SAAO,YAAY,eAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC3C,CAAC,CAAC;AAGF,QAAM,aAAa,UAAU,cAAc;AAG3C,QAAM;AAAA;AAAA,IAEJ,iBAAiB,UAAU,MAAM;AAAA,IAGjC,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAAA;AAGxE,MAAI,CAAC,cAAc;AACjB,WAAO,YAAY,eAAe,KAAK,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACvE,aAAO,IAAI,SAAS,YAAY,IAAI,OAAO,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,IAChE,CAAC,CAAC;AAAA,EACJ;AAEA,QAAM,SAAS,UAAU;AAGzB,MAAI,CAAC,UAAU,UAAU,YAAY;AACnC,cAAU,WAAW,MAAM;AAC3B;AAAA,EACF;AAIA,MAAI;AAEJ,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;AAE3C,WAAO,OAAO,KAAsB,QAAwB;AAG1D,UAAI,OAAO,UAAU,IAAI,QAAQ,IAAI,GAAG,MAAM,QAAW;AACvD,cAAM,WAAW,IAAI,QAAQ,mBAAmB,MAAO,IAAI,OAAe,YAAY,UAAU;AAChG,cAAM,OAAO,GAAG,QAAQ,MAAM,IAAI,QAAQ,YAAY,KAAK,IAAI,QAAQ,IAAI;AAC3E,cAAM,WAAW,MAAM,OAAO,QAAQ,WAAW,EAAE,MAAM,SAAS,IAAI,CAAC,CAAC;AACxE,eAAO,YAAY,KAAK,QAAQ;AAAA,MAElC,OAAO;AACL,eAAO,WAAW,QAAQ,EAAE,KAAK,GAAG;AAAA,MACtC;AAAA,IACF;AAAA,EAEF,OAAO;AACL,WAAO,cAAc,OAAO,OAAO;AAAA,EACrC;AAGA,SAAO,gBAAgB,WAAW,CAAC,KAAsB,QAAwB;AAC/E,UAAM,cAAc;AAAA,MAClB,GAAG,WAAW;AAAA,MACd,GAAG,WAAW,eAAe,IAAI,QAAQ,IAAI,OAAc,CAAC;AAAA,IAC9D;AAEA,QAAI,IAAI,WAAW,WAAW;AAC5B,UAAI,UAAU,KAAK,WAAW;AAC9B,UAAI,IAAI;AACR;AAAA,IACF;AAEA,WAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AACpD,UAAI,UAAU,KAAK,KAAK;AAAA,IAC1B,CAAC;AAED,SAAK,KAAK,GAAG;AAAA,EACf,CAAC;AACH;AAEA,SAAS,iBAAiB,YAAiC;AAOzD,QAAM,QAAS,YAAoB,SAAS,SAAU,YAAoB,QAAQ;AAElF,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,SAAO,MAAM,KAAK,CAAC,UAAe,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,SAAS,MAAM,IAAI,CAAC;AACtG;AAOO,IAAI,oBAA8C,CAAC;AAEnD,SAAS,aAGd,WAAc,SAAiB,CAAC,GAAa;AAE7C,sBAAoB;AAEpB,SAAO,uBAAuB,EAAE,GAAG,UAAU,GAAG,MAAM;AACxD;",
|
|
6
6
|
"names": ["createEndpoint"]
|
|
7
7
|
}
|
package/build/utils/Utils.cjs
CHANGED
|
@@ -130,7 +130,8 @@ function wrapTryCatch(method, onError, exceptionClass, methodName, rethrow = fal
|
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
function dynamicImport(moduleName) {
|
|
133
|
-
if (typeof __dirname !== "undefined"
|
|
133
|
+
if (typeof __dirname !== "undefined" && // @ts-ignore
|
|
134
|
+
typeof Bun === "undefined") {
|
|
134
135
|
try {
|
|
135
136
|
return Promise.resolve(require(moduleName));
|
|
136
137
|
} catch (e) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/Utils.ts"],
|
|
4
|
-
"sourcesContent": ["import { nanoid } from 'nanoid';\nimport { type RoomException, type RoomMethodName } from '../errors/RoomExceptions.ts';\n\nimport { debugAndPrintError, debugMatchMaking } from '../Debug.ts';\n\nexport type Type<T> = new (...args: any[]) => T;\nexport type MethodName<T> = string & {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never\n}[keyof T];\n\n/**\n * Utility type that extracts the return type of a method or the type of a property\n * from a given class/object type.\n *\n * - If the key is a method, returns the awaited return type of that method\n * - If the key is a property, returns the type of that property\n */\nexport type ExtractMethodOrPropertyType<\n TClass,\n TKey extends keyof TClass\n> = TClass[TKey] extends (...args: any[]) => infer R\n ? Awaited<R>\n : TClass[TKey];\n\n// remote room call timeouts\nexport const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2000);\nexport const MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME = Number(process.env.COLYSEUS_MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME || 0.5);\n\nexport function generateId(length: number = 9) {\n return nanoid(length);\n}\n\nexport function getBearerToken(authHeader: string) {\n return (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n}\n\n// nodemon sends SIGUSR2 before reloading\n// (https://github.com/remy/nodemon#controlling-shutdown-of-your-script)\n//\nconst signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2'];\n\nexport function registerGracefulShutdown(callback: (err?: Error) => void) {\n /**\n * Gracefully shutdown on uncaught errors\n */\n process.on('uncaughtException', (err) => {\n debugAndPrintError(err);\n callback(err);\n });\n\n signals.forEach((signal) =>\n process.once(signal, () => callback()));\n}\n\nexport function retry<T = any>(\n cb: Function,\n maxRetries: number = 3,\n errorWhiteList: any[] = [],\n retries: number = 0,\n) {\n return new Promise<T>((resolve, reject) => {\n cb()\n .then(resolve)\n .catch((e: any) => {\n if (\n errorWhiteList.indexOf(e.constructor) !== -1 &&\n retries++ < maxRetries\n ) {\n setTimeout(() => {\n debugMatchMaking(\"retrying due to error (error: %s, retries: %s, maxRetries: %s)\", e.message, retries, maxRetries);\n retry<T>(cb, maxRetries, errorWhiteList, retries).\n then(resolve).\n catch((e2) => reject(e2));\n }, Math.floor(Math.random() * Math.pow(2, retries) * 400));\n\n } else {\n reject(e);\n }\n });\n });\n}\n\nexport function spliceOne(arr: any[], index: number): boolean {\n // manually splice availableRooms array\n // http://jsperf.com/manual-splice\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n return true;\n}\n\nexport class Deferred<T = any> {\n public promise: Promise<T>;\n\n public resolve: Function;\n public reject: Function;\n\n constructor(promise?: Promise<T>) {\n this.promise = promise ?? new Promise<T>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n\n public then(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any) {\n return this.promise.then(onFulfilled, onRejected);\n }\n\n public catch(func: (value: any) => any) {\n return this.promise.catch(func);\n }\n\n static reject (reason?: any) {\n return new Deferred(Promise.reject(reason));\n }\n\n static resolve<T = any>(value?: T) {\n return new Deferred<T>(Promise.resolve(value));\n }\n\n}\n\nexport function merge(a: any, ...objs: any[]): any {\n for (let i = 0, len = objs.length; i < len; i++) {\n const b = objs[i];\n for (const key in b) {\n if (b.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n }\n return a;\n}\n\nexport function wrapTryCatch(\n method: Function,\n onError: (error: RoomException, methodName: RoomMethodName) => void,\n exceptionClass: Type<RoomException>,\n methodName: RoomMethodName,\n rethrow: boolean = false,\n ...additionalErrorArgs: any[]\n) {\n return (...args: any[]) => {\n try {\n const result = method(...args);\n if (typeof (result?.catch) === \"function\") {\n return result.catch((e: Error) => {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n });\n }\n return result;\n } catch (e: any) {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n }\n };\n}\n\n/**\n * Dynamically import a module using either require() or import()\n * based on the current module system (CJS vs ESM).\n *\n * This avoids double-loading packages when running in mixed ESM/CJS environments.\n * Errors are silently caught - await the promise and handle errors at usage site.\n */\nexport function dynamicImport<T = any>(moduleName: string): Promise<T> {\n // __dirname exists in CJS but not in ESM\n if (typeof __dirname !== 'undefined') {\n // CJS context - use require()\n try {\n return Promise.resolve(require(moduleName));\n } catch (e: any) {\n // If the error is not a MODULE_NOT_FOUND error, reject with the error.\n if (e.code !== 'MODULE_NOT_FOUND') {\n return Promise.reject(e);\n }\n return Promise.resolve(undefined);\n }\n } else {\n // ESM context - use import()\n const promise = import(moduleName);\n promise.catch(() => {}); // prevent unhandled rejection warnings\n return promise;\n }\n}"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { nanoid } from 'nanoid';\nimport { type RoomException, type RoomMethodName } from '../errors/RoomExceptions.ts';\n\nimport { debugAndPrintError, debugMatchMaking } from '../Debug.ts';\n\nexport type Type<T> = new (...args: any[]) => T;\nexport type MethodName<T> = string & {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never\n}[keyof T];\n\n/**\n * Utility type that extracts the return type of a method or the type of a property\n * from a given class/object type.\n *\n * - If the key is a method, returns the awaited return type of that method\n * - If the key is a property, returns the type of that property\n */\nexport type ExtractMethodOrPropertyType<\n TClass,\n TKey extends keyof TClass\n> = TClass[TKey] extends (...args: any[]) => infer R\n ? Awaited<R>\n : TClass[TKey];\n\n// remote room call timeouts\nexport const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2000);\nexport const MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME = Number(process.env.COLYSEUS_MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME || 0.5);\n\nexport function generateId(length: number = 9) {\n return nanoid(length);\n}\n\nexport function getBearerToken(authHeader: string) {\n return (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n}\n\n// nodemon sends SIGUSR2 before reloading\n// (https://github.com/remy/nodemon#controlling-shutdown-of-your-script)\n//\nconst signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2'];\n\nexport function registerGracefulShutdown(callback: (err?: Error) => void) {\n /**\n * Gracefully shutdown on uncaught errors\n */\n process.on('uncaughtException', (err) => {\n debugAndPrintError(err);\n callback(err);\n });\n\n signals.forEach((signal) =>\n process.once(signal, () => callback()));\n}\n\nexport function retry<T = any>(\n cb: Function,\n maxRetries: number = 3,\n errorWhiteList: any[] = [],\n retries: number = 0,\n) {\n return new Promise<T>((resolve, reject) => {\n cb()\n .then(resolve)\n .catch((e: any) => {\n if (\n errorWhiteList.indexOf(e.constructor) !== -1 &&\n retries++ < maxRetries\n ) {\n setTimeout(() => {\n debugMatchMaking(\"retrying due to error (error: %s, retries: %s, maxRetries: %s)\", e.message, retries, maxRetries);\n retry<T>(cb, maxRetries, errorWhiteList, retries).\n then(resolve).\n catch((e2) => reject(e2));\n }, Math.floor(Math.random() * Math.pow(2, retries) * 400));\n\n } else {\n reject(e);\n }\n });\n });\n}\n\nexport function spliceOne(arr: any[], index: number): boolean {\n // manually splice availableRooms array\n // http://jsperf.com/manual-splice\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n return true;\n}\n\nexport class Deferred<T = any> {\n public promise: Promise<T>;\n\n public resolve: Function;\n public reject: Function;\n\n constructor(promise?: Promise<T>) {\n this.promise = promise ?? new Promise<T>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n\n public then(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any) {\n return this.promise.then(onFulfilled, onRejected);\n }\n\n public catch(func: (value: any) => any) {\n return this.promise.catch(func);\n }\n\n static reject (reason?: any) {\n return new Deferred(Promise.reject(reason));\n }\n\n static resolve<T = any>(value?: T) {\n return new Deferred<T>(Promise.resolve(value));\n }\n\n}\n\nexport function merge(a: any, ...objs: any[]): any {\n for (let i = 0, len = objs.length; i < len; i++) {\n const b = objs[i];\n for (const key in b) {\n if (b.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n }\n return a;\n}\n\nexport function wrapTryCatch(\n method: Function,\n onError: (error: RoomException, methodName: RoomMethodName) => void,\n exceptionClass: Type<RoomException>,\n methodName: RoomMethodName,\n rethrow: boolean = false,\n ...additionalErrorArgs: any[]\n) {\n return (...args: any[]) => {\n try {\n const result = method(...args);\n if (typeof (result?.catch) === \"function\") {\n return result.catch((e: Error) => {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n });\n }\n return result;\n } catch (e: any) {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n }\n };\n}\n\n/**\n * Dynamically import a module using either require() or import()\n * based on the current module system (CJS vs ESM).\n *\n * This avoids double-loading packages when running in mixed ESM/CJS environments.\n * Errors are silently caught - await the promise and handle errors at usage site.\n */\nexport function dynamicImport<T = any>(moduleName: string): Promise<T> {\n // __dirname exists in CJS but not in ESM\n if (\n typeof __dirname !== 'undefined' &&\n // @ts-ignore\n typeof (Bun) === 'undefined' // prevent bun from loading CJS modules\n ) {\n // CJS context - use require()\n try {\n return Promise.resolve(require(moduleName));\n } catch (e: any) {\n // If the error is not a MODULE_NOT_FOUND error, reject with the error.\n if (e.code !== 'MODULE_NOT_FOUND') {\n return Promise.reject(e);\n }\n return Promise.resolve(undefined);\n }\n } else {\n // ESM context - use import()\n const promise = import(moduleName);\n promise.catch(() => {}); // prevent unhandled rejection warnings\n return promise;\n }\n}"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/build/utils/Utils.mjs
CHANGED
|
@@ -103,7 +103,8 @@ function wrapTryCatch(method, onError, exceptionClass, methodName, rethrow = fal
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
function dynamicImport(moduleName) {
|
|
106
|
-
if (typeof __dirname !== "undefined"
|
|
106
|
+
if (typeof __dirname !== "undefined" && // @ts-ignore
|
|
107
|
+
typeof Bun === "undefined") {
|
|
107
108
|
try {
|
|
108
109
|
return Promise.resolve(__require(moduleName));
|
|
109
110
|
} catch (e) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/Utils.ts"],
|
|
4
|
-
"sourcesContent": ["import { nanoid } from 'nanoid';\nimport { type RoomException, type RoomMethodName } from '../errors/RoomExceptions.ts';\n\nimport { debugAndPrintError, debugMatchMaking } from '../Debug.ts';\n\nexport type Type<T> = new (...args: any[]) => T;\nexport type MethodName<T> = string & {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never\n}[keyof T];\n\n/**\n * Utility type that extracts the return type of a method or the type of a property\n * from a given class/object type.\n *\n * - If the key is a method, returns the awaited return type of that method\n * - If the key is a property, returns the type of that property\n */\nexport type ExtractMethodOrPropertyType<\n TClass,\n TKey extends keyof TClass\n> = TClass[TKey] extends (...args: any[]) => infer R\n ? Awaited<R>\n : TClass[TKey];\n\n// remote room call timeouts\nexport const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2000);\nexport const MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME = Number(process.env.COLYSEUS_MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME || 0.5);\n\nexport function generateId(length: number = 9) {\n return nanoid(length);\n}\n\nexport function getBearerToken(authHeader: string) {\n return (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n}\n\n// nodemon sends SIGUSR2 before reloading\n// (https://github.com/remy/nodemon#controlling-shutdown-of-your-script)\n//\nconst signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2'];\n\nexport function registerGracefulShutdown(callback: (err?: Error) => void) {\n /**\n * Gracefully shutdown on uncaught errors\n */\n process.on('uncaughtException', (err) => {\n debugAndPrintError(err);\n callback(err);\n });\n\n signals.forEach((signal) =>\n process.once(signal, () => callback()));\n}\n\nexport function retry<T = any>(\n cb: Function,\n maxRetries: number = 3,\n errorWhiteList: any[] = [],\n retries: number = 0,\n) {\n return new Promise<T>((resolve, reject) => {\n cb()\n .then(resolve)\n .catch((e: any) => {\n if (\n errorWhiteList.indexOf(e.constructor) !== -1 &&\n retries++ < maxRetries\n ) {\n setTimeout(() => {\n debugMatchMaking(\"retrying due to error (error: %s, retries: %s, maxRetries: %s)\", e.message, retries, maxRetries);\n retry<T>(cb, maxRetries, errorWhiteList, retries).\n then(resolve).\n catch((e2) => reject(e2));\n }, Math.floor(Math.random() * Math.pow(2, retries) * 400));\n\n } else {\n reject(e);\n }\n });\n });\n}\n\nexport function spliceOne(arr: any[], index: number): boolean {\n // manually splice availableRooms array\n // http://jsperf.com/manual-splice\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n return true;\n}\n\nexport class Deferred<T = any> {\n public promise: Promise<T>;\n\n public resolve: Function;\n public reject: Function;\n\n constructor(promise?: Promise<T>) {\n this.promise = promise ?? new Promise<T>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n\n public then(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any) {\n return this.promise.then(onFulfilled, onRejected);\n }\n\n public catch(func: (value: any) => any) {\n return this.promise.catch(func);\n }\n\n static reject (reason?: any) {\n return new Deferred(Promise.reject(reason));\n }\n\n static resolve<T = any>(value?: T) {\n return new Deferred<T>(Promise.resolve(value));\n }\n\n}\n\nexport function merge(a: any, ...objs: any[]): any {\n for (let i = 0, len = objs.length; i < len; i++) {\n const b = objs[i];\n for (const key in b) {\n if (b.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n }\n return a;\n}\n\nexport function wrapTryCatch(\n method: Function,\n onError: (error: RoomException, methodName: RoomMethodName) => void,\n exceptionClass: Type<RoomException>,\n methodName: RoomMethodName,\n rethrow: boolean = false,\n ...additionalErrorArgs: any[]\n) {\n return (...args: any[]) => {\n try {\n const result = method(...args);\n if (typeof (result?.catch) === \"function\") {\n return result.catch((e: Error) => {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n });\n }\n return result;\n } catch (e: any) {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n }\n };\n}\n\n/**\n * Dynamically import a module using either require() or import()\n * based on the current module system (CJS vs ESM).\n *\n * This avoids double-loading packages when running in mixed ESM/CJS environments.\n * Errors are silently caught - await the promise and handle errors at usage site.\n */\nexport function dynamicImport<T = any>(moduleName: string): Promise<T> {\n // __dirname exists in CJS but not in ESM\n if (typeof __dirname !== 'undefined') {\n // CJS context - use require()\n try {\n return Promise.resolve(require(moduleName));\n } catch (e: any) {\n // If the error is not a MODULE_NOT_FOUND error, reject with the error.\n if (e.code !== 'MODULE_NOT_FOUND') {\n return Promise.reject(e);\n }\n return Promise.resolve(undefined);\n }\n } else {\n // ESM context - use import()\n const promise = import(moduleName);\n promise.catch(() => {}); // prevent unhandled rejection warnings\n return promise;\n }\n}"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { nanoid } from 'nanoid';\nimport { type RoomException, type RoomMethodName } from '../errors/RoomExceptions.ts';\n\nimport { debugAndPrintError, debugMatchMaking } from '../Debug.ts';\n\nexport type Type<T> = new (...args: any[]) => T;\nexport type MethodName<T> = string & {\n [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never\n}[keyof T];\n\n/**\n * Utility type that extracts the return type of a method or the type of a property\n * from a given class/object type.\n *\n * - If the key is a method, returns the awaited return type of that method\n * - If the key is a property, returns the type of that property\n */\nexport type ExtractMethodOrPropertyType<\n TClass,\n TKey extends keyof TClass\n> = TClass[TKey] extends (...args: any[]) => infer R\n ? Awaited<R>\n : TClass[TKey];\n\n// remote room call timeouts\nexport const REMOTE_ROOM_SHORT_TIMEOUT = Number(process.env.COLYSEUS_PRESENCE_SHORT_TIMEOUT || 2000);\nexport const MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME = Number(process.env.COLYSEUS_MAX_CONCURRENT_CREATE_ROOM_WAIT_TIME || 0.5);\n\nexport function generateId(length: number = 9) {\n return nanoid(length);\n}\n\nexport function getBearerToken(authHeader: string) {\n return (authHeader && authHeader.startsWith(\"Bearer \") && authHeader.substring(7, authHeader.length)) || undefined;\n}\n\n// nodemon sends SIGUSR2 before reloading\n// (https://github.com/remy/nodemon#controlling-shutdown-of-your-script)\n//\nconst signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM', 'SIGUSR2'];\n\nexport function registerGracefulShutdown(callback: (err?: Error) => void) {\n /**\n * Gracefully shutdown on uncaught errors\n */\n process.on('uncaughtException', (err) => {\n debugAndPrintError(err);\n callback(err);\n });\n\n signals.forEach((signal) =>\n process.once(signal, () => callback()));\n}\n\nexport function retry<T = any>(\n cb: Function,\n maxRetries: number = 3,\n errorWhiteList: any[] = [],\n retries: number = 0,\n) {\n return new Promise<T>((resolve, reject) => {\n cb()\n .then(resolve)\n .catch((e: any) => {\n if (\n errorWhiteList.indexOf(e.constructor) !== -1 &&\n retries++ < maxRetries\n ) {\n setTimeout(() => {\n debugMatchMaking(\"retrying due to error (error: %s, retries: %s, maxRetries: %s)\", e.message, retries, maxRetries);\n retry<T>(cb, maxRetries, errorWhiteList, retries).\n then(resolve).\n catch((e2) => reject(e2));\n }, Math.floor(Math.random() * Math.pow(2, retries) * 400));\n\n } else {\n reject(e);\n }\n });\n });\n}\n\nexport function spliceOne(arr: any[], index: number): boolean {\n // manually splice availableRooms array\n // http://jsperf.com/manual-splice\n if (index === -1 || index >= arr.length) {\n return false;\n }\n\n const len = arr.length - 1;\n for (let i = index; i < len; i++) {\n arr[i] = arr[i + 1];\n }\n\n arr.length = len;\n return true;\n}\n\nexport class Deferred<T = any> {\n public promise: Promise<T>;\n\n public resolve: Function;\n public reject: Function;\n\n constructor(promise?: Promise<T>) {\n this.promise = promise ?? new Promise<T>((resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n });\n }\n\n public then(onFulfilled?: (value: T) => any, onRejected?: (reason: any) => any) {\n return this.promise.then(onFulfilled, onRejected);\n }\n\n public catch(func: (value: any) => any) {\n return this.promise.catch(func);\n }\n\n static reject (reason?: any) {\n return new Deferred(Promise.reject(reason));\n }\n\n static resolve<T = any>(value?: T) {\n return new Deferred<T>(Promise.resolve(value));\n }\n\n}\n\nexport function merge(a: any, ...objs: any[]): any {\n for (let i = 0, len = objs.length; i < len; i++) {\n const b = objs[i];\n for (const key in b) {\n if (b.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n }\n return a;\n}\n\nexport function wrapTryCatch(\n method: Function,\n onError: (error: RoomException, methodName: RoomMethodName) => void,\n exceptionClass: Type<RoomException>,\n methodName: RoomMethodName,\n rethrow: boolean = false,\n ...additionalErrorArgs: any[]\n) {\n return (...args: any[]) => {\n try {\n const result = method(...args);\n if (typeof (result?.catch) === \"function\") {\n return result.catch((e: Error) => {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n });\n }\n return result;\n } catch (e: any) {\n onError(new exceptionClass(e, e.message, ...args, ...additionalErrorArgs), methodName);\n if (rethrow) { throw e; }\n }\n };\n}\n\n/**\n * Dynamically import a module using either require() or import()\n * based on the current module system (CJS vs ESM).\n *\n * This avoids double-loading packages when running in mixed ESM/CJS environments.\n * Errors are silently caught - await the promise and handle errors at usage site.\n */\nexport function dynamicImport<T = any>(moduleName: string): Promise<T> {\n // __dirname exists in CJS but not in ESM\n if (\n typeof __dirname !== 'undefined' &&\n // @ts-ignore\n typeof (Bun) === 'undefined' // prevent bun from loading CJS modules\n ) {\n // CJS context - use require()\n try {\n return Promise.resolve(require(moduleName));\n } catch (e: any) {\n // If the error is not a MODULE_NOT_FOUND error, reject with the error.\n if (e.code !== 'MODULE_NOT_FOUND') {\n return Promise.reject(e);\n }\n return Promise.resolve(undefined);\n }\n } else {\n // ESM context - use import()\n const promise = import(moduleName);\n promise.catch(() => {}); // prevent unhandled rejection warnings\n return promise;\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/core",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.35",
|
|
4
4
|
"description": "Multiplayer Framework for Node.js.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"input": "./src/index.ts",
|
|
@@ -52,23 +52,23 @@
|
|
|
52
52
|
"debug": "^4.3.4",
|
|
53
53
|
"nanoid": "^3.3.11",
|
|
54
54
|
"@colyseus/shared-types": "^0.17.6",
|
|
55
|
-
"@colyseus/
|
|
56
|
-
"@colyseus/
|
|
55
|
+
"@colyseus/greeting-banner": "^3.0.8",
|
|
56
|
+
"@colyseus/better-call": "^1.3.1"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@colyseus/schema": "^4.0.7",
|
|
60
60
|
"express": "^5.0.0",
|
|
61
61
|
"@colyseus/redis-presence": "^0.17.6",
|
|
62
|
-
"@colyseus/
|
|
63
|
-
"@colyseus/
|
|
62
|
+
"@colyseus/redis-driver": "^0.17.6",
|
|
63
|
+
"@colyseus/tools": "^0.17.18"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
66
|
"@colyseus/schema": "^4.0.7",
|
|
67
67
|
"@pm2/io": "^6.1.0",
|
|
68
68
|
"express": "^4.16.0 || ^5.0.0",
|
|
69
69
|
"zod": "^4.1.12",
|
|
70
|
-
"@colyseus/
|
|
71
|
-
"@colyseus/
|
|
70
|
+
"@colyseus/better-call": "^1.3.1",
|
|
71
|
+
"@colyseus/ws-transport": "^0.17.9"
|
|
72
72
|
},
|
|
73
73
|
"optionalPeerDependencies": {
|
|
74
74
|
"@colyseus/tools": "0.17.x",
|
package/src/router/index.ts
CHANGED
|
@@ -62,18 +62,18 @@ export function bindRouterToTransport(transport: Transport, router: Router) {
|
|
|
62
62
|
if (expressApp) {
|
|
63
63
|
server.removeListener('request', expressApp);
|
|
64
64
|
|
|
65
|
-
// execute router first, fallback to express in case of 404
|
|
66
65
|
next = async (req: IncomingMessage, res: ServerResponse) => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
66
|
+
// check if the route is defined in the router
|
|
67
|
+
// if so, use the router handler, otherwise fallback to express
|
|
68
|
+
if (router.findRoute(req.method, req.url) !== undefined) {
|
|
69
|
+
const protocol = req.headers["x-forwarded-proto"] || ((req.socket as any).encrypted ? "https" : "http");
|
|
70
|
+
const base = `${protocol}://${req.headers[":authority"] || req.headers.host}`;
|
|
71
|
+
const response = await router.handler(getRequest({ base, request: req }));
|
|
72
|
+
return setResponse(res, response);
|
|
73
|
+
|
|
74
|
+
} else {
|
|
73
75
|
return expressApp['handle'](req, res);
|
|
74
76
|
}
|
|
75
|
-
|
|
76
|
-
return setResponse(res, response);
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
} else {
|
package/src/utils/Utils.ts
CHANGED
|
@@ -173,7 +173,11 @@ export function wrapTryCatch(
|
|
|
173
173
|
*/
|
|
174
174
|
export function dynamicImport<T = any>(moduleName: string): Promise<T> {
|
|
175
175
|
// __dirname exists in CJS but not in ESM
|
|
176
|
-
if (
|
|
176
|
+
if (
|
|
177
|
+
typeof __dirname !== 'undefined' &&
|
|
178
|
+
// @ts-ignore
|
|
179
|
+
typeof (Bun) === 'undefined' // prevent bun from loading CJS modules
|
|
180
|
+
) {
|
|
177
181
|
// CJS context - use require()
|
|
178
182
|
try {
|
|
179
183
|
return Promise.resolve(require(moduleName));
|