diff options
author | 2022-08-12 19:54:46 +0200 | |
---|---|---|
committer | 2022-08-12 19:54:46 +0200 | |
commit | d22c3b0c257f5daf5b401988a35ab9ce981a2341 (patch) | |
tree | 0a661c927c37b52197326d1c05e211daf9bd19e5 /subprojects/frontend/src/xtext/XtextWebSocketClient.ts | |
parent | fix(language): rule parsing test (diff) | |
download | refinery-d22c3b0c257f5daf5b401988a35ab9ce981a2341.tar.gz refinery-d22c3b0c257f5daf5b401988a35ab9ce981a2341.tar.zst refinery-d22c3b0c257f5daf5b401988a35ab9ce981a2341.zip |
refactor(frontend): move from Webpack to Vite
Also overhaulds the building and linting for frontend assets.
Diffstat (limited to 'subprojects/frontend/src/xtext/XtextWebSocketClient.ts')
-rw-r--r-- | subprojects/frontend/src/xtext/XtextWebSocketClient.ts | 94 |
1 files changed, 55 insertions, 39 deletions
diff --git a/subprojects/frontend/src/xtext/XtextWebSocketClient.ts b/subprojects/frontend/src/xtext/XtextWebSocketClient.ts index 2ce20a54..ceb1f3fd 100644 --- a/subprojects/frontend/src/xtext/XtextWebSocketClient.ts +++ b/subprojects/frontend/src/xtext/XtextWebSocketClient.ts | |||
@@ -1,16 +1,17 @@ | |||
1 | import { nanoid } from 'nanoid'; | 1 | import { nanoid } from 'nanoid'; |
2 | 2 | ||
3 | import { getLogger } from '../utils/logger'; | 3 | import PendingTask from '../utils/PendingTask'; |
4 | import { PendingTask } from '../utils/PendingTask'; | 4 | import Timer from '../utils/Timer'; |
5 | import { Timer } from '../utils/Timer'; | 5 | import getLogger from '../utils/getLogger'; |
6 | |||
6 | import { | 7 | import { |
7 | xtextWebErrorResponse, | 8 | XtextWebErrorResponse, |
8 | XtextWebRequest, | 9 | XtextWebRequest, |
9 | xtextWebOkResponse, | 10 | XtextWebOkResponse, |
10 | xtextWebPushMessage, | 11 | XtextWebPushMessage, |
11 | XtextWebPushService, | 12 | XtextWebPushService, |
12 | } from './xtextMessages'; | 13 | } from './xtextMessages'; |
13 | import { pongResult } from './xtextServiceResults'; | 14 | import { PongResult } from './xtextServiceResults'; |
14 | 15 | ||
15 | const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1'; | 16 | const XTEXT_SUBPROTOCOL_V1 = 'tools.refinery.language.web.xtext.v1'; |
16 | 17 | ||
@@ -18,7 +19,8 @@ const WEBSOCKET_CLOSE_OK = 1000; | |||
18 | 19 | ||
19 | const RECONNECT_DELAY_MS = [200, 1000, 5000, 30_000]; | 20 | const RECONNECT_DELAY_MS = [200, 1000, 5000, 30_000]; |
20 | 21 | ||
21 | const MAX_RECONNECT_DELAY_MS = RECONNECT_DELAY_MS[RECONNECT_DELAY_MS.length - 1]; | 22 | const MAX_RECONNECT_DELAY_MS = |
23 | RECONNECT_DELAY_MS[RECONNECT_DELAY_MS.length - 1]; | ||
22 | 24 | ||
23 | const BACKGROUND_IDLE_TIMEOUT_MS = 5 * 60 * 1000; | 25 | const BACKGROUND_IDLE_TIMEOUT_MS = 5 * 60 * 1000; |
24 | 26 | ||
@@ -47,7 +49,7 @@ enum State { | |||
47 | TimedOut, | 49 | TimedOut, |
48 | } | 50 | } |
49 | 51 | ||
50 | export class XtextWebSocketClient { | 52 | export default class XtextWebSocketClient { |
51 | private nextMessageId = 0; | 53 | private nextMessageId = 0; |
52 | 54 | ||
53 | private connection!: WebSocket; | 55 | private connection!: WebSocket; |
@@ -88,9 +90,11 @@ export class XtextWebSocketClient { | |||
88 | } | 90 | } |
89 | 91 | ||
90 | get isOpen(): boolean { | 92 | get isOpen(): boolean { |
91 | return this.state === State.TabVisible | 93 | return ( |
92 | || this.state === State.TabHiddenIdle | 94 | this.state === State.TabVisible || |
93 | || this.state === State.TabHiddenWaiting; | 95 | this.state === State.TabHiddenIdle || |
96 | this.state === State.TabHiddenWaiting | ||
97 | ); | ||
94 | } | 98 | } |
95 | 99 | ||
96 | private reconnect() { | 100 | private reconnect() { |
@@ -104,7 +108,11 @@ export class XtextWebSocketClient { | |||
104 | this.connection = new WebSocket(webSocketUrl, XTEXT_SUBPROTOCOL_V1); | 108 | this.connection = new WebSocket(webSocketUrl, XTEXT_SUBPROTOCOL_V1); |
105 | this.connection.addEventListener('open', () => { | 109 | this.connection.addEventListener('open', () => { |
106 | if (this.connection.protocol !== XTEXT_SUBPROTOCOL_V1) { | 110 | if (this.connection.protocol !== XTEXT_SUBPROTOCOL_V1) { |
107 | log.error('Unknown subprotocol', this.connection.protocol, 'selected by server'); | 111 | log.error( |
112 | 'Unknown subprotocol', | ||
113 | this.connection.protocol, | ||
114 | 'selected by server', | ||
115 | ); | ||
108 | this.forceReconnectOnError(); | 116 | this.forceReconnectOnError(); |
109 | } | 117 | } |
110 | if (document.visibilityState === 'hidden') { | 118 | if (document.visibilityState === 'hidden') { |
@@ -126,8 +134,11 @@ export class XtextWebSocketClient { | |||
126 | this.handleMessage(event.data); | 134 | this.handleMessage(event.data); |
127 | }); | 135 | }); |
128 | this.connection.addEventListener('close', (event) => { | 136 | this.connection.addEventListener('close', (event) => { |
129 | if (this.isLogicallyClosed && event.code === WEBSOCKET_CLOSE_OK | 137 | if ( |
130 | && this.pendingRequests.size === 0) { | 138 | this.isLogicallyClosed && |
139 | event.code === WEBSOCKET_CLOSE_OK && | ||
140 | this.pendingRequests.size === 0 | ||
141 | ) { | ||
131 | log.info('Websocket closed'); | 142 | log.info('Websocket closed'); |
132 | return; | 143 | return; |
133 | } | 144 | } |
@@ -144,7 +155,10 @@ export class XtextWebSocketClient { | |||
144 | return; | 155 | return; |
145 | } | 156 | } |
146 | this.idleTimer.cancel(); | 157 | this.idleTimer.cancel(); |
147 | if (this.state === State.TabHiddenIdle || this.state === State.TabHiddenWaiting) { | 158 | if ( |
159 | this.state === State.TabHiddenIdle || | ||
160 | this.state === State.TabHiddenWaiting | ||
161 | ) { | ||
148 | this.handleTabVisibleConnected(); | 162 | this.handleTabVisibleConnected(); |
149 | return; | 163 | return; |
150 | } | 164 | } |
@@ -183,7 +197,11 @@ export class XtextWebSocketClient { | |||
183 | this.closeConnection(1000, 'idle timeout'); | 197 | this.closeConnection(1000, 'idle timeout'); |
184 | return; | 198 | return; |
185 | } | 199 | } |
186 | log.info('Waiting for', pending, 'pending requests before closing websocket'); | 200 | log.info( |
201 | 'Waiting for', | ||
202 | pending, | ||
203 | 'pending requests before closing websocket', | ||
204 | ); | ||
187 | } | 205 | } |
188 | 206 | ||
189 | private sendPing() { | 207 | private sendPing() { |
@@ -192,19 +210,21 @@ export class XtextWebSocketClient { | |||
192 | } | 210 | } |
193 | const ping = nanoid(); | 211 | const ping = nanoid(); |
194 | log.trace('Ping', ping); | 212 | log.trace('Ping', ping); |
195 | this.send({ ping }).then((result) => { | 213 | this.send({ ping }) |
196 | const parsedPongResult = pongResult.safeParse(result); | 214 | .then((result) => { |
197 | if (parsedPongResult.success && parsedPongResult.data.pong === ping) { | 215 | const parsedPongResult = PongResult.safeParse(result); |
198 | log.trace('Pong', ping); | 216 | if (parsedPongResult.success && parsedPongResult.data.pong === ping) { |
199 | this.pingTimer.schedule(); | 217 | log.trace('Pong', ping); |
200 | } else { | 218 | this.pingTimer.schedule(); |
201 | log.error('Invalid pong:', parsedPongResult, 'expected:', ping); | 219 | } else { |
220 | log.error('Invalid pong:', parsedPongResult, 'expected:', ping); | ||
221 | this.forceReconnectOnError(); | ||
222 | } | ||
223 | }) | ||
224 | .catch((error) => { | ||
225 | log.error('Error while waiting for ping', error); | ||
202 | this.forceReconnectOnError(); | 226 | this.forceReconnectOnError(); |
203 | } | 227 | }); |
204 | }).catch((error) => { | ||
205 | log.error('Error while waiting for ping', error); | ||
206 | this.forceReconnectOnError(); | ||
207 | }); | ||
208 | } | 228 | } |
209 | 229 | ||
210 | send(request: unknown): Promise<unknown> { | 230 | send(request: unknown): Promise<unknown> { |
@@ -250,13 +270,13 @@ export class XtextWebSocketClient { | |||
250 | this.forceReconnectOnError(); | 270 | this.forceReconnectOnError(); |
251 | return; | 271 | return; |
252 | } | 272 | } |
253 | const okResponse = xtextWebOkResponse.safeParse(message); | 273 | const okResponse = XtextWebOkResponse.safeParse(message); |
254 | if (okResponse.success) { | 274 | if (okResponse.success) { |
255 | const { id, response } = okResponse.data; | 275 | const { id, response } = okResponse.data; |
256 | this.resolveRequest(id, response); | 276 | this.resolveRequest(id, response); |
257 | return; | 277 | return; |
258 | } | 278 | } |
259 | const errorResponse = xtextWebErrorResponse.safeParse(message); | 279 | const errorResponse = XtextWebErrorResponse.safeParse(message); |
260 | if (errorResponse.success) { | 280 | if (errorResponse.success) { |
261 | const { id, error, message: errorMessage } = errorResponse.data; | 281 | const { id, error, message: errorMessage } = errorResponse.data; |
262 | this.rejectRequest(id, new Error(`${error} error: ${errorMessage}`)); | 282 | this.rejectRequest(id, new Error(`${error} error: ${errorMessage}`)); |
@@ -266,14 +286,9 @@ export class XtextWebSocketClient { | |||
266 | } | 286 | } |
267 | return; | 287 | return; |
268 | } | 288 | } |
269 | const pushMessage = xtextWebPushMessage.safeParse(message); | 289 | const pushMessage = XtextWebPushMessage.safeParse(message); |
270 | if (pushMessage.success) { | 290 | if (pushMessage.success) { |
271 | const { | 291 | const { resource, stateId, service, push } = pushMessage.data; |
272 | resource, | ||
273 | stateId, | ||
274 | service, | ||
275 | push, | ||
276 | } = pushMessage.data; | ||
277 | this.onPush(resource, stateId, service, push); | 292 | this.onPush(resource, stateId, service, push); |
278 | } else { | 293 | } else { |
279 | log.error( | 294 | log.error( |
@@ -343,7 +358,8 @@ export class XtextWebSocketClient { | |||
343 | private handleErrorState() { | 358 | private handleErrorState() { |
344 | this.state = State.Error; | 359 | this.state = State.Error; |
345 | this.reconnectTryCount += 1; | 360 | this.reconnectTryCount += 1; |
346 | const delay = RECONNECT_DELAY_MS[this.reconnectTryCount - 1] || MAX_RECONNECT_DELAY_MS; | 361 | const delay = |
362 | RECONNECT_DELAY_MS[this.reconnectTryCount - 1] || MAX_RECONNECT_DELAY_MS; | ||
347 | log.info('Reconnecting in', delay, 'ms'); | 363 | log.info('Reconnecting in', delay, 'ms'); |
348 | this.reconnectTimer.schedule(delay); | 364 | this.reconnectTimer.schedule(delay); |
349 | } | 365 | } |