UNPKG

4.44 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.AppController = void 0;
4const tslib_1 = require("tslib");
5const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
6const child_process_1 = require("child_process");
7const pstree_remy_1 = (0, tslib_1.__importStar)(require("pstree.remy"));
8const platform_1 = require("../util/platform");
9function invariant(condition, message) {
10 if (!condition) {
11 const err = new Error(message);
12 err.name = 'Invariant Violation';
13 throw err;
14 }
15}
16class AppController {
17 constructor(executablePath, argv) {
18 this.state = {
19 appRunning: false,
20 proc: null,
21 pid: null,
22 };
23 this.executablePath = executablePath;
24 this.argv = argv;
25 }
26 stopApp() {
27 return (0, tslib_1.__awaiter)(this, void 0, void 0, function* () {
28 return new Promise((resolve) => {
29 if (this.state.appRunning) {
30 console.log('Sending SIGTERM signal to app...');
31 const { pid } = this.state;
32 const closeHandler = (code, signal) => {
33 this.setState({
34 appRunning: false,
35 proc: null,
36 pid: null,
37 });
38 resolve();
39 };
40 if ((0, platform_1.isWindows)()) {
41 (0, child_process_1.exec)('taskkill /pid ' + pid + ' /T /F').on('close', closeHandler);
42 }
43 else {
44 // pstree is used to kill the full subtree of a spawned app
45 (0, pstree_remy_1.default)(pid, (_, children) => {
46 if (pstree_remy_1.hasPS) {
47 // we now send SIGTERM to the spawned process
48 (0, child_process_1.spawn)('kill', ['-s', 'SIGTERM', pid].concat(children)).on('close', closeHandler);
49 }
50 else {
51 const pids = children.concat(pid).sort();
52 pids.forEach((childPid) => {
53 // 15 is for SIGTERM
54 (0, child_process_1.exec)('kill -15 ' + childPid).on('close', closeHandler);
55 });
56 }
57 });
58 }
59 }
60 else {
61 resolve();
62 }
63 });
64 });
65 }
66 runApp() {
67 invariant(!this.state.appRunning, "Can't start app when app is already running!");
68 // spawn the process
69 const proc = (0, child_process_1.spawn)('node', [this.executablePath, ...this.argv]);
70 // attach event listeners
71 proc.on('error', (e) => {
72 console.log(chalk_1.default.red('Failed to start app: ' + e.message));
73 this.setState({
74 appRunning: false,
75 proc: null,
76 pid: null,
77 });
78 });
79 proc.on('exit', (code, signal) => {
80 if (code !== null) {
81 console.log(code > 0
82 ? chalk_1.default.red('App exited with code ' + code + '.')
83 : chalk_1.default.green('App exited with code ' + code + '.'));
84 }
85 if (signal !== null) {
86 console.log(signal !== 'SIGTERM'
87 ? chalk_1.default.red('App killed with signal ' + signal + '.')
88 : chalk_1.default.green('App killed with signal SIGTERM.'));
89 }
90 this.setState({
91 appRunning: false,
92 proc: null,
93 pid: null,
94 });
95 });
96 // pipe spawned output stream to current process's output streams
97 proc.stdout.pipe(process.stdout);
98 proc.stderr.pipe(process.stderr);
99 if (proc.pid) {
100 console.log(chalk_1.default.green('App started!'));
101 this.setState({
102 proc,
103 pid: proc.pid.toString(),
104 appRunning: true,
105 });
106 }
107 }
108 setState(state) {
109 this.state = state;
110 }
111}
112exports.AppController = AppController;
113//# sourceMappingURL=processHandler.js.map
\No newline at end of file