diff --git a/packages/xarc-app-dev/lib/dev-admin/admin-server.js b/packages/xarc-app-dev/lib/dev-admin/admin-server.js index fdfefeb04..782057c79 100644 --- a/packages/xarc-app-dev/lib/dev-admin/admin-server.js +++ b/packages/xarc-app-dev/lib/dev-admin/admin-server.js @@ -27,6 +27,10 @@ const APP_SERVER_NAME = "your app server"; const DEV_SERVER_NAME = "Electrode webpack dev server"; const PROXY_SERVER_NAME = "Electrode Dev Proxy"; +const DEV_ADMIN_STATUS = "DevAdminStatus"; +const WDS_PROGRESS = "WDSProgress"; +const LOG_ALERT = "LogAlert"; + const SERVER_ENVS = { [APP_SERVER_NAME]: { XARC_BABEL_TARGET: "node" @@ -49,6 +53,7 @@ class AdminServer { // will mess up the in place progress display that log-update handles // this._io = (options && options.inputOutput) || new ConsoleIO(); + this._shutdown = false; this._fullAppLogUrl = formUrl({ ...fullDevServer, path: controlPaths.appLog }); } @@ -57,7 +62,14 @@ class AdminServer { this._wds = ck`[wds] `; this._proxy = ck`[proxy] `; this._app = ck`[app] `; + this._menu = ""; this._io.setup(); + this._io.addItem({ + name: DEV_ADMIN_STATUS, + display: ck`[DEV ADMIN]`, + spinner: true + }); + this.updateStatus("webpack is PENDING"); this.handleUserInput(); this._shutdown || (await this.startWebpackDevServer()); @@ -70,11 +82,21 @@ class AdminServer { this._shutdown || setTimeout(() => { - this.showMenu(); + this.showMenu(true); }, 100); } - showMenu() { + updateStatus(line) { + if (line !== undefined) { + this._statusLine = line; + } + this._io.updateItem( + DEV_ADMIN_STATUS, + `Press M to show/hide menu. Q to exit. ${this._statusLine}${this._menu}` + ); + } + + makeMenu() { const reporterUrl = formUrl({ ...fullDevServer, path: controlPaths.reporter }); const logUrl = formUrl({ ...fullDevServer, path: controlPaths.appLog }); const devurl = formUrl({ ...fullDevServer, path: controlPaths.dev }); @@ -92,7 +114,21 @@ ${proxyItem}M - Show this menu Q - Shutdown App Log URL: ${logUrl} DEV dashboard: ${devurl} WebPack reporter: ${reporterUrl}`; - this._io.show("\n" + boxen(menu, { margin: { left: 5 }, padding: { right: 3, left: 3 } })); + + this._menu = "\n" + boxen(menu, { margin: { left: 5 }, padding: { right: 3, left: 3 } }); + } + + showMenu(force) { + const show = force !== undefined ? force : !this._menu; + + if (show) { + this.makeMenu(); + clearTimeout(this._hideMenuTimer); + this._hideMenuTimer = setTimeout(() => this.showMenu(false), 15 * 60 * 1000).unref(); // hide menu after a while + } else { + this._menu = ""; + } + this.updateStatus(); } getServer(name) { @@ -152,7 +188,6 @@ ${proxyItem}M - Show this menu Q - Shutdown async _quit() { this._shutdown = true; - this._io.clearStatusMessage(true); this._io.show(ck`admin server exit, shutting down servers`); if (this._appWatcher) { this._appWatcher.close(); @@ -295,13 +330,18 @@ ${proxyItem}M - Show this menu Q - Shutdown .forEach(line => { if (line.startsWith(progSig)) { progLine = line.substring(progSig.length).replace(cwdRegex, "."); - out.writeStatusMessage(this._wds, progLine); + this._io.addItem({ name: WDS_PROGRESS, spinner: true, display: `Webpack Progress` }); + this._io.updateItem(WDS_PROGRESS, progLine); } else { if (progLine) { - out.clearStatusMessage(this._wds); + setTimeout(() => this._io.removeItem(WDS_PROGRESS), 2000).unref(); progLine = ""; } - out.write(this._wds + line.replace(cwdRegex, ".") + "\n"); + if (line.includes("webpack bundle is now")) { + this.updateStatus(line); + } else { + out.write(this._wds + line.replace(cwdRegex, ".") + "\n"); + } } }); }; @@ -346,24 +386,34 @@ ${proxyItem}M - Show this menu Q - Shutdown const { logSaver } = options; logSaver._toggle = !logSaver._toggle; if (!logSaver._toggle) { - this._io.clearStatusMessage(options.tag); + this._io.removeItem(LOG_ALERT); } else { - this.showFullLogUrlMessage(options.tag, options.fullLogUrl); + this.showFullLogUrlMessage(logSaver._time, logSaver.fullLogUrl); } } } - showFullLogUrlMessage(tag, url) { - const time = new Date().toLocaleTimeString().replace(/ /g, ""); - this._io.writeStatusMessage( - tag, - [ - ck`${time} - There may be logs from your app server that requires your attention.`, - ck`View full logs at: ${url}` - ], - true, - ck`Press Z to hide or show this message.` - ); + showFullLogUrlMessage(time, url) { + this._io.addItem({ + name: LOG_ALERT, + display: ck`ALERT`, + spinner: true + }); + const instruction = `View full logs at: ${url} - \ +Press Z to hide or show this message`; + if (time) { + this._io.updateItem( + LOG_ALERT, + ck`${time} - Your app server may have logs that requires your attention. +${instruction}` + ); + } else { + this._io.updateItem( + LOG_ALERT, + ck`no unusual log detected from your app server. +${instruction}` + ); + } } deferLogsOutput(context, showFullLink = true, delay = 999) { @@ -398,10 +448,10 @@ ${proxyItem}M - Show this menu Q - Shutdown } if (typeof store[ix] === "string") { - this._io.write(tag + store[ix] + "\n"); + this._io.show(tag + store[ix]); } else if (store[ix]) { const json = store[ix]; - this._io.write(tag + (json.msg || json.message || JSON.stringify(json)) + "\n"); + this._io.show(tag + (json.msg || json.message || JSON.stringify(json))); } } currentIx = ix + 1; @@ -409,7 +459,8 @@ ${proxyItem}M - Show this menu Q - Shutdown context._deferIx = []; if (context._showFullLink === true) { context._toggle = true; - this.showFullLogUrlMessage(tag, context.fullLogUrl); + context._time = new Date().toLocaleTimeString().replace(/ /g, ""); + this.showFullLogUrlMessage(context._time, context.fullLogUrl); } context._showFullLink = undefined; if (store.length > 25000) { @@ -454,8 +505,6 @@ ${proxyItem}M - Show this menu Q - Shutdown async startAppServer(debug) { const skipWatch = debug === "--inspect-brk"; - this._io.clearStatusMessage(this._app); - const logSaver = { tag: this._app, store: [], fullLogUrl: this._fullAppLogUrl }; await this.startServer({ diff --git a/packages/xarc-app-dev/lib/dev-admin/console-io.js b/packages/xarc-app-dev/lib/dev-admin/console-io.js index bac91f134..84a502a0f 100644 --- a/packages/xarc-app-dev/lib/dev-admin/console-io.js +++ b/packages/xarc-app-dev/lib/dev-admin/console-io.js @@ -4,11 +4,12 @@ const readline = require("readline"); const logUpdate = require("log-update"); +const VisualLogger = require("visual-logger"); -class ConsoleIO { - constructor() { - this._out = process.stdout; - this.currentStatus = {}; +class ConsoleIO extends VisualLogger { + constructor(options) { + super({ ...options, saveLogs: false }); + this.setPrefix(""); } setup() { @@ -30,63 +31,15 @@ class ConsoleIO { } show(...args) { - this.clearStatusMessage(); - console.log(...args); - this.writeStatusMessage(); + this.log(...args); } write(str) { - this.clearStatusMessage(); - this._out.write(str); - this.writeStatusMessage(); - } - - clearStatusMessage(resetTag) { - const { showing, preserve } = this.currentStatus; - if (showing) { - if (resetTag && resetTag !== true && resetTag !== this.currentStatus.tag) { - this.preserveStatusMsg(); - } - logUpdate.clear(); - this.currentStatus.showing = false; - } - if (resetTag) { - this.currentStatus = {}; - } - } - - preserveStatusMsg() { - if (this.currentStatus.msg && this.currentStatus.preserve) { - const { tag, msg } = this.currentStatus; - this.showStatusMessage(tag, msg); - logUpdate.done(); - } - } - - showStatusMessage(tag, msg, clearMsg = "") { - const lineTxt = [] - .concat(msg, clearMsg) - .filter(x => x) - .map(line => `${tag}${line}`); - logUpdate(lineTxt.join("\n")); - this.currentStatus.showing = true; - } - - writeStatusMessage(tag, msg, preserve = false, clearMsg = "") { - if (tag && msg) { - if (this.currentStatus.tag && this.currentStatus.tag !== tag) { - this.preserveStatusMsg(); - } - this.currentStatus = { tag, msg, preserve, clearMsg }; - } - if (!this.currentStatus.msg) return; - - const { tag: xtag, msg: xmsg } = this.currentStatus; - this.showStatusMessage(xtag, xmsg, clearMsg); + this.log(str.trimRight()); } exit() { - this._out.write("\n"); + this.clearItems(); process.exit(); } } diff --git a/packages/xarc-app-dev/package.json b/packages/xarc-app-dev/package.json index d3ce6e033..f1ef439ee 100644 --- a/packages/xarc-app-dev/package.json +++ b/packages/xarc-app-dev/package.json @@ -79,6 +79,7 @@ "style-loader": "^0.20.1", "subapp-util": "^1.0.4", "sudo-prompt": "^8.2.5", + "visual-logger": "^1.0.0", "webpack-cli": "^3.3.9", "webpack-dev-middleware": "^3.4.0", "webpack-hot-middleware": "^2.22.2",