vscode-ws-jsonrpc
Version:
VSCode JSON RPC over WebSocket
99 lines • 3.47 kB
JavaScript
/* --------------------------------------------------------------------------------------------
* Copyright (c) 2024 TypeFox and others.
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
import { AbstractMessageReader } from 'vscode-jsonrpc/lib/common/messageReader.js';
export class WebSocketMessageReader extends AbstractMessageReader {
socket;
state = 'initial';
callback;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
events = [];
constructor(socket) {
super();
this.socket = socket;
this.socket.onMessage(message => this.readMessage(message));
this.socket.onError(error => this.fireError(error));
this.socket.onClose((code, reason) => {
if (code !== 1000) {
const error = {
name: '' + code,
message: `Error during socket reconnect: code = ${code}, reason = ${reason}`
};
this.fireError(error);
}
this.fireClose();
});
}
listen(callback) {
if (this.state === 'initial') {
this.state = 'listening';
this.callback = callback;
while (this.events.length !== 0) {
const event = this.events.pop();
if (event.message !== undefined) {
this.readMessage(event.message);
}
else if (event.error !== undefined) {
this.fireError(event.error);
}
else {
this.fireClose();
}
}
}
return {
dispose: () => {
if (this.callback === callback) {
this.state = 'initial';
this.callback = undefined;
}
}
};
}
dispose() {
super.dispose();
this.state = 'initial';
this.callback = undefined;
this.events.splice(0, this.events.length);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readMessage(message) {
if (this.state === 'initial') {
this.events.splice(0, 0, { message });
}
else if (this.state === 'listening') {
try {
const data = JSON.parse(message);
this.callback(data);
}
catch (err) {
const error = {
name: '' + 400,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
message: `Error during message parsing, reason = ${typeof err === 'object' ? err.message : 'unknown'}`
};
this.fireError(error);
}
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fireError(error) {
if (this.state === 'initial') {
this.events.splice(0, 0, { error });
}
else if (this.state === 'listening') {
super.fireError(error);
}
}
fireClose() {
if (this.state === 'initial') {
this.events.splice(0, 0, {});
}
else if (this.state === 'listening') {
super.fireClose();
}
this.state = 'closed';
}
}
//# sourceMappingURL=reader.js.map