@colyseus/core 0.17.15 → 0.17.17

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/Server.ts"],
4
- "sourcesContent": ["import { greet } from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError } from './Debug.ts';\nimport * as matchMaker from './MatchMaker.ts';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';\n\nimport { type OnCreateOptions, Room } from './Room.ts';\nimport { registerGracefulShutdown, type Type } from './utils/Utils.ts';\n\nimport type { Presence } from \"./presence/Presence.ts\";\nimport { LocalPresence } from './presence/LocalPresence.ts';\nimport { LocalDriver } from './matchmaker/LocalDriver/LocalDriver.ts';\n\nimport { setTransport, Transport } from './Transport.ts';\nimport { logger, setLogger } from './Logger.ts';\nimport { setDevMode, isDevMode } from './utils/DevMode.ts';\nimport { type Router, bindRouterToServer } from './router/index.ts';\nimport { type SDKTypes as SharedSDKTypes } from '@colyseus/shared-types';\nimport { getDefaultRouter } from './router/default_routes.ts';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n};\n\n/**\n * Exposed types for the client-side SDK.\n * Re-exported from @colyseus/shared-types with specific type constraints.\n */\nexport interface SDKTypes<\n RoomTypes extends Record<string, RegisteredHandler> = any,\n Routes extends Router = any\n> extends SharedSDKTypes<RoomTypes, Routes> {}\n\nexport class Server<\n RoomTypes extends Record<string, RegisteredHandler> = any,\n Routes extends Router = any\n> implements SDKTypes<RoomTypes, Routes> {\n '~rooms': RoomTypes;\n '~routes': Routes;\n\n public transport: Transport;\n public router: Routes;\n public options: ServerOptions;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number | string;\n protected greet: boolean;\n\n private _originalRoomOnMessage: typeof Room.prototype['_onMessage'] | null = null;\n\n constructor(options: ServerOptions = {}) {\n const {\n gracefullyShutdown = true,\n greet = true\n } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.options = options;\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n options.selectProcessIdToCreateRoom,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n this.transport = options.transport || this.getDefaultTransport(options);\n delete options.transport;\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port - Port number or Unix socket path\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number | string, hostname?: string, backlog?: number, listeningListener?: Function) {\n //\n // if Colyseus Cloud is detected, use @colyseus/tools to listen\n //\n if (process.env.COLYSEUS_CLOUD !== undefined ) {\n if (typeof(hostname) === \"number\") {\n //\n // workaround, @colyseus/tools calls server.listen() again with the port as a string\n //\n hostname = undefined;\n\n } else {\n try {\n return (await import(\"@colyseus/tools\")).listen(this);\n } catch (error) {\n const err = new Error(\"Please install @colyseus/tools to be able to host on Colyseus Cloud.\");\n err.cause = error;\n throw err;\n }\n }\n }\n\n //\n // otherwise, listen on the port directly\n //\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.accept();\n\n /**\n * Greetings!\n */\n if (this.greet) {\n greet();\n }\n\n return new Promise<void>((resolve, reject) => {\n // TODO: refactor me!\n // set transport globally, to be used by matchmaking route\n setTransport(this.transport);\n\n this.transport.listen(port, hostname, backlog, (err) => {\n const server = this.transport.server;\n\n // default router is used if no router is provided\n if (!this.router) {\n this.router = getDefaultRouter() as unknown as Routes;\n\n } else {\n // make sure default routes are included\n // https://github.com/Bekacru/better-call/pull/67\n this.router = this.router.extend({ ...getDefaultRouter().endpoints }) as unknown as Routes;\n }\n\n if (server) {\n server.on('error', (err) => reject(err));\n bindRouterToServer(server, this.router);\n }\n\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: OnCreateOptions<T>,\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: OnCreateOptions<T>,\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | OnCreateOptions<T>,\n defaultOptions?: OnCreateOptions<T>,\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return;\n }\n\n try {\n // custom \"before shutdown\" method\n await this.onBeforeShutdownCallback();\n\n // this is going to lock all rooms and wait for them to be disposed\n await matchMaker.gracefullyShutdown();\n\n this.transport.shutdown();\n this.presence.shutdown();\n await this.driver.shutdown();\n\n // custom \"after shutdown\" method\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : function (this: Room, client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => originalOnMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n public onBeforeShutdown(callback: () => void | Promise<any>) {\n this.onBeforeShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected onBeforeShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n}\n\nexport type DefineServerOptions<\n T extends Record<string, RegisteredHandler>,\n R extends Router\n> = ServerOptions & {\n rooms: T,\n routes?: R,\n};\n\nexport function defineServer<\n T extends Record<string, RegisteredHandler>,\n R extends Router\n>(\n options: DefineServerOptions<T, R>,\n): Server<T, R> {\n const { rooms, routes, ...serverOptions } = options;\n const server = new Server<T, R>(serverOptions);\n\n server.router = routes;\n\n for (const [name, handler] of Object.entries(rooms)) {\n handler.name = name;\n matchMaker.addRoomType(handler);\n }\n\n return server;\n}\n\nexport function defineRoom<T extends Type<Room>>(\n roomKlass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n): RegisteredHandler<T> {\n return new RegisteredHandler(roomKlass, defaultOptions);\n}"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { greet } from \"@colyseus/greeting-banner\";\n\nimport { debugAndPrintError } from './Debug.ts';\nimport * as matchMaker from './MatchMaker.ts';\nimport { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';\n\nimport { type OnCreateOptions, Room } from './Room.ts';\nimport { registerGracefulShutdown, type Type } from './utils/Utils.ts';\n\nimport type { Presence } from \"./presence/Presence.ts\";\nimport { LocalPresence } from './presence/LocalPresence.ts';\nimport { LocalDriver } from './matchmaker/LocalDriver/LocalDriver.ts';\n\nimport { setTransport, Transport } from './Transport.ts';\nimport { logger, setLogger } from './Logger.ts';\nimport { setDevMode, isDevMode } from './utils/DevMode.ts';\nimport { type Router, bindRouterToServer } from './router/index.ts';\nimport { type SDKTypes as SharedSDKTypes } from '@colyseus/shared-types';\nimport { getDefaultRouter } from './router/default_routes.ts';\n\nexport type ServerOptions = {\n publicAddress?: string,\n presence?: Presence,\n driver?: matchMaker.MatchMakerDriver,\n transport?: Transport,\n gracefullyShutdown?: boolean,\n logger?: any;\n\n /**\n * Custom function to determine which process should handle room creation.\n * Default: assign new rooms the process with least amount of rooms created\n */\n selectProcessIdToCreateRoom?: matchMaker.SelectProcessIdCallback;\n\n /**\n * If enabled, rooms are going to be restored in the server-side upon restart,\n * clients are going to automatically re-connect when server reboots.\n *\n * Beware of \"schema mismatch\" issues. When updating Schema structures and\n * reloading existing data, you may see \"schema mismatch\" errors in the\n * client-side.\n *\n * (This operation is costly and should not be used in a production\n * environment)\n */\n devMode?: boolean,\n\n /**\n * Display greeting message on server start.\n * Default: true\n */\n greet?: boolean,\n};\n\n/**\n * Exposed types for the client-side SDK.\n * Re-exported from @colyseus/shared-types with specific type constraints.\n */\nexport interface SDKTypes<\n RoomTypes extends Record<string, RegisteredHandler> = any,\n Routes extends Router = any\n> extends SharedSDKTypes<RoomTypes, Routes> {}\n\nexport class Server<\n RoomTypes extends Record<string, RegisteredHandler> = any,\n Routes extends Router = any\n> implements SDKTypes<RoomTypes, Routes> {\n '~rooms': RoomTypes;\n '~routes': Routes;\n\n public transport: Transport;\n public router: Routes;\n public options: ServerOptions;\n\n protected presence: Presence;\n protected driver: matchMaker.MatchMakerDriver;\n\n protected port: number | string;\n protected greet: boolean;\n\n private _originalRoomOnMessage: typeof Room.prototype['_onMessage'] | null = null;\n\n constructor(options: ServerOptions = {}) {\n const {\n gracefullyShutdown = true,\n greet = true\n } = options;\n\n setDevMode(options.devMode === true);\n\n this.presence = options.presence || new LocalPresence();\n this.driver = options.driver || new LocalDriver();\n this.options = options;\n this.greet = greet;\n\n this.attach(options);\n\n matchMaker.setup(\n this.presence,\n this.driver,\n options.publicAddress,\n options.selectProcessIdToCreateRoom,\n );\n\n if (gracefullyShutdown) {\n registerGracefulShutdown((err) => this.gracefullyShutdown(true, err));\n }\n\n if (options.logger) {\n setLogger(options.logger);\n }\n }\n\n public attach(options: ServerOptions) {\n this.transport = options.transport || this.getDefaultTransport(options);\n }\n\n /**\n * Bind the server into the port specified.\n *\n * @param port - Port number or Unix socket path\n * @param hostname\n * @param backlog\n * @param listeningListener\n */\n public async listen(port: number | string, hostname?: string, backlog?: number, listeningListener?: Function) {\n //\n // if Colyseus Cloud is detected, use @colyseus/tools to listen\n //\n if (process.env.COLYSEUS_CLOUD !== undefined ) {\n if (typeof(hostname) === \"number\") {\n //\n // workaround, @colyseus/tools calls server.listen() again with the port as a string\n //\n hostname = undefined;\n\n } else {\n try {\n return (await import(\"@colyseus/tools\")).listen(this);\n } catch (error) {\n const err = new Error(\"Please install @colyseus/tools to be able to host on Colyseus Cloud.\");\n err.cause = error;\n throw err;\n }\n }\n }\n\n //\n // otherwise, listen on the port directly\n //\n this.port = port;\n\n //\n // Make sure matchmaker is ready before accepting connections\n // (isDevMode: matchmaker may take extra milliseconds to restore the rooms)\n //\n await matchMaker.accept();\n\n /**\n * Greetings!\n */\n if (this.greet) {\n greet();\n }\n\n return new Promise<void>((resolve, reject) => {\n // TODO: refactor me!\n // set transport globally, to be used by matchmaking route\n setTransport(this.transport);\n\n this.transport.listen(port, hostname, backlog, (err) => {\n const server = this.transport.server;\n\n // default router is used if no router is provided\n if (!this.router) {\n this.router = getDefaultRouter() as unknown as Routes;\n\n } else {\n // make sure default routes are included\n // https://github.com/Bekacru/better-call/pull/67\n this.router = this.router.extend({ ...getDefaultRouter().endpoints }) as unknown as Routes;\n }\n\n if (server) {\n server.on('error', (err) => reject(err));\n bindRouterToServer(server, this.router);\n }\n\n if (listeningListener) {\n listeningListener(err);\n }\n\n if (err) {\n reject(err);\n\n } else {\n resolve();\n }\n });\n });\n }\n\n /**\n * Define a new type of room for matchmaking.\n *\n * @param name public room identifier for match-making.\n * @param roomClass Room class definition\n * @param defaultOptions default options for `onCreate`\n */\n public define<T extends Type<Room>>(\n roomClass: T,\n defaultOptions?: OnCreateOptions<T>,\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n name: string,\n roomClass: T,\n defaultOptions?: OnCreateOptions<T>,\n ): RegisteredHandler\n public define<T extends Type<Room>>(\n nameOrHandler: string | T,\n handlerOrOptions: T | OnCreateOptions<T>,\n defaultOptions?: OnCreateOptions<T>,\n ): RegisteredHandler {\n const name = (typeof(nameOrHandler) === \"string\")\n ? nameOrHandler\n : nameOrHandler.name;\n\n const roomClass = (typeof(nameOrHandler) === \"string\")\n ? handlerOrOptions\n : nameOrHandler;\n\n const options = (typeof(nameOrHandler) === \"string\")\n ? defaultOptions\n : handlerOrOptions;\n\n return matchMaker.defineRoomType(name, roomClass, options);\n }\n\n /**\n * Remove a room definition from matchmaking.\n * This method does not destroy any room. It only dissallows matchmaking\n */\n public removeRoomType(name: string): void {\n matchMaker.removeRoomType(name);\n }\n\n public async gracefullyShutdown(exit: boolean = true, err?: Error) {\n if (matchMaker.state === matchMaker.MatchMakerState.SHUTTING_DOWN) {\n return;\n }\n\n try {\n // custom \"before shutdown\" method\n await this.onBeforeShutdownCallback();\n\n // this is going to lock all rooms and wait for them to be disposed\n await matchMaker.gracefullyShutdown();\n\n this.transport.shutdown();\n this.presence.shutdown();\n await this.driver.shutdown();\n\n // custom \"after shutdown\" method\n await this.onShutdownCallback();\n\n } catch (e) {\n debugAndPrintError(`error during shutdown: ${e}`);\n\n } finally {\n if (exit) {\n process.exit((err && !isDevMode) ? 1 : 0);\n }\n }\n }\n\n /**\n * Add simulated latency between client and server.\n * @param milliseconds round trip latency in milliseconds.\n */\n public simulateLatency(milliseconds: number) {\n if (milliseconds > 0) {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation enabled \u2192 ${milliseconds}ms latency for round trip.`);\n } else {\n logger.warn(`\uD83D\uDCF6\uFE0F\u2757 Colyseus latency simulation disabled.`);\n }\n\n const halfwayMS = (milliseconds / 2);\n this.transport.simulateLatency(halfwayMS);\n\n if (this._originalRoomOnMessage == null) {\n this._originalRoomOnMessage = Room.prototype['_onMessage'];\n }\n\n const originalOnMessage = this._originalRoomOnMessage;\n\n Room.prototype['_onMessage'] = milliseconds <= Number.EPSILON ? originalOnMessage : function (this: Room, client, buffer) {\n // uWebSockets.js: duplicate buffer because it is cleared at native layer before the timeout.\n const cachedBuffer = Buffer.from(buffer);\n setTimeout(() => originalOnMessage.call(this, client, cachedBuffer), halfwayMS);\n };\n }\n\n /**\n * Register a callback that is going to be executed before the server shuts down.\n * @param callback\n */\n public onShutdown(callback: () => void | Promise<any>) {\n this.onShutdownCallback = callback;\n }\n\n public onBeforeShutdown(callback: () => void | Promise<any>) {\n this.onBeforeShutdownCallback = callback;\n }\n\n protected getDefaultTransport(_: any): Transport {\n throw new Error(\"Please provide a 'transport' layer. Default transport not set.\");\n }\n\n protected onShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n\n protected onBeforeShutdownCallback: () => void | Promise<any> =\n () => Promise.resolve()\n}\n\nexport type DefineServerOptions<\n T extends Record<string, RegisteredHandler>,\n R extends Router\n> = ServerOptions & {\n rooms: T,\n routes?: R,\n};\n\nexport function defineServer<\n T extends Record<string, RegisteredHandler>,\n R extends Router\n>(\n options: DefineServerOptions<T, R>,\n): Server<T, R> {\n const { rooms, routes, ...serverOptions } = options;\n const server = new Server<T, R>(serverOptions);\n\n server.router = routes;\n\n for (const [name, handler] of Object.entries(rooms)) {\n handler.name = name;\n matchMaker.addRoomType(handler);\n }\n\n return server;\n}\n\nexport function defineRoom<T extends Type<Room>>(\n roomKlass: T,\n defaultOptions?: Parameters<NonNullable<InstanceType<T>['onCreate']>>[0],\n): RegisteredHandler<T> {\n return new RegisteredHandler(roomKlass, defaultOptions);\n}"],
5
+ "mappings": "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",
6
6
  "names": ["gracefullyShutdown", "greet", "err"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import { ClockTimer as Clock, Delayed } from '@colyseus/timer';\n\n// Shared types - re-export from @colyseus/shared-types for convenience\nexport {\n Protocol,\n ErrorCode,\n CloseCode,\n type InferState,\n type ExtractRoomMessages,\n type ExtractRoomClientMessages,\n} from '@colyseus/shared-types';\n\n// Core classes\nexport { Server, defineRoom, defineServer, type ServerOptions, type SDKTypes } from './Server.ts';\nexport { Room, room, RoomInternalState, validate, type RoomOptions, type MessageHandlerWithFormat, type Messages, type ExtractRoomState, type ExtractRoomMetadata, type ExtractRoomClient } from './Room.ts';\nexport { getMessageBytes } from './Protocol.ts';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';\nexport { ServerError } from './errors/ServerError.ts';\n\nexport {\n type RoomException,\n type RoomMethodName,\n OnCreateException,\n OnAuthException,\n OnJoinException,\n OnLeaveException,\n OnDisposeException,\n OnMessageException,\n SimulationIntervalException,\n TimedEventException,\n} from './errors/RoomExceptions.ts';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker.ts';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby.ts';\n\n// Driver\nexport * from './matchmaker/LocalDriver/LocalDriver.ts';\nexport { initializeRoomCache } from './matchmaker/driver.ts';\n\n// Transport\nexport { type Client, type ClientPrivate, type AuthContext, ClientState, ClientArray, Transport, type ISendOptions, connectClientToRoom } from './Transport.ts';\n\n// Presence\nexport { type Presence } from './presence/Presence.ts';\nexport { LocalPresence } from './presence/LocalPresence.ts';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer.ts';\nexport { SchemaSerializer } from './serializer/SchemaSerializer.ts';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils.ts';\nexport { isDevMode } from './utils/DevMode.ts';\n\n// IPC\nexport { subscribeIPC, requestFromIPC } from './IPC.ts';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug.ts';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom.ts';\nexport { RelayRoom } from './rooms/RelayRoom.ts';\nexport { RankedQueueRoom, type RankedQueueOptions, type MatchGroup, type MatchTeam, type ClientQueueData } from './rooms/RankedQueueRoom.ts';\n\n// Router / Endpoints\nexport {\n createEndpoint,\n createInternalContext,\n createMiddleware,\n createRouter,\n toNodeHandler,\n __globalEndpoints,\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from './router/index.ts';\n\n// Abstract logging support\nexport { logger } from './Logger.ts';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA6C;AAG7C,0BAOO;AAGP,oBAAoF;AACpF,kBAAiM;AACjM,sBAAgC;AAChC,+BAAkC;AAClC,yBAA4B;AAE5B,4BAWO;AAGP,iBAA4B;AAE5B,mBAA4C;AAG5C,0BAAc,qDAtCd;AAuCA,oBAAoC;AAGpC,uBAA+I;AAG/I,sBAA8B;AAC9B,2BAA8B;AAG9B,wBAAgC;AAChC,8BAAiC;AAIjC,mBAAgF;AAChF,qBAA0B;AAG1B,iBAA6C;AAG7C,mBASO;AAGP,uBAA0B;AAC1B,uBAA0B;AAC1B,6BAAgH;AAGhH,oBAaO;AAGP,oBAAuB;",
4
+ "sourcesContent": ["import { ClockTimer as Clock, Delayed } from '@colyseus/timer';\n\n// Shared types - re-export from @colyseus/shared-types for convenience\nexport {\n Protocol,\n ErrorCode,\n CloseCode,\n type InferState,\n type ExtractRoomMessages,\n type ExtractRoomClientMessages,\n} from '@colyseus/shared-types';\n\n// Core classes\nexport { Server, defineRoom, defineServer, type ServerOptions, type SDKTypes } from './Server.ts';\nexport { Room, room, RoomInternalState, validate, type RoomOptions, type MessageHandlerWithFormat, type Messages, type ExtractRoomState, type ExtractRoomMetadata, type ExtractRoomClient } from './Room.ts';\nexport { getMessageBytes } from './Protocol.ts';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';\nexport { ServerError } from './errors/ServerError.ts';\n\nexport {\n type RoomException,\n type RoomMethodName,\n OnCreateException,\n OnAuthException,\n OnJoinException,\n OnLeaveException,\n OnDisposeException,\n OnMessageException,\n SimulationIntervalException,\n TimedEventException,\n} from './errors/RoomExceptions.ts';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker.ts';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby.ts';\n\n// Driver\nexport * from './matchmaker/LocalDriver/LocalDriver.ts';\nexport { initializeRoomCache } from './matchmaker/driver.ts';\n\n// Transport\nexport { type Client, type ClientPrivate, type AuthContext, ClientState, ClientArray, Transport, type ISendOptions, connectClientToRoom } from './Transport.ts';\n\n// Presence\nexport { type Presence } from './presence/Presence.ts';\nexport { LocalPresence } from './presence/LocalPresence.ts';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer.ts';\nexport { SchemaSerializer } from './serializer/SchemaSerializer.ts';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils.ts';\nexport { isDevMode } from './utils/DevMode.ts';\n\n// IPC\nexport { subscribeIPC, requestFromIPC } from './IPC.ts';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug.ts';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom.ts';\nexport { RelayRoom } from './rooms/RelayRoom.ts';\nexport { RankedQueueRoom, type RankedQueueOptions, type MatchGroup, type MatchTeam, type ClientQueueData } from './rooms/RankedQueueRoom.ts';\n\n// Router / Endpoints\nexport {\n createEndpoint,\n createInternalContext,\n createMiddleware,\n createRouter,\n toNodeHandler,\n __globalEndpoints,\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointHandler,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from './router/index.ts';\n\n// Abstract logging support\nexport { logger } from './Logger.ts';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,4BAAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA6C;AAG7C,0BAOO;AAGP,oBAAoF;AACpF,kBAAiM;AACjM,sBAAgC;AAChC,+BAAkC;AAClC,yBAA4B;AAE5B,4BAWO;AAGP,iBAA4B;AAE5B,mBAA4C;AAG5C,0BAAc,qDAtCd;AAuCA,oBAAoC;AAGpC,uBAA+I;AAG/I,sBAA8B;AAC9B,2BAA8B;AAG9B,wBAAgC;AAChC,8BAAiC;AAIjC,mBAAgF;AAChF,qBAA0B;AAG1B,iBAA6C;AAG7C,mBASO;AAGP,uBAA0B;AAC1B,uBAA0B;AAC1B,6BAAgH;AAGhH,oBAcO;AAGP,oBAAuB;",
6
6
  "names": ["Clock"]
7
7
  }
package/build/index.d.ts CHANGED
@@ -24,5 +24,5 @@ export { debugMatchMaking, debugMessage, debugPatch, debugError, debugConnection
24
24
  export { LobbyRoom } from './rooms/LobbyRoom.ts';
25
25
  export { RelayRoom } from './rooms/RelayRoom.ts';
26
26
  export { RankedQueueRoom, type RankedQueueOptions, type MatchGroup, type MatchTeam, type ClientQueueData } from './rooms/RankedQueueRoom.ts';
27
- export { createEndpoint, createInternalContext, createMiddleware, createRouter, toNodeHandler, __globalEndpoints, type Router, type RouterConfig, type Endpoint, type EndpointOptions, type EndpointContext, type StrictEndpoint, } from './router/index.ts';
27
+ export { createEndpoint, createInternalContext, createMiddleware, createRouter, toNodeHandler, __globalEndpoints, type Router, type RouterConfig, type Endpoint, type EndpointHandler, type EndpointOptions, type EndpointContext, type StrictEndpoint, } from './router/index.ts';
28
28
  export { logger } from './Logger.ts';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import { ClockTimer as Clock, Delayed } from '@colyseus/timer';\n\n// Shared types - re-export from @colyseus/shared-types for convenience\nexport {\n Protocol,\n ErrorCode,\n CloseCode,\n type InferState,\n type ExtractRoomMessages,\n type ExtractRoomClientMessages,\n} from '@colyseus/shared-types';\n\n// Core classes\nexport { Server, defineRoom, defineServer, type ServerOptions, type SDKTypes } from './Server.ts';\nexport { Room, room, RoomInternalState, validate, type RoomOptions, type MessageHandlerWithFormat, type Messages, type ExtractRoomState, type ExtractRoomMetadata, type ExtractRoomClient } from './Room.ts';\nexport { getMessageBytes } from './Protocol.ts';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';\nexport { ServerError } from './errors/ServerError.ts';\n\nexport {\n type RoomException,\n type RoomMethodName,\n OnCreateException,\n OnAuthException,\n OnJoinException,\n OnLeaveException,\n OnDisposeException,\n OnMessageException,\n SimulationIntervalException,\n TimedEventException,\n} from './errors/RoomExceptions.ts';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker.ts';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby.ts';\n\n// Driver\nexport * from './matchmaker/LocalDriver/LocalDriver.ts';\nexport { initializeRoomCache } from './matchmaker/driver.ts';\n\n// Transport\nexport { type Client, type ClientPrivate, type AuthContext, ClientState, ClientArray, Transport, type ISendOptions, connectClientToRoom } from './Transport.ts';\n\n// Presence\nexport { type Presence } from './presence/Presence.ts';\nexport { LocalPresence } from './presence/LocalPresence.ts';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer.ts';\nexport { SchemaSerializer } from './serializer/SchemaSerializer.ts';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils.ts';\nexport { isDevMode } from './utils/DevMode.ts';\n\n// IPC\nexport { subscribeIPC, requestFromIPC } from './IPC.ts';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug.ts';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom.ts';\nexport { RelayRoom } from './rooms/RelayRoom.ts';\nexport { RankedQueueRoom, type RankedQueueOptions, type MatchGroup, type MatchTeam, type ClientQueueData } from './rooms/RankedQueueRoom.ts';\n\n// Router / Endpoints\nexport {\n createEndpoint,\n createInternalContext,\n createMiddleware,\n createRouter,\n toNodeHandler,\n __globalEndpoints,\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from './router/index.ts';\n\n// Abstract logging support\nexport { logger } from './Logger.ts';\n"],
5
- "mappings": ";AAAA,SAAS,cAAc,OAAO,eAAe;AAG7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAGP,SAAS,QAAQ,YAAY,oBAAuD;AACpF,SAAS,MAAM,MAAM,mBAAmB,gBAAyJ;AACjM,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAE5B;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,YAAY,gBAAgB;AAE5B,SAAS,aAAa,sBAAsB;AAG5C,cAAc;AACd,SAAS,2BAA2B;AAGpC,SAA4D,aAAa,aAAa,WAA8B,2BAA2B;AAG/I,eAA8B;AAC9B,SAAS,qBAAqB;AAG9B,eAAgC;AAChC,SAAS,wBAAwB;AAIjC,SAAS,YAAY,UAAU,gBAAgB,WAAW,sBAAsB;AAChF,SAAS,iBAAiB;AAG1B,SAAS,cAAc,sBAAsB;AAG7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,uBAAuG;AAGhH;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAOK;AAGP,SAAS,cAAc;",
4
+ "sourcesContent": ["import { ClockTimer as Clock, Delayed } from '@colyseus/timer';\n\n// Shared types - re-export from @colyseus/shared-types for convenience\nexport {\n Protocol,\n ErrorCode,\n CloseCode,\n type InferState,\n type ExtractRoomMessages,\n type ExtractRoomClientMessages,\n} from '@colyseus/shared-types';\n\n// Core classes\nexport { Server, defineRoom, defineServer, type ServerOptions, type SDKTypes } from './Server.ts';\nexport { Room, room, RoomInternalState, validate, type RoomOptions, type MessageHandlerWithFormat, type Messages, type ExtractRoomState, type ExtractRoomMetadata, type ExtractRoomClient } from './Room.ts';\nexport { getMessageBytes } from './Protocol.ts';\nexport { RegisteredHandler } from './matchmaker/RegisteredHandler.ts';\nexport { ServerError } from './errors/ServerError.ts';\n\nexport {\n type RoomException,\n type RoomMethodName,\n OnCreateException,\n OnAuthException,\n OnJoinException,\n OnLeaveException,\n OnDisposeException,\n OnMessageException,\n SimulationIntervalException,\n TimedEventException,\n} from './errors/RoomExceptions.ts';\n\n// MatchMaker\nimport * as matchMaker from './MatchMaker.ts';\nexport { matchMaker };\nexport { updateLobby, subscribeLobby } from './matchmaker/Lobby.ts';\n\n// Driver\nexport * from './matchmaker/LocalDriver/LocalDriver.ts';\nexport { initializeRoomCache } from './matchmaker/driver.ts';\n\n// Transport\nexport { type Client, type ClientPrivate, type AuthContext, ClientState, ClientArray, Transport, type ISendOptions, connectClientToRoom } from './Transport.ts';\n\n// Presence\nexport { type Presence } from './presence/Presence.ts';\nexport { LocalPresence } from './presence/LocalPresence.ts';\n\n// Serializers\nexport { type Serializer } from './serializer/Serializer.ts';\nexport { SchemaSerializer } from './serializer/SchemaSerializer.ts';\n\n// Utilities\nexport { Clock, Delayed };\nexport { generateId, Deferred, HttpServerMock, spliceOne, getBearerToken } from './utils/Utils.ts';\nexport { isDevMode } from './utils/DevMode.ts';\n\n// IPC\nexport { subscribeIPC, requestFromIPC } from './IPC.ts';\n\n// Debug\nexport {\n debugMatchMaking,\n debugMessage,\n debugPatch,\n debugError,\n debugConnection,\n debugDriver,\n debugPresence,\n debugAndPrintError,\n} from './Debug.ts';\n\n// Default rooms\nexport { LobbyRoom } from './rooms/LobbyRoom.ts';\nexport { RelayRoom } from './rooms/RelayRoom.ts';\nexport { RankedQueueRoom, type RankedQueueOptions, type MatchGroup, type MatchTeam, type ClientQueueData } from './rooms/RankedQueueRoom.ts';\n\n// Router / Endpoints\nexport {\n createEndpoint,\n createInternalContext,\n createMiddleware,\n createRouter,\n toNodeHandler,\n __globalEndpoints,\n type Router,\n type RouterConfig,\n type Endpoint,\n type EndpointHandler,\n type EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from './router/index.ts';\n\n// Abstract logging support\nexport { logger } from './Logger.ts';\n"],
5
+ "mappings": ";AAAA,SAAS,cAAc,OAAO,eAAe;AAG7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAGP,SAAS,QAAQ,YAAY,oBAAuD;AACpF,SAAS,MAAM,MAAM,mBAAmB,gBAAyJ;AACjM,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAE5B;AAAA,EAGE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,YAAY,gBAAgB;AAE5B,SAAS,aAAa,sBAAsB;AAG5C,cAAc;AACd,SAAS,2BAA2B;AAGpC,SAA4D,aAAa,aAAa,WAA8B,2BAA2B;AAG/I,eAA8B;AAC9B,SAAS,qBAAqB;AAG9B,eAAgC;AAChC,SAAS,wBAAwB;AAIjC,SAAS,YAAY,UAAU,gBAAgB,WAAW,sBAAsB;AAChF,SAAS,iBAAiB;AAG1B,SAAS,cAAc,sBAAsB;AAG7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,uBAAuG;AAGhH;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAQK;AAGP,SAAS,cAAc;",
6
6
  "names": []
7
7
  }
@@ -39,7 +39,7 @@ var matchMaker = __toESM(require("../MatchMaker.cjs"), 1);
39
39
  var controller = {
40
40
  DEFAULT_CORS_HEADERS: {
41
41
  "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization",
42
- "Access-Control-Allow-Methods": "OPTIONS, POST, GET",
42
+ "Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
43
43
  "Access-Control-Allow-Credentials": "true",
44
44
  "Access-Control-Allow-Origin": "*",
45
45
  "Access-Control-Max-Age": "2592000"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/matchmaker/controller.ts"],
4
- "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from '@colyseus/shared-types';\nimport { ServerError } from '../errors/ServerError.ts';\nimport * as matchMaker from '../MatchMaker.ts';\nimport type { AuthContext } from '../Transport.ts';\n\nexport const controller = {\n DEFAULT_CORS_HEADERS: {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n },\n\n exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(headers) {\n * if (headers.get('referer') !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(headers: Headers): { [header: string]: string } {\n return {\n ['Access-Control-Allow-Origin']: headers.get(\"origin\") || \"*\",\n };\n },\n\n async invokeMethod(\n method: string,\n roomName: string,\n clientOptions: matchMaker.ClientOptions = {},\n authOptions?: AuthContext,\n ) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions, authOptions);\n\n } catch (e: any) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
4
+ "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from '@colyseus/shared-types';\nimport { ServerError } from '../errors/ServerError.ts';\nimport * as matchMaker from '../MatchMaker.ts';\nimport type { AuthContext } from '../Transport.ts';\n\nexport const controller = {\n DEFAULT_CORS_HEADERS: {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',\n 'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n },\n\n exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(headers) {\n * if (headers.get('referer') !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(headers: Headers): { [header: string]: string } {\n return {\n ['Access-Control-Allow-Origin']: headers.get(\"origin\") || \"*\",\n };\n },\n\n async invokeMethod(\n method: string,\n roomName: string,\n clientOptions: matchMaker.ClientOptions = {},\n authOptions?: AuthContext,\n ) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions, authOptions);\n\n } catch (e: any) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,0BAA0B;AAC1B,yBAA4B;AAC5B,iBAA4B;AAGrB,IAAM,aAAa;AAAA,EACxB,sBAAsB;AAAA,IACpB,gCAAgC;AAAA,IAChC,gCAAgC;AAAA,IAChC,oCAAoC;AAAA,IACpC,+BAA+B;AAAA,IAC/B,0BAA0B;AAAA;AAAA,EAE5B;AAAA,EAEA,gBAAgB,CAAC,gBAAgB,UAAU,QAAQ,YAAY,WAAW;AAAA,EAC1E,sBAAsB;AAAA,EACtB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBhB,eAAe,SAAgD;AAC7D,WAAO;AAAA,MACL,CAAC,6BAA6B,GAAG,QAAQ,IAAI,QAAQ,KAAK;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,QACA,UACA,gBAA0C,CAAC,GAC3C,aACA;AACA,QAAI,KAAK,eAAe,QAAQ,MAAM,MAAM,IAAI;AAC9C,YAAM,IAAI,+BAAY,8BAAU,sBAAsB,mBAAmB,MAAM,GAAG;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,MAAM,WAAW,MAAM,EAAE,UAAU,eAAe,WAAW;AAAA,IAEtE,SAAS,GAAQ;AACf,YAAM,IAAI,+BAAY,EAAE,QAAQ,8BAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -5,7 +5,7 @@ import * as matchMaker from "../MatchMaker.mjs";
5
5
  var controller = {
6
6
  DEFAULT_CORS_HEADERS: {
7
7
  "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, Authorization",
8
- "Access-Control-Allow-Methods": "OPTIONS, POST, GET",
8
+ "Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
9
9
  "Access-Control-Allow-Credentials": "true",
10
10
  "Access-Control-Allow-Origin": "*",
11
11
  "Access-Control-Max-Age": "2592000"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/matchmaker/controller.ts"],
4
- "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from '@colyseus/shared-types';\nimport { ServerError } from '../errors/ServerError.ts';\nimport * as matchMaker from '../MatchMaker.ts';\nimport type { AuthContext } from '../Transport.ts';\n\nexport const controller = {\n DEFAULT_CORS_HEADERS: {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',\n 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n },\n\n exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(headers) {\n * if (headers.get('referer') !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(headers: Headers): { [header: string]: string } {\n return {\n ['Access-Control-Allow-Origin']: headers.get(\"origin\") || \"*\",\n };\n },\n\n async invokeMethod(\n method: string,\n roomName: string,\n clientOptions: matchMaker.ClientOptions = {},\n authOptions?: AuthContext,\n ) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions, authOptions);\n\n } catch (e: any) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
4
+ "sourcesContent": ["/**\n * Matchmaking controller\n * (for interoperability between different http frameworks, e.g. express, uWebSockets.js, etc)\n */\n\nimport { ErrorCode } from '@colyseus/shared-types';\nimport { ServerError } from '../errors/ServerError.ts';\nimport * as matchMaker from '../MatchMaker.ts';\nimport type { AuthContext } from '../Transport.ts';\n\nexport const controller = {\n DEFAULT_CORS_HEADERS: {\n 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',\n 'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',\n 'Access-Control-Allow-Credentials': 'true',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Max-Age': '2592000',\n // ...\n },\n\n exposedMethods: ['joinOrCreate', 'create', 'join', 'joinById', 'reconnect'],\n allowedRoomNameChars: /([a-zA-Z_\\-0-9]+)/gi,\n matchmakeRoute: 'matchmake',\n\n /**\n * You can manually change the default corsHeaders by overwriting the `getCorsHeaders()` method:\n * ```\n * import { matchMaker } from \"@colyseus/core\";\n * matchMaker.controller.getCorsHeaders = function(headers) {\n * if (headers.get('referer') !== \"xxx\") {\n * }\n *\n * return {\n * 'Access-Control-Allow-Origin': 'safedomain.com',\n * }\n * }\n * ```\n */\n getCorsHeaders(headers: Headers): { [header: string]: string } {\n return {\n ['Access-Control-Allow-Origin']: headers.get(\"origin\") || \"*\",\n };\n },\n\n async invokeMethod(\n method: string,\n roomName: string,\n clientOptions: matchMaker.ClientOptions = {},\n authOptions?: AuthContext,\n ) {\n if (this.exposedMethods.indexOf(method) === -1) {\n throw new ServerError(ErrorCode.MATCHMAKE_NO_HANDLER, `invalid method \"${method}\"`);\n }\n\n try {\n return await matchMaker[method](roomName, clientOptions, authOptions);\n\n } catch (e: any) {\n throw new ServerError(e.code || ErrorCode.MATCHMAKE_UNHANDLED, e.message);\n }\n }\n\n}\n\n"],
5
5
  "mappings": ";AAKA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,YAAY,gBAAgB;AAGrB,IAAM,aAAa;AAAA,EACxB,sBAAsB;AAAA,IACpB,gCAAgC;AAAA,IAChC,gCAAgC;AAAA,IAChC,oCAAoC;AAAA,IACpC,+BAA+B;AAAA,IAC/B,0BAA0B;AAAA;AAAA,EAE5B;AAAA,EAEA,gBAAgB,CAAC,gBAAgB,UAAU,QAAQ,YAAY,WAAW;AAAA,EAC1E,sBAAsB;AAAA,EACtB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBhB,eAAe,SAAgD;AAC7D,WAAO;AAAA,MACL,CAAC,6BAA6B,GAAG,QAAQ,IAAI,QAAQ,KAAK;AAAA,IAC5D;AAAA,EACF;AAAA,EAEA,MAAM,aACJ,QACA,UACA,gBAA0C,CAAC,GAC3C,aACA;AACA,QAAI,KAAK,eAAe,QAAQ,MAAM,MAAM,IAAI;AAC9C,YAAM,IAAI,YAAY,UAAU,sBAAsB,mBAAmB,MAAM,GAAG;AAAA,IACpF;AAEA,QAAI;AACF,aAAO,MAAM,WAAW,MAAM,EAAE,UAAU,eAAe,WAAW;AAAA,IAEtE,SAAS,GAAQ;AACf,YAAM,IAAI,YAAY,EAAE,QAAQ,UAAU,qBAAqB,EAAE,OAAO;AAAA,IAC1E;AAAA,EACF;AAEF;",
6
6
  "names": []
7
7
  }
@@ -28,7 +28,7 @@ export declare class LocalPresence implements Presence {
28
28
  del(key: string): void;
29
29
  sadd(key: string, value: any): void;
30
30
  smembers(key: string): Promise<string[]>;
31
- sismember(key: string, field: string): Promise<0 | 1>;
31
+ sismember(key: string, field: string): Promise<1 | 0>;
32
32
  srem(key: string, value: any): void;
33
33
  scard(key: string): number;
34
34
  sinter(...keys: string[]): Promise<any[]>;
@@ -45,7 +45,6 @@ var import_controller = require("../matchmaker/controller.cjs");
45
45
  var import_package = __toESM(require("../../package.json"), 1);
46
46
  var import_better_call2 = require("@colyseus/better-call");
47
47
  function bindRouterToServer(server, router) {
48
- const expressApp = server.listeners("request").find((listener) => listener.name === "app" && listener["mountpath"] === "/");
49
48
  router.addEndpoint((0, import_better_call.createEndpoint)("/__healthcheck", { method: "GET" }, async (ctx) => {
50
49
  return new Response("", { status: 200 });
51
50
  }));
@@ -55,11 +54,12 @@ function bindRouterToServer(server, router) {
55
54
  return new Response(`Colyseus ${import_package.default.version}`, { status: 200 });
56
55
  }));
57
56
  }
57
+ const expressApp = server.listeners("request").find((listener) => listener.name === "app" && listener["mountpath"] === "/");
58
+ let next = (0, import_node.toNodeHandler)(router.handler);
58
59
  if (expressApp) {
59
- expressApp.set("x-powered-by", false);
60
- expressApp.use((0, import_node.toNodeHandler)(router.handler));
61
- } else {
62
- server.on("request", (0, import_node.toNodeHandler)(router.handler));
60
+ server.removeListener("request", expressApp);
61
+ expressApp.use(next);
62
+ next = expressApp;
63
63
  }
64
64
  server.prependListener("request", (req, res) => {
65
65
  const corsHeaders = {
@@ -74,6 +74,7 @@ function bindRouterToServer(server, router) {
74
74
  Object.entries(corsHeaders).forEach(([key, value]) => {
75
75
  res.setHeader(key, value);
76
76
  });
77
+ next(req, res);
77
78
  });
78
79
  }
79
80
  var __globalEndpoints = {};
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/router/index.ts"],
4
- "sourcesContent": ["import type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler } from \"@colyseus/better-call/node\";\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 EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToServer(server: Server, router: Router) {\n // check if the server is bound to an express app\n const expressApp: any = server.listeners('request').find((listener: Function) =>\n listener.name === \"app\" && listener['mountpath'] === '/');\n\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"\", { status: 200 });\n }));\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\");\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n if (expressApp) {\n // turn off x-powered-by header - it is breaking the cors headers\n expressApp.set(\"x-powered-by\", false);\n\n // bind the router to the express app\n expressApp.use(toNodeHandler(router.handler));\n\n } else {\n // otherwise, bind the router to the http server\n server.on('request', 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}\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;AACA,yBAAsH;AACtH,kBAA8B;AAC9B,wBAA2B;AAC3B,qBAAgB;AAEhB,IAAAA,sBAYO;AAIA,SAAS,mBAAmB,QAAgB,QAAgB;AAEjE,QAAM,aAAkB,OAAO,UAAU,SAAS,EAAE,KAAK,CAAC,aACxD,SAAS,SAAS,SAAS,SAAS,WAAW,MAAM,GAAG;AAG1D,SAAO,gBAAY,mCAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzC,CAAC,CAAC;AAGF,QAAM,eAAe,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAC3F,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,MAAI,YAAY;AAEd,eAAW,IAAI,gBAAgB,KAAK;AAGpC,eAAW,QAAI,2BAAc,OAAO,OAAO,CAAC;AAAA,EAE9C,OAAO;AAEL,WAAO,GAAG,eAAW,2BAAc,OAAO,OAAO,CAAC;AAAA,EACpD;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;AAAA,EACH,CAAC;AACH;AAOO,IAAI,oBAA8C,CAAC;AAEnD,SAAS,aAGd,WAAc,SAAiB,CAAC,GAAa;AAE7C,sBAAoB;AAEpB,aAAO,mBAAAC,cAAuB,EAAE,GAAG,UAAU,GAAG,MAAM;AACxD;",
4
+ "sourcesContent": ["import type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler } from \"@colyseus/better-call/node\";\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 bindRouterToServer(server: Server, router: Router) {\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"\", { status: 200 });\n }));\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\");\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n // check if the server is bound to an express app\n const expressApp: any = server.listeners('request').find((listener: Function) =>\n listener.name === \"app\" && listener['mountpath'] === '/');\n\n // main router handler\n let next: Function = toNodeHandler(router.handler);\n\n if (expressApp) {\n server.removeListener('request', expressApp);\n\n // bind the router to the express app\n expressApp.use(next);\n\n // use the express app as the next function\n next = expressApp;\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\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;AACA,yBAAsH;AACtH,kBAA8B;AAC9B,wBAA2B;AAC3B,qBAAgB;AAEhB,IAAAA,sBAaO;AAIA,SAAS,mBAAmB,QAAgB,QAAgB;AAEjE,SAAO,gBAAY,mCAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzC,CAAC,CAAC;AAGF,QAAM,eAAe,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAC3F,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;AAGA,QAAM,aAAkB,OAAO,UAAU,SAAS,EAAE,KAAK,CAAC,aACxD,SAAS,SAAS,SAAS,SAAS,WAAW,MAAM,GAAG;AAG1D,MAAI,WAAiB,2BAAc,OAAO,OAAO;AAEjD,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;AAG3C,eAAW,IAAI,IAAI;AAGnB,WAAO;AAAA,EACT;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;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
  }
@@ -1,7 +1,7 @@
1
1
  import type { Server } from "http";
2
2
  import { type Endpoint, type Router, type RouterConfig } from "@colyseus/better-call";
3
3
  import { toNodeHandler } from "@colyseus/better-call/node";
4
- export { createEndpoint, createMiddleware, createInternalContext, type Router, type RouterConfig, type Endpoint, type EndpointOptions, type EndpointContext, type StrictEndpoint, } from "@colyseus/better-call";
4
+ export { createEndpoint, createMiddleware, createInternalContext, type Router, type RouterConfig, type Endpoint, type EndpointHandler, type EndpointOptions, type EndpointContext, type StrictEndpoint, } from "@colyseus/better-call";
5
5
  export { toNodeHandler };
6
6
  export declare function bindRouterToServer(server: Server, router: Router): void;
7
7
  /**
@@ -9,7 +9,6 @@ import {
9
9
  createInternalContext
10
10
  } from "@colyseus/better-call";
11
11
  function bindRouterToServer(server, router) {
12
- const expressApp = server.listeners("request").find((listener) => listener.name === "app" && listener["mountpath"] === "/");
13
12
  router.addEndpoint(createEndpoint("/__healthcheck", { method: "GET" }, async (ctx) => {
14
13
  return new Response("", { status: 200 });
15
14
  }));
@@ -19,11 +18,12 @@ function bindRouterToServer(server, router) {
19
18
  return new Response(`Colyseus ${pkg.version}`, { status: 200 });
20
19
  }));
21
20
  }
21
+ const expressApp = server.listeners("request").find((listener) => listener.name === "app" && listener["mountpath"] === "/");
22
+ let next = toNodeHandler(router.handler);
22
23
  if (expressApp) {
23
- expressApp.set("x-powered-by", false);
24
- expressApp.use(toNodeHandler(router.handler));
25
- } else {
26
- server.on("request", toNodeHandler(router.handler));
24
+ server.removeListener("request", expressApp);
25
+ expressApp.use(next);
26
+ next = expressApp;
27
27
  }
28
28
  server.prependListener("request", (req, res) => {
29
29
  const corsHeaders = {
@@ -38,6 +38,7 @@ function bindRouterToServer(server, router) {
38
38
  Object.entries(corsHeaders).forEach(([key, value]) => {
39
39
  res.setHeader(key, value);
40
40
  });
41
+ next(req, res);
41
42
  });
42
43
  }
43
44
  var __globalEndpoints = {};
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/router/index.ts"],
4
- "sourcesContent": ["import type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler } from \"@colyseus/better-call/node\";\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 EndpointOptions,\n type EndpointContext,\n type StrictEndpoint,\n} from \"@colyseus/better-call\";\n\nexport { toNodeHandler };\n\nexport function bindRouterToServer(server: Server, router: Router) {\n // check if the server is bound to an express app\n const expressApp: any = server.listeners('request').find((listener: Function) =>\n listener.name === \"app\" && listener['mountpath'] === '/');\n\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"\", { status: 200 });\n }));\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\");\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n if (expressApp) {\n // turn off x-powered-by header - it is breaking the cors headers\n expressApp.set(\"x-powered-by\", false);\n\n // bind the router to the express app\n expressApp.use(toNodeHandler(router.handler));\n\n } else {\n // otherwise, bind the router to the http server\n server.on('request', 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}\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": ";AACA,SAAwD,gBAAgB,wBAAwB,sBAAsB;AACtH,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,SAAS,qBAAqB,KAAK,EAAE,MAAM,OAAO;AAEzD;AAAA,EACE,kBAAAA;AAAA,EACA;AAAA,EACA;AAAA,OASK;AAIA,SAAS,mBAAmB,QAAgB,QAAgB;AAEjE,QAAM,aAAkB,OAAO,UAAU,SAAS,EAAE,KAAK,CAAC,aACxD,SAAS,SAAS,SAAS,SAAS,WAAW,MAAM,GAAG;AAG1D,SAAO,YAAY,eAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzC,CAAC,CAAC;AAGF,QAAM,eAAe,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAC3F,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,MAAI,YAAY;AAEd,eAAW,IAAI,gBAAgB,KAAK;AAGpC,eAAW,IAAI,cAAc,OAAO,OAAO,CAAC;AAAA,EAE9C,OAAO;AAEL,WAAO,GAAG,WAAW,cAAc,OAAO,OAAO,CAAC;AAAA,EACpD;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;AAAA,EACH,CAAC;AACH;AAOO,IAAI,oBAA8C,CAAC;AAEnD,SAAS,aAGd,WAAc,SAAiB,CAAC,GAAa;AAE7C,sBAAoB;AAEpB,SAAO,uBAAuB,EAAE,GAAG,UAAU,GAAG,MAAM;AACxD;",
4
+ "sourcesContent": ["import type { IncomingMessage, Server, ServerResponse } from \"http\";\nimport { type Endpoint, type Router, type RouterConfig, createRouter as createBetterCallRouter, createEndpoint } from \"@colyseus/better-call\";\nimport { toNodeHandler } from \"@colyseus/better-call/node\";\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 bindRouterToServer(server: Server, router: Router) {\n // add default \"/__healthcheck\" endpoint\n router.addEndpoint(createEndpoint(\"/__healthcheck\", { method: \"GET\" }, async (ctx) => {\n return new Response(\"\", { status: 200 });\n }));\n\n // add default \"/\" route, if not provided.\n const hasRootRoute = Object.values(router.endpoints).some(endpoint => endpoint.path === \"/\");\n if (!hasRootRoute) {\n router.addEndpoint(createEndpoint(\"/\", { method: \"GET\" }, async (ctx) => {\n return new Response(`Colyseus ${pkg.version}`, { status: 200 });\n }));\n }\n\n // check if the server is bound to an express app\n const expressApp: any = server.listeners('request').find((listener: Function) =>\n listener.name === \"app\" && listener['mountpath'] === '/');\n\n // main router handler\n let next: Function = toNodeHandler(router.handler);\n\n if (expressApp) {\n server.removeListener('request', expressApp);\n\n // bind the router to the express app\n expressApp.use(next);\n\n // use the express app as the next function\n next = expressApp;\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\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": ";AACA,SAAwD,gBAAgB,wBAAwB,sBAAsB;AACtH,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,SAAS,qBAAqB,KAAK,EAAE,MAAM,OAAO;AAEzD;AAAA,EACE,kBAAAA;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AAIA,SAAS,mBAAmB,QAAgB,QAAgB;AAEjE,SAAO,YAAY,eAAe,kBAAkB,EAAE,QAAQ,MAAM,GAAG,OAAO,QAAQ;AACpF,WAAO,IAAI,SAAS,IAAI,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzC,CAAC,CAAC;AAGF,QAAM,eAAe,OAAO,OAAO,OAAO,SAAS,EAAE,KAAK,cAAY,SAAS,SAAS,GAAG;AAC3F,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;AAGA,QAAM,aAAkB,OAAO,UAAU,SAAS,EAAE,KAAK,CAAC,aACxD,SAAS,SAAS,SAAS,SAAS,WAAW,MAAM,GAAG;AAG1D,MAAI,OAAiB,cAAc,OAAO,OAAO;AAEjD,MAAI,YAAY;AACd,WAAO,eAAe,WAAW,UAAU;AAG3C,eAAW,IAAI,IAAI;AAGnB,WAAO;AAAA,EACT;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;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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colyseus/core",
3
- "version": "0.17.15",
3
+ "version": "0.17.17",
4
4
  "description": "Multiplayer Framework for Node.js.",
5
5
  "type": "module",
6
6
  "input": "./src/index.ts",
@@ -51,20 +51,21 @@
51
51
  "@standard-schema/spec": "^1.0.0",
52
52
  "debug": "^4.3.4",
53
53
  "nanoid": "^3.3.11",
54
- "@colyseus/shared-types": "^0.17.1",
55
- "@colyseus/greeting-banner": "^3.0.6",
56
- "@colyseus/better-call": "^1.0.27"
54
+ "@colyseus/shared-types": "^0.17.2",
55
+ "@colyseus/better-call": "^1.2.0",
56
+ "@colyseus/greeting-banner": "^3.0.6"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@colyseus/schema": "^4.0.4",
60
- "@colyseus/redis-presence": "^0.17.5",
61
60
  "@colyseus/redis-driver": "^0.17.5",
62
- "@colyseus/tools": "^0.17.9"
61
+ "@colyseus/tools": "^0.17.13",
62
+ "@colyseus/redis-presence": "^0.17.5"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "@colyseus/schema": "^4.0.4",
66
66
  "@pm2/io": "^6.1.0",
67
- "zod": "^4.1.12"
67
+ "zod": "^4.1.12",
68
+ "@colyseus/better-call": "^1.2.0"
68
69
  },
69
70
  "optionalPeerDependencies": {
70
71
  "@colyseus/tools": "0.17.x",
package/src/MatchMaker.ts CHANGED
@@ -251,7 +251,7 @@ export async function reconnect(roomId: string, clientOptions: ClientOptions = {
251
251
  if (!room) {
252
252
  // TODO: support a "logLevel" out of the box?
253
253
  if (process.env.NODE_ENV !== 'production') {
254
- logger.info(`āŒ room "${roomId}" has been disposed. Did you miss .allowReconnection()?\nšŸ‘‰ https://docs.colyseus.io/server/room#allow-reconnection`);
254
+ logger.info(`āŒ room "${roomId}" has been disposed. Did you miss .allowReconnection()?\nšŸ‘‰ https://docs.colyseus.io/room#allow-reconnection`);
255
255
  }
256
256
 
257
257
  throw new ServerError(ErrorCode.MATCHMAKE_INVALID_ROOM_ID, `room "${roomId}" has been disposed.`);
@@ -269,7 +269,7 @@ export async function reconnect(roomId: string, clientOptions: ClientOptions = {
269
269
  } else {
270
270
  // TODO: support a "logLevel" out of the box?
271
271
  if (process.env.NODE_ENV !== 'production') {
272
- logger.info(`āŒ reconnection token invalid or expired. Did you miss .allowReconnection()?\nšŸ‘‰ https://docs.colyseus.io/server/room#allow-reconnection`);
272
+ logger.info(`āŒ reconnection token invalid or expired. Did you miss .allowReconnection()?\nšŸ‘‰ https://docs.colyseus.io/room#allow-reconnection`);
273
273
  }
274
274
  throw new ServerError(ErrorCode.MATCHMAKE_EXPIRED, `reconnection token invalid or expired.`);
275
275
  }
package/src/Room.ts CHANGED
@@ -456,8 +456,9 @@ export class Room<T extends RoomOptions = RoomOptions> {
456
456
  * This method is called when a client joins the room.
457
457
  * @param client - The client that joined the room.
458
458
  * @param options - The options passed to the client when it joined the room.
459
+ * @param auth - The data returned by the `onAuth` method - (Deprecated: use `client.auth` instead)
459
460
  */
460
- public onJoin?(client: ExtractRoomClient<T>, options?: any): void | Promise<any>;
461
+ public onJoin?(client: ExtractRoomClient<T>, options?: any, auth?: any): void | Promise<any>;
461
462
 
462
463
  /**
463
464
  * This method is called when a client leaves the room without consent.
@@ -1217,7 +1218,8 @@ export class Room<T extends RoomOptions = RoomOptions> {
1217
1218
  });
1218
1219
 
1219
1220
  if (this.onJoin) {
1220
- await this.onJoin(client, joinOptions);
1221
+ // TODO: deprecate auth as 3rd argument on Colyseus 1.0
1222
+ await this.onJoin(client, joinOptions, client.auth);
1221
1223
  }
1222
1224
 
1223
1225
  // @ts-ignore: client left during `onJoin`, call _onLeave immediately.
package/src/Server.ts CHANGED
@@ -113,7 +113,6 @@ export class Server<
113
113
 
114
114
  public attach(options: ServerOptions) {
115
115
  this.transport = options.transport || this.getDefaultTransport(options);
116
- delete options.transport;
117
116
  }
118
117
 
119
118
  /**
package/src/index.ts CHANGED
@@ -86,6 +86,7 @@ export {
86
86
  type Router,
87
87
  type RouterConfig,
88
88
  type Endpoint,
89
+ type EndpointHandler,
89
90
  type EndpointOptions,
90
91
  type EndpointContext,
91
92
  type StrictEndpoint,
@@ -11,7 +11,7 @@ import type { AuthContext } from '../Transport.ts';
11
11
  export const controller = {
12
12
  DEFAULT_CORS_HEADERS: {
13
13
  'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
14
- 'Access-Control-Allow-Methods': 'OPTIONS, POST, GET',
14
+ 'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
15
15
  'Access-Control-Allow-Credentials': 'true',
16
16
  'Access-Control-Allow-Origin': '*',
17
17
  'Access-Control-Max-Age': '2592000',
@@ -13,6 +13,7 @@ export {
13
13
  type Router,
14
14
  type RouterConfig,
15
15
  type Endpoint,
16
+ type EndpointHandler,
16
17
  type EndpointOptions,
17
18
  type EndpointContext,
18
19
  type StrictEndpoint,
@@ -21,10 +22,6 @@ export {
21
22
  export { toNodeHandler };
22
23
 
23
24
  export function bindRouterToServer(server: Server, router: Router) {
24
- // check if the server is bound to an express app
25
- const expressApp: any = server.listeners('request').find((listener: Function) =>
26
- listener.name === "app" && listener['mountpath'] === '/');
27
-
28
25
  // add default "/__healthcheck" endpoint
29
26
  router.addEndpoint(createEndpoint("/__healthcheck", { method: "GET" }, async (ctx) => {
30
27
  return new Response("", { status: 200 });
@@ -38,16 +35,21 @@ export function bindRouterToServer(server: Server, router: Router) {
38
35
  }));
39
36
  }
40
37
 
38
+ // check if the server is bound to an express app
39
+ const expressApp: any = server.listeners('request').find((listener: Function) =>
40
+ listener.name === "app" && listener['mountpath'] === '/');
41
+
42
+ // main router handler
43
+ let next: Function = toNodeHandler(router.handler);
44
+
41
45
  if (expressApp) {
42
- // turn off x-powered-by header - it is breaking the cors headers
43
- expressApp.set("x-powered-by", false);
46
+ server.removeListener('request', expressApp);
44
47
 
45
48
  // bind the router to the express app
46
- expressApp.use(toNodeHandler(router.handler));
49
+ expressApp.use(next);
47
50
 
48
- } else {
49
- // otherwise, bind the router to the http server
50
- server.on('request', toNodeHandler(router.handler));
51
+ // use the express app as the next function
52
+ next = expressApp;
51
53
  }
52
54
 
53
55
  // handle cors headers for all requests by default
@@ -55,7 +57,7 @@ export function bindRouterToServer(server: Server, router: Router) {
55
57
  const corsHeaders = {
56
58
  ...controller.DEFAULT_CORS_HEADERS,
57
59
  ...controller.getCorsHeaders(new Headers(req.headers as any)),
58
- }
60
+ };
59
61
 
60
62
  if (req.method === "OPTIONS") {
61
63
  res.writeHead(204, corsHeaders);
@@ -66,6 +68,8 @@ export function bindRouterToServer(server: Server, router: Router) {
66
68
  Object.entries(corsHeaders).forEach(([key, value]) => {
67
69
  res.setHeader(key, value);
68
70
  });
71
+
72
+ next(req, res);
69
73
  });
70
74
  }
71
75