Skip to content

Commit ebe5e1b

Browse files
code-asherkylecarbs
authored andcommitted
Uploader online (#26)
1 parent 62b1e0e commit ebe5e1b

20 files changed

+430
-264
lines changed

packages/ide/src/client.ts

+15-21
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11
import { Event } from "@coder/events";
22
import { field, logger, time, Time } from "@coder/logger";
33
import { InitData, ISharedProcessData } from "@coder/protocol";
4-
import { retry, Retry } from "./retry";
4+
import { retry } from "./retry";
5+
import { Upload } from "./upload";
56
import { client } from "./fill/client";
67
import { Clipboard, clipboard } from "./fill/clipboard";
7-
8-
export interface IURI {
9-
10-
readonly path: string;
11-
readonly fsPath: string;
12-
readonly scheme: string;
13-
14-
}
15-
16-
export interface IURIFactory {
17-
18-
/**
19-
* Convert the object to an instance of a real URI.
20-
*/
21-
create<T extends IURI>(uri: IURI): T;
22-
file(path: string): IURI;
23-
parse(raw: string): IURI;
24-
25-
}
8+
import { INotificationService, NotificationService, IProgressService, ProgressService } from "./fill/notification";
9+
import { IURIFactory } from "./fill/uri";
2610

2711
/**
2812
* A general abstraction of an IDE client.
@@ -34,9 +18,10 @@ export interface IURIFactory {
3418
*/
3519
export abstract class Client {
3620

37-
public readonly retry: Retry = retry;
21+
public readonly retry = retry;
3822
public readonly clipboard: Clipboard = clipboard;
3923
public readonly uriFactory: IURIFactory;
24+
public readonly upload = new Upload(new NotificationService(), new ProgressService());
4025
private start: Time | undefined;
4126
private readonly progressElement: HTMLElement | undefined;
4227
private tasks: string[] = [];
@@ -187,6 +172,15 @@ export abstract class Client {
187172
return this.sharedProcessDataPromise;
188173
}
189174

175+
public set notificationService(service: INotificationService) {
176+
this.retry.notificationService = service;
177+
this.upload.notificationService = service;
178+
}
179+
180+
public set progressService(service: IProgressService) {
181+
this.upload.progressService = service;
182+
}
183+
190184
/**
191185
* Initialize the IDE.
192186
*/
+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
import { CP } from "@coder/protocol";
22
import { client } from "./client";
3+
import { promisify } from "./util";
34

4-
export = new CP(client);
5+
const cp = new CP(client);
6+
7+
// tslint:disable-next-line no-any makes util.promisify return an object
8+
(cp as any).exec[promisify.customPromisifyArgs] = ["stdout", "stderr"];
9+
10+
export = cp;

packages/ide/src/fill/client.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Connection implements ReadWriteConnection {
1616
private readonly downEmitter: Emitter<void> = new Emitter();
1717
private readonly messageBuffer: Uint8Array[] = [];
1818
private socketTimeoutDelay = 60 * 1000;
19-
private retryName = "Web socket";
19+
private retryName = "Socket";
2020
private isUp: boolean = false;
2121
private closed: boolean = false;
2222

packages/ide/src/fill/notification.ts

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { logger, field } from "@coder/logger";
2+
3+
/**
4+
* Handle for a notification that allows it to be closed and updated.
5+
*/
6+
export interface INotificationHandle {
7+
8+
/**
9+
* Closes the notification.
10+
*/
11+
close(): void;
12+
13+
/**
14+
* Update the message.
15+
*/
16+
updateMessage(message: string): void;
17+
18+
/**
19+
* Update the buttons.
20+
*/
21+
updateButtons(buttons: INotificationButton[]): void;
22+
23+
}
24+
25+
/**
26+
* Notification severity.
27+
*/
28+
export enum Severity {
29+
Ignore = 0,
30+
Info = 1,
31+
Warning = 2,
32+
Error = 3,
33+
}
34+
35+
/**
36+
* Notification button.
37+
*/
38+
export interface INotificationButton {
39+
label: string;
40+
run(): void;
41+
}
42+
43+
/**
44+
* Optional notification service.
45+
*/
46+
export interface INotificationService {
47+
48+
/**
49+
* Display an error message.
50+
*/
51+
error(error: Error): void;
52+
53+
/**
54+
* Show a notification.
55+
*/
56+
prompt(severity: Severity, message: string, buttons: INotificationButton[], onCancel: () => void): INotificationHandle;
57+
58+
}
59+
60+
/**
61+
* Updatable progress.
62+
*/
63+
export interface IProgress {
64+
65+
/**
66+
* Report progress. Progress is the completed percentage from 0 to 100.
67+
*/
68+
report(progress: number): void;
69+
70+
}
71+
72+
/**
73+
* Option progress reporting service.
74+
*/
75+
export interface IProgressService {
76+
77+
/**
78+
* Start a new progress bar that resolves & disappears when the task finishes.
79+
*/
80+
start<T>(title: string, task: (progress: IProgress) => Promise<T>, onCancel: () => void): Promise<T>;
81+
82+
}
83+
84+
/**
85+
* Temporary notification service.
86+
*/
87+
export class NotificationService implements INotificationService {
88+
89+
public error(error: Error): void {
90+
logger.error(error.message, field("error", error));
91+
}
92+
93+
public prompt(_severity: Severity, message: string, _buttons: INotificationButton[], _onCancel: () => void): INotificationHandle {
94+
throw new Error(`cannot prompt using the console: ${message}`);
95+
}
96+
97+
}
98+
99+
/**
100+
* Temporary progress service.
101+
*/
102+
export class ProgressService implements IProgressService {
103+
104+
public start<T>(title: string, task: (progress: IProgress) => Promise<T>): Promise<T> {
105+
logger.info(title);
106+
107+
return task({
108+
report: (progress): void => {
109+
logger.info(`${title} progress: ${progress}`);
110+
},
111+
});
112+
}
113+
114+
}

packages/ide/src/fill/uri.ts

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export interface IURI {
2+
3+
readonly path: string;
4+
readonly fsPath: string;
5+
readonly scheme: string;
6+
7+
}
8+
9+
export interface IURIFactory {
10+
11+
/**
12+
* Convert the object to an instance of a real URI.
13+
*/
14+
create<T extends IURI>(uri: IURI): T;
15+
file(path: string): IURI;
16+
parse(raw: string): IURI;
17+
18+
}

packages/ide/src/fill/util.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from "../../../../node_modules/util";
2-
import { implementation } from "util.promisify";
2+
import { implementation } from "../../../../node_modules/util.promisify";
33

44
export const promisify = implementation;

packages/ide/src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./client";
2-
export * from "./upload";
2+
export * from "./fill/uri";
3+
export * from "./fill/notification";

packages/ide/src/retry.ts

+9-63
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,5 @@
11
import { logger } from "@coder/logger";
2-
3-
/**
4-
* Handle for a notification that allows it to be closed and updated.
5-
*/
6-
export interface INotificationHandle {
7-
8-
/**
9-
* Closes the notification.
10-
*/
11-
close(): void;
12-
13-
/**
14-
* Update the message.
15-
*/
16-
updateMessage(message: string): void;
17-
18-
/**
19-
* Update the buttons.
20-
*/
21-
updateButtons(buttons: INotificationButton[]): void;
22-
23-
}
24-
25-
/**
26-
* Notification severity.
27-
*/
28-
enum Severity {
29-
Ignore = 0,
30-
Info = 1,
31-
Warning = 2,
32-
Error = 3,
33-
}
34-
35-
/**
36-
* Notification button.
37-
*/
38-
export interface INotificationButton {
39-
label: string;
40-
run(): void;
41-
}
42-
43-
/**
44-
* Optional notification service.
45-
*/
46-
export interface INotificationService {
47-
48-
/**
49-
* Show a notification.
50-
*/
51-
prompt(severity: Severity, message: string, buttons: INotificationButton[], onCancel: () => void): INotificationHandle;
52-
53-
}
2+
import { NotificationService, INotificationHandle, INotificationService, Severity } from "./fill/notification";
543

554
interface IRetryItem {
565
count?: number;
@@ -91,15 +40,16 @@ export class Retry {
9140
// for reasoning.)
9241
private waitDelay = 50;
9342

94-
public constructor(private notificationService?: INotificationService) {
43+
public constructor(private _notificationService: INotificationService) {
9544
this.items = new Map();
9645
}
9746

98-
/**
99-
* Set notification service.
100-
*/
101-
public setNotificationService(notificationService?: INotificationService): void {
102-
this.notificationService = notificationService;
47+
public set notificationService(service: INotificationService) {
48+
this._notificationService = service;
49+
}
50+
51+
public get notificationService(): INotificationService {
52+
return this._notificationService;
10353
}
10454

10555
/**
@@ -262,10 +212,6 @@ export class Retry {
262212
* Update, close, or show the notification.
263213
*/
264214
private updateNotification(): void {
265-
if (!this.notificationService) {
266-
return;
267-
}
268-
269215
// tslint:disable-next-line no-any because NodeJS.Timer is valid.
270216
clearTimeout(this.updateTimeout as any);
271217

@@ -343,4 +289,4 @@ export class Retry {
343289

344290
// Global instance so we can block other retries when retrying the main
345291
// connection.
346-
export const retry = new Retry();
292+
export const retry = new Retry(new NotificationService());

0 commit comments

Comments
 (0)