{"mappings":"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","sources":["src/index.ts","src/config/index.ts","src/instance.ts","src/models/realm.ts","src/models/messageQueue.ts","src/services/checkBrokenConnections/index.ts","src/services/messagesExpire/index.ts","src/enums.ts","src/services/webSocketServer/index.ts","src/models/client.ts","src/messageHandler/index.ts","src/messageHandler/handlers/index.ts","src/messageHandler/handlers/heartbeat/index.ts","src/messageHandler/handlers/transmission/index.ts","src/messageHandler/handlersRegistry.ts","src/api/index.ts","app.json","src/api/v1/public/index.ts"],"sourcesContent":["import express, { type Express } from \"express\";\nimport http from \"node:http\";\nimport https from \"node:https\";\n\nimport type { IConfig } from \"./config/index.ts\";\nimport defaultConfig from \"./config/index.ts\";\nimport type { PeerServerEvents } from \"./instance.ts\";\nimport { createInstance } from \"./instance.ts\";\nimport type { IClient } from \"./models/client.ts\";\nimport type { IMessage } from \"./models/message.ts\";\n\nexport type { MessageType } from \"./enums.ts\";\nexport type { IConfig, PeerServerEvents, IClient, IMessage };\n\nfunction ExpressPeerServer(\n\tserver: https.Server | http.Server,\n\toptions?: Partial<IConfig>,\n) {\n\tconst app = express();\n\n\tconst newOptions: IConfig = {\n\t\t...defaultConfig,\n\t\t...options,\n\t};\n\n\tif (newOptions.proxied) {\n\t\tapp.set(\n\t\t\t\"trust proxy\",\n\t\t\tnewOptions.proxied === \"false\" ? false : !!newOptions.proxied,\n\t\t);\n\t}\n\n\tapp.on(\"mount\", () => {\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tif (!server) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Server is not passed to constructor - \" + \"can't start PeerServer\",\n\t\t\t);\n\t\t}\n\n\t\tcreateInstance({ app, server, options: newOptions });\n\t});\n\n\treturn app as Express & PeerServerEvents;\n}\n\nfunction PeerServer(\n\toptions: Partial<IConfig> = {},\n\tcallback?: (server: https.Server | http.Server) => void,\n) {\n\tconst app = express();\n\n\tlet newOptions: IConfig = {\n\t\t...defaultConfig,\n\t\t...options,\n\t};\n\n\tconst port = newOptions.port;\n\tconst host = newOptions.host;\n\n\tlet server: https.Server | http.Server;\n\n\tconst { ssl, ...restOptions } = newOptions;\n\tif (ssl && Object.keys(ssl).length) {\n\t\tserver = https.createServer(ssl, app);\n\n\t\tnewOptions = restOptions;\n\t} else {\n\t\tserver = http.createServer(app);\n\t}\n\n\tconst peerjs = ExpressPeerServer(server, newOptions);\n\tapp.use(peerjs);\n\n\tserver.listen(port, host, () => callback?.(server));\n\n\treturn peerjs;\n}\n\nexport { ExpressPeerServer, PeerServer };\n","import type { WebSocketServer, ServerOptions } from \"ws\";\nimport type { CorsOptions } from \"cors\";\n\nexport interface IConfig {\n\treadonly host: string;\n\treadonly port: number;\n\treadonly expire_timeout: number;\n\treadonly alive_timeout: number;\n\treadonly key: string;\n\treadonly path: string;\n\treadonly concurrent_limit: number;\n\treadonly allow_discovery: boolean;\n\treadonly proxied: boolean | string;\n\treadonly cleanup_out_msgs: number;\n\treadonly ssl?: {\n\t\tkey: string;\n\t\tcert: string;\n\t};\n\treadonly generateClientId?: () => string;\n\treadonly createWebSocketServer?: (options: ServerOptions) => WebSocketServer;\n\treadonly corsOptions: CorsOptions;\n}\n\nconst defaultConfig: IConfig = {\n\thost: \"::\",\n\tport: 9000,\n\texpire_timeout: 5000,\n\talive_timeout: 90000,\n\tkey: \"peerjs\",\n\tpath: \"/\",\n\tconcurrent_limit: 5000,\n\tallow_discovery: false,\n\tproxied: false,\n\tcleanup_out_msgs: 1000,\n\tcorsOptions: { origin: true },\n};\n\nexport default defaultConfig;\n","import type express from \"express\";\nimport type { Server as HttpServer } from \"node:http\";\nimport type { Server as HttpsServer } from \"node:https\";\nimport path from \"node:path\";\nimport type { IRealm } from \"./models/realm.ts\";\nimport { Realm } from \"./models/realm.ts\";\nimport { CheckBrokenConnections } from \"./services/checkBrokenConnections/index.ts\";\nimport type { IMessagesExpire } from \"./services/messagesExpire/index.ts\";\nimport { MessagesExpire } from \"./services/messagesExpire/index.ts\";\nimport type { IWebSocketServer } from \"./services/webSocketServer/index.ts\";\nimport { WebSocketServer } from \"./services/webSocketServer/index.ts\";\nimport { MessageHandler } from \"./messageHandler/index.ts\";\nimport { Api } from \"./api/index.ts\";\nimport type { IClient } from \"./models/client.ts\";\nimport type { IMessage } from \"./models/message.ts\";\nimport type { IConfig } from \"./config/index.ts\";\n\nexport interface PeerServerEvents {\n\ton(event: \"connection\", listener: (client: IClient) => void): this;\n\ton(\n\t\tevent: \"message\",\n\t\tlistener: (client: IClient, message: IMessage) => void,\n\t): this;\n\t// eslint-disable-next-line @typescript-eslint/unified-signatures\n\ton(event: \"disconnect\", listener: (client: IClient) => void): this;\n\ton(event: \"error\", listener: (client: Error) => void): this;\n}\n\nexport const createInstance = ({\n\tapp,\n\tserver,\n\toptions,\n}: {\n\tapp: express.Application;\n\tserver: HttpServer | HttpsServer;\n\toptions: IConfig;\n}): void => {\n\tconst config = options;\n\tconst realm: IRealm = new Realm();\n\tconst messageHandler = new MessageHandler(realm);\n\n\tconst api = Api({ config, realm, corsOptions: options.corsOptions });\n\tconst messagesExpire: IMessagesExpire = new MessagesExpire({\n\t\trealm,\n\t\tconfig,\n\t\tmessageHandler,\n\t});\n\tconst checkBrokenConnections = new CheckBrokenConnections({\n\t\trealm,\n\t\tconfig,\n\t\tonClose: (client) => {\n\t\t\tapp.emit(\"disconnect\", client);\n\t\t},\n\t});\n\n\tapp.use(options.path, api);\n\n\t//use mountpath for WS server\n\tconst customConfig = {\n\t\t...config,\n\t\tpath: path.posix.join(app.path(), options.path, \"/\"),\n\t};\n\n\tconst wss: IWebSocketServer = new WebSocketServer({\n\t\tserver,\n\t\trealm,\n\t\tconfig: customConfig,\n\t});\n\n\twss.on(\"connection\", (client: IClient) => {\n\t\tconst messageQueue = realm.getMessageQueueById(client.getId());\n\n\t\tif (messageQueue) {\n\t\t\tlet message: IMessage | undefined;\n\n\t\t\twhile ((message = messageQueue.readMessage())) {\n\t\t\t\tmessageHandler.handle(client, message);\n\t\t\t}\n\t\t\trealm.clearMessageQueue(client.getId());\n\t\t}\n\n\t\tapp.emit(\"connection\", client);\n\t});\n\n\twss.on(\"message\", (client: IClient, message: IMessage) => {\n\t\tapp.emit(\"message\", client, message);\n\t\tmessageHandler.handle(client, message);\n\t});\n\n\twss.on(\"close\", (client: IClient) => {\n\t\tapp.emit(\"disconnect\", client);\n\t});\n\n\twss.on(\"error\", (error: Error) => {\n\t\tapp.emit(\"error\", error);\n\t});\n\n\tmessagesExpire.startMessagesExpiration();\n\tcheckBrokenConnections.start();\n};\n","import type { IMessageQueue } from \"./messageQueue.ts\";\nimport { MessageQueue } from \"./messageQueue.ts\";\nimport { randomUUID } from \"node:crypto\";\nimport type { IClient } from \"./client.ts\";\nimport type { IMessage } from \"./message.ts\";\n\nexport interface IRealm {\n\tgetClientsIds(): string[];\n\n\tgetClientById(clientId: string): IClient | undefined;\n\n\tgetClientsIdsWithQueue(): string[];\n\n\tsetClient(client: IClient, id: string): void;\n\n\tremoveClientById(id: string): boolean;\n\n\tgetMessageQueueById(id: string): IMessageQueue | undefined;\n\n\taddMessageToQueue(id: string, message: IMessage): void;\n\n\tclearMessageQueue(id: string): void;\n\n\tgenerateClientId(generateClientId?: () => string): string;\n}\n\nexport class Realm implements IRealm {\n\tprivate readonly clients = new Map<string, IClient>();\n\tprivate readonly messageQueues = new Map<string, IMessageQueue>();\n\n\tpublic getClientsIds(): string[] {\n\t\treturn [...this.clients.keys()];\n\t}\n\n\tpublic getClientById(clientId: string): IClient | undefined {\n\t\treturn this.clients.get(clientId);\n\t}\n\n\tpublic getClientsIdsWithQueue(): string[] {\n\t\treturn [...this.messageQueues.keys()];\n\t}\n\n\tpublic setClient(client: IClient, id: string): void {\n\t\tthis.clients.set(id, client);\n\t}\n\n\tpublic removeClientById(id: string): boolean {\n\t\tconst client = this.getClientById(id);\n\n\t\tif (!client) return false;\n\n\t\tthis.clients.delete(id);\n\n\t\treturn true;\n\t}\n\n\tpublic getMessageQueueById(id: string): IMessageQueue | undefined {\n\t\treturn this.messageQueues.get(id);\n\t}\n\n\tpublic addMessageToQueue(id: string, message: IMessage): void {\n\t\tif (!this.getMessageQueueById(id)) {\n\t\t\tthis.messageQueues.set(id, new MessageQueue());\n\t\t}\n\n\t\tthis.getMessageQueueById(id)?.addMessage(message);\n\t}\n\n\tpublic clearMessageQueue(id: string): void {\n\t\tthis.messageQueues.delete(id);\n\t}\n\n\tpublic generateClientId(generateClientId?: () => string): string {\n\t\tconst generateId = generateClientId ? generateClientId : randomUUID;\n\n\t\tlet clientId = generateId();\n\n\t\twhile (this.getClientById(clientId)) {\n\t\t\tclientId = generateId();\n\t\t}\n\n\t\treturn clientId;\n\t}\n}\n","import type { IMessage } from \"./message.ts\";\n\nexport interface IMessageQueue {\n\tgetLastReadAt(): number;\n\n\taddMessage(message: IMessage): void;\n\n\treadMessage(): IMessage | undefined;\n\n\tgetMessages(): IMessage[];\n}\n\nexport class MessageQueue implements IMessageQueue {\n\tprivate lastReadAt: number = new Date().getTime();\n\tprivate readonly messages: IMessage[] = [];\n\n\tpublic getLastReadAt(): number {\n\t\treturn this.lastReadAt;\n\t}\n\n\tpublic addMessage(message: IMessage): void {\n\t\tthis.messages.push(message);\n\t}\n\n\tpublic readMessage(): IMessage | undefined {\n\t\tif (this.messages.length > 0) {\n\t\t\tthis.lastReadAt = new Date().getTime();\n\t\t\treturn this.messages.shift();\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\tpublic getMessages(): IMessage[] {\n\t\treturn this.messages;\n\t}\n}\n","import type { IConfig } from \"../../config/index.ts\";\nimport type { IClient } from \"../../models/client.ts\";\nimport type { IRealm } from \"../../models/realm.ts\";\n\nconst DEFAULT_CHECK_INTERVAL = 300;\n\ntype CustomConfig = Pick<IConfig, \"alive_timeout\">;\n\nexport class CheckBrokenConnections {\n\tpublic readonly checkInterval: number;\n\tprivate timeoutId: NodeJS.Timeout | null = null;\n\tprivate readonly realm: IRealm;\n\tprivate readonly config: CustomConfig;\n\tprivate readonly onClose?: (client: IClient) => void;\n\n\tconstructor({\n\t\trealm,\n\t\tconfig,\n\t\tcheckInterval = DEFAULT_CHECK_INTERVAL,\n\t\tonClose,\n\t}: {\n\t\trealm: IRealm;\n\t\tconfig: CustomConfig;\n\t\tcheckInterval?: number;\n\t\tonClose?: (client: IClient) => void;\n\t}) {\n\t\tthis.realm = realm;\n\t\tthis.config = config;\n\t\tthis.onClose = onClose;\n\t\tthis.checkInterval = checkInterval;\n\t}\n\n\tpublic start(): void {\n\t\tif (this.timeoutId) {\n\t\t\tclearTimeout(this.timeoutId);\n\t\t}\n\n\t\tthis.timeoutId = setTimeout(() => {\n\t\t\tthis.checkConnections();\n\n\t\t\tthis.timeoutId = null;\n\n\t\t\tthis.start();\n\t\t}, this.checkInterval);\n\t}\n\n\tpublic stop(): void {\n\t\tif (this.timeoutId) {\n\t\t\tclearTimeout(this.timeoutId);\n\t\t\tthis.timeoutId = null;\n\t\t}\n\t}\n\n\tprivate checkConnections(): void {\n\t\tconst clientsIds = this.realm.getClientsIds();\n\n\t\tconst now = new Date().getTime();\n\t\tconst { alive_timeout: aliveTimeout } = this.config;\n\n\t\tfor (const clientId of clientsIds) {\n\t\t\tconst client = this.realm.getClientById(clientId);\n\n\t\t\tif (!client) continue;\n\n\t\t\tconst timeSinceLastPing = now - client.getLastPing();\n\n\t\t\tif (timeSinceLastPing < aliveTimeout) continue;\n\n\t\t\ttry {\n\t\t\t\tclient.getSocket()?.close();\n\t\t\t} finally {\n\t\t\t\tthis.realm.clearMessageQueue(clientId);\n\t\t\t\tthis.realm.removeClientById(clientId);\n\n\t\t\t\tclient.setSocket(null);\n\n\t\t\t\tthis.onClose?.(client);\n\t\t\t}\n\t\t}\n\t}\n}\n","import { MessageType } from \"../../enums.ts\";\nimport type { IConfig } from \"../../config/index.ts\";\nimport type { IMessageHandler } from \"../../messageHandler/index.ts\";\nimport type { IRealm } from \"../../models/realm.ts\";\n\nexport interface IMessagesExpire {\n\tstartMessagesExpiration(): void;\n\tstopMessagesExpiration(): void;\n}\n\ntype CustomConfig = Pick<IConfig, \"cleanup_out_msgs\" | \"expire_timeout\">;\n\nexport class MessagesExpire implements IMessagesExpire {\n\tprivate readonly realm: IRealm;\n\tprivate readonly config: CustomConfig;\n\tprivate readonly messageHandler: IMessageHandler;\n\n\tprivate timeoutId: NodeJS.Timeout | null = null;\n\n\tconstructor({\n\t\trealm,\n\t\tconfig,\n\t\tmessageHandler,\n\t}: {\n\t\trealm: IRealm;\n\t\tconfig: CustomConfig;\n\t\tmessageHandler: IMessageHandler;\n\t}) {\n\t\tthis.realm = realm;\n\t\tthis.config = config;\n\t\tthis.messageHandler = messageHandler;\n\t}\n\n\tpublic startMessagesExpiration(): void {\n\t\tif (this.timeoutId) {\n\t\t\tclearTimeout(this.timeoutId);\n\t\t}\n\n\t\t// Clean up outstanding messages\n\t\tthis.timeoutId = setTimeout(() => {\n\t\t\tthis.pruneOutstanding();\n\n\t\t\tthis.timeoutId = null;\n\n\t\t\tthis.startMessagesExpiration();\n\t\t}, this.config.cleanup_out_msgs);\n\t}\n\n\tpublic stopMessagesExpiration(): void {\n\t\tif (this.timeoutId) {\n\t\t\tclearTimeout(this.timeoutId);\n\t\t\tthis.timeoutId = null;\n\t\t}\n\t}\n\n\tprivate pruneOutstanding(): void {\n\t\tconst destinationClientsIds = this.realm.getClientsIdsWithQueue();\n\n\t\tconst now = new Date().getTime();\n\t\tconst maxDiff = this.config.expire_timeout;\n\n\t\tconst seen: Record<string, boolean> = {};\n\n\t\tfor (const destinationClientId of destinationClientsIds) {\n\t\t\tconst messageQueue = this.realm.getMessageQueueById(destinationClientId);\n\n\t\t\tif (!messageQueue) continue;\n\n\t\t\tconst lastReadDiff = now - messageQueue.getLastReadAt();\n\n\t\t\tif (lastReadDiff < maxDiff) continue;\n\n\t\t\tconst messages = messageQueue.getMessages();\n\n\t\t\tfor (const message of messages) {\n\t\t\t\tconst seenKey = `${message.src}_${message.dst}`;\n\n\t\t\t\tif (!seen[seenKey]) {\n\t\t\t\t\tthis.messageHandler.handle(undefined, {\n\t\t\t\t\t\ttype: MessageType.EXPIRE,\n\t\t\t\t\t\tsrc: message.dst,\n\t\t\t\t\t\tdst: message.src,\n\t\t\t\t\t});\n\n\t\t\t\t\tseen[seenKey] = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.realm.clearMessageQueue(destinationClientId);\n\t\t}\n\t}\n}\n","export enum Errors {\n\tINVALID_KEY = \"Invalid key provided\",\n\tINVALID_TOKEN = \"Invalid token provided\",\n\tINVALID_WS_PARAMETERS = \"No id, token, or key supplied to websocket server\",\n\tCONNECTION_LIMIT_EXCEED = \"Server has reached its concurrent user limit\",\n}\n\nexport enum MessageType {\n\tOPEN = \"OPEN\",\n\tLEAVE = \"LEAVE\",\n\tCANDIDATE = \"CANDIDATE\",\n\tOFFER = \"OFFER\",\n\tANSWER = \"ANSWER\",\n\tEXPIRE = \"EXPIRE\",\n\tHEARTBEAT = \"HEARTBEAT\",\n\tID_TAKEN = \"ID-TAKEN\",\n\tERROR = \"ERROR\",\n}\n","import { EventEmitter } from \"node:events\";\nimport type { IncomingMessage } from \"node:http\";\nimport type WebSocket from \"ws\";\nimport { Errors, MessageType } from \"../../enums.ts\";\nimport type { IClient } from \"../../models/client.ts\";\nimport { Client } from \"../../models/client.ts\";\nimport type { IConfig } from \"../../config/index.ts\";\nimport type { IRealm } from \"../../models/realm.ts\";\nimport { WebSocketServer as Server } from \"ws\";\nimport type { Server as HttpServer } from \"node:http\";\nimport type { Server as HttpsServer } from \"node:https\";\nimport { IMessage } from \"../../models/message.js\";\n\nexport interface IWebSocketServer extends EventEmitter {\n\treadonly path: string;\n}\n\ntype CustomConfig = Pick<\n\tIConfig,\n\t\"path\" | \"key\" | \"concurrent_limit\" | \"createWebSocketServer\"\n>;\n\nconst WS_PATH = \"peerjs\";\n\nexport class WebSocketServer extends EventEmitter implements IWebSocketServer {\n\tpublic readonly path: string;\n\tprivate readonly realm: IRealm;\n\tprivate readonly config: CustomConfig;\n\tpublic readonly socketServer: Server;\n\n\tconstructor({\n\t\tserver,\n\t\trealm,\n\t\tconfig,\n\t}: {\n\t\tserver: HttpServer | HttpsServer;\n\t\trealm: IRealm;\n\t\tconfig: CustomConfig;\n\t}) {\n\t\tsuper();\n\n\t\tthis.setMaxListeners(0);\n\n\t\tthis.realm = realm;\n\t\tthis.config = config;\n\n\t\tconst path = this.config.path;\n\t\tthis.path = `${path}${path.endsWith(\"/\") ? \"\" : \"/\"}${WS_PATH}`;\n\n\t\tconst options: WebSocket.ServerOptions = {\n\t\t\tpath: this.path,\n\t\t\tserver,\n\t\t};\n\n\t\tthis.socketServer = config.createWebSocketServer\n\t\t\t? config.createWebSocketServer(options)\n\t\t\t: new Server(options);\n\n\t\tthis.socketServer.on(\"connection\", (socket, req) => {\n\t\t\tthis._onSocketConnection(socket, req);\n\t\t});\n\t\tthis.socketServer.on(\"error\", (error: Error) => {\n\t\t\tthis._onSocketError(error);\n\t\t});\n\t}\n\n\tprivate _onSocketConnection(socket: WebSocket, req: IncomingMessage): void {\n\t\t// An unhandled socket error might crash the server. Handle it first.\n\t\tsocket.on(\"error\", (error) => {\n\t\t\tthis._onSocketError(error);\n\t\t});\n\n\t\t// We are only interested in the query, the base url is therefore not relevant\n\t\tconst { searchParams } = new URL(req.url ?? \"\", \"https://peerjs\");\n\t\tconst { id, token, key } = Object.fromEntries(searchParams.entries());\n\n\t\tif (!id || !token || !key) {\n\t\t\tthis._sendErrorAndClose(socket, Errors.INVALID_WS_PARAMETERS);\n\t\t\treturn;\n\t\t}\n\n\t\tif (key !== this.config.key) {\n\t\t\tthis._sendErrorAndClose(socket, Errors.INVALID_KEY);\n\t\t\treturn;\n\t\t}\n\n\t\tconst client = this.realm.getClientById(id);\n\n\t\tif (client) {\n\t\t\tif (token !== client.getToken()) {\n\t\t\t\t// ID-taken, invalid token\n\t\t\t\tsocket.send(\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\ttype: MessageType.ID_TAKEN,\n\t\t\t\t\t\tpayload: { msg: \"ID is taken\" },\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\tsocket.close();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._configureWS(socket, client);\n\t\t\treturn;\n\t\t}\n\n\t\tthis._registerClient({ socket, id, token });\n\t}\n\n\tprivate _onSocketError(error: Error): void {\n\t\t// handle error\n\t\tthis.emit(\"error\", error);\n\t}\n\n\tprivate _registerClient({\n\t\tsocket,\n\t\tid,\n\t\ttoken,\n\t}: {\n\t\tsocket: WebSocket;\n\t\tid: string;\n\t\ttoken: string;\n\t}): void {\n\t\t// Check concurrent limit\n\t\tconst clientsCount = this.realm.getClientsIds().length;\n\n\t\tif (clientsCount >= this.config.concurrent_limit) {\n\t\t\tthis._sendErrorAndClose(socket, Errors.CONNECTION_LIMIT_EXCEED);\n\t\t\treturn;\n\t\t}\n\n\t\tconst newClient: IClient = new Client({ id, token });\n\t\tthis.realm.setClient(newClient, id);\n\t\tsocket.send(JSON.stringify({ type: MessageType.OPEN }));\n\n\t\tthis._configureWS(socket, newClient);\n\t}\n\n\tprivate _configureWS(socket: WebSocket, client: IClient): void {\n\t\tclient.setSocket(socket);\n\n\t\t// Cleanup after a socket closes.\n\t\tsocket.on(\"close\", () => {\n\t\t\tif (client.getSocket() === socket) {\n\t\t\t\tthis.realm.removeClientById(client.getId());\n\t\t\t\tthis.emit(\"close\", client);\n\t\t\t}\n\t\t});\n\n\t\t// Handle messages from peers.\n\t\tsocket.on(\"message\", (data) => {\n\t\t\ttry {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-base-to-string\n\t\t\t\tconst message = JSON.parse(data.toString()) as Writable<IMessage>;\n\n\t\t\t\tmessage.src = client.getId();\n\n\t\t\t\tthis.emit(\"message\", client, message);\n\t\t\t} catch (e) {\n\t\t\t\tthis.emit(\"error\", e);\n\t\t\t}\n\t\t});\n\n\t\tthis.emit(\"connection\", client);\n\t}\n\n\tprivate _sendErrorAndClose(socket: WebSocket, msg: Errors): void {\n\t\tsocket.send(\n\t\t\tJSON.stringify({\n\t\t\t\ttype: MessageType.ERROR,\n\t\t\t\tpayload: { msg },\n\t\t\t}),\n\t\t);\n\n\t\tsocket.close();\n\t}\n}\n\ntype Writable<T> = {\n\t-readonly [K in keyof T]: T[K];\n};\n","import type WebSocket from \"ws\";\n\nexport interface IClient {\n\tgetId(): string;\n\n\tgetToken(): string;\n\n\tgetSocket(): WebSocket | null;\n\n\tsetSocket(socket: WebSocket | null): void;\n\n\tgetLastPing(): number;\n\n\tsetLastPing(lastPing: number): void;\n\n\tsend<T>(data: T): void;\n}\n\nexport class Client implements IClient {\n\tprivate readonly id: string;\n\tprivate readonly token: string;\n\tprivate socket: WebSocket | null = null;\n\tprivate lastPing: number = new Date().getTime();\n\n\tconstructor({ id, token }: { id: string; token: string }) {\n\t\tthis.id = id;\n\t\tthis.token = token;\n\t}\n\n\tpublic getId(): string {\n\t\treturn this.id;\n\t}\n\n\tpublic getToken(): string {\n\t\treturn this.token;\n\t}\n\n\tpublic getSocket(): WebSocket | null {\n\t\treturn this.socket;\n\t}\n\n\tpublic setSocket(socket: WebSocket | null): void {\n\t\tthis.socket = socket;\n\t}\n\n\tpublic getLastPing(): number {\n\t\treturn this.lastPing;\n\t}\n\n\tpublic setLastPing(lastPing: number): void {\n\t\tthis.lastPing = lastPing;\n\t}\n\n\tpublic send<T>(data: T): void {\n\t\tthis.socket?.send(JSON.stringify(data));\n\t}\n}\n","import { MessageType } from \"../enums.ts\";\nimport { HeartbeatHandler, TransmissionHandler } from \"./handlers/index.ts\";\nimport type { IHandlersRegistry } from \"./handlersRegistry.ts\";\nimport { HandlersRegistry } from \"./handlersRegistry.ts\";\nimport type { IClient } from \"../models/client.ts\";\nimport type { IMessage } from \"../models/message.ts\";\nimport type { IRealm } from \"../models/realm.ts\";\nimport type { Handler } from \"./handler.ts\";\n\nexport interface IMessageHandler {\n\thandle(client: IClient | undefined, message: IMessage): boolean;\n}\n\nexport class MessageHandler implements IMessageHandler {\n\tconstructor(\n\t\trealm: IRealm,\n\t\tprivate readonly handlersRegistry: IHandlersRegistry = new HandlersRegistry(),\n\t) {\n\t\tconst transmissionHandler: Handler = TransmissionHandler({ realm });\n\t\tconst heartbeatHandler: Handler = HeartbeatHandler;\n\n\t\tconst handleTransmission: Handler = (\n\t\t\tclient: IClient | undefined,\n\t\t\t{ type, src, dst, payload }: IMessage,\n\t\t): boolean => {\n\t\t\treturn transmissionHandler(client, {\n\t\t\t\ttype,\n\t\t\t\tsrc,\n\t\t\t\tdst,\n\t\t\t\tpayload,\n\t\t\t});\n\t\t};\n\n\t\tconst handleHeartbeat = (client: IClient | undefined, message: IMessage) =>\n\t\t\theartbeatHandler(client, message);\n\n\t\tthis.handlersRegistry.registerHandler(\n\t\t\tMessageType.HEARTBEAT,\n\t\t\thandleHeartbeat,\n\t\t);\n\t\tthis.handlersRegistry.registerHandler(\n\t\t\tMessageType.OFFER,\n\t\t\thandleTransmission,\n\t\t);\n\t\tthis.handlersRegistry.registerHandler(\n\t\t\tMessageType.ANSWER,\n\t\t\thandleTransmission,\n\t\t);\n\t\tthis.handlersRegistry.registerHandler(\n\t\t\tMessageType.CANDIDATE,\n\t\t\thandleTransmission,\n\t\t);\n\t\tthis.handlersRegistry.registerHandler(\n\t\t\tMessageType.LEAVE,\n\t\t\thandleTransmission,\n\t\t);\n\t\tthis.handlersRegistry.registerHandler(\n\t\t\tMessageType.EXPIRE,\n\t\t\thandleTransmission,\n\t\t);\n\t}\n\n\tpublic handle(client: IClient | undefined, message: IMessage): boolean {\n\t\treturn this.handlersRegistry.handle(client, message);\n\t}\n}\n","export { HeartbeatHandler } from \"./heartbeat/index.ts\";\nexport { TransmissionHandler } from \"./transmission/index.ts\";\n","import type { IClient } from \"../../../models/client.ts\";\n\nexport const HeartbeatHandler = (client: IClient | undefined): boolean => {\n\tif (client) {\n\t\tconst nowTime = new Date().getTime();\n\t\tclient.setLastPing(nowTime);\n\t}\n\n\treturn true;\n};\n","import { MessageType } from \"../../../enums.ts\";\nimport type { IClient } from \"../../../models/client.ts\";\nimport type { IMessage } from \"../../../models/message.ts\";\nimport type { IRealm } from \"../../../models/realm.ts\";\n\nexport const TransmissionHandler = ({\n\trealm,\n}: {\n\trealm: IRealm;\n}): ((client: IClient | undefined, message: IMessage) => boolean) => {\n\tconst handle = (client: IClient | undefined, message: IMessage) => {\n\t\tconst type = message.type;\n\t\tconst srcId = message.src;\n\t\tconst dstId = message.dst;\n\n\t\tconst destinationClient = realm.getClientById(dstId);\n\n\t\t// User is connected!\n\t\tif (destinationClient) {\n\t\t\tconst socket = destinationClient.getSocket();\n\t\t\ttry {\n\t\t\t\tif (socket) {\n\t\t\t\t\tconst data = JSON.stringify(message);\n\n\t\t\t\t\tsocket.send(data);\n\t\t\t\t} else {\n\t\t\t\t\t// Neither socket no res available. Peer dead?\n\t\t\t\t\tthrow new Error(\"Peer dead\");\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\t// This happens when a peer disconnects without closing connections and\n\t\t\t\t// the associated WebSocket has not closed.\n\t\t\t\t// Tell other side to stop trying.\n\t\t\t\tif (socket) {\n\t\t\t\t\tsocket.close();\n\t\t\t\t} else {\n\t\t\t\t\trealm.removeClientById(destinationClient.getId());\n\t\t\t\t}\n\n\t\t\t\thandle(client, {\n\t\t\t\t\ttype: MessageType.LEAVE,\n\t\t\t\t\tsrc: dstId,\n\t\t\t\t\tdst: srcId,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// Wait for this client to connect/reconnect (XHR) for important\n\t\t\t// messages.\n\t\t\tconst ignoredTypes = [MessageType.LEAVE, MessageType.EXPIRE];\n\n\t\t\tif (!ignoredTypes.includes(type) && dstId) {\n\t\t\t\trealm.addMessageToQueue(dstId, message);\n\t\t\t} else if (type === MessageType.LEAVE && !dstId) {\n\t\t\t\trealm.removeClientById(srcId);\n\t\t\t} else {\n\t\t\t\t// Unavailable destination specified with message LEAVE or EXPIRE\n\t\t\t\t// Ignore\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t};\n\n\treturn handle;\n};\n","import type { MessageType } from \"../enums.ts\";\nimport type { IClient } from \"../models/client.ts\";\nimport type { IMessage } from \"../models/message.ts\";\nimport type { Handler } from \"./handler.ts\";\n\nexport interface IHandlersRegistry {\n\tregisterHandler(messageType: MessageType, handler: Handler): void;\n\thandle(client: IClient | undefined, message: IMessage): boolean;\n}\n\nexport class HandlersRegistry implements IHandlersRegistry {\n\tprivate readonly handlers = new Map<MessageType, Handler>();\n\n\tpublic registerHandler(messageType: MessageType, handler: Handler): void {\n\t\tif (this.handlers.has(messageType)) return;\n\n\t\tthis.handlers.set(messageType, handler);\n\t}\n\n\tpublic handle(client: IClient | undefined, message: IMessage): boolean {\n\t\tconst { type } = message;\n\n\t\tconst handler = this.handlers.get(type);\n\n\t\tif (!handler) return false;\n\n\t\treturn handler(client, message);\n\t}\n}\n","import cors, { CorsOptions } from \"cors\";\nimport express from \"express\";\nimport publicContent from \"../../app.json\";\nimport PublicApi from \"./v1/public/index.ts\";\nimport type { IConfig } from \"../config/index.ts\";\nimport type { IRealm } from \"../models/realm.ts\";\n\nexport const Api = ({\n\tconfig,\n\trealm,\n\tcorsOptions,\n}: {\n\tconfig: IConfig;\n\trealm: IRealm;\n\tcorsOptions: CorsOptions;\n}): express.Router => {\n\tconst app = express.Router();\n\n\tapp.use(cors(corsOptions));\n\n\tapp.get(\"/\", (_, res) => {\n\t\tres.send(publicContent);\n\t});\n\n\tapp.use(\"/:key\", PublicApi({ config, realm }));\n\n\treturn app;\n};\n","{\n\t\"name\": \"PeerJS Server\",\n\t\"description\": \"A server side element to broker connections between PeerJS clients.\",\n\t\"website\": \"https://peerjs.com/\"\n}\n","import express from \"express\";\nimport type { IConfig } from \"../../../config/index.ts\";\nimport type { IRealm } from \"../../../models/realm.ts\";\n\nexport default ({\n\tconfig,\n\trealm,\n}: {\n\tconfig: IConfig;\n\trealm: IRealm;\n}): express.Router => {\n\tconst app = express.Router();\n\n\t// Retrieve guaranteed random ID.\n\tapp.get(\"/id\", (_, res: express.Response) => {\n\t\tres.contentType(\"html\");\n\t\tres.send(realm.generateClientId(config.generateClientId));\n\t});\n\n\t// Get a list of all peers for a key, enabled by the `allowDiscovery` flag.\n\tapp.get(\"/peers\", (_, res: express.Response) => {\n\t\tif (config.allow_discovery) {\n\t\t\tconst clientsIds = realm.getClientsIds();\n\n\t\t\treturn res.send(clientsIds);\n\t\t}\n\n\t\treturn res.sendStatus(401);\n\t});\n\n\treturn app;\n};\n"],"names":[],"version":3,"file":"index.cjs.map","sourceRoot":"../"}