123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = void 0;
- function _ws() {
- const data = require("ws");
- _ws = function () {
- return data;
- };
- return data;
- }
- function _cliTools() {
- const data = require("@react-native-community/cli-tools");
- _cliTools = function () {
- return data;
- };
- return data;
- }
- function _prettyFormat() {
- const data = _interopRequireDefault(require("pretty-format"));
- _prettyFormat = function () {
- return data;
- };
- return data;
- }
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
- /**
- * This number is used to version the communication protocol between
- * Dev tooling like Flipper and Metro, so that in the future we can recognize
- * messages coming from old clients, so that it will be simpler to implement
- * backward compatibility.
- *
- * We start at 2 as the protocol is currently the same as used internally at FB,
- * which happens to be at version 2 as well.
- */
- const PROTOCOL_VERSION = 2;
- function parseMessage(data) {
- try {
- const message = JSON.parse(data);
- if (message.version === PROTOCOL_VERSION) {
- return message;
- }
- _cliTools().logger.error('Received message had wrong protocol version: ' + message.version);
- } catch (_unused) {
- _cliTools().logger.error('Failed to parse the message as JSON:\n' + data);
- }
- return undefined;
- }
- /**
- * Two types of messages will arrive in this function,
- * 1) messages generated by Metro itself (through the reporter abstraction)
- * those are yet to be serialized, and can contain any kind of data structure
- * 2) a specific event generated by Metro is `client_log`, which describes
- * console.* calls in the app.
- * The arguments send to the console are pretty printed so that they can be
- * displayed in a nicer way in dev tools
- *
- * @param message
- */
- function serializeMessage(message) {
- // We do want to send Metro report messages, but their contents is not guaranteed to be serializable.
- // For some known types we will pretty print otherwise not serializable parts first:
- let toSerialize = message;
- if (message && message.error && message.error instanceof Error) {
- toSerialize = { ...message,
- error: (0, _prettyFormat().default)(message.error, {
- escapeString: true,
- highlight: true,
- maxDepth: 3,
- min: true
- })
- };
- } else if (message && message.type === 'client_log') {
- toSerialize = { ...message,
- data: message.data.map(item => typeof item === 'string' ? item : (0, _prettyFormat().default)(item, {
- escapeString: true,
- highlight: true,
- maxDepth: 3,
- min: true,
- plugins: [_prettyFormat().default.plugins.ReactElement]
- }))
- };
- }
- try {
- return JSON.stringify(toSerialize);
- } catch (e) {
- _cliTools().logger.error('Failed to serialize: ' + e);
- return null;
- }
- }
- /**
- * Starts the eventsSocket at the given path
- *
- * @param server
- * @param path typically: 'events/'
- * @param messageSocket: webSocket to which all connected RN apps are listening
- */
- function attachToServer(server, path, messageSocket) {
- const wss = new (_ws().Server)({
- server: server,
- path: path,
- verifyClient({
- origin
- }) {
- // This exposes the full JS logs and enables issuing commands like reload
- // so let's make sure only locally running stuff can connect to it
- return origin.startsWith('http://localhost:') || origin.startsWith('file:');
- }
- });
- const clients = new Map();
- let nextClientId = 0;
- /**
- * broadCastEvent is called by reportEvent (below), which is called by the
- * default reporter of this server, to make sure that all Metro events are
- * broadcasted to all connected clients
- * (that is, all devtools such as Flipper, _not_: connected apps)
- *
- * @param message
- */
- function broadCastEvent(message) {
- if (!clients.size) {
- return;
- }
- const serialized = serializeMessage(message);
- if (!serialized) {
- return;
- }
- for (const ws of clients.values()) {
- try {
- ws.send(serialized);
- } catch (e) {
- _cliTools().logger.error(`Failed to send broadcast to client due to:\n ${e.toString()}`);
- }
- }
- }
- wss.on('connection', function (clientWs) {
- const clientId = `client#${nextClientId++}`;
- clients.set(clientId, clientWs);
- clientWs.onclose = clientWs.onerror = () => {
- clients.delete(clientId);
- };
- clientWs.onmessage = event => {
- const message = parseMessage(event.data.toString());
- if (message == null) {
- return;
- }
- if (message.type === 'command') {
- try {
- /**
- * messageSocket.broadcast (not to be confused with our own broadcast above)
- * forwards a command to all connected React Native applications.
- */
- messageSocket.broadcast(message.command, message.params);
- } catch (e) {
- _cliTools().logger.error('Failed to forward message to clients: ', e);
- }
- } else {
- _cliTools().logger.error('Unknown message type: ', message.type);
- }
- };
- });
- return {
- reportEvent: event => {
- broadCastEvent(event);
- }
- };
- }
- var _default = {
- attachToServer
- };
- exports.default = _default;
- //# sourceMappingURL=eventsSocketServer.js.map
|