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
5 changes: 5 additions & 0 deletions .github/workflows/verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ jobs:
run: |
npm run report:versions

- name: Build
shell: bash
run: |
npm run build

- name: Execute verification
shell: bash
run: |
Expand Down
19 changes: 5 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 17 additions & 4 deletions packages/client/src/worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* Licensed under the MIT License. See LICENSE in the package root for license information.
* ------------------------------------------------------------------------------------------ */

// oxlint-disable typescript/no-redundant-type-constituents

import type { ILogger } from '@codingame/monaco-vscode-log-service-override';
import { getEnhancedMonacoEnvironment } from 'monaco-languageclient/vscodeApiWrapper';

Expand All @@ -18,26 +20,37 @@ export class Worker {

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

export type PossibleWorkerLabelsExtended =
| 'editorWorkerService'
| 'extensionHostWorkerMain'
| 'TextMateWorker'
| 'OutputLinkDetectionWorker'
| 'LanguageDetectionWorker'
| 'NotebookEditorWorker'
| 'LocalFileSearchWorker';
Comment thread
kaisalmen marked this conversation as resolved.

export type PossibleWorkerLabelsClassic = 'editorWorkerService' | 'css' | 'html' | 'json' | 'javascript' | 'typescript';

export interface WorkerFactoryConfig {
workerLoaders?: Partial<Record<string, WorkerLoader>>;
workerLoaders?: Partial<Record<PossibleWorkerLabelsExtended | PossibleWorkerLabelsClassic | string, WorkerLoader>>;
logger?: ILogger;
}

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

envEnhanced.getWorkerUrl = (workerId: string, label: string) => {
envEnhanced.getWorkerUrl = (workerId: string, label: PossibleWorkerLabelsExtended | PossibleWorkerLabelsClassic | string) => {
config.logger?.info(`getWorkerUrl: workerId: ${workerId} label: ${label}`);
return config.workerLoaders?.[label]?.().url.toString();
};

envEnhanced.getWorkerOptions = (moduleId: string, label: string) => {
envEnhanced.getWorkerOptions = (moduleId: string, label: PossibleWorkerLabelsExtended | PossibleWorkerLabelsClassic | string) => {
config.logger?.info(`getWorkerOptions: moduleId: ${moduleId} label: ${label}`);
return config.workerLoaders?.[label]?.().options;
};
};

export const defineDefaultWorkerLoaders: () => Partial<Record<string, WorkerLoader>> = () => {
export const defineDefaultWorkerLoaders: () => Record<PossibleWorkerLabelsExtended, WorkerLoader> = () => {
const defaultEditorWorkerService = () =>
new Worker(new URL('@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' });
const defaultExtensionHostWorkerMain = () =>
Expand Down
25 changes: 14 additions & 11 deletions packages/client/test/support/helper-classic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
* ------------------------------------------------------------------------------------------ */

import type { ILogger } from '@codingame/monaco-vscode-log-service-override';
import { useWorkerFactory, Worker, type WorkerLoader } from 'monaco-languageclient/workerFactory';
import { useWorkerFactory, Worker, type PossibleWorkerLabelsClassic, type WorkerLoader } from 'monaco-languageclient/workerFactory';

const workerResolver: Map<string, (value: void | PromiseLike<void>) => void> = new Map();
const workerPromises: Map<string, Promise<void>> = new Map();
export const createWorkerPromises = (keys: string[]) => {
const workerResolver: Map<PossibleWorkerLabelsClassic, (value: void | PromiseLike<void>) => void> = new Map();
const workerPromises: Map<PossibleWorkerLabelsClassic, Promise<void>> = new Map();
export const createWorkerPromises = (keys: PossibleWorkerLabelsClassic[]) => {
workerResolver.clear();
workerPromises.clear();
for (const key of keys) {
Expand All @@ -23,46 +23,49 @@ export const awaitWorkerPromises = () => {
return Promise.all([...workerPromises.values()]);
};

const pushAndPrintLastWorker = (lastWorker: string) => {
const pushAndPrintLastWorker = (lastWorker: PossibleWorkerLabelsClassic) => {
console.log(`Called: ${lastWorker}\n`);
workerResolver.get(lastWorker)?.();
};

const defineClassicWorkers: () => Partial<Record<string, WorkerLoader>> = () => {
const defineClassicWorkers: () => Partial<Record<PossibleWorkerLabelsClassic, WorkerLoader>> = (): Record<
PossibleWorkerLabelsClassic,
WorkerLoader
> => {
const editorWorkerServiceWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js', import.meta.url);
const worker = new Worker(workerUrl, {
type: 'module'
});
pushAndPrintLastWorker('editorWorker');
pushAndPrintLastWorker('editorWorkerService');
return worker;
};

const cssWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-css-language-features', import.meta.url);
const worker = new Worker(workerUrl, { type: 'module' });
pushAndPrintLastWorker('cssWorker');
pushAndPrintLastWorker('css');
return worker;
};

const jsonWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-json-language-features', import.meta.url);
const worker = new Worker(workerUrl, { type: 'module' });
pushAndPrintLastWorker('jsonWorker');
pushAndPrintLastWorker('json');
return worker;
};

const htmlWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-html-language-features', import.meta.url);
const worker = new Worker(workerUrl, { type: 'module' });
pushAndPrintLastWorker('htmlWorker');
pushAndPrintLastWorker('html');
return worker;
};

const tsWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-typescript-language-features', import.meta.url);
const worker = new Worker(workerUrl, { type: 'module' });
pushAndPrintLastWorker('tsWorker');
pushAndPrintLastWorker('typescript');
return worker;
};

Expand Down
4 changes: 2 additions & 2 deletions packages/client/test/worker/workerFactory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { LogLevel } from '@codingame/monaco-vscode-api';
import { ConsoleLogger } from '@codingame/monaco-vscode-log-service-override';
import { getEnhancedMonacoEnvironment } from 'monaco-languageclient/vscodeApiWrapper';
import { useWorkerFactory, Worker } from 'monaco-languageclient/workerFactory';
import { useWorkerFactory, Worker, type PossibleWorkerLabelsExtended, type WorkerLoader } from 'monaco-languageclient/workerFactory';
import { describe, expect, test } from 'vitest';

describe.concurrent('WorkerFactory Tests', { concurrent: false, tags: ['vscode'] }, () => {
Expand All @@ -28,7 +28,7 @@ describe.concurrent('WorkerFactory Tests', { concurrent: false, tags: ['vscode']
new Worker(new URL('@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js', import.meta.url), {
type: 'module'
})
},
} as Record<PossibleWorkerLabelsExtended, WorkerLoader>,
logger
});

Expand Down
8 changes: 4 additions & 4 deletions packages/client/test/worker/workerLoaders.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe.concurrent('Test WorkerLoaders', { concurrent: false, tags: ['vscode']
console.log(`editorWorkerUrl: ${editorWorkerUrl} worker: ${editorWorkerCheck !== undefined}\n`);

// default, expect editor worker to be loaded
createWorkerPromises(['editorWorker']);
createWorkerPromises(['editorWorkerService']);
await editorApp.start(htmlContainer);
expect(await awaitWorkerPromises()).toStrictEqual([undefined]);
await editorApp.disposeModelRefs();
Expand All @@ -54,7 +54,7 @@ describe.concurrent('Test WorkerLoaders', { concurrent: false, tags: ['vscode']
console.log(`jsonWorkerUrl: ${jsonWorkerUrl} worker: ${jsonWorkerCheck !== undefined}\n`);

// ts worker, expect ts worker and json worker to be loaded
createWorkerPromises(['tsWorker', 'jsonWorker']);
createWorkerPromises(['typescript', 'json']);
await editorApp.updateCodeResources({
modified: {
text: '',
Expand All @@ -69,7 +69,7 @@ describe.concurrent('Test WorkerLoaders', { concurrent: false, tags: ['vscode']
expect(cssWorkerCheck).toBeUndefined();
console.log(`cssWorkerUrl: ${cssWorkerUrl} worker: ${cssWorkerCheck !== undefined}\n`);

createWorkerPromises(['cssWorker']);
createWorkerPromises(['css']);
await editorApp.updateCodeResources({
modified: {
text: '',
Expand All @@ -84,7 +84,7 @@ describe.concurrent('Test WorkerLoaders', { concurrent: false, tags: ['vscode']
expect(htmlWorkerCheck).toBeUndefined();
console.log(`htmlWorkerUrl: ${htmlWorkerUrl} worker: ${htmlWorkerCheck !== undefined}\n`);

createWorkerPromises(['htmlWorker']);
createWorkerPromises(['html']);
await editorApp.updateCodeResources({
modified: {
text: '',
Expand Down
5 changes: 5 additions & 0 deletions packages/examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@
"@codingame/monaco-vscode-search-result-default-extension": "^35.0.0",
"@codingame/monaco-vscode-search-service-override": "^35.0.0",
"@codingame/monaco-vscode-secret-storage-service-override": "^35.0.0",
"@codingame/monaco-vscode-standalone-css-language-features": "^35.0.0",
"@codingame/monaco-vscode-standalone-html-language-features": "^35.0.0",
"@codingame/monaco-vscode-standalone-json-language-features": "^35.0.0",
"@codingame/monaco-vscode-standalone-languages": "^35.0.0",
"@codingame/monaco-vscode-standalone-typescript-language-features": "^35.0.0",
"@codingame/monaco-vscode-storage-service-override": "^35.0.0",
"@codingame/monaco-vscode-testing-service-override": "^35.0.0",
"@codingame/monaco-vscode-theme-defaults-default-extension": "^35.0.0",
Expand Down
9 changes: 7 additions & 2 deletions packages/examples/src/common/client/extendedClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import { LogLevel } from '@codingame/monaco-vscode-api';
import { EditorApp, type EditorAppConfig } from 'monaco-languageclient/editorApp';
import { LanguageClientWrapper, type LanguageClientConfig } from 'monaco-languageclient/lcwrapper';
import { MonacoVscodeApiWrapper, type MonacoVscodeApiConfig } from 'monaco-languageclient/vscodeApiWrapper';
import { configureDefaultWorkerFactory, useWorkerFactory, type WorkerLoader } from 'monaco-languageclient/workerFactory';
import {
configureDefaultWorkerFactory,
useWorkerFactory,
type PossibleWorkerLabelsExtended,
type WorkerLoader
} from 'monaco-languageclient/workerFactory';
import { createUrl, type ConnectionConfigOptions, type WebSocketConfigOptionsDirect } from 'monaco-languageclient/common';
import type { ILogger } from '@codingame/monaco-vscode-log-service-override';

Expand Down Expand Up @@ -155,5 +160,5 @@ export type ExampleLsConfig = {
basePath: string;
languageId: string;
useExternalWebSocket: boolean;
workerLoaders?: () => Partial<Record<string, WorkerLoader>>;
workerLoaders?: () => Partial<Record<PossibleWorkerLabelsExtended, WorkerLoader>>;
};
51 changes: 51 additions & 0 deletions packages/examples/src/common/worker/classic-workers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* --------------------------------------------------------------------------------------------
* Copyright (c) 2026 TypeFox and others.
* Licensed under the MIT License. See License.txt in the project root for license information.
* ------------------------------------------------------------------------------------------ */

import type { ILogger } from '@codingame/monaco-vscode-log-service-override';
import { useWorkerFactory, Worker, type PossibleWorkerLabelsClassic, type WorkerLoader } from 'monaco-languageclient/workerFactory';

export const defineClassicWorkers: () => Record<PossibleWorkerLabelsClassic, WorkerLoader> = () => {
const editorWorkerServiceWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js', import.meta.url);
return new Worker(workerUrl, { type: 'module' });
};

const cssWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-css-language-features', import.meta.url);
return new Worker(workerUrl, { type: 'module' });
};

const jsonWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-json-language-features', import.meta.url);
return new Worker(workerUrl, { type: 'module' });
};

const htmlWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-html-language-features', import.meta.url);
return new Worker(workerUrl, { type: 'module' });
};

const tsWorker = () => {
const workerUrl = new URL('@codingame/monaco-vscode-standalone-typescript-language-features', import.meta.url);
return new Worker(workerUrl, { type: 'module' });
};

return {
editorWorkerService: editorWorkerServiceWorker,
css: cssWorker,
html: htmlWorker,
json: jsonWorker,
// both have to be defined otherwise this leads to a test error
javascript: tsWorker,
typescript: tsWorker
};
};

export const configureClassicWorkerFactory = (logger?: ILogger) => {
useWorkerFactory({
workerLoaders: defineClassicWorkers(),
logger
});
};
Loading