Some cleanup
- Use whateverEmitter.event for the onWhatever methods. - Add readonly to a bunch of things. - Remove some redundancy in types. - Move initializations out of the constructor and into the declarations where it was reasonable to do so. - Disable a few no-any violations.
This commit is contained in:
parent
ddf96077a3
commit
588da0443c
@ -1,6 +1,5 @@
|
|||||||
import { Event } from "@coder/events";
|
|
||||||
import { field, logger, time, Time } from "@coder/logger";
|
import { field, logger, time, Time } from "@coder/logger";
|
||||||
import { InitData, ISharedProcessData } from "@coder/protocol";
|
import { ISharedProcessData } from "@coder/protocol";
|
||||||
import { retry } from "./retry";
|
import { retry } from "./retry";
|
||||||
import { upload } from "./upload";
|
import { upload } from "./upload";
|
||||||
import { client } from "./fill/client";
|
import { client } from "./fill/client";
|
||||||
@ -24,14 +23,16 @@ export abstract class IdeClient {
|
|||||||
private readonly tasks = <string[]>[];
|
private readonly tasks = <string[]>[];
|
||||||
private finishedTaskCount = 0;
|
private finishedTaskCount = 0;
|
||||||
private readonly loadTime: Time;
|
private readonly loadTime: Time;
|
||||||
private readonly sharedProcessDataPromise: Promise<ISharedProcessData>;
|
|
||||||
|
public readonly initData = client.initData;
|
||||||
|
public readonly sharedProcessData: Promise<ISharedProcessData>;
|
||||||
|
public readonly onSharedProcessActive = client.onSharedProcessActive;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
logger.info("Loading IDE");
|
logger.info("Loading IDE");
|
||||||
|
|
||||||
this.loadTime = time(2500);
|
this.loadTime = time(2500);
|
||||||
|
|
||||||
this.sharedProcessDataPromise = new Promise((resolve): void => {
|
this.sharedProcessData = new Promise((resolve): void => {
|
||||||
client.onSharedProcessActive(resolve);
|
client.onSharedProcessActive(resolve);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -96,27 +97,6 @@ export abstract class IdeClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A promise that resolves with initialization data.
|
|
||||||
*/
|
|
||||||
public get initData(): Promise<InitData> {
|
|
||||||
return client.initData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An event that fires every time the shared process (re-)starts.
|
|
||||||
*/
|
|
||||||
public get onSharedProcessActive(): Event<ISharedProcessData> {
|
|
||||||
return client.onSharedProcessActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A promise that resolves with *initial* shared process data.
|
|
||||||
*/
|
|
||||||
public get sharedProcessData(): Promise<ISharedProcessData> {
|
|
||||||
return this.sharedProcessDataPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set notificationService(service: INotificationService) {
|
public set notificationService(service: INotificationService) {
|
||||||
this.retry.notificationService = service;
|
this.retry.notificationService = service;
|
||||||
this.upload.notificationService = service;
|
this.upload.notificationService = service;
|
||||||
|
@ -9,36 +9,28 @@ import { retry } from "../retry";
|
|||||||
*/
|
*/
|
||||||
class Connection implements ReadWriteConnection {
|
class Connection implements ReadWriteConnection {
|
||||||
private activeSocket: WebSocket | undefined;
|
private activeSocket: WebSocket | undefined;
|
||||||
private readonly messageEmitter: Emitter<Uint8Array> = new Emitter();
|
private readonly messageBuffer = <Uint8Array[]>[];
|
||||||
private readonly closeEmitter: Emitter<void> = new Emitter();
|
private readonly socketTimeoutDelay = 60 * 1000;
|
||||||
private readonly upEmitter: Emitter<void> = new Emitter();
|
private readonly retryName = "Socket";
|
||||||
private readonly downEmitter: Emitter<void> = new Emitter();
|
|
||||||
private readonly messageBuffer: Uint8Array[] = [];
|
|
||||||
private socketTimeoutDelay = 60 * 1000;
|
|
||||||
private retryName = "Socket";
|
|
||||||
private isUp: boolean = false;
|
private isUp: boolean = false;
|
||||||
private closed: boolean = false;
|
private closed: boolean = false;
|
||||||
|
|
||||||
|
private readonly messageEmitter = new Emitter<Uint8Array>();
|
||||||
|
private readonly closeEmitter = new Emitter<void>();
|
||||||
|
private readonly upEmitter = new Emitter<void>();
|
||||||
|
private readonly downEmitter = new Emitter<void>();
|
||||||
|
|
||||||
|
public readonly onUp = this.upEmitter.event;
|
||||||
|
public readonly onClose = this.closeEmitter.event;
|
||||||
|
public readonly onDown = this.downEmitter.event;
|
||||||
|
public readonly onMessage = this.messageEmitter.event;
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
retry.register(this.retryName, () => this.connect());
|
retry.register(this.retryName, () => this.connect());
|
||||||
retry.block(this.retryName);
|
retry.block(this.retryName);
|
||||||
retry.run(this.retryName);
|
retry.run(this.retryName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a function to be called when the connection goes up.
|
|
||||||
*/
|
|
||||||
public onUp(cb: () => void): void {
|
|
||||||
this.upEmitter.event(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a function to be called when the connection goes down.
|
|
||||||
*/
|
|
||||||
public onDown(cb: () => void): void {
|
|
||||||
this.downEmitter.event(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public send(data: Buffer | Uint8Array): void {
|
public send(data: Buffer | Uint8Array): void {
|
||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
throw new Error("web socket is closed");
|
throw new Error("web socket is closed");
|
||||||
@ -50,14 +42,6 @@ class Connection implements ReadWriteConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public onMessage(cb: (data: Uint8Array | Buffer) => void): void {
|
|
||||||
this.messageEmitter.event(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public onClose(cb: () => void): void {
|
|
||||||
this.closeEmitter.event(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
public close(): void {
|
public close(): void {
|
||||||
this.closed = true;
|
this.closed = true;
|
||||||
this.dispose();
|
this.dispose();
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { IDisposable } from "@coder/disposable";
|
|
||||||
import { Emitter } from "@coder/events";
|
import { Emitter } from "@coder/events";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around the native clipboard with some fallbacks.
|
* Wrapper around the native clipboard with some fallbacks.
|
||||||
*/
|
*/
|
||||||
export class Clipboard {
|
export class Clipboard {
|
||||||
private readonly enableEmitter: Emitter<boolean> = new Emitter();
|
private readonly enableEmitter = new Emitter<boolean>();
|
||||||
|
public readonly onPermissionChange = this.enableEmitter.event;
|
||||||
private _isEnabled: boolean = false;
|
private _isEnabled: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,14 +70,6 @@ export class Clipboard {
|
|||||||
// tslint:enable no-any
|
// tslint:enable no-any
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a function to be called when the native clipboard is
|
|
||||||
* enabled/disabled.
|
|
||||||
*/
|
|
||||||
public onPermissionChange(cb: (enabled: boolean) => void): IDisposable {
|
|
||||||
return this.enableEmitter.event(cb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read text from the clipboard.
|
* Read text from the clipboard.
|
||||||
*/
|
*/
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { IDisposable } from "@coder/disposable";
|
|
||||||
import { Emitter } from "@coder/events";
|
import { Emitter } from "@coder/events";
|
||||||
|
|
||||||
import "./dialog.scss";
|
import "./dialog.scss";
|
||||||
@ -27,19 +26,16 @@ export enum IKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Dialog {
|
export class Dialog {
|
||||||
private options: IDialogOptions;
|
private readonly overlay: HTMLElement;
|
||||||
private overlay: HTMLElement;
|
|
||||||
private cachedActiveElement: HTMLElement | undefined;
|
private cachedActiveElement: HTMLElement | undefined;
|
||||||
private input: HTMLInputElement | undefined;
|
private input: HTMLInputElement | undefined;
|
||||||
private actionEmitter: Emitter<IDialogAction>;
|
|
||||||
private errors: HTMLElement;
|
private errors: HTMLElement;
|
||||||
private buttons: HTMLElement[] | undefined;
|
private buttons: HTMLElement[] | undefined;
|
||||||
|
|
||||||
public constructor(options: IDialogOptions) {
|
private actionEmitter = new Emitter<IDialogAction>();
|
||||||
this.options = options;
|
public onAction = this.actionEmitter.event;
|
||||||
|
|
||||||
this.actionEmitter = new Emitter();
|
|
||||||
|
|
||||||
|
public constructor(private readonly options: IDialogOptions) {
|
||||||
const msgBox = document.createElement("div");
|
const msgBox = document.createElement("div");
|
||||||
msgBox.classList.add("msgbox");
|
msgBox.classList.add("msgbox");
|
||||||
|
|
||||||
@ -108,13 +104,6 @@ export class Dialog {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a function to be called when the user performs an action.
|
|
||||||
*/
|
|
||||||
public onAction(callback: (action: IDialogAction) => void): IDisposable {
|
|
||||||
return this.actionEmitter.event(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input value if this dialog has an input.
|
* Input value if this dialog has an input.
|
||||||
*/
|
*/
|
||||||
|
@ -13,7 +13,7 @@ class OS {
|
|||||||
|
|
||||||
public homedir(): string {
|
public homedir(): string {
|
||||||
if (typeof this._homedir === "undefined") {
|
if (typeof this._homedir === "undefined") {
|
||||||
throw new Error("not initialized");
|
throw new Error("trying to access homedir before it has been set");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._homedir;
|
return this._homedir;
|
||||||
@ -21,7 +21,7 @@ class OS {
|
|||||||
|
|
||||||
public tmpdir(): string {
|
public tmpdir(): string {
|
||||||
if (typeof this._tmpdir === "undefined") {
|
if (typeof this._tmpdir === "undefined") {
|
||||||
throw new Error("not initialized");
|
throw new Error("trying to access tmpdir before it has been set");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._tmpdir;
|
return this._tmpdir;
|
||||||
|
@ -21,7 +21,7 @@ interface IRetryItem {
|
|||||||
* to the user explaining what is happening with an option to immediately retry.
|
* to the user explaining what is happening with an option to immediately retry.
|
||||||
*/
|
*/
|
||||||
export class Retry {
|
export class Retry {
|
||||||
private items: Map<string, IRetryItem>;
|
private items = new Map<string, IRetryItem>();
|
||||||
|
|
||||||
// Times are in seconds.
|
// Times are in seconds.
|
||||||
private readonly retryMinDelay = 1;
|
private readonly retryMinDelay = 1;
|
||||||
@ -31,17 +31,15 @@ export class Retry {
|
|||||||
private blocked: string | boolean | undefined;
|
private blocked: string | boolean | undefined;
|
||||||
|
|
||||||
private notificationHandle: INotificationHandle | undefined;
|
private notificationHandle: INotificationHandle | undefined;
|
||||||
private updateDelay = 1;
|
private readonly updateDelay = 1;
|
||||||
private updateTimeout: number | NodeJS.Timer | undefined;
|
private updateTimeout: number | NodeJS.Timer | undefined;
|
||||||
private notificationThreshold = 3;
|
private readonly notificationThreshold = 3;
|
||||||
|
|
||||||
// Time in milliseconds to wait before restarting a service. (See usage below
|
// Time in milliseconds to wait before restarting a service. (See usage below
|
||||||
// for reasoning.)
|
// for reasoning.)
|
||||||
private waitDelay = 50;
|
private readonly waitDelay = 50;
|
||||||
|
|
||||||
public constructor(private _notificationService: INotificationService) {
|
public constructor(private _notificationService: INotificationService) {}
|
||||||
this.items = new Map();
|
|
||||||
}
|
|
||||||
|
|
||||||
public set notificationService(service: INotificationService) {
|
public set notificationService(service: INotificationService) {
|
||||||
this._notificationService = service;
|
this._notificationService = service;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { appendFile } from "fs";
|
import { appendFile } from "fs";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
import { logger, Logger } from "@coder/logger";
|
import { logger } from "@coder/logger";
|
||||||
import { escapePath } from "@coder/protocol";
|
import { escapePath } from "@coder/protocol";
|
||||||
import { NotificationService, INotificationService, ProgressService, IProgressService, IProgress, Severity } from "./fill/notification";
|
import { NotificationService, INotificationService, ProgressService, IProgressService, IProgress, Severity } from "./fill/notification";
|
||||||
|
|
||||||
@ -40,27 +40,20 @@ export class Upload {
|
|||||||
private readonly maxParallelUploads = 100;
|
private readonly maxParallelUploads = 100;
|
||||||
private readonly readSize = 32000; // ~32kb max while reading in the file.
|
private readonly readSize = 32000; // ~32kb max while reading in the file.
|
||||||
private readonly packetSize = 32000; // ~32kb max when writing.
|
private readonly packetSize = 32000; // ~32kb max when writing.
|
||||||
private readonly logger: Logger;
|
private readonly logger = logger.named("Upload");
|
||||||
private readonly currentlyUploadingFiles: Map<string, File>;
|
private readonly currentlyUploadingFiles = new Map<string, File>();
|
||||||
private readonly queueByDirectory: Map<string, IUploadableDirectory>;
|
private readonly queueByDirectory = new Map<string, IUploadableDirectory>();
|
||||||
private progress: IProgress | undefined;
|
private progress: IProgress | undefined;
|
||||||
private uploadPromise: Promise<string[]> | undefined;
|
private uploadPromise: Promise<string[]> | undefined;
|
||||||
private resolveUploadPromise: (() => void) | undefined;
|
private resolveUploadPromise: (() => void) | undefined;
|
||||||
private finished: number;
|
private finished = 0;
|
||||||
private uploadedFilePaths: string[];
|
private uploadedFilePaths = <string[]>[];
|
||||||
private total: number;
|
private total = 0;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private _notificationService: INotificationService,
|
private _notificationService: INotificationService,
|
||||||
private _progressService: IProgressService,
|
private _progressService: IProgressService,
|
||||||
) {
|
) {}
|
||||||
this.logger = logger.named("Upload");
|
|
||||||
this.currentlyUploadingFiles = new Map();
|
|
||||||
this.queueByDirectory = new Map();
|
|
||||||
this.uploadedFilePaths = [];
|
|
||||||
this.finished = 0;
|
|
||||||
this.total = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public set notificationService(service: INotificationService) {
|
public set notificationService(service: INotificationService) {
|
||||||
this._notificationService = service;
|
this._notificationService = service;
|
||||||
|
@ -113,8 +113,8 @@ const hashStringToColor = (str: string): string => {
|
|||||||
* currently built items and appends to that.
|
* currently built items and appends to that.
|
||||||
*/
|
*/
|
||||||
export abstract class Formatter {
|
export abstract class Formatter {
|
||||||
protected format: string = "";
|
protected format = "";
|
||||||
protected args: string[] = [];
|
protected args = <string[]>[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a tag.
|
* Add a tag.
|
||||||
@ -250,14 +250,13 @@ export class Logger {
|
|||||||
public level = Level.Info;
|
public level = Level.Info;
|
||||||
|
|
||||||
private readonly nameColor?: string;
|
private readonly nameColor?: string;
|
||||||
private muted: boolean;
|
private muted: boolean = false;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private _formatter: Formatter,
|
private _formatter: Formatter,
|
||||||
private readonly name?: string,
|
private readonly name?: string,
|
||||||
private readonly defaultFields?: FieldArray,
|
private readonly defaultFields?: FieldArray,
|
||||||
) {
|
) {
|
||||||
this.muted = false;
|
|
||||||
if (name) {
|
if (name) {
|
||||||
this.nameColor = hashStringToColor(name);
|
this.nameColor = hashStringToColor(name);
|
||||||
}
|
}
|
||||||
@ -388,10 +387,6 @@ export class Logger {
|
|||||||
times = fields.filter((f) => f.value instanceof Time);
|
times = fields.filter((f) => f.value instanceof Time);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format is:
|
|
||||||
// [TAG] [NAME?] MESSAGE TIME?
|
|
||||||
// field1 (type)?: value
|
|
||||||
// field2 (type)?: value
|
|
||||||
this._formatter.tag(options.type.toUpperCase(), options.tagColor);
|
this._formatter.tag(options.type.toUpperCase(), options.tagColor);
|
||||||
if (this.name && this.nameColor) {
|
if (this.name && this.nameColor) {
|
||||||
this._formatter.tag(this.name.toUpperCase(), this.nameColor);
|
this._formatter.tag(this.name.toUpperCase(), this.nameColor);
|
||||||
|
@ -9,27 +9,28 @@ import { EventEmitter } from "events";
|
|||||||
* Client accepts an arbitrary connection intended to communicate with the Server.
|
* Client accepts an arbitrary connection intended to communicate with the Server.
|
||||||
*/
|
*/
|
||||||
export class Client {
|
export class Client {
|
||||||
public Socket: typeof ServerSocket;
|
public readonly Socket: typeof ServerSocket;
|
||||||
|
|
||||||
private evalId: number = 0;
|
private evalId = 0;
|
||||||
private evalDoneEmitter: Emitter<EvalDoneMessage> = new Emitter();
|
private readonly evalDoneEmitter = new Emitter<EvalDoneMessage>();
|
||||||
private evalFailedEmitter: Emitter<EvalFailedMessage> = new Emitter();
|
private readonly evalFailedEmitter = new Emitter<EvalFailedMessage>();
|
||||||
private evalEventEmitter: Emitter<EvalEventMessage> = new Emitter();
|
private readonly evalEventEmitter = new Emitter<EvalEventMessage>();
|
||||||
|
|
||||||
private sessionId: number = 0;
|
private sessionId = 0;
|
||||||
private readonly sessions: Map<number, ServerProcess> = new Map();
|
private readonly sessions = new Map<number, ServerProcess>();
|
||||||
|
|
||||||
private connectionId: number = 0;
|
private connectionId = 0;
|
||||||
private readonly connections: Map<number, ServerSocket> = new Map();
|
private readonly connections = new Map<number, ServerSocket>();
|
||||||
|
|
||||||
private serverId: number = 0;
|
private serverId = 0;
|
||||||
private readonly servers: Map<number, ServerListener> = new Map();
|
private readonly servers = new Map<number, ServerListener>();
|
||||||
|
|
||||||
private _initData: InitData | undefined;
|
private _initData: InitData | undefined;
|
||||||
private initDataEmitter = new Emitter<InitData>();
|
private readonly initDataEmitter = new Emitter<InitData>();
|
||||||
private initDataPromise: Promise<InitData>;
|
private readonly initDataPromise: Promise<InitData>;
|
||||||
|
|
||||||
private sharedProcessActiveEmitter = new Emitter<ISharedProcessData>();
|
private readonly sharedProcessActiveEmitter = new Emitter<ISharedProcessData>();
|
||||||
|
public readonly onSharedProcessActive = this.sharedProcessActiveEmitter.event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param connection Established connection to the server
|
* @param connection Established connection to the server
|
||||||
@ -63,10 +64,6 @@ export class Client {
|
|||||||
return this.initDataPromise;
|
return this.initDataPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
public get onSharedProcessActive(): Event<ISharedProcessData> {
|
|
||||||
return this.sharedProcessActiveEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
public run(func: (ae: ActiveEval) => void | Promise<void>): ActiveEval;
|
public run(func: (ae: ActiveEval) => void | Promise<void>): ActiveEval;
|
||||||
public run<T1>(func: (ae: ActiveEval, a1: T1) => void | Promise<void>, a1: T1): ActiveEval;
|
public run<T1>(func: (ae: ActiveEval, a1: T1) => void | Promise<void>, a1: T1): ActiveEval;
|
||||||
public run<T1, T2>(func: (ae: ActiveEval, a1: T1, a2: T2) => void | Promise<void>, a1: T1, a2: T2): ActiveEval;
|
public run<T1, T2>(func: (ae: ActiveEval, a1: T1, a2: T2) => void | Promise<void>, a1: T1, a2: T2): ActiveEval;
|
||||||
@ -95,8 +92,8 @@ export class Client {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
on: (event: string, cb: (...args: any[]) => void) => eventEmitter.on(event, cb),
|
on: (event: string, cb: (...args: any[]) => void): EventEmitter => eventEmitter.on(event, cb),
|
||||||
emit: (event: string, ...args: any[]) => {
|
emit: (event: string, ...args: any[]): void => {
|
||||||
const eventsMsg = new EvalEventMessage();
|
const eventsMsg = new EvalEventMessage();
|
||||||
eventsMsg.setId(doEval.id);
|
eventsMsg.setId(doEval.id);
|
||||||
eventsMsg.setEvent(event);
|
eventsMsg.setEvent(event);
|
||||||
|
@ -20,12 +20,12 @@ export interface ServerOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Server {
|
export class Server {
|
||||||
private readonly sessions: Map<number, Process> = new Map();
|
private readonly sessions = new Map<number, Process>();
|
||||||
private readonly connections: Map<number, net.Socket> = new Map();
|
private readonly connections = new Map<number, net.Socket>();
|
||||||
private readonly servers: Map<number, net.Server> = new Map();
|
private readonly servers = new Map<number, net.Server>();
|
||||||
private readonly evals: Map<number, ActiveEvaluation> = new Map();
|
private readonly evals = new Map<number, ActiveEvaluation>();
|
||||||
|
|
||||||
private connectionId: number = Number.MAX_SAFE_INTEGER;
|
private connectionId = Number.MAX_SAFE_INTEGER;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly connection: ReadWriteConnection,
|
private readonly connection: ReadWriteConnection,
|
||||||
|
@ -3,7 +3,7 @@ import { ChildProcess } from "child_process";
|
|||||||
|
|
||||||
export interface IpcMessage {
|
export interface IpcMessage {
|
||||||
readonly event: string;
|
readonly event: string;
|
||||||
readonly args: any[];
|
readonly args: any[]; // tslint:disable-line no-any
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StdioIpcHandler extends EventEmitter {
|
export class StdioIpcHandler extends EventEmitter {
|
||||||
@ -15,21 +15,28 @@ export class StdioIpcHandler extends EventEmitter {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line no-any
|
||||||
public on(event: string, cb: (...args: any[]) => void): this {
|
public on(event: string, cb: (...args: any[]) => void): this {
|
||||||
this.listen();
|
this.listen();
|
||||||
|
|
||||||
return super.on(event, cb);
|
return super.on(event, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line no-any
|
||||||
public once(event: string, cb: (...args: any[]) => void): this {
|
public once(event: string, cb: (...args: any[]) => void): this {
|
||||||
this.listen();
|
this.listen();
|
||||||
|
|
||||||
return super.once(event, cb);
|
return super.once(event, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line no-any
|
||||||
public addListener(event: string, cb: (...args: any[]) => void): this {
|
public addListener(event: string, cb: (...args: any[]) => void): this {
|
||||||
this.listen();
|
this.listen();
|
||||||
|
|
||||||
return super.addListener(event, cb);
|
return super.addListener(event, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tslint:disable-next-line no-any
|
||||||
public send(event: string, ...args: any[]): void {
|
public send(event: string, ...args: any[]): void {
|
||||||
const msg: IpcMessage = {
|
const msg: IpcMessage = {
|
||||||
event,
|
event,
|
||||||
@ -47,7 +54,8 @@ export class StdioIpcHandler extends EventEmitter {
|
|||||||
if (this.isListening) {
|
if (this.isListening) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const onData = (data: any) => {
|
// tslint:disable-next-line no-any
|
||||||
|
const onData = (data: any): void => {
|
||||||
try {
|
try {
|
||||||
const d = JSON.parse(data.toString()) as IpcMessage;
|
const d = JSON.parse(data.toString()) as IpcMessage;
|
||||||
this.emit(d.event, ...d.args);
|
this.emit(d.event, ...d.args);
|
||||||
|
@ -26,20 +26,16 @@ export class SharedProcess {
|
|||||||
private _state: SharedProcessState = SharedProcessState.Stopped;
|
private _state: SharedProcessState = SharedProcessState.Stopped;
|
||||||
private activeProcess: ChildProcess | undefined;
|
private activeProcess: ChildProcess | undefined;
|
||||||
private ipcHandler: StdioIpcHandler | undefined;
|
private ipcHandler: StdioIpcHandler | undefined;
|
||||||
private readonly onStateEmitter: Emitter<SharedProcessEvent>;
|
private readonly onStateEmitter = new Emitter<SharedProcessEvent>();
|
||||||
|
public readonly onState = this.onStateEmitter.event;
|
||||||
|
|
||||||
public constructor(
|
public constructor(
|
||||||
private readonly userDataDir: string,
|
private readonly userDataDir: string,
|
||||||
private readonly builtInExtensionsDir: string,
|
private readonly builtInExtensionsDir: string,
|
||||||
) {
|
) {
|
||||||
this.onStateEmitter = new Emitter();
|
|
||||||
this.restart();
|
this.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get onState(): Event<SharedProcessEvent> {
|
|
||||||
return this.onStateEmitter.event;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get state(): SharedProcessState {
|
public get state(): SharedProcessState {
|
||||||
return this._state;
|
return this._state;
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,10 @@ type nodePtyType = typeof nodePty;
|
|||||||
* Implementation of nodePty for the browser.
|
* Implementation of nodePty for the browser.
|
||||||
*/
|
*/
|
||||||
class Pty implements nodePty.IPty {
|
class Pty implements nodePty.IPty {
|
||||||
private readonly emitter: EventEmitter;
|
private readonly emitter = new EventEmitter();
|
||||||
private readonly cp: ChildProcess;
|
private readonly cp: ChildProcess;
|
||||||
|
|
||||||
public constructor(file: string, args: string[] | string, options: nodePty.IPtyForkOptions) {
|
public constructor(file: string, args: string[] | string, options: nodePty.IPtyForkOptions) {
|
||||||
this.emitter = new EventEmitter();
|
|
||||||
this.cp = client.spawn(file, Array.isArray(args) ? args : [args], {
|
this.cp = client.spawn(file, Array.isArray(args) ? args : [args], {
|
||||||
...options,
|
...options,
|
||||||
tty: {
|
tty: {
|
||||||
@ -38,7 +37,8 @@ class Pty implements nodePty.IPty {
|
|||||||
return this.cp.title!;
|
return this.cp.title!;
|
||||||
}
|
}
|
||||||
|
|
||||||
public on(event: string, listener: (...args) => void): void {
|
// tslint:disable-next-line no-any
|
||||||
|
public on(event: string, listener: (...args: any[]) => void): void {
|
||||||
this.emitter.on(event, listener);
|
this.emitter.on(event, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,13 @@ import { IpcRenderer } from "electron";
|
|||||||
export * from "@coder/ide/src/fill/electron";
|
export * from "@coder/ide/src/fill/electron";
|
||||||
|
|
||||||
class StdioIpcRenderer extends StdioIpcHandler implements IpcRenderer {
|
class StdioIpcRenderer extends StdioIpcHandler implements IpcRenderer {
|
||||||
public sendTo(windowId: number, channel: string, ...args: any[]): void {
|
// tslint:disable-next-line no-any
|
||||||
|
public sendTo(_windowId: number, _channel: string, ..._args: any[]): void {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendToHost(channel: string, ...args: any[]): void {
|
// tslint:disable-next-line no-any
|
||||||
|
public sendToHost(_channel: string, ..._args: any[]): void {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import { logger, field } from "@coder/logger";
|
|||||||
|
|
||||||
class StorageDatabase implements workspaceStorage.IStorageDatabase {
|
class StorageDatabase implements workspaceStorage.IStorageDatabase {
|
||||||
public readonly onDidChangeItemsExternal = Event.None;
|
public readonly onDidChangeItemsExternal = Event.None;
|
||||||
private items = new Map<string, string>();
|
private readonly items = new Map<string, string>();
|
||||||
private fetched: boolean = false;
|
private fetched: boolean = false;
|
||||||
|
|
||||||
public constructor(private readonly path: string) {
|
public constructor(private readonly path: string) {
|
||||||
|
@ -17,21 +17,21 @@ class WindowsService implements IWindowsService {
|
|||||||
// tslint:disable-next-line no-any
|
// tslint:disable-next-line no-any
|
||||||
public _serviceBrand: any;
|
public _serviceBrand: any;
|
||||||
|
|
||||||
private openEmitter = new Emitter<number>();
|
private readonly openEmitter = new Emitter<number>();
|
||||||
private focusEmitter = new Emitter<number>();
|
private readonly focusEmitter = new Emitter<number>();
|
||||||
private blurEmitter = new Emitter<number>();
|
private readonly blurEmitter = new Emitter<number>();
|
||||||
private maximizeEmitter = new Emitter<number>();
|
private readonly maximizeEmitter = new Emitter<number>();
|
||||||
private unmaximizeEmitter = new Emitter<number>();
|
private readonly unmaximizeEmitter = new Emitter<number>();
|
||||||
private recentlyOpenedChangeEmitter = new Emitter<void>();
|
private readonly recentlyOpenedChangeEmitter = new Emitter<void>();
|
||||||
|
|
||||||
public onWindowOpen = this.openEmitter.event;
|
public readonly onWindowOpen = this.openEmitter.event;
|
||||||
public onWindowFocus = this.focusEmitter.event;
|
public readonly onWindowFocus = this.focusEmitter.event;
|
||||||
public onWindowBlur = this.blurEmitter.event;
|
public readonly onWindowBlur = this.blurEmitter.event;
|
||||||
public onWindowMaximize = this.maximizeEmitter.event;
|
public readonly onWindowMaximize = this.maximizeEmitter.event;
|
||||||
public onWindowUnmaximize = this.unmaximizeEmitter.event;
|
public readonly onWindowUnmaximize = this.unmaximizeEmitter.event;
|
||||||
public onRecentlyOpenedChange = this.recentlyOpenedChangeEmitter.event;
|
public readonly onRecentlyOpenedChange = this.recentlyOpenedChangeEmitter.event;
|
||||||
|
|
||||||
private window = new electron.BrowserWindow();
|
private readonly window = new electron.BrowserWindow();
|
||||||
|
|
||||||
// Dialogs
|
// Dialogs
|
||||||
public pickFileFolderAndOpen(_options: INativeOpenDialogOptions): Promise<void> {
|
public pickFileFolderAndOpen(_options: INativeOpenDialogOptions): Promise<void> {
|
||||||
|
Reference in New Issue
Block a user