{"version":3,"names":["PROTOCOL_VERSION","parseMessage","data","binary","logger","error","undefined","message","JSON","parse","version","e","isBroadcast","method","id","target","isRequest","isResponse","requestId","clientId","result","createMessageSocketEndpoint","wss","WebSocketServer","noServer","clients","Map","nextClientId","getClientWs","clientWs","get","Error","handleSendBroadcast","broadcasterId","forwarded","params","size","warn","otherId","otherWs","send","stringify","toString","on","handleCaughtError","errorMessage","handleServerRequest","forEach","url","upgradeReq","query","forwardRequest","forwardResponse","set","onCloseHandler","onmessage","delete","onclose","onerror","event","server","broadcast"],"sources":["../../src/websocket/createMessageSocketEndpoint.ts"],"sourcesContent":["/**\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport url from 'url';\nimport {Server as WebSocketServer} from 'ws';\nimport {logger} from '@react-native-community/cli-tools';\n\nconst PROTOCOL_VERSION = 2;\n\ntype IdObject = {\n requestId: string;\n clientId: string;\n};\n\ntype Message = {\n version?: string;\n id?: IdObject;\n method?: string;\n target: string;\n result?: any;\n error?: Error;\n params?: Record;\n};\n\nfunction parseMessage(data: string, binary: any) {\n if (binary) {\n logger.error('Expected text message, got binary!');\n return undefined;\n }\n try {\n const message = JSON.parse(data);\n if (message.version === PROTOCOL_VERSION) {\n return message;\n }\n logger.error(\n `Received message had wrong protocol version: ${message.version}`,\n );\n } catch (e) {\n logger.error(`Failed to parse the message as JSON:\\n${data}`);\n }\n return undefined;\n}\n\nfunction isBroadcast(message: Message) {\n return (\n typeof message.method === 'string' &&\n message.id === undefined &&\n message.target === undefined\n );\n}\n\nfunction isRequest(message: Message) {\n return (\n typeof message.method === 'string' && typeof message.target === 'string'\n );\n}\n\nfunction isResponse(message: Message) {\n return (\n typeof message.id === 'object' &&\n typeof message.id.requestId !== 'undefined' &&\n typeof message.id.clientId === 'string' &&\n (message.result !== undefined || message.error !== undefined)\n );\n}\n\nexport default function createMessageSocketEndpoint(): {\n server: WebSocketServer;\n broadcast: (method: string, params?: Record) => void;\n} {\n const wss = new WebSocketServer({\n noServer: true,\n });\n const clients = new Map();\n let nextClientId = 0;\n\n function getClientWs(clientId: string) {\n const clientWs = clients.get(clientId);\n if (clientWs === undefined) {\n throw new Error(\n `could not find id \"${clientId}\" while forwarding request`,\n );\n }\n return clientWs;\n }\n\n function handleSendBroadcast(\n broadcasterId: string | null,\n message: Partial,\n ) {\n const forwarded = {\n version: PROTOCOL_VERSION,\n method: message.method,\n params: message.params,\n };\n if (clients.size === 0) {\n logger.warn(\n `No apps connected. Sending \"${message.method}\" to all React Native apps failed. Make sure your app is running in the simulator or on a phone connected via USB.`,\n );\n }\n for (const [otherId, otherWs] of clients) {\n if (otherId !== broadcasterId) {\n try {\n otherWs.send(JSON.stringify(forwarded));\n } catch (e) {\n logger.error(\n `Failed to send broadcast to client: '${otherId}' ` +\n `due to:\\n ${(e as any).toString()}`,\n );\n }\n }\n }\n }\n\n wss.on('connection', (clientWs) => {\n const clientId = `client#${nextClientId++}`;\n\n function handleCaughtError(message: Message, error: Error) {\n const errorMessage = {\n id: message.id,\n method: message.method,\n target: message.target,\n error: message.error === undefined ? 'undefined' : 'defined',\n params: message.params === undefined ? 'undefined' : 'defined',\n result: message.result === undefined ? 'undefined' : 'defined',\n };\n\n if (message.id === undefined) {\n logger.error(\n `Handling message from ${clientId} failed with:\\n${error}\\n` +\n `message:\\n${JSON.stringify(errorMessage)}`,\n );\n } else {\n try {\n clientWs.send(\n JSON.stringify({\n version: PROTOCOL_VERSION,\n error,\n id: message.id,\n }),\n );\n } catch (e) {\n logger.error(\n `Failed to reply to ${clientId} with error:\\n${error}` +\n `\\nmessage:\\n${JSON.stringify(errorMessage)}` +\n `\\ndue to error: ${(e as any).toString()}`,\n );\n }\n }\n }\n\n function handleServerRequest(message: Message) {\n let result = null;\n switch (message.method) {\n case 'getid':\n result = clientId;\n break;\n case 'getpeers':\n result = {};\n clients.forEach((otherWs, otherId) => {\n if (clientId !== otherId) {\n result[otherId] = url.parse(otherWs.upgradeReq.url, true).query;\n }\n });\n break;\n default:\n throw new Error(`unknown method: ${message.method}`);\n }\n\n clientWs.send(\n JSON.stringify({\n version: PROTOCOL_VERSION,\n result,\n id: message.id,\n }),\n );\n }\n\n function forwardRequest(message: Message) {\n getClientWs(message.target).send(\n JSON.stringify({\n version: PROTOCOL_VERSION,\n method: message.method,\n params: message.params,\n id:\n message.id === undefined\n ? undefined\n : {requestId: message.id, clientId},\n }),\n );\n }\n\n function forwardResponse(message: Message) {\n if (!message.id) {\n return;\n }\n getClientWs(message.id.clientId).send(\n JSON.stringify({\n version: PROTOCOL_VERSION,\n result: message.result,\n error: message.error,\n id: message.id.requestId,\n }),\n );\n }\n\n clients.set(clientId, clientWs);\n const onCloseHandler = () => {\n clientWs.onmessage = () => {};\n clients.delete(clientId);\n };\n clientWs.onclose = onCloseHandler;\n clientWs.onerror = onCloseHandler;\n clientWs.onmessage = (event: any) => {\n const message = parseMessage(event.data, event.binary);\n if (message === undefined) {\n logger.error('Received message not matching protocol');\n return;\n }\n\n try {\n if (isBroadcast(message)) {\n handleSendBroadcast(clientId, message);\n } else if (isRequest(message)) {\n if (message.target === 'server') {\n handleServerRequest(message);\n } else {\n forwardRequest(message);\n }\n } else if (isResponse(message)) {\n forwardResponse(message);\n } else {\n throw new Error('Invalid message, did not match the protocol');\n }\n } catch (e) {\n handleCaughtError(message, (e as any).toString());\n }\n };\n });\n\n return {\n server: wss,\n broadcast: (method: string, params?: Record) => {\n handleSendBroadcast(null, {method, params});\n },\n };\n}\n"],"mappings":"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"}