2019-01-28 17:14:06 +00:00
|
|
|
import { client } from "@coder/ide/src/fill/client";
|
2019-01-08 00:46:19 +00:00
|
|
|
import { EventEmitter } from "events";
|
|
|
|
import * as nodePty from "node-pty";
|
2019-02-22 21:56:29 +00:00
|
|
|
import { ActiveEvalHelper } from "@coder/protocol";
|
2019-01-08 00:46:19 +00:00
|
|
|
|
2019-02-19 16:17:03 +00:00
|
|
|
// Use this to prevent Webpack from hijacking require.
|
|
|
|
declare var __non_webpack_require__: typeof require;
|
2019-01-08 00:46:19 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of nodePty for the browser.
|
|
|
|
*/
|
|
|
|
class Pty implements nodePty.IPty {
|
2019-02-06 17:53:23 +00:00
|
|
|
private readonly emitter = new EventEmitter();
|
2019-02-22 21:56:29 +00:00
|
|
|
private readonly ae: ActiveEvalHelper;
|
2019-02-19 16:17:03 +00:00
|
|
|
private _pid = -1;
|
|
|
|
private _process = "";
|
2019-01-08 00:46:19 +00:00
|
|
|
|
|
|
|
public constructor(file: string, args: string[] | string, options: nodePty.IPtyForkOptions) {
|
2019-02-19 16:17:03 +00:00
|
|
|
this.ae = client.run((ae, file, args, options) => {
|
|
|
|
const nodePty = __non_webpack_require__("node-pty") as typeof import("node-pty");
|
|
|
|
|
2019-02-22 21:56:29 +00:00
|
|
|
ae.preserveEnv(options);
|
2019-02-19 16:17:03 +00:00
|
|
|
|
|
|
|
const ptyProc = nodePty.spawn(file, args, options);
|
|
|
|
|
|
|
|
let process = ptyProc.process;
|
|
|
|
ae.emit("process", process);
|
|
|
|
ae.emit("pid", ptyProc.pid);
|
|
|
|
|
|
|
|
const timer = setInterval(() => {
|
|
|
|
if (ptyProc.process !== process) {
|
|
|
|
process = ptyProc.process;
|
|
|
|
ae.emit("process", process);
|
|
|
|
}
|
|
|
|
}, 200);
|
|
|
|
|
|
|
|
ptyProc.on("exit", (code, signal) => {
|
|
|
|
clearTimeout(timer);
|
|
|
|
ae.emit("exit", code, signal);
|
|
|
|
});
|
|
|
|
|
|
|
|
ptyProc.on("data", (data) => ae.emit("data", data));
|
|
|
|
|
2019-02-19 21:30:56 +00:00
|
|
|
ae.on("resize", (cols: number, rows: number) => ptyProc.resize(cols, rows));
|
|
|
|
ae.on("write", (data: string) => ptyProc.write(data));
|
|
|
|
ae.on("kill", (signal: string) => ptyProc.kill(signal));
|
2019-02-19 16:17:03 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
onDidDispose: (cb): void => ptyProc.on("exit", cb),
|
|
|
|
dispose: (): void => {
|
|
|
|
ptyProc.kill();
|
|
|
|
setTimeout(() => ptyProc.kill("SIGKILL"), 5000); // Double tap.
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}, file, args, options);
|
|
|
|
|
|
|
|
this.ae.on("pid", (pid) => this._pid = pid);
|
|
|
|
this.ae.on("process", (process) => this._process = process);
|
|
|
|
|
|
|
|
this.ae.on("exit", (code, signal) => this.emitter.emit("exit", code, signal));
|
|
|
|
this.ae.on("data", (data) => this.emitter.emit("data", data));
|
2019-01-08 00:46:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public get pid(): number {
|
2019-02-19 16:17:03 +00:00
|
|
|
return this._pid;
|
2019-01-08 00:46:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public get process(): string {
|
2019-02-19 16:17:03 +00:00
|
|
|
return this._process;
|
2019-01-08 00:46:19 +00:00
|
|
|
}
|
|
|
|
|
2019-02-06 17:53:23 +00:00
|
|
|
// tslint:disable-next-line no-any
|
|
|
|
public on(event: string, listener: (...args: any[]) => void): void {
|
2019-01-08 00:46:19 +00:00
|
|
|
this.emitter.on(event, listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
public resize(columns: number, rows: number): void {
|
2019-02-19 16:17:03 +00:00
|
|
|
this.ae.emit("resize", columns, rows);
|
2019-01-08 00:46:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public write(data: string): void {
|
2019-02-19 16:17:03 +00:00
|
|
|
this.ae.emit("write", data);
|
2019-01-08 00:46:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public kill(signal?: string): void {
|
2019-02-19 16:17:03 +00:00
|
|
|
this.ae.emit("kill", signal);
|
2019-01-08 00:46:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-19 16:17:03 +00:00
|
|
|
const ptyType: typeof nodePty = {
|
2019-01-08 00:46:19 +00:00
|
|
|
spawn: (file: string, args: string[] | string, options: nodePty.IPtyForkOptions): nodePty.IPty => {
|
|
|
|
return new Pty(file, args, options);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-01-28 17:14:06 +00:00
|
|
|
module.exports = ptyType;
|