Skip to content

Commit d64bfbb

Browse files
committed
Unclutter WorkerFactory. Only support direct worker loading, but keep classic preset (used in Langium Classic example)
1 parent 43f1093 commit d64bfbb

File tree

3 files changed

+43
-98
lines changed

3 files changed

+43
-98
lines changed

packages/examples/src/common/client/utils.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ export const disableButton = (id: string, disabled: boolean) => {
1515

1616
export const configureMonacoWorkers = (logger?: Logger) => {
1717
useWorkerFactory({
18-
ignoreMapping: true,
19-
workerLoaders: {
20-
TextEditorWorker: () => new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' }),
21-
TextMateWorker: () => new Worker(new URL('@codingame/monaco-vscode-textmate-service-override/worker', import.meta.url), { type: 'module' })
22-
}
23-
}, logger);
18+
workerOverrides: {
19+
ignoreMapping: true,
20+
workerLoaders: {
21+
TextEditorWorker: () => new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker.js', import.meta.url), { type: 'module' }),
22+
TextMateWorker: () => new Worker(new URL('@codingame/monaco-vscode-textmate-service-override/worker', import.meta.url), { type: 'module' })
23+
}
24+
},
25+
logger
26+
});
2427
};

packages/examples/src/langium/langium-dsl/config/classicConfig.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import getConfigurationServiceOverride from '@codingame/monaco-vscode-configurat
77
import getEditorServiceOverride from '@codingame/monaco-vscode-editor-service-override';
88
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override';
99
import { useOpenEditorStub } from 'monaco-editor-wrapper/vscode/services';
10-
import { checkLogLevel } from 'monaco-languageclient/tools';
10+
import { checkLogLevel, Logger } from 'monaco-languageclient/tools';
1111
import { WrapperConfig } from 'monaco-editor-wrapper';
12-
import { configureMonacoWorkers } from '../../../common/client/utils.js';
12+
// import { configureMonacoWorkers } from '../../../common/client/utils.js';
1313
import { LangiumMonarchContent } from './langium.monarch.js';
1414
import { loadLangiumWorker } from '../wrapperLangium.js';
1515
import code from '../content/example.langium?raw';
16+
import { useWorkerFactory } from 'monaco-editor-wrapper/workerFactory';
1617

1718
export const setupLangiumClientClassic = async (): Promise<WrapperConfig> => {
1819
const langiumWorker = loadLangiumWorker();
@@ -44,7 +45,11 @@ export const setupLangiumClientClassic = async (): Promise<WrapperConfig> => {
4445
monarchLanguage: LangiumMonarchContent,
4546
languageExtensionConfig: { id: 'langium' },
4647
},
47-
monacoWorkerFactory: configureMonacoWorkers
48+
monacoWorkerFactory: (logger?: Logger) => {
49+
useWorkerFactory({
50+
logger
51+
});
52+
}
4853
},
4954
languageClientConfigs: {
5055
langium: {

packages/wrapper/src/workerFactory.ts

Lines changed: 26 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -7,122 +7,58 @@ import { initEnhancedMonacoEnvironment } from 'monaco-languageclient/vscode/serv
77
import { Logger } from 'monaco-languageclient/tools';
88

99
export interface WorkerOverrides {
10-
rootPath?: string | URL;
11-
basePath?: string | URL;
12-
workerLoaders?: Partial<Record<string, WorkerConfigSupplier | WorkerLoader>>;
10+
workerLoaders?: Partial<Record<string, WorkerLoader>>;
1311
ignoreMapping?: boolean;
1412
userDefinedMapping?: (label: string) => string;
1513
}
1614

17-
export interface WorkerConfig {
18-
rootPath: string | URL;
19-
basePath?: string | URL;
20-
workerFile: string | URL;
21-
options?: WorkerOptions;
22-
}
23-
24-
export type WorkerConfigSupplier = () => WorkerConfig;
25-
export type WorkerLoader = () => Worker
26-
27-
export const defaultWorkerLoaders: Partial<Record<string, WorkerConfigSupplier | WorkerLoader>> = {
28-
editorWorker: () => {
29-
return {
30-
rootPath: import.meta.url,
31-
workerFile: 'monaco-editor-wrapper/dist/workers/editorWorker-es.js'
32-
};
33-
},
34-
tsWorker: () => {
35-
return {
36-
rootPath: import.meta.url,
37-
workerFile: 'monaco-editor-wrapper/dist/workers/tsWorker-es.js'
38-
};
39-
},
40-
htmlWorker: () => {
41-
return {
42-
rootPath: import.meta.url,
43-
workerFile: 'monaco-editor-wrapper/dist/workers/htmlWorker-es.js'
44-
};
45-
},
46-
cssWorker: () => {
47-
return {
48-
rootPath: import.meta.url,
49-
workerFile: 'monaco-editor-wrapper/dist/workers/cssWorker-es.js'
50-
};
51-
},
52-
jsonWorker: () => {
53-
return {
54-
rootPath: import.meta.url,
55-
workerFile: 'monaco-editor-wrapper/dist/workers/jsonWorker-es.js'
56-
};
57-
}
58-
};
59-
/**
60-
* Cross origin workers don't work
61-
* The workaround used by vscode is to start a worker on a blob url containing a short script calling 'importScripts'
62-
* importScripts accepts to load the code inside the blob worker
63-
*/
64-
export const buildWorker = (config: WorkerConfig, workerOverrides?: WorkerOverrides, logger?: Logger): Worker => {
65-
if (workerOverrides?.rootPath !== undefined) {
66-
config.rootPath = workerOverrides.rootPath;
67-
}
68-
if (workerOverrides?.basePath !== undefined) {
69-
config.basePath = workerOverrides.basePath;
70-
}
71-
let workerFile = config.workerFile;
72-
if (config.basePath !== undefined) {
73-
workerFile = `${config.basePath}/${config.workerFile}`;
74-
}
75-
const fullUrl = new URL(workerFile, config.rootPath).href;
76-
logger?.info(`Creating worker: ${fullUrl}`);
15+
export type WorkerLoader = () => Worker;
7716

78-
// default to 'module' if not specified
79-
const workerOptions = config.options ?? {};
80-
if (!workerOptions.type) {
81-
workerOptions.type = 'module';
82-
}
83-
const js = workerOptions.type === 'module' ? `import '${fullUrl}';` : `importScripts('${fullUrl}');`;
84-
const blob = new Blob([js], { type: 'application/javascript' });
17+
export interface WorkerFactoryConfig {
18+
workerOverrides?: WorkerOverrides;
19+
logger?: Logger;
20+
}
8521

86-
return new Worker(URL.createObjectURL(blob), workerOptions);
22+
export const defaultWorkerLoaders: Partial<Record<string, WorkerLoader>> = {
23+
editorWorker: () => new Worker(new URL('monaco-editor-wrapper/workers/module/editor', import.meta.url), { type: 'module' }),
24+
tsWorker: () => new Worker(new URL('monaco-editor-wrapper/workers/module/ts', import.meta.url), { type: 'module' }),
25+
htmlWorker: () => new Worker(new URL('monaco-editor-wrapper/workers/module/html', import.meta.url), { type: 'module' }),
26+
cssWorker: () => new Worker(new URL('monaco-editor-wrapper/workers/module/css', import.meta.url), { type: 'module' }),
27+
jsonWorker: () => new Worker(new URL('monaco-editor-wrapper/workers/module/json', import.meta.url), { type: 'module' })
8728
};
8829

89-
export const useWorkerFactory = (workerOverrides?: WorkerOverrides, logger?: Logger) => {
30+
export const useWorkerFactory = (config: WorkerFactoryConfig) => {
9031
const envEnhanced = initEnhancedMonacoEnvironment();
9132

9233
const getWorker = (moduleId: string, label: string) => {
93-
logger?.info(`getWorker: moduleId: ${moduleId} label: ${label}`);
34+
config.logger?.info(`getWorker: moduleId: ${moduleId} label: ${label}`);
9435

9536
let selector = label;
9637
let workerLoaders;
9738

98-
// if you choose to ignore the default mapping only the
99-
// workerLoaders passed with workerOverrides are used
100-
if (workerOverrides?.ignoreMapping === true) {
39+
// if you choose to ignore the default mapping only the workerLoaders passed with workerOverrides are used
40+
if (config.workerOverrides?.ignoreMapping === true) {
10141
workerLoaders = {
102-
...workerOverrides.workerLoaders
42+
...config.workerOverrides.workerLoaders
10343
};
10444
} else {
10545
workerLoaders = {
106-
...defaultWorkerLoaders, ...workerOverrides?.workerLoaders
46+
...defaultWorkerLoaders, ...config.workerOverrides?.workerLoaders
10747
};
10848

10949
let mappingFunc = useDefaultWorkerMapping;
110-
if (workerOverrides?.userDefinedMapping) {
111-
mappingFunc = workerOverrides.userDefinedMapping;
50+
if (config.workerOverrides?.userDefinedMapping) {
51+
mappingFunc = config.workerOverrides.userDefinedMapping;
11252
}
11353
selector = mappingFunc(label);
11454
}
11555

116-
const workerOrConfig = workerLoaders[selector];
117-
if (workerOrConfig) {
118-
const invoked = workerOrConfig();
119-
if (Object.hasOwn(invoked, 'workerFile')) {
120-
return buildWorker(invoked as WorkerConfig, workerOverrides, logger);
121-
} else {
122-
return invoked as Worker;
123-
}
56+
const workerFunc = workerLoaders[selector];
57+
if (workerFunc !== undefined) {
58+
return workerFunc();
59+
} else {
60+
throw new Error(`Unimplemented worker ${label} (${moduleId})`);
12461
}
125-
throw new Error(`Unimplemented worker ${label} (${moduleId})`);
12662
};
12763
envEnhanced.getWorker = getWorker;
12864
};
@@ -131,6 +67,7 @@ export const useDefaultWorkerMapping = (label: string) => {
13167
switch (label) {
13268
case 'editor':
13369
case 'editorWorkerService':
70+
case 'TextEditorWorker':
13471
return 'editorWorker';
13572
case 'typescript':
13673
case 'javascript':

0 commit comments

Comments
 (0)