Skip to content

Commit bda36cf

Browse files
committed
Use promises for host -> child queries.
refs #27 closes #19
1 parent 75d1315 commit bda36cf

File tree

7 files changed

+127
-29
lines changed

7 files changed

+127
-29
lines changed

lib/globals.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
/// <reference path="./typings/mustache.d.ts"/>
1010

1111
/// <reference path="./node_modules/views/views.d.ts"/>
12+
/// <reference path="./typings/atompromise.d.ts"/>

lib/main/atomts.js

+1-5
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@ function activate(state) {
4444
return;
4545
}
4646
var text = editor.getText();
47-
parent.updateText({ filePath: filePath, text: text }, function () {
48-
parent.getErrorsForFile({ filePath: filePath }, function (resp) {
49-
errorView.setErrors(filePath, resp.errors);
50-
});
51-
});
47+
parent.updateText({ filePath: filePath, text: text }).then(function () { return parent.getErrorsForFile({ filePath: filePath }); }).then(function (resp) { return errorView.setErrors(filePath, resp.errors); });
5248
program.languageServiceHost.updateScript(filePath, text);
5349
var position = atomUtils.getEditorPosition(editor);
5450
signatureProvider.requestHandler({

lib/main/atomts.ts

+4-6
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,10 @@ export function activate(state: PackageState) {
109109
var text = editor.getText();
110110

111111
// Update the file in the worker
112-
parent.updateText({ filePath: filePath, text: text },() => {
113-
parent.getErrorsForFile({ filePath: filePath },(resp) => {
114-
// Set errors in project per file
115-
errorView.setErrors(filePath, resp.errors);
116-
});
117-
});
112+
parent.updateText({ filePath: filePath, text: text })
113+
// Set errors in project per file
114+
.then(() => parent.getErrorsForFile({ filePath: filePath }))
115+
.then((resp) => errorView.setErrors(filePath, resp.errors));
118116

119117
// Update the file
120118
program.languageServiceHost.updateScript(filePath, text);

lib/tsconfig.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
"module": "commonjs",
55
"declaration": false,
66
"noImplicitAny": false,
7-
"removeComments": true
7+
"removeComments": true,
8+
"noLib": false
89
},
910
"filesGlob": [
1011
"./**/*.ts"
@@ -25,6 +26,7 @@
2526
"./main/tsconfig/tsconfig.ts",
2627
"./node_modules/views/views.d.ts",
2728
"./typings/atom/atom.d.ts",
29+
"./typings/atompromise.d.ts",
2830
"./typings/bluebird.d.ts",
2931
"./typings/brackets.d.ts",
3032
"./typings/codemirror.d.ts",

lib/typings/atompromise.d.ts

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Ripped from lib.es6.d.ts with addtions for atom
2+
3+
/**
4+
* Represents the completion of an asynchronous operation
5+
*/
6+
interface Promise<T> {
7+
/**
8+
* Attaches callbacks for the resolution and/or rejection of the Promise.
9+
* @param onfulfilled The callback to execute when the Promise is resolved.
10+
* @param onrejected The callback to execute when the Promise is rejected.
11+
* @returns A Promise for the completion of which ever callback is executed.
12+
*/
13+
then<TResult>(onfulfilled?: (value: T) => TResult | Promise<TResult>, onrejected?: (reason: any) => TResult | Promise<TResult>): Promise<TResult>;
14+
15+
/**
16+
* Attaches a callback for only the rejection of the Promise.
17+
* @param onrejected The callback to execute when the Promise is rejected.
18+
* @returns A Promise for the completion of the callback.
19+
*/
20+
catch(onrejected?: (reason: any) => T | Promise<T>): Promise<T>;
21+
}
22+
23+
interface PromiseConstructor {
24+
/**
25+
* A reference to the prototype.
26+
*/
27+
prototype: Promise<any>;
28+
29+
/**
30+
* Creates a new Promise.
31+
* @param init A callback used to initialize the promise. This callback is passed two arguments:
32+
* a resolve callback used resolve the promise with a value or the result of another promise,
33+
* and a reject callback used to reject the promise with a provided reason or error.
34+
*/
35+
new <T>(init: (resolve: (value?: T | Promise<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
36+
37+
<T>(init: (resolve: (value?: T | Promise<T>) => void, reject: (reason?: any) => void) => void): Promise<T>;
38+
39+
/**
40+
* Creates a Promise that is resolved with an array of results when all of the provided Promises
41+
* resolve, or rejected when any Promise is rejected.
42+
* @param values An array of Promises.
43+
* @returns A new Promise.
44+
*/
45+
all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
46+
47+
/**
48+
* Creates a Promise that is resolved with an array of results when all of the provided Promises
49+
* resolve, or rejected when any Promise is rejected.
50+
* @param values An array of values.
51+
* @returns A new Promise.
52+
*/
53+
all(values: Promise<void>[]): Promise<void>;
54+
55+
/**
56+
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
57+
* or rejected.
58+
* @param values An array of Promises.
59+
* @returns A new Promise.
60+
*/
61+
race<T>(values: (T | Promise<T>)[]): Promise<T>;
62+
63+
/**
64+
* Creates a new rejected promise for the provided reason.
65+
* @param reason The reason the promise was rejected.
66+
* @returns A new rejected Promise.
67+
*/
68+
reject(reason: any): Promise<void>;
69+
70+
/**
71+
* Creates a new rejected promise for the provided reason.
72+
* @param reason The reason the promise was rejected.
73+
* @returns A new rejected Promise.
74+
*/
75+
reject<T>(reason: any): Promise<T>;
76+
77+
/**
78+
* Creates a new resolved promise for the provided value.
79+
* @param value A promise.
80+
* @returns A promise whose internal state matches the provided promise.
81+
*/
82+
resolve<T>(value: T | Promise<T>): Promise<T>;
83+
84+
/**
85+
* Creates a new resolved promise .
86+
* @returns A resolved promise.
87+
*/
88+
resolve(): Promise<void>;
89+
90+
/// BAS ADDITIONS AFTER INSPECTION INTO ATOM
91+
defer<T>(): PromiseDeferred<T>;
92+
}
93+
94+
interface PromiseDeferred<T> {
95+
promise: Promise<T>; resolve(value: T): any; reject(error: T): any;
96+
}
97+
98+
declare var Promise: PromiseConstructor;

lib/worker/parent.js

+8-8
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function startWorker() {
3030
return;
3131
}
3232
else {
33-
currentListeners[parsed.message][parsed.id](parsed.data);
33+
currentListeners[parsed.message][parsed.id].resolve(parsed.data);
3434
delete currentListeners[parsed.message][parsed.id];
3535
}
3636
}
@@ -79,25 +79,25 @@ function createId() {
7979
return v.toString(16);
8080
});
8181
}
82-
function query(message, data, callback) {
83-
if (callback === void 0) { callback = function () {
84-
}; }
82+
function query(message, data) {
8583
if (!child || !child.stdin.writable) {
8684
console.log('PARENT ERR: no child when you tried to send :', message);
8785
return;
8886
}
8987
var id = createId();
9088
if (!currentListeners[message])
9189
currentListeners[message] = {};
92-
currentListeners[message][id] = callback;
90+
var defer = Promise.defer();
91+
currentListeners[message][id] = defer;
9392
child.stdin.write(JSON.stringify({ message: message, id: id, data: data }) + messages.BufferedBySeperatorHandler.seperator);
93+
return defer.promise;
9494
}
9595
function showError(error) {
9696
atom.notifications.addError("Failed to start a child TypeScript worker. Atom-TypeScript is disabled.");
9797
if (error) {
9898
console.error('Failed to activate ts-worker:', error);
9999
}
100100
}
101-
exports.echo = function (data, callback) { return query(messages.echo, data, callback); };
102-
exports.updateText = function (data, callback) { return query(messages.updateText, data, callback); };
103-
exports.getErrorsForFile = function (data, callback) { return query(messages.getErrorsForFile, data, callback); };
101+
exports.echo = function (data) { return query(messages.echo, data); };
102+
exports.updateText = function (data) { return query(messages.updateText, data); };
103+
exports.getErrorsForFile = function (data) { return query(messages.getErrorsForFile, data); };

lib/worker/parent.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ var exec = childprocess.exec;
1010
var spawn = childprocess.spawn;
1111

1212
var child: childprocess.ChildProcess;
13-
var currentListeners: { [messages: string]: { [id: string]: Function } } = {};
13+
var currentListeners: { [messages: string]: { [id: string]: PromiseDeferred<any> } } = {};
1414
export function startWorker() {
1515
try {
1616
var env = Object.create(process.env);
@@ -41,7 +41,7 @@ export function startWorker() {
4141
return;
4242
}
4343
else {
44-
currentListeners[parsed.message][parsed.id](parsed.data);
44+
currentListeners[parsed.message][parsed.id].resolve(parsed.data);
4545
delete currentListeners[parsed.message][parsed.id];
4646
}
4747
}
@@ -98,7 +98,7 @@ function createId(): string {
9898
});
9999
}
100100

101-
function query<Query, Response>(message: string, data: Query, callback: (response: Response) => any = () => { }) {
101+
function query<Query, Response>(message: string, data: Query) : Promise<Response> {
102102

103103
// If we don't have a child exit
104104
if (!child || !child.stdin.writable) {
@@ -111,14 +111,17 @@ function query<Query, Response>(message: string, data: Query, callback: (respons
111111

112112
// Store the callback against this Id:
113113
if (!currentListeners[message]) currentListeners[message] = {};
114-
currentListeners[message][id] = callback;
114+
115+
var defer = Promise.defer();
116+
currentListeners[message][id] = defer;
115117

116118
// Send data to worker
117119
child.stdin.write(JSON.stringify({ message: message, id: id, data: data }) + messages.BufferedBySeperatorHandler.seperator);
120+
return defer.promise;
118121
}
119122

120-
export interface Exec<Query, Response> {
121-
(data: Query, callback?: (res: Response) => any);
123+
export interface Exec<Query,Response> {
124+
(data: Query): Promise<Response>;
122125
}
123126

124127
function showError(error?: Error) {
@@ -132,10 +135,10 @@ function showError(error?: Error) {
132135

133136

134137
export var echo: Exec<messages.EchoQuery, messages.EchoResponse>
135-
= (data, callback) => query(messages.echo, data, callback);
138+
= (data) => query(messages.echo, data);
136139

137140
export var updateText: Exec<messages.UpdateTextQuery, messages.EchoResponse>
138-
= (data, callback?) => query(messages.updateText, data, callback);
141+
= (data) => query(messages.updateText, data);
139142

140143
export var getErrorsForFile: Exec<messages.GetErrorsForFileQuery, messages.GetErrorsForFileResponse>
141-
= (data, callback) => query(messages.getErrorsForFile, data, callback);
144+
= (data) => query(messages.getErrorsForFile, data);

0 commit comments

Comments
 (0)