Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions packages/client/src/vscode/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { EnvironmentOverride } from '@codingame/monaco-vscode-api/workbench
import type { Logger } from 'monaco-languageclient/tools';
import { FakeWorker as Worker } from './fakeWorker.js';
import { setUnexpectedErrorHandler } from '@codingame/monaco-vscode-api/monaco';
import { useWorkerFactory } from '../workerFactory.js';

export interface MonacoEnvironmentEnhanced extends monaco.Environment {
vscodeInitialising?: boolean;
Expand Down Expand Up @@ -50,11 +51,12 @@ export interface InitServicesInstructions {
caller?: string;
performServiceConsistencyChecks?: () => boolean;
logger?: Logger;
monacoWorkerFactory?: (logger?: Logger) => void;
}

export const initEnhancedMonacoEnvironment = () => {
export const getEnhancedMonacoEnvironment = (): MonacoEnvironmentEnhanced => {
const monWin = (self as Window);
if (!monWin.MonacoEnvironment) {
if (monWin.MonacoEnvironment === undefined) {
monWin.MonacoEnvironment = {};
}
const envEnhanced = monWin.MonacoEnvironment as MonacoEnvironmentEnhanced;
Expand Down Expand Up @@ -97,8 +99,15 @@ export const mergeServices = (overrideServices: monaco.editor.IEditorOverrideSer
};

export const initServices = async (vscodeApiConfig: VscodeApiConfig, instructions?: InitServicesInstructions) => {
const envEnhanced = initEnhancedMonacoEnvironment();
const envEnhanced = getEnhancedMonacoEnvironment();

if (typeof instructions?.monacoWorkerFactory === 'function') {
instructions.monacoWorkerFactory(instructions.logger);
} else {
useWorkerFactory({
logger: instructions?.logger
});
}
if (!(envEnhanced.vscodeInitialising ?? false)) {

if (envEnhanced.vscodeApiInitialised ?? false) {
Expand Down
8 changes: 4 additions & 4 deletions packages/client/src/workerFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */

import { initEnhancedMonacoEnvironment } from 'monaco-languageclient/vscode/services';
import { getEnhancedMonacoEnvironment } from 'monaco-languageclient/vscode/services';
import type { Logger } from 'monaco-languageclient/tools';

export type WorkerLoader = (() => Worker) | undefined;

export interface WorkerFactoryConfig {
workerLoaders: Record<string, WorkerLoader>;
workerLoaders?: Record<string, WorkerLoader>;
logger?: Logger;
getWorkerOverride?: (moduleId: string, label: string) => Worker;
}

export const useWorkerFactory = (config: WorkerFactoryConfig) => {
const envEnhanced = initEnhancedMonacoEnvironment();
const envEnhanced = getEnhancedMonacoEnvironment();

const getWorker = (moduleId: string, label: string) => {
config.logger?.info(`getWorker: moduleId: ${moduleId} label: ${label}`);

const workerFunc = config.workerLoaders[label];
const workerFunc = config.workerLoaders?.[label] ?? undefined;
if (workerFunc === undefined) {
throw new Error(`Unimplemented worker ${label} (${moduleId})`);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/client/test/vscode/services.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { describe, expect, test } from 'vitest';
import { initServices, type MonacoEnvironmentEnhanced } from 'monaco-languageclient/vscode/services';

describe('VSCde services Tests', () => {
describe('VSCode services Tests', () => {

test('initServices', async () => {
const vscodeApiConfig = {
Expand Down
42 changes: 42 additions & 0 deletions packages/client/test/workerFactory.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) 2024 TypeFox and others.
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */

import { describe, expect, test } from 'vitest';
import { LogLevel } from '@codingame/monaco-vscode-api';
import { ConsoleLogger } from 'monaco-languageclient/tools';
import { useWorkerFactory } from 'monaco-languageclient/workerFactory';

describe('WorkerFactory Tests', () => {

test('useWorkerFactory: Nothing', () => {

useWorkerFactory({});

const monWin = (self as Window);
const getWorker = () => monWin.MonacoEnvironment?.getWorker?.('test', 'TextEditorWorker');
expect(getWorker).toThrowError('Unimplemented worker TextEditorWorker (test)');
});

test('useWorkerFactory: TextEditorWorker', async () => {
const logger = new ConsoleLogger(LogLevel.Info);

useWorkerFactory({
workerLoaders: {
TextEditorWorker: () => new Worker(
new URL('@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js', import.meta.url),
{ type: 'module' }
)
},
logger
});

const monWin = (self as Window);
const getWorker = () => monWin.MonacoEnvironment?.getWorker?.('test', 'TextEditorWorker');
const workerFunc = getWorker();
expect(workerFunc).toBeDefined();
expect(workerFunc).toBeInstanceOf(Worker);
});

});
5 changes: 1 addition & 4 deletions packages/wrapper/src/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,7 @@ export class MonacoEditorLanguageClientWrapper {
this.markInitializing();

this.id = wrapperConfig.id ?? Math.floor(Math.random() * 1000001).toString();

this.logger.setLevel(wrapperConfig.logLevel ?? LogLevel.Off);
if (typeof wrapperConfig.editorAppConfig?.monacoWorkerFactory === 'function') {
wrapperConfig.editorAppConfig.monacoWorkerFactory(this.logger);
}

if (!(wrapperConfig.vscodeApiConfig?.vscodeApiInitPerformExternally === true)) {
wrapperConfig.vscodeApiConfig = await augmentVscodeApiConfig(wrapperConfig.$type, {
Expand All @@ -114,6 +110,7 @@ export class MonacoEditorLanguageClientWrapper {
semanticHighlighting: wrapperConfig.editorAppConfig?.editorOptions?.['semanticHighlighting.enabled'] === true
});
await initServices(wrapperConfig.vscodeApiConfig, {
monacoWorkerFactory: wrapperConfig.editorAppConfig?.monacoWorkerFactory,
htmlContainer: wrapperConfig.htmlContainer,
caller: `monaco-editor (${this.id})`,
performServiceConsistencyChecks: checkServiceConsistency,
Expand Down
14 changes: 14 additions & 0 deletions packages/wrapper/test/wrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -307,4 +307,18 @@ describe('Test MonacoEditorLanguageClientWrapper', () => {
expect(error).toBe(false);
});

test('monacoWorkerFactory: Nothing', async () => {
const wrapperConfig = createWrapperConfigExtendedApp({});
wrapperConfig.editorAppConfig!.monacoWorkerFactory = undefined;

const wrapper = new MonacoEditorLanguageClientWrapper();
await expect(await wrapper.init(wrapperConfig)).toBeUndefined();

const monWin = (self as Window);
const getWorker = () => monWin.MonacoEnvironment?.getWorker?.('test', 'TextEditorWorker');
expect(getWorker).toThrowError('Unimplemented worker TextEditorWorker (test)');

await expect(await wrapper.start()).toBeUndefined();
});

});
1 change: 1 addition & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const vitestConfig = {
},
// keep an explicit list of tests to run, so they can be commented in case of problems
include: [
'**/client/test/workerFactory.test.ts',
'**/client/test/fs/endpoints/emptyEndpoint.test.ts',
'**/client/test/tools/index.test.ts',
'**/client/test/tools/utils.test.ts',
Expand Down