-
-
Notifications
You must be signed in to change notification settings - Fork 560
/
Copy pathLogger.ts
93 lines (80 loc) · 2.55 KB
/
Logger.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import http from 'http';
import path from 'path';
import express from 'express';
import ews from 'express-ws';
import Tab from './Tab';
export { Tab };
export default class Logger {
private app = express();
private ws!: ews.Instance;
private tabs: Tab[] = [];
private server: http.Server | null = null;
constructor(private port = 9000) {
this.registerRoutes();
}
private registerRoutes() {
this.ws = ews(this.app);
this.app.get('/rest/tabs', (_req, res) => res.json(this.tabs));
this.app.use('/xterm/addons/fit', express.static(path.dirname(require.resolve('xterm-addon-fit'))));
this.app.use('/xterm/addons/search', express.static(path.dirname(require.resolve('xterm-addon-search'))));
this.app.use('/xterm', express.static(path.resolve(require.resolve('xterm'), '../..')));
this.app.use(express.static(path.resolve(__dirname, '..', 'static')));
this.ws.app.ws('/sub', () => {
// I assume this endpoint is just a no-op needed for some reason.
});
}
/**
* Find an available port between 9000 and 9009 for web UI.
* @returns the port number.
*/
private async findAvailablePort(): Promise<number> {
const maxPortAttempts = 10; // Maximum attempts to find an available port
let port = this.port;
let attempts = 0;
while (attempts < maxPortAttempts) {
try {
await new Promise<void>((resolve, reject) => {
const server = http.createServer();
server.unref(); // Allows the program to exit if this is the only active server
server.on('error', reject);
server.listen(port, () => {
server.close(() => {
resolve();
});
});
});
return port;
} catch {
// Port is in use, try the next one
port++;
attempts++;
}
}
throw new Error('Could not find an available port between 9000 and 9009. Please free up a port and try again.');
}
/**
* Creates a new tab with the given name, the name should be human readable
* it will be used as the tab title in the front end.
*/
createTab(name: string): Tab {
const tab = new Tab(name, this.ws);
this.tabs.push(tab);
return tab;
}
/**
* Start the HTTP server hosting the web UI.
*
* @returns the port number
*/
async start(): Promise<number> {
this.port = await this.findAvailablePort();
this.server = this.app.listen(this.port);
return this.port;
}
/**
* Stop the HTTP server hosting the web UI
*/
stop(): void {
if (this.server) this.server.close();
}
}