diff options
-rw-r--r-- | language-web/package.json | 5 | ||||
-rw-r--r-- | language-web/src/main/js/editor/EditorArea.tsx | 3 | ||||
-rw-r--r-- | language-web/src/main/js/editor/EditorStore.ts | 13 | ||||
-rw-r--r-- | language-web/src/main/js/global.d.ts | 6 | ||||
-rw-r--r-- | language-web/src/main/js/logging.tsx | 49 | ||||
-rw-r--r-- | language-web/src/main/js/xtext/ServiceBuilder.js | 27 | ||||
-rw-r--r-- | language-web/webpack.config.js | 8 | ||||
-rw-r--r-- | language-web/yarn.lock | 15 |
8 files changed, 114 insertions, 12 deletions
diff --git a/language-web/package.json b/language-web/package.json index ddb00f57..79e63342 100644 --- a/language-web/package.json +++ b/language-web/package.json | |||
@@ -1,5 +1,5 @@ | |||
1 | { | 1 | { |
2 | "name": "language-web", | 2 | "name": "refinery", |
3 | "version": "0.0.0", | 3 | "version": "0.0.0", |
4 | "description": "Web frontend for VIATRA-Generator", | 4 | "description": "Web frontend for VIATRA-Generator", |
5 | "main": "index.js", | 5 | "main": "index.js", |
@@ -58,6 +58,7 @@ | |||
58 | "webpack-subresource-integrity": "^5.0.0-rc.1" | 58 | "webpack-subresource-integrity": "^5.0.0-rc.1" |
59 | }, | 59 | }, |
60 | "dependencies": { | 60 | "dependencies": { |
61 | "ansi-styles": "^6.1.0", | ||
61 | "@babel/runtime": "^7.15.0", | 62 | "@babel/runtime": "^7.15.0", |
62 | "@emotion/react": "^11.4.1", | 63 | "@emotion/react": "^11.4.1", |
63 | "@emotion/styled": "^11.3.0", | 64 | "@emotion/styled": "^11.3.0", |
@@ -67,6 +68,8 @@ | |||
67 | "@material-ui/icons": "5.0.0-beta.4", | 68 | "@material-ui/icons": "5.0.0-beta.4", |
68 | "codemirror": "^5.62.3", | 69 | "codemirror": "^5.62.3", |
69 | "jquery": "^3.6.0", | 70 | "jquery": "^3.6.0", |
71 | "loglevel": "^1.7.1", | ||
72 | "loglevel-plugin-prefix": "^0.8.4", | ||
70 | "mobx": "^6.3.2", | 73 | "mobx": "^6.3.2", |
71 | "mobx-react-lite": "^3.2.0", | 74 | "mobx-react-lite": "^3.2.0", |
72 | "react": "^17.0.2", | 75 | "react": "^17.0.2", |
diff --git a/language-web/src/main/js/editor/EditorArea.tsx b/language-web/src/main/js/editor/EditorArea.tsx index f07a0ad8..531a57c9 100644 --- a/language-web/src/main/js/editor/EditorArea.tsx +++ b/language-web/src/main/js/editor/EditorArea.tsx | |||
@@ -15,8 +15,7 @@ export const EditorArea = observer(() => { | |||
15 | onChange={(e) => editorStore.updateValue(e.target.value)} | 15 | onChange={(e) => editorStore.updateValue(e.target.value)} |
16 | ref={fallbackTextarea} | 16 | ref={fallbackTextarea} |
17 | className={`problem-fallback-editor cm-s-${editorStore.codeMirrorTheme}`} | 17 | className={`problem-fallback-editor cm-s-${editorStore.codeMirrorTheme}`} |
18 | > | 18 | /> |
19 | </textarea> | ||
20 | ); | 19 | ); |
21 | } | 20 | } |
22 | 21 | ||
diff --git a/language-web/src/main/js/editor/EditorStore.ts b/language-web/src/main/js/editor/EditorStore.ts index 1ac2e79f..8b9432dd 100644 --- a/language-web/src/main/js/editor/EditorStore.ts +++ b/language-web/src/main/js/editor/EditorStore.ts | |||
@@ -8,8 +8,11 @@ import { | |||
8 | import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror'; | 8 | import type { IXtextOptions, IXtextServices } from 'xtext/xtext-codemirror'; |
9 | 9 | ||
10 | import type { IEditorChunk } from './editor'; | 10 | import type { IEditorChunk } from './editor'; |
11 | import { getLogger } from '../logging'; | ||
11 | import type { ThemeStore } from '../theme/ThemeStore'; | 12 | import type { ThemeStore } from '../theme/ThemeStore'; |
12 | 13 | ||
14 | const log = getLogger('EditorStore'); | ||
15 | |||
13 | const xtextLang = 'problem'; | 16 | const xtextLang = 'problem'; |
14 | 17 | ||
15 | const xtextOptions: IXtextOptions = { | 18 | const xtextOptions: IXtextOptions = { |
@@ -52,12 +55,20 @@ export class EditorStore { | |||
52 | xtextServices: observable.ref, | 55 | xtextServices: observable.ref, |
53 | initialSelection: false, | 56 | initialSelection: false, |
54 | }); | 57 | }); |
58 | this.loadChunk(); | ||
59 | } | ||
60 | |||
61 | private loadChunk(): void { | ||
62 | const loadingStartMillis = Date.now(); | ||
63 | log.info('Requesting editor chunk'); | ||
55 | import('./editor').then(({ editorChunk }) => { | 64 | import('./editor').then(({ editorChunk }) => { |
56 | runInAction(() => { | 65 | runInAction(() => { |
57 | this.chunk = editorChunk; | 66 | this.chunk = editorChunk; |
58 | }); | 67 | }); |
68 | const loadingDurationMillis = Date.now() - loadingStartMillis; | ||
69 | log.info('Loaded editor chunk in', loadingDurationMillis, 'ms'); | ||
59 | }).catch((error) => { | 70 | }).catch((error) => { |
60 | console.warn('Error while loading editor', error); | 71 | log.error('Error while loading editor', error); |
61 | }); | 72 | }); |
62 | } | 73 | } |
63 | 74 | ||
diff --git a/language-web/src/main/js/global.d.ts b/language-web/src/main/js/global.d.ts index 39bda7f3..0533a46e 100644 --- a/language-web/src/main/js/global.d.ts +++ b/language-web/src/main/js/global.d.ts | |||
@@ -1,3 +1,9 @@ | |||
1 | declare const DEBUG: boolean; | ||
2 | |||
3 | declare const PACKAGE_NAME: string; | ||
4 | |||
5 | declare const PACKAGE_VERSION: string; | ||
6 | |||
1 | declare module '*.module.scss' { | 7 | declare module '*.module.scss' { |
2 | const cssVariables: { [key in string]?: string }; | 8 | const cssVariables: { [key in string]?: string }; |
3 | // eslint-disable-next-line import/no-default-export | 9 | // eslint-disable-next-line import/no-default-export |
diff --git a/language-web/src/main/js/logging.tsx b/language-web/src/main/js/logging.tsx new file mode 100644 index 00000000..25f50f19 --- /dev/null +++ b/language-web/src/main/js/logging.tsx | |||
@@ -0,0 +1,49 @@ | |||
1 | import styles, { CSPair } from 'ansi-styles'; | ||
2 | import log from 'loglevel'; | ||
3 | import * as prefix from 'loglevel-plugin-prefix'; | ||
4 | |||
5 | const colors: Record<string, CSPair> = { | ||
6 | TRACE: styles.magenta, | ||
7 | DEBUG: styles.cyan, | ||
8 | INFO: styles.blue, | ||
9 | WARN: styles.yellow, | ||
10 | ERROR: styles.red, | ||
11 | }; | ||
12 | |||
13 | prefix.reg(log); | ||
14 | |||
15 | if (DEBUG) { | ||
16 | log.setLevel(log.levels.DEBUG); | ||
17 | } else { | ||
18 | log.setLevel(log.levels.WARN); | ||
19 | } | ||
20 | |||
21 | if ('chrome' in window) { | ||
22 | // Only Chromium supports console ANSI escape sequences. | ||
23 | prefix.apply(log, { | ||
24 | format(level, name, timestamp) { | ||
25 | const formattedTimestamp = `${styles.gray.open}[${timestamp.toString()}]${styles.gray.close}`; | ||
26 | const levelColor = colors[level.toUpperCase()] || styles.red; | ||
27 | const formattedLevel = `${levelColor.open}${level}${levelColor.close}`; | ||
28 | const formattedName = `${styles.green.open}(${name || 'root'})${styles.green.close}`; | ||
29 | return `${formattedTimestamp} ${formattedLevel} ${formattedName}`; | ||
30 | }, | ||
31 | }); | ||
32 | } else { | ||
33 | prefix.apply(log, { | ||
34 | template: '[%t] %l (%n)', | ||
35 | }); | ||
36 | } | ||
37 | |||
38 | const appLogger = log.getLogger(PACKAGE_NAME); | ||
39 | |||
40 | appLogger.info('Version:', PACKAGE_NAME, PACKAGE_VERSION); | ||
41 | appLogger.info('Debug mode:', DEBUG); | ||
42 | |||
43 | export function getLoggerFromRoot(name: string | symbol): log.Logger { | ||
44 | return log.getLogger(name); | ||
45 | } | ||
46 | |||
47 | export function getLogger(name: string | symbol): log.Logger { | ||
48 | return getLoggerFromRoot(`${PACKAGE_NAME}.${name.toString()}`); | ||
49 | } | ||
diff --git a/language-web/src/main/js/xtext/ServiceBuilder.js b/language-web/src/main/js/xtext/ServiceBuilder.js index 38b08ecc..57fcb310 100644 --- a/language-web/src/main/js/xtext/ServiceBuilder.js +++ b/language-web/src/main/js/xtext/ServiceBuilder.js | |||
@@ -18,10 +18,11 @@ define([ | |||
18 | 'xtext/services/ContentAssistService', | 18 | 'xtext/services/ContentAssistService', |
19 | 'xtext/services/HoverService', | 19 | 'xtext/services/HoverService', |
20 | 'xtext/services/OccurrencesService', | 20 | 'xtext/services/OccurrencesService', |
21 | 'xtext/services/FormattingService' | 21 | 'xtext/services/FormattingService', |
22 | '../logging', | ||
22 | ], function(jQuery, XtextService, LoadResourceService, SaveResourceService, HighlightingService, | 23 | ], function(jQuery, XtextService, LoadResourceService, SaveResourceService, HighlightingService, |
23 | ValidationService, UpdateService, ContentAssistService, HoverService, OccurrencesService, | 24 | ValidationService, UpdateService, ContentAssistService, HoverService, OccurrencesService, |
24 | FormattingService) { | 25 | FormattingService, logging) { |
25 | 26 | ||
26 | /** | 27 | /** |
27 | * Builder class for the Xtext services. | 28 | * Builder class for the Xtext services. |
@@ -179,12 +180,22 @@ define([ | |||
179 | }); | 180 | }); |
180 | } | 181 | } |
181 | 182 | ||
182 | services.successListeners = []; | 183 | const log = logging.getLoggerFromRoot('xtext.XtextService'); |
184 | services.successListeners = [function(serviceType, result) { | ||
185 | if (log.getLevel() <= log.levels.TRACE) { | ||
186 | log.trace('service', serviceType, 'request success', JSON.parse(JSON.stringify(result))); | ||
187 | } | ||
188 | }]; | ||
183 | services.errorListeners = [function(serviceType, severity, message, requestData) { | 189 | services.errorListeners = [function(serviceType, severity, message, requestData) { |
184 | if (options.showErrorDialogs) | 190 | const messageParts = ['service', serviceType, 'failed:', message || '(no message)']; |
185 | window.alert('Xtext service \'' + serviceType + '\' failed: ' + message); | 191 | if (requestData) { |
186 | else | 192 | messageParts.push(JSON.parse(JSON.stringify(requestData))); |
187 | console.log('Xtext service \'' + serviceType + '\' failed: ' + message); | 193 | } |
194 | if (severity === 'warning') { | ||
195 | log.warn(...messageParts); | ||
196 | } else { | ||
197 | log.error(...messageParts); | ||
198 | } | ||
188 | }]; | 199 | }]; |
189 | } | 200 | } |
190 | 201 | ||
@@ -271,4 +282,4 @@ define([ | |||
271 | } | 282 | } |
272 | 283 | ||
273 | return ServiceBuilder; | 284 | return ServiceBuilder; |
274 | }); \ No newline at end of file | 285 | }); |
diff --git a/language-web/webpack.config.js b/language-web/webpack.config.js index 1bd0edb2..c51d55d6 100644 --- a/language-web/webpack.config.js +++ b/language-web/webpack.config.js | |||
@@ -1,11 +1,14 @@ | |||
1 | const fs = require('fs'); | 1 | const fs = require('fs'); |
2 | const path = require('path'); | 2 | const path = require('path'); |
3 | 3 | ||
4 | const { DefinePlugin } = require('webpack'); | ||
4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); | 5 | const HtmlWebpackPlugin = require('html-webpack-plugin'); |
5 | const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload'); | 6 | const HtmlWebpackInjectPreload = require('@principalstudio/html-webpack-inject-preload'); |
6 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | 7 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); |
7 | const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity'); | 8 | const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity'); |
8 | 9 | ||
10 | const packageInfo = require('./package.json'); | ||
11 | |||
9 | const currentNodeEnv = process.env.NODE_ENV || 'development'; | 12 | const currentNodeEnv = process.env.NODE_ENV || 'development'; |
10 | const devMode = currentNodeEnv !== 'production'; | 13 | const devMode = currentNodeEnv !== 'production'; |
11 | const outputPath = path.resolve(__dirname, 'build/webpack', currentNodeEnv); | 14 | const outputPath = path.resolve(__dirname, 'build/webpack', currentNodeEnv); |
@@ -194,6 +197,11 @@ module.exports = { | |||
194 | }, | 197 | }, |
195 | }, | 198 | }, |
196 | plugins: [ | 199 | plugins: [ |
200 | new DefinePlugin({ | ||
201 | 'DEBUG': JSON.stringify(devMode), | ||
202 | 'PACKAGE_NAME': JSON.stringify(packageInfo.name), | ||
203 | 'PACKAGE_VERSION': JSON.stringify(packageInfo.version), | ||
204 | }), | ||
197 | new MiniCssExtractPlugin({ | 205 | new MiniCssExtractPlugin({ |
198 | filename: '[name].[contenthash].css', | 206 | filename: '[name].[contenthash].css', |
199 | chunkFilename: '[name].[contenthash].css', | 207 | chunkFilename: '[name].[contenthash].css', |
diff --git a/language-web/yarn.lock b/language-web/yarn.lock index 3aac4633..a307229f 100644 --- a/language-web/yarn.lock +++ b/language-web/yarn.lock | |||
@@ -1739,6 +1739,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: | |||
1739 | dependencies: | 1739 | dependencies: |
1740 | color-convert "^2.0.1" | 1740 | color-convert "^2.0.1" |
1741 | 1741 | ||
1742 | ansi-styles@^6.1.0: | ||
1743 | version "6.1.0" | ||
1744 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3" | ||
1745 | integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== | ||
1746 | |||
1742 | anymatch@~3.1.2: | 1747 | anymatch@~3.1.2: |
1743 | version "3.1.2" | 1748 | version "3.1.2" |
1744 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" | 1749 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" |
@@ -4967,6 +4972,16 @@ logalot@^2.0.0, logalot@^2.1.0: | |||
4967 | figures "^1.3.5" | 4972 | figures "^1.3.5" |
4968 | squeak "^1.0.0" | 4973 | squeak "^1.0.0" |
4969 | 4974 | ||
4975 | loglevel-plugin-prefix@^0.8.4: | ||
4976 | version "0.8.4" | ||
4977 | resolved "https://registry.yarnpkg.com/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz#2fe0e05f1a820317d98d8c123e634c1bd84ff644" | ||
4978 | integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g== | ||
4979 | |||
4980 | loglevel@^1.7.1: | ||
4981 | version "1.7.1" | ||
4982 | resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" | ||
4983 | integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== | ||
4984 | |||
4970 | longest-streak@^2.0.0: | 4985 | longest-streak@^2.0.0: |
4971 | version "2.0.4" | 4986 | version "2.0.4" |
4972 | resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" | 4987 | resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" |