Skip to content

Commit 520aca5

Browse files
code-asherkylecarbs
authored andcommitted
Extension host (#20)
* Implement net.Server * Move Socket class into Client This way we don't need to expose anything. * Remove some unused imports * Pass environment variables to bootstrap fork * Add debug log for when socket disconnects from server * Use VSCODE_ALLOW_IO for shared process only * Extension host can send messages now * Support callback for logging This lets us do potentially expensive operations which will only be performed if the log level is sufficiently low. * Stop extension host from committing suicide * Blank line * Add static serve (#21) * Add extension URLs * how did i remove this * Fix writing an empty string * Implement dialogs on window service
1 parent cb61901 commit 520aca5

27 files changed

+431
-793
lines changed

packages/ide/src/fill/dialog.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ export class Dialog {
8888
if (this.options.buttons && this.options.buttons.length > 0) {
8989
this.buttons = this.options.buttons.map((buttonText, buttonIndex) => {
9090
const button = document.createElement("button");
91-
button.innerText = buttonText;
91+
// TODO: support mnemonics.
92+
button.innerText = buttonText.replace("_", "");
9293
button.addEventListener("click", () => {
9394
this.actionEmitter.emit({
9495
buttonIndex,

packages/logger/src/logger.ts

+64-41
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ export class Time {
4242

4343
}
4444

45-
export type FieldArray = Array<Field<any>>; // tslint:disable-line no-any
45+
// tslint:disable-next-line no-any
46+
export type FieldArray = Array<Field<any>>;
47+
48+
// Functions can be used to remove the need to perform operations when the
49+
// logging level won't output the result anyway.
50+
export type LogCallback = () => [string, ...FieldArray];
4651

4752
/**
4853
* Creates a time field
@@ -127,6 +132,7 @@ export abstract class Formatter {
127132
public abstract push(arg: string, color?: string, weight?: string): void;
128133
public abstract push(arg: any): void; // tslint:disable-line no-any
129134

135+
// tslint:disable-next-line no-any
130136
public abstract fields(fields: Array<Field<any>>): void;
131137

132138
/**
@@ -184,7 +190,9 @@ export class BrowserFormatter extends Formatter {
184190
this.args.push(arg);
185191
}
186192

193+
// tslint:disable-next-line no-any
187194
public fields(fields: Array<Field<any>>): void {
195+
// tslint:disable-next-line no-console
188196
console.groupCollapsed(...this.flush());
189197
fields.forEach((field) => {
190198
this.push(field.identifier, "#3794ff", "bold");
@@ -193,8 +201,10 @@ export class BrowserFormatter extends Formatter {
193201
}
194202
this.push(": ");
195203
this.push(field.value);
204+
// tslint:disable-next-line no-console
196205
console.log(...this.flush());
197206
});
207+
// tslint:disable-next-line no-console
198208
console.groupEnd();
199209
}
200210

@@ -229,8 +239,10 @@ export class ServerFormatter extends Formatter {
229239
this.args.push(arg);
230240
}
231241

242+
// tslint:disable-next-line no-any
232243
public fields(fields: Array<Field<any>>): void {
233-
const obj = {} as any;
244+
// tslint:disable-next-line no-any
245+
const obj: { [key: string]: any} = {};
234246
this.format += "\u001B[38;2;140;140;140m";
235247
fields.forEach((field) => {
236248
obj[field.identifier] = field.value;
@@ -284,57 +296,61 @@ export class Logger {
284296
/**
285297
* Outputs information.
286298
*/
287-
public info(msg: string, ...fields: FieldArray): void {
288-
if (this.level <= Level.Info) {
289-
this.handle({
290-
type: "info",
291-
message: msg,
292-
fields,
293-
tagColor: "#008FBF",
294-
});
295-
}
299+
public info(fn: LogCallback): void;
300+
public info(message: string, ...fields: FieldArray): void;
301+
public info(message: LogCallback | string, ...fields: FieldArray): void {
302+
this.handle({
303+
type: "info",
304+
message,
305+
fields,
306+
tagColor: "#008FBF",
307+
level: Level.Info,
308+
});
296309
}
297310

298311
/**
299312
* Outputs a warning.
300313
*/
301-
public warn(msg: string, ...fields: FieldArray): void {
302-
if (this.level <= Level.Warn) {
303-
this.handle({
304-
type: "warn",
305-
message: msg,
306-
fields,
307-
tagColor: "#FF9D00",
308-
});
309-
}
314+
public warn(fn: LogCallback): void;
315+
public warn(message: string, ...fields: FieldArray): void;
316+
public warn(message: LogCallback | string, ...fields: FieldArray): void {
317+
this.handle({
318+
type: "warn",
319+
message,
320+
fields,
321+
tagColor: "#FF9D00",
322+
level: Level.Warn,
323+
});
310324
}
311325

312326
/**
313327
* Outputs a debug message.
314328
*/
315-
public debug(msg: string, ...fields: FieldArray): void {
316-
if (this.level <= Level.Debug) {
317-
this.handle({
318-
type: "debug",
319-
message: msg,
320-
fields,
321-
tagColor: "#84009E",
322-
});
323-
}
329+
public debug(fn: LogCallback): void;
330+
public debug(message: string, ...fields: FieldArray): void;
331+
public debug(message: LogCallback | string, ...fields: FieldArray): void {
332+
this.handle({
333+
type: "debug",
334+
message,
335+
fields,
336+
tagColor: "#84009E",
337+
level: Level.Debug,
338+
});
324339
}
325340

326341
/**
327342
* Outputs an error.
328343
*/
329-
public error(msg: string, ...fields: FieldArray): void {
330-
if (this.level <= Level.Error) {
331-
this.handle({
332-
type: "error",
333-
message: msg,
334-
fields,
335-
tagColor: "#B00000",
336-
});
337-
}
344+
public error(fn: LogCallback): void;
345+
public error(message: string, ...fields: FieldArray): void;
346+
public error(message: LogCallback | string, ...fields: FieldArray): void {
347+
this.handle({
348+
type: "error",
349+
message,
350+
fields,
351+
tagColor: "#B00000",
352+
level: Level.Error,
353+
});
338354
}
339355

340356
/**
@@ -355,15 +371,22 @@ export class Logger {
355371
*/
356372
private handle(options: {
357373
type: "info" | "warn" | "debug" | "error";
358-
message: string;
374+
message: string | LogCallback;
359375
fields?: FieldArray;
376+
level: Level;
360377
tagColor: string;
361378
}): void {
362-
if (this.muted) {
379+
if (this.level > options.level || this.muted) {
363380
return;
364381
}
365382

366-
const passedFields = options.fields || [];
383+
let passedFields = options.fields || [];
384+
if (typeof options.message === "function") {
385+
const values = options.message();
386+
options.message = values.shift() as string;
387+
passedFields = values as FieldArray;
388+
}
389+
367390
const fields = this.defaultFields
368391
? passedFields.concat(this.defaultFields)
369392
: passedFields;

packages/protocol/src/browser/client.ts

+37-25
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { ReadWriteConnection, InitData, OperatingSystem, ISharedProcessData } from "../common/connection";
2-
import { NewEvalMessage, ServerMessage, EvalDoneMessage, EvalFailedMessage, TypedValue, ClientMessage, NewSessionMessage, TTYDimensions, SessionOutputMessage, CloseSessionInputMessage, WorkingInitMessage, NewConnectionMessage, NewServerMessage } from "../proto";
2+
import { NewEvalMessage, ServerMessage, EvalDoneMessage, EvalFailedMessage, TypedValue, ClientMessage, NewSessionMessage, TTYDimensions, SessionOutputMessage, CloseSessionInputMessage, WorkingInitMessage } from "../proto";
33
import { Emitter, Event } from "@coder/events";
44
import { logger, field } from "@coder/logger";
5-
import { ChildProcess, SpawnOptions, ServerProcess, ServerSocket, Socket, ServerListener, Server } from "./command";
5+
import { ChildProcess, SpawnOptions, ForkOptions, ServerProcess, ServerSocket, Socket, ServerListener, Server } from "./command";
66

77
/**
88
* Client accepts an arbitrary connection intended to communicate with the Server.
99
*/
1010
export class Client {
11+
12+
public Socket: typeof ServerSocket;
13+
1114
private evalId: number = 0;
1215
private evalDoneEmitter: Emitter<EvalDoneMessage> = new Emitter();
1316
private evalFailedEmitter: Emitter<EvalFailedMessage> = new Emitter();
@@ -41,6 +44,15 @@ export class Client {
4144
}
4245
});
4346

47+
const that = this;
48+
this.Socket = class extends ServerSocket {
49+
50+
public constructor() {
51+
super(that.connection, that.connectionId++, that.registerConnection);
52+
}
53+
54+
};
55+
4456
this.initDataPromise = new Promise((resolve): void => {
4557
this.initDataEmitter.event(resolve);
4658
});
@@ -77,7 +89,7 @@ export class Client {
7789
const newEval = new NewEvalMessage();
7890
const id = this.evalId++;
7991
newEval.setId(id);
80-
newEval.setArgsList([a1, a2, a3, a4, a5, a6].filter(a => a).map(a => JSON.stringify(a)));
92+
newEval.setArgsList([a1, a2, a3, a4, a5, a6].filter(a => typeof a !== "undefined").map(a => JSON.stringify(a)));
8193
newEval.setFunction(func.toString());
8294

8395
const clientMsg = new ClientMessage();
@@ -158,7 +170,7 @@ export class Client {
158170
* @param args Args to add for the module
159171
* @param options Options to execute
160172
*/
161-
public fork(modulePath: string, args: string[] = [], options?: SpawnOptions): ChildProcess {
173+
public fork(modulePath: string, args: string[] = [], options?: ForkOptions): ChildProcess {
162174
return this.doSpawn(modulePath, args, options, true);
163175
}
164176

@@ -167,27 +179,17 @@ export class Client {
167179
* Forks a module from bootstrap-fork
168180
* @param modulePath Path of the module
169181
*/
170-
public bootstrapFork(modulePath: string): ChildProcess {
171-
return this.doSpawn(modulePath, [], undefined, true, true);
182+
public bootstrapFork(modulePath: string, args: string[] = [], options?: ForkOptions): ChildProcess {
183+
return this.doSpawn(modulePath, args, options, true, true);
172184
}
173185

174-
public createConnection(path: string, callback?: () => void): Socket;
175-
public createConnection(port: number, callback?: () => void): Socket;
176-
public createConnection(target: string | number, callback?: () => void): Socket {
186+
public createConnection(path: string, callback?: Function): Socket;
187+
public createConnection(port: number, callback?: Function): Socket;
188+
public createConnection(target: string | number, callback?: Function): Socket;
189+
public createConnection(target: string | number, callback?: Function): Socket {
177190
const id = this.connectionId++;
178-
const newCon = new NewConnectionMessage();
179-
newCon.setId(id);
180-
if (typeof target === "string") {
181-
newCon.setPath(target);
182-
} else {
183-
newCon.setPort(target);
184-
}
185-
const clientMsg = new ClientMessage();
186-
clientMsg.setNewConnection(newCon);
187-
this.connection.send(clientMsg.serializeBinary());
188-
189-
const socket = new ServerSocket(this.connection, id, callback);
190-
this.connections.set(id, socket);
191+
const socket = new ServerSocket(this.connection, id, this.registerConnection);
192+
socket.connect(target, callback);
191193

192194
return socket;
193195
}
@@ -214,7 +216,9 @@ export class Client {
214216
}
215217
if (options.env) {
216218
Object.keys(options.env).forEach((envKey) => {
217-
newSess.getEnvMap().set(envKey, options.env![envKey]);
219+
if (options.env![envKey]) {
220+
newSess.getEnvMap().set(envKey, options.env![envKey].toString());
221+
}
218222
});
219223
}
220224
if (options.tty) {
@@ -356,9 +360,9 @@ export class Client {
356360
return;
357361
}
358362
const conId = message.getServerConnectionEstablished()!.getConnectionId();
359-
const serverSocket = new ServerSocket(this.connection, conId);
363+
const serverSocket = new ServerSocket(this.connection, conId, this.registerConnection);
364+
this.registerConnection(conId, serverSocket);
360365
serverSocket.emit("connect");
361-
this.connections.set(conId, serverSocket);
362366
s.emit("connection", serverSocket);
363367
} else if (message.getServerFailure()) {
364368
const s = this.servers.get(message.getServerFailure()!.getId());
@@ -376,4 +380,12 @@ export class Client {
376380
this.servers.delete(message.getServerClose()!.getId());
377381
}
378382
}
383+
384+
private registerConnection = (id: number, socket: ServerSocket): void => {
385+
if (this.connections.has(id)) {
386+
throw new Error(`${id} is already registered`);
387+
}
388+
this.connections.set(id, socket);
389+
}
390+
379391
}

0 commit comments

Comments
 (0)