From 616f437432848abaff45c10a4a6da677fb85ddcd Mon Sep 17 00:00:00 2001 From: Alex Hunt Date: Wed, 25 Sep 2024 03:52:04 -0700 Subject: [PATCH] Add TerminalReporter events for outputting server logs and menus Summary: Introduces new event types in Metro's TerminalReporter, intended for a host dev server to append logs via Metro (in particular, leveraging the internal `Terminal` API to safely display logs without colliding with bundler progress output). - `unstable_server_log`: Allows the server to emit a log message at various `level`s. Mirrors the design of `client_log`. - `unstable_server_menu_updated`: Allows the server to present/update a menu (a persistent item / interactive status line) below all other streamed output. For now, the specialised term "menu" fits well and is descriptive (I'd imagine we introduce specialised events for future flavours of persistent status). - `unstable_server_menu_cleared` This supports interactive debugger target selection in React Native. These simplified and generic event types and also will allow us to improve/align log handling to use Metro's `Terminal` abstraction in the open source dev server setup (both `dev-middleware` and `community-cli-plugin`). Changelog: ``` - **[Experimental]**: Add `unstable_server_log`, `unstable_server_menu_updated`, and `unstable_server_menu_cleared` reporter events ``` Reviewed By: hoxyq Differential Revision: D63255296 fbshipit-source-id: 9278f19fb4e6eb2b8fd0bb267f2321d52b32bb7c --- packages/metro/src/lib/TerminalReporter.js | 30 +++++++++++++++++++--- packages/metro/src/lib/reporting.js | 13 ++++++++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/packages/metro/src/lib/TerminalReporter.js b/packages/metro/src/lib/TerminalReporter.js index 49d1512ac..398ad87ef 100644 --- a/packages/metro/src/lib/TerminalReporter.js +++ b/packages/metro/src/lib/TerminalReporter.js @@ -41,8 +41,18 @@ export type TerminalReportableEvent = ... } | { - type: 'unstable_set_interaction_status', - status: ?string, + type: 'unstable_server_log', + level: 'info' | 'warn' | 'error', + data: string | Array, + ... + } + | { + type: 'unstable_server_menu_updated', + message: string, + ... + } + | { + type: 'unstable_server_menu_cleared', ... }; @@ -251,6 +261,15 @@ class TerminalReporter { case 'client_log': logToConsole(this.terminal, event.level, event.mode, ...event.data); break; + case 'unstable_server_log': + const logFn = { + info: reporting.logInfo, + warn: reporting.logWarning, + error: reporting.logError, + }[event.level]; + const [format, ...args] = [].concat(event.data); + logFn(this.terminal, String(format), ...args); + break; case 'dep_graph_loading': const color = event.hasReducedPerformance ? chalk.red : chalk.blue; const version = 'v' + require('../../package.json').version; @@ -385,8 +404,11 @@ class TerminalReporter { case 'bundle_transform_progressed_throttled': this._updateBundleProgress(event); break; - case 'unstable_set_interaction_status': - this._interactionStatus = event.status; + case 'unstable_server_menu_updated': + this._interactionStatus = event.message; + break; + case 'unstable_server_menu_cleared': + this._interactionStatus = null; break; } } diff --git a/packages/metro/src/lib/reporting.js b/packages/metro/src/lib/reporting.js index 7087762e4..1a84acfb0 100644 --- a/packages/metro/src/lib/reporting.js +++ b/packages/metro/src/lib/reporting.js @@ -211,6 +211,18 @@ function logError( ); } +/** + * Similar to `logWarning`, but for informational messages. + */ +function logInfo( + terminal: Terminal, + format: string, + ...args: Array +): void { + const str = util.format(format, ...args); + terminal.log('%s: %s', chalk.cyan('info'), str); +} + /** * A reporter that does nothing. Errors and warnings will be swallowed, that * is generally not what you want. @@ -220,5 +232,6 @@ const nullReporter = {update(): void {}}; module.exports = { logWarning, logError, + logInfo, nullReporter, };