Skip to content

Commit 5470343

Browse files
authored
Ensure configuration is init before service init (#820)
* Implement review comments and add unit test * Update dependencies * Added comments to unit test
1 parent e6cb7dd commit 5470343

File tree

10 files changed

+277
-188
lines changed

10 files changed

+277
-188
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"request": "launch",
2929
"url": "http://localhost:20001",
3030
"webRoot": "${workspaceFolder}",
31-
"userDataDir": "${workspaceFolder/.chrome/profile"
31+
"userDataDir": "${workspaceFolder}/.chrome/profile"
3232
},
3333
{
3434
"name": "Chrome Preview",

package-lock.json

Lines changed: 189 additions & 161 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@
1818
"@eslint/js": "~9.17.0",
1919
"@stylistic/eslint-plugin": "~2.12.1",
2020
"@testing-library/react": "~16.1.0",
21-
"@types/node": "~22.10.2",
21+
"@types/node": "~22.10.5",
2222
"@types/react": "~18.3.14",
2323
"@types/react-dom": "~18.3.3",
2424
"@types/vscode": "~1.95.0",
25-
"@typescript-eslint/eslint-plugin": "~8.18.1",
26-
"@typescript-eslint/parser": "~8.18.1",
25+
"@typescript-eslint/eslint-plugin": "~8.19.1",
26+
"@typescript-eslint/parser": "~8.19.1",
2727
"@vitejs/plugin-react": "~4.3.4",
2828
"@vitest/browser": "~2.1.8",
2929
"editorconfig": "~2.0.0",
30-
"esbuild": "~0.24.0",
30+
"esbuild": "~0.24.2",
3131
"eslint": "~9.17.0",
3232
"eslint-plugin-header": "~3.1.1",
3333
"eslint-plugin-import": "~2.31.0",
@@ -37,7 +37,7 @@
3737
"minimatch": "~10.0.1",
3838
"playwright": "~1.49.1",
3939
"typescript": "~5.7.2",
40-
"vite": "~6.0.3",
40+
"vite": "~6.0.7",
4141
"vite-node": "~2.1.8",
4242
"vitest": "~2.1.8"
4343
},
@@ -79,6 +79,6 @@
7979
"packages/examples"
8080
],
8181
"overrides": {
82-
"vite": "~6.0.3"
82+
"vite": "~6.0.7"
8383
}
8484
}

packages/client/src/vscode/services.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { EnvironmentOverride } from 'vscode/workbench';
1717
import { Logger } from 'monaco-languageclient/tools';
1818
import { FakeWorker as Worker } from './fakeWorker.js';
1919
import { setUnexpectedErrorHandler } from 'vscode/monaco';
20-
import { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override';
20+
import { initUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override';
2121

2222
export interface MonacoEnvironmentEnhanced extends monaco.Environment {
2323
vscodeInitialising?: boolean;
@@ -94,25 +94,31 @@ export const mergeServices = (overrideServices: monaco.editor.IEditorOverrideSer
9494
}
9595
};
9696

97-
export const initServices = async (vscodeApiConfig: VscodeApiConfig, instructions: InitServicesInstructions) => {
97+
export const initServices = async (vscodeApiConfig: VscodeApiConfig, instructions?: InitServicesInstructions) => {
9898
const envEnhanced = initEnhancedMonacoEnvironment();
9999

100100
if (!(envEnhanced.vscodeInitialising ?? false)) {
101+
101102
if (envEnhanced.vscodeApiInitialised ?? false) {
102-
instructions.logger?.debug('Initialization of vscode services can only performed once!');
103+
instructions?.logger?.debug('Initialization of vscode services can only performed once!');
103104
} else {
104105
envEnhanced.vscodeInitialising = true;
105-
instructions.logger?.debug(`Initializing vscode services. Caller: ${instructions.caller ?? 'unknown'}`);
106+
instructions?.logger?.debug(`Initializing vscode services. Caller: ${instructions.caller ?? 'unknown'}`);
106107

108+
if (vscodeApiConfig.userConfiguration?.json !== undefined) {
109+
await initUserConfiguration(vscodeApiConfig.userConfiguration.json);
110+
}
107111
await importAllServices(vscodeApiConfig, instructions);
112+
108113
vscodeApiConfig.viewsConfig?.viewsInitFunc?.();
109-
instructions.logger?.debug('Initialization of vscode services completed successfully.');
114+
instructions?.logger?.debug('Initialization of vscode services completed successfully.');
110115

111116
envEnhanced.vscodeApiInitialised = true;
117+
envEnhanced.vscodeInitialising = false;
112118
}
113-
114-
await updateUserConfiguration(vscodeApiConfig.userConfiguration?.json ?? JSON.stringify({}));
115119
}
120+
121+
return envEnhanced.vscodeApiInitialised;
116122
};
117123

118124
/**
@@ -126,25 +132,25 @@ export const initServices = async (vscodeApiConfig: VscodeApiConfig, instruction
126132
* - languages
127133
* - model
128134
*/
129-
export const importAllServices = async (vscodeApiConfig: VscodeApiConfig, instructions: InitServicesInstructions) => {
135+
export const importAllServices = async (vscodeApiConfig: VscodeApiConfig, instructions?: InitServicesInstructions) => {
130136
const services = await supplyRequiredServices();
131137

132138
mergeServices(services, vscodeApiConfig.serviceOverrides);
133139
await configureExtHostWorker(vscodeApiConfig.enableExtHostWorker === true, services);
134140

135-
reportServiceLoading(services, instructions.logger);
141+
reportServiceLoading(services, instructions?.logger);
136142

137-
if (instructions.performServiceConsistencyChecks === undefined ||
143+
if (instructions?.performServiceConsistencyChecks === undefined ||
138144
(typeof instructions.performServiceConsistencyChecks === 'function' && instructions.performServiceConsistencyChecks())) {
139145
if (vscodeApiConfig.viewsConfig?.viewServiceType === 'ViewsService' || vscodeApiConfig.viewsConfig?.viewServiceType === 'WorkspaceService') {
140-
await initialize(services, instructions.htmlContainer, vscodeApiConfig.workspaceConfig, vscodeApiConfig.envOptions);
146+
await initialize(services, instructions?.htmlContainer, vscodeApiConfig.workspaceConfig, vscodeApiConfig.envOptions);
141147
} else {
142148
await initialize(services, undefined, vscodeApiConfig.workspaceConfig, vscodeApiConfig.envOptions);
143149
}
144150
}
145151

146152
setUnexpectedErrorHandler((e) => {
147-
instructions.logger?.createErrorAndLog('Unexpected error', e);
153+
instructions?.logger?.createErrorAndLog('Unexpected error', e);
148154
});
149155
};
150156

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* --------------------------------------------------------------------------------------------
2+
* Copyright (c) 2024 TypeFox and others.
3+
* Licensed under the MIT License. See LICENSE in the package root for license information.
4+
* ------------------------------------------------------------------------------------------ */
5+
6+
import { describe, expect, test } from 'vitest';
7+
import { initServices, MonacoEnvironmentEnhanced } from 'monaco-languageclient/vscode/services';
8+
import getConfigurationServiceOverride from '@codingame/monaco-vscode-configuration-service-override';
9+
10+
describe('VSCde services Tests', () => {
11+
12+
test('initServices', async () => {
13+
const vscodeApiConfig = {
14+
serviceOverrides: {
15+
...getConfigurationServiceOverride()
16+
},
17+
userConfiguration: {
18+
json: JSON.stringify({
19+
'workbench.colorTheme': 'Default Dark Modern'
20+
})
21+
}
22+
};
23+
24+
let envEnhanced = (self as Window).MonacoEnvironment as MonacoEnvironmentEnhanced;
25+
expect(envEnhanced).toBeUndefined();
26+
27+
// call initServices with userConfiguration
28+
const promise = initServices(vscodeApiConfig);
29+
envEnhanced = (self as Window).MonacoEnvironment as MonacoEnvironmentEnhanced;
30+
expect(envEnhanced.vscodeInitialising).toBeTruthy();
31+
expect(envEnhanced.vscodeApiInitialised).toBeFalsy();
32+
33+
// try a second time and expect that the api init is ongoing but not completed
34+
const secondCallResult = await initServices(vscodeApiConfig);
35+
36+
expect(secondCallResult).toBeFalsy();
37+
envEnhanced = (self as Window).MonacoEnvironment as MonacoEnvironmentEnhanced;
38+
expect(envEnhanced.vscodeInitialising).toBeTruthy();
39+
expect(envEnhanced.vscodeApiInitialised).toBeFalsy();
40+
41+
// wait for the initial promise to complete and expect that api init was completed and is no longer ongoing
42+
const initialCallResult = await promise;
43+
expect(initialCallResult).toBeTruthy();
44+
envEnhanced = (self as Window).MonacoEnvironment as MonacoEnvironmentEnhanced;
45+
expect(envEnhanced.vscodeInitialising).toBeFalsy();
46+
expect(envEnhanced.vscodeApiInitialised).toBeTruthy();
47+
});
48+
49+
});

packages/examples/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"@codingame/monaco-vscode-standalone-json-language-features": "~11.1.2",
9090
"@codingame/monaco-vscode-standalone-languages": "~11.1.2",
9191
"@codingame/monaco-vscode-standalone-typescript-language-features": "~11.1.2",
92+
"@codingame/monaco-vscode-storage-service-override": "~11.1.2",
9293
"@codingame/monaco-vscode-textmate-service-override": "~11.1.2",
9394
"@codingame/monaco-vscode-theme-defaults-default-extension": "~11.1.2",
9495
"@codingame/monaco-vscode-theme-service-override": "~11.1.2",

packages/examples/src/appPlayground/main.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { RegisteredFileSystemProvider, registerFileSystemOverlay, RegisteredMemo
1818
import getRemoteAgentServiceOverride from '@codingame/monaco-vscode-remote-agent-service-override';
1919
import getEnvironmentServiceOverride from '@codingame/monaco-vscode-environment-service-override';
2020
import getSecretStorageServiceOverride from '@codingame/monaco-vscode-secret-storage-service-override';
21+
import getStorageServiceOverride from '@codingame/monaco-vscode-storage-service-override';
2122
// this is required syntax highlighting
2223
import '@codingame/monaco-vscode-typescript-basics-default-extension';
2324
import '@codingame/monaco-vscode-typescript-language-features-default-extension';
@@ -53,7 +54,8 @@ export const runApplicationPlayground = async () => {
5354
...getExplorerServiceOverride(),
5455
...getRemoteAgentServiceOverride(),
5556
...getEnvironmentServiceOverride(),
56-
...getSecretStorageServiceOverride()
57+
...getSecretStorageServiceOverride(),
58+
...getStorageServiceOverride()
5759
},
5860
enableExtHostWorker: true,
5961
viewsConfig: {

packages/examples/src/bare/client.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,24 @@ import { WebSocketMessageReader, WebSocketMessageWriter, toSocket } from 'vscode
1515
import { CloseAction, ErrorAction, MessageTransports } from 'vscode-languageclient/browser.js';
1616
import { configureMonacoWorkers } from '../common/client/utils.js';
1717
import { ConsoleLogger } from 'monaco-languageclient/tools';
18-
import { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override';
1918

2019
export const runClient = async () => {
2120
const logger = new ConsoleLogger(LogLevel.Debug);
2221
const htmlContainer = document.getElementById('monaco-editor-root')!;
2322
await initServices({
2423
serviceOverrides: {
2524
...getConfigurationServiceOverride()
26-
}
25+
},
26+
userConfiguration: {
27+
json: JSON.stringify({
28+
'editor.experimental.asyncTokenization': true
29+
})
30+
},
2731
}, {
2832
htmlContainer,
2933
logger
3034
});
3135

32-
updateUserConfiguration(JSON.stringify({
33-
'editor.experimental.asyncTokenization': true
34-
}));
35-
3636
// register the JSON language with Monaco
3737
monaco.languages.register({
3838
id: 'json',

packages/wrapper/test/vscode/services.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { describe, expect, test } from 'vitest';
77
import { LogLevel } from 'vscode/services';
8-
import { augmentVscodeApiConfig } from '../../src/vscode/services.js';
8+
import { augmentVscodeApiConfig } from 'monaco-editor-wrapper/vscode/services';
99

1010
describe('createUrl', () => {
1111

vitest.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ export const vitestBaseConfig = {
2626
}
2727
},
2828
include: [
29+
'**/client/test/fs/emptyEndpoint.test.ts',
2930
'**/client/test/tools/index.test.ts',
31+
'**/client/test/tools/utils.test.ts',
32+
'**/client/test/vscode/services.test.ts',
3033
'**/wrapper/test/vscode/services.test.ts',
3134
'**/wrapper/test/editorApp.test.ts',
3235
'**/wrapper/test/languageClientWrapper.test.ts',

0 commit comments

Comments
 (0)