aboutsummaryrefslogtreecommitdiffstats
path: root/language-web/src/main/js/xtext/XtextWebSocketClient.ts
diff options
context:
space:
mode:
Diffstat (limited to 'language-web/src/main/js/xtext/XtextWebSocketClient.ts')
-rw-r--r--language-web/src/main/js/xtext/XtextWebSocketClient.ts67
1 files changed, 44 insertions, 23 deletions
diff --git a/language-web/src/main/js/xtext/XtextWebSocketClient.ts b/language-web/src/main/js/xtext/XtextWebSocketClient.ts
index 488e4b3b..2ce20a54 100644
--- a/language-web/src/main/js/xtext/XtextWebSocketClient.ts
+++ b/language-web/src/main/js/xtext/XtextWebSocketClient.ts
@@ -4,12 +4,13 @@ import { getLogger } from '../utils/logger';
4import { PendingTask } from '../utils/PendingTask'; 4import { PendingTask } from '../utils/PendingTask';
5import { Timer } from '../utils/Timer'; 5import { Timer } from '../utils/Timer';
6import { 6import {
7 isErrorResponse, 7 xtextWebErrorResponse,
8 isOkResponse, 8 XtextWebRequest,
9 isPushMessage, 9 xtextWebOkResponse,
10 IXtextWebRequest, 10 xtextWebPushMessage,
11 XtextWebPushService,
11} from './xtextMessages'; 12} from './xtextMessages';
12import { isPongResult } from './xtextServiceResults'; 13import { pongResult } from './xtextServiceResults';
13 14
14const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1'; 15const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1';
15 16
@@ -32,7 +33,7 @@ export type ReconnectHandler = () => void;
32export type PushHandler = ( 33export type PushHandler = (
33 resourceId: string, 34 resourceId: string,
34 stateId: string, 35 stateId: string,
35 service: string, 36 service: XtextWebPushService,
36 data: unknown, 37 data: unknown,
37) => void; 38) => void;
38 39
@@ -192,11 +193,12 @@ export class XtextWebSocketClient {
192 const ping = nanoid(); 193 const ping = nanoid();
193 log.trace('Ping', ping); 194 log.trace('Ping', ping);
194 this.send({ ping }).then((result) => { 195 this.send({ ping }).then((result) => {
195 if (isPongResult(result) && result.pong === ping) { 196 const parsedPongResult = pongResult.safeParse(result);
197 if (parsedPongResult.success && parsedPongResult.data.pong === ping) {
196 log.trace('Pong', ping); 198 log.trace('Pong', ping);
197 this.pingTimer.schedule(); 199 this.pingTimer.schedule();
198 } else { 200 } else {
199 log.error('Invalid pong'); 201 log.error('Invalid pong:', parsedPongResult, 'expected:', ping);
200 this.forceReconnectOnError(); 202 this.forceReconnectOnError();
201 } 203 }
202 }).catch((error) => { 204 }).catch((error) => {
@@ -222,7 +224,7 @@ export class XtextWebSocketClient {
222 const message = JSON.stringify({ 224 const message = JSON.stringify({
223 id: messageId, 225 id: messageId,
224 request, 226 request,
225 } as IXtextWebRequest); 227 } as XtextWebRequest);
226 log.trace('Sending message', message); 228 log.trace('Sending message', message);
227 return new Promise((resolve, reject) => { 229 return new Promise((resolve, reject) => {
228 const task = new PendingTask(resolve, reject, REQUEST_TIMEOUT_MS, () => { 230 const task = new PendingTask(resolve, reject, REQUEST_TIMEOUT_MS, () => {
@@ -248,23 +250,42 @@ export class XtextWebSocketClient {
248 this.forceReconnectOnError(); 250 this.forceReconnectOnError();
249 return; 251 return;
250 } 252 }
251 if (isOkResponse(message)) { 253 const okResponse = xtextWebOkResponse.safeParse(message);
252 this.resolveRequest(message.id, message.response); 254 if (okResponse.success) {
253 } else if (isErrorResponse(message)) { 255 const { id, response } = okResponse.data;
254 this.rejectRequest(message.id, new Error(`${message.error} error: ${message.message}`)); 256 this.resolveRequest(id, response);
255 if (message.error === 'server') { 257 return;
256 log.error('Reconnecting due to server error: ', message.message); 258 }
259 const errorResponse = xtextWebErrorResponse.safeParse(message);
260 if (errorResponse.success) {
261 const { id, error, message: errorMessage } = errorResponse.data;
262 this.rejectRequest(id, new Error(`${error} error: ${errorMessage}`));
263 if (error === 'server') {
264 log.error('Reconnecting due to server error: ', errorMessage);
257 this.forceReconnectOnError(); 265 this.forceReconnectOnError();
258 } 266 }
259 } else if (isPushMessage(message)) { 267 return;
260 this.onPush( 268 }
261 message.resource, 269 const pushMessage = xtextWebPushMessage.safeParse(message);
262 message.stateId, 270 if (pushMessage.success) {
263 message.service, 271 const {
264 message.push, 272 resource,
265 ); 273 stateId,
274 service,
275 push,
276 } = pushMessage.data;
277 this.onPush(resource, stateId, service, push);
266 } else { 278 } else {
267 log.error('Unexpected websocket message', message); 279 log.error(
280 'Unexpected websocket message:',
281 message,
282 'not ok response because:',
283 okResponse.error,
284 'not error response because:',
285 errorResponse.error,
286 'not push message because:',
287 pushMessage.error,
288 );
268 this.forceReconnectOnError(); 289 this.forceReconnectOnError();
269 } 290 }
270 } 291 }