vscode-jsonrpc
Advanced tools
Comparing version 2.2.0 to 2.3.0
@@ -56,3 +56,3 @@ /*--------------------------------------------------------------------------------------------- | ||
return MutableToken; | ||
})(); | ||
}()); | ||
var CancellationTokenSource = (function () { | ||
@@ -88,3 +88,4 @@ function CancellationTokenSource() { | ||
return CancellationTokenSource; | ||
})(); | ||
}()); | ||
exports.CancellationTokenSource = CancellationTokenSource; | ||
//# sourceMappingURL=cancellation.js.map |
@@ -34,4 +34,4 @@ /* -------------------------------------------------------------------------------------------- | ||
if (disposables) { | ||
for (var _i = 0; _i < disposables.length; _i++) { | ||
var disposable = disposables[_i]; | ||
for (var _i = 0, disposables_1 = disposables; _i < disposables_1.length; _i++) { | ||
var disposable = disposables_1[_i]; | ||
disposable.dispose(); | ||
@@ -53,3 +53,3 @@ } | ||
return DisposableImpl; | ||
})(); | ||
}()); | ||
var CallbackList = (function () { | ||
@@ -121,3 +121,3 @@ function CallbackList() { | ||
return CallbackList; | ||
})(); | ||
}()); | ||
var Emitter = (function () { | ||
@@ -181,3 +181,4 @@ function Emitter(_options) { | ||
return Emitter; | ||
})(); | ||
}()); | ||
exports.Emitter = Emitter; | ||
//# sourceMappingURL=events.js.map |
@@ -47,1 +47,2 @@ /* -------------------------------------------------------------------------------------------- | ||
exports.stringArray = stringArray; | ||
//# sourceMappingURL=is.js.map |
@@ -38,3 +38,5 @@ import { Message, RequestMessage, RequestType, ResponseError, ErrorCodes, NotificationMessage, NotificationType } from './messages'; | ||
onClose: Event<void>; | ||
onUnhandledNotification: Event<NotificationMessage>; | ||
listen(): any; | ||
onDispose: Event<void>; | ||
dispose(): void; | ||
@@ -41,0 +43,0 @@ } |
@@ -51,4 +51,6 @@ /* -------------------------------------------------------------------------------------------- | ||
(function (ConnectionState) { | ||
ConnectionState[ConnectionState["Active"] = 1] = "Active"; | ||
ConnectionState[ConnectionState["Closed"] = 2] = "Closed"; | ||
ConnectionState[ConnectionState["New"] = 1] = "New"; | ||
ConnectionState[ConnectionState["Listening"] = 2] = "Listening"; | ||
ConnectionState[ConnectionState["Closed"] = 3] = "Closed"; | ||
ConnectionState[ConnectionState["Disposed"] = 4] = "Disposed"; | ||
})(ConnectionState || (ConnectionState = {})); | ||
@@ -65,10 +67,19 @@ function createMessageConnection(messageReader, messageWriter, logger, client) { | ||
var tracer; | ||
var state = ConnectionState.Active; | ||
var state = ConnectionState.New; | ||
var errorEmitter = new events_1.Emitter(); | ||
var closeEmitter = new events_1.Emitter(); | ||
var unhandledNotificationEmitter = new events_1.Emitter(); | ||
var disposeEmitter = new events_1.Emitter(); | ||
function isListening() { | ||
return state === ConnectionState.Listening; | ||
} | ||
function isDisposed() { | ||
return state === ConnectionState.Disposed; | ||
} | ||
function closeHandler() { | ||
if (state !== ConnectionState.Closed) { | ||
if (state === ConnectionState.New || state === ConnectionState.Listening) { | ||
state = ConnectionState.Closed; | ||
closeEmitter.fire(undefined); | ||
} | ||
// If the connection is disposed don't sent close events. | ||
} | ||
@@ -87,2 +98,7 @@ ; | ||
function handleRequest(requestMessage) { | ||
if (isDisposed()) { | ||
// we return here silently since we fired an event when the | ||
// connection got disposed. | ||
return; | ||
} | ||
function reply(resultOrError) { | ||
@@ -125,4 +141,4 @@ var message = { | ||
var cancellationSource = new cancellation_1.CancellationTokenSource(); | ||
var tokenKey = String(requestMessage.id); | ||
requestTokens[tokenKey] = cancellationSource; | ||
var tokenKey_1 = String(requestMessage.id); | ||
requestTokens[tokenKey_1] = cancellationSource; | ||
try { | ||
@@ -132,3 +148,3 @@ var handlerResult = requestHandler(requestMessage.params, cancellationSource.token); | ||
if (!handlerResult) { | ||
delete requestTokens[tokenKey]; | ||
delete requestTokens[tokenKey_1]; | ||
replySuccess(handlerResult); | ||
@@ -138,6 +154,6 @@ } | ||
promise.then(function (resultOrError) { | ||
delete requestTokens[tokenKey]; | ||
delete requestTokens[tokenKey_1]; | ||
reply(resultOrError); | ||
}, function (error) { | ||
delete requestTokens[tokenKey]; | ||
delete requestTokens[tokenKey_1]; | ||
if (error instanceof messages_1.ResponseError) { | ||
@@ -155,3 +171,3 @@ replyError(error); | ||
else { | ||
delete requestTokens[tokenKey]; | ||
delete requestTokens[tokenKey_1]; | ||
reply(handlerResult); | ||
@@ -161,3 +177,3 @@ } | ||
catch (error) { | ||
delete requestTokens[tokenKey]; | ||
delete requestTokens[tokenKey_1]; | ||
if (error instanceof messages_1.ResponseError) { | ||
@@ -179,2 +195,6 @@ reply(error); | ||
function handleResponse(responseMessage) { | ||
if (isDisposed()) { | ||
// See handle request. | ||
return; | ||
} | ||
var key = String(responseMessage.id); | ||
@@ -209,2 +229,6 @@ var responsePromise = responsePromises[key]; | ||
function handleNotification(message) { | ||
if (isDisposed()) { | ||
// See handle request. | ||
return; | ||
} | ||
var eventHandler; | ||
@@ -239,2 +263,5 @@ if (message.method === CancelNotification.type.method) { | ||
} | ||
else { | ||
unhandledNotificationEmitter.fire(message); | ||
} | ||
} | ||
@@ -321,4 +348,8 @@ function handleInvalidMessage(message) { | ||
}; | ||
var disposedMessage = 'Connection is disposed'; | ||
var connection = { | ||
sendNotification: function (type, params) { | ||
if (isDisposed()) { | ||
throw new Error(disposedMessage); | ||
} | ||
var notificatioMessage = { | ||
@@ -335,5 +366,11 @@ jsonrpc: version, | ||
onNotification: function (type, handler) { | ||
if (isDisposed()) { | ||
throw new Error(disposedMessage); | ||
} | ||
eventHandlers[type.method] = handler; | ||
}, | ||
sendRequest: function (type, params, token) { | ||
if (isDisposed()) { | ||
throw new Error(disposedMessage); | ||
} | ||
var id = sequenceNumber++; | ||
@@ -371,2 +408,5 @@ var result = new Promise(function (resolve, reject) { | ||
onRequest: function (type, handler) { | ||
if (isDisposed()) { | ||
throw new Error(disposedMessage); | ||
} | ||
requestHandlers[type.method] = handler; | ||
@@ -385,5 +425,25 @@ }, | ||
onClose: closeEmitter.event, | ||
onUnhandledNotification: unhandledNotificationEmitter.event, | ||
onDispose: disposeEmitter.event, | ||
dispose: function () { | ||
if (isDisposed()) { | ||
return; | ||
} | ||
state = ConnectionState.Disposed; | ||
disposeEmitter.fire(undefined); | ||
var error = new Error('Connection got disposed.'); | ||
Object.keys(responsePromises).forEach(function (key) { | ||
responsePromises[key].reject(error); | ||
}); | ||
responsePromises = Object.create(null); | ||
requestTokens = Object.create(null); | ||
}, | ||
listen: function () { | ||
if (isDisposed()) { | ||
throw new Error(disposedMessage); | ||
} | ||
if (isListening()) { | ||
throw new Error('Conneciton is already listening'); | ||
} | ||
state = ConnectionState.Listening; | ||
messageReader.listen(callback); | ||
@@ -412,1 +472,2 @@ } | ||
exports.createClientMessageConnection = createClientMessageConnection; | ||
//# sourceMappingURL=main.js.map |
@@ -7,5 +7,10 @@ import { ChildProcess } from 'child_process'; | ||
} | ||
export interface PartialMessageInfo { | ||
messageToken: number; | ||
waitingTime: number; | ||
} | ||
export interface MessageReader { | ||
onError: Event<Error>; | ||
onClose: Event<void>; | ||
onPartialMessage: Event<PartialMessageInfo>; | ||
listen(callback: DataCallback): void; | ||
@@ -16,2 +21,3 @@ } | ||
private closeEmitter; | ||
private partialMessageEmitter; | ||
constructor(); | ||
@@ -22,2 +28,4 @@ onError: Event<Error>; | ||
protected fireClose(): void; | ||
onPartialMessage: Event<PartialMessageInfo>; | ||
protected firePartialMessage(info: PartialMessageInfo): void; | ||
private asError(error); | ||
@@ -30,5 +38,11 @@ } | ||
private nextMessageLength; | ||
private messageToken; | ||
private partialMessageTimer; | ||
private _partialMessageTimeout; | ||
constructor(readable: NodeJS.ReadableStream, encoding?: string); | ||
partialMessageTimeout: number; | ||
listen(callback: DataCallback): void; | ||
private onData(data); | ||
private clearPartialMessageTimer(); | ||
private setPartialMessageTimer(); | ||
} | ||
@@ -35,0 +49,0 @@ export declare class IPCMessageReader extends AbstractMessageReader implements MessageReader { |
@@ -90,3 +90,3 @@ /* -------------------------------------------------------------------------------------------- | ||
return MessageBuffer; | ||
})(); | ||
}()); | ||
var AbstractMessageReader = (function () { | ||
@@ -96,2 +96,3 @@ function AbstractMessageReader() { | ||
this.closeEmitter = new events_1.Emitter(); | ||
this.partialMessageEmitter = new events_1.Emitter(); | ||
} | ||
@@ -118,2 +119,12 @@ Object.defineProperty(AbstractMessageReader.prototype, "onError", { | ||
}; | ||
Object.defineProperty(AbstractMessageReader.prototype, "onPartialMessage", { | ||
get: function () { | ||
return this.partialMessageEmitter.event; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
AbstractMessageReader.prototype.firePartialMessage = function (info) { | ||
this.partialMessageEmitter.fire(info); | ||
}; | ||
AbstractMessageReader.prototype.asError = function (error) { | ||
@@ -128,3 +139,3 @@ if (error instanceof Error) { | ||
return AbstractMessageReader; | ||
})(); | ||
}()); | ||
exports.AbstractMessageReader = AbstractMessageReader; | ||
@@ -138,6 +149,19 @@ var StreamMessageReader = (function (_super) { | ||
this.buffer = new MessageBuffer(encoding); | ||
this._partialMessageTimeout = 10000; | ||
} | ||
Object.defineProperty(StreamMessageReader.prototype, "partialMessageTimeout", { | ||
get: function () { | ||
return this._partialMessageTimeout; | ||
}, | ||
set: function (timeout) { | ||
this._partialMessageTimeout = timeout; | ||
}, | ||
enumerable: true, | ||
configurable: true | ||
}); | ||
StreamMessageReader.prototype.listen = function (callback) { | ||
var _this = this; | ||
this.nextMessageLength = -1; | ||
this.messageToken = 0; | ||
this.partialMessageTimer = undefined; | ||
this.callback = callback; | ||
@@ -170,5 +194,9 @@ this.readable.on('data', function (data) { | ||
if (msg === null) { | ||
/** We haven't recevied the full message yet. */ | ||
this.setPartialMessageTimer(); | ||
return; | ||
} | ||
this.clearPartialMessageTimer(); | ||
this.nextMessageLength = -1; | ||
this.messageToken++; | ||
var json = JSON.parse(msg); | ||
@@ -178,4 +206,24 @@ this.callback(json); | ||
}; | ||
StreamMessageReader.prototype.clearPartialMessageTimer = function () { | ||
if (this.partialMessageTimer) { | ||
clearTimeout(this.partialMessageTimer); | ||
this.partialMessageTimer = undefined; | ||
} | ||
}; | ||
StreamMessageReader.prototype.setPartialMessageTimer = function () { | ||
var _this = this; | ||
this.clearPartialMessageTimer(); | ||
if (this._partialMessageTimeout <= 0) { | ||
return; | ||
} | ||
this.partialMessageTimer = setTimeout(function (token, timeout) { | ||
_this.partialMessageTimer = undefined; | ||
if (token === _this.messageToken) { | ||
_this.firePartialMessage({ messageToken: token, waitingTime: timeout }); | ||
_this.setPartialMessageTimer(); | ||
} | ||
}, this._partialMessageTimeout, this.messageToken, this._partialMessageTimeout); | ||
}; | ||
return StreamMessageReader; | ||
})(AbstractMessageReader); | ||
}(AbstractMessageReader)); | ||
exports.StreamMessageReader = StreamMessageReader; | ||
@@ -195,3 +243,4 @@ var IPCMessageReader = (function (_super) { | ||
return IPCMessageReader; | ||
})(AbstractMessageReader); | ||
}(AbstractMessageReader)); | ||
exports.IPCMessageReader = IPCMessageReader; | ||
//# sourceMappingURL=messageReader.js.map |
@@ -55,3 +55,3 @@ /* -------------------------------------------------------------------------------------------- | ||
return ResponseError; | ||
})(Error); | ||
}(Error)); | ||
exports.ResponseError = ResponseError; | ||
@@ -82,1 +82,2 @@ /** | ||
exports.isReponseMessage = isReponseMessage; | ||
//# sourceMappingURL=messages.js.map |
@@ -49,3 +49,3 @@ /* -------------------------------------------------------------------------------------------- | ||
return AbstractMessageWriter; | ||
})(); | ||
}()); | ||
exports.AbstractMessageWriter = AbstractMessageWriter; | ||
@@ -84,3 +84,3 @@ var StreamMessageWriter = (function (_super) { | ||
return StreamMessageWriter; | ||
})(AbstractMessageWriter); | ||
}(AbstractMessageWriter)); | ||
exports.StreamMessageWriter = StreamMessageWriter; | ||
@@ -108,3 +108,4 @@ var IPCMessageWriter = (function (_super) { | ||
return IPCMessageWriter; | ||
})(AbstractMessageWriter); | ||
}(AbstractMessageWriter)); | ||
exports.IPCMessageWriter = IPCMessageWriter; | ||
//# sourceMappingURL=messageWriter.js.map |
{ | ||
"name": "vscode-jsonrpc", | ||
"description": "A json rpc implementation over streams", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"author": "Microsoft Corporation", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
@@ -9,3 +9,39 @@ # VSCode JSON RPC | ||
Click [here](https://code.visualstudio.com/docs/extensions/example-language-server) for a detailed document on how to uses this npm module | ||
to implement language servers for [VSCode](https://code.visualstudio.com/). | ||
The npm module can also be used standalone to establish a [JSON-RPC](http://www.jsonrpc.org/) channel between | ||
a client and a server. Below an example how to setup a JSON-RPC connection. First the client side. | ||
```ts | ||
import * as cp from 'child_process'; | ||
import * as rpc from 'vscode-jsonrpc'; | ||
let childProcess = cp.spawn(...); | ||
// Use stdin and stdout for communication: | ||
let connection = rpc.createClientMessageConnection( | ||
new rpc.StreamMessageReader(childProcess.stdout), | ||
new rpc.StreamMessageWriter(childProcess.stdin)); | ||
let notification: rpc.NotificationType<string> = { method: 'testNotification' }; | ||
connection.listen(); | ||
connection.sendNotification(notification, 'Hello World'); | ||
``` | ||
The server side looks very symmetrical: | ||
```ts | ||
import * as rpc from 'vscode-jsonrpc'; | ||
let connection = rpc.createClientMessageConnection( | ||
new rpc.StreamMessageReader(process.stdin), | ||
new rpc.StreamMessageWriter(process.stdout)); | ||
let notification: rpc.NotificationType<string> = { method: 'testNotification' }; | ||
connection.onNotification(notification, (param: string) => { | ||
console.log(param); // This prints Hello World | ||
}); | ||
connection.listen(); | ||
``` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
63521
1514
46