diff options
author | Kristóf Marussy <kristof@marussy.com> | 2022-11-10 14:35:24 +0100 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2022-11-10 14:35:24 +0100 |
commit | 4971c864a603e0c01f7ad84a23697905d096283b (patch) | |
tree | fc2ed2ced39aa50aa98602ad4bd2a9d877577dcd /subprojects/frontend/src/xtext/XtextWebSocketClient.ts | |
parent | refactor: rename CallKind to Polarity (diff) | |
download | refinery-4971c864a603e0c01f7ad84a23697905d096283b.tar.gz refinery-4971c864a603e0c01f7ad84a23697905d096283b.tar.zst refinery-4971c864a603e0c01f7ad84a23697905d096283b.zip |
feat(web): backend URL configuration
To point the frontend to a backend server, update the config.json
file in the website root.
The config.json is generated automatically in debug mode and when
running from a standalone jar.
Diffstat (limited to 'subprojects/frontend/src/xtext/XtextWebSocketClient.ts')
-rw-r--r-- | subprojects/frontend/src/xtext/XtextWebSocketClient.ts | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/subprojects/frontend/src/xtext/XtextWebSocketClient.ts b/subprojects/frontend/src/xtext/XtextWebSocketClient.ts index a39620cb..6b734546 100644 --- a/subprojects/frontend/src/xtext/XtextWebSocketClient.ts +++ b/subprojects/frontend/src/xtext/XtextWebSocketClient.ts | |||
@@ -7,7 +7,8 @@ import CancelledError from '../utils/CancelledError'; | |||
7 | import PendingTask from '../utils/PendingTask'; | 7 | import PendingTask from '../utils/PendingTask'; |
8 | import getLogger from '../utils/getLogger'; | 8 | import getLogger from '../utils/getLogger'; |
9 | 9 | ||
10 | import webSocketMachine, { isWebSocketURLLocal } from './webSocketMachine'; | 10 | import fetchBackendConfig from './fetchBackendConfig'; |
11 | import webSocketMachine from './webSocketMachine'; | ||
11 | import { | 12 | import { |
12 | type XtextWebPushService, | 13 | type XtextWebPushService, |
13 | XtextResponse, | 14 | XtextResponse, |
@@ -42,26 +43,18 @@ export default class XtextWebSocketClient { | |||
42 | private readonly pendingRequests = new Map<string, PendingTask<unknown>>(); | 43 | private readonly pendingRequests = new Map<string, PendingTask<unknown>>(); |
43 | 44 | ||
44 | private readonly interpreter = interpret( | 45 | private readonly interpreter = interpret( |
45 | webSocketMachine | 46 | webSocketMachine.withConfig({ |
46 | .withContext({ | 47 | actions: { |
47 | ...webSocketMachine.context, | 48 | openWebSocket: () => this.openWebSocket(), |
48 | webSocketURL: `${window.location.origin.replace( | 49 | closeWebSocket: () => this.closeWebSocket(), |
49 | /^http/, | 50 | notifyReconnect: () => this.onReconnect(), |
50 | 'ws', | 51 | notifyDisconnect: () => this.onDisconnect(), |
51 | )}/xtext-service`, | 52 | cancelPendingRequests: () => this.cancelPendingRequests(), |
52 | }) | 53 | }, |
53 | .withConfig({ | 54 | services: { |
54 | actions: { | 55 | pingService: () => this.sendPing(), |
55 | openWebSocket: ({ webSocketURL }) => this.openWebSocket(webSocketURL), | 56 | }, |
56 | closeWebSocket: () => this.closeWebSocket(), | 57 | }), |
57 | notifyReconnect: () => this.onReconnect(), | ||
58 | notifyDisconnect: () => this.onDisconnect(), | ||
59 | cancelPendingRequests: () => this.cancelPendingRequests(), | ||
60 | }, | ||
61 | services: { | ||
62 | pingService: () => this.sendPing(), | ||
63 | }, | ||
64 | }), | ||
65 | { | 58 | { |
66 | logger: log.log.bind(log), | 59 | logger: log.log.bind(log), |
67 | }, | 60 | }, |
@@ -151,6 +144,7 @@ export default class XtextWebSocketClient { | |||
151 | | 'webSocket' | 144 | | 'webSocket' |
152 | | 'interpreter' | 145 | | 'interpreter' |
153 | | 'openListener' | 146 | | 'openListener' |
147 | | 'openWebSocket' | ||
154 | | 'errorListener' | 148 | | 'errorListener' |
155 | | 'closeListener' | 149 | | 'closeListener' |
156 | | 'messageListener' | 150 | | 'messageListener' |
@@ -160,6 +154,7 @@ export default class XtextWebSocketClient { | |||
160 | webSocket: observable.ref, | 154 | webSocket: observable.ref, |
161 | interpreter: false, | 155 | interpreter: false, |
162 | openListener: false, | 156 | openListener: false, |
157 | openWebSocket: false, | ||
163 | errorListener: false, | 158 | errorListener: false, |
164 | closeListener: false, | 159 | closeListener: false, |
165 | messageListener: false, | 160 | messageListener: false, |
@@ -221,9 +216,7 @@ export default class XtextWebSocketClient { | |||
221 | get networkMissing(): boolean { | 216 | get networkMissing(): boolean { |
222 | return ( | 217 | return ( |
223 | this.state.matches('connection.temporarilyOffline') || | 218 | this.state.matches('connection.temporarilyOffline') || |
224 | (this.disconnectedByUser && | 219 | (this.disconnectedByUser && this.state.matches('network.offline')) |
225 | this.state.matches('network.offline') && | ||
226 | !isWebSocketURLLocal(this.state.context.webSocketURL)) | ||
227 | ); | 220 | ); |
228 | } | 221 | } |
229 | 222 | ||
@@ -275,17 +268,27 @@ export default class XtextWebSocketClient { | |||
275 | this.interpreter.send(document.hidden ? 'TAB_HIDDEN' : 'TAB_VISIBLE'); | 268 | this.interpreter.send(document.hidden ? 'TAB_HIDDEN' : 'TAB_VISIBLE'); |
276 | } | 269 | } |
277 | 270 | ||
278 | private openWebSocket(webSocketURL: string | undefined): void { | 271 | private openWebSocket(): void { |
279 | if (this.webSocket !== undefined) { | 272 | if (this.webSocket !== undefined) { |
280 | throw new Error('WebSocket already open'); | 273 | throw new Error('WebSocket already open'); |
281 | } | 274 | } |
282 | 275 | ||
283 | if (webSocketURL === undefined) { | ||
284 | throw new Error('URL not configured'); | ||
285 | } | ||
286 | |||
287 | log.debug('Creating WebSocket'); | 276 | log.debug('Creating WebSocket'); |
288 | 277 | ||
278 | (async () => { | ||
279 | const { webSocketURL } = await fetchBackendConfig(); | ||
280 | this.openWebSocketWithURL(webSocketURL); | ||
281 | })().catch((error) => { | ||
282 | log.error('Error while initializing connection', error); | ||
283 | const message = error instanceof Error ? error.message : String(error); | ||
284 | this.interpreter.send({ | ||
285 | type: 'ERROR', | ||
286 | message, | ||
287 | }); | ||
288 | }); | ||
289 | } | ||
290 | |||
291 | private openWebSocketWithURL(webSocketURL: string): void { | ||
289 | this.webSocket = new WebSocket(webSocketURL, XTEXT_SUBPROTOCOL_V1); | 292 | this.webSocket = new WebSocket(webSocketURL, XTEXT_SUBPROTOCOL_V1); |
290 | this.webSocket.addEventListener('open', this.openListener); | 293 | this.webSocket.addEventListener('open', this.openListener); |
291 | this.webSocket.addEventListener('close', this.closeListener); | 294 | this.webSocket.addEventListener('close', this.closeListener); |
@@ -295,7 +298,9 @@ export default class XtextWebSocketClient { | |||
295 | 298 | ||
296 | private closeWebSocket() { | 299 | private closeWebSocket() { |
297 | if (this.webSocket === undefined) { | 300 | if (this.webSocket === undefined) { |
298 | throw new Error('WebSocket already closed'); | 301 | // We might get here when there is a network error before the socket is initialized |
302 | // and we don't have to do anything to close it. | ||
303 | return; | ||
299 | } | 304 | } |
300 | 305 | ||
301 | log.debug('Closing WebSocket'); | 306 | log.debug('Closing WebSocket'); |