diff --git a/.gitignore b/.gitignore
index 07e4af692..22a1810f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ lib
node_modules
*.tsbuildinfo
.angular
+__screenshots__
diff --git a/docs/versions-and-history.md b/docs/versions-and-history.md
index 4a9bb74fc..187b3678d 100644
--- a/docs/versions-and-history.md
+++ b/docs/versions-and-history.md
@@ -6,6 +6,7 @@ The following table describes which version of **monaco-languageclient** and **@
| monaco-languageclient | monaco-editor-wrapper | monaco-editor-react | monaco-vscode-api / editor-api | vscode | monaco-editor | release date | comment |
| :---- | :---- | :--- | :--- | :--- | :--- | :--- | :--- |
+| 9.0.0-next.0 | 6.0.0-next.0 | 6.0.0-next.0 | 8.0.4 | 1.92.2 | 0.51.0 | 2024-09-xy | |
| 8.8.3 | 5.5.3 | 4.5.3 | 8.0.4 | 1.92.2 | 0.51.0 | 2024-08-26 | |
| 8.8.2 | 5.5.2 | 4.5.2 | 8.0.2 | 1.92.2 | 0.50.0 | 2024-08-21 | |
| 8.8.1 | 5.5.1 | 4.5.1 | 8.0.1 | 1.92.1 | 0.50.0 | 2024-08-12 | |
diff --git a/index.html b/index.html
index b55d8fefd..39af637ec 100644
--- a/index.html
+++ b/index.html
@@ -54,6 +54,11 @@
Groovy
Groovy Language Client & Language Server (Web Socket)
+ Multiple Languageclients
+ Please execute npm run start:example:server:python
and npm run start:example:server:json
beforehand:
+ Json & Python Languageclients & Language Server (Web Socket)
+
+
Monaco Editor React
React: Langium Statemachine Language Client & Language Server (Worker)
@@ -65,8 +70,6 @@ Monaco Editor React
monaco-editor related examples
Monaco Editor Wrapper TypeScript Example
- Multiple Editors
-
Verification
Angular
diff --git a/package-lock.json b/package-lock.json
index 391158240..a85637691 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,9 +15,9 @@
"@codingame/esbuild-import-meta-url-plugin": "~1.0.2",
"@codingame/monaco-vscode-rollup-vsix-plugin": "~8.0.4",
"@rollup/pluginutils": "~5.1.0",
- "@testing-library/react": "~16.0.0",
- "@types/node": "~20.14.15",
- "@types/react": "~18.3.4",
+ "@testing-library/react": "~16.0.1",
+ "@types/node": "~20.16.5",
+ "@types/react": "~18.3.5",
"@types/react-dom": "~18.3.0",
"@types/vscode": "~1.92.0",
"@typescript-eslint/eslint-plugin": "~7.18.0",
@@ -33,10 +33,10 @@
"http-server": "~14.1.1",
"minimatch": "~10.0.1",
"typescript": "~5.5.4",
- "vite": "~5.4.2",
+ "vite": "~5.4.3",
"vite-node": "~2.0.5",
"vitest": "~2.0.5",
- "webdriverio": "~9.0.6"
+ "webdriverio": "~9.0.7"
}
},
"node_modules/@ampproject/remapping": {
@@ -1953,9 +1953,9 @@
"dev": true
},
"node_modules/@promptbook/utils": {
- "version": "0.66.0",
- "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.66.0.tgz",
- "integrity": "sha512-L8CDhFE2p6lEGFW4sWSICljfXCQTeQ10hQrhVjULf8e2UDpqJ2C3nSTe3a890nGLwI5Rg8SStpIIndkQo/zpIw==",
+ "version": "0.70.0-1",
+ "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.70.0-1.tgz",
+ "integrity": "sha512-qd2lLRRN+sE6UuNMi2tEeUUeb4zmXnxY5EMdfHVXNE+bqBDpUC7/aEfXgA3jnUXEr+xFjQ8PTFQgWvBMaKvw0g==",
"dev": true,
"funding": [
{
@@ -1973,9 +1973,9 @@
}
},
"node_modules/@puppeteer/browsers": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.1.tgz",
- "integrity": "sha512-uK7o3hHkK+naEobMSJ+2ySYyXtQkBxIH8Gn4MK9ciePjNV+Pf+PgY/W7iPzn2MTjl3stcYB5AlcTmPYw7AXDwA==",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz",
+ "integrity": "sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -2262,10 +2262,11 @@
}
},
"node_modules/@testing-library/react": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.0.tgz",
- "integrity": "sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==",
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.0.1.tgz",
+ "integrity": "sha512-dSmwJVtJXmku+iocRhWOUFbrERC76TX2Mnf0ATODz8brzAZrMBbzLwQixlBSanZxR6LddK3eiwpSFZgDET1URg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/runtime": "^7.12.5"
},
@@ -2468,13 +2469,13 @@
}
},
"node_modules/@types/node": {
- "version": "20.14.15",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.15.tgz",
- "integrity": "sha512-Fz1xDMCF/B00/tYSVMlmK7hVeLh7jE5f3B7X1/hmV0MJBwE27KlS7EvD/Yp+z1lm8mVhwV5w+n8jOZG8AfTlKw==",
+ "version": "20.16.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz",
+ "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "undici-types": "~5.26.4"
+ "undici-types": "~6.19.2"
}
},
"node_modules/@types/prop-types": {
@@ -2496,9 +2497,9 @@
"dev": true
},
"node_modules/@types/react": {
- "version": "18.3.4",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz",
- "integrity": "sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==",
+ "version": "18.3.5",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.5.tgz",
+ "integrity": "sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -3148,9 +3149,9 @@
}
},
"node_modules/@zip.js/zip.js": {
- "version": "2.7.48",
- "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.48.tgz",
- "integrity": "sha512-J7cliimZ2snAbr0IhLx2U8BwfA1pKucahKzTpFtYq4hEgKxwvFJcIjCIVNPwQpfVab7iVP+AKmoH1gidBlyhiQ==",
+ "version": "2.7.52",
+ "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.52.tgz",
+ "integrity": "sha512-+5g7FQswvrCHwYKNMd/KFxZSObctLSsQOgqBSi0LzwHo3li9Eh1w5cF5ndjQw9Zbr3ajVnd2+XyiX85gAetx1Q==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -3603,9 +3604,9 @@
"optional": true
},
"node_modules/bare-fs": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz",
- "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.3.tgz",
+ "integrity": "sha512-7RYKL+vZVCyAsMLi5SPu7QGauGGT8avnP/HO571ndEuV4MYdGXvLhtW67FuLPeEI8EiIY7zbbRR9x7x7HU0kgw==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
@@ -3616,9 +3617,9 @@
}
},
"node_modules/bare-os": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz",
- "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.2.tgz",
+ "integrity": "sha512-HZoJwzC+rZ9lqEemTMiO0luOePoGYNBgsLLgegKR/cljiJvcDNhDZQkzC+NC5Oh0aHbdBNSOHpghwMuB5tqhjg==",
"dev": true,
"license": "Apache-2.0",
"optional": true
@@ -3635,13 +3636,14 @@
}
},
"node_modules/bare-stream": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz",
- "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.2.1.tgz",
+ "integrity": "sha512-YTB47kHwBW9zSG8LD77MIBAAQXjU2WjAkMHeeb7hUplVs6+IoM5I7uEVQNPMB7lj9r8I76UMdoMkGnCodHOLqg==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
+ "b4a": "^1.6.6",
"streamx": "^2.18.0"
}
},
@@ -5701,9 +5703,9 @@
"dev": true
},
"node_modules/fast-xml-parser": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
- "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
+ "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
"dev": true,
"funding": [
{
@@ -6001,9 +6003,9 @@
}
},
"node_modules/geckodriver": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.3.tgz",
- "integrity": "sha512-79rvaq8pvKVUtuM9XBjQApb04kOVkl3TFRX+zTt1wlmL+wqpt85ocWCdqiENU/3zIzg2Me21eClUcnE7F1kL2w==",
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.4.tgz",
+ "integrity": "sha512-0zaw19tcmWeluqx7+Y559JGBtidu1D0Lb8ElYKiNEQu8r3sCfrLUf5V10xypl8u29ZLbgRV7WflxCJVTCkCMFA==",
"dev": true,
"hasInstallScript": true,
"license": "MPL-2.0",
@@ -7299,9 +7301,9 @@
}
},
"node_modules/locate-app": {
- "version": "2.4.28",
- "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.28.tgz",
- "integrity": "sha512-+fcrSieGg19C7YS7MBrngAcaWmdeTpljyWneKof7X9NGe3F2xPodl3y9kx1MpyaXtRmzFnV1/frARI3O73agQg==",
+ "version": "2.4.38",
+ "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.38.tgz",
+ "integrity": "sha512-fJNTsDQZSiy+bn98RicvVX8e7HwH3YqZnRRisircGDGPpf0eZ2x57Ev7LGs0pCBO7hzjINVtVr5QFfK8KH7hjg==",
"dev": true,
"funding": [
{
@@ -7315,7 +7317,7 @@
],
"license": "SEE LICENSE IN LICENSE",
"dependencies": {
- "@promptbook/utils": "0.66.0",
+ "@promptbook/utils": "0.70.0-1",
"type-fest": "2.13.0",
"userhome": "1.0.0"
}
@@ -8281,9 +8283,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.41",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
- "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
+ "version": "8.4.45",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.45.tgz",
+ "integrity": "sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==",
"dev": true,
"funding": [
{
@@ -8446,9 +8448,9 @@
}
},
"node_modules/pyright": {
- "version": "1.1.377",
- "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.377.tgz",
- "integrity": "sha512-y6ENYuyZXTczPnPWZnqx78pE+ZgyIotEas2M/LFRTq3EfbgVk84EcvuSKLIy2DJeDKjKDxVP/LVmDNHabljD3g==",
+ "version": "1.1.379",
+ "resolved": "https://registry.npmjs.org/pyright/-/pyright-1.1.379.tgz",
+ "integrity": "sha512-n0X+IMqot6zL5b54vfU9GattS8jM9IOh8TRFho1k/6VoyjrpzQ7TnU6PtZzwEZNJaZi5izoLIDeMnGmbin8n8Q==",
"license": "MIT",
"bin": {
"pyright": "index.js",
@@ -9877,10 +9879,11 @@
}
},
"node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
- "dev": true
+ "version": "6.19.8",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
+ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/union": {
"version": "0.5.0",
@@ -10012,14 +10015,14 @@
}
},
"node_modules/vite": {
- "version": "5.4.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
- "integrity": "sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA==",
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.3.tgz",
+ "integrity": "sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"esbuild": "^0.21.3",
- "postcss": "^8.4.41",
+ "postcss": "^8.4.43",
"rollup": "^4.20.0"
},
"bin": {
@@ -10584,13 +10587,14 @@
}
},
"node_modules/vscode-json-languageservice": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.4.0.tgz",
- "integrity": "sha512-NCkkCr63OHVkE4lcb0xlUAaix6vE5gHQW4NrswbLEh3ArXj81lrGuFTsGEYEUXlNHdnc53vWPcjeSy/nMTrfXg==",
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-5.4.1.tgz",
+ "integrity": "sha512-5czFGNyVPxz3ZJYl8R3a3SuIj5gjhmGF4Wv05MRPvD4DEnHK6b8km4VbNMJNHBlTCh7A0aHzUbPVzo+0C18mCA==",
+ "license": "MIT",
"dependencies": {
"@vscode/l10n": "^0.0.18",
- "jsonc-parser": "^3.3.0",
- "vscode-languageserver-textdocument": "^1.0.11",
+ "jsonc-parser": "^3.3.1",
+ "vscode-languageserver-textdocument": "^1.0.12",
"vscode-languageserver-types": "^3.17.5",
"vscode-uri": "^3.0.8"
}
@@ -10656,9 +10660,10 @@
}
},
"node_modules/vscode-languageserver-textdocument": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.11.tgz",
- "integrity": "sha512-X+8T3GoiwTVlJbicx/sIAF+yuJAqz8VvwJyoMVhwEMoEKE/fkDmrqUgDMyBECcM2A2frVZIUj5HI/ErRXCfOeA=="
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
+ "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
+ "license": "MIT"
},
"node_modules/vscode-languageserver-types": {
"version": "3.17.5",
@@ -10723,9 +10728,9 @@
}
},
"node_modules/webdriver": {
- "version": "9.0.6",
- "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.0.6.tgz",
- "integrity": "sha512-S9f1qkEuIN1RgDFF0KmfWUc2NiBUb9d1UpGI/Y9IkSy9wTnAJk+xTvCezSUGO2D9rtZYHLal7jU+yOf9ntBg5Q==",
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.0.7.tgz",
+ "integrity": "sha512-0PN4omqCGlgi3RG0LyrQXr0RUmlDCenNtpN+dfzikfYoV+CHiCw2GMnZp2XCuYUnU01MaCKgRQxLuGobyZov+A==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10744,9 +10749,9 @@
}
},
"node_modules/webdriverio": {
- "version": "9.0.6",
- "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.0.6.tgz",
- "integrity": "sha512-STRjhpC18tUPFox1DSRPMhKfMXwsgr7ZqyWWbLXCPUeKpejVXlVigcXM4bXVWXpuAbLVo8PHGtX/zy28Jkwmow==",
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.0.7.tgz",
+ "integrity": "sha512-/6CvJkKpUWYbX/59PNJCHXGLPwulQ/bXZwlIUrsF6MWKdf8Eb6yTaXkMJBaBy5x496b50PQcXkbe+qpfsnqXsg==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -10776,7 +10781,7 @@
"rgb2hex": "0.2.5",
"serialize-error": "^11.0.3",
"urlpattern-polyfill": "^10.0.0",
- "webdriver": "9.0.6"
+ "webdriver": "9.0.7"
},
"engines": {
"node": ">=18"
@@ -11079,7 +11084,7 @@
},
"packages/client": {
"name": "monaco-languageclient",
- "version": "8.8.3",
+ "version": "9.0.0-next.0",
"license": "MIT",
"dependencies": {
"@codingame/monaco-vscode-extensions-service-override": "~8.0.4",
@@ -11109,7 +11114,7 @@
},
"packages/examples": {
"name": "monaco-languageclient-examples",
- "version": "2024.8.4",
+ "version": "2024.9.1",
"license": "MIT",
"dependencies": {
"@codingame/monaco-vscode-configuration-service-override": "~8.0.4",
@@ -11130,18 +11135,18 @@
"@codingame/monaco-vscode-theme-service-override": "~8.0.4",
"@codingame/monaco-vscode-typescript-basics-default-extension": "~8.0.4",
"@codingame/monaco-vscode-typescript-language-features-default-extension": "~8.0.4",
- "@typefox/monaco-editor-react": "~4.5.3",
+ "@typefox/monaco-editor-react": "~6.0.0-next.0",
"express": "~4.19.2",
"langium": "~3.1.3",
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3",
- "monaco-languageclient": "~8.8.3",
- "pyright": "~1.1.377",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient": "~9.0.0-next.0",
+ "pyright": "~1.1.379",
"react": "~18.3.1",
"react-dom": "~18.3.1",
"request-light": "~0.8.0",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4",
- "vscode-json-languageservice": "~5.4.0",
+ "vscode-json-languageservice": "~5.4.1",
"vscode-languageclient": "~9.0.1",
"vscode-languageserver": "~9.0.1",
"vscode-uri": "~3.0.8",
@@ -11169,7 +11174,7 @@
},
"packages/wrapper": {
"name": "monaco-editor-wrapper",
- "version": "5.5.3",
+ "version": "6.0.0-next.0",
"license": "MIT",
"dependencies": {
"@codingame/monaco-vscode-configuration-service-override": "~8.0.4",
@@ -11207,7 +11212,7 @@
},
"peerDependencies": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-languageclient": "~8.8.3",
+ "monaco-languageclient": "~9.0.0-next.0",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4"
},
"peerDependenciesMeta": {
@@ -11224,19 +11229,19 @@
},
"packages/wrapper-react": {
"name": "@typefox/monaco-editor-react",
- "version": "4.5.3",
+ "version": "6.0.0-next.0",
"license": "MIT",
"dependencies": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3",
- "monaco-languageclient": "~8.8.3",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient": "~9.0.0-next.0",
"react": "~18.3.1",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4"
},
"peerDependencies": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3",
- "monaco-languageclient": "~8.8.3",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient": "~9.0.0-next.0",
"react": "~18.3.1",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4"
},
diff --git a/package.json b/package.json
index 13c353eca..d3ca70917 100644
--- a/package.json
+++ b/package.json
@@ -5,9 +5,9 @@
"@codingame/esbuild-import-meta-url-plugin": "~1.0.2",
"@codingame/monaco-vscode-rollup-vsix-plugin": "~8.0.4",
"@rollup/pluginutils": "~5.1.0",
- "@testing-library/react": "~16.0.0",
- "@types/node": "~20.14.15",
- "@types/react": "~18.3.4",
+ "@testing-library/react": "~16.0.1",
+ "@types/node": "~20.16.5",
+ "@types/react": "~18.3.5",
"@types/react-dom": "~18.3.0",
"@types/vscode": "~1.92.0",
"@typescript-eslint/eslint-plugin": "~7.18.0",
@@ -23,14 +23,14 @@
"http-server": "~14.1.1",
"minimatch": "~10.0.1",
"typescript": "~5.5.4",
- "vite": "~5.4.2",
+ "vite": "~5.4.3",
"vite-node": "~2.0.5",
"vitest": "~2.0.5",
- "webdriverio": "~9.0.6"
+ "webdriverio": "~9.0.7"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"scripts": {
"clean": "npm run clean --workspaces",
diff --git a/packages/client/CHANGELOG.md b/packages/client/CHANGELOG.md
index 523b90d4f..559d25601 100644
--- a/packages/client/CHANGELOG.md
+++ b/packages/client/CHANGELOG.md
@@ -2,6 +2,10 @@
All notable changes to this npm module are documented in this file.
+## [9.0.0-next.0] - 2024-08-26
+
+- Pass MessageTransports directly
+
## [8.8.3] - 2024-08-26
- Update to monaco-vscode-api 8.0.4 (monaco-editor 0.51.0)
diff --git a/packages/client/package.json b/packages/client/package.json
index 0ac9e208c..dd8e84871 100644
--- a/packages/client/package.json
+++ b/packages/client/package.json
@@ -1,6 +1,6 @@
{
"name": "monaco-languageclient",
- "version": "8.8.3",
+ "version": "9.0.0-next.0",
"description": "Monaco Language client implementation",
"author": {
"name": "TypeFox GmbH",
@@ -51,8 +51,8 @@
"npm": ">=9.0.0"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"files": [
"lib",
diff --git a/packages/client/src/client.ts b/packages/client/src/client.ts
new file mode 100644
index 000000000..9a3bd7ed9
--- /dev/null
+++ b/packages/client/src/client.ts
@@ -0,0 +1,26 @@
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) 2024 TypeFox and others.
+ * Licensed under the MIT License. See LICENSE in the package root for license information.
+ * ------------------------------------------------------------------------------------------ */
+
+import { BaseLanguageClient, MessageTransports, LanguageClientOptions } from 'vscode-languageclient/browser.js';
+
+export type MonacoLanguageClientOptions = {
+ name: string;
+ id?: string;
+ clientOptions: LanguageClientOptions;
+ messageTransports: MessageTransports;
+}
+
+export class MonacoLanguageClient extends BaseLanguageClient {
+ protected readonly messageTransports: MessageTransports;
+
+ constructor({ id, name, clientOptions, messageTransports }: MonacoLanguageClientOptions) {
+ super(id ?? name.toLowerCase(), name, clientOptions);
+ this.messageTransports = messageTransports;
+ }
+
+ protected override createMessageTransports(_encoding: string): Promise {
+ return Promise.resolve(this.messageTransports);
+ }
+}
diff --git a/packages/wrapper/src/commonTypes.ts b/packages/client/src/commonTypes.ts
similarity index 57%
rename from packages/wrapper/src/commonTypes.ts
rename to packages/client/src/commonTypes.ts
index 263476b10..bdc31dbad 100644
--- a/packages/wrapper/src/commonTypes.ts
+++ b/packages/client/src/commonTypes.ts
@@ -3,52 +3,58 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
-import { MonacoLanguageClient } from 'monaco-languageclient';
+import { MonacoLanguageClient } from './client.js';
-export type WebSocketCallOptions = {
+export type ConnetionConfigOptions = WebSocketConfigOptionsDirect | WebSocketConfigOptionsParams | WebSocketConfigOptionsUrl | WorkerConfigOptionsParams | WorkerConfigOptionsDirect;
+
+export interface WebSocketCallOptions {
/** Adds handle on languageClient */
onCall: (languageClient?: MonacoLanguageClient) => void;
/** Reports Status Of Language Client */
reportStatus?: boolean;
}
-export type LanguageClientConfigType = 'WebSocket' | 'WebSocketUrl' | 'WorkerConfig' | 'Worker';
-
-export type WebSocketUrl = {
- secured: boolean;
- host: string;
- port?: number;
- path?: string;
+export interface WebSocketConfigOptionsDirect {
+ $type: 'WebSocketDirect'
+ webSocket: WebSocket
+ startOptions?: WebSocketCallOptions;
+ stopOptions?: WebSocketCallOptions;
}
-export type WebSocketConfigOptions = {
- $type: 'WebSocket'
+export interface WebSocketUrlParams {
secured: boolean;
host: string;
port?: number;
path?: string;
extraParams?: Record>;
+}
+
+export interface WebSocketConfigOptionsParams extends WebSocketUrlParams {
+ $type: 'WebSocketParams'
startOptions?: WebSocketCallOptions;
stopOptions?: WebSocketCallOptions;
}
-export type WebSocketConfigOptionsUrl = {
- $type: 'WebSocketUrl'
+export interface WebSocketUrlString {
url: string;
+}
+
+export interface WebSocketConfigOptionsUrl extends WebSocketUrlString {
+ $type: 'WebSocketUrl'
startOptions?: WebSocketCallOptions;
stopOptions?: WebSocketCallOptions;
}
-export type WorkerConfigOptions = {
+export interface WorkerConfigOptionsParams {
$type: 'WorkerConfig'
url: URL;
type: 'classic' | 'module';
messagePort?: MessagePort;
workerName?: string;
-};
+}
-export type WorkerConfigDirect = {
+export interface WorkerConfigOptionsDirect {
$type: 'WorkerDirect';
worker: Worker;
messagePort?: MessagePort;
-};
+}
diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts
index bf4ef8e5f..de65a7bd3 100644
--- a/packages/client/src/index.ts
+++ b/packages/client/src/index.ts
@@ -3,28 +3,7 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
-import { BaseLanguageClient, MessageTransports, LanguageClientOptions } from 'vscode-languageclient/lib/common/client.js';
-
-export interface IConnectionProvider {
- get(encoding: string): Promise;
-}
-
-export type MonacoLanguageClientOptions = {
- name: string;
- id?: string;
- clientOptions: LanguageClientOptions;
- connectionProvider: IConnectionProvider;
-}
-
-export class MonacoLanguageClient extends BaseLanguageClient {
- protected readonly connectionProvider: IConnectionProvider;
-
- constructor({ id, name, clientOptions, connectionProvider }: MonacoLanguageClientOptions) {
- super(id ?? name.toLowerCase(), name, clientOptions);
- this.connectionProvider = connectionProvider;
- }
-
- protected override createMessageTransports(encoding: string): Promise {
- return this.connectionProvider.get(encoding);
- }
-}
+export type * from './client.js';
+export * from './client.js';
+export type * from './commonTypes.js';
+export * from './commonTypes.js';
diff --git a/packages/client/src/vscode/services.ts b/packages/client/src/vscode/services.ts
index 19e6002ae..744a591dc 100644
--- a/packages/client/src/vscode/services.ts
+++ b/packages/client/src/vscode/services.ts
@@ -19,12 +19,12 @@ export interface MonacoEnvironmentEnhanced extends monaco.Environment {
vscodeApiInitialised?: boolean;
}
-export type InitializeServiceConfig = {
+export interface InitializeServiceConfig {
userServices?: monaco.editor.IEditorOverrideServices;
enableExtHostWorker?: boolean;
debugLogging?: boolean;
workspaceConfig?: IWorkbenchConstructionOptions;
-};
+}
export const initEnhancedMonacoEnvironment = () => {
const monWin = (self as Window);
@@ -61,12 +61,12 @@ export const mergeServices = (services: monaco.editor.IEditorOverrideServices, o
}
};
-export type InitServicesInstruction = {
+export interface InitServicesInstruction {
serviceConfig?: InitializeServiceConfig;
caller?: string;
performChecks?: () => boolean;
logger?: Logger;
-};
+}
export const initServices = async (instruction: InitServicesInstruction) => {
const envEnhanced = initEnhancedMonacoEnvironment();
diff --git a/packages/client/tsconfig.src.json b/packages/client/tsconfig.src.json
index fe6194cd2..33c4b69bf 100644
--- a/packages/client/tsconfig.src.json
+++ b/packages/client/tsconfig.src.json
@@ -4,9 +4,10 @@
"rootDir": "src",
"outDir": "lib",
"declarationDir": "lib",
- "types": [
- "vscode"
- ]
+ // because vscode-jsonrpc requires DedicatedWorkerGlobalScope
+ // we are required to include both DOM and WebWorker libs
+ // the only way out currently is to disable lib checking
+ "skipLibCheck": true
},
"include": [
"src/**/*.ts",
diff --git a/packages/examples/CHANGELOG.md b/packages/examples/CHANGELOG.md
index 995d2f26a..b0b521bca 100644
--- a/packages/examples/CHANGELOG.md
+++ b/packages/examples/CHANGELOG.md
@@ -2,6 +2,10 @@
All notable changes to this npm module are documented in this file.
+## [2024.9.1] - 2024-09-xy
+
+- Updated to `monaco-languageclient@9.0.0-next.0`, `monaco-editor-wrapper@6.0.0-next.0` and `@typefox/monaco-editor-react@6.0.0-next.0`. Updated all `@codingame/monaco-vscode` packages to `8.0.4`.
+
## [2024.8.4] - 2024-08-26
- Updated to `monaco-languageclient@8.8.3`, `monaco-editor-wrapper@5.5.3` and `@typefox/monaco-editor-react@4.5.3`. Updated all `@codingame/monaco-vscode` packages to `8.0.4`.
diff --git a/packages/examples/build/downloadResources.mts b/packages/examples/build/downloadResources.mts
index d62f497af..8494dcbb6 100644
--- a/packages/examples/build/downloadResources.mts
+++ b/packages/examples/build/downloadResources.mts
@@ -28,5 +28,12 @@ const downloadVsix = async (url: string, targetDir: string, filename: string) =>
}
};
+// Source: https://gist.github.com/wanglf/7acc591890dc0d8ceff1e7ec9af32a55?permalink_comment_id=4151555#gistcomment-4151555
+// https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${extension}/${version}/vspackage
+
await downloadVsix('https://marketplace.visualstudio.com/_apis/public/gallery/publishers/GitHub/vsextensions/github-vscode-theme/6.3.4/vspackage',
- resolve(getLocalDirectory(), '../resources/vsix/'), 'GitHub.github-vscode-theme-6.3.4.vsix');
+ resolve(getLocalDirectory(), '../resources/vsix/'), 'github-vscode-theme.vsix');
+
+// not yet used
+await downloadVsix('https://marketplace.visualstudio.com/_apis/public/gallery/publishers/TypeFox/vsextensions/open-collaboration-tools/0.2.3/vspackage',
+ resolve(getLocalDirectory(), '../resources/vsix/'), 'open-collaboration-tools.vsix');
diff --git a/packages/examples/package.json b/packages/examples/package.json
index 60473c769..2ce10f289 100644
--- a/packages/examples/package.json
+++ b/packages/examples/package.json
@@ -1,6 +1,6 @@
{
"name": "monaco-languageclient-examples",
- "version": "2024.8.4",
+ "version": "2024.9.1",
"description": "Monaco Language client examples",
"author": {
"name": "TypeFox GmbH",
@@ -72,18 +72,18 @@
"@codingame/monaco-vscode-theme-service-override": "~8.0.4",
"@codingame/monaco-vscode-typescript-basics-default-extension": "~8.0.4",
"@codingame/monaco-vscode-typescript-language-features-default-extension": "~8.0.4",
- "@typefox/monaco-editor-react": "~4.5.3",
+ "@typefox/monaco-editor-react": "~6.0.0-next.0",
"express": "~4.19.2",
"langium": "~3.1.3",
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3",
- "monaco-languageclient": "~8.8.3",
- "pyright": "~1.1.377",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient": "~9.0.0-next.0",
+ "pyright": "~1.1.379",
"react": "~18.3.1",
"react-dom": "~18.3.1",
"request-light": "~0.8.0",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4",
- "vscode-json-languageservice": "~5.4.0",
+ "vscode-json-languageservice": "~5.4.1",
"vscode-languageclient": "~9.0.1",
"vscode-languageserver": "~9.0.1",
"vscode-uri": "~3.0.8",
@@ -98,8 +98,8 @@
"vscode-languageserver-types": "~3.17.5"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"files": [
"dist",
diff --git a/packages/examples/src/bare/client.ts b/packages/examples/src/bare/client.ts
index 1a020b45c..8e6ca5e1e 100644
--- a/packages/examples/src/bare/client.ts
+++ b/packages/examples/src/bare/client.ts
@@ -13,7 +13,7 @@ import '@codingame/monaco-vscode-theme-defaults-default-extension';
import '@codingame/monaco-vscode-json-default-extension';
import { MonacoLanguageClient } from 'monaco-languageclient';
import { WebSocketMessageReader, WebSocketMessageWriter, toSocket } from 'vscode-ws-jsonrpc';
-import { CloseAction, ErrorAction, MessageTransports } from 'vscode-languageclient';
+import { CloseAction, ErrorAction, MessageTransports } from 'vscode-languageclient/browser.js';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
export const configureMonacoWorkers = () => {
@@ -73,7 +73,7 @@ export const initWebSocketAndStartClient = (url: string): WebSocket => {
return webSocket;
};
-export const createLanguageClient = (transports: MessageTransports): MonacoLanguageClient => {
+export const createLanguageClient = (messageTransports: MessageTransports): MonacoLanguageClient => {
return new MonacoLanguageClient({
name: 'Sample Language Client',
clientOptions: {
@@ -86,10 +86,6 @@ export const createLanguageClient = (transports: MessageTransports): MonacoLangu
}
},
// create a language client connection from the JSON RPC connection on demand
- connectionProvider: {
- get: () => {
- return Promise.resolve(transports);
- }
- }
+ messageTransports
});
};
diff --git a/packages/examples/src/browser/main.ts b/packages/examples/src/browser/main.ts
index 3b0ad381c..0ea6f7d31 100644
--- a/packages/examples/src/browser/main.ts
+++ b/packages/examples/src/browser/main.ts
@@ -10,7 +10,7 @@ import '@codingame/monaco-vscode-json-default-extension';
import { getLanguageService, TextDocument } from 'vscode-json-languageservice';
import { createConverter as createCodeConverter } from 'vscode-languageclient/lib/common/codeConverter.js';
import { createConverter as createProtocolConverter } from 'vscode-languageclient/lib/common/protocolConverter.js';
-import { MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
+import { MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
export const configureMonacoWorkers = () => {
@@ -36,30 +36,28 @@ export const runBrowserEditor = async () => {
const codeUri = '/workspace/model.json';
const wrapper = new MonacoEditorLanguageClientWrapper();
- const jsonClientUserConfig: UserConfig = {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride(),
- },
- debugLogging: true
+ const jsonClientUserConfig: WrapperConfig = {
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride(),
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: code,
- uri: codeUri
- }
- },
- useDiffEditor: false,
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.lightbulb.enabled': 'On'
- })
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: code,
+ uri: codeUri
}
+ },
+ useDiffEditor: false,
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.lightbulb.enabled': 'On'
+ })
}
}
};
diff --git a/packages/examples/src/common/client/utils.ts b/packages/examples/src/common/client/utils.ts
new file mode 100644
index 000000000..f06902591
--- /dev/null
+++ b/packages/examples/src/common/client/utils.ts
@@ -0,0 +1,11 @@
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) 2024 TypeFox and others.
+ * Licensed under the MIT License. See LICENSE in the package root for license information.
+ * ------------------------------------------------------------------------------------------ */
+
+export const disableButton = (id: string, disabled: boolean) => {
+ const button = document.getElementById(id) as HTMLButtonElement | null;
+ if (button !== null) {
+ button.disabled = disabled;
+ }
+};
diff --git a/packages/examples/src/common/node/server-commons.ts b/packages/examples/src/common/node/server-commons.ts
index 55af67eef..bf95c60ef 100644
--- a/packages/examples/src/common/node/server-commons.ts
+++ b/packages/examples/src/common/node/server-commons.ts
@@ -10,7 +10,7 @@ import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { IWebSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
import { createConnection, createServerProcess, forward } from 'vscode-ws-jsonrpc/server';
-import { Message, InitializeRequest, InitializeParams } from 'vscode-languageserver';
+import { Message, InitializeRequest, InitializeParams, RequestMessage, ResponseMessage } from 'vscode-languageserver-protocol';
import * as cp from 'child_process';
export enum LanguageName {
@@ -28,6 +28,9 @@ export interface LanguageServerRunConfig {
runCommandArgs: string[];
wsServerOptions: ServerOptions,
spawnOptions?: cp.SpawnOptions;
+ logMessages?: boolean;
+ requestMessageHandler?: (message: RequestMessage) => RequestMessage;
+ responseMessageHandler?: (message: ResponseMessage) => ResponseMessage;
}
/**
@@ -43,16 +46,27 @@ export const launchLanguageServer = (runconfig: LanguageServerRunConfig, socket:
if (serverConnection) {
forward(socketConnection, serverConnection, message => {
if (Message.isRequest(message)) {
- console.log(`${serverName} Server received:`);
- console.log(message);
if (message.method === InitializeRequest.type.method) {
const initializeParams = message.params as InitializeParams;
initializeParams.processId = process.pid;
}
+
+ if (runconfig.logMessages ?? false) {
+ console.log(`${serverName} Server received: ${message.method}`);
+ console.log(message);
+ }
+ if (runconfig.requestMessageHandler !== undefined) {
+ return runconfig.requestMessageHandler(message);
+ }
}
if (Message.isResponse(message)) {
- console.log(`${serverName} Server sent:`);
- console.log(message);
+ if (runconfig.logMessages ?? false) {
+ console.log(`${serverName} Server sent:`);
+ console.log(message);
+ }
+ if (runconfig.responseMessageHandler !== undefined) {
+ return runconfig.responseMessageHandler(message);
+ }
}
return message;
});
@@ -76,7 +90,6 @@ export const upgradeWsServer = (runconfig: LanguageServerRunConfig,
}
}),
onMessage: cb => webSocket.on('message', (data) => {
- console.log(data.toString());
cb(data);
}),
onError: cb => webSocket.on('error', cb),
diff --git a/packages/examples/src/eclipse.jdt.ls/client/main.ts b/packages/examples/src/eclipse.jdt.ls/client/main.ts
index 895a915b9..f4d0ebc3d 100644
--- a/packages/examples/src/eclipse.jdt.ls/client/main.ts
+++ b/packages/examples/src/eclipse.jdt.ls/client/main.ts
@@ -7,10 +7,10 @@ import * as vscode from 'vscode';
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
// this is required syntax highlighting
import '@codingame/monaco-vscode-java-default-extension';
-import { MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
+import { MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
import { RegisteredFileSystemProvider, RegisteredMemoryFile, registerFileSystemOverlay } from '@codingame/monaco-vscode-files-service-override';
-import { eclipseJdtLsConfig } from '../config';
+import { eclipseJdtLsConfig } from '../config.js';
import helloJavaCode from '../../../resources/eclipse.jdt.ls/workspace/hello.java?raw';
export const configureMonacoWorkers = () => {
@@ -28,46 +28,49 @@ export const runEclipseJdtLsClient = () => {
fileSystemProvider.registerFile(new RegisteredMemoryFile(helloJavaUri, helloJavaCode));
registerFileSystemOverlay(1, fileSystemProvider);
- const userConfig: UserConfig = {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride(),
- },
- debugLogging: true
+ const userConfig: WrapperConfig = {
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride(),
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: helloJavaCode,
- uri: `${eclipseJdtLsConfig.basePath}/workspace/hello.java`
- }
- },
- useDiffEditor: false,
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.wordBasedSuggestions': 'off'
- })
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: helloJavaCode,
+ uri: `${eclipseJdtLsConfig.basePath}/workspace/hello.java`
}
+ },
+ useDiffEditor: false,
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.wordBasedSuggestions': 'off'
+ })
}
+
},
- languageClientConfig: {
- languageId: 'java',
- options: {
- $type: 'WebSocketUrl',
- url: 'ws://localhost:30003/jdtls'
- },
- clientOptions: {
- documentSelector: ['java'],
- workspaceFolder: {
- index: 0,
- name: 'workspace',
- uri: vscode.Uri.parse(`${eclipseJdtLsConfig.basePath}/workspace`)
+ languageClientConfigs: {
+ java: {
+ languageId: 'java',
+ connection: {
+ options: {
+ $type: 'WebSocketUrl',
+ url: 'ws://localhost:30003/jdtls'
+ }
},
- },
+ clientOptions: {
+ documentSelector: ['java'],
+ workspaceFolder: {
+ index: 0,
+ name: 'workspace',
+ uri: vscode.Uri.parse(`${eclipseJdtLsConfig.basePath}/workspace`)
+ }
+ }
+ }
}
};
diff --git a/packages/examples/src/groovy/client/main.ts b/packages/examples/src/groovy/client/main.ts
index 9996c2e96..95720250a 100644
--- a/packages/examples/src/groovy/client/main.ts
+++ b/packages/examples/src/groovy/client/main.ts
@@ -6,7 +6,7 @@
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
// this is required syntax highlighting
import '@codingame/monaco-vscode-groovy-default-extension';
-import { MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
+import { MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
import { groovyConfig } from '../config.js';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
@@ -24,37 +24,39 @@ import java.io.File;
File file = new File("E:/Example.txt");
`;
-const userConfig: UserConfig = {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride(),
- },
- debugLogging: true
+const userConfig: WrapperConfig = {
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride(),
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: code,
- fileExt: 'groovy'
- }
- },
- useDiffEditor: false,
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.wordBasedSuggestions': 'off'
- })
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: code,
+ fileExt: 'groovy'
}
+ },
+ useDiffEditor: false,
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.wordBasedSuggestions': 'off'
+ })
}
},
- languageClientConfig: {
- languageId: 'groovy',
- options: {
- $type: 'WebSocketUrl',
- url: `ws://localhost:${groovyConfig.port}${groovyConfig.path}`
+ languageClientConfigs: {
+ groovy: {
+ languageId: 'groovy',
+ connection: {
+ options: {
+ $type: 'WebSocketUrl',
+ url: `ws://localhost:${groovyConfig.port}${groovyConfig.path}`
+ }
+ }
}
}
};
diff --git a/packages/examples/src/json/client/wrapperWs.ts b/packages/examples/src/json/client/wrapperWs.ts
index 3582b2f9d..7460bb188 100644
--- a/packages/examples/src/json/client/wrapperWs.ts
+++ b/packages/examples/src/json/client/wrapperWs.ts
@@ -6,7 +6,7 @@
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
// this is required syntax highlighting
import '@codingame/monaco-vscode-json-default-extension';
-import { MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
+import { MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
export const configureMonacoWorkers = () => {
@@ -24,49 +24,51 @@ const text = `{
"line_endings": {"value": "unix"}
}`;
-export const jsonClientUserConfig: UserConfig = {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride(),
- },
- debugLogging: true
+export const jsonClientUserConfig: WrapperConfig = {
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride(),
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text,
- fileExt: 'json'
- }
- },
- useDiffEditor: false,
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.lightbulb.enabled': 'On',
- 'editor.wordBasedSuggestions': 'off'
- })
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text,
+ fileExt: 'json'
}
+ },
+ useDiffEditor: false,
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.lightbulb.enabled': 'On',
+ 'editor.wordBasedSuggestions': 'off'
+ })
}
},
- languageClientConfig: {
- languageId: 'json',
- options: {
- $type: 'WebSocketUrl',
- url: 'ws://localhost:30000/sampleServer',
- startOptions: {
- onCall: () => {
- console.log('Connected to socket.');
- },
- reportStatus: true
- },
- stopOptions: {
- onCall: () => {
- console.log('Disconnected from socket.');
- },
- reportStatus: true
+ languageClientConfigs: {
+ json: {
+ languageId: 'json',
+ connection: {
+ options: {
+ $type: 'WebSocketUrl',
+ url: 'ws://localhost:30000/sampleServer',
+ startOptions: {
+ onCall: () => {
+ console.log('Connected to socket.');
+ },
+ reportStatus: true
+ },
+ stopOptions: {
+ onCall: () => {
+ console.log('Disconnected from socket.');
+ },
+ reportStatus: true
+ }
+ }
}
}
}
diff --git a/packages/examples/src/langium/langium-dsl/config/classicConfig.ts b/packages/examples/src/langium/langium-dsl/config/classicConfig.ts
index 2cb396efa..488e76162 100644
--- a/packages/examples/src/langium/langium-dsl/config/classicConfig.ts
+++ b/packages/examples/src/langium/langium-dsl/config/classicConfig.ts
@@ -7,53 +7,55 @@ import getConfigurationServiceOverride from '@codingame/monaco-vscode-configurat
import getEditorServiceOverride from '@codingame/monaco-vscode-editor-service-override';
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
import { useOpenEditorStub } from 'monaco-editor-wrapper/vscode/services';
-import { UserConfig } from 'monaco-editor-wrapper';
+import { WrapperConfig } from 'monaco-editor-wrapper';
import { LangiumMonarchContent } from './langium.monarch.js';
import { loadLangiumWorker } from '../wrapperLangium.js';
import code from '../content/example.langium?raw';
-export const setupLangiumClientClassic = async (): Promise => {
+export const setupLangiumClientClassic = async (): Promise => {
const langiumWorker = loadLangiumWorker();
return {
loggerConfig: {
enabled: true,
debugEnabled: true
},
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getConfigurationServiceOverride(),
- ...getEditorServiceOverride(useOpenEditorStub),
- ...getKeybindingsServiceOverride()
- },
- debugLogging: true
+ serviceConfig: {
+ userServices: {
+ ...getConfigurationServiceOverride(),
+ ...getEditorServiceOverride(useOpenEditorStub),
+ ...getKeybindingsServiceOverride()
},
- editorAppConfig: {
- $type: 'classic',
- codeResources: {
- main: {
- text: code,
- fileExt: 'langium',
- enforceLanguageId: 'langium'
- }
- },
- useDiffEditor: false,
- editorOptions: {
- 'semanticHighlighting.enabled': true,
- wordBasedSuggestions: 'off',
- theme: 'vs-dark'
- },
- languageDef: {
- monarchLanguage: LangiumMonarchContent,
- languageExtensionConfig: { id: 'langium' },
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'classic',
+ codeResources: {
+ main: {
+ text: code,
+ fileExt: 'langium',
+ enforceLanguageId: 'langium'
}
+ },
+ useDiffEditor: false,
+ editorOptions: {
+ 'semanticHighlighting.enabled': true,
+ wordBasedSuggestions: 'off',
+ theme: 'vs-dark'
+ },
+ languageDef: {
+ monarchLanguage: LangiumMonarchContent,
+ languageExtensionConfig: { id: 'langium' },
}
},
- languageClientConfig: {
- languageId: 'langium',
- options: {
- $type: 'WorkerDirect',
- worker: langiumWorker
+ languageClientConfigs: {
+ langium: {
+ languageId: 'langium',
+ connection: {
+ options: {
+ $type: 'WorkerDirect',
+ worker: langiumWorker
+ }
+ }
}
}
};
diff --git a/packages/examples/src/langium/langium-dsl/config/extendedConfig.ts b/packages/examples/src/langium/langium-dsl/config/extendedConfig.ts
index 425ffc76d..5cc60226b 100644
--- a/packages/examples/src/langium/langium-dsl/config/extendedConfig.ts
+++ b/packages/examples/src/langium/langium-dsl/config/extendedConfig.ts
@@ -5,16 +5,16 @@
import getEditorServiceOverride from '@codingame/monaco-vscode-editor-service-override';
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
-import '../../../../resources/vsix/GitHub.github-vscode-theme-6.3.4.vsix';
+import '../../../../resources/vsix/github-vscode-theme.vsix';
import { useOpenEditorStub } from 'monaco-editor-wrapper/vscode/services';
-import { UserConfig } from 'monaco-editor-wrapper';
+import { WrapperConfig } from 'monaco-editor-wrapper';
import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageclient/browser.js';
import { loadLangiumWorker } from '../wrapperLangium.js';
import langiumLanguageConfig from './langium.configuration.json?raw';
import langiumTextmateGrammar from './langium.tmLanguage.json?raw';
import text from '../content/example.langium?raw';
-export const setupLangiumClientExtended = async (): Promise => {
+export const setupLangiumClientExtended = async (): Promise => {
const extensionFilesOrContents = new Map();
// vite build is easier with string content
@@ -26,64 +26,64 @@ export const setupLangiumClientExtended = async (): Promise => {
const writer = new BrowserMessageWriter(langiumWorker);
return {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getEditorServiceOverride(useOpenEditorStub),
- ...getKeybindingsServiceOverride()
- },
- debugLogging: true
+ serviceConfig: {
+ userServices: {
+ ...getEditorServiceOverride(useOpenEditorStub),
+ ...getKeybindingsServiceOverride()
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text,
- fileExt: 'langium'
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text,
+ fileExt: 'langium'
+ }
+ },
+ useDiffEditor: false,
+ extensions: [{
+ config: {
+ name: 'langium-example',
+ publisher: 'monaco-editor-wrapper-examples',
+ version: '1.0.0',
+ engines: {
+ vscode: '*'
+ },
+ contributes: {
+ languages: [{
+ id: 'langium',
+ extensions: ['.langium'],
+ aliases: ['langium', 'LANGIUM'],
+ configuration: './langium-configuration.json'
+ }],
+ grammars: [{
+ language: 'langium',
+ scopeName: 'source.langium',
+ path: './langium-grammar.json'
+ }]
}
},
- useDiffEditor: false,
- extensions: [{
- config: {
- name: 'langium-example',
- publisher: 'monaco-editor-wrapper-examples',
- version: '1.0.0',
- engines: {
- vscode: '*'
- },
- contributes: {
- languages: [{
- id: 'langium',
- extensions: ['.langium'],
- aliases: ['langium', 'LANGIUM'],
- configuration: './langium-configuration.json'
- }],
- grammars: [{
- language: 'langium',
- scopeName: 'source.langium',
- path: './langium-grammar.json'
- }]
- }
- },
- filesOrContents: extensionFilesOrContents
- }],
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'GitHub Dark High Contrast',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.wordBasedSuggestions': 'off'
- })
- }
+ filesOrContents: extensionFilesOrContents
+ }],
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'GitHub Dark High Contrast',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.wordBasedSuggestions': 'off'
+ })
}
},
- languageClientConfig: {
- languageId: 'langium',
- options: {
- $type: 'WorkerDirect',
- worker: langiumWorker
- },
- connectionProvider: {
- get: async () => ({ reader, writer }),
+ languageClientConfigs: {
+ langium: {
+ languageId: 'langium',
+ connection: {
+ options: {
+ $type: 'WorkerDirect',
+ worker: langiumWorker
+ },
+ messageTransports: { reader, writer }
+ }
}
}
};
diff --git a/packages/examples/src/langium/langium-dsl/wrapperLangium.ts b/packages/examples/src/langium/langium-dsl/wrapperLangium.ts
index 20713d10e..9ca1aacae 100644
--- a/packages/examples/src/langium/langium-dsl/wrapperLangium.ts
+++ b/packages/examples/src/langium/langium-dsl/wrapperLangium.ts
@@ -8,6 +8,7 @@ import { setupLangiumClientExtended } from './config/extendedConfig.js';
import { setupLangiumClientClassic } from './config/classicConfig.js';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
import workerUrl from './worker/langium-server?worker&url';
+import { disableButton } from '../../common/client/utils.js';
let wrapper: MonacoEditorLanguageClientWrapper | undefined;
let extended = false;
@@ -67,13 +68,6 @@ const checkStarted = () => {
return false;
};
-const disableButton = (id: string, disabled: boolean) => {
- const button = document.getElementById(id) as HTMLButtonElement | null;
- if (button !== null) {
- button.disabled = disabled;
- }
-};
-
export const disposeEditor = async () => {
if (!wrapper) return;
wrapper.reportStatus();
diff --git a/packages/examples/src/langium/statemachine/config/wrapperStatemachineConfig.ts b/packages/examples/src/langium/statemachine/config/wrapperStatemachineConfig.ts
index cae12bddf..e54abc400 100644
--- a/packages/examples/src/langium/statemachine/config/wrapperStatemachineConfig.ts
+++ b/packages/examples/src/langium/statemachine/config/wrapperStatemachineConfig.ts
@@ -6,12 +6,12 @@
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
import getLifecycleServiceOverride from '@codingame/monaco-vscode-lifecycle-service-override';
import getLocalizationServiceOverride from '@codingame/monaco-vscode-localization-service-override';
-import { IConnectionProvider } from 'monaco-languageclient';
import { createDefaultLocaleConfiguration } from 'monaco-languageclient/vscode/services';
-import { LanguageClientConfig, UserConfig } from 'monaco-editor-wrapper';
+import { LanguageClientConfig, WrapperConfig } from 'monaco-editor-wrapper';
// cannot be imported with assert as json contains comments
import statemachineLanguageConfig from './language-configuration.json?raw';
import responseStatemachineTm from '../syntaxes/statemachine.tmLanguage.json?raw';
+import { MessageTransports } from 'vscode-languageclient';
export const createLangiumGlobalConfig = async (params: {
languageServerId: string,
@@ -19,8 +19,8 @@ export const createLangiumGlobalConfig = async (params: {
text?: string,
worker?: Worker,
messagePort?: MessagePort,
- connectionProvider?: IConnectionProvider
-}): Promise => {
+ messageTransports?: MessageTransports
+}): Promise => {
const extensionFilesOrContents = new Map();
extensionFilesOrContents.set(`/${params.languageServerId}-statemachine-configuration.json`, statemachineLanguageConfig);
extensionFilesOrContents.set(`/${params.languageServerId}-statemachine-grammar.json`, responseStatemachineTm);
@@ -33,66 +33,68 @@ export const createLangiumGlobalConfig = async (params: {
};
}
- const languageClientConfig: LanguageClientConfig | undefined = params.useLanguageClient && params.worker ? {
- languageId: 'statemachine',
- options: {
- $type: 'WorkerDirect',
- worker: params.worker,
- messagePort: params.messagePort,
- },
- connectionProvider: params.connectionProvider
+ const languageClientConfigs: Record | undefined = params.useLanguageClient && params.worker ? {
+ statemachine: {
+ languageId: 'statemachine',
+ connection: {
+ options: {
+ $type: 'WorkerDirect',
+ worker: params.worker,
+ messagePort: params.messagePort,
+ },
+ messageTransports: params.messageTransports
+ }
+ }
} : undefined;
return {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride(),
- ...getLifecycleServiceOverride(),
- ...getLocalizationServiceOverride(createDefaultLocaleConfiguration()),
- },
- debugLogging: true
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride(),
+ ...getLifecycleServiceOverride(),
+ ...getLocalizationServiceOverride(createDefaultLocaleConfiguration()),
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main
- },
- useDiffEditor: false,
- extensions: [{
- config: {
- name: 'statemachine-example',
- publisher: 'monaco-editor-wrapper-examples',
- version: '1.0.0',
- engines: {
- vscode: '*'
- },
- contributes: {
- languages: [{
- id: 'statemachine',
- extensions: ['.statemachine'],
- aliases: ['statemachine', 'Statemachine'],
- configuration: `./${params.languageServerId}-statemachine-configuration.json`
- }],
- grammars: [{
- language: 'statemachine',
- scopeName: 'source.statemachine',
- path: `./${params.languageServerId}-statemachine-grammar.json`
- }]
- }
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main
+ },
+ useDiffEditor: false,
+ extensions: [{
+ config: {
+ name: 'statemachine-example',
+ publisher: 'monaco-editor-wrapper-examples',
+ version: '1.0.0',
+ engines: {
+ vscode: '*'
},
- filesOrContents: extensionFilesOrContents
- }],
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.wordBasedSuggestions': 'off'
- })
- }
+ contributes: {
+ languages: [{
+ id: 'statemachine',
+ extensions: ['.statemachine'],
+ aliases: ['statemachine', 'Statemachine'],
+ configuration: `./${params.languageServerId}-statemachine-configuration.json`
+ }],
+ grammars: [{
+ language: 'statemachine',
+ scopeName: 'source.statemachine',
+ path: `./${params.languageServerId}-statemachine-grammar.json`
+ }]
+ }
+ },
+ filesOrContents: extensionFilesOrContents
+ }],
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.wordBasedSuggestions': 'off'
+ })
}
},
- languageClientConfig,
+ languageClientConfigs,
loggerConfig: {
enabled: true,
debugEnabled: true
diff --git a/packages/examples/src/langium/statemachine/main-react.tsx b/packages/examples/src/langium/statemachine/main-react.tsx
index 3ba131a42..3543116eb 100644
--- a/packages/examples/src/langium/statemachine/main-react.tsx
+++ b/packages/examples/src/langium/statemachine/main-react.tsx
@@ -48,7 +48,7 @@ export const runStatemachineReact = async () => {
+ wrapperConfig={langiumGlobalConfig} />
);
};
diff --git a/packages/examples/src/langium/statemachine/main.ts b/packages/examples/src/langium/statemachine/main.ts
index 48e5bc06c..a64819925 100644
--- a/packages/examples/src/langium/statemachine/main.ts
+++ b/packages/examples/src/langium/statemachine/main.ts
@@ -55,9 +55,7 @@ const startEditor = async () => {
useLanguageClient: true,
worker: stateMachineWorkerPort,
messagePort: channel.port1,
- connectionProvider: {
- get: async () => ({ reader, writer })
- }
+ messageTransports: { reader, writer }
});
await wrapper.initAndStart(langiumGlobalConfig, document.getElementById('monaco-editor-root'));
diff --git a/packages/examples/src/multi/twoLanguageClients.ts b/packages/examples/src/multi/twoLanguageClients.ts
new file mode 100644
index 000000000..d4085e14f
--- /dev/null
+++ b/packages/examples/src/multi/twoLanguageClients.ts
@@ -0,0 +1,149 @@
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) 2024 TypeFox and others.
+ * Licensed under the MIT License. See LICENSE in the package root for license information.
+ * ------------------------------------------------------------------------------------------ */
+
+import * as vscode from 'vscode';
+import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
+// this is required syntax highlighting
+import '@codingame/monaco-vscode-json-default-extension';
+import '@codingame/monaco-vscode-python-default-extension';
+import { CodePlusFileExt, MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
+import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
+import { MonacoLanguageClient } from 'monaco-languageclient';
+import { disableButton } from '../common/client/utils.js';
+
+export const configureMonacoWorkers = () => {
+ useWorkerFactory({
+ ignoreMapping: true,
+ workerLoaders: {
+ editorWorkerService: () => new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' })
+ }
+ });
+};
+
+export const runMultipleLanguageClientsExample = async () => {
+ disableButton('button-flip', true);
+
+ const textJson = `{
+ "$schema": "http://json.schemastore.org/coffeelint",
+ "line_endings": {"value": "unix"}
+}`;
+
+ const textPython = `from hello2 import print_hello
+
+print_hello()
+print("Hello Moon!")
+`;
+
+ let currentText = textJson;
+ let currenFileExt = 'json';
+
+ const wrapperConfig: WrapperConfig = {
+ id: '42',
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride()
+ },
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: currentText,
+ fileExt: currenFileExt
+ }
+ },
+ useDiffEditor: false,
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.wordBasedSuggestions': 'off'
+ })
+ }
+ },
+ languageClientConfigs: {
+ json: {
+ languageId: 'json',
+ name: 'JSON Client',
+ connection: {
+ options: {
+ $type: 'WebSocketParams',
+ host: 'localhost',
+ port: 30000,
+ path: 'sampleServer',
+ secured: false
+ }
+ }
+ },
+ python: {
+ languageId: 'python',
+ name: 'Python Client',
+ connection: {
+ options: {
+ $type: 'WebSocketParams',
+ host: 'localhost',
+ port: 30001,
+ path: 'pyright',
+ secured: false,
+ extraParams: {
+ authorization: 'UserAuth'
+ },
+ startOptions: {
+ onCall: (languageClient?: MonacoLanguageClient) => {
+ setTimeout(() => {
+ ['pyright.restartserver', 'pyright.organizeimports'].forEach((cmdName) => {
+ vscode.commands.registerCommand(cmdName, (...args: unknown[]) => {
+ languageClient?.sendRequest('workspace/executeCommand', { command: cmdName, arguments: args });
+ });
+ });
+ }, 250);
+ },
+ reportStatus: true,
+ }
+ }
+ },
+ clientOptions: {
+ documentSelector: ['python', 'py'],
+ workspaceFolder: {
+ index: 0,
+ name: 'workspace',
+ uri: vscode.Uri.parse('/workspace')
+ }
+ }
+ }
+ }
+ };
+
+ const htmlElement = document.getElementById('monaco-editor-root');
+ const wrapper = new MonacoEditorLanguageClientWrapper();
+
+ try {
+ document.querySelector('#button-start')?.addEventListener('click', async () => {
+ if (wrapperConfig.editorAppConfig.codeResources?.main !== undefined) {
+ (wrapperConfig.editorAppConfig.codeResources.main as CodePlusFileExt).text = currentText;
+ (wrapperConfig.editorAppConfig.codeResources.main as CodePlusFileExt).fileExt = currenFileExt;
+ }
+
+ await wrapper.initAndStart(wrapperConfig, htmlElement);
+ disableButton('button-flip', false);
+ });
+ document.querySelector('#button-dispose')?.addEventListener('click', async () => {
+ await wrapper.dispose();
+ disableButton('button-flip', true);
+ });
+ document.querySelector('#button-flip')?.addEventListener('click', async () => {
+ currentText = currentText === textJson ? textPython : textJson;
+ currenFileExt = currenFileExt === 'json' ? 'py' : 'json';
+ wrapper.updateCodeResources({
+ main: {
+ text: currentText,
+ fileExt: currenFileExt
+ }
+ });
+ });
+ } catch (e) {
+ console.error(e);
+ }
+};
diff --git a/packages/examples/src/python/client/config.ts b/packages/examples/src/python/client/config.ts
index cdb670e5a..72b5fa352 100644
--- a/packages/examples/src/python/client/config.ts
+++ b/packages/examples/src/python/client/config.ts
@@ -7,71 +7,83 @@ import * as vscode from 'vscode';
import getEditorServiceOverride from '@codingame/monaco-vscode-editor-service-override';
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
import '@codingame/monaco-vscode-python-default-extension';
-import { UserConfig } from 'monaco-editor-wrapper';
+import { createUrl, WrapperConfig } from 'monaco-editor-wrapper';
import { useOpenEditorStub } from 'monaco-editor-wrapper/vscode/services';
import { MonacoLanguageClient } from 'monaco-languageclient';
+import { toSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
+
+export const createUserConfig = (workspaceRoot: string, code: string, codeUri: string): WrapperConfig => {
+ const url = createUrl({
+ secured: false,
+ host: 'localhost',
+ port: 30001,
+ path: 'pyright',
+ extraParams: {
+ authorization: 'UserAuth'
+ }
+ });
+ const webSocket = new WebSocket(url);
+ const iWebSocket = toSocket(webSocket);
+ const reader = new WebSocketMessageReader(iWebSocket);
+ const writer = new WebSocketMessageWriter(iWebSocket);
-export const createUserConfig = (workspaceRoot: string, code: string, codeUri: string): UserConfig => {
return {
- languageClientConfig: {
- languageId: 'python',
- name: 'Python Language Server Example',
- options: {
- $type: 'WebSocket',
- host: 'localhost',
- port: 30001,
- path: 'pyright',
- extraParams: {
- authorization: 'UserAuth'
+ languageClientConfigs: {
+ python: {
+ languageId: 'python',
+ name: 'Python Language Server Example',
+ connection: {
+ options: {
+ $type: 'WebSocketDirect',
+ webSocket: webSocket,
+ startOptions: {
+ onCall: (languageClient?: MonacoLanguageClient) => {
+ setTimeout(() => {
+ ['pyright.restartserver', 'pyright.organizeimports'].forEach((cmdName) => {
+ vscode.commands.registerCommand(cmdName, (...args: unknown[]) => {
+ languageClient?.sendRequest('workspace/executeCommand', { command: cmdName, arguments: args });
+ });
+ });
+ }, 250);
+ },
+ reportStatus: true,
+ }
+ },
+ messageTransports: { reader, writer }
},
- secured: false,
- startOptions: {
- onCall: (languageClient?: MonacoLanguageClient) => {
- setTimeout(() => {
- ['pyright.restartserver', 'pyright.organizeimports'].forEach((cmdName) => {
- vscode.commands.registerCommand(cmdName, (...args: unknown[]) => {
- languageClient?.sendRequest('workspace/executeCommand', { command: cmdName, arguments: args });
- });
- });
- }, 250);
+ clientOptions: {
+ documentSelector: ['python'],
+ workspaceFolder: {
+ index: 0,
+ name: 'workspace',
+ uri: vscode.Uri.parse(workspaceRoot)
},
- reportStatus: true,
}
+ }
+ },
+ serviceConfig: {
+ userServices: {
+ ...getEditorServiceOverride(useOpenEditorStub),
+ ...getKeybindingsServiceOverride()
},
- clientOptions: {
- documentSelector: ['python'],
- workspaceFolder: {
- index: 0,
- name: 'workspace',
- uri: vscode.Uri.parse(workspaceRoot)
- },
- },
+ debugLogging: true
},
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getEditorServiceOverride(useOpenEditorStub),
- ...getKeybindingsServiceOverride()
- },
- debugLogging: true
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: code,
+ uri: codeUri
+ }
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: code,
- uri: codeUri
- }
- },
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'editor.guides.bracketPairsHorizontal': 'active',
- 'editor.wordBasedSuggestions': 'off'
- })
- },
- useDiffEditor: false
- }
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'editor.guides.bracketPairsHorizontal': 'active',
+ 'editor.wordBasedSuggestions': 'off'
+ })
+ },
+ useDiffEditor: false
},
loggerConfig: {
enabled: true,
diff --git a/packages/examples/src/python/client/reactPython.tsx b/packages/examples/src/python/client/reactPython.tsx
index b644d9c1e..38d35849a 100644
--- a/packages/examples/src/python/client/reactPython.tsx
+++ b/packages/examples/src/python/client/reactPython.tsx
@@ -41,7 +41,7 @@ export const runPythonReact = async () => {
return (
{
diff --git a/packages/examples/src/python/server/main.ts b/packages/examples/src/python/server/main.ts
index 684f9b6e9..1e736b5df 100644
--- a/packages/examples/src/python/server/main.ts
+++ b/packages/examples/src/python/server/main.ts
@@ -35,6 +35,7 @@ export const runPythonServer = (baseDir: string, relativeDir: string) => {
callback(false);
}
}
- }
+ },
+ logMessages: true
});
};
diff --git a/packages/examples/src/ts/wrapperAdvanced.ts b/packages/examples/src/ts/wrapperAdvanced.ts
deleted file mode 100644
index a8e80dab8..000000000
--- a/packages/examples/src/ts/wrapperAdvanced.ts
+++ /dev/null
@@ -1,236 +0,0 @@
-/* --------------------------------------------------------------------------------------------
- * Copyright (c) 2024 TypeFox and others.
- * Licensed under the MIT License. See LICENSE in the package root for license information.
- * ------------------------------------------------------------------------------------------ */
-
-import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
-import '@codingame/monaco-vscode-standalone-languages';
-import '@codingame/monaco-vscode-standalone-typescript-language-features';
-import { EditorAppConfigClassic, LanguageClientError, MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
-import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
-
-export const configureMonacoWorkers = () => {
- useWorkerFactory({
- ignoreMapping: true,
- workerLoaders: {
- editorWorkerService: () => new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' }),
- javascript: () => new Worker(new URL('monaco-editor-wrapper/workers/module/ts', import.meta.url), { type: 'module' }),
- }
- });
-};
-
-const wrapper42 = new MonacoEditorLanguageClientWrapper();
-const wrapper43 = new MonacoEditorLanguageClientWrapper();
-const wrapper44 = new MonacoEditorLanguageClientWrapper();
-
-const wrapper42Config: UserConfig = {
- id: '42',
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride()
- },
- debugLogging: true
- },
- editorAppConfig: {
- $type: 'classic',
- codeResources: {
- original: {
- text: `This line is equal.
-This number is different 2002
-Misspeelled!
-Same again.`,
- fileExt: 'txt'
- },
- main: {
- text: `This line is equal.
-This number is different 2022
-Misspelled!
-Same again.`,
- fileExt: 'txt'
- }
- },
- useDiffEditor: true,
- }
- },
- languageClientConfig: {
- languageId: 'json',
- name: 'wrapper42 language client',
- options: {
- $type: 'WebSocket',
- host: 'localhost',
- port: 30000,
- path: 'sampleServer',
- secured: false
- }
- }
-};
-
-const wrapper43Config: UserConfig = {
- id: '43',
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride()
- },
- debugLogging: true
- },
- editorAppConfig: {
- $type: 'classic',
- codeResources: {
- original: {
- text: 'This line is equal.\nThis number is different 3022.\nMisspelled!Same again.',
- fileExt: 'txt'
- },
- main: {
- text: 'This line is equal.\nThis number is different 3002.\nMisspelled!Same again.',
- fileExt: 'txt'
- }
- },
- useDiffEditor: true,
- editorOptions: {
- lineNumbers: 'off'
- },
- diffEditorOptions: {
- lineNumbers: 'off'
- }
- }
- }
-};
-
-const wrapper44Config: UserConfig = {
- id: '44',
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride()
- },
- debugLogging: true
- },
- editorAppConfig: {
- $type: 'classic',
- codeResources: {
- main: {
- text: `function logMe() {
- console.log('Hello monaco-editor-wrapper!');
-};`,
- fileExt: 'js'
- }
- },
- useDiffEditor: false,
- editorOptions: {
- minimap: {
- enabled: true
- },
- theme: 'vs-dark'
- }
- }
- }
-};
-
-const startWrapper42 = async () => {
- await wrapper42.initAndStart(wrapper42Config, document.getElementById('monaco-editor-root-42'));
- console.log('wrapper42 was started.');
-};
-
-const startWrapper43 = async () => {
- await wrapper43.initAndStart(wrapper43Config, document.getElementById('monaco-editor-root-43'));
- console.log('wrapper43 was started.');
-};
-const startWrapper44 = async () => {
- await wrapper44.initAndStart(wrapper44Config, document.getElementById('monaco-editor-root-44'));
- console.log('wrapper44 was started.');
-};
-
-const sleepOne = (milliseconds: number) => {
- setTimeout(async () => {
- alert(`Updating editors after ${milliseconds}ms`);
-
- await wrapper42.dispose();
- wrapper42Config.languageClientConfig = undefined;
- const appConfig42 = wrapper42Config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- appConfig42.codeResources = {
- main: {
- text: `function logMe() {
- console.log('Hello swap editors!');
-};`,
- fileExt: 'js'
- }
- };
- appConfig42.useDiffEditor = false;
- const w42Start = wrapper42.initAndStart(wrapper42Config, document.getElementById('monaco-editor-root-42'));
-
- const w43Start = await wrapper43.updateCodeResources({
- main: {
- text: 'text 5678',
- fileExt: 'txt'
- },
- original: {
- text: 'text 1234',
- fileExt: 'txt'
- }
- });
-
- await wrapper44.dispose();
- const appConfig44 = wrapper44Config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- appConfig44.useDiffEditor = true;
- appConfig44.codeResources = {
- original: {
- text: 'oh la la la!',
- fileExt: 'txt'
- },
- main: {
- text: 'oh lo lo lo!',
- fileExt: 'txt'
- }
- };
- // This affects all editors globally and is only effective
- // if it is not in contrast to one configured later
- appConfig44.editorOptions = {
- theme: 'vs-light'
- };
- const w44Start = wrapper44.initAndStart(wrapper44Config, document.getElementById('monaco-editor-root-44'));
-
- await w42Start;
- console.log('Restarted wrapper42.');
- await w43Start;
- console.log('Updated diffmodel of wrapper43.');
- await w44Start;
- console.log('Restarted wrapper44.');
- }, milliseconds);
-};
-
-const sleepTwo = (milliseconds: number) => {
- setTimeout(async () => {
- alert(`Updating last editor after ${milliseconds}ms`);
-
- await wrapper44.dispose();
- const appConfig44 = wrapper44Config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- appConfig44.useDiffEditor = false;
- appConfig44.editorOptions = {
- theme: 'vs-dark'
- };
- await wrapper44.initAndStart(wrapper44Config, document.getElementById('monaco-editor-root-44'));
- console.log('Restarted wrapper44.');
- }, milliseconds);
-};
-
-export const runAdvancedExample = async () => {
- try {
- await startWrapper43();
- await startWrapper44();
- try {
- await startWrapper42();
- } catch (e) {
- console.log(`Catched expected connection error: ${(e as LanguageClientError).message}`);
- }
-
- // change the editors config, content or swap normal and diff editors after five seconds
- sleepOne(5000);
-
- // change last editor to regular mode
- sleepTwo(10000);
- } catch (e) {
- console.error(e);
- }
-};
diff --git a/packages/examples/src/ts/wrapperTs.ts b/packages/examples/src/ts/wrapperTs.ts
index 5b10c12bb..56867bf12 100644
--- a/packages/examples/src/ts/wrapperTs.ts
+++ b/packages/examples/src/ts/wrapperTs.ts
@@ -8,7 +8,7 @@ import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-
import '@codingame/monaco-vscode-theme-defaults-default-extension';
import '@codingame/monaco-vscode-typescript-basics-default-extension';
import '@codingame/monaco-vscode-typescript-language-features-default-extension';
-import { CodePlusUri, MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
+import { CodePlusUri, MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
export const configureMonacoWorkers = () => {
@@ -31,39 +31,37 @@ export const runTsWrapper = async () => {
return "Goodbye";
};`;
- const userConfig: UserConfig = {
- wrapperConfig: {
- serviceConfig: {
- userServices: {
- ...getKeybindingsServiceOverride()
- },
- enableExtHostWorker: true,
- debugLogging: true
+ const wrapperConfig: WrapperConfig = {
+ serviceConfig: {
+ userServices: {
+ ...getKeybindingsServiceOverride()
},
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: code,
- uri: codeUri
- },
- original: {
- text: codeOriginal,
- uri: codeOriginalUri,
- }
+ enableExtHostWorker: true,
+ debugLogging: true
+ },
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: code,
+ uri: codeUri
},
- useDiffEditor: false,
- userConfiguration: {
- json: JSON.stringify({
- 'workbench.colorTheme': 'Default Dark Modern',
- 'typescript.tsserver.web.projectWideIntellisense.enabled': true,
- 'typescript.tsserver.web.projectWideIntellisense.suppressSemanticErrors': false,
- 'diffEditor.renderSideBySide': false,
- 'editor.lightbulb.enabled': 'on',
- 'editor.glyphMargin': true,
- 'editor.guides.bracketPairsHorizontal': true
- })
+ original: {
+ text: codeOriginal,
+ uri: codeOriginalUri,
}
+ },
+ useDiffEditor: false,
+ userConfiguration: {
+ json: JSON.stringify({
+ 'workbench.colorTheme': 'Default Dark Modern',
+ 'typescript.tsserver.web.projectWideIntellisense.enabled': true,
+ 'typescript.tsserver.web.projectWideIntellisense.suppressSemanticErrors': false,
+ 'diffEditor.renderSideBySide': false,
+ 'editor.lightbulb.enabled': 'on',
+ 'editor.glyphMargin': true,
+ 'editor.guides.bracketPairsHorizontal': true
+ })
}
}
};
@@ -73,7 +71,7 @@ export const runTsWrapper = async () => {
try {
document.querySelector('#button-start')?.addEventListener('click', async () => {
- await wrapper.initAndStart(userConfig, htmlElement);
+ await wrapper.initAndStart(wrapperConfig, htmlElement);
vscode.commands.getCommands().then((x) => {
console.log(`Found ${x.length} commands`);
@@ -112,9 +110,9 @@ export const runTsWrapper = async () => {
});
document.querySelector('#button-diff')?.addEventListener('click', async () => {
// ensure it is boolean value and not undefined
- const useDiffEditor = userConfig.wrapperConfig.editorAppConfig.useDiffEditor ?? false;
- userConfig.wrapperConfig.editorAppConfig.useDiffEditor = !useDiffEditor;
- await wrapper.initAndStart(userConfig, htmlElement);
+ const useDiffEditor = wrapperConfig.editorAppConfig.useDiffEditor ?? false;
+ wrapperConfig.editorAppConfig.useDiffEditor = !useDiffEditor;
+ await wrapper.initAndStart(wrapperConfig, htmlElement);
});
document.querySelector('#button-dispose')?.addEventListener('click', async () => {
await wrapper.dispose();
diff --git a/packages/examples/tsconfig.build.json b/packages/examples/tsconfig.build.json
index e41c77a38..0cb7e416d 100644
--- a/packages/examples/tsconfig.build.json
+++ b/packages/examples/tsconfig.build.json
@@ -2,11 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./build",
- "noEmit": true,
- // all other types are not needed here
- "types": [
- "node"
- ]
+ "noEmit": true
},
"include": [
"build/**/*.ts",
diff --git a/packages/examples/two_langauge_clients.html b/packages/examples/two_langauge_clients.html
new file mode 100644
index 000000000..a8d6b9d31
--- /dev/null
+++ b/packages/examples/two_langauge_clients.html
@@ -0,0 +1,25 @@
+
+
+
+
+ Json & Python Languageclients & Language Server (Web Socket)
+
+
+
+
+
+
+ Json & Python Languageclients & Language Server (Web Socket)
+
+
+
+
+
+
+
+
diff --git a/packages/examples/wrapper_adv.html b/packages/examples/wrapper_adv.html
deleted file mode 100644
index e8e79f041..000000000
--- a/packages/examples/wrapper_adv.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
- Multiple Editors
-
-
-
-
- Multiple Editors
-
-
-
-
-
-
-
-
-
-
diff --git a/packages/examples/wrapper_ws.html b/packages/examples/wrapper_ws.html
index d1fd7c2f3..82472b9bc 100644
--- a/packages/examples/wrapper_ws.html
+++ b/packages/examples/wrapper_ws.html
@@ -2,9 +2,9 @@
+ JSON Language Client & Language Server (Web Socket)
- JSON Language Client & Language Server (Web Socket)
diff --git a/packages/vscode-ws-jsonrpc/package.json b/packages/vscode-ws-jsonrpc/package.json
index 068865a3f..9e5f6a51c 100644
--- a/packages/vscode-ws-jsonrpc/package.json
+++ b/packages/vscode-ws-jsonrpc/package.json
@@ -51,8 +51,8 @@
"npm": ">=8.0.0"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"files": [
"lib",
diff --git a/packages/vscode-ws-jsonrpc/tsconfig.src.json b/packages/vscode-ws-jsonrpc/tsconfig.src.json
index 618618919..b7c5ac54f 100644
--- a/packages/vscode-ws-jsonrpc/tsconfig.src.json
+++ b/packages/vscode-ws-jsonrpc/tsconfig.src.json
@@ -3,9 +3,7 @@
"compilerOptions": {
"rootDir": "src",
"outDir": "lib",
- "declarationDir": "lib",
- // no types definitions are required to undertand dependent code
- "types": []
+ "declarationDir": "lib"
},
"include": [
"src/**/*.ts",
diff --git a/packages/wrapper-react/CHANGELOG.md b/packages/wrapper-react/CHANGELOG.md
index 715d34385..19c250728 100644
--- a/packages/wrapper-react/CHANGELOG.md
+++ b/packages/wrapper-react/CHANGELOG.md
@@ -2,6 +2,10 @@
All notable changes to npm module [@typefox/monaco-editor-react](https://www.npmjs.com/package/@typefox/monaco-editor-react) are documented in this file.
+## [6.0.0-next.0] - 2024-09-xy
+
+- Updated to `monaco-editor-wrapper@9.0.0-next.0` and `monaco-languageclient@6.0.0-next.0`. Updated all `@codingame/monaco-vscode` packages to `8.0.4`.
+
## [4.5.3] - 2024-08-26
- Updated to `monaco-editor-wrapper@5.5.3` and `monaco-languageclient@8.8.3`. Updated all `@codingame/monaco-vscode` packages to `8.0.4`.
diff --git a/packages/wrapper-react/package.json b/packages/wrapper-react/package.json
index 302868429..e7fee5f18 100644
--- a/packages/wrapper-react/package.json
+++ b/packages/wrapper-react/package.json
@@ -1,6 +1,6 @@
{
"name": "@typefox/monaco-editor-react",
- "version": "4.5.3",
+ "version": "6.0.0-next.0",
"license": "MIT",
"description": "React component for Monaco-Editor and Monaco Languageclient",
"keywords": [
@@ -38,20 +38,20 @@
"build": "npm run clean && npm run compile"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"dependencies": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3",
- "monaco-languageclient": "~8.8.3",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient": "~9.0.0-next.0",
"react": "~18.3.1",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4"
},
"peerDependencies": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3",
- "monaco-languageclient": "~8.8.3",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient": "~9.0.0-next.0",
"react": "~18.3.1",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4"
},
diff --git a/packages/wrapper-react/src/index.tsx b/packages/wrapper-react/src/index.tsx
index 4af8680f9..475d38d79 100644
--- a/packages/wrapper-react/src/index.tsx
+++ b/packages/wrapper-react/src/index.tsx
@@ -5,7 +5,7 @@
import * as monaco from 'monaco-editor';
import React, { CSSProperties, useCallback, useEffect, useRef, useState } from 'react';
-import { MonacoEditorLanguageClientWrapper, TextContents, UserConfig } from 'monaco-editor-wrapper';
+import { MonacoEditorLanguageClientWrapper, TextContents, WrapperConfig } from 'monaco-editor-wrapper';
import { Logger } from 'monaco-languageclient/tools';
export type TextChanges = TextContents & {
@@ -15,7 +15,7 @@ export type TextChanges = TextContents & {
export type MonacoEditorProps = {
style?: CSSProperties;
className?: string;
- userConfig: UserConfig,
+ wrapperConfig: WrapperConfig,
onTextChanged?: (textChanges: TextChanges) => void;
onLoad?: (wrapper: MonacoEditorLanguageClientWrapper) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -26,7 +26,7 @@ export const MonacoEditorReactComp: React.FC = (props) => {
const {
style,
className,
- userConfig,
+ wrapperConfig,
onTextChanged,
onLoad,
onError
@@ -38,7 +38,7 @@ export const MonacoEditorReactComp: React.FC = (props) => {
const [onTextChangedSubscriptions, setOnTextChangedSubscriptions] = useState([]);
useEffect(() => {
- loggerRef.current.updateConfig(userConfig.loggerConfig);
+ loggerRef.current.updateConfig(wrapperConfig.loggerConfig);
return () => {
destroyMonaco();
};
@@ -46,7 +46,7 @@ export const MonacoEditorReactComp: React.FC = (props) => {
useEffect(() => {
handleReInit();
- }, [userConfig]);
+ }, [wrapperConfig]);
useEffect(() => {
handleOnTextChanged();
@@ -72,11 +72,11 @@ export const MonacoEditorReactComp: React.FC = (props) => {
await wrapperRef.current.isStarting();
}
- }, [userConfig]);
+ }, [wrapperConfig]);
const initMonaco = useCallback(async () => {
- await wrapperRef.current.init(userConfig);
- }, [userConfig]);
+ await wrapperRef.current.init(wrapperConfig);
+ }, [wrapperConfig]);
const startMonaco = useCallback(async () => {
if (containerRef.current) {
@@ -105,7 +105,7 @@ export const MonacoEditorReactComp: React.FC = (props) => {
const verifyModelContent = () => {
const text = textModels.text?.getValue() ?? '';
const textOriginal = textModels.textOriginal?.getValue() ?? '';
- const codeResources = userConfig.wrapperConfig.editorAppConfig.codeResources;
+ const codeResources = wrapperConfig.editorAppConfig.codeResources;
const dirty = text !== codeResources?.main?.text;
const dirtyOriginal = textOriginal !== codeResources?.original?.text;
onTextChanged({
@@ -132,7 +132,7 @@ export const MonacoEditorReactComp: React.FC = (props) => {
// do it initially
verifyModelContent();
}
- }, [onTextChanged, userConfig]);
+ }, [onTextChanged, wrapperConfig]);
const destroyMonaco = useCallback(async () => {
try {
diff --git a/packages/wrapper-react/test/index.test.tsx b/packages/wrapper-react/test/index.test.tsx
index 3a4a8e399..9d16f15a4 100644
--- a/packages/wrapper-react/test/index.test.tsx
+++ b/packages/wrapper-react/test/index.test.tsx
@@ -7,37 +7,35 @@ import { describe, expect, test } from 'vitest';
import { render, RenderResult } from '@testing-library/react';
import React from 'react';
import { MonacoEditorReactComp, TextChanges } from '@typefox/monaco-editor-react';
-import { MonacoEditorLanguageClientWrapper, UserConfig } from 'monaco-editor-wrapper';
-import { updateExtendedAppPrototyp } from './helper';
+import { MonacoEditorLanguageClientWrapper, WrapperConfig } from 'monaco-editor-wrapper';
+import { updateExtendedAppPrototyp } from './helper.js';
describe('Test MonacoEditorReactComp', () => {
test('rerender', async () => {
updateExtendedAppPrototyp();
- const userConfig: UserConfig = {
- wrapperConfig: {
- editorAppConfig: {
- $type: 'extended',
- }
+ const wrapperConfig: WrapperConfig = {
+ editorAppConfig: {
+ $type: 'extended',
},
loggerConfig: {
enabled: true,
debugEnabled: true,
}
};
- const { rerender } = render();
- rerender();
+ const { rerender } = render();
+ rerender();
await Promise.resolve();
- rerender();
+ rerender();
let renderResult: RenderResult;
// we have to await the full start of the editor with the onLoad callback, then it is save to contine
const p = await new Promise(resolve => {
const handleOnLoad = async (_wrapper: MonacoEditorLanguageClientWrapper) => {
- renderResult.rerender();
+ renderResult.rerender();
resolve();
};
- renderResult = render();
+ renderResult = render();
});
// void promise is undefined after it was awaited
expect(p).toBeUndefined();
@@ -45,15 +43,13 @@ describe('Test MonacoEditorReactComp', () => {
test('update onTextChanged', async () => {
updateExtendedAppPrototyp();
- const userConfig: UserConfig = {
- wrapperConfig: {
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: 'hello world',
- fileExt: 'js'
- }
+ const wrapperConfig: WrapperConfig = {
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: 'hello world',
+ fileExt: 'js'
}
}
},
@@ -74,13 +70,13 @@ describe('Test MonacoEditorReactComp', () => {
p1Resolve();
};
// because the onTextChanged callback is updated there will be a result even if the text is unchanged
- renderResult.rerender();
+ renderResult.rerender();
});
expect(p1).toBeUndefined();
resolve();
};
- renderResult = render();
+ renderResult = render();
});
// void promise is undefined after it was awaited
expect(p).toBeUndefined();
@@ -88,15 +84,13 @@ describe('Test MonacoEditorReactComp', () => {
test('update codeResources', async () => {
updateExtendedAppPrototyp();
- const userConfig: UserConfig = {
- wrapperConfig: {
- editorAppConfig: {
- $type: 'extended',
- codeResources: {
- main: {
- text: 'hello world',
- fileExt: 'js'
- }
+ const wrapperConfig: WrapperConfig = {
+ editorAppConfig: {
+ $type: 'extended',
+ codeResources: {
+ main: {
+ text: 'hello world',
+ fileExt: 'js'
}
}
},
@@ -125,13 +119,13 @@ describe('Test MonacoEditorReactComp', () => {
p1Resolve();
};
- renderResult.rerender();
+ renderResult.rerender();
});
expect(p1).toBeUndefined();
resolve();
};
- renderResult = render();
+ renderResult = render();
});
// void promise is undefined after it was awaited
expect(p).toBeUndefined();
diff --git a/packages/wrapper-react/tsconfig.src.json b/packages/wrapper-react/tsconfig.src.json
index fe71f2b09..36d5005ae 100644
--- a/packages/wrapper-react/tsconfig.src.json
+++ b/packages/wrapper-react/tsconfig.src.json
@@ -4,9 +4,10 @@
"rootDir": "src",
"outDir": "dist",
"declarationDir": "dist",
- "types": [
- "vscode"
- ]
+ // because vscode-jsonrpc requires DedicatedWorkerGlobalScope
+ // we are required to include both DOM and WebWorker libs
+ // the only way out currently is to disable lib checking
+ "skipLibCheck": true
},
"references": [{
"path": "../wrapper/tsconfig.src.json"
diff --git a/packages/wrapper-react/tsconfig.test.json b/packages/wrapper-react/tsconfig.test.json
index b3ee8ba7a..dfccd5b7a 100644
--- a/packages/wrapper-react/tsconfig.test.json
+++ b/packages/wrapper-react/tsconfig.test.json
@@ -2,7 +2,11 @@
"extends": "./tsconfig.src.json",
"compilerOptions": {
"noEmit": true,
- "rootDir": "test"
+ "rootDir": "test",
+ // because vscode-jsonrpc requires DedicatedWorkerGlobalScope
+ // we are required to include both DOM and WebWorker libs
+ // the only way out currently is to disable lib checking
+ "skipLibCheck": true
},
"references": [{
"path": "./tsconfig.src.json"
diff --git a/packages/wrapper/CHANGELOG.md b/packages/wrapper/CHANGELOG.md
index 127c0db1f..7d5701b77 100644
--- a/packages/wrapper/CHANGELOG.md
+++ b/packages/wrapper/CHANGELOG.md
@@ -2,6 +2,10 @@
All notable changes to npm module [monaco-editor-wrapper](https://www.npmjs.com/package/monaco-editor-wrapper) are documented in this file.
+## [6.0.0-next.0] - 2024-08-xy
+
+- Updated to `monaco-languageclient@9.0.0-next.0`. Updated all `@codingame/monaco-vscode` packages to `8.0.4`.
+
## [5.5.3] - 2024-08-26
- Updated to `monaco-languageclient@8.8.3`. Updated all `@codingame/monaco-vscode` packages to `8.0.4`.
diff --git a/packages/wrapper/package.json b/packages/wrapper/package.json
index 441498f80..5cc3da210 100644
--- a/packages/wrapper/package.json
+++ b/packages/wrapper/package.json
@@ -1,6 +1,6 @@
{
"name": "monaco-editor-wrapper",
- "version": "5.5.3",
+ "version": "6.0.0-next.0",
"license": "MIT",
"description": "Wrapper for monaco-vscode-editor-api and monaco-languageclient",
"keywords": [
@@ -81,8 +81,8 @@
"build": "npm run clean && npm run compile && npm run build:workers:esbuild && npm run build:workers:vite"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"dependencies": {
"@codingame/monaco-vscode-configuration-service-override": "~8.0.4",
@@ -120,7 +120,7 @@
},
"peerDependencies": {
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-languageclient": "~8.8.3",
+ "monaco-languageclient": "~9.0.0-next.0",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4"
},
"peerDependenciesMeta": {
diff --git a/packages/wrapper/src/editorAppBase.ts b/packages/wrapper/src/editorAppBase.ts
index 041492cdb..24ed6f381 100644
--- a/packages/wrapper/src/editorAppBase.ts
+++ b/packages/wrapper/src/editorAppBase.ts
@@ -10,27 +10,27 @@ import { getUserConfiguration, updateUserConfiguration as vscodeUpdateUserConfig
import { getEditorUri, isModelUpdateRequired, ModelUpdateType } from './utils.js';
import { Logger } from 'monaco-languageclient/tools';
-export type CodeContent = {
+export interface CodeContent {
text: string;
enforceLanguageId?: string;
}
-export type CodePlusUri = CodeContent & {
+export interface CodePlusUri extends CodeContent {
uri: string;
}
-export type CodePlusFileExt = CodeContent & {
+export interface CodePlusFileExt extends CodeContent {
fileExt: string;
}
-export type CodeResources = {
+export interface CodeResources {
main?: CodePlusUri | CodePlusFileExt;
original?: CodePlusUri | CodePlusFileExt;
}
export type EditorAppType = 'extended' | 'classic';
-export type EditorAppConfigBase = {
+export interface EditorAppConfigBase {
$type: EditorAppType;
codeResources?: CodeResources;
useDiffEditor?: boolean;
@@ -42,17 +42,17 @@ export type EditorAppConfigBase = {
diffEditorOptions?: monaco.editor.IStandaloneDiffEditorConstructionOptions;
}
-export type ModelRefs = {
+export interface ModelRefs {
modelRef?: IReference;
modelRefOriginal?: IReference;
}
-export type TextModels = {
+export interface TextModels {
text?: monaco.editor.ITextModel;
textOriginal?: monaco.editor.ITextModel;
}
-export type TextContents = {
+export interface TextContents {
text?: string;
textOriginal?: string;
}
diff --git a/packages/wrapper/src/editorAppClassic.ts b/packages/wrapper/src/editorAppClassic.ts
index 333870627..33cc177a2 100644
--- a/packages/wrapper/src/editorAppClassic.ts
+++ b/packages/wrapper/src/editorAppClassic.ts
@@ -7,9 +7,8 @@ import * as monaco from 'monaco-editor';
import { Logger } from 'monaco-languageclient/tools';
import { EditorAppBase, EditorAppConfigBase } from './editorAppBase.js';
import { ModelUpdateType, isEqual, isModelUpdateRequired } from './utils.js';
-import { UserConfig } from './userConfig.js';
-export type EditorAppConfigClassic = EditorAppConfigBase & {
+export interface EditorAppConfigClassic extends EditorAppConfigBase {
$type: 'classic';
languageDef?: {
languageExtensionConfig: monaco.languages.ILanguageExtensionPoint;
@@ -19,7 +18,7 @@ export type EditorAppConfigClassic = EditorAppConfigBase & {
data: monaco.editor.IStandaloneThemeData;
}
}
-};
+}
/**
* The classic monaco-editor app uses the classic monaco-editor configuration.
@@ -28,11 +27,10 @@ export class EditorAppClassic extends EditorAppBase {
private config: EditorAppConfigClassic;
- constructor(id: string, userConfig: UserConfig, logger?: Logger) {
+ constructor(id: string, editorAppConfig: EditorAppConfigClassic, logger?: Logger) {
super(id, logger);
- const userAppConfig = userConfig.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- this.config = this.buildConfig(userAppConfig) as EditorAppConfigClassic;
- this.config.languageDef = userAppConfig.languageDef;
+ this.config = this.buildConfig(editorAppConfig) as EditorAppConfigClassic;
+ this.config.languageDef = editorAppConfig.languageDef;
}
getConfig(): EditorAppConfigClassic {
@@ -88,7 +86,7 @@ export class EditorAppClassic extends EditorAppBase {
this.disposeEditors();
}
- isAppConfigDifferent(orgConfig: EditorAppConfigClassic, config: EditorAppConfigClassic, includeModelData: boolean): boolean {
+ isAppConfigDifferent(orgConfig: EditorAppConfigBase, config: EditorAppConfigBase, includeModelData: boolean): boolean {
let different = false;
if (includeModelData) {
different = isModelUpdateRequired(orgConfig.codeResources, config.codeResources) !== ModelUpdateType.NONE;
diff --git a/packages/wrapper/src/editorAppExtended.ts b/packages/wrapper/src/editorAppExtended.ts
index 22e8367ab..83d6ee15e 100644
--- a/packages/wrapper/src/editorAppExtended.ts
+++ b/packages/wrapper/src/editorAppExtended.ts
@@ -8,39 +8,38 @@ import * as monaco from 'monaco-editor';
import { EditorAppBase, EditorAppConfigBase } from './editorAppBase.js';
import { registerExtension, IExtensionManifest, ExtensionHostKind } from 'vscode/extensions';
import { Logger } from 'monaco-languageclient/tools';
-import { UserConfig } from './userConfig.js';
import { verifyUrlOrCreateDataUrl, ModelUpdateType, isEqual, isModelUpdateRequired } from './utils.js';
import { DisposableStore } from 'vscode/monaco';
-export type ExtensionConfig = {
+export interface ExtensionConfig {
config: IExtensionManifest | object;
filesOrContents?: Map;
-};
+}
-export type UserConfiguration = {
+export interface UserConfiguration {
json?: string;
}
-export type EditorAppConfigExtended = EditorAppConfigBase & {
+export interface EditorAppConfigExtended extends EditorAppConfigBase {
$type: 'extended';
extensions?: ExtensionConfig[];
userConfiguration?: UserConfiguration;
-};
+}
-export type RegisterExtensionResult = {
+export interface RegisterExtensionResult {
id: string;
dispose(): Promise;
whenReady(): Promise;
}
-interface RegisterLocalExtensionResult extends RegisterExtensionResult {
+export interface RegisterLocalExtensionResult extends RegisterExtensionResult {
registerFileUrl: (path: string, url: string) => monaco.IDisposable;
}
-export type RegisterLocalProcessExtensionResult = RegisterLocalExtensionResult & {
+export interface RegisterLocalProcessExtensionResult extends RegisterLocalExtensionResult {
getApi(): Promise;
setAsDefaultApi(): Promise;
-};
+}
/**
* The vscode-apo monaco-editor app uses vscode user and extension configuration for monaco-editor.
@@ -51,13 +50,12 @@ export class EditorAppExtended extends EditorAppBase {
private extensionRegisterResults: Map = new Map();
private subscriptions: DisposableStore = new DisposableStore();
- constructor(id: string, userConfig: UserConfig, logger?: Logger) {
+ constructor(id: string, editorAppConfig: EditorAppConfigExtended, logger?: Logger) {
super(id);
this.logger = logger;
- const userAppConfig = userConfig.wrapperConfig.editorAppConfig as EditorAppConfigExtended;
- this.config = this.buildConfig(userAppConfig) as EditorAppConfigExtended;
- this.config.extensions = userAppConfig.extensions ?? undefined;
- this.config.userConfiguration = userAppConfig.userConfiguration ?? undefined;
+ this.config = this.buildConfig(editorAppConfig) as EditorAppConfigExtended;
+ this.config.extensions = editorAppConfig.extensions ?? undefined;
+ this.config.userConfiguration = editorAppConfig.userConfiguration ?? undefined;
}
getConfig(): EditorAppConfigExtended {
@@ -112,7 +110,7 @@ export class EditorAppExtended extends EditorAppBase {
this.subscriptions.dispose();
}
- isAppConfigDifferent(orgConfig: EditorAppConfigExtended, config: EditorAppConfigExtended, includeModelData: boolean): boolean {
+ isAppConfigDifferent(orgConfig: EditorAppConfigBase, config: EditorAppConfigBase, includeModelData: boolean): boolean {
let different = false;
if (includeModelData) {
different = isModelUpdateRequired(orgConfig.codeResources, config.codeResources) !== ModelUpdateType.NONE;
diff --git a/packages/wrapper/src/index.ts b/packages/wrapper/src/index.ts
index 46e0035c4..f7598fac8 100644
--- a/packages/wrapper/src/index.ts
+++ b/packages/wrapper/src/index.ts
@@ -3,104 +3,20 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
-import {
- EditorAppBase,
-} from './editorAppBase.js';
+export type * from './editorAppBase.js';
+export * from './editorAppBase.js';
-import type {
- EditorAppConfigBase,
- EditorAppType,
- CodeContent,
- CodePlusUri,
- CodePlusFileExt,
- CodeResources,
- ModelRefs,
- TextModels,
- TextContents
-} from './editorAppBase.js';
+export type * from './editorAppClassic.js';
+export * from './editorAppClassic.js';
-import type {
- EditorAppConfigClassic,
-} from './editorAppClassic.js';
+export type * from './editorAppExtended.js';
+export * from './editorAppExtended.js';
-import {
- EditorAppClassic
-} from './editorAppClassic.js';
+export type * from './languageClientWrapper.js';
+export * from './languageClientWrapper.js';
-import type {
- ExtensionConfig,
- EditorAppConfigExtended,
- RegisterExtensionResult,
- RegisterLocalProcessExtensionResult,
- UserConfiguration
-} from './editorAppExtended.js';
-
-import {
- EditorAppExtended
-} from './editorAppExtended.js';
-
-import type {
- WebSocketCallOptions,
- LanguageClientConfigType,
- WebSocketConfigOptions,
- WebSocketConfigOptionsUrl,
- WorkerConfigOptions,
- WorkerConfigDirect
-} from './commonTypes.js';
-
-import type {
- LanguageClientConfig,
- LanguageClientError
-} from './languageClientWrapper.js';
-
-import {
- LanguageClientWrapper,
-} from './languageClientWrapper.js';
-
-import type {
- UserConfig,
- WrapperConfig
-} from './userConfig.js';
-
-import {
- MonacoEditorLanguageClientWrapper,
-} from './wrapper.js';
-
-export type {
- WrapperConfig,
- EditorAppConfigBase,
- EditorAppType,
- EditorAppConfigClassic,
- ExtensionConfig,
- EditorAppConfigExtended,
- RegisterExtensionResult,
- RegisterLocalProcessExtensionResult,
- UserConfiguration,
- WebSocketCallOptions,
- LanguageClientConfigType,
- WebSocketConfigOptions,
- WebSocketConfigOptionsUrl,
- WorkerConfigOptions,
- WorkerConfigDirect,
- LanguageClientConfig,
- LanguageClientError,
- UserConfig,
- CodeContent,
- CodePlusUri,
- CodePlusFileExt,
- CodeResources,
- ModelRefs,
- TextModels,
- TextContents
-};
-
-export {
- MonacoEditorLanguageClientWrapper,
- LanguageClientWrapper,
- EditorAppBase,
- EditorAppClassic,
- EditorAppExtended
-};
+export type * from './wrapper.js';
+export * from './wrapper.js';
export * from './utils.js';
export type * from './utils.js';
diff --git a/packages/wrapper/src/languageClientWrapper.ts b/packages/wrapper/src/languageClientWrapper.ts
index a964e1770..aba92f200 100644
--- a/packages/wrapper/src/languageClientWrapper.ts
+++ b/packages/wrapper/src/languageClientWrapper.ts
@@ -3,40 +3,48 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
-import { MonacoLanguageClient, IConnectionProvider } from 'monaco-languageclient';
-import { toSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
-import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver-protocol/browser.js';
-import { CloseAction, ErrorAction, LanguageClientOptions, MessageTransports, State } from 'vscode-languageclient/lib/common/client.js';
+import { MonacoLanguageClient, ConnetionConfigOptions, WorkerConfigOptionsDirect, WorkerConfigOptionsParams } from 'monaco-languageclient';
import { Logger } from 'monaco-languageclient/tools';
+import { BrowserMessageReader, BrowserMessageWriter } from 'vscode-languageserver-protocol/browser.js';
+import { CloseAction, ErrorAction, LanguageClientOptions, MessageTransports, State } from 'vscode-languageclient/browser.js';
import { createUrl } from './utils.js';
-import { WebSocketConfigOptions, WebSocketConfigOptionsUrl, WorkerConfigDirect, WorkerConfigOptions } from './commonTypes.js';
+import { toSocket, WebSocketMessageReader, WebSocketMessageWriter } from 'vscode-ws-jsonrpc';
-export type LanguageClientConfig = {
- languageId: string;
- options: WebSocketConfigOptions | WebSocketConfigOptionsUrl | WorkerConfigOptions | WorkerConfigDirect;
+export interface ConnectionConfig {
+ options: ConnetionConfigOptions;
+ messageTransports?: MessageTransports;
+}
+
+export interface LanguageClientConfig {
name?: string;
+ languageId: string;
+ connection: ConnectionConfig;
clientOptions?: LanguageClientOptions;
- connectionProvider?: IConnectionProvider;
+ restartOptions?: LanguageClientRestartOptions;
}
-export type LanguageClientError = {
+export interface LanguageClientRestartOptions {
+ retries: number;
+ timeout: number;
+ keepWorker?: boolean;
+}
+
+export interface LanguageClientError {
message: string;
error: Error | string;
-};
+}
export class LanguageClientWrapper {
private languageClient?: MonacoLanguageClient;
- private languageClientConfig?: LanguageClientConfig;
- private messageTransports?: MessageTransports;
- private connectionProvider?: IConnectionProvider;
+ private languageClientConfig: LanguageClientConfig;
private languageId: string;
private worker?: Worker;
private port?: MessagePort;
private name?: string;
private logger: Logger | undefined;
- async init(config: {
+ constructor(config: {
languageClientConfig: LanguageClientConfig,
logger?: Logger
}) {
@@ -50,10 +58,6 @@ export class LanguageClientWrapper {
return this.languageClient !== undefined;
}
- haveLanguageClientConfig(): boolean {
- return this.languageClientConfig !== undefined;
- }
-
getLanguageClient(): MonacoLanguageClient | undefined {
return this.languageClient;
}
@@ -66,24 +70,24 @@ export class LanguageClientWrapper {
return this.languageClient !== undefined && this.languageClient.isRunning();
}
- getMessageTransports(): MessageTransports | undefined {
- return this.messageTransports;
- }
+ async start(): Promise {
+ if (this.languageClient?.isRunning() ?? false) {
+ this.logger?.info('startLanguageClientConnection: monaco-languageclient already running!');
+ return Promise.resolve();
+ }
- getConnectionProvider(): IConnectionProvider | undefined {
- return this.connectionProvider;
- }
+ return new Promise((resolve, reject) => {
+ const conConfig = this.languageClientConfig.connection;
+ const conOptions = conConfig.options;
- async start() {
- if (this.languageClientConfig) {
- return this.startLanguageClientConnection();
- } else {
- const languageClientError: LanguageClientError = {
- message: `languageClientWrapper (${this.name}): Unable to start monaco-languageclient. No configuration was provided.`,
- error: 'No error was provided.'
- };
- return Promise.reject(languageClientError);
- }
+ if (conOptions.$type === 'WebSocketDirect' || conOptions.$type === 'WebSocketParams' || conOptions.$type === 'WebSocketUrl') {
+ const webSocket = conOptions.$type === 'WebSocketDirect' ? conOptions.webSocket : new WebSocket(createUrl(conOptions));
+ this.initMessageTransportWebSocket(webSocket, resolve, reject);
+ } else {
+ // init of worker and start of languageclient can be handled directly, because worker available already
+ this.initMessageTransportWorker(conOptions, resolve, reject);
+ }
+ });
}
/**
@@ -92,108 +96,91 @@ export class LanguageClientWrapper {
* @param updatedWorker Set a new worker here that should be used. keepWorker has no effect then, as we want to dispose of the prior workers
* @param keepWorker Set to true if worker should not be disposed
*/
- async restartLanguageClient(updatedWorker?: Worker, keepWorker?: boolean): Promise {
- if (updatedWorker) {
- await this.disposeLanguageClient(false);
- } else {
- await this.disposeLanguageClient(keepWorker);
- }
+ async restartLanguageClient(updatedWorker?: Worker, keepWorker: boolean = false): Promise {
+ await this.disposeLanguageClient(keepWorker);
+
this.worker = updatedWorker;
- if (this.languageClientConfig) {
- this.logger?.info('Re-Starting monaco-languageclient');
- return this.startLanguageClientConnection();
- } else {
- const languageClientError: LanguageClientError = {
- message: `languageClientWrapper (${this.name}): Unable to restart languageclient. No configuration was provided.`,
- error: 'No error was provided.'
+ this.logger?.info('Re-Starting monaco-languageclient');
+ return this.start();
+ }
+
+ protected async initMessageTransportWebSocket(webSocket: WebSocket, resolve: () => void, reject: (reason?: unknown) => void) {
+
+ let messageTransports = this.languageClientConfig.connection.messageTransports;
+ if (messageTransports === undefined) {
+ const iWebSocket = toSocket(webSocket);
+ messageTransports = {
+ reader: new WebSocketMessageReader(iWebSocket),
+ writer: new WebSocketMessageWriter(iWebSocket)
};
- return Promise.reject(languageClientError);
}
- }
- private startLanguageClientConnection(): Promise {
- if (this.languageClient && this.languageClient.isRunning()) {
- this.logger?.info('monaco-languageclient already running!');
- return Promise.resolve();
+ // if websocket is already open, then start the languageclient directly
+ if (webSocket.readyState === WebSocket.OPEN) {
+ await this.performLanguageClientStart(messageTransports, resolve, reject);
}
- const lcConfig = this.languageClientConfig?.options;
- // allow to fully override the clonnecetionProvider
- // if it is undefined it will be created from the message transports in handleLanguageClientStart
- this.connectionProvider = this.languageClientConfig?.connectionProvider;
+ // otherwise start on open
+ webSocket.onopen = async () => {
+ await this.performLanguageClientStart(messageTransports, resolve, reject);
+ };
+ webSocket.onerror = (ev: Event) => {
+ const languageClientError: LanguageClientError = {
+ message: `languageClientWrapper (${this.name}): Websocket connection failed.`,
+ error: (ev as ErrorEvent).error ?? 'No error was provided.'
+ };
+ reject(languageClientError);
+ };
+ }
- return new Promise((resolve, reject) => {
- if (lcConfig?.$type === 'WebSocket' || lcConfig?.$type === 'WebSocketUrl') {
- const url = createUrl(lcConfig);
- const webSocket = new WebSocket(url);
-
- webSocket.onopen = async () => {
- const socket = toSocket(webSocket);
- this.messageTransports = await this.connectionProvider?.get('') ?? {
- reader: new WebSocketMessageReader(socket),
- writer: new WebSocketMessageWriter(socket)
- };
- this.handleLanguageClientStart(resolve, reject);
- };
- webSocket.onerror = (ev: Event) => {
+ protected async initMessageTransportWorker(lccOptions: WorkerConfigOptionsDirect | WorkerConfigOptionsParams, resolve: () => void, reject: (reason?: unknown) => void) {
+ if (!this.worker) {
+ if (lccOptions.$type === 'WorkerConfig') {
+ const workerConfig = lccOptions as WorkerConfigOptionsParams;
+ this.worker = new Worker(new URL(workerConfig.url, import.meta.url).href, {
+ type: workerConfig.type,
+ name: workerConfig.workerName
+ });
+
+ this.worker.onerror = (ev) => {
const languageClientError: LanguageClientError = {
- message: `languageClientWrapper (${this.name}): Websocket connection failed.`,
- error: (ev as ErrorEvent).error ?? 'No error was provided.'
+ message: `languageClientWrapper (${this.name}): Illegal worker configuration detected. Potentially the url is wrong.`,
+ error: ev.error ?? 'No error was provided.'
};
reject(languageClientError);
};
} else {
- if (!this.worker) {
- if (lcConfig?.$type === 'WorkerConfig') {
- const workerConfig = lcConfig as WorkerConfigOptions;
- this.worker = new Worker(new URL(workerConfig.url, import.meta.url).href, {
- type: workerConfig.type,
- name: workerConfig.workerName
- });
-
- this.worker.onerror = (ev) => {
- const languageClientError: LanguageClientError = {
- message: `languageClientWrapper (${this.name}): Illegal worker configuration detected. Potentially the url is wrong.`,
- error: ev.error ?? 'No error was provided.'
- };
- reject(languageClientError);
- };
- } else {
- const workerDirectConfig = lcConfig as WorkerConfigDirect;
- this.worker = workerDirectConfig.worker;
- }
- if (lcConfig?.messagePort) {
- this.port = lcConfig.messagePort;
- }
- }
-
- const startWorkerLS = async (port: MessagePort | Worker) => {
- this.messageTransports = await this.connectionProvider?.get('') ?? {
- reader: new BrowserMessageReader(port),
- writer: new BrowserMessageWriter(port)
- };
- this.handleLanguageClientStart(resolve, reject);
- };
- startWorkerLS(this.port ? this.port : this.worker);
+ const workerDirectConfig = lccOptions as WorkerConfigOptionsDirect;
+ this.worker = workerDirectConfig.worker;
}
- });
- }
+ if (lccOptions.messagePort !== undefined) {
+ this.port = lccOptions.messagePort;
+ }
+ }
- private async handleLanguageClientStart(resolve: () => void, reject: (reason?: unknown) => void) {
- if (!this.connectionProvider) {
- this.connectionProvider = {
- get: () => {
- // even with the check "if (this.messageTransports)" the compiler requires the ! here
- return Promise.resolve(this.messageTransports!);
- }
+ const portOrWorker = this.port ? this.port : this.worker;
+ let messageTransports = this.languageClientConfig.connection.messageTransports;
+ if (messageTransports === undefined) {
+ messageTransports = {
+ reader: new BrowserMessageReader(portOrWorker),
+ writer: new BrowserMessageWriter(portOrWorker)
};
}
+ await this.performLanguageClientStart(messageTransports, resolve, reject);
+ }
+
+ protected async performLanguageClientStart(messageTransports: MessageTransports, resolve: () => void, reject: (reason?: unknown) => void) {
+ // do not perform another start attempt if already running
+ if (this.languageClient?.isRunning() ?? false) {
+ this.logger?.info('performLanguageClientStart: monaco-languageclient already running!');
+ resolve();
+ }
const mlcConfig = {
- name: this.languageClientConfig?.name ?? 'Monaco Wrapper Language Client',
+ name: this.languageClientConfig.name ?? 'Monaco Wrapper Language Client',
// allow to fully override the clientOptions
- clientOptions: this.languageClientConfig?.clientOptions ?? {
+ clientOptions: this.languageClientConfig.clientOptions ?? {
documentSelector: [this.languageId],
// disable the default error handler
errorHandler: {
@@ -201,18 +188,19 @@ export class LanguageClientWrapper {
closed: () => ({ action: CloseAction.DoNotRestart })
}
},
-
- connectionProvider: this.connectionProvider!
+ messageTransports
};
+
this.languageClient = new MonacoLanguageClient(mlcConfig);
- const lcConfig = this.languageClientConfig?.options;
+ const conOptions = this.languageClientConfig.connection.options;
+ this.initRestartConfiguration(messageTransports, this.languageClientConfig.restartOptions);
- this.messageTransports?.reader.onClose(async () => {
+ messageTransports.reader.onClose(async () => {
await this.languageClient?.stop();
- if ((lcConfig?.$type === 'WebSocket' || lcConfig?.$type === 'WebSocketUrl') && lcConfig.stopOptions) {
- const stopOptions = lcConfig.stopOptions;
+ if ((conOptions.$type === 'WebSocketParams' || conOptions.$type === 'WebSocketUrl') && conOptions.stopOptions !== undefined) {
+ const stopOptions = conOptions.stopOptions;
stopOptions.onCall(this.getLanguageClient());
if (stopOptions.reportStatus !== undefined) {
this.logger?.info(this.reportStatus().join('\n'));
@@ -223,8 +211,8 @@ export class LanguageClientWrapper {
try {
await this.languageClient.start();
- if ((lcConfig?.$type === 'WebSocket' || lcConfig?.$type === 'WebSocketUrl') && lcConfig.startOptions) {
- const startOptions = lcConfig.startOptions;
+ if ((conOptions.$type === 'WebSocketParams' || conOptions.$type === 'WebSocketUrl') && conOptions.startOptions !== undefined) {
+ const startOptions = conOptions.startOptions;
startOptions.onCall(this.getLanguageClient());
if (startOptions.reportStatus !== undefined) {
this.logger?.info(this.reportStatus().join('\n'));
@@ -241,14 +229,43 @@ export class LanguageClientWrapper {
resolve();
}
- private disposeWorker(keepWorker?: boolean) {
+ protected initRestartConfiguration(messageTransports: MessageTransports, restartOptions?: LanguageClientRestartOptions) {
+ if (restartOptions !== undefined) {
+ let retry = 0;
+
+ const readerOnError = messageTransports.reader.onError(() => restartLC);
+ const readerOnClose = messageTransports.reader.onClose(() => restartLC);
+
+ const restartLC = async () => {
+ if (this.isStarted()) {
+ try {
+ readerOnError.dispose();
+ readerOnClose.dispose();
+
+ await this.restartLanguageClient(this.worker, restartOptions.keepWorker);
+ } finally {
+ retry++;
+ if (retry > (restartOptions.retries) && !this.isStarted()) {
+ this.logger?.info('Disabling Language Client. Failed to start clangd after 5 retries');
+ } else {
+ setTimeout(async () => {
+ await this.restartLanguageClient(this.worker, restartOptions.keepWorker);
+ }, restartOptions.timeout);
+ }
+ }
+ }
+ };
+ }
+ }
+
+ protected disposeWorker(keepWorker?: boolean) {
if (keepWorker === undefined || keepWorker === false) {
this.worker?.terminate();
this.worker = undefined;
}
}
- public async disposeLanguageClient(keepWorker?: boolean): Promise {
+ async disposeLanguageClient(keepWorker?: boolean): Promise {
// If there is no language client, try to terminate the worker
if (!this.languageClient) {
this.disposeWorker(keepWorker);
diff --git a/packages/wrapper/src/userConfig.ts b/packages/wrapper/src/userConfig.ts
deleted file mode 100644
index 463e5b74c..000000000
--- a/packages/wrapper/src/userConfig.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/* --------------------------------------------------------------------------------------------
- * Copyright (c) 2024 TypeFox and others.
- * Licensed under the MIT License. See LICENSE in the package root for license information.
- * ------------------------------------------------------------------------------------------ */
-
-import { InitializeServiceConfig } from 'monaco-languageclient/vscode/services';
-import type { LoggerConfig } from 'monaco-languageclient/tools';
-import { EditorAppConfigExtended } from './editorAppExtended.js';
-import { EditorAppConfigClassic } from './editorAppClassic.js';
-import { LanguageClientConfig } from './languageClientWrapper.js';
-
-export type WrapperConfig = {
- serviceConfig?: InitializeServiceConfig;
- editorAppConfig: EditorAppConfigExtended | EditorAppConfigClassic;
-};
-
-export type UserConfig = {
- id?: string;
- loggerConfig?: LoggerConfig;
- wrapperConfig: WrapperConfig;
- languageClientConfig?: LanguageClientConfig;
-}
diff --git a/packages/wrapper/src/utils.ts b/packages/wrapper/src/utils.ts
index 04782788f..56ff50dbf 100644
--- a/packages/wrapper/src/utils.ts
+++ b/packages/wrapper/src/utils.ts
@@ -4,22 +4,22 @@
* ------------------------------------------------------------------------------------------ */
import * as vscode from 'vscode';
-import { WebSocketConfigOptions, WebSocketConfigOptionsUrl, WorkerConfigDirect, WorkerConfigOptions } from './commonTypes.js';
+import { WebSocketUrlParams, WebSocketUrlString } from 'monaco-languageclient';
import { CodePlusFileExt, CodePlusUri, CodeResources } from './editorAppBase.js';
import { EditorAppClassic } from './editorAppClassic.js';
-import { UserConfig } from './userConfig.js';
import { EditorAppExtended } from './editorAppExtended.js';
+import { EditorAppConfigBase } from './editorAppBase.js';
-export const createUrl = (config: WebSocketConfigOptions | WebSocketConfigOptionsUrl) => {
+export const createUrl = (config: WebSocketUrlParams | WebSocketUrlString) => {
let buildUrl = '';
- if ((config as WebSocketConfigOptionsUrl).url) {
- const options = config as WebSocketConfigOptionsUrl;
+ if ((config as WebSocketUrlString).url) {
+ const options = config as WebSocketUrlString;
if (!options.url.startsWith('ws://') && !options.url.startsWith('wss://')) {
throw new Error(`This is not a proper websocket url: ${options.url}`);
}
buildUrl = options.url;
} else {
- const options = config as WebSocketConfigOptions;
+ const options = config as WebSocketUrlParams;
const protocol = options.secured ? 'wss' : 'ws';
buildUrl = `${protocol}://${options.host}`;
if (options.port !== undefined) {
@@ -115,34 +115,15 @@ export const isEqual = (obj1: unknown, obj2: unknown) => {
* @param previousUserConfig
* @returns
*/
-export const isReInitRequired = (editorApp: EditorAppClassic | EditorAppExtended, userConfig: UserConfig, previousUserConfig: UserConfig): boolean => {
+export const isReInitRequired = (editorApp: EditorAppClassic | EditorAppExtended, config: EditorAppConfigBase, previousConfig: EditorAppConfigBase): boolean => {
let mustReInit = false;
- const config = userConfig.wrapperConfig.editorAppConfig;
- const prevConfig = previousUserConfig.wrapperConfig.editorAppConfig;
- const prevWorkerOptions = previousUserConfig.languageClientConfig?.options;
- const currentWorkerOptions = userConfig.languageClientConfig?.options;
- const prevIsWorker = (prevWorkerOptions?.$type === 'WorkerDirect');
- const currentIsWorker = (currentWorkerOptions?.$type === 'WorkerDirect');
- const prevIsWorkerConfig = (prevWorkerOptions?.$type === 'WorkerConfig');
- const currentIsWorkerConfig = (currentWorkerOptions?.$type === 'WorkerConfig');
-
- // check if both are configs and the workers are both undefined
- if (prevIsWorkerConfig && !prevIsWorker && currentIsWorkerConfig && !currentIsWorker) {
- mustReInit = (prevWorkerOptions as WorkerConfigOptions).url !== (currentWorkerOptions as WorkerConfigOptions).url;
- // check if both are workers and configs are both undefined
- } else if (!prevIsWorkerConfig && prevIsWorker && !currentIsWorkerConfig && currentIsWorker) {
- mustReInit = (prevWorkerOptions as WorkerConfigDirect).worker !== (currentWorkerOptions as WorkerConfigDirect).worker;
- // previous was worker and current config is not or the other way around
- } else if (prevIsWorker && currentIsWorkerConfig || prevIsWorkerConfig && currentIsWorker) {
- mustReInit = true;
- }
- if (prevConfig.$type !== config.$type) {
+ if (previousConfig.$type !== config.$type) {
mustReInit = true;
- } else if (prevConfig.$type === 'classic' && config.$type === 'classic') {
- mustReInit = (editorApp as EditorAppClassic).isAppConfigDifferent(prevConfig, config, false) === true;
- } else if (prevConfig.$type === 'extended' && config.$type === 'extended') {
- mustReInit = (editorApp as EditorAppExtended).isAppConfigDifferent(prevConfig, config, false) === true;
+ } else if (previousConfig.$type === 'classic' && config.$type === 'classic') {
+ mustReInit = (editorApp as EditorAppClassic).isAppConfigDifferent(previousConfig, config, false) === true;
+ } else if (previousConfig.$type === 'extended' && config.$type === 'extended') {
+ mustReInit = (editorApp as EditorAppExtended).isAppConfigDifferent(previousConfig, config, false) === true;
}
return mustReInit;
diff --git a/packages/wrapper/src/vscode/services.ts b/packages/wrapper/src/vscode/services.ts
index 283957481..955929920 100644
--- a/packages/wrapper/src/vscode/services.ts
+++ b/packages/wrapper/src/vscode/services.ts
@@ -10,11 +10,11 @@ import { OpenEditor } from '@codingame/monaco-vscode-editor-service-override';
import { mergeServices, InitializeServiceConfig } from 'monaco-languageclient/vscode/services';
import { Logger } from 'monaco-languageclient/tools';
-export type VscodeServicesConfig = {
+export interface VscodeServicesConfig {
serviceConfig?: InitializeServiceConfig;
specificServices?: monaco.editor.IEditorOverrideServices;
logger?: Logger;
-};
+}
/**
* Child classes are allow to override the services configuration implementation.
diff --git a/packages/wrapper/src/workerFactory.ts b/packages/wrapper/src/workerFactory.ts
index e4db1c1a0..a8fabd080 100644
--- a/packages/wrapper/src/workerFactory.ts
+++ b/packages/wrapper/src/workerFactory.ts
@@ -3,9 +3,10 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
+import { Logger } from 'monaco-languageclient/tools';
import { initEnhancedMonacoEnvironment } from 'monaco-languageclient/vscode/services';
-export type WorkerOverrides = {
+export interface WorkerOverrides {
rootPath?: string | URL;
basePath?: string | URL;
workerLoaders?: Partial>;
@@ -13,7 +14,7 @@ export type WorkerOverrides = {
userDefinedMapping?: (label: string) => string;
}
-export type WorkerConfig = {
+export interface WorkerConfig {
rootPath: string | URL;
basePath?: string | URL;
workerFile: string | URL;
@@ -60,7 +61,7 @@ export const defaultWorkerLoaders: Partial {
+export const buildWorker = (config: WorkerConfig, workerOverrides?: WorkerOverrides, logger?: Logger): Worker => {
if (workerOverrides?.rootPath !== undefined) {
config.rootPath = workerOverrides.rootPath;
}
@@ -72,7 +73,7 @@ export const buildWorker = (config: WorkerConfig, workerOverrides?: WorkerOverri
workerFile = `${config.basePath}/${config.workerFile}`;
}
const fullUrl = new URL(workerFile, config.rootPath).href;
- console.log(`Creating worker: ${fullUrl}`);
+ logger?.info(`Creating worker: ${fullUrl}`);
// default to 'module' if not specified
const workerOptions = config.options ?? {};
@@ -85,11 +86,11 @@ export const buildWorker = (config: WorkerConfig, workerOverrides?: WorkerOverri
return new Worker(URL.createObjectURL(blob), workerOptions);
};
-export const useWorkerFactory = (workerOverrides?: WorkerOverrides) => {
+export const useWorkerFactory = (workerOverrides?: WorkerOverrides, logger?: Logger) => {
const envEnhanced = initEnhancedMonacoEnvironment();
const getWorker = (moduleId: string, label: string) => {
- console.log(`getWorker: moduleId: ${moduleId} label: ${label}`);
+ logger?.info(`getWorker: moduleId: ${moduleId} label: ${label}`);
let selector = label;
let workerLoaders;
@@ -116,7 +117,7 @@ export const useWorkerFactory = (workerOverrides?: WorkerOverrides) => {
if (workerOrConfig) {
const invoked = workerOrConfig();
if (Object.hasOwn(invoked, 'workerFile')) {
- return buildWorker(invoked as WorkerConfig, workerOverrides);
+ return buildWorker(invoked as WorkerConfig, workerOverrides, logger);
} else {
return invoked as Worker;
}
diff --git a/packages/wrapper/src/wrapper.ts b/packages/wrapper/src/wrapper.ts
index d9630bb75..5adb2115e 100644
--- a/packages/wrapper/src/wrapper.ts
+++ b/packages/wrapper/src/wrapper.ts
@@ -5,14 +5,21 @@
import * as monaco from 'monaco-editor';
import { MonacoLanguageClient } from 'monaco-languageclient';
-import { initServices } from 'monaco-languageclient/vscode/services';
-import { Logger } from 'monaco-languageclient/tools';
+import { InitializeServiceConfig, initServices } from 'monaco-languageclient/vscode/services';
+import { Logger, LoggerConfig } from 'monaco-languageclient/tools';
import { checkServiceConsistency, configureServices } from './vscode/services.js';
-import { EditorAppExtended } from './editorAppExtended.js';
-import { EditorAppClassic } from './editorAppClassic.js';
+import { EditorAppConfigExtended, EditorAppExtended } from './editorAppExtended.js';
+import { EditorAppClassic, EditorAppConfigClassic } from './editorAppClassic.js';
import { CodeResources, ModelRefs, TextContents, TextModels } from './editorAppBase.js';
-import { LanguageClientWrapper } from './languageClientWrapper.js';
-import { UserConfig } from './userConfig.js';
+import { LanguageClientConfig, LanguageClientWrapper } from './languageClientWrapper.js';
+
+export interface WrapperConfig {
+ id?: string;
+ loggerConfig?: LoggerConfig;
+ serviceConfig?: InitializeServiceConfig;
+ editorAppConfig: EditorAppConfigExtended | EditorAppConfigClassic;
+ languageClientConfigs?: Record;
+}
/**
* This class is responsible for the overall ochestration.
@@ -23,7 +30,7 @@ export class MonacoEditorLanguageClientWrapper {
private id: string;
private editorApp: EditorAppClassic | EditorAppExtended | undefined;
- private languageClientWrapper?: LanguageClientWrapper;
+ private languageClientWrappers: Map = new Map();
private logger: Logger = new Logger();
private initDone = false;
private starting?: Promise;
@@ -34,32 +41,32 @@ export class MonacoEditorLanguageClientWrapper {
/**
* Perform an isolated initialization of the user services and the languageclient wrapper (if used).
*/
- async init(userConfig: UserConfig) {
+ async init(wrapperConfig: WrapperConfig) {
this.markStarting();
if (this.initDone) {
throw new Error('init was already performed. Please call dispose first if you want to re-start.');
}
- const editorAppConfig = userConfig.wrapperConfig.editorAppConfig;
+ const editorAppConfig = wrapperConfig.editorAppConfig;
if ((editorAppConfig.useDiffEditor ?? false) && !editorAppConfig.codeResources?.original) {
throw new Error(`Use diff editor was used without a valid config. code: ${editorAppConfig.codeResources?.main} codeOriginal: ${editorAppConfig.codeResources?.original}`);
}
// Always dispose old instances before start
this.dispose(false);
- this.id = userConfig.id ?? Math.floor(Math.random() * 101).toString();
- this.logger.updateConfig(userConfig.loggerConfig);
+ this.id = wrapperConfig.id ?? Math.floor(Math.random() * 101).toString();
+ this.logger.updateConfig(wrapperConfig.loggerConfig);
if (editorAppConfig.$type === 'classic') {
- this.editorApp = new EditorAppClassic(this.id, userConfig, this.logger);
+ this.editorApp = new EditorAppClassic(this.id, wrapperConfig.editorAppConfig as EditorAppConfigClassic, this.logger);
} else {
- this.editorApp = new EditorAppExtended(this.id, userConfig, this.logger);
+ this.editorApp = new EditorAppExtended(this.id, wrapperConfig.editorAppConfig as EditorAppConfigExtended, this.logger);
}
// editorApps init their own service thats why they have to be created first
const specificServices = await this.editorApp.specifyServices();
const serviceConfig = await configureServices({
- serviceConfig: userConfig.wrapperConfig.serviceConfig,
+ serviceConfig: wrapperConfig.serviceConfig,
specificServices,
logger: this.logger
});
@@ -70,12 +77,15 @@ export class MonacoEditorLanguageClientWrapper {
logger: this.logger
});
- if (userConfig.languageClientConfig) {
- this.languageClientWrapper = new LanguageClientWrapper();
- await this.languageClientWrapper.init({
- languageClientConfig: userConfig.languageClientConfig,
- logger: this.logger
- });
+ const lccEntries = Object.entries(wrapperConfig.languageClientConfigs ?? {});
+ if (lccEntries.length > 0) {
+ for (const [languageId, lcc] of lccEntries) {
+ const lcw = new LanguageClientWrapper({
+ languageClientConfig: lcc,
+ logger: this.logger
+ });
+ this.languageClientWrappers.set(languageId, lcw);
+ }
}
this.initDone = true;
@@ -84,8 +94,8 @@ export class MonacoEditorLanguageClientWrapper {
/**
* Performs a full user configuration and the languageclient wrapper (if used) init and then start the application.
*/
- async initAndStart(userConfig: UserConfig, htmlElement: HTMLElement | null) {
- await this.init(userConfig);
+ async initAndStart(wrapperConfig: WrapperConfig, htmlElement: HTMLElement | null) {
+ await this.init(wrapperConfig);
await this.start(htmlElement);
}
@@ -104,9 +114,10 @@ export class MonacoEditorLanguageClientWrapper {
await this.editorApp?.init();
await this.editorApp?.createEditors(htmlElement);
- if (this.languageClientWrapper?.haveLanguageClientConfig() ?? false) {
- await this.languageClientWrapper?.start();
+ for (const lcw of this.languageClientWrappers.values()) {
+ await lcw.start();
}
+
this.markStarted();
}
@@ -135,14 +146,19 @@ export class MonacoEditorLanguageClientWrapper {
return false;
}
- if (this.languageClientWrapper?.haveLanguageClient() ?? false) {
- return this.languageClientWrapper?.isStarted() ?? false;
+ for (const lcw of this.languageClientWrappers.values()) {
+ if (lcw.haveLanguageClient()) {
+ // as soon as one is not started return
+ if (!lcw.isStarted()) {
+ return false;
+ }
+ }
}
return true;
}
- haveLanguageClient(): boolean {
- return this.languageClientWrapper !== undefined;
+ haveLanguageClients(): boolean {
+ return this.languageClientWrappers.size > 0;
}
getMonacoEditorApp() {
@@ -157,12 +173,12 @@ export class MonacoEditorLanguageClientWrapper {
return this.editorApp?.getDiffEditor();
}
- getLanguageClientWrapper(): LanguageClientWrapper | undefined {
- return this.languageClientWrapper;
+ getLanguageClientWrapper(languageId: string): LanguageClientWrapper | undefined {
+ return this.languageClientWrappers.get(languageId);
}
- getLanguageClient(): MonacoLanguageClient | undefined {
- return this.languageClientWrapper?.getLanguageClient();
+ getLanguageClient(languageId: string): MonacoLanguageClient | undefined {
+ return this.languageClientWrappers.get(languageId)?.getLanguageClient();
}
getTextContents(): TextContents | undefined {
@@ -177,8 +193,8 @@ export class MonacoEditorLanguageClientWrapper {
return this.editorApp?.getModelRefs();
}
- getWorker(): Worker | undefined {
- return this.languageClientWrapper?.getWorker();
+ getWorker(languageId: string): Worker | undefined {
+ return this.languageClientWrappers.get(languageId)?.getWorker();
}
async updateCodeResources(codeResources?: CodeResources): Promise {
@@ -200,21 +216,23 @@ export class MonacoEditorLanguageClientWrapper {
/**
* Disposes all application and editor resources, plus the languageclient (if used).
*/
- async dispose(disposeLanguageClient: boolean = true): Promise {
+ async dispose(disposeLanguageClients: boolean = true) {
this.markStopping();
this.editorApp?.disposeApp();
-
- if ((disposeLanguageClient && this.languageClientWrapper?.haveLanguageClient()) ?? false) {
- await this.languageClientWrapper?.disposeLanguageClient(false);
- this.editorApp = undefined;
- await Promise.resolve('Monaco editor and languageclient completed disposed.');
+ this.editorApp = undefined;
+
+ if (disposeLanguageClients) {
+ const allPromises: Array> = [];
+ for (const lcw of this.languageClientWrappers.values()) {
+ if (lcw.haveLanguageClient()) {
+ allPromises.push(lcw.disposeLanguageClient(false));
+ }
+ }
+ await Promise.all(allPromises);
}
- else {
- await Promise.resolve('Monaco editor has been disposed.');
- }
- this.initDone = false;
+ this.initDone = false;
this.markStopped();
}
diff --git a/packages/wrapper/test/editorAppBase.test.ts b/packages/wrapper/test/editorAppBase.test.ts
index 1b60d5ea5..d58bb9944 100644
--- a/packages/wrapper/test/editorAppBase.test.ts
+++ b/packages/wrapper/test/editorAppBase.test.ts
@@ -5,17 +5,17 @@
import { describe, expect, test } from 'vitest';
import { isCodeUpdateRequired, isModelUpdateRequired, ModelUpdateType } from 'monaco-editor-wrapper';
-import { createEditorAppConfig, createWrapperConfig } from './helper.js';
+import { createEditorAppConfig, createBaseConfig } from './helper.js';
describe('Test EditorAppBase', () => {
test('classic type: empty EditorAppConfigClassic', () => {
- const wrapperConfig = createWrapperConfig('classic');
+ const wrapperConfig = createBaseConfig('classic');
expect(wrapperConfig.editorAppConfig.$type).toBe('classic');
});
test('extended type: empty EditorAppConfigExtended', () => {
- const wrapperConfig = createWrapperConfig('extended');
+ const wrapperConfig = createBaseConfig('extended');
expect(wrapperConfig.editorAppConfig.$type).toBe('extended');
});
diff --git a/packages/wrapper/test/editorAppClassic.test.ts b/packages/wrapper/test/editorAppClassic.test.ts
index 7c4f7b740..4e7c6f4ad 100644
--- a/packages/wrapper/test/editorAppClassic.test.ts
+++ b/packages/wrapper/test/editorAppClassic.test.ts
@@ -4,49 +4,49 @@
* ------------------------------------------------------------------------------------------ */
import { describe, expect, test } from 'vitest';
-import { EditorAppClassic, EditorAppConfigClassic } from 'monaco-editor-wrapper';
+import { EditorAppClassic, EditorAppConfigClassic, WrapperConfig } from 'monaco-editor-wrapper';
import { createBaseConfig, createEditorAppConfig } from './helper.js';
-const buildConfig = () => {
- const config = createBaseConfig('classic');
- (config.wrapperConfig.editorAppConfig as EditorAppConfigClassic).editorOptions = {};
- return config;
+const buildConfig = (): WrapperConfig => {
+ const wrapperConfig = createBaseConfig('classic');
+ (wrapperConfig.editorAppConfig as EditorAppConfigClassic).editorOptions = {};
+ return wrapperConfig;
};
describe('Test EditorAppClassic', () => {
test('editorOptions: semanticHighlighting=true', () => {
- const config = buildConfig();
- const configclassic = config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- configclassic.editorOptions!['semanticHighlighting.enabled'] = true;
+ const wrapperConfig = buildConfig();
+ const configClassic = wrapperConfig.editorAppConfig as EditorAppConfigClassic;
+ configClassic.editorOptions!['semanticHighlighting.enabled'] = true;
- const app = new EditorAppClassic('config defaults', config);
- expect(configclassic.$type).toEqual('classic');
+ const app = new EditorAppClassic('config defaults', configClassic);
+ expect(configClassic.$type).toEqual('classic');
expect(app.getConfig().editorOptions?.['semanticHighlighting.enabled']).toBeTruthy();
});
test('editorOptions: semanticHighlighting=false', () => {
- const config = buildConfig();
- const configclassic = config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- configclassic.editorOptions!['semanticHighlighting.enabled'] = false;
+ const wrapperConfig = buildConfig();
+ const configClassic = wrapperConfig.editorAppConfig as EditorAppConfigClassic;
+ configClassic.editorOptions!['semanticHighlighting.enabled'] = false;
- const app = new EditorAppClassic('config defaults', config);
+ const app = new EditorAppClassic('config defaults', configClassic);
expect(app.getConfig().editorOptions?.['semanticHighlighting.enabled']).toBeFalsy();
});
test('editorOptions: semanticHighlighting="configuredByTheme"', () => {
- const config = buildConfig();
- const configclassic = config.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
- configclassic.editorOptions!['semanticHighlighting.enabled'] = 'configuredByTheme';
+ const wrapperConfig = buildConfig();
+ const configClassic = wrapperConfig.editorAppConfig as EditorAppConfigClassic;
+ configClassic.editorOptions!['semanticHighlighting.enabled'] = 'configuredByTheme';
- const app = new EditorAppClassic('config defaults', config);
+ const app = new EditorAppClassic('config defaults', configClassic);
expect(app.getConfig().editorOptions?.['semanticHighlighting.enabled']).toEqual('configuredByTheme');
});
test('isAppConfigDifferent: basic', () => {
const orgConfig = createEditorAppConfig('classic') as EditorAppConfigClassic;
const config = createEditorAppConfig('classic') as EditorAppConfigClassic;
- const app = new EditorAppClassic('test', createBaseConfig('classic'));
+ const app = new EditorAppClassic('test', config);
expect(app.isAppConfigDifferent(orgConfig, config, false)).toBeFalsy();
config.codeResources ??= {};
@@ -66,20 +66,20 @@ describe('Test EditorAppClassic', () => {
});
test('isAppConfigDifferent: non-simple properties"', () => {
- const config1 = buildConfig();
- const config2 = buildConfig();
- const configclassic1 = config1.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
+ const wrapperConfig1 = buildConfig();
+ const wrapperConfig2 = buildConfig();
+ const configclassic1 = wrapperConfig1.editorAppConfig as EditorAppConfigClassic;
configclassic1.editorOptions!['semanticHighlighting.enabled'] = true;
- const configclassic2 = config2.wrapperConfig.editorAppConfig as EditorAppConfigClassic;
+ const configclassic2 = wrapperConfig2.editorAppConfig as EditorAppConfigClassic;
configclassic2.editorOptions!['semanticHighlighting.enabled'] = true;
- const app = new EditorAppClassic('config defaults', config1);
+ const app = new EditorAppClassic('config defaults', configclassic1);
expect(app.isAppConfigDifferent(configclassic1, configclassic2, false)).toBeFalsy();
});
test('config defaults', () => {
- const config = createBaseConfig('classic');
- const app = new EditorAppClassic('config defaults', config);
+ const editorAppConfig = createEditorAppConfig('classic') as EditorAppConfigClassic;
+ const app = new EditorAppClassic('config defaults', editorAppConfig);
expect(app.getConfig().codeResources?.main?.text).toEqual('');
expect(app.getConfig().codeResources?.original).toBeUndefined();
expect(app.getConfig().useDiffEditor ?? false).toBeFalsy();
diff --git a/packages/wrapper/test/editorAppExtended.test.ts b/packages/wrapper/test/editorAppExtended.test.ts
index d959280e8..55280da8f 100644
--- a/packages/wrapper/test/editorAppExtended.test.ts
+++ b/packages/wrapper/test/editorAppExtended.test.ts
@@ -21,19 +21,19 @@ describe('Test EditorAppExtended', () => {
});
test('config userConfiguration', () => {
- const config = createBaseConfig('extended');
- const appConfig = config.wrapperConfig.editorAppConfig as EditorAppConfigExtended;
+ const wrapperConfig = createBaseConfig('extended');
+ const appConfig = wrapperConfig.editorAppConfig as EditorAppConfigExtended;
appConfig.userConfiguration = {
json: '{ "editor.semanticHighlighting.enabled": true }'
};
- const app = new EditorAppExtended('config defaults', config);
+ const app = new EditorAppExtended('config defaults', appConfig);
expect(app.getConfig().userConfiguration?.json).toEqual('{ "editor.semanticHighlighting.enabled": true }');
});
test('isAppConfigDifferent: basic', () => {
const orgConfig = createEditorAppConfig('extended') as EditorAppConfigExtended;
const config = createEditorAppConfig('extended') as EditorAppConfigExtended;
- const app = new EditorAppExtended('test', createBaseConfig('extended'));
+ const app = new EditorAppExtended('test', config);
expect(app.isAppConfigDifferent(orgConfig, config, false)).toBeFalsy();
config.codeResources ??= {};
@@ -61,8 +61,8 @@ describe('Test EditorAppExtended', () => {
});
test('config defaults', () => {
- const config = createBaseConfig('extended');
- const app = new EditorAppExtended('config defaults', config);
+ const editorAppConfig = createEditorAppConfig('extended') as EditorAppConfigExtended;
+ const app = new EditorAppExtended('config defaults', editorAppConfig);
expect(app.getConfig().codeResources?.main?.text).toEqual('');
expect(app.getConfig().codeResources?.original).toBeUndefined();
expect(app.getConfig().useDiffEditor ?? false).toBeFalsy();
diff --git a/packages/wrapper/test/helper.ts b/packages/wrapper/test/helper.ts
index 098dcb01d..6897d5b9e 100644
--- a/packages/wrapper/test/helper.ts
+++ b/packages/wrapper/test/helper.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */
-import { UserConfig, EditorAppType } from 'monaco-editor-wrapper';
+import { EditorAppType, WrapperConfig } from 'monaco-editor-wrapper';
export const createMonacoEditorDiv = () => {
const div = document.createElement('div');
@@ -11,13 +11,7 @@ export const createMonacoEditorDiv = () => {
document.body.insertAdjacentElement('beforeend', div);
};
-export const createBaseConfig = (type: EditorAppType): UserConfig => {
- return {
- wrapperConfig: createWrapperConfig(type)
- };
-};
-
-export const createWrapperConfig = (type: EditorAppType) => {
+export const createBaseConfig = (type: EditorAppType): WrapperConfig => {
return {
editorAppConfig: createEditorAppConfig(type)
};
@@ -35,12 +29,3 @@ export const createEditorAppConfig = (type: EditorAppType) => {
useDiffEditor: false,
};
};
-
-/**
- * Helper to generate a quick worker from a function blob
- */
-export const createWorkerFromFunction = (fn: () => void): Worker => {
- return new Worker(URL.createObjectURL(
- new Blob([`(${fn.toString()})()`], { type: 'application/javascript' })
- ));
-};
diff --git a/packages/wrapper/test/languageClientWrapper.test.ts b/packages/wrapper/test/languageClientWrapper.test.ts
index e73e00987..d458a38c3 100644
--- a/packages/wrapper/test/languageClientWrapper.test.ts
+++ b/packages/wrapper/test/languageClientWrapper.test.ts
@@ -5,7 +5,7 @@
import { describe, expect, test } from 'vitest';
import { LanguageClientConfig, LanguageClientWrapper, MonacoEditorLanguageClientWrapper } from 'monaco-editor-wrapper';
-import { createBaseConfig, createWorkerFromFunction } from './helper.js';
+import { createBaseConfig } from './helper.js';
describe('Test LanguageClientWrapper', () => {
@@ -13,98 +13,113 @@ describe('Test LanguageClientWrapper', () => {
const wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.init(createBaseConfig('extended'));
- const languageClientWrapper = wrapper.getLanguageClientWrapper();
+ const languageClientWrapper = wrapper.getLanguageClientWrapper('unknown');
expect(languageClientWrapper).toBeUndefined();
});
test('Constructor: no config', async () => {
// create a web worker to pass to the wrapper
- const worker = createWorkerFromFunction(() => {
- console.info('Hello');
+ const worker = new Worker('./worker/langium-server.ts', {
+ type: 'module',
+ name: 'Langium LS',
});
const languageClientConfig: LanguageClientConfig = {
languageId: 'javascript',
- options: {
- $type: 'WorkerDirect',
- worker
+ connection: {
+ options: {
+ $type: 'WorkerDirect',
+ worker
+ }
}
};
- const languageClientWrapper = new LanguageClientWrapper();
- languageClientWrapper.init({
+ const languageClientWrapper = new LanguageClientWrapper({
languageClientConfig
});
expect(languageClientWrapper).toBeDefined();
expect(languageClientWrapper.haveLanguageClient).toBeTruthy();
- expect(languageClientWrapper.haveLanguageClientConfig).toBeTruthy();
});
test('Dispose: direct worker is cleaned up afterwards', async () => {
// create a web worker to pass to the wrapper
- const worker = createWorkerFromFunction(() => {
- console.info('Hello');
+ const worker = new Worker('./worker/langium-server.ts', {
+ type: 'module',
+ name: 'Langium LS',
});
// setup the wrapper
const config = createBaseConfig('extended');
- config.languageClientConfig = {
- languageId: 'javascript',
- options: {
- $type: 'WorkerDirect',
- worker
+ config.languageClientConfigs = {
+ javascript: {
+ languageId: 'javascript',
+ connection: {
+ options: {
+ $type: 'WorkerDirect',
+ worker
+ }
+ }
}
};
const wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.init(config);
- const languageClientWrapper = wrapper.getLanguageClientWrapper();
+ const languageClientWrapper = wrapper.getLanguageClientWrapper('javascript');
expect(languageClientWrapper).toBeDefined();
- // start up & verify (don't wait for start to finish, just roll past it, we only care about the worker)
- languageClientWrapper!.start();
- expect(languageClientWrapper!.getWorker()).toBeTruthy();
+ expect(languageClientWrapper?.getWorker()).toBeFalsy();
+
+ // WA: for whatever reasons "await" kills the test,
+ // but the languageClientWrapper needs to be fully initialised as otherwise the follow up steps fail
+ languageClientWrapper?.start();
- // dispose & verify
- languageClientWrapper!.disposeLanguageClient();
- expect(languageClientWrapper!.getWorker()).toBeUndefined();
+ setTimeout(async () => {
+ // dispose & verify
+ await languageClientWrapper?.disposeLanguageClient();
+ expect(languageClientWrapper?.getWorker()).toBeUndefined();
+ }, 250);
+ expect(languageClientWrapper?.getWorker()).toBeTruthy();
});
test('Constructor: config', async () => {
const config = createBaseConfig('extended');
- config.languageClientConfig = {
- languageId: 'javascript',
- options: {
- $type: 'WebSocketUrl',
- url: 'ws://localhost:12345/Tester'
+ config.languageClientConfigs = {
+ javascript: {
+ languageId: 'javascript',
+ connection: {
+ options: {
+ $type: 'WebSocketUrl',
+ url: 'ws://localhost:12345/Tester'
+ }
+ }
}
};
const wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.init(config);
- const languageClientWrapper = wrapper.getLanguageClientWrapper();
+ const languageClientWrapper = wrapper.getLanguageClientWrapper('javascript');
expect(languageClientWrapper).toBeDefined();
-
- expect(languageClientWrapper!.haveLanguageClientConfig()).toBeTruthy();
});
test('Start: unreachable url', async () => {
const config = createBaseConfig('extended');
- config.languageClientConfig = {
- languageId: 'javascript',
- name: 'test-unreachable',
- options: {
- $type: 'WebSocketUrl',
- url: 'ws://localhost:12345/Tester'
+ config.languageClientConfigs = {
+ javascript: {
+ languageId: 'javascript',
+ name: 'test-unreachable',
+ connection: {
+ options: {
+ $type: 'WebSocketUrl',
+ url: 'ws://localhost:12345/Tester'
+ }
+ }
}
};
const wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.init(config);
- const languageClientWrapper = wrapper.getLanguageClientWrapper();
+ const languageClientWrapper = wrapper.getLanguageClientWrapper('javascript');
expect(languageClientWrapper).toBeDefined();
- expect(languageClientWrapper!.haveLanguageClientConfig()).toBeTruthy();
- console.log('start');
await expect(languageClientWrapper!.start()).rejects.toEqual({
message: 'languageClientWrapper (test-unreachable): Websocket connection failed.',
error: 'No error was provided.'
@@ -124,21 +139,24 @@ describe('Test LanguageClientWrapper', () => {
test('Start: unreachable worker url', async () => {
const config = createBaseConfig('extended');
- config.languageClientConfig = {
- languageId: 'javascript',
- options: {
- $type: 'WorkerConfig',
- url: new URL('http://localhost:20101'),
- type: 'classic'
+ config.languageClientConfigs = {
+ javascript: {
+ languageId: 'javascript',
+ connection: {
+ options: {
+ $type: 'WorkerConfig',
+ url: new URL('http://localhost:20101'),
+ type: 'classic'
+ }
+ }
}
};
const wrapper = new MonacoEditorLanguageClientWrapper();
await wrapper.init(config);
- const languageClientWrapper = wrapper.getLanguageClientWrapper();
+ const languageClientWrapper = wrapper.getLanguageClientWrapper('javascript');
expect(languageClientWrapper).toBeDefined();
- expect(languageClientWrapper!.haveLanguageClientConfig()).toBeTruthy();
await expect(languageClientWrapper!.start()).rejects.toEqual({
message: 'languageClientWrapper (unnamed): Illegal worker configuration detected. Potentially the url is wrong.',
error: 'No error was provided.'
diff --git a/packages/wrapper/test/utils.test.ts b/packages/wrapper/test/utils.test.ts
index 7ab0e4536..5b07c0bd5 100644
--- a/packages/wrapper/test/utils.test.ts
+++ b/packages/wrapper/test/utils.test.ts
@@ -4,7 +4,8 @@
* ------------------------------------------------------------------------------------------ */
import { describe, expect, test } from 'vitest';
-import { WebSocketConfigOptions, WebSocketConfigOptionsUrl, createUrl } from 'monaco-editor-wrapper';
+import { WebSocketConfigOptionsParams, WebSocketConfigOptionsUrl } from 'monaco-languageclient';
+import { createUrl } from 'monaco-editor-wrapper';
describe('createUrl', () => {
@@ -14,7 +15,7 @@ describe('createUrl', () => {
host: 'localhost',
port: 30000,
path: 'sampleServer'
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('ws://localhost:30000/sampleServer');
});
@@ -25,7 +26,7 @@ describe('createUrl', () => {
host: 'localhost',
port: 30000,
path: 'sampleServer'
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('wss://localhost:30000/sampleServer');
});
@@ -35,7 +36,7 @@ describe('createUrl', () => {
secured: true,
host: 'localhost',
path: 'sampleServer'
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('wss://localhost/sampleServer');
});
@@ -45,7 +46,7 @@ describe('createUrl', () => {
secured: true,
host: 'localhost',
port: 30000
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('wss://localhost:30000');
});
@@ -54,7 +55,7 @@ describe('createUrl', () => {
const url = createUrl({
secured: true,
host: 'localhost'
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('wss://localhost');
});
@@ -64,7 +65,7 @@ describe('createUrl', () => {
secured: false,
host: 'localhost',
port: 80
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('ws://localhost');
});
@@ -75,7 +76,7 @@ describe('createUrl', () => {
host: 'localhost',
port: 80,
path: 'sampleServer'
- } as WebSocketConfigOptions);
+ } as WebSocketConfigOptionsParams);
expect(url).toBe('ws://localhost/sampleServer');
});
diff --git a/packages/wrapper/test/worker/langium-server.ts b/packages/wrapper/test/worker/langium-server.ts
new file mode 100644
index 000000000..be1c511f5
--- /dev/null
+++ b/packages/wrapper/test/worker/langium-server.ts
@@ -0,0 +1,24 @@
+/* --------------------------------------------------------------------------------------------
+ * Copyright (c) 2018-2022 TypeFox and others.
+ * Licensed under the MIT License. See LICENSE in the package root for license information.
+ * ------------------------------------------------------------------------------------------ */
+///
+
+import { EmptyFileSystem } from 'langium';
+import { DefaultSharedModuleContext, startLanguageServer } from 'langium/lsp';
+import { createLangiumGrammarServices } from 'langium/grammar';
+import { BrowserMessageReader, BrowserMessageWriter, createConnection } from 'vscode-languageserver/browser.js';
+
+/* browser specific setup code */
+const messageReader = new BrowserMessageReader(self as DedicatedWorkerGlobalScope);
+const messageWriter = new BrowserMessageWriter(self as DedicatedWorkerGlobalScope);
+
+// Inject the shared services and language-specific services
+const context = {
+ connection: createConnection(messageReader, messageWriter),
+ ...EmptyFileSystem
+} as unknown as DefaultSharedModuleContext;
+const { shared } = createLangiumGrammarServices(context);
+
+// Start the language server with the shared services
+startLanguageServer(shared);
diff --git a/packages/wrapper/test/wrapper.test.ts b/packages/wrapper/test/wrapper.test.ts
index 161080715..5ee1e9b52 100644
--- a/packages/wrapper/test/wrapper.test.ts
+++ b/packages/wrapper/test/wrapper.test.ts
@@ -13,7 +13,7 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test('New wrapper has undefined editor', () => {
const wrapper = new MonacoEditorLanguageClientWrapper();
- expect(wrapper.haveLanguageClient()).toBeFalsy();
+ expect(wrapper.haveLanguageClients()).toBeFalsy();
expect(wrapper.getEditor()).toBeUndefined();
});
@@ -63,20 +63,20 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test('Verify if configuration changes make re-init necessary', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfigClassic = createBaseConfig('classic');
- wrapper.init(userConfigClassic);
+ const wrapperConfigClassic = createBaseConfig('classic');
+ wrapper.init(wrapperConfigClassic);
const app = wrapper.getMonacoEditorApp();
expect(app).toBeDefined();
if (app) {
- expect(isReInitRequired(app, userConfigClassic, userConfigClassic)).toBeFalsy();
+ expect(isReInitRequired(app, wrapperConfigClassic.editorAppConfig, wrapperConfigClassic.editorAppConfig)).toBeFalsy();
- const userConfigExtended = createBaseConfig('extended');
- expect(isReInitRequired(app, userConfigClassic, userConfigExtended)).toBeTruthy();
+ const wrapperConfigExtended = createBaseConfig('extended');
+ expect(isReInitRequired(app, wrapperConfigClassic.editorAppConfig, wrapperConfigExtended.editorAppConfig)).toBeTruthy();
- const userConfigClassicNew = createBaseConfig('classic');
- userConfigClassicNew.wrapperConfig.editorAppConfig.useDiffEditor = true;
+ const wrapperConfigClassicNew = createBaseConfig('classic');
+ wrapperConfigClassicNew.editorAppConfig.useDiffEditor = true;
- expect(isReInitRequired(app, userConfigClassicNew, userConfigClassic)).toBeTruthy();
+ expect(isReInitRequired(app, wrapperConfigClassicNew.editorAppConfig, wrapperConfigClassic.editorAppConfig)).toBeTruthy();
}
});
@@ -96,8 +96,8 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test('code resources original', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfig = createBaseConfig('classic');
- let codeResources = userConfig.wrapperConfig.editorAppConfig.codeResources;
+ const wrapperConfig = createBaseConfig('classic');
+ let codeResources = wrapperConfig.editorAppConfig.codeResources;
if (!codeResources) {
codeResources = {};
}
@@ -106,7 +106,7 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
text: 'original',
fileExt: 'js'
};
- await wrapper.initAndStart(userConfig, document.getElementById('monaco-editor-root'));
+ await wrapper.initAndStart(wrapperConfig, document.getElementById('monaco-editor-root'));
const app = wrapper.getMonacoEditorApp();
const modelRefs = app?.getModelRefs();
@@ -118,8 +118,8 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test('code resources main and original', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfig = createBaseConfig('classic');
- let codeResources = userConfig.wrapperConfig.editorAppConfig.codeResources;
+ const wrapperConfig = createBaseConfig('classic');
+ let codeResources = wrapperConfig.editorAppConfig.codeResources;
if (!codeResources) {
codeResources = {};
}
@@ -127,7 +127,7 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
text: 'original',
fileExt: 'js'
};
- await wrapper.initAndStart(userConfig, document.getElementById('monaco-editor-root'));
+ await wrapper.initAndStart(wrapperConfig, document.getElementById('monaco-editor-root'));
const app = wrapper.getMonacoEditorApp();
const modelRefs = app?.getModelRefs();
@@ -146,9 +146,9 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test('code resources empty', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfig = createBaseConfig('classic');
- userConfig.wrapperConfig.editorAppConfig.codeResources = {};
- await wrapper.initAndStart(userConfig, document.getElementById('monaco-editor-root'));
+ const wrapperConfig = createBaseConfig('classic');
+ wrapperConfig.editorAppConfig.codeResources = {};
+ await wrapper.initAndStart(wrapperConfig, document.getElementById('monaco-editor-root'));
const app = wrapper.getMonacoEditorApp();
const modelRefs = app?.getModelRefs();
@@ -159,9 +159,9 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test('code resources model direct', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfig = createBaseConfig('classic');
- userConfig.wrapperConfig.editorAppConfig.codeResources = {};
- await wrapper.initAndStart(userConfig, document.getElementById('monaco-editor-root'));
+ const wrapperConfig = createBaseConfig('classic');
+ wrapperConfig.editorAppConfig.codeResources = {};
+ await wrapper.initAndStart(wrapperConfig, document.getElementById('monaco-editor-root'));
const app = wrapper.getMonacoEditorApp();
@@ -183,8 +183,8 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
test.skip('extended editor disposes extensions', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfig = createBaseConfig('extended');
- (userConfig.wrapperConfig.editorAppConfig as EditorAppConfigExtended).extensions = [{
+ const wrapperConfig = createBaseConfig('extended');
+ (wrapperConfig.editorAppConfig as EditorAppConfigExtended).extensions = [{
config: {
engines: {
vscode: '*'
@@ -207,18 +207,18 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
['/javascript.tmLanguage.json', '{}']
]),
}];
- await wrapper.initAndStart(userConfig, document.getElementById('monaco-editor-root'));
+ await wrapper.initAndStart(wrapperConfig, document.getElementById('monaco-editor-root'));
await wrapper.dispose();
- await wrapper.initAndStart(userConfig, document.getElementById('monaco-editor-root'));
+ await wrapper.initAndStart(wrapperConfig, document.getElementById('monaco-editor-root'));
});
test('Early code resources update on wrapper are ok', async () => {
createMonacoEditorDiv();
const wrapper = new MonacoEditorLanguageClientWrapper();
- const userConfig = createBaseConfig('classic');
- userConfig.wrapperConfig.editorAppConfig.codeResources = {};
+ const wrapperConfig = createBaseConfig('classic');
+ wrapperConfig.editorAppConfig.codeResources = {};
- await wrapper.init(userConfig);
+ await wrapper.init(wrapperConfig);
const app = wrapper.getMonacoEditorApp();
const promise = await wrapper.updateCodeResources({
main: {
diff --git a/packages/wrapper/tsconfig.build.json b/packages/wrapper/tsconfig.build.json
index e41c77a38..0cb7e416d 100644
--- a/packages/wrapper/tsconfig.build.json
+++ b/packages/wrapper/tsconfig.build.json
@@ -2,11 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./build",
- "noEmit": true,
- // all other types are not needed here
- "types": [
- "node"
- ]
+ "noEmit": true
},
"include": [
"build/**/*.ts",
diff --git a/packages/wrapper/tsconfig.src.json b/packages/wrapper/tsconfig.src.json
index 47c7bcf03..5f42eb538 100644
--- a/packages/wrapper/tsconfig.src.json
+++ b/packages/wrapper/tsconfig.src.json
@@ -7,10 +7,7 @@
// because vscode-jsonrpc requires DedicatedWorkerGlobalScope
// we are required to include both DOM and WebWorker libs
// the only way out currently is to disable lib checking
- "skipLibCheck": true,
- "types": [
- "vscode"
- ]
+ "skipLibCheck": true
},
"references": [{
"path": "../client/tsconfig.src.json",
diff --git a/packages/wrapper/tsconfig.test.json b/packages/wrapper/tsconfig.test.json
index 606d704d7..143bf44ec 100644
--- a/packages/wrapper/tsconfig.test.json
+++ b/packages/wrapper/tsconfig.test.json
@@ -2,7 +2,11 @@
"extends": "./tsconfig.src.json",
"compilerOptions": {
"noEmit": true,
- "rootDir": "test"
+ "rootDir": "test",
+ // because vscode-jsonrpc requires DedicatedWorkerGlobalScope
+ // we are required to include both DOM and WebWorker libs
+ // the only way out currently is to disable lib checking
+ "skipLibCheck": true
},
"references": [{
"path": "./tsconfig.src.json"
diff --git a/tsconfig.json b/tsconfig.json
index bc75e2d94..cc281bbe0 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,8 +1,8 @@
{
"compilerOptions": {
"target": "ESNext",
- "module": "ESNext",
- "moduleResolution": "Bundler",
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
"lib": [
"ESNext",
"DOM"
diff --git a/verify/angular/package.json b/verify/angular/package.json
index f1758a006..3a5e760fb 100644
--- a/verify/angular/package.json
+++ b/verify/angular/package.json
@@ -39,7 +39,7 @@
"style-loader": "~4.0.0"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
}
}
diff --git a/verify/pnpm/package.json b/verify/pnpm/package.json
index 49b452485..1c272e5f6 100644
--- a/verify/pnpm/package.json
+++ b/verify/pnpm/package.json
@@ -14,8 +14,8 @@
"vite": "~5.3.3"
},
"volta": {
- "node": "20.16.0",
- "pnpm": "9.7.0"
+ "node": "20.17.0",
+ "pnpm": "9.9.0"
},
"scripts": {
"verify": "pnpm install && pnpm run build && pnpm run start",
diff --git a/verify/vite/package.json b/verify/vite/package.json
index f0166e7fa..cea2b9cdb 100644
--- a/verify/vite/package.json
+++ b/verify/vite/package.json
@@ -14,8 +14,8 @@
"vite": "~5.3.3"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"scripts": {
"verify": "npm install && npm run build && npm run start",
diff --git a/verify/webpack/package.json b/verify/webpack/package.json
index 0dbd3d03f..b7178f549 100644
--- a/verify/webpack/package.json
+++ b/verify/webpack/package.json
@@ -19,8 +19,8 @@
"webpack-cli": "~5.1.4"
},
"volta": {
- "node": "20.16.0",
- "npm": "10.8.1"
+ "node": "20.17.0",
+ "npm": "10.8.3"
},
"scripts": {
"verify": "npm install && npm run build && npm run start",
diff --git a/verify/yarn/package.json b/verify/yarn/package.json
index f846e338c..474b9e998 100644
--- a/verify/yarn/package.json
+++ b/verify/yarn/package.json
@@ -4,10 +4,10 @@
"private": true,
"type": "module",
"dependencies": {
- "@typefox/monaco-editor-react": "~4.5.3",
+ "@typefox/monaco-editor-react": "~6.0.0-next.0",
"monaco-editor": "npm:@codingame/monaco-vscode-editor-api@~8.0.4",
- "monaco-editor-wrapper": "~5.5.3s",
- "monaco-languageclient-examples": "~2024.8.4",
+ "monaco-editor-wrapper": "~6.0.0-next.0",
+ "monaco-languageclient-examples": "~2024.9.1",
"vscode": "npm:@codingame/monaco-vscode-api@~8.0.4",
"vscode-ws-jsonrpc": "~3.3.2"
},
@@ -16,7 +16,7 @@
"vite": "~5.3.3"
},
"volta": {
- "node": "20.16.0",
+ "node": "20.17.0",
"yarn": "1.22.22"
},
"scripts": {
diff --git a/vite.config.ts b/vite.config.ts
index 1c6f59563..94ca38d64 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -32,6 +32,9 @@ const viteConfig = defineViteConfig({
// grrovy
groovy: path.resolve(__dirname, 'packages/examples/groovy.html'),
+ // json & python
+ twoLangaugeClients: path.resolve(__dirname, 'packages/examples/two_langauge_clients.html'),
+
// monaco-editor-react
// langium
reactStatemachine: path.resolve(__dirname, 'packages/examples/react_statemachine.html'),
@@ -39,8 +42,7 @@ const viteConfig = defineViteConfig({
reactPython: path.resolve(__dirname, 'packages/examples/react_python.html'),
// other examples
- wrapperTs: path.resolve(__dirname, 'packages/examples/wrapper_ts.html'),
- wrapperAdvanced: path.resolve(__dirname, 'packages/examples/wrapper_adv.html'),
+ wrapperTs: path.resolve(__dirname, 'packages/examples/wrapper_ts.html')
}
}
},