aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-10 14:35:24 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-10 14:35:24 +0100
commit4971c864a603e0c01f7ad84a23697905d096283b (patch)
treefc2ed2ced39aa50aa98602ad4bd2a9d877577dcd
parentrefactor: rename CallKind to Polarity (diff)
downloadrefinery-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.
-rw-r--r--package.json2
-rw-r--r--subprojects/frontend/package.json20
-rw-r--r--subprojects/frontend/src/RootStore.ts21
-rw-r--r--subprojects/frontend/src/xtext/XtextClient.ts3
-rw-r--r--subprojects/frontend/src/xtext/XtextWebSocketClient.ts65
-rw-r--r--subprojects/frontend/src/xtext/fetchBackendConfig.ts16
-rw-r--r--subprojects/frontend/src/xtext/webSocketMachine.ts36
-rw-r--r--subprojects/frontend/types/ImportMeta.d.ts1
-rw-r--r--subprojects/frontend/vite.config.ts25
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java5
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java29
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfig.java20
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfigServlet.java39
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java3
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java39
-rw-r--r--subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java22
-rw-r--r--yarn.lock228
17 files changed, 336 insertions, 238 deletions
diff --git a/package.json b/package.json
index 2f047d76..fd5c226a 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
10 }, 10 },
11 "packageManager": "yarn@3.2.4", 11 "packageManager": "yarn@3.2.4",
12 "devDependencies": { 12 "devDependencies": {
13 "eslint": "^8.26.0", 13 "eslint": "^8.27.0",
14 "typescript": "4.8.4" 14 "typescript": "4.8.4"
15 } 15 }
16} 16}
diff --git a/subprojects/frontend/package.json b/subprojects/frontend/package.json
index 10de68ee..ed4b101b 100644
--- a/subprojects/frontend/package.json
+++ b/subprojects/frontend/package.json
@@ -29,21 +29,21 @@
29 "@codemirror/lint": "^6.0.0", 29 "@codemirror/lint": "^6.0.0",
30 "@codemirror/search": "^6.2.2", 30 "@codemirror/search": "^6.2.2",
31 "@codemirror/state": "^6.1.2", 31 "@codemirror/state": "^6.1.2",
32 "@codemirror/view": "^6.4.0", 32 "@codemirror/view": "^6.4.1",
33 "@emotion/react": "^11.10.5", 33 "@emotion/react": "^11.10.5",
34 "@emotion/styled": "^11.10.5", 34 "@emotion/styled": "^11.10.5",
35 "@fontsource/inter": "^4.5.14", 35 "@fontsource/inter": "^4.5.14",
36 "@fontsource/jetbrains-mono": "^4.5.11", 36 "@fontsource/jetbrains-mono": "^4.5.11",
37 "@lezer/common": "^1.0.1", 37 "@lezer/common": "^1.0.1",
38 "@lezer/highlight": "^1.1.2", 38 "@lezer/highlight": "^1.1.2",
39 "@lezer/lr": "^1.2.3", 39 "@lezer/lr": "^1.2.4",
40 "@material-icons/svg": "^1.0.33", 40 "@material-icons/svg": "^1.0.33",
41 "@mui/icons-material": "5.10.9", 41 "@mui/icons-material": "5.10.9",
42 "@mui/material": "5.10.12", 42 "@mui/material": "5.10.13",
43 "ansi-styles": "^6.2.1", 43 "ansi-styles": "^6.2.1",
44 "escape-string-regexp": "^5.0.0", 44 "escape-string-regexp": "^5.0.0",
45 "lodash-es": "^4.17.21", 45 "lodash-es": "^4.17.21",
46 "loglevel": "^1.8.0", 46 "loglevel": "^1.8.1",
47 "loglevel-plugin-prefix": "^0.8.4", 47 "loglevel-plugin-prefix": "^0.8.4",
48 "mobx": "^6.6.2", 48 "mobx": "^6.6.2",
49 "mobx-react-lite": "^3.4.0", 49 "mobx-react-lite": "^3.4.0",
@@ -56,7 +56,7 @@
56 "zod": "^3.19.1" 56 "zod": "^3.19.1"
57 }, 57 },
58 "devDependencies": { 58 "devDependencies": {
59 "@lezer/generator": "^1.1.1", 59 "@lezer/generator": "^1.1.3",
60 "@types/eslint": "^8.4.10", 60 "@types/eslint": "^8.4.10",
61 "@types/html-minifier-terser": "^7.0.0", 61 "@types/html-minifier-terser": "^7.0.0",
62 "@types/lodash-es": "^4.17.6", 62 "@types/lodash-es": "^4.17.6",
@@ -65,12 +65,12 @@
65 "@types/prettier": "^2.7.1", 65 "@types/prettier": "^2.7.1",
66 "@types/react": "^18.0.25", 66 "@types/react": "^18.0.25",
67 "@types/react-dom": "^18.0.8", 67 "@types/react-dom": "^18.0.8",
68 "@typescript-eslint/eslint-plugin": "^5.42.0", 68 "@typescript-eslint/eslint-plugin": "^5.42.1",
69 "@typescript-eslint/parser": "^5.42.0", 69 "@typescript-eslint/parser": "^5.42.1",
70 "@vitejs/plugin-react": "^2.2.0", 70 "@vitejs/plugin-react": "^2.2.0",
71 "@xstate/cli": "^0.3.3", 71 "@xstate/cli": "^0.3.3",
72 "cross-env": "^7.0.3", 72 "cross-env": "^7.0.3",
73 "eslint": "^8.26.0", 73 "eslint": "^8.27.0",
74 "eslint-config-airbnb": "^19.0.4", 74 "eslint-config-airbnb": "^19.0.4",
75 "eslint-config-airbnb-typescript": "^17.0.0", 75 "eslint-config-airbnb-typescript": "^17.0.0",
76 "eslint-config-prettier": "^8.5.0", 76 "eslint-config-prettier": "^8.5.0",
@@ -84,9 +84,9 @@
84 "html-minifier-terser": "^7.0.0", 84 "html-minifier-terser": "^7.0.0",
85 "prettier": "^2.7.1", 85 "prettier": "^2.7.1",
86 "typescript": "4.8.4", 86 "typescript": "4.8.4",
87 "vite": "^3.2.2", 87 "vite": "^3.2.3",
88 "vite-plugin-inject-preload": "^1.1.0", 88 "vite-plugin-inject-preload": "^1.1.0",
89 "vite-plugin-pwa": "^0.13.2", 89 "vite-plugin-pwa": "^0.13.3",
90 "workbox-window": "^6.5.4" 90 "workbox-window": "^6.5.4"
91 } 91 }
92} 92}
diff --git a/subprojects/frontend/src/RootStore.ts b/subprojects/frontend/src/RootStore.ts
index 54a80501..2e76d66d 100644
--- a/subprojects/frontend/src/RootStore.ts
+++ b/subprojects/frontend/src/RootStore.ts
@@ -23,18 +23,17 @@ export default class RootStore {
23 pwaStore: false, 23 pwaStore: false,
24 themeStore: false, 24 themeStore: false,
25 }); 25 });
26 import('./editor/EditorStore') 26 (async () => {
27 .then(({ default: EditorStore }) => { 27 const { default: EditorStore } = await import('./editor/EditorStore');
28 runInAction(() => { 28 runInAction(() => {
29 if (this.disposed) { 29 if (this.disposed) {
30 return; 30 return;
31 } 31 }
32 this.editorStore = new EditorStore(initialValue, this.pwaStore); 32 this.editorStore = new EditorStore(initialValue, this.pwaStore);
33 });
34 })
35 .catch((error) => {
36 log.error('Failed to load EditorStore', error);
37 }); 33 });
34 })().catch((error) => {
35 log.error('Failed to load EditorStore', error);
36 });
38 } 37 }
39 38
40 dispose(): void { 39 dispose(): void {
diff --git a/subprojects/frontend/src/xtext/XtextClient.ts b/subprojects/frontend/src/xtext/XtextClient.ts
index e7d26ae6..14fb2430 100644
--- a/subprojects/frontend/src/xtext/XtextClient.ts
+++ b/subprojects/frontend/src/xtext/XtextClient.ts
@@ -35,8 +35,7 @@ export default class XtextClient {
35 this.webSocketClient = new XtextWebSocketClient( 35 this.webSocketClient = new XtextWebSocketClient(
36 () => this.onReconnect(), 36 () => this.onReconnect(),
37 () => this.onDisconnect(), 37 () => this.onDisconnect(),
38 (resource, stateId, service, push) => 38 this.onPush.bind(this),
39 this.onPush(resource, stateId, service, push),
40 ); 39 );
41 this.updateService = new UpdateService(store, this.webSocketClient); 40 this.updateService = new UpdateService(store, this.webSocketClient);
42 this.contentAssistService = new ContentAssistService(this.updateService); 41 this.contentAssistService = new ContentAssistService(this.updateService);
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';
7import PendingTask from '../utils/PendingTask'; 7import PendingTask from '../utils/PendingTask';
8import getLogger from '../utils/getLogger'; 8import getLogger from '../utils/getLogger';
9 9
10import webSocketMachine, { isWebSocketURLLocal } from './webSocketMachine'; 10import fetchBackendConfig from './fetchBackendConfig';
11import webSocketMachine from './webSocketMachine';
11import { 12import {
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');
diff --git a/subprojects/frontend/src/xtext/fetchBackendConfig.ts b/subprojects/frontend/src/xtext/fetchBackendConfig.ts
new file mode 100644
index 00000000..f8087a70
--- /dev/null
+++ b/subprojects/frontend/src/xtext/fetchBackendConfig.ts
@@ -0,0 +1,16 @@
1/* eslint-disable @typescript-eslint/no-redeclare -- Declare types with their companion objects */
2
3import { z } from 'zod';
4
5export const BackendConfig = z.object({
6 webSocketURL: z.string().url(),
7});
8
9export type BackendConfig = z.infer<typeof BackendConfig>;
10
11export default async function fetchBackendConfig(): Promise<BackendConfig> {
12 const configURL = `${import.meta.env.BASE_URL}config.json`;
13 const response = await fetch(configURL);
14 const rawConfig = (await response.json()) as unknown;
15 return BackendConfig.parse(rawConfig);
16}
diff --git a/subprojects/frontend/src/xtext/webSocketMachine.ts b/subprojects/frontend/src/xtext/webSocketMachine.ts
index b5b40d11..5f6bc604 100644
--- a/subprojects/frontend/src/xtext/webSocketMachine.ts
+++ b/subprojects/frontend/src/xtext/webSocketMachine.ts
@@ -6,12 +6,10 @@ const { raise } = actions;
6const ERROR_WAIT_TIMES = ['200', '1s', '5s', '30s'].map(ms); 6const ERROR_WAIT_TIMES = ['200', '1s', '5s', '30s'].map(ms);
7 7
8export interface WebSocketContext { 8export interface WebSocketContext {
9 webSocketURL: string | undefined;
10 errors: string[]; 9 errors: string[];
11} 10}
12 11
13export type WebSocketEvent = 12export type WebSocketEvent =
14 | { type: 'CONFIGURE'; webSocketURL: string }
15 | { type: 'CONNECT' } 13 | { type: 'CONNECT' }
16 | { type: 'DISCONNECT' } 14 | { type: 'DISCONNECT' }
17 | { type: 'OPENED' } 15 | { type: 'OPENED' }
@@ -25,24 +23,6 @@ export type WebSocketEvent =
25 | { type: 'OFFLINE' } 23 | { type: 'OFFLINE' }
26 | { type: 'ERROR'; message: string }; 24 | { type: 'ERROR'; message: string };
27 25
28export function isWebSocketURLLocal(webSocketURL: string | undefined): boolean {
29 if (webSocketURL === undefined) {
30 return false;
31 }
32 let hostname: string;
33 try {
34 ({ hostname } = new URL(webSocketURL));
35 } catch {
36 return false;
37 }
38 // https://stackoverflow.com/a/57949518
39 return (
40 hostname === 'localhost' ||
41 hostname === '[::1]' ||
42 hostname.match(/^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/) !== null
43 );
44}
45
46export default createMachine( 26export default createMachine(
47 { 27 {
48 id: 'webSocket', 28 id: 'webSocket',
@@ -53,7 +33,6 @@ export default createMachine(
53 }, 33 },
54 tsTypes: {} as import('./webSocketMachine.typegen').Typegen0, 34 tsTypes: {} as import('./webSocketMachine.typegen').Typegen0,
55 context: { 35 context: {
56 webSocketURL: undefined,
57 errors: [], 36 errors: [],
58 }, 37 },
59 type: 'parallel', 38 type: 'parallel',
@@ -65,16 +44,12 @@ export default createMachine(
65 disconnected: { 44 disconnected: {
66 id: 'disconnected', 45 id: 'disconnected',
67 entry: ['clearErrors', 'notifyDisconnect'], 46 entry: ['clearErrors', 'notifyDisconnect'],
68 on: {
69 CONFIGURE: { actions: 'configure' },
70 },
71 }, 47 },
72 timedOut: { 48 timedOut: {
73 id: 'timedOut', 49 id: 'timedOut',
74 always: [ 50 always: [
75 { 51 {
76 target: 'temporarilyOffline', 52 target: 'temporarilyOffline',
77 cond: 'needsNetwork',
78 in: '#offline', 53 in: '#offline',
79 }, 54 },
80 { target: 'socketCreated', in: '#tabVisible' }, 55 { target: 'socketCreated', in: '#tabVisible' },
@@ -89,7 +64,6 @@ export default createMachine(
89 always: [ 64 always: [
90 { 65 {
91 target: 'temporarilyOffline', 66 target: 'temporarilyOffline',
92 cond: 'needsNetwork',
93 in: '#offline', 67 in: '#offline',
94 }, 68 },
95 ], 69 ],
@@ -183,7 +157,7 @@ export default createMachine(
183 }, 157 },
184 }, 158 },
185 on: { 159 on: {
186 CONNECT: { target: '.timedOut', cond: 'hasWebSocketURL' }, 160 CONNECT: '.timedOut',
187 DISCONNECT: '.disconnected', 161 DISCONNECT: '.disconnected',
188 }, 162 },
189 }, 163 },
@@ -224,10 +198,6 @@ export default createMachine(
224 }, 198 },
225 }, 199 },
226 { 200 {
227 guards: {
228 hasWebSocketURL: ({ webSocketURL }) => webSocketURL !== undefined,
229 needsNetwork: ({ webSocketURL }) => !isWebSocketURLLocal(webSocketURL),
230 },
231 delays: { 201 delays: {
232 IDLE_TIMEOUT: ms('5m'), 202 IDLE_TIMEOUT: ms('5m'),
233 OPEN_TIMEOUT: ms('10s'), 203 OPEN_TIMEOUT: ms('10s'),
@@ -239,10 +209,6 @@ export default createMachine(
239 }, 209 },
240 }, 210 },
241 actions: { 211 actions: {
242 configure: assign((context, { webSocketURL }) => ({
243 ...context,
244 webSocketURL,
245 })),
246 pushError: assign((context, { message }) => ({ 212 pushError: assign((context, { message }) => ({
247 ...context, 213 ...context,
248 errors: [...context.errors, message], 214 errors: [...context.errors, message],
diff --git a/subprojects/frontend/types/ImportMeta.d.ts b/subprojects/frontend/types/ImportMeta.d.ts
index 2008e268..c32b48f5 100644
--- a/subprojects/frontend/types/ImportMeta.d.ts
+++ b/subprojects/frontend/types/ImportMeta.d.ts
@@ -1,5 +1,6 @@
1interface ImportMeta { 1interface ImportMeta {
2 env: { 2 env: {
3 BASE_URL: string;
3 DEV: boolean; 4 DEV: boolean;
4 MODE: string; 5 MODE: string;
5 PROD: boolean; 6 PROD: boolean;
diff --git a/subprojects/frontend/vite.config.ts b/subprojects/frontend/vite.config.ts
index e690d005..526ea541 100644
--- a/subprojects/frontend/vite.config.ts
+++ b/subprojects/frontend/vite.config.ts
@@ -30,6 +30,7 @@ const apiPort = portNumberOrElse('API_PORT', 1312);
30const apiSecure = apiPort === 443; 30const apiSecure = apiPort === 443;
31const publicHost = process.env.PUBLIC_HOST || listenHost; 31const publicHost = process.env.PUBLIC_HOST || listenHost;
32const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort); 32const publicPort = portNumberOrElse('PUBLIC_PORT', listenPort);
33const publicSecure = publicPort === 443;
33 34
34const { name: packageName, version: packageVersion } = JSON.parse( 35const { name: packageName, version: packageVersion } = JSON.parse(
35 readFileSync(path.join(thisDir, 'package.json'), 'utf8'), 36 readFileSync(path.join(thisDir, 'package.json'), 'utf8'),
@@ -56,6 +57,23 @@ const minifyPlugin: PluginOption = {
56 }, 57 },
57}; 58};
58 59
60const backendConfigPlugin: PluginOption = {
61 name: 'backend-config',
62 configureServer(server) {
63 const protocol = publicSecure ? 'wss' : 'ws';
64 const webSocketURL = `${protocol}://${publicHost}:${publicPort}/xtext-service`;
65 const config = JSON.stringify({ webSocketURL });
66 server.middlewares.use((req, res, next) => {
67 if (req.url === '/config.json') {
68 res.setHeader('Content-Type', 'application/json');
69 res.end(config);
70 } else {
71 next();
72 }
73 });
74 },
75};
76
59export default defineConfig({ 77export default defineConfig({
60 logLevel: 'info', 78 logLevel: 'info',
61 mode, 79 mode,
@@ -63,6 +81,7 @@ export default defineConfig({
63 cacheDir: path.join(thisDir, 'build/vite/cache'), 81 cacheDir: path.join(thisDir, 'build/vite/cache'),
64 plugins: [ 82 plugins: [
65 minifyPlugin, 83 minifyPlugin,
84 backendConfigPlugin,
66 react(), 85 react(),
67 injectPreload({ 86 injectPreload({
68 files: [ 87 files: [
@@ -90,6 +109,12 @@ export default defineConfig({
90 ], 109 ],
91 dontCacheBustURLsMatching: /\.(?:css|js|woff2?)$/, 110 dontCacheBustURLsMatching: /\.(?:css|js|woff2?)$/,
92 navigateFallbackDenylist: [/^\/xtext-service/], 111 navigateFallbackDenylist: [/^\/xtext-service/],
112 runtimeCaching: [
113 {
114 urlPattern: 'config.json',
115 handler: 'StaleWhileRevalidate',
116 },
117 ],
93 }, 118 },
94 includeAssets: ['apple-touch-icon.png', 'favicon.svg', 'mask-icon.svg'], 119 includeAssets: ['apple-touch-icon.png', 'favicon.svg', 'mask-icon.svg'],
95 manifest: { 120 manifest: {
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
index fbce62c1..fd2af1b2 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/CacheControlFilter.java
@@ -13,8 +13,9 @@ import java.util.regex.Pattern;
13public class CacheControlFilter implements Filter { 13public class CacheControlFilter implements Filter {
14 private static final Pattern CACHE_URI_PATTERN = Pattern.compile(".*\\.(css|gif|js|map|png|svg|woff2?)"); 14 private static final Pattern CACHE_URI_PATTERN = Pattern.compile(".*\\.(css|gif|js|map|png|svg|woff2?)");
15 15
16 private static final Set<String> CACHE_URI_DENYLIST = Set.of("apple-touch-icon.png", "favicon.png", "favicon.svg", 16 private static final Set<String> CACHE_URI_DENYLIST = Set.of("apple-touch-icon.png", "config.json", "favicon.png",
17 "favicon-96x96.png", "icon-any.svg", "icon-192x192.png", "icon-512x512.png", "mask-icon.svg", "sw.js"); 17 "favicon.svg", "favicon-96x96.png", "icon-any.svg", "icon-192x192.png", "icon-512x512.png", "mask-icon.svg",
18 "sw.js");
18 19
19 private static final Duration EXPIRY = Duration.ofDays(365); 20 private static final Duration EXPIRY = Duration.ofDays(365);
20 21
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
index ffa61321..58c8ea4e 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/ServerLauncher.java
@@ -14,6 +14,7 @@ import org.eclipse.jetty.util.resource.Resource;
14import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer; 14import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
15import org.slf4j.Logger; 15import org.slf4j.Logger;
16import org.slf4j.LoggerFactory; 16import org.slf4j.LoggerFactory;
17import tools.refinery.language.web.config.BackendConfigServlet;
17import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet; 18import tools.refinery.language.web.xtext.servlet.XtextWebSocketServlet;
18 19
19import java.io.File; 20import java.io.File;
@@ -41,11 +42,13 @@ public class ServerLauncher {
41 42
42 private final Server server; 43 private final Server server;
43 44
44 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource, String[] allowedOrigins) { 45 public ServerLauncher(InetSocketAddress bindAddress, Resource baseResource, String[] allowedOrigins,
46 String webSocketUrl) {
45 server = new Server(bindAddress); 47 server = new Server(bindAddress);
46 var handler = new ServletContextHandler(); 48 var handler = new ServletContextHandler();
47 addSessionHandler(handler); 49 addSessionHandler(handler);
48 addProblemServlet(handler, allowedOrigins); 50 addProblemServlet(handler, allowedOrigins);
51 addBackendConfigServlet(handler, webSocketUrl);
49 if (baseResource != null) { 52 if (baseResource != null) {
50 handler.setBaseResource(baseResource); 53 handler.setBaseResource(baseResource);
51 handler.setWelcomeFiles(new String[]{"index.html"}); 54 handler.setWelcomeFiles(new String[]{"index.html"});
@@ -76,6 +79,12 @@ public class ServerLauncher {
76 JettyWebSocketServletContainerInitializer.configure(handler, null); 79 JettyWebSocketServletContainerInitializer.configure(handler, null);
77 } 80 }
78 81
82 private void addBackendConfigServlet(ServletContextHandler handler, String webSocketUrl) {
83 var backendConfigServletHolder = new ServletHolder(BackendConfigServlet.class);
84 backendConfigServletHolder.setInitParameter(BackendConfigServlet.WEBSOCKET_URL_INIT_PARAM, webSocketUrl);
85 handler.addServlet(backendConfigServletHolder, "/config.json");
86 }
87
79 private void addDefaultServlet(ServletContextHandler handler) { 88 private void addDefaultServlet(ServletContextHandler handler) {
80 var defaultServletHolder = new ServletHolder(DefaultServlet.class); 89 var defaultServletHolder = new ServletHolder(DefaultServlet.class);
81 var isWindows = System.getProperty("os.name").toLowerCase().contains("win"); 90 var isWindows = System.getProperty("os.name").toLowerCase().contains("win");
@@ -97,7 +106,8 @@ public class ServerLauncher {
97 var bindAddress = getBindAddress(); 106 var bindAddress = getBindAddress();
98 var baseResource = getBaseResource(); 107 var baseResource = getBaseResource();
99 var allowedOrigins = getAllowedOrigins(); 108 var allowedOrigins = getAllowedOrigins();
100 var serverLauncher = new ServerLauncher(bindAddress, baseResource, allowedOrigins); 109 var webSocketUrl = getWebSocketUrl();
110 var serverLauncher = new ServerLauncher(bindAddress, baseResource, allowedOrigins, webSocketUrl);
101 serverLauncher.start(); 111 serverLauncher.start();
102 } catch (Exception exception) { 112 } catch (Exception exception) {
103 LOG.error("Fatal server error", exception); 113 LOG.error("Fatal server error", exception);
@@ -190,4 +200,19 @@ public class ServerLauncher {
190 } 200 }
191 return new String[]{urlWithPort}; 201 return new String[]{urlWithPort};
192 } 202 }
203
204 private static String getWebSocketUrl() {
205 String host;
206 int port;
207 var publicHost = getPublicHost();
208 if (publicHost == null) {
209 host = getListenAddress();
210 port = getListenPort();
211 } else {
212 host = publicHost;
213 port = getPublicPort();
214 }
215 var scheme = port == HTTPS_DEFAULT_PORT ? "wss" : "ws";
216 return String.format("%s://%s:%d/xtext-service", scheme, host, port);
217 }
193} 218}
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfig.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfig.java
new file mode 100644
index 00000000..2e864998
--- /dev/null
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfig.java
@@ -0,0 +1,20 @@
1package tools.refinery.language.web.config;
2
3import com.google.gson.annotations.SerializedName;
4
5public class BackendConfig {
6 @SerializedName("webSocketURL")
7 private String webSocketUrl;
8
9 public BackendConfig(String webSocketUrl) {
10 this.webSocketUrl = webSocketUrl;
11 }
12
13 public String getWebSocketUrl() {
14 return webSocketUrl;
15 }
16
17 public void setWebSocketUrl(String webSocketUrl) {
18 this.webSocketUrl = webSocketUrl;
19 }
20}
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfigServlet.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfigServlet.java
new file mode 100644
index 00000000..f314a9fa
--- /dev/null
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/config/BackendConfigServlet.java
@@ -0,0 +1,39 @@
1package tools.refinery.language.web.config;
2
3import com.google.gson.Gson;
4import jakarta.servlet.ServletConfig;
5import jakarta.servlet.ServletException;
6import jakarta.servlet.http.HttpServlet;
7import jakarta.servlet.http.HttpServletRequest;
8import jakarta.servlet.http.HttpServletResponse;
9import org.eclipse.jetty.http.HttpStatus;
10
11import java.io.IOException;
12
13public class BackendConfigServlet extends HttpServlet {
14 public static final String WEBSOCKET_URL_INIT_PARAM = "tools.refinery.language.web.config.BackendConfigServlet" +
15 ".webSocketUrl";
16
17 private String serializedConfig;
18
19 @Override
20 public void init(ServletConfig config) throws ServletException {
21 super.init(config);
22 var webSocketUrl = config.getInitParameter(WEBSOCKET_URL_INIT_PARAM);
23 if (webSocketUrl == null) {
24 throw new IllegalArgumentException("Init parameter " + WEBSOCKET_URL_INIT_PARAM + " is mandatory");
25 }
26 var backendConfig = new BackendConfig(webSocketUrl);
27 var gson = new Gson();
28 serializedConfig = gson.toJson(backendConfig);
29 }
30
31 @Override
32 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
33 resp.setStatus(HttpStatus.OK_200);
34 resp.setContentType("application/json");
35 var writer = resp.getWriter();
36 writer.write(serializedConfig);
37 writer.flush();
38 }
39}
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java
index 34fcb546..b686d33a 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/ResponseHandlerException.java
@@ -1,7 +1,10 @@
1package tools.refinery.language.web.xtext.server; 1package tools.refinery.language.web.xtext.server;
2 2
3import java.io.Serial;
4
3public class ResponseHandlerException extends Exception { 5public class ResponseHandlerException extends Exception {
4 6
7 @Serial
5 private static final long serialVersionUID = 3589866922420268164L; 8 private static final long serialVersionUID = 3589866922420268164L;
6 9
7 public ResponseHandlerException(String message, Throwable cause) { 10 public ResponseHandlerException(String message, Throwable cause) {
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java
index 0b417b06..7bb11d2e 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/server/TransactionExecutor.java
@@ -1,35 +1,25 @@
1package tools.refinery.language.web.xtext.server; 1package tools.refinery.language.web.xtext.server;
2 2
3import java.lang.ref.WeakReference; 3import com.google.common.base.Strings;
4import java.util.ArrayList; 4import com.google.inject.Injector;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
8
9import org.eclipse.emf.common.util.URI; 5import org.eclipse.emf.common.util.URI;
10import org.eclipse.xtext.resource.IResourceServiceProvider; 6import org.eclipse.xtext.resource.IResourceServiceProvider;
11import org.eclipse.xtext.util.IDisposable; 7import org.eclipse.xtext.util.IDisposable;
12import org.eclipse.xtext.web.server.IServiceContext; 8import org.eclipse.xtext.web.server.*;
13import org.eclipse.xtext.web.server.IServiceResult;
14import org.eclipse.xtext.web.server.ISession;
15import org.eclipse.xtext.web.server.InvalidRequestException;
16import org.eclipse.xtext.web.server.InvalidRequestException.UnknownLanguageException; 9import org.eclipse.xtext.web.server.InvalidRequestException.UnknownLanguageException;
17import org.eclipse.xtext.web.server.XtextServiceDispatcher;
18import org.slf4j.Logger; 10import org.slf4j.Logger;
19import org.slf4j.LoggerFactory; 11import org.slf4j.LoggerFactory;
20 12import tools.refinery.language.web.xtext.server.message.*;
21import com.google.common.base.Strings;
22import com.google.inject.Injector;
23
24import tools.refinery.language.web.xtext.server.message.XtextWebErrorKind;
25import tools.refinery.language.web.xtext.server.message.XtextWebErrorResponse;
26import tools.refinery.language.web.xtext.server.message.XtextWebOkResponse;
27import tools.refinery.language.web.xtext.server.message.XtextWebPushMessage;
28import tools.refinery.language.web.xtext.server.message.XtextWebRequest;
29import tools.refinery.language.web.xtext.server.push.PrecomputationListener; 13import tools.refinery.language.web.xtext.server.push.PrecomputationListener;
30import tools.refinery.language.web.xtext.server.push.PushWebDocument; 14import tools.refinery.language.web.xtext.server.push.PushWebDocument;
31import tools.refinery.language.web.xtext.servlet.SimpleServiceContext; 15import tools.refinery.language.web.xtext.servlet.SimpleServiceContext;
32 16
17import java.lang.ref.WeakReference;
18import java.util.ArrayList;
19import java.util.HashMap;
20import java.util.List;
21import java.util.Map;
22
33public class TransactionExecutor implements IDisposable, PrecomputationListener { 23public class TransactionExecutor implements IDisposable, PrecomputationListener {
34 private static final Logger LOG = LoggerFactory.getLogger(TransactionExecutor.class); 24 private static final Logger LOG = LoggerFactory.getLogger(TransactionExecutor.class);
35 25
@@ -41,11 +31,11 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener
41 31
42 private ResponseHandler responseHandler; 32 private ResponseHandler responseHandler;
43 33
44 private Object callPendingLock = new Object(); 34 private final Object callPendingLock = new Object();
45 35
46 private boolean callPending; 36 private boolean callPending;
47 37
48 private List<XtextWebPushMessage> pendingPushMessages = new ArrayList<>(); 38 private final List<XtextWebPushMessage> pendingPushMessages = new ArrayList<>();
49 39
50 public TransactionExecutor(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) { 40 public TransactionExecutor(ISession session, IResourceServiceProvider.Registry resourceServiceProviderRegistry) {
51 this.session = session; 41 this.session = session;
@@ -132,10 +122,9 @@ public class TransactionExecutor implements IDisposable, PrecomputationListener
132 122
133 /** 123 /**
134 * Get the injector to satisfy the request in the {@code serviceContext}. 124 * Get the injector to satisfy the request in the {@code serviceContext}.
135 *
136 * Based on {@link org.eclipse.xtext.web.servlet.XtextServlet#getInjector}. 125 * Based on {@link org.eclipse.xtext.web.servlet.XtextServlet#getInjector}.
137 * 126 *
138 * @param serviceContext the Xtext service context of the request 127 * @param context the Xtext service context of the request
139 * @return the injector for the Xtext language in the request 128 * @return the injector for the Xtext language in the request
140 * @throws UnknownLanguageException if the Xtext language cannot be determined 129 * @throws UnknownLanguageException if the Xtext language cannot be determined
141 */ 130 */
diff --git a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
index fd41f213..82391d8b 100644
--- a/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
+++ b/subprojects/language-web/src/main/java/tools/refinery/language/web/xtext/servlet/XtextWebSocket.java
@@ -1,31 +1,25 @@
1package tools.refinery.language.web.xtext.servlet; 1package tools.refinery.language.web.xtext.servlet;
2 2
3import java.io.IOException; 3import com.google.gson.Gson;
4import java.io.Reader; 4import com.google.gson.JsonIOException;
5 5import com.google.gson.JsonParseException;
6import org.eclipse.jetty.websocket.api.Session; 6import org.eclipse.jetty.websocket.api.Session;
7import org.eclipse.jetty.websocket.api.StatusCode; 7import org.eclipse.jetty.websocket.api.StatusCode;
8import org.eclipse.jetty.websocket.api.WriteCallback; 8import org.eclipse.jetty.websocket.api.WriteCallback;
9import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; 9import org.eclipse.jetty.websocket.api.annotations.*;
10import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
11import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
12import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
13import org.eclipse.jetty.websocket.api.annotations.WebSocket;
14import org.eclipse.xtext.resource.IResourceServiceProvider; 10import org.eclipse.xtext.resource.IResourceServiceProvider;
15import org.eclipse.xtext.web.server.ISession; 11import org.eclipse.xtext.web.server.ISession;
16import org.slf4j.Logger; 12import org.slf4j.Logger;
17import org.slf4j.LoggerFactory; 13import org.slf4j.LoggerFactory;
18
19import com.google.gson.Gson;
20import com.google.gson.JsonIOException;
21import com.google.gson.JsonParseException;
22
23import tools.refinery.language.web.xtext.server.ResponseHandler; 14import tools.refinery.language.web.xtext.server.ResponseHandler;
24import tools.refinery.language.web.xtext.server.ResponseHandlerException; 15import tools.refinery.language.web.xtext.server.ResponseHandlerException;
25import tools.refinery.language.web.xtext.server.TransactionExecutor; 16import tools.refinery.language.web.xtext.server.TransactionExecutor;
26import tools.refinery.language.web.xtext.server.message.XtextWebRequest; 17import tools.refinery.language.web.xtext.server.message.XtextWebRequest;
27import tools.refinery.language.web.xtext.server.message.XtextWebResponse; 18import tools.refinery.language.web.xtext.server.message.XtextWebResponse;
28 19
20import java.io.IOException;
21import java.io.Reader;
22
29@WebSocket 23@WebSocket
30public class XtextWebSocket implements WriteCallback, ResponseHandler { 24public class XtextWebSocket implements WriteCallback, ResponseHandler {
31 private static final Logger LOG = LoggerFactory.getLogger(XtextWebSocket.class); 25 private static final Logger LOG = LoggerFactory.getLogger(XtextWebSocket.class);
@@ -118,7 +112,7 @@ public class XtextWebSocket implements WriteCallback, ResponseHandler {
118 webSocketSession.getRemote().sendPartialString(responseString, true, this); 112 webSocketSession.getRemote().sendPartialString(responseString, true, this);
119 } catch (IOException e) { 113 } catch (IOException e) {
120 throw new ResponseHandlerException( 114 throw new ResponseHandlerException(
121 "Cannot initiaite async write to websocket " + webSocketSession.getRemoteAddress(), e); 115 "Cannot initiate async write to websocket " + webSocketSession.getRemoteAddress(), e);
122 } 116 }
123 } 117 }
124 118
diff --git a/yarn.lock b/yarn.lock
index 3834353e..2d4e7d31 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1407,14 +1407,14 @@ __metadata:
1407 languageName: node 1407 languageName: node
1408 linkType: hard 1408 linkType: hard
1409 1409
1410"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.4.0": 1410"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.4.1":
1411 version: 6.4.0 1411 version: 6.4.1
1412 resolution: "@codemirror/view@npm:6.4.0" 1412 resolution: "@codemirror/view@npm:6.4.1"
1413 dependencies: 1413 dependencies:
1414 "@codemirror/state": ^6.0.0 1414 "@codemirror/state": ^6.0.0
1415 style-mod: ^4.0.0 1415 style-mod: ^4.0.0
1416 w3c-keyname: ^2.2.4 1416 w3c-keyname: ^2.2.4
1417 checksum: 57ed7d9d51907f1ea549a2a158872fb7affa6cdff72e29e214f8437b7142ea2a2431ac3c780cbc0187dfff7cb5fd1055a45a887ea9b8c2a09d8430c60ebe9083 1417 checksum: 51f8e9bf1701cd490708784fd42a90dd9b2ad84aaebfacdbcfa9093e7f99ded38093ac49bc9eb037924b7734a58ed854a19621d931cce3f7962c2a0b30fecc23
1418 languageName: node 1418 languageName: node
1419 linkType: hard 1419 linkType: hard
1420 1420
@@ -1719,15 +1719,15 @@ __metadata:
1719 languageName: node 1719 languageName: node
1720 linkType: hard 1720 linkType: hard
1721 1721
1722"@lezer/generator@npm:^1.1.1": 1722"@lezer/generator@npm:^1.1.3":
1723 version: 1.1.1 1723 version: 1.1.3
1724 resolution: "@lezer/generator@npm:1.1.1" 1724 resolution: "@lezer/generator@npm:1.1.3"
1725 dependencies: 1725 dependencies:
1726 "@lezer/common": ^1.0.0 1726 "@lezer/common": ^1.0.0
1727 "@lezer/lr": ^1.0.0 1727 "@lezer/lr": ^1.0.0
1728 bin: 1728 bin:
1729 lezer-generator: dist/lezer-generator.cjs 1729 lezer-generator: dist/lezer-generator.cjs
1730 checksum: 16638471b593a40db5052f22df387bba323dba49dc92712927e86bc1333786680bbbaef24c16c81659e226da05d4583728641567d4058997de39e9aa6d4cdf20 1730 checksum: 50057aa2bdad39f2c30296e0043e5565a6020efc1ffd0729d25e0e07ef6037a8f151fcebdbcb9fa91bab676e9ecbd2edb4dba9e486a5c8f1a67d0bc1b7c92622
1731 languageName: node 1731 languageName: node
1732 linkType: hard 1732 linkType: hard
1733 1733
@@ -1740,12 +1740,12 @@ __metadata:
1740 languageName: node 1740 languageName: node
1741 linkType: hard 1741 linkType: hard
1742 1742
1743"@lezer/lr@npm:^1.0.0, @lezer/lr@npm:^1.2.3": 1743"@lezer/lr@npm:^1.0.0, @lezer/lr@npm:^1.2.4":
1744 version: 1.2.3 1744 version: 1.2.4
1745 resolution: "@lezer/lr@npm:1.2.3" 1745 resolution: "@lezer/lr@npm:1.2.4"
1746 dependencies: 1746 dependencies:
1747 "@lezer/common": ^1.0.0 1747 "@lezer/common": ^1.0.0
1748 checksum: 118db077d32f6eb9d6b219c766d7e5715c6c004d89d76ed0137ea2a364aeca67f21dc5924ea67a649b5de1d13bfbb85571923b38536e6995820eb0a5c8844594 1748 checksum: c3351c7e51692591abf84bdcf881a6c7547861b26f3f783ec75ead37d976dc21ec43ccdac315cb6cdfd9295b58db55bb42da3dd53ea05836a9f7f9e49c2d4c91
1749 languageName: node 1749 languageName: node
1750 linkType: hard 1750 linkType: hard
1751 1751
@@ -1756,9 +1756,9 @@ __metadata:
1756 languageName: node 1756 languageName: node
1757 linkType: hard 1757 linkType: hard
1758 1758
1759"@mui/base@npm:5.0.0-alpha.104": 1759"@mui/base@npm:5.0.0-alpha.105":
1760 version: 5.0.0-alpha.104 1760 version: 5.0.0-alpha.105
1761 resolution: "@mui/base@npm:5.0.0-alpha.104" 1761 resolution: "@mui/base@npm:5.0.0-alpha.105"
1762 dependencies: 1762 dependencies:
1763 "@babel/runtime": ^7.19.0 1763 "@babel/runtime": ^7.19.0
1764 "@emotion/is-prop-valid": ^1.2.0 1764 "@emotion/is-prop-valid": ^1.2.0
@@ -1775,14 +1775,14 @@ __metadata:
1775 peerDependenciesMeta: 1775 peerDependenciesMeta:
1776 "@types/react": 1776 "@types/react":
1777 optional: true 1777 optional: true
1778 checksum: f66693b4659bb50cc89b6b0e055db45d091bb546f82a4c6cc230f3699e647b68c941dcb8e8d42648e3470f83da5600f400ff21af9a8f7aaf6b018ac5ad3ceeb1 1778 checksum: 1db3dcd6760c814437c679ddf13d9e3c4e7fc6f51ce933445715a56aa65dcaeb38aff35832c524211d62fb3401b436cbcc3e9e4234068a0c3379da727f44cff2
1779 languageName: node 1779 languageName: node
1780 linkType: hard 1780 linkType: hard
1781 1781
1782"@mui/core-downloads-tracker@npm:^5.10.12": 1782"@mui/core-downloads-tracker@npm:^5.10.13":
1783 version: 5.10.12 1783 version: 5.10.13
1784 resolution: "@mui/core-downloads-tracker@npm:5.10.12" 1784 resolution: "@mui/core-downloads-tracker@npm:5.10.13"
1785 checksum: 894c7ee810851de2ee5de43648822e6f5ea639e4ab494fd54c9a6cb6dbace608b5634699fab05978f2d21efc4378bbce83b8352ef7aa958afd3d387c32373244 1785 checksum: 175d5779e8e4b6130c96d2ce990047ea58571f847a7041ca273564edc5411456296d1e094e350970d1294c4cc4d8459ea237f69e7917926a6530d5195fb41cc6
1786 languageName: node 1786 languageName: node
1787 linkType: hard 1787 linkType: hard
1788 1788
@@ -1802,14 +1802,14 @@ __metadata:
1802 languageName: node 1802 languageName: node
1803 linkType: hard 1803 linkType: hard
1804 1804
1805"@mui/material@npm:5.10.12": 1805"@mui/material@npm:5.10.13":
1806 version: 5.10.12 1806 version: 5.10.13
1807 resolution: "@mui/material@npm:5.10.12" 1807 resolution: "@mui/material@npm:5.10.13"
1808 dependencies: 1808 dependencies:
1809 "@babel/runtime": ^7.19.0 1809 "@babel/runtime": ^7.19.0
1810 "@mui/base": 5.0.0-alpha.104 1810 "@mui/base": 5.0.0-alpha.105
1811 "@mui/core-downloads-tracker": ^5.10.12 1811 "@mui/core-downloads-tracker": ^5.10.13
1812 "@mui/system": ^5.10.12 1812 "@mui/system": ^5.10.13
1813 "@mui/types": ^7.2.0 1813 "@mui/types": ^7.2.0
1814 "@mui/utils": ^5.10.9 1814 "@mui/utils": ^5.10.9
1815 "@types/react-transition-group": ^4.4.5 1815 "@types/react-transition-group": ^4.4.5
@@ -1831,7 +1831,7 @@ __metadata:
1831 optional: true 1831 optional: true
1832 "@types/react": 1832 "@types/react":
1833 optional: true 1833 optional: true
1834 checksum: 37b3d605d0cdb5136ac5a568d1c3c00ad5a3e01242cea6bccad5ccb08512e3c600dde75af852515c947b994fb5afa972044faac07416d347cbb6e503651c23a3 1834 checksum: 817e61e575a47b60cba54f826e8a090399f9332b192e2632efa9f82ae6bc44653fe6ab3606c047c29686a5b4ee3ec7bbd69b89c9a0dd6ca1e382aff23c0e5c96
1835 languageName: node 1835 languageName: node
1836 linkType: hard 1836 linkType: hard
1837 1837
@@ -1873,9 +1873,9 @@ __metadata:
1873 languageName: node 1873 languageName: node
1874 linkType: hard 1874 linkType: hard
1875 1875
1876"@mui/system@npm:^5.10.12": 1876"@mui/system@npm:^5.10.13":
1877 version: 5.10.12 1877 version: 5.10.13
1878 resolution: "@mui/system@npm:5.10.12" 1878 resolution: "@mui/system@npm:5.10.13"
1879 dependencies: 1879 dependencies:
1880 "@babel/runtime": ^7.19.0 1880 "@babel/runtime": ^7.19.0
1881 "@mui/private-theming": ^5.10.9 1881 "@mui/private-theming": ^5.10.9
@@ -1897,7 +1897,7 @@ __metadata:
1897 optional: true 1897 optional: true
1898 "@types/react": 1898 "@types/react":
1899 optional: true 1899 optional: true
1900 checksum: 1803a6f54bc1fda304834f362c60697b2ee157df7629b26337cb3d180093cbc244a94df45719da436b2917f98674687a98fea353a9ec8e6de7c5c3b5ba592bc8 1900 checksum: afac3f4859b9e137fa62fa4446642909704964209a44f63a472d452ace6428a0b337b48a934cd805e3728a0098ad4f41fedbc06ce14e245a5fa42fabe349d9e8
1901 languageName: node 1901 languageName: node
1902 linkType: hard 1902 linkType: hard
1903 1903
@@ -2006,18 +2006,18 @@ __metadata:
2006 "@codemirror/lint": ^6.0.0 2006 "@codemirror/lint": ^6.0.0
2007 "@codemirror/search": ^6.2.2 2007 "@codemirror/search": ^6.2.2
2008 "@codemirror/state": ^6.1.2 2008 "@codemirror/state": ^6.1.2
2009 "@codemirror/view": ^6.4.0 2009 "@codemirror/view": ^6.4.1
2010 "@emotion/react": ^11.10.5 2010 "@emotion/react": ^11.10.5
2011 "@emotion/styled": ^11.10.5 2011 "@emotion/styled": ^11.10.5
2012 "@fontsource/inter": ^4.5.14 2012 "@fontsource/inter": ^4.5.14
2013 "@fontsource/jetbrains-mono": ^4.5.11 2013 "@fontsource/jetbrains-mono": ^4.5.11
2014 "@lezer/common": ^1.0.1 2014 "@lezer/common": ^1.0.1
2015 "@lezer/generator": ^1.1.1 2015 "@lezer/generator": ^1.1.3
2016 "@lezer/highlight": ^1.1.2 2016 "@lezer/highlight": ^1.1.2
2017 "@lezer/lr": ^1.2.3 2017 "@lezer/lr": ^1.2.4
2018 "@material-icons/svg": ^1.0.33 2018 "@material-icons/svg": ^1.0.33
2019 "@mui/icons-material": 5.10.9 2019 "@mui/icons-material": 5.10.9
2020 "@mui/material": 5.10.12 2020 "@mui/material": 5.10.13
2021 "@types/eslint": ^8.4.10 2021 "@types/eslint": ^8.4.10
2022 "@types/html-minifier-terser": ^7.0.0 2022 "@types/html-minifier-terser": ^7.0.0
2023 "@types/lodash-es": ^4.17.6 2023 "@types/lodash-es": ^4.17.6
@@ -2026,14 +2026,14 @@ __metadata:
2026 "@types/prettier": ^2.7.1 2026 "@types/prettier": ^2.7.1
2027 "@types/react": ^18.0.25 2027 "@types/react": ^18.0.25
2028 "@types/react-dom": ^18.0.8 2028 "@types/react-dom": ^18.0.8
2029 "@typescript-eslint/eslint-plugin": ^5.42.0 2029 "@typescript-eslint/eslint-plugin": ^5.42.1
2030 "@typescript-eslint/parser": ^5.42.0 2030 "@typescript-eslint/parser": ^5.42.1
2031 "@vitejs/plugin-react": ^2.2.0 2031 "@vitejs/plugin-react": ^2.2.0
2032 "@xstate/cli": ^0.3.3 2032 "@xstate/cli": ^0.3.3
2033 ansi-styles: ^6.2.1 2033 ansi-styles: ^6.2.1
2034 cross-env: ^7.0.3 2034 cross-env: ^7.0.3
2035 escape-string-regexp: ^5.0.0 2035 escape-string-regexp: ^5.0.0
2036 eslint: ^8.26.0 2036 eslint: ^8.27.0
2037 eslint-config-airbnb: ^19.0.4 2037 eslint-config-airbnb: ^19.0.4
2038 eslint-config-airbnb-typescript: ^17.0.0 2038 eslint-config-airbnb-typescript: ^17.0.0
2039 eslint-config-prettier: ^8.5.0 2039 eslint-config-prettier: ^8.5.0
@@ -2046,7 +2046,7 @@ __metadata:
2046 eslint-plugin-react-hooks: ^4.6.0 2046 eslint-plugin-react-hooks: ^4.6.0
2047 html-minifier-terser: ^7.0.0 2047 html-minifier-terser: ^7.0.0
2048 lodash-es: ^4.17.21 2048 lodash-es: ^4.17.21
2049 loglevel: ^1.8.0 2049 loglevel: ^1.8.1
2050 loglevel-plugin-prefix: ^0.8.4 2050 loglevel-plugin-prefix: ^0.8.4
2051 mobx: ^6.6.2 2051 mobx: ^6.6.2
2052 mobx-react-lite: ^3.4.0 2052 mobx-react-lite: ^3.4.0
@@ -2057,9 +2057,9 @@ __metadata:
2057 react: ^18.2.0 2057 react: ^18.2.0
2058 react-dom: ^18.2.0 2058 react-dom: ^18.2.0
2059 typescript: 4.8.4 2059 typescript: 4.8.4
2060 vite: ^3.2.2 2060 vite: ^3.2.3
2061 vite-plugin-inject-preload: ^1.1.0 2061 vite-plugin-inject-preload: ^1.1.0
2062 vite-plugin-pwa: ^0.13.2 2062 vite-plugin-pwa: ^0.13.3
2063 workbox-window: ^6.5.4 2063 workbox-window: ^6.5.4
2064 xstate: ^4.34.0 2064 xstate: ^4.34.0
2065 zod: ^3.19.1 2065 zod: ^3.19.1
@@ -2070,7 +2070,7 @@ __metadata:
2070 version: 0.0.0-use.local 2070 version: 0.0.0-use.local
2071 resolution: "@refinery/root@workspace:." 2071 resolution: "@refinery/root@workspace:."
2072 dependencies: 2072 dependencies:
2073 eslint: ^8.26.0 2073 eslint: ^8.27.0
2074 typescript: 4.8.4 2074 typescript: 4.8.4
2075 languageName: unknown 2075 languageName: unknown
2076 linkType: soft 2076 linkType: soft
@@ -2120,6 +2120,18 @@ __metadata:
2120 languageName: node 2120 languageName: node
2121 linkType: hard 2121 linkType: hard
2122 2122
2123"@rollup/plugin-replace@npm:^4.0.0":
2124 version: 4.0.0
2125 resolution: "@rollup/plugin-replace@npm:4.0.0"
2126 dependencies:
2127 "@rollup/pluginutils": ^3.1.0
2128 magic-string: ^0.25.7
2129 peerDependencies:
2130 rollup: ^1.20.0 || ^2.0.0
2131 checksum: b61701e612661a46da06ca88f390c3839b586708abc0329a476411b90aa8ac59fe94437ede4c3fe53fea268b3054ea9d7d4ee851d7bd0cb7a5f06906002067cb
2132 languageName: node
2133 linkType: hard
2134
2123"@rollup/pluginutils@npm:^3.1.0": 2135"@rollup/pluginutils@npm:^3.1.0":
2124 version: 3.1.0 2136 version: 3.1.0
2125 resolution: "@rollup/pluginutils@npm:3.1.0" 2137 resolution: "@rollup/pluginutils@npm:3.1.0"
@@ -2316,13 +2328,13 @@ __metadata:
2316 languageName: node 2328 languageName: node
2317 linkType: hard 2329 linkType: hard
2318 2330
2319"@typescript-eslint/eslint-plugin@npm:^5.42.0": 2331"@typescript-eslint/eslint-plugin@npm:^5.42.1":
2320 version: 5.42.0 2332 version: 5.42.1
2321 resolution: "@typescript-eslint/eslint-plugin@npm:5.42.0" 2333 resolution: "@typescript-eslint/eslint-plugin@npm:5.42.1"
2322 dependencies: 2334 dependencies:
2323 "@typescript-eslint/scope-manager": 5.42.0 2335 "@typescript-eslint/scope-manager": 5.42.1
2324 "@typescript-eslint/type-utils": 5.42.0 2336 "@typescript-eslint/type-utils": 5.42.1
2325 "@typescript-eslint/utils": 5.42.0 2337 "@typescript-eslint/utils": 5.42.1
2326 debug: ^4.3.4 2338 debug: ^4.3.4
2327 ignore: ^5.2.0 2339 ignore: ^5.2.0
2328 natural-compare-lite: ^1.4.0 2340 natural-compare-lite: ^1.4.0
@@ -2335,43 +2347,43 @@ __metadata:
2335 peerDependenciesMeta: 2347 peerDependenciesMeta:
2336 typescript: 2348 typescript:
2337 optional: true 2349 optional: true
2338 checksum: 8dd13c77f5b83a8ba7e37196769b9c8a296c4417ffe7e33cb4d172495e1596ea0a9140dae0f1bbe1317a0cd5d5d92bf76a1799e7b9f8b3a577433b9569f1436d 2350 checksum: 6e80b15df7e655964ddd3041d5f7c0bf564e9901f9e3a9cdaf8d056301841fad8d40cd253d83669f01e0ddc62521af9286a27f098df43e304cf932d768995e98
2339 languageName: node 2351 languageName: node
2340 linkType: hard 2352 linkType: hard
2341 2353
2342"@typescript-eslint/parser@npm:^5.42.0": 2354"@typescript-eslint/parser@npm:^5.42.1":
2343 version: 5.42.0 2355 version: 5.42.1
2344 resolution: "@typescript-eslint/parser@npm:5.42.0" 2356 resolution: "@typescript-eslint/parser@npm:5.42.1"
2345 dependencies: 2357 dependencies:
2346 "@typescript-eslint/scope-manager": 5.42.0 2358 "@typescript-eslint/scope-manager": 5.42.1
2347 "@typescript-eslint/types": 5.42.0 2359 "@typescript-eslint/types": 5.42.1
2348 "@typescript-eslint/typescript-estree": 5.42.0 2360 "@typescript-eslint/typescript-estree": 5.42.1
2349 debug: ^4.3.4 2361 debug: ^4.3.4
2350 peerDependencies: 2362 peerDependencies:
2351 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 2363 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
2352 peerDependenciesMeta: 2364 peerDependenciesMeta:
2353 typescript: 2365 typescript:
2354 optional: true 2366 optional: true
2355 checksum: 790d5fcc53f02a25628b1d2a06e3b7f26f4fa12e78f51a67e1db0ac6a4b643a34f247991d7b938f45c7f8395fcaf920807c8a29d768913a7a8266162d2244806 2367 checksum: 7208a085102be5c569ac2be5799d05e080a9c0b9157ed3efa5d7eadb675185bddfa05f2f27e20c235910193a2bd835e5375fb9fc13561a6e20d110e444f37caa
2356 languageName: node 2368 languageName: node
2357 linkType: hard 2369 linkType: hard
2358 2370
2359"@typescript-eslint/scope-manager@npm:5.42.0": 2371"@typescript-eslint/scope-manager@npm:5.42.1":
2360 version: 5.42.0 2372 version: 5.42.1
2361 resolution: "@typescript-eslint/scope-manager@npm:5.42.0" 2373 resolution: "@typescript-eslint/scope-manager@npm:5.42.1"
2362 dependencies: 2374 dependencies:
2363 "@typescript-eslint/types": 5.42.0 2375 "@typescript-eslint/types": 5.42.1
2364 "@typescript-eslint/visitor-keys": 5.42.0 2376 "@typescript-eslint/visitor-keys": 5.42.1
2365 checksum: c7dac787c27db640ef8add18e91f84ade36871a50e84f36604fc1b823fc544ad28cea4731c4b7cadec157964f5399e6db2b3a9a115b2a2dd97fbc2bae7b1f9e0 2377 checksum: cfad5f04328fae4bb6d965a94c980ac2f6fa0eee6183e9bed6d7ebdb067f01a0a9a3b5500fc3638d5e287f46f4412aa462e238c610c1fb96b794b83c575c7fb4
2366 languageName: node 2378 languageName: node
2367 linkType: hard 2379 linkType: hard
2368 2380
2369"@typescript-eslint/type-utils@npm:5.42.0": 2381"@typescript-eslint/type-utils@npm:5.42.1":
2370 version: 5.42.0 2382 version: 5.42.1
2371 resolution: "@typescript-eslint/type-utils@npm:5.42.0" 2383 resolution: "@typescript-eslint/type-utils@npm:5.42.1"
2372 dependencies: 2384 dependencies:
2373 "@typescript-eslint/typescript-estree": 5.42.0 2385 "@typescript-eslint/typescript-estree": 5.42.1
2374 "@typescript-eslint/utils": 5.42.0 2386 "@typescript-eslint/utils": 5.42.1
2375 debug: ^4.3.4 2387 debug: ^4.3.4
2376 tsutils: ^3.21.0 2388 tsutils: ^3.21.0
2377 peerDependencies: 2389 peerDependencies:
@@ -2379,23 +2391,23 @@ __metadata:
2379 peerDependenciesMeta: 2391 peerDependenciesMeta:
2380 typescript: 2392 typescript:
2381 optional: true 2393 optional: true
2382 checksum: 5c98bdff38d8ace74f77b792d97572c41e3d0d01506529a32bc1244791a9e933d06dcc516eaad5bf1fc85b2cf1a95642f519f9c4ce4d6a974481e1a3680ed8dd 2394 checksum: 7ac3180aeb966351e54055440f42b723aa864fd39c74be5a41aae97401e6424df94d9f96ae945f1c3a6023860ffd7ba424ff6506c21bd373a6cd878466d9ba62
2383 languageName: node 2395 languageName: node
2384 linkType: hard 2396 linkType: hard
2385 2397
2386"@typescript-eslint/types@npm:5.42.0": 2398"@typescript-eslint/types@npm:5.42.1":
2387 version: 5.42.0 2399 version: 5.42.1
2388 resolution: "@typescript-eslint/types@npm:5.42.0" 2400 resolution: "@typescript-eslint/types@npm:5.42.1"
2389 checksum: 7a17ff007972129a1e2105a653d8aa637070b74d4f8b98309aeb83d06076ab40cebfa1c3e9aae3fc614118e730c4539ff13e8299d34530851cb06260483ef14c 2401 checksum: b0eb3df3792dd0e447abcf2b4fd79b2eaa6f944242d00afa8ef2d9f892ea63e52f200e7cb1758ddbc46154aa6764cec8bc796ed96f7554457a20db976f9f2089
2390 languageName: node 2402 languageName: node
2391 linkType: hard 2403 linkType: hard
2392 2404
2393"@typescript-eslint/typescript-estree@npm:5.42.0": 2405"@typescript-eslint/typescript-estree@npm:5.42.1":
2394 version: 5.42.0 2406 version: 5.42.1
2395 resolution: "@typescript-eslint/typescript-estree@npm:5.42.0" 2407 resolution: "@typescript-eslint/typescript-estree@npm:5.42.1"
2396 dependencies: 2408 dependencies:
2397 "@typescript-eslint/types": 5.42.0 2409 "@typescript-eslint/types": 5.42.1
2398 "@typescript-eslint/visitor-keys": 5.42.0 2410 "@typescript-eslint/visitor-keys": 5.42.1
2399 debug: ^4.3.4 2411 debug: ^4.3.4
2400 globby: ^11.1.0 2412 globby: ^11.1.0
2401 is-glob: ^4.0.3 2413 is-glob: ^4.0.3
@@ -2404,35 +2416,35 @@ __metadata:
2404 peerDependenciesMeta: 2416 peerDependenciesMeta:
2405 typescript: 2417 typescript:
2406 optional: true 2418 optional: true
2407 checksum: cc8a98815daf6c8bf6f8f5e43c4a7bf7008aa850cecc669de7b8cfdddb0648fd2eae738a185165176a24aed360cb12204cc0808f251e9fcf8e436cd15fff3645 2419 checksum: dfd3e20d41ba4b574a52d82cc40b38708b8c2c4277d6304a8d914fe2a4a9ce8779f4d79fdac140e77a3afd3c6a2a7e3f31620dc427cabd04e4e906bb0ca3a468
2408 languageName: node 2420 languageName: node
2409 linkType: hard 2421 linkType: hard
2410 2422
2411"@typescript-eslint/utils@npm:5.42.0": 2423"@typescript-eslint/utils@npm:5.42.1":
2412 version: 5.42.0 2424 version: 5.42.1
2413 resolution: "@typescript-eslint/utils@npm:5.42.0" 2425 resolution: "@typescript-eslint/utils@npm:5.42.1"
2414 dependencies: 2426 dependencies:
2415 "@types/json-schema": ^7.0.9 2427 "@types/json-schema": ^7.0.9
2416 "@types/semver": ^7.3.12 2428 "@types/semver": ^7.3.12
2417 "@typescript-eslint/scope-manager": 5.42.0 2429 "@typescript-eslint/scope-manager": 5.42.1
2418 "@typescript-eslint/types": 5.42.0 2430 "@typescript-eslint/types": 5.42.1
2419 "@typescript-eslint/typescript-estree": 5.42.0 2431 "@typescript-eslint/typescript-estree": 5.42.1
2420 eslint-scope: ^5.1.1 2432 eslint-scope: ^5.1.1
2421 eslint-utils: ^3.0.0 2433 eslint-utils: ^3.0.0
2422 semver: ^7.3.7 2434 semver: ^7.3.7
2423 peerDependencies: 2435 peerDependencies:
2424 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 2436 eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
2425 checksum: cc57ba8bdf1cf18de5c6c264b71be80dc8c4a7630c0d6a34f73ed991cd3684c97a06605f414a8fd439ce2201f7724249b2fc29eac1e54a770ee4e8303cabef52 2437 checksum: 9f1c429a602dad4ba7a52df00924aab6033854234a1e1bf699a3e5b48455b5fdc1a41de459a7f11a3ccfed1528831ecb95fc7e54d30be7d8cccbb689f885fdac
2426 languageName: node 2438 languageName: node
2427 linkType: hard 2439 linkType: hard
2428 2440
2429"@typescript-eslint/visitor-keys@npm:5.42.0": 2441"@typescript-eslint/visitor-keys@npm:5.42.1":
2430 version: 5.42.0 2442 version: 5.42.1
2431 resolution: "@typescript-eslint/visitor-keys@npm:5.42.0" 2443 resolution: "@typescript-eslint/visitor-keys@npm:5.42.1"
2432 dependencies: 2444 dependencies:
2433 "@typescript-eslint/types": 5.42.0 2445 "@typescript-eslint/types": 5.42.1
2434 eslint-visitor-keys: ^3.3.0 2446 eslint-visitor-keys: ^3.3.0
2435 checksum: d198e51ea968555dd44b3ff14587dd82ce43c30ae43d4021d4eacb468e4476102a5b715e15240adcdeec4b4b5280d819087a9c4090360f1e4dcb05829ea8f2dc 2447 checksum: d36c59da7bf3b3c150c12cbe4b0331edc15253f59599ec3d8b873b2a3d9fc7a4fea11490c1b20d972afcdc9c842deb5ada527ea9c538aa7e87555699d9a59f24
2436 languageName: node 2448 languageName: node
2437 linkType: hard 2449 linkType: hard
2438 2450
@@ -3902,9 +3914,9 @@ __metadata:
3902 languageName: node 3914 languageName: node
3903 linkType: hard 3915 linkType: hard
3904 3916
3905"eslint@npm:^8.26.0": 3917"eslint@npm:^8.27.0":
3906 version: 8.26.0 3918 version: 8.27.0
3907 resolution: "eslint@npm:8.26.0" 3919 resolution: "eslint@npm:8.27.0"
3908 dependencies: 3920 dependencies:
3909 "@eslint/eslintrc": ^1.3.3 3921 "@eslint/eslintrc": ^1.3.3
3910 "@humanwhocodes/config-array": ^0.11.6 3922 "@humanwhocodes/config-array": ^0.11.6
@@ -3947,7 +3959,7 @@ __metadata:
3947 text-table: ^0.2.0 3959 text-table: ^0.2.0
3948 bin: 3960 bin:
3949 eslint: bin/eslint.js 3961 eslint: bin/eslint.js
3950 checksum: a2aced939ea060f77d10dcfced5cfeb940f63f383fd7ab1decadea64170ab552582e1c5909db1db641d4283178c9bc569f19b0f8900e00314a5f783e4b3f759d 3962 checksum: 153b022d309e1b647a73b1bb0fa98912add699b06e279084155f23c6f2b5fc5abd05411fc1ba81608a24bbfaf044ca079544c16fffa6fc987b8f676c9960a2c4
3951 languageName: node 3963 languageName: node
3952 linkType: hard 3964 linkType: hard
3953 3965
@@ -5050,10 +5062,10 @@ __metadata:
5050 languageName: node 5062 languageName: node
5051 linkType: hard 5063 linkType: hard
5052 5064
5053"loglevel@npm:^1.8.0": 5065"loglevel@npm:^1.8.1":
5054 version: 1.8.0 5066 version: 1.8.1
5055 resolution: "loglevel@npm:1.8.0" 5067 resolution: "loglevel@npm:1.8.1"
5056 checksum: 41aeea17de24aba8dba68084a31fe9189648bce4f39c1277e021bb276c3c53a75b0d337395919cf271068ad40ecefabad0e4fdeb4a8f11908beee532b898f4a7 5068 checksum: a1a62db40291aaeaef2f612334c49e531bff71cc1d01a2acab689ab80d59e092f852ab164a5aedc1a752fdc46b7b162cb097d8a9eb2cf0b299511106c29af61d
5057 languageName: node 5069 languageName: node
5058 linkType: hard 5070 linkType: hard
5059 5071
@@ -6746,10 +6758,11 @@ __metadata:
6746 languageName: node 6758 languageName: node
6747 linkType: hard 6759 linkType: hard
6748 6760
6749"vite-plugin-pwa@npm:^0.13.2": 6761"vite-plugin-pwa@npm:^0.13.3":
6750 version: 0.13.2 6762 version: 0.13.3
6751 resolution: "vite-plugin-pwa@npm:0.13.2" 6763 resolution: "vite-plugin-pwa@npm:0.13.3"
6752 dependencies: 6764 dependencies:
6765 "@rollup/plugin-replace": ^4.0.0
6753 debug: ^4.3.4 6766 debug: ^4.3.4
6754 fast-glob: ^3.2.11 6767 fast-glob: ^3.2.11
6755 pretty-bytes: ^6.0.0 6768 pretty-bytes: ^6.0.0
@@ -6760,13 +6773,13 @@ __metadata:
6760 vite: ^3.1.0 6773 vite: ^3.1.0
6761 workbox-build: ^6.5.4 6774 workbox-build: ^6.5.4
6762 workbox-window: ^6.5.4 6775 workbox-window: ^6.5.4
6763 checksum: 6a8383dd0782e29c6c0bce0d3838ce5213c37c898fea874802df4f3f70f9cc021a0387f9f18f812da7f3598bf885c471618570ea4da2ca32a6874e8a7213ea16 6776 checksum: be1e8699e2fb4fea98454d20c8df4bcbd828aecb2b714a1251405fde4dc9ac9c95520b33fdfc1a3d91d51f9d920501d93f57f4f0a2f1361ba38785c86e4756a4
6764 languageName: node 6777 languageName: node
6765 linkType: hard 6778 linkType: hard
6766 6779
6767"vite@npm:^3.2.2": 6780"vite@npm:^3.2.3":
6768 version: 3.2.2 6781 version: 3.2.3
6769 resolution: "vite@npm:3.2.2" 6782 resolution: "vite@npm:3.2.3"
6770 dependencies: 6783 dependencies:
6771 esbuild: ^0.15.9 6784 esbuild: ^0.15.9
6772 fsevents: ~2.3.2 6785 fsevents: ~2.3.2
@@ -6774,6 +6787,7 @@ __metadata:
6774 resolve: ^1.22.1 6787 resolve: ^1.22.1
6775 rollup: ^2.79.1 6788 rollup: ^2.79.1
6776 peerDependencies: 6789 peerDependencies:
6790 "@types/node": ">= 14"
6777 less: "*" 6791 less: "*"
6778 sass: "*" 6792 sass: "*"
6779 stylus: "*" 6793 stylus: "*"
@@ -6783,6 +6797,8 @@ __metadata:
6783 fsevents: 6797 fsevents:
6784 optional: true 6798 optional: true
6785 peerDependenciesMeta: 6799 peerDependenciesMeta:
6800 "@types/node":
6801 optional: true
6786 less: 6802 less:
6787 optional: true 6803 optional: true
6788 sass: 6804 sass:
@@ -6795,7 +6811,7 @@ __metadata:
6795 optional: true 6811 optional: true
6796 bin: 6812 bin:
6797 vite: bin/vite.js 6813 vite: bin/vite.js
6798 checksum: 7197ac91c612dda922367a95afa1b210353d6168d41845c186e2217bda1328d17b021b93d8089e336f9533b94645ae5dca18bb10937759f559c87006dd957fcd 6814 checksum: 3c7c618f7fb471cdfaf7f8eb769cb5f4174447e1103cd6221cbc2ae1ea1102bc28dd6a621ead250e6aa42c1e9ee3c8092666ea81078e1d88d2325c484218fd0a
6799 languageName: node 6815 languageName: node
6800 linkType: hard 6816 linkType: hard
6801 6817