diff --git a/bbj-vscode/.gitignore b/bbj-vscode/.gitignore index 5de64feb..e2461d2e 100644 --- a/bbj-vscode/.gitignore +++ b/bbj-vscode/.gitignore @@ -1,3 +1,5 @@ /out/ /src/language/generated/ /syntaxes/gen-bbj.tmLanguage.json +/public/**/* +!/public/index.html \ No newline at end of file diff --git a/bbj-vscode/esbuild.mjs b/bbj-vscode/esbuild.mjs index 333b51a0..9b2fab1e 100644 --- a/bbj-vscode/esbuild.mjs +++ b/bbj-vscode/esbuild.mjs @@ -4,7 +4,7 @@ import * as esbuild from 'esbuild'; const watch = process.argv.includes('--watch'); const minify = process.argv.includes('--minify'); -const ctx = await esbuild.context({ +const nodeCtx = await esbuild.context({ entryPoints: ['src/extension.ts', 'src/language/main.ts'], outdir: 'out', bundle: true, @@ -16,9 +16,29 @@ const ctx = await esbuild.context({ minify }); +const browserCtx = await esbuild.context({ + entryPoints: ['src/language/main-browser.ts', 'src/editor/monaco-editor.ts'], + outdir: 'public', + bundle: true, + target: "es6", + format: 'iife', + loader: { + '.ts': 'ts', + '.ttf': 'dataurl', + }, + platform: 'browser', + sourcemap: !minify, + minify +}); + if (watch) { - await ctx.watch(); + Promise.all([ + nodeCtx.watch(), + browserCtx.watch() + ]); } else { - await ctx.rebuild(); - ctx.dispose(); + await nodeCtx.rebuild(); + await browserCtx.rebuild(); + nodeCtx.dispose(); + browserCtx.dispose(); } diff --git a/bbj-vscode/package-lock.json b/bbj-vscode/package-lock.json index 3e9a6008..cc7289ec 100644 --- a/bbj-vscode/package-lock.json +++ b/bbj-vscode/package-lock.json @@ -1,30 +1,36 @@ { "name": "bbj-vscode", - "version": "0.0.7-SNAPSHOT", + "version": "0.0.9-SNAPSHOT", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "bbj-vscode", - "version": "0.0.7-SNAPSHOT", + "version": "0.0.9-SNAPSHOT", "license": "MIT", "dependencies": { "chevrotain": "^10.4.2", "langium": "~1.2.0", + "monaco-editor": "0.34.1", + "monaco-editor-workers": "~0.34.0", + "monaco-editor-wrapper": "1.6.1", "properties-file": "~3.2.5", "properties-reader": "^2.2.0", "vscode-jsonrpc": "~8.0.2", "vscode-languageclient": "~8.0.2", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "ws": "^8.13.0" }, "devDependencies": { "@types/node": "^14.17.3", "@types/vscode": "^1.56.0", + "@types/ws": "^8.5.5", "@typescript-eslint/eslint-plugin": "^5.28.0", "@typescript-eslint/parser": "^5.28.0", "concurrently": "^8.2.0", "esbuild": "^0.18.12", "eslint": "^8.17.0", + "http-server": "^14.1.1", "langium-cli": "~1.2.0", "shx": "^0.3.4", "typescript": "^4.9.4", @@ -551,6 +557,11 @@ "@types/chai": "*" } }, + "node_modules/@types/css-font-loading-module": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.8.tgz", + "integrity": "sha512-PdJeLlCJj/ShOA+c0dXdZ/e1P0Cdjhip+dRBtPaigOqwKd0DiFx3NeO6T2E7AQ5JszSR3dub3YkQjc2hcQyxSw==" + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -575,6 +586,15 @@ "integrity": "sha512-emg7wdsTFzdi+elvoyoA+Q8keEautdQHyY5LNmHVM4PTpY8JgOTVADrGVyXGepJ6dVW2OS5/xnLUWh+nZxvdiA==", "dev": true }, + "node_modules/@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.54.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz", @@ -928,11 +948,32 @@ "node": "*" } }, + "node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -969,6 +1010,19 @@ "node": ">=8" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1176,6 +1230,15 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1549,6 +1612,12 @@ "node": ">=0.10.0" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1663,6 +1732,26 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fs-extra": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", @@ -1721,6 +1810,21 @@ "node": "*" } }, + "node_modules/get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1821,6 +1925,104 @@ "node": ">=8" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dev": true, + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2138,6 +2340,18 @@ "node": ">=8.6" } }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2181,6 +2395,45 @@ "ufo": "^1.1.2" } }, + "node_modules/monaco-editor": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz", + "integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ==" + }, + "node_modules/monaco-editor-workers": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/monaco-editor-workers/-/monaco-editor-workers-0.34.2.tgz", + "integrity": "sha512-MdO1nvAbGNzc7ygyzwACvs5DOPaTOUNDjU/qTQx0Rsw00BrhL88eMi9sWBm+LYfQbPaZf+YBqwJaJUovl3M6bQ==" + }, + "node_modules/monaco-editor-wrapper": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/monaco-editor-wrapper/-/monaco-editor-wrapper-1.6.1.tgz", + "integrity": "sha512-aK7uvsbjPmwo+Odg8oQ6scPfkt2z0lLuykKBfMwKiiGijlq3vzKYvUnuub5/OxalxQCoV6kOhN5Y0HKkXc44tg==", + "dependencies": { + "@types/css-font-loading-module": "~0.0.7", + "monaco-languageclient": "4.0.3", + "normalize-url": "~8.0.0", + "vscode-languageserver-protocol": "3.17.2", + "vscode-ws-jsonrpc": "2.0.1" + } + }, + "node_modules/monaco-languageclient": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/monaco-languageclient/-/monaco-languageclient-4.0.3.tgz", + "integrity": "sha512-1mGIUb5PFRknITBhNxgH0SnQy1/jntt9oo0cQpOl3HdhYEL/CYK2UrsZZX7Udqmz1PXKyRIzQ3tZ7dJn4mzWtA==", + "dependencies": { + "vscode": "npm:@codingame/monaco-vscode-api@1.69.13", + "vscode-jsonrpc": "8.0.2", + "vscode-languageclient": "8.0.2" + }, + "engines": { + "node": ">=16.11.0", + "npm": ">=8.0.0" + }, + "peerDependencies": { + "vscode": ">= npm:@codingame/monaco-vscode-api@1.69.0 < npm:@codingame/monaco-vscode-api@1.70.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2217,6 +2470,26 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2226,6 +2499,15 @@ "wrappy": "1" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -2371,6 +2653,41 @@ "pathe": "^1.1.0" } }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "dependencies": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/portfinder/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, "node_modules/postcss": { "version": "8.4.23", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", @@ -2462,6 +2779,21 @@ "node": ">=6" } }, + "node_modules/qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2532,6 +2864,12 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "node_modules/resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -2637,6 +2975,24 @@ "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", "dev": true }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -2714,6 +3070,20 @@ "node": ">=6" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -3031,6 +3401,18 @@ "integrity": "sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==", "dev": true }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "dependencies": { + "qs": "^6.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -3049,6 +3431,12 @@ "punycode": "^2.1.0" } }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "node_modules/vite": { "version": "4.3.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", @@ -3576,6 +3964,17 @@ } } }, + "node_modules/vscode": { + "name": "@codingame/monaco-vscode-api", + "version": "1.69.13", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.69.13.tgz", + "integrity": "sha512-7+dQbQ5O8mQhFyUcAiiJkCotNjZUzRxh4NMBKc/BSIFi0jG47bay+jP/+ngsmxHBapjs/xUAPaKSGNnf9WBmAA==", + "peerDependencies": { + "monaco-editor": "~0.34.0", + "vscode-oniguruma": "^1.6.2", + "vscode-textmate": "^7.0.1" + } + }, "node_modules/vscode-jsonrpc": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz", @@ -3627,11 +4026,47 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "peer": true + }, + "node_modules/vscode-textmate": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-7.0.4.tgz", + "integrity": "sha512-9hJp0xL7HW1Q5OgGe03NACo7yiCTMEk3WU/rtKXUbncLtdg6rVVNJnHwD88UhbIYU2KoxY0Dih0x+kIsmUKn2A==", + "peer": true + }, "node_modules/vscode-uri": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz", "integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==" }, + "node_modules/vscode-ws-jsonrpc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-2.0.1.tgz", + "integrity": "sha512-ne5DO8/qe8tHt1U4LafLiYS832Yd4OltkP4+YZVOQwqGEU5nwLwZowUBqqEWt8sOZ0eLdCLV9luotGC2aUQ+LA==", + "dependencies": { + "vscode-jsonrpc": "8.0.2" + }, + "engines": { + "node": ">=16.11.0", + "npm": ">=8.0.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -3715,6 +4150,26 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -4084,6 +4539,11 @@ "@types/chai": "*" } }, + "@types/css-font-loading-module": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/css-font-loading-module/-/css-font-loading-module-0.0.8.tgz", + "integrity": "sha512-PdJeLlCJj/ShOA+c0dXdZ/e1P0Cdjhip+dRBtPaigOqwKd0DiFx3NeO6T2E7AQ5JszSR3dub3YkQjc2hcQyxSw==" + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -4108,6 +4568,15 @@ "integrity": "sha512-emg7wdsTFzdi+elvoyoA+Q8keEautdQHyY5LNmHVM4PTpY8JgOTVADrGVyXGepJ6dVW2OS5/xnLUWh+nZxvdiA==", "dev": true }, + "@types/ws": { + "version": "8.5.5", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.5.tgz", + "integrity": "sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "5.54.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.0.tgz", @@ -4332,11 +4801,29 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -4367,6 +4854,16 @@ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4526,6 +5023,12 @@ } } }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4804,6 +5307,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -4899,6 +5408,12 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "dev": true + }, "fs-extra": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.1.0.tgz", @@ -4941,6 +5456,18 @@ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, + "get-intrinsic": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3" + } + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -5014,6 +5541,74 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dev": true, + "requires": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + } + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -5250,6 +5845,12 @@ "picomatch": "^2.3.1" } }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -5281,6 +5882,38 @@ "ufo": "^1.1.2" } }, + "monaco-editor": { + "version": "0.34.1", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.34.1.tgz", + "integrity": "sha512-FKc80TyiMaruhJKKPz5SpJPIjL+dflGvz4CpuThaPMc94AyN7SeC9HQ8hrvaxX7EyHdJcUY5i4D0gNyJj1vSZQ==" + }, + "monaco-editor-workers": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/monaco-editor-workers/-/monaco-editor-workers-0.34.2.tgz", + "integrity": "sha512-MdO1nvAbGNzc7ygyzwACvs5DOPaTOUNDjU/qTQx0Rsw00BrhL88eMi9sWBm+LYfQbPaZf+YBqwJaJUovl3M6bQ==" + }, + "monaco-editor-wrapper": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/monaco-editor-wrapper/-/monaco-editor-wrapper-1.6.1.tgz", + "integrity": "sha512-aK7uvsbjPmwo+Odg8oQ6scPfkt2z0lLuykKBfMwKiiGijlq3vzKYvUnuub5/OxalxQCoV6kOhN5Y0HKkXc44tg==", + "requires": { + "@types/css-font-loading-module": "~0.0.7", + "monaco-languageclient": "4.0.3", + "normalize-url": "~8.0.0", + "vscode-languageserver-protocol": "3.17.2", + "vscode-ws-jsonrpc": "2.0.1" + } + }, + "monaco-languageclient": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/monaco-languageclient/-/monaco-languageclient-4.0.3.tgz", + "integrity": "sha512-1mGIUb5PFRknITBhNxgH0SnQy1/jntt9oo0cQpOl3HdhYEL/CYK2UrsZZX7Udqmz1PXKyRIzQ3tZ7dJn4mzWtA==", + "requires": { + "vscode": "npm:@codingame/monaco-vscode-api@1.69.13", + "vscode-jsonrpc": "8.0.2", + "vscode-languageclient": "8.0.2" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -5305,6 +5938,17 @@ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true }, + "normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==" + }, + "object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -5314,6 +5958,12 @@ "wrappy": "1" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, "optionator": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", @@ -5420,6 +6070,37 @@ "pathe": "^1.1.0" } }, + "portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", + "dev": true, + "requires": { + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + } + } + }, "postcss": { "version": "8.4.23", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz", @@ -5475,6 +6156,15 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, + "qs": { + "version": "6.11.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", + "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5519,6 +6209,12 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, "resolve": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", @@ -5586,6 +6282,24 @@ } } }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true + }, "semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -5636,6 +6350,17 @@ "shelljs": "^0.8.5" } }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", @@ -5860,6 +6585,15 @@ "integrity": "sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==", "dev": true }, + "union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", + "dev": true, + "requires": { + "qs": "^6.4.0" + } + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -5875,6 +6609,12 @@ "punycode": "^2.1.0" } }, + "url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, "vite": { "version": "4.3.9", "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz", @@ -6121,6 +6861,12 @@ "why-is-node-running": "^2.2.2" } }, + "vscode": { + "version": "npm:@codingame/monaco-vscode-api@1.69.13", + "resolved": "https://registry.npmjs.org/@codingame/monaco-vscode-api/-/monaco-vscode-api-1.69.13.tgz", + "integrity": "sha512-7+dQbQ5O8mQhFyUcAiiJkCotNjZUzRxh4NMBKc/BSIFi0jG47bay+jP/+ngsmxHBapjs/xUAPaKSGNnf9WBmAA==", + "requires": {} + }, "vscode-jsonrpc": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2.tgz", @@ -6163,11 +6909,40 @@ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz", "integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==" }, + "vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "peer": true + }, + "vscode-textmate": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-7.0.4.tgz", + "integrity": "sha512-9hJp0xL7HW1Q5OgGe03NACo7yiCTMEk3WU/rtKXUbncLtdg6rVVNJnHwD88UhbIYU2KoxY0Dih0x+kIsmUKn2A==", + "peer": true + }, "vscode-uri": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz", "integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA==" }, + "vscode-ws-jsonrpc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-2.0.1.tgz", + "integrity": "sha512-ne5DO8/qe8tHt1U4LafLiYS832Yd4OltkP4+YZVOQwqGEU5nwLwZowUBqqEWt8sOZ0eLdCLV9luotGC2aUQ+LA==", + "requires": { + "vscode-jsonrpc": "8.0.2" + } + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -6229,6 +7004,12 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "requires": {} + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/bbj-vscode/package.json b/bbj-vscode/package.json index 4baac057..d716f358 100644 --- a/bbj-vscode/package.json +++ b/bbj-vscode/package.json @@ -251,26 +251,32 @@ "esbuild-watch": "npm run esbuild-base -- --sourcemap --watch", "test-compile": "tsc -p ./", "langium:generate": "langium generate", - "langium:watch": "langium generate --watch" + "langium:watch": "langium generate --watch", + "start:monaco": "shx cp -R ./node_modules/monaco-editor-workers/dist/workers ./public/editor/workers && http-server ./public" }, - "dependencies": { "chevrotain": "^10.4.2", "langium": "~1.2.0", + "monaco-editor": "0.34.1", + "monaco-editor-workers": "~0.34.0", + "monaco-editor-wrapper": "1.6.1", "properties-file": "~3.2.5", "properties-reader": "^2.2.0", "vscode-jsonrpc": "~8.0.2", "vscode-languageclient": "~8.0.2", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "ws": "^8.13.0" }, "devDependencies": { "@types/node": "^14.17.3", "@types/vscode": "^1.56.0", + "@types/ws": "^8.5.5", "@typescript-eslint/eslint-plugin": "^5.28.0", "@typescript-eslint/parser": "^5.28.0", "concurrently": "^8.2.0", "esbuild": "^0.18.12", "eslint": "^8.17.0", + "http-server": "^14.1.1", "langium-cli": "~1.2.0", "shx": "^0.3.4", "typescript": "^4.9.4", diff --git a/bbj-vscode/public/index.html b/bbj-vscode/public/index.html new file mode 100644 index 00000000..2d9fea66 --- /dev/null +++ b/bbj-vscode/public/index.html @@ -0,0 +1,7 @@ + + + +
+ + + diff --git a/bbj-vscode/src/editor/monaco-editor.ts b/bbj-vscode/src/editor/monaco-editor.ts new file mode 100644 index 00000000..016fe2e2 --- /dev/null +++ b/bbj-vscode/src/editor/monaco-editor.ts @@ -0,0 +1,44 @@ +import { MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper'; +import { buildWorkerDefinition } from 'monaco-editor-workers'; +import monarch from './monarch'; + +buildWorkerDefinition('/editor/workers', window.origin, false); +MonacoEditorLanguageClientWrapper.addMonacoStyles('monaco-editor-styles'); + +const wrapper = new MonacoEditorLanguageClientWrapper('bbj'); +const config = wrapper.getEditorConfig(); +config.setMainLanguageId('bbj'); +config.setMonarchTokensProvider(monarch); + +config.setUseLanguageClient(true); + config.setUseWebSocket(false); + config.setLanguageClientConfigOptions({ + workerType: 'classic', + workerURL: '/language/main-browser.js', + }); + +config.setAutomaticLayout(true); +config.setMainCode(`x = 1, z = 2 + +some_object! = "" +a! +next + +IF some_object! <> 3 THEN ?"x", STR(some_object!); ?"y"; ? "z"; rem af + +if some_object! = null() then methodret + +IF some_object! <> 3 THEN + PRINT "some_object is " + PRINT "some_object is " +ELSE + PRINT "some_object is " +ENDIF + +next + +DIM sss[1] +`); + + +wrapper.startEditor(document.getElementById('editor')!); diff --git a/bbj-vscode/src/editor/monarch.ts b/bbj-vscode/src/editor/monarch.ts new file mode 100644 index 00000000..c768de7b --- /dev/null +++ b/bbj-vscode/src/editor/monarch.ts @@ -0,0 +1,34 @@ +// Monarch syntax highlighting for the bbj language. +export default { + keywords: [ + 'ADDR','AND','BREAK','BYE','CASE','CLASS','CLASSEND','CLIPFROMSTR','CLOSE','CONTINUE','DEFAULT','DIM','ELSE','END','ENDIF','ERR','EXIT','EXITTO','EXTENDS','EXTRACT','FI','FIELD','FIND','FOR','GOSUB','GOTO','IF','IMPLEMENTS','INPUT','INTERFACE','INTERFACEEND','LET','METHOD','METHODEND','METHODRET','MLTHEN','MODE','NEXT','OPEN','OR','PRINT','PRIVATE','PROCESS_EVENTS','PROTECTED','PUBLIC','READ','RECORD','RELEASE','RETURN','SETERR','SLTHEN','SQLCLOSE','SQLEXEC','SQLOPEN','SQLPREP','STATIC','STEP','SWEND','SWITCH','THROW','TO','WAIT','WEND','WHILE','WRITE','auto','declare','library','new','use','var' + ], + operators: [ + '!','#','*','+',',','-','.','/',':',';','<','<=','<>','=','>','>=','?','^' + ], + symbols: /!|#|\(|\)|\*|\+|,|-|\.|\/|:|;|<|<=|<>|=|>|>=|\?|\[|\]|\^/, + + tokenizer: { + initial: [ + { regex: /([rR][eE][mM])([ \t][^\n\r]*)?[\n\r]+/, action: {"token":"COMMENT"} }, + { regex: /_endline_print_comma/, action: {"token":"ENDLINE_PRINT_COMMA"} }, + { regex: /_next/, action: {"token":"NEXT_TOKEN"} }, + { regex: /_methodret_end/, action: {"token":"METHODRET_END"} }, + { regex: /::.*::/, action: {"token":"BBjFilePath"} }, + { regex: /[_a-zA-Z][\w_]*(!|\$|%)/, action: {"token":"ID_WITH_SUFFIX"} }, + { regex: /[_a-zA-Z][\w_]*/, action: { cases: { '@keywords': {"token":"keyword"}, '@default': {"token":"ID"} }} }, + { regex: /[0-9]+(\.[0-9]*)?/, action: {"token":"number"} }, + { regex: /"([^"]|"{2})*"/, action: {"token":"string"} }, + { regex: /\$[0-9a-fA-F]*\$/, action: {"token":"HEX_STRING"} }, + { regex: /'[0-9A-Z_]*'/, action: {"token":"MNEMONIC"} }, + { regex: /\/@@[\s\S]*?@\//, action: {"token":"DOCU"} }, + { include: '@whitespace' }, + { regex: /@symbols/, action: { cases: { '@operators': {"token":"operator"}, '@default': {"token":""} }} }, + ], + whitespace: [ + { regex: /\s+/, action: {"token":"white"} }, + ], + comment: [ + ], + } +}; diff --git a/bbj-vscode/src/language/bbj-browser-module.ts b/bbj-vscode/src/language/bbj-browser-module.ts new file mode 100644 index 00000000..833ce453 --- /dev/null +++ b/bbj-vscode/src/language/bbj-browser-module.ts @@ -0,0 +1,57 @@ +/****************************************************************************** + * Copyright 2023 TypeFox GmbH + * This program and the accompanying materials are made available under the + * terms of the MIT License, which is available in the project root. + ******************************************************************************/ + +import { + createDefaultModule, createDefaultSharedModule, DeepPartial, DefaultSharedModuleContext, inject, + LangiumSharedServices, Module +} from 'langium'; +import { BBjGeneratedModule, BBjGeneratedSharedModule } from './generated/module'; +import { registerValidationChecks } from './bbj-validator'; +import { BBjDocumentBuilder } from './bbj-document-builder'; +import { BBjIndexManager } from './bbj-index-manager'; +import { BBjModule, BBjServices } from './bbj-module'; + + +export const BBjSharedModule: Module> = { + workspace: { + DocumentBuilder: (services: LangiumSharedServices) => new BBjDocumentBuilder(services), + IndexManager: (services: LangiumSharedServices) => new BBjIndexManager(services) + }, +} + +/** + * Create the full set of services required by Langium. + * + * First inject the shared services by merging two modules: + * - Langium default shared services + * - Services generated by langium-cli + * + * Then inject the language-specific services by merging three modules: + * - Langium default language-specific services + * - Services generated by langium-cli + * - Services specified in this file + * + * @param context Optional module context with the LSP connection + * @returns An object wrapping the shared services and the language-specific services + */ +export function createBBjServices(context: DefaultSharedModuleContext): { + shared: LangiumSharedServices, + BBj: BBjServices +} { + const shared = inject( + createDefaultSharedModule(context), + BBjGeneratedSharedModule, + BBjSharedModule + ); + const BBj = inject( + createDefaultModule({ shared }), + BBjGeneratedModule, + BBjModule + ); + shared.ServiceRegistry.register(BBj); + registerValidationChecks(BBj); + return { shared, BBj }; +} diff --git a/bbj-vscode/src/language/bbj-document-builder.ts b/bbj-vscode/src/language/bbj-document-builder.ts index 6c81e2d9..ad117766 100644 --- a/bbj-vscode/src/language/bbj-document-builder.ts +++ b/bbj-vscode/src/language/bbj-document-builder.ts @@ -1,6 +1,5 @@ import { AstNode, BuildOptions, DefaultDocumentBuilder, DocumentState, LangiumDocument, LangiumSharedServices, WorkspaceManager } from "langium"; -import { BBjWorkspaceManager } from "./bbj-ws-manager"; - +import { BBjWsManager } from "./bbj-ws-manager"; export class BBjDocumentBuilder extends DefaultDocumentBuilder { wsManager: () => WorkspaceManager; @@ -16,9 +15,10 @@ export class BBjDocumentBuilder extends DefaultDocumentBuilder { _document.state = DocumentState.Validated; return false; } - if (this.wsManager() instanceof BBjWorkspaceManager) { + const wsManager = this.wsManager(); + if (BBjWsManager.is(wsManager)) { const validate = super.shouldValidate(_document, options) - && !(this.wsManager() as BBjWorkspaceManager).isExternalDocument(_document.uri) + && !wsManager.isExternalDocument(_document.uri) if (!validate) { // mark as validated to avoid rebuilding _document.state = DocumentState.Validated; diff --git a/bbj-vscode/src/language/bbj-index-manager.ts b/bbj-vscode/src/language/bbj-index-manager.ts index 2b63d828..63a5b228 100644 --- a/bbj-vscode/src/language/bbj-index-manager.ts +++ b/bbj-vscode/src/language/bbj-index-manager.ts @@ -1,6 +1,6 @@ import { AstNode, DefaultIndexManager, LangiumDocument, LangiumSharedServices, WorkspaceManager } from "langium"; import { URI } from "vscode-uri"; -import { BBjWorkspaceManager } from "./bbj-ws-manager"; +import { BBjWsManager } from "./bbj-ws-manager"; export class BBjIndexManager extends DefaultIndexManager { @@ -16,14 +16,14 @@ export class BBjIndexManager extends DefaultIndexManager { // only affected by ClassPath changes return false; } - if (this.wsManager() instanceof BBjWorkspaceManager) { - const bbjWsManager = this.wsManager() as BBjWorkspaceManager; - const isExternal = bbjWsManager.isExternalDocument(document.uri) + const wsManager = this.wsManager(); + if (BBjWsManager.is(wsManager)) { + const isExternal = wsManager.isExternalDocument(document.uri) if (document.references.some(e => e.error !== undefined)) { // don't rebuild external documents that has errors return !isExternal } - if(!bbjWsManager.isExternalDocument(changed) && isExternal) { + if(!wsManager.isExternalDocument(changed) && isExternal) { // don't rebuild external documents if ws document changed return false; } diff --git a/bbj-vscode/src/language/bbj-linker.ts b/bbj-vscode/src/language/bbj-linker.ts index 9eb67d79..1542e49f 100644 --- a/bbj-vscode/src/language/bbj-linker.ts +++ b/bbj-vscode/src/language/bbj-linker.ts @@ -8,8 +8,8 @@ import { import { CancellationToken } from 'vscode-languageserver'; import { URI } from 'vscode-uri'; import { StreamScopeWithPredicate } from './bbj-scope'; -import { BBjWorkspaceManager } from './bbj-ws-manager'; import { BinaryExpression, ConstructorCall, isBBjClassMember, isMethodDecl, LibFunction, MethodDecl, ParameterCall, SymbolRef, VariableDecl } from './generated/ast'; +import { BBjWsManager } from './bbj-ws-manager'; export class BbjLinker extends DefaultLinker { @@ -29,8 +29,7 @@ export class BbjLinker extends DefaultLinker { override async link(document: LangiumDocument, cancelToken = CancellationToken.None): Promise { const wsManager = this.wsManager() - const externalDoc = (wsManager instanceof BBjWorkspaceManager) - && (wsManager as BBjWorkspaceManager).isExternalDocument(document.uri) + const externalDoc = BBjWsManager.is(wsManager) && wsManager.isExternalDocument(document.uri) const treeIter = streamAst(document.parseResult.value).iterator() for (const node of treeIter) { diff --git a/bbj-vscode/src/language/bbj-module.ts b/bbj-vscode/src/language/bbj-module.ts index 792fd3bd..511dfd07 100644 --- a/bbj-vscode/src/language/bbj-module.ts +++ b/bbj-vscode/src/language/bbj-module.ts @@ -5,20 +5,15 @@ ******************************************************************************/ import { - createDefaultModule, createDefaultSharedModule, DeepPartial, DefaultSharedModuleContext, inject, - LangiumServices, LangiumSharedServices, Module, PartialLangiumServices + LangiumServices, Module, PartialLangiumServices } from 'langium'; -import { BBjGeneratedModule, BBjGeneratedSharedModule } from './generated/module'; -import { BBjValidator, registerValidationChecks } from './bbj-validator'; +import { BBjValidator } from './bbj-validator'; import { JavaInteropService } from './java-interop'; import { BbjNameProvider, BbjScopeComputation, BbjScopeProvider } from './bbj-scope'; -import { BBjWorkspaceManager } from './bbj-ws-manager'; import { BBjHoverProvider } from './bbj-hover'; import { BBjValueConverter } from './bbj-value-converter'; import { BbjLinker } from './bbj-linker'; -import { BBjDocumentBuilder } from './bbj-document-builder'; import { BBjTokenBuilder } from './bbj-token-builder'; -import { BBjIndexManager } from './bbj-index-manager'; import { BBjDocumentSymbolProvider } from './bbj-document-symbol'; import { BBjDocumentValidator } from './bbj-document-validator'; import { BBjCompletionProvider } from './bbj-completion-provider'; @@ -72,45 +67,3 @@ export const BBjModule: Module new BbjLexer(services) } }; - -export const BBjSharedModule: Module> = { - workspace: { - DocumentBuilder: (services: LangiumSharedServices) => new BBjDocumentBuilder(services), - WorkspaceManager: (services: LangiumSharedServices) => new BBjWorkspaceManager(services), - IndexManager: (services: LangiumSharedServices) => new BBjIndexManager(services) - }, -} - -/** - * Create the full set of services required by Langium. - * - * First inject the shared services by merging two modules: - * - Langium default shared services - * - Services generated by langium-cli - * - * Then inject the language-specific services by merging three modules: - * - Langium default language-specific services - * - Services generated by langium-cli - * - Services specified in this file - * - * @param context Optional module context with the LSP connection - * @returns An object wrapping the shared services and the language-specific services - */ -export function createBBjServices(context: DefaultSharedModuleContext): { - shared: LangiumSharedServices, - BBj: BBjServices -} { - const shared = inject( - createDefaultSharedModule(context), - BBjGeneratedSharedModule, - BBjSharedModule - ); - const BBj = inject( - createDefaultModule({ shared }), - BBjGeneratedModule, - BBjModule - ); - shared.ServiceRegistry.register(BBj); - registerValidationChecks(BBj); - return { shared, BBj }; -} diff --git a/bbj-vscode/src/language/bbj-node-module.ts b/bbj-vscode/src/language/bbj-node-module.ts new file mode 100644 index 00000000..4d8e5ce2 --- /dev/null +++ b/bbj-vscode/src/language/bbj-node-module.ts @@ -0,0 +1,58 @@ +/****************************************************************************** + * Copyright 2023 TypeFox GmbH + * This program and the accompanying materials are made available under the + * terms of the MIT License, which is available in the project root. + ******************************************************************************/ + +import { + createDefaultModule, createDefaultSharedModule, DeepPartial, DefaultSharedModuleContext, inject, + LangiumSharedServices, Module +} from 'langium'; +import { BBjGeneratedModule, BBjGeneratedSharedModule } from './generated/module'; +import { registerValidationChecks } from './bbj-validator'; +import { BBjNodeWorkspaceManager } from './bbj-node-ws-manager'; +import { BBjDocumentBuilder } from './bbj-document-builder'; +import { BBjIndexManager } from './bbj-index-manager'; +import { BBjModule, BBjServices } from './bbj-module'; + +export const BBjSharedModule: Module> = { + workspace: { + DocumentBuilder: (services: LangiumSharedServices) => new BBjDocumentBuilder(services), + WorkspaceManager: (services: LangiumSharedServices) => new BBjNodeWorkspaceManager(services), + IndexManager: (services: LangiumSharedServices) => new BBjIndexManager(services) + }, +} + +/** + * Create the full set of services required by Langium. + * + * First inject the shared services by merging two modules: + * - Langium default shared services + * - Services generated by langium-cli + * + * Then inject the language-specific services by merging three modules: + * - Langium default language-specific services + * - Services generated by langium-cli + * - Services specified in this file + * + * @param context Optional module context with the LSP connection + * @returns An object wrapping the shared services and the language-specific services + */ +export function createBBjServices(context: DefaultSharedModuleContext): { + shared: LangiumSharedServices, + BBj: BBjServices +} { + const shared = inject( + createDefaultSharedModule(context), + BBjGeneratedSharedModule, + BBjSharedModule + ); + const BBj = inject( + createDefaultModule({ shared }), + BBjGeneratedModule, + BBjModule + ); + shared.ServiceRegistry.register(BBj); + registerValidationChecks(BBj); + return { shared, BBj }; +} diff --git a/bbj-vscode/src/language/bbj-node-ws-manager.ts b/bbj-vscode/src/language/bbj-node-ws-manager.ts new file mode 100644 index 00000000..d5c37658 --- /dev/null +++ b/bbj-vscode/src/language/bbj-node-ws-manager.ts @@ -0,0 +1,149 @@ +import { AstNode, DefaultWorkspaceManager, LangiumDocument, LangiumDocumentFactory, LangiumSharedServices } from "langium"; +import { KeyValuePairObject, getProperties } from 'properties-file'; +import { CancellationToken } from "vscode"; +import { WorkspaceFolder } from 'vscode-languageserver'; +import { URI } from "vscode-uri"; +import { BBjServices } from "./bbj-module"; +import { JavaInteropService } from "./java-interop"; +import { builtinFunctions } from "./lib/functions"; +import { builtinVariables } from "./lib/variables"; +import { BBjWsManager } from "./bbj-ws-manager"; + +// TODO extend the FileSystemAccess or add an additional service +// to not use 'fs' and 'os' here +import fs from 'fs'; +import os from 'os'; +import path from 'path'; + +export class BBjNodeWorkspaceManager extends DefaultWorkspaceManager implements BBjWsManager { + + private documentFactory: LangiumDocumentFactory; + private javaInterop: JavaInteropService; + private settings: { prefixes: string[], classpath: string[] } | undefined = undefined; + private bbjdir = ""; + + constructor(services: LangiumSharedServices) { + super(services); + services.lsp.LanguageServer.onInitialize(params => { + this.bbjdir = params.initializationOptions; + }); + this.documentFactory = services.workspace.LangiumDocumentFactory; + const bbjServices = services.ServiceRegistry.all.find(service => service.LanguageMetaData.languageId === 'bbj') as BBjServices; + this.javaInterop = bbjServices.java.JavaInteropService; + } + + override async initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken | undefined): Promise { + try { + const content = await this.fileSystemProvider.readDirectory(this.getRootFolder(folders[0])); + const confFile = content.find(file => file.isFile && file.uri.path.endsWith("project.properties")); + let propcontents = ""; + if (confFile) { + propcontents = this.fileSystemProvider.readFileSync(confFile.uri); + } + let prefixfromconfig; + if(this.bbjdir) { + const bbjcfgdir = await this.fileSystemProvider.readDirectory(URI.parse(this.bbjdir+"/cfg/")); + const configbbx = bbjcfgdir.find(file => file.isFile && file.uri.path.endsWith("config.bbx")); + if (configbbx) { + prefixfromconfig = this.fileSystemProvider.readFileSync(configbbx.uri).split('\n').find(line => line.startsWith("PREFIX"))?.substring(7) || ""; + } + } else { + console.warn("No bbjdir set. No classpath and prefixes loaded.") + } + this.settings = parseSettings(propcontents, prefixfromconfig) + await this.javaInterop.loadClasspath(this.settings!.classpath, cancelToken) + await this.javaInterop.loadImplicitImports(cancelToken); + } catch (e) { + // all fine + console.error(e); + } + return await super.initializeWorkspace(folders, cancelToken); + } + + protected override async traverseFolder(workspaceFolder: WorkspaceFolder, folderPath: URI, fileExtensions: string[], collector: (document: LangiumDocument) => void): Promise { + const content = await this.fileSystemProvider.readDirectory(folderPath); + await Promise.all(content.map(async entry => { + if (this.includeEntry(workspaceFolder, entry, fileExtensions)) { + if (entry.isDirectory) { + await this.traverseFolder(workspaceFolder, entry.uri, fileExtensions, collector); + } else if (entry.isFile) { + // TODO Read from stream + const file = await this.fileSystemProvider.readFile(entry.uri); + if(!file.startsWith('<>')) { + const document = this.langiumDocuments.getOrCreateDocument(entry.uri); + collector(document); + } else { + console.warn(`Skipped binary file from index: ${entry.uri}`) + } + } + } + })); + } + protected override async loadAdditionalDocuments( + folders: WorkspaceFolder[], + collector: (document: LangiumDocument) => void + ): Promise { + // Load library + collector(this.documentFactory.fromString(builtinFunctions, URI.parse('bbjlib:///functions.bbl'))); + collector(this.documentFactory.fromString(builtinVariables, URI.parse('bbjlib:///variables.bbl'))); + + // Load additional files configured with the PREFIX property + if (this.settings?.prefixes) { + Promise.all(this.settings.prefixes.map(async prefixPath => { + console.warn('Add to additional files: ' + prefixPath.toString()) + if (fs.existsSync(prefixPath)) { + await this.traverseFolder({ name: "", uri: "" }, URI.file(prefixPath), ['.bbj'], collector) + } else { + console.warn(`${prefixPath} is not a directory. Skipped.`) + } + })) + } + } + + public getSettings() { + return this.settings; + } + + public getBBjDir() { + return this.bbjdir; + } + + public isExternalDocument(documentUri: URI): boolean { + if (this.settings?.prefixes) { + for (const prefix of this.settings?.prefixes) { + // TODO check that document is part of the workspace folders + if (documentUri.fsPath.startsWith(path.normalize(prefix))) { + return true; + } + } + } + return false; + } +} + +export function parseSettings(input: string, prefixfromconfigbbx: string | undefined): { prefixes: string[], classpath: string[] } { + + let props: KeyValuePairObject; + props = getProperties(input); + let cp=""; + if (props.classpath) { + cp = resolveTilde(props.classpath); + } + + let pfx="" + if (props.PREFIX) { + pfx = props.PREFIX; + } else if(prefixfromconfigbbx) + pfx = prefixfromconfigbbx; + + return { prefixes: collectPrefixes(pfx), classpath: cp.split(":")}; +} + +export function collectPrefixes(input: string): string[] { + return input.split(" ").map(entry => resolveTilde(entry.trim().slice(1, -1))) +} + +export function resolveTilde(input: string): string { + return input.replaceAll('~', os.homedir()) +} + diff --git a/bbj-vscode/src/language/bbj-ws-manager.ts b/bbj-vscode/src/language/bbj-ws-manager.ts index 458b7918..0253bb90 100644 --- a/bbj-vscode/src/language/bbj-ws-manager.ts +++ b/bbj-vscode/src/language/bbj-ws-manager.ts @@ -1,148 +1,12 @@ -import { AstNode, DefaultWorkspaceManager, LangiumDocument, LangiumDocumentFactory, LangiumSharedServices } from "langium"; -import { KeyValuePairObject, getProperties } from 'properties-file'; -import { CancellationToken } from "vscode"; -import { WorkspaceFolder } from 'vscode-languageserver'; +import { WorkspaceManager } from "langium"; import { URI } from "vscode-uri"; -import { BBjServices } from "./bbj-module"; -import { JavaInteropService } from "./java-interop"; -import { builtinFunctions } from "./lib/functions"; -import { builtinVariables } from "./lib/variables"; -// TODO extend the FileSystemAccess or add an additional service -// to not use 'fs' and 'os' here -import fs from 'fs'; -import os from 'os'; -import path from 'path'; - -export class BBjWorkspaceManager extends DefaultWorkspaceManager { - - private documentFactory: LangiumDocumentFactory; - private javaInterop: JavaInteropService; - private settings: { prefixes: string[], classpath: string[] } | undefined = undefined; - private bbjdir = ""; - - constructor(services: LangiumSharedServices) { - super(services); - services.lsp.LanguageServer.onInitialize(params => { - this.bbjdir = params.initializationOptions; - }); - this.documentFactory = services.workspace.LangiumDocumentFactory; - const bbjServices = services.ServiceRegistry.all.find(service => service.LanguageMetaData.languageId === 'bbj') as BBjServices; - this.javaInterop = bbjServices.java.JavaInteropService; - } - - override async initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken | undefined): Promise { - try { - const content = await this.fileSystemProvider.readDirectory(this.getRootFolder(folders[0])); - const confFile = content.find(file => file.isFile && file.uri.path.endsWith("project.properties")); - let propcontents = ""; - if (confFile) { - propcontents = this.fileSystemProvider.readFileSync(confFile.uri); - } - let prefixfromconfig; - if(this.bbjdir) { - const bbjcfgdir = await this.fileSystemProvider.readDirectory(URI.parse(this.bbjdir+"/cfg/")); - const configbbx = bbjcfgdir.find(file => file.isFile && file.uri.path.endsWith("config.bbx")); - if (configbbx) { - prefixfromconfig = this.fileSystemProvider.readFileSync(configbbx.uri).split('\n').find(line => line.startsWith("PREFIX"))?.substring(7) || ""; - } - } else { - console.warn("No bbjdir set. No classpath and prefixes loaded.") - } - this.settings = parseSettings(propcontents, prefixfromconfig) - await this.javaInterop.loadClasspath(this.settings!.classpath, cancelToken) - await this.javaInterop.loadImplicitImports(cancelToken); - } catch (e) { - // all fine - console.error(e); - } - return await super.initializeWorkspace(folders, cancelToken); - } - - protected override async traverseFolder(workspaceFolder: WorkspaceFolder, folderPath: URI, fileExtensions: string[], collector: (document: LangiumDocument) => void): Promise { - const content = await this.fileSystemProvider.readDirectory(folderPath); - await Promise.all(content.map(async entry => { - if (this.includeEntry(workspaceFolder, entry, fileExtensions)) { - if (entry.isDirectory) { - await this.traverseFolder(workspaceFolder, entry.uri, fileExtensions, collector); - } else if (entry.isFile) { - // TODO Read from stream - const file = await this.fileSystemProvider.readFile(entry.uri); - if(!file.startsWith('<>')) { - const document = this.langiumDocuments.getOrCreateDocument(entry.uri); - collector(document); - } else { - console.warn(`Skipped binary file from index: ${entry.uri}`) - } - } - } - })); - } - protected override async loadAdditionalDocuments( - folders: WorkspaceFolder[], - collector: (document: LangiumDocument) => void - ): Promise { - // Load library - collector(this.documentFactory.fromString(builtinFunctions, URI.parse('bbjlib:///functions.bbl'))); - collector(this.documentFactory.fromString(builtinVariables, URI.parse('bbjlib:///variables.bbl'))); - - // Load additional files configured with the PREFIX property - if (this.settings?.prefixes) { - Promise.all(this.settings.prefixes.map(async prefixPath => { - console.warn('Add to additional files: ' + prefixPath.toString()) - if (fs.existsSync(prefixPath)) { - await this.traverseFolder({ name: "", uri: "" }, URI.file(prefixPath), ['.bbj'], collector) - } else { - console.warn(`${prefixPath} is not a directory. Skipped.`) - } - })) - } - } - - public getSettings() { - return this.settings; - } - - public getBBjDir() { - return this.bbjdir; - } - - public isExternalDocument(documentUri: URI): boolean { - if (this.settings?.prefixes) { - for (const prefix of this.settings?.prefixes) { - // TODO check that document is part of the workspace folders - if (documentUri.fsPath.startsWith(path.normalize(prefix))) { - return true; - } - } - } - return false; - } +export interface BBjWsManager extends WorkspaceManager { + isExternalDocument(documentUri: URI): boolean; } -export function parseSettings(input: string, prefixfromconfigbbx: string | undefined): { prefixes: string[], classpath: string[] } { - - let props: KeyValuePairObject; - props = getProperties(input); - let cp=""; - if (props.classpath) { - cp = resolveTilde(props.classpath); +export namespace BBjWsManager { + export function is(workspaceManager: WorkspaceManager): workspaceManager is BBjWsManager { + return 'isExternalDocument' in workspaceManager; } - - let pfx="" - if (props.PREFIX) { - pfx = props.PREFIX; - } else if(prefixfromconfigbbx) - pfx = prefixfromconfigbbx; - - return { prefixes: collectPrefixes(pfx), classpath: cp.split(":")}; -} - -export function collectPrefixes(input: string): string[] { - return input.split(" ").map(entry => resolveTilde(entry.trim().slice(1, -1))) } - -export function resolveTilde(input: string): string { - return input.replaceAll('~', os.homedir()) -} - diff --git a/bbj-vscode/src/language/java-interop.ts b/bbj-vscode/src/language/java-interop.ts index afe96c2c..58c9ae75 100644 --- a/bbj-vscode/src/language/java-interop.ts +++ b/bbj-vscode/src/language/java-interop.ts @@ -5,10 +5,10 @@ ******************************************************************************/ import { LangiumDocument, LangiumDocuments, linkContentToContainer, Mutable } from 'langium'; -import { Socket } from 'net'; +import { RawData, WebSocket } from 'ws'; import { - CancellationToken, createMessageConnection, MessageConnection, RequestType, SocketMessageReader, SocketMessageWriter -} from 'vscode-jsonrpc/node'; + CancellationToken, createMessageConnection, DataCallback, Disposable, Emitter, Event, Message, MessageConnection, MessageReader, MessageWriter, PartialMessageInfo, RequestType +} from 'vscode-jsonrpc'; import { URI } from 'vscode-uri'; import { BBjServices } from './bbj-module'; import { Classpath, JavaClass, JavaField, JavaMethod, JavaMethodParameter } from './generated/ast'; @@ -37,18 +37,17 @@ export class JavaInteropService { return this.connection; } const socket = await this.createSocket(); - const connection = createMessageConnection(new SocketMessageReader(socket), new SocketMessageWriter(socket)); + const connection = createMessageConnection(new WebSocketMessageReader(socket), new WebSocketMessageWriter(socket)); connection.listen(); this.connection = connection; return connection; } - protected createSocket(): Promise { + protected createSocket(): Promise { return new Promise((resolve, reject) => { - const socket = new Socket(); + const socket = new WebSocket('127.0.0.1:' + DEFAULT_PORT); socket.on('error', reject); socket.on('ready', () => resolve(socket)); - socket.connect(DEFAULT_PORT, '127.0.0.1'); }); } @@ -156,6 +155,83 @@ export class JavaInteropService { } +class WebSocketMessageReader implements MessageReader { + + constructor(readonly socket: WebSocket) { + this.socket.on('error', e => { + this.onErrorEmitter.fire(e); + }); + this.socket.on('close', () => { + this.onCloseEmitter.fire(); + }); + } + + private onErrorEmitter = new Emitter(); + private onCloseEmitter = new Emitter(); + private decoder = new TextDecoder(); + + get onError(): Event { + return this.onErrorEmitter.event; + } + get onClose(): Event { + return this.onCloseEmitter.event; + } + get onPartialMessage(): Event { + return Event.None; + } + listen(callback: DataCallback): Disposable { + const socketCallback = ((data: RawData) => { + if (!Array.isArray(data)) { + const stringValue = this.decoder.decode(data); + const json = JSON.parse(stringValue); + callback(json); + } + }).bind(this); + this.socket.on('message', socketCallback); + return Disposable.create(() => { + this.socket.off('message', socketCallback); + }); + } + dispose(): void { + this.socket.close(); + } +} + +class WebSocketMessageWriter implements MessageWriter { + + constructor(readonly socket: WebSocket) { + this.socket.on('error', e => { + this.onErrorEmitter.fire([e, undefined, undefined]); + }); + this.socket.on('close', () => { + this.onCloseEmitter.fire(); + }); + } + + private onErrorEmitter = new Emitter<[Error, undefined, undefined]>(); + private onCloseEmitter = new Emitter(); + private encoder = new TextEncoder(); + + get onError(): Event<[Error, Message | undefined, number | undefined]> { + return this.onErrorEmitter.event; + } + get onClose(): Event { + return this.onCloseEmitter.event; + } + async write(msg: Message): Promise { + const json = JSON.stringify(msg); + const encoded = this.encoder.encode(json); + this.socket.send(encoded); + } + end(): void { + this.socket.close(); + } + dispose(): void { + this.socket.close(); + } + +} + const loadClasspathRequest = new RequestType('loadClasspath'); const getClassInfoRequest = new RequestType('getClassInfo'); const getClassInfosRequest = new RequestType('getClassInfos'); diff --git a/bbj-vscode/src/language/main-browser.ts b/bbj-vscode/src/language/main-browser.ts new file mode 100644 index 00000000..20cd2ed5 --- /dev/null +++ b/bbj-vscode/src/language/main-browser.ts @@ -0,0 +1,22 @@ +/****************************************************************************** + * Copyright 2023 TypeFox GmbH + * This program and the accompanying materials are made available under the + * terms of the MIT License, which is available in the project root. + ******************************************************************************/ + +import { EmptyFileSystem, startLanguageServer } from 'langium'; +import { createConnection } from 'vscode-languageserver/browser'; +import { createBBjServices } from './bbj-browser-module'; +import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-jsonrpc/browser'; + +const reader = new BrowserMessageReader(self as any); +const writer = new BrowserMessageWriter(self as any); + +// Create a connection to the client +const connection = createConnection(reader, writer); + +// Inject the shared services and language-specific services +const { shared } = createBBjServices({ connection, ...EmptyFileSystem }); + +// Start the language server with the shared services +startLanguageServer(shared); diff --git a/bbj-vscode/src/language/main.ts b/bbj-vscode/src/language/main.ts index f0b9b870..f20f7805 100644 --- a/bbj-vscode/src/language/main.ts +++ b/bbj-vscode/src/language/main.ts @@ -7,7 +7,7 @@ import { startLanguageServer } from 'langium'; import { NodeFileSystem } from 'langium/node'; import { createConnection, ProposedFeatures } from 'vscode-languageserver/node'; -import { createBBjServices } from './bbj-module'; +import { createBBjServices } from './bbj-node-module'; // Create a connection to the client const connection = createConnection(ProposedFeatures.all); diff --git a/bbj-vscode/test/bbj-test-module.ts b/bbj-vscode/test/bbj-test-module.ts index 3747148f..ac5e4990 100644 --- a/bbj-vscode/test/bbj-test-module.ts +++ b/bbj-vscode/test/bbj-test-module.ts @@ -1,6 +1,7 @@ import { DeepPartial, DefaultSharedModuleContext, LangiumSharedServices, Module, PartialLangiumServices, createDefaultModule, createDefaultSharedModule, inject } from "langium"; -import { BBjAddedServices, BBjModule, BBjServices, BBjSharedModule } from "../src/language/bbj-module"; +import { BBjAddedServices, BBjModule, BBjServices } from "../src/language/bbj-module"; import { BBjGeneratedModule, BBjGeneratedSharedModule } from "../src/language/generated/module"; +import { BBjSharedModule } from "../src/language/bbj-node-module"; import { registerValidationChecks } from "../src/language/bbj-validator"; import { JavaInteropService } from "../src/language/java-interop"; import { Classpath, JavaClass, JavaMethod } from "../src/language/generated/ast"; diff --git a/bbj-vscode/test/example-files.test.ts b/bbj-vscode/test/example-files.test.ts index 167750fe..0197c465 100644 --- a/bbj-vscode/test/example-files.test.ts +++ b/bbj-vscode/test/example-files.test.ts @@ -3,7 +3,7 @@ import { parseHelper } from 'langium/test'; import path from 'path'; import fs from 'fs'; import { describe, expect, test } from 'vitest'; -import { createBBjServices } from '../src/language/bbj-module'; +import { createBBjServices } from '../src/language/bbj-node-module'; import { Model } from '../src/language/generated/ast'; const services = createBBjServices(EmptyFileSystem); diff --git a/bbj-vscode/test/parser.test.ts b/bbj-vscode/test/parser.test.ts index 491cbde5..2687101c 100644 --- a/bbj-vscode/test/parser.test.ts +++ b/bbj-vscode/test/parser.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from 'vitest'; import { parseHelper } from 'langium/test'; -import { createBBjServices } from '../src/language/bbj-module'; +import { createBBjServices } from '../src/language/bbj-node-module'; import { EmptyFileSystem, LangiumDocument } from 'langium'; import { CompoundStatement, isCommentStatement, isCompoundStatement, isLibrary, isPrintValue, isProgram, Library, Model, Program } from '../src/language/generated/ast'; diff --git a/bbj-vscode/test/utils.test.ts b/bbj-vscode/test/utils.test.ts index ef70a4b9..4570be4f 100644 --- a/bbj-vscode/test/utils.test.ts +++ b/bbj-vscode/test/utils.test.ts @@ -1,7 +1,7 @@ import os from 'os'; import { describe, expect, test } from 'vitest'; -import { parseSettings } from '../src/language/bbj-ws-manager'; +import { parseSettings } from '../src/language/bbj-node-ws-manager'; const exampleInput = ` classpath=~/git/bbj-language-server/examples/lib/com.google.guava_30.1.0.v20221112-0806.jar:~/someOtherPath.jar:~/someOtherPath2.jar diff --git a/bbj-vscode/tsconfig.json b/bbj-vscode/tsconfig.json index 5bc5903c..c55eff29 100644 --- a/bbj-vscode/tsconfig.json +++ b/bbj-vscode/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES6", "module": "commonjs", - "lib": ["ESNext"], + "lib": ["ESNext", "WebWorker", "DOM"], "noEmit": true, "strict": true, "noUnusedLocals": true,