UNPKG

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