1 | "use strict";
|
2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3 | if (k2 === undefined) k2 = k;
|
4 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
5 | }) : (function(o, m, k, k2) {
|
6 | if (k2 === undefined) k2 = k;
|
7 | o[k2] = m[k];
|
8 | }));
|
9 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
10 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
11 | }) : function(o, v) {
|
12 | o["default"] = v;
|
13 | });
|
14 | var __importStar = (this && this.__importStar) || function (mod) {
|
15 | if (mod && mod.__esModule) return mod;
|
16 | var result = {};
|
17 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
18 | __setModuleDefault(result, mod);
|
19 | return result;
|
20 | };
|
21 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
22 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
23 | };
|
24 | Object.defineProperty(exports, "__esModule", { value: true });
|
25 | exports.paintDashboard = exports.getServerInfoMessage = exports.getPort = exports.paintEvent = void 0;
|
26 | const detect_port_1 = __importDefault(require("detect-port"));
|
27 | const colors = __importStar(require("kleur/colors"));
|
28 | const path_1 = __importDefault(require("path"));
|
29 | const readline_1 = __importDefault(require("readline"));
|
30 | const logger_1 = require("../logger");
|
31 | const IS_FILE_CHANGED_MESSAGE = /File changed\.\.\./;
|
32 |
|
33 | function summarizeHistory(history) {
|
34 |
|
35 | return history.reduce((historyString, record) => {
|
36 | let line;
|
37 |
|
38 |
|
39 | if (record.count === 1) {
|
40 | line = record.val;
|
41 | }
|
42 | else if (IS_FILE_CHANGED_MESSAGE.test(record.val)) {
|
43 | line = record.val + colors.green(` [x${record.count}]`);
|
44 | }
|
45 | else {
|
46 | line = Array(record.count).fill(record.val).join('\n');
|
47 | }
|
48 |
|
49 |
|
50 | return historyString + '\n' + line;
|
51 | }, '');
|
52 | }
|
53 | exports.paintEvent = {
|
54 | BUILD_FILE: 'BUILD_FILE',
|
55 | LOAD_ERROR: 'LOAD_ERROR',
|
56 | SERVER_START: 'SERVER_START',
|
57 | WORKER_COMPLETE: 'WORKER_COMPLETE',
|
58 | WORKER_MSG: 'WORKER_MSG',
|
59 | WORKER_RESET: 'WORKER_RESET',
|
60 | };
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 | async function getPort(defaultPort) {
|
67 | const bestAvailablePort = await detect_port_1.default(defaultPort);
|
68 | if (defaultPort !== bestAvailablePort) {
|
69 | let useNextPort = false;
|
70 | if (process.stdout.isTTY) {
|
71 | const rl = readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
|
72 | useNextPort = await new Promise((resolve) => {
|
73 | rl.question(colors.yellow(`! Port ${colors.bold(defaultPort)} not available. Run on port ${colors.bold(bestAvailablePort)} instead? (Y/n) `), (answer) => {
|
74 | resolve(!/^no?$/i.test(answer));
|
75 | });
|
76 | });
|
77 | rl.close();
|
78 | }
|
79 | if (!useNextPort) {
|
80 | logger_1.logger.error(`✘ Port ${colors.bold(defaultPort)} not available. Use ${colors.bold('--port')} to specify a different port.`);
|
81 | process.exit(1);
|
82 | }
|
83 | }
|
84 | return bestAvailablePort;
|
85 | }
|
86 | exports.getPort = getPort;
|
87 | function getServerInfoMessage({ startTimeMs, port, protocol, hostname, remoteIp }, isBuilding = false) {
|
88 | let output = '';
|
89 | const isServerStarted = startTimeMs > 0 && port > 0 && protocol;
|
90 | if (isServerStarted) {
|
91 | output += ` ${colors.bold(colors.cyan(`${protocol}//${hostname}:${port}`))}`;
|
92 | if (remoteIp) {
|
93 | output += `${colors.cyan(` • `)}${colors.bold(colors.cyan(`${protocol}//${remoteIp}:${port}`))}`;
|
94 | }
|
95 | output += '\n';
|
96 | output += colors.dim(
|
97 |
|
98 | startTimeMs < 1000 ? ` Server started in ${startTimeMs}ms.` : ` Server started.`);
|
99 | if (isBuilding) {
|
100 | output += colors.dim(` Building...`);
|
101 | }
|
102 | output += '\n\n';
|
103 | }
|
104 | else {
|
105 | output += colors.dim(` Server starting…`) + '\n\n';
|
106 | }
|
107 | return output;
|
108 | }
|
109 | exports.getServerInfoMessage = getServerInfoMessage;
|
110 | const WORKER_BASE_STATE = { done: false, error: null, output: '' };
|
111 | function paintDashboard(bus, config) {
|
112 | let serverInfo;
|
113 | const allWorkerStates = {};
|
114 | const allFileBuilds = new Set();
|
115 | for (const plugin of config.plugins.map((p) => p.name)) {
|
116 | allWorkerStates[plugin] = { ...WORKER_BASE_STATE };
|
117 | }
|
118 | function setupWorker(id) {
|
119 | if (!allWorkerStates[id]) {
|
120 | allWorkerStates[id] = { ...WORKER_BASE_STATE };
|
121 | }
|
122 | }
|
123 | function repaint() {
|
124 |
|
125 | process.stdout.write(process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H');
|
126 |
|
127 | process.stdout.write(`${colors.bold(`snowpack`)}\n\n`);
|
128 |
|
129 | serverInfo && process.stdout.write(getServerInfoMessage(serverInfo, allFileBuilds.size > 0));
|
130 |
|
131 | const history = logger_1.logger.getHistory();
|
132 | if (history.length) {
|
133 | process.stdout.write(`${colors.underline(colors.bold('▼ Console'))}\n`);
|
134 | process.stdout.write(summarizeHistory(history));
|
135 | process.stdout.write('\n\n');
|
136 | }
|
137 |
|
138 | for (const [script, workerState] of Object.entries(allWorkerStates)) {
|
139 | if (!workerState.output) {
|
140 | continue;
|
141 | }
|
142 | const colorsFn = Array.isArray(workerState.error) ? colors.red : colors.reset;
|
143 | process.stdout.write(`${colorsFn(colors.underline(colors.bold('▼ ' + script)))}\n\n`);
|
144 | process.stdout.write(' ' + workerState.output.trim().replace(/\n/gm, '\n '));
|
145 | process.stdout.write('\n\n');
|
146 | }
|
147 | }
|
148 | bus.on(exports.paintEvent.BUILD_FILE, ({ id, isBuilding }) => {
|
149 | if (isBuilding) {
|
150 | allFileBuilds.add(path_1.default.relative(config.root, id));
|
151 | }
|
152 | else {
|
153 | allFileBuilds.delete(path_1.default.relative(config.root, id));
|
154 | }
|
155 | repaint();
|
156 | });
|
157 | bus.on(exports.paintEvent.WORKER_MSG, ({ id, msg }) => {
|
158 | setupWorker(id);
|
159 | allWorkerStates[id].output += msg;
|
160 | repaint();
|
161 | });
|
162 | bus.on(exports.paintEvent.WORKER_COMPLETE, ({ id, error }) => {
|
163 | allWorkerStates[id].done = true;
|
164 | allWorkerStates[id].error = allWorkerStates[id].error || error;
|
165 | repaint();
|
166 | });
|
167 | bus.on(exports.paintEvent.WORKER_RESET, ({ id }) => {
|
168 | allWorkerStates[id] = { ...WORKER_BASE_STATE };
|
169 | repaint();
|
170 | });
|
171 | bus.on(exports.paintEvent.SERVER_START, (info) => {
|
172 | serverInfo = info;
|
173 | repaint();
|
174 | });
|
175 |
|
176 | logger_1.logger.on('debug', () => {
|
177 | repaint();
|
178 | });
|
179 | logger_1.logger.on('info', () => {
|
180 | repaint();
|
181 | });
|
182 | logger_1.logger.on('warn', () => {
|
183 | repaint();
|
184 | });
|
185 | logger_1.logger.on('error', () => {
|
186 | repaint();
|
187 | });
|
188 | repaint();
|
189 | }
|
190 | exports.paintDashboard = paintDashboard;
|