mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-20 10:19:02 +00:00
Introduces IWebWorkerService to allow the monaco editor to customize web worker handling via service injection
This commit is contained in:
committed by
Henning Dieterichs
parent
77a0f670d3
commit
32b7a94b60
@@ -3,8 +3,11 @@
|
|||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
WebWorkerDescriptor.useBundlerLocationRef();
|
registerSingleton(IWebWorkerService, StandaloneWebWorkerService, InstantiationType.Eager);
|
||||||
|
|
||||||
import { WebWorkerDescriptor } from '../../src/vs/base/browser/webWorkerFactory.js';
|
|
||||||
import '../../src/vs/code/browser/workbench/workbench.ts';
|
import '../../src/vs/code/browser/workbench/workbench.ts';
|
||||||
|
import { InstantiationType, registerSingleton } from '../../src/vs/platform/instantiation/common/extensions.ts';
|
||||||
|
import { IWebWorkerService } from '../../src/vs/platform/webWorker/browser/webWorkerService.ts';
|
||||||
|
// eslint-disable-next-line local/code-no-standalone-editor
|
||||||
|
import { StandaloneWebWorkerService } from '../../src/vs/editor/standalone/browser/services/standaloneWebWorkerService.ts';
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,6 @@ export default tseslint.config(
|
|||||||
'src/vs/base/browser/dom.ts',
|
'src/vs/base/browser/dom.ts',
|
||||||
'src/vs/base/browser/markdownRenderer.ts',
|
'src/vs/base/browser/markdownRenderer.ts',
|
||||||
'src/vs/base/browser/touch.ts',
|
'src/vs/base/browser/touch.ts',
|
||||||
'src/vs/base/browser/webWorkerFactory.ts',
|
|
||||||
'src/vs/base/common/async.ts',
|
'src/vs/base/common/async.ts',
|
||||||
'src/vs/base/common/desktopEnvironmentInfo.ts',
|
'src/vs/base/common/desktopEnvironmentInfo.ts',
|
||||||
'src/vs/base/common/objects.ts',
|
'src/vs/base/common/objects.ts',
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts"
|
"vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts"
|
||||||
],
|
],
|
||||||
"ban-worker-calls": [
|
"ban-worker-calls": [
|
||||||
"vs/base/browser/webWorkerFactory.ts",
|
"vs/platform/webWorker/browser/webWorkerServiceImpl.ts",
|
||||||
"vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts"
|
"vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts"
|
||||||
],
|
],
|
||||||
"ban-worker-importscripts": [
|
"ban-worker-importscripts": [
|
||||||
|
|||||||
@@ -1,236 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------------------------
|
|
||||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
||||||
*--------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
import { createTrustedTypesPolicy } from './trustedTypes.js';
|
|
||||||
import { onUnexpectedError } from '../common/errors.js';
|
|
||||||
import { COI } from '../common/network.js';
|
|
||||||
import { URI } from '../common/uri.js';
|
|
||||||
import { IWebWorker, IWebWorkerClient, Message, WebWorkerClient } from '../common/worker/webWorker.js';
|
|
||||||
import { Disposable, toDisposable } from '../common/lifecycle.js';
|
|
||||||
import { coalesce } from '../common/arrays.js';
|
|
||||||
import { getNLSLanguage, getNLSMessages } from '../../nls.js';
|
|
||||||
import { Emitter } from '../common/event.js';
|
|
||||||
import { getMonacoEnvironment } from './browser.js';
|
|
||||||
|
|
||||||
type WorkerGlobalWithPolicy = typeof globalThis & {
|
|
||||||
workerttPolicy?: ReturnType<typeof createTrustedTypesPolicy>;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Reuse the trusted types policy defined from worker bootstrap
|
|
||||||
// when available.
|
|
||||||
// Refs https://github.com/microsoft/vscode/issues/222193
|
|
||||||
let ttPolicy: ReturnType<typeof createTrustedTypesPolicy>;
|
|
||||||
const workerGlobalThis = globalThis as WorkerGlobalWithPolicy;
|
|
||||||
if (typeof self === 'object' && self.constructor && self.constructor.name === 'DedicatedWorkerGlobalScope' && workerGlobalThis.workerttPolicy !== undefined) {
|
|
||||||
ttPolicy = workerGlobalThis.workerttPolicy;
|
|
||||||
} else {
|
|
||||||
ttPolicy = createTrustedTypesPolicy('defaultWorkerFactory', { createScriptURL: value => value });
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Worker {
|
|
||||||
if (!blobUrl.startsWith('blob:')) {
|
|
||||||
throw new URIError('Not a blob-url: ' + blobUrl);
|
|
||||||
}
|
|
||||||
return new Worker(ttPolicy ? ttPolicy.createScriptURL(blobUrl) as unknown as string : blobUrl, { ...options, type: 'module' });
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWorker(descriptor: WebWorkerDescriptor, id: number): Worker | Promise<Worker> {
|
|
||||||
const label = descriptor.label || 'anonymous' + id;
|
|
||||||
|
|
||||||
// Option for hosts to overwrite the worker script (used in the standalone editor)
|
|
||||||
const monacoEnvironment = getMonacoEnvironment();
|
|
||||||
if (monacoEnvironment) {
|
|
||||||
if (typeof monacoEnvironment.getWorker === 'function') {
|
|
||||||
const w = monacoEnvironment.getWorker('workerMain.js', label);
|
|
||||||
if (w !== undefined) {
|
|
||||||
return w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof monacoEnvironment.getWorkerUrl === 'function') {
|
|
||||||
const workerUrl = monacoEnvironment.getWorkerUrl('workerMain.js', label);
|
|
||||||
if (workerUrl !== undefined) {
|
|
||||||
return new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: 'module' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const esmWorkerLocation = descriptor.getUrl();
|
|
||||||
if (esmWorkerLocation) {
|
|
||||||
const workerUrl = getWorkerBootstrapUrl(label, esmWorkerLocation);
|
|
||||||
const worker = new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: label, type: 'module' });
|
|
||||||
return whenESMWorkerReady(worker);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWorkerBootstrapUrl(label: string, workerScriptUrl: string): string {
|
|
||||||
if (/^((http:)|(https:)|(file:))/.test(workerScriptUrl) && workerScriptUrl.substring(0, globalThis.origin.length) !== globalThis.origin) {
|
|
||||||
// this is the cross-origin case
|
|
||||||
// i.e. the webpage is running at a different origin than where the scripts are loaded from
|
|
||||||
} else {
|
|
||||||
const start = workerScriptUrl.lastIndexOf('?');
|
|
||||||
const end = workerScriptUrl.lastIndexOf('#', start);
|
|
||||||
const params = start > 0
|
|
||||||
? new URLSearchParams(workerScriptUrl.substring(start + 1, ~end ? end : undefined))
|
|
||||||
: new URLSearchParams();
|
|
||||||
|
|
||||||
COI.addSearchParam(params, true, true);
|
|
||||||
const search = params.toString();
|
|
||||||
if (!search) {
|
|
||||||
workerScriptUrl = `${workerScriptUrl}#${label}`;
|
|
||||||
} else {
|
|
||||||
workerScriptUrl = `${workerScriptUrl}?${params.toString()}#${label}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In below blob code, we are using JSON.stringify to ensure the passed
|
|
||||||
// in values are not breaking our script. The values may contain string
|
|
||||||
// terminating characters (such as ' or ").
|
|
||||||
const blob = new Blob([coalesce([
|
|
||||||
`/*${label}*/`,
|
|
||||||
`globalThis._VSCODE_NLS_MESSAGES = ${JSON.stringify(getNLSMessages())};`,
|
|
||||||
`globalThis._VSCODE_NLS_LANGUAGE = ${JSON.stringify(getNLSLanguage())};`,
|
|
||||||
`globalThis._VSCODE_FILE_ROOT = ${JSON.stringify(globalThis._VSCODE_FILE_ROOT)};`,
|
|
||||||
`const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });`,
|
|
||||||
`globalThis.workerttPolicy = ttPolicy;`,
|
|
||||||
`await import(ttPolicy?.createScriptURL(${JSON.stringify(workerScriptUrl)}) ?? ${JSON.stringify(workerScriptUrl)});`,
|
|
||||||
`globalThis.postMessage({ type: 'vscode-worker-ready' });`,
|
|
||||||
`/*${label}*/`
|
|
||||||
]).join('')], { type: 'application/javascript' });
|
|
||||||
return URL.createObjectURL(blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
function whenESMWorkerReady(worker: Worker): Promise<Worker> {
|
|
||||||
return new Promise<Worker>((resolve, reject) => {
|
|
||||||
worker.onmessage = function (e) {
|
|
||||||
if (e.data.type === 'vscode-worker-ready') {
|
|
||||||
worker.onmessage = null;
|
|
||||||
resolve(worker);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
worker.onerror = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function isPromiseLike<T>(obj: unknown): obj is PromiseLike<T> {
|
|
||||||
return !!obj && typeof (obj as PromiseLike<T>).then === 'function';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A worker that uses HTML5 web workers so that is has
|
|
||||||
* its own global scope and its own thread.
|
|
||||||
*/
|
|
||||||
class WebWorker extends Disposable implements IWebWorker {
|
|
||||||
|
|
||||||
private static LAST_WORKER_ID = 0;
|
|
||||||
|
|
||||||
private readonly id: number;
|
|
||||||
private worker: Promise<Worker> | null;
|
|
||||||
|
|
||||||
private readonly _onMessage = this._register(new Emitter<Message>());
|
|
||||||
public readonly onMessage = this._onMessage.event;
|
|
||||||
|
|
||||||
private readonly _onError = this._register(new Emitter<MessageEvent | ErrorEvent>());
|
|
||||||
public readonly onError = this._onError.event;
|
|
||||||
|
|
||||||
constructor(descriptorOrWorker: WebWorkerDescriptor | Worker | Promise<Worker>) {
|
|
||||||
super();
|
|
||||||
this.id = ++WebWorker.LAST_WORKER_ID;
|
|
||||||
const workerOrPromise = (
|
|
||||||
descriptorOrWorker instanceof Worker
|
|
||||||
? descriptorOrWorker :
|
|
||||||
'then' in descriptorOrWorker ? descriptorOrWorker
|
|
||||||
: getWorker(descriptorOrWorker, this.id)
|
|
||||||
);
|
|
||||||
if (isPromiseLike(workerOrPromise)) {
|
|
||||||
this.worker = workerOrPromise;
|
|
||||||
} else {
|
|
||||||
this.worker = Promise.resolve(workerOrPromise);
|
|
||||||
}
|
|
||||||
this.postMessage('-please-ignore-', []); // TODO: Eliminate this extra message
|
|
||||||
const errorHandler = (ev: ErrorEvent) => {
|
|
||||||
this._onError.fire(ev);
|
|
||||||
};
|
|
||||||
this.worker.then((w) => {
|
|
||||||
w.onmessage = (ev) => {
|
|
||||||
this._onMessage.fire(ev.data);
|
|
||||||
};
|
|
||||||
w.onmessageerror = (ev) => {
|
|
||||||
this._onError.fire(ev);
|
|
||||||
};
|
|
||||||
if (typeof w.addEventListener === 'function') {
|
|
||||||
w.addEventListener('error', errorHandler);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._register(toDisposable(() => {
|
|
||||||
this.worker?.then(w => {
|
|
||||||
w.onmessage = null;
|
|
||||||
w.onmessageerror = null;
|
|
||||||
w.removeEventListener('error', errorHandler);
|
|
||||||
w.terminate();
|
|
||||||
});
|
|
||||||
this.worker = null;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public getId(): number {
|
|
||||||
return this.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public postMessage(message: unknown, transfer: Transferable[]): void {
|
|
||||||
this.worker?.then(w => {
|
|
||||||
try {
|
|
||||||
w.postMessage(message, transfer);
|
|
||||||
} catch (err) {
|
|
||||||
onUnexpectedError(err);
|
|
||||||
onUnexpectedError(new Error(`FAILED to post message to worker`, { cause: err }));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class WebWorkerDescriptor {
|
|
||||||
private static _useBundlerLocationRef = false;
|
|
||||||
|
|
||||||
/** TODO @hediet: Use web worker service! */
|
|
||||||
public static useBundlerLocationRef() {
|
|
||||||
WebWorkerDescriptor._useBundlerLocationRef = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public readonly esmModuleLocation: URI | (() => URI) | undefined;
|
|
||||||
public readonly esmModuleLocationBundler: URL | (() => URL) | undefined;
|
|
||||||
public readonly label: string | undefined;
|
|
||||||
|
|
||||||
constructor(args: {
|
|
||||||
/** The location of the esm module after transpilation */
|
|
||||||
esmModuleLocation?: URI | (() => URI);
|
|
||||||
/** The location of the esm module when used in a bundler environment. Refer to the typescript file in the src folder and use `?worker`. */
|
|
||||||
esmModuleLocationBundler?: URL | (() => URL);
|
|
||||||
label?: string;
|
|
||||||
}) {
|
|
||||||
this.esmModuleLocation = args.esmModuleLocation;
|
|
||||||
this.esmModuleLocationBundler = args.esmModuleLocationBundler;
|
|
||||||
this.label = args.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
getUrl(): string | undefined {
|
|
||||||
if (WebWorkerDescriptor._useBundlerLocationRef) {
|
|
||||||
if (this.esmModuleLocationBundler) {
|
|
||||||
const esmWorkerLocation = typeof this.esmModuleLocationBundler === 'function' ? this.esmModuleLocationBundler() : this.esmModuleLocationBundler;
|
|
||||||
return esmWorkerLocation.toString();
|
|
||||||
}
|
|
||||||
} else if (this.esmModuleLocation) {
|
|
||||||
const esmWorkerLocation = typeof this.esmModuleLocation === 'function' ? this.esmModuleLocation() : this.esmModuleLocation;
|
|
||||||
return esmWorkerLocation.toString(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createWebWorker<T extends object>(workerDescriptor: WebWorkerDescriptor | Worker | Promise<Worker>): IWebWorkerClient<T> {
|
|
||||||
return new WebWorkerClient<T>(new WebWorker(workerDescriptor));
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,8 @@ import { timeout } from '../../../base/common/async.js';
|
|||||||
import { Disposable, IDisposable } from '../../../base/common/lifecycle.js';
|
import { Disposable, IDisposable } from '../../../base/common/lifecycle.js';
|
||||||
import { URI } from '../../../base/common/uri.js';
|
import { URI } from '../../../base/common/uri.js';
|
||||||
import { logOnceWebWorkerWarning, IWebWorkerClient, Proxied } from '../../../base/common/worker/webWorker.js';
|
import { logOnceWebWorkerWarning, IWebWorkerClient, Proxied } from '../../../base/common/worker/webWorker.js';
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from '../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { Position } from '../../common/core/position.js';
|
import { Position } from '../../common/core/position.js';
|
||||||
import { IRange, Range } from '../../common/core/range.js';
|
import { IRange, Range } from '../../common/core/range.js';
|
||||||
import { ITextModel } from '../../common/model.js';
|
import { ITextModel } from '../../common/model.js';
|
||||||
@@ -67,6 +68,7 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ
|
|||||||
@ILogService logService: ILogService,
|
@ILogService logService: ILogService,
|
||||||
@ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService,
|
@ILanguageConfigurationService private readonly _languageConfigurationService: ILanguageConfigurationService,
|
||||||
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
|
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
|
||||||
|
@IWebWorkerService private readonly _webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._modelService = modelService;
|
this._modelService = modelService;
|
||||||
@@ -77,7 +79,7 @@ export class EditorWorkerService extends Disposable implements IEditorWorkerServ
|
|||||||
label: 'editorWorkerService'
|
label: 'editorWorkerService'
|
||||||
});
|
});
|
||||||
|
|
||||||
this._workerManager = this._register(new WorkerManager(workerDescriptor, this._modelService));
|
this._workerManager = this._register(new WorkerManager(workerDescriptor, this._modelService, this._webWorkerService));
|
||||||
this._logService = logService;
|
this._logService = logService;
|
||||||
|
|
||||||
// register default link-provider and default completions-provider
|
// register default link-provider and default completions-provider
|
||||||
@@ -333,15 +335,18 @@ class WordBasedCompletionItemProvider implements languages.CompletionItemProvide
|
|||||||
class WorkerManager extends Disposable {
|
class WorkerManager extends Disposable {
|
||||||
|
|
||||||
private readonly _modelService: IModelService;
|
private readonly _modelService: IModelService;
|
||||||
|
private readonly _webWorkerService: IWebWorkerService;
|
||||||
private _editorWorkerClient: EditorWorkerClient | null;
|
private _editorWorkerClient: EditorWorkerClient | null;
|
||||||
private _lastWorkerUsedTime: number;
|
private _lastWorkerUsedTime: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _workerDescriptor: WebWorkerDescriptor,
|
private readonly _workerDescriptor: WebWorkerDescriptor,
|
||||||
@IModelService modelService: IModelService
|
@IModelService modelService: IModelService,
|
||||||
|
@IWebWorkerService webWorkerService: IWebWorkerService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._modelService = modelService;
|
this._modelService = modelService;
|
||||||
|
this._webWorkerService = webWorkerService;
|
||||||
this._editorWorkerClient = null;
|
this._editorWorkerClient = null;
|
||||||
this._lastWorkerUsedTime = (new Date()).getTime();
|
this._lastWorkerUsedTime = (new Date()).getTime();
|
||||||
|
|
||||||
@@ -393,7 +398,7 @@ class WorkerManager extends Disposable {
|
|||||||
public withWorker(): Promise<EditorWorkerClient> {
|
public withWorker(): Promise<EditorWorkerClient> {
|
||||||
this._lastWorkerUsedTime = (new Date()).getTime();
|
this._lastWorkerUsedTime = (new Date()).getTime();
|
||||||
if (!this._editorWorkerClient) {
|
if (!this._editorWorkerClient) {
|
||||||
this._editorWorkerClient = new EditorWorkerClient(this._workerDescriptor, false, this._modelService);
|
this._editorWorkerClient = new EditorWorkerClient(this._workerDescriptor, false, this._modelService, this._webWorkerService);
|
||||||
}
|
}
|
||||||
return Promise.resolve(this._editorWorkerClient);
|
return Promise.resolve(this._editorWorkerClient);
|
||||||
}
|
}
|
||||||
@@ -428,6 +433,7 @@ export interface IEditorWorkerClient {
|
|||||||
export class EditorWorkerClient extends Disposable implements IEditorWorkerClient {
|
export class EditorWorkerClient extends Disposable implements IEditorWorkerClient {
|
||||||
|
|
||||||
private readonly _modelService: IModelService;
|
private readonly _modelService: IModelService;
|
||||||
|
private readonly _webWorkerService: IWebWorkerService;
|
||||||
private readonly _keepIdleModels: boolean;
|
private readonly _keepIdleModels: boolean;
|
||||||
private _worker: IWebWorkerClient<EditorWorker> | null;
|
private _worker: IWebWorkerClient<EditorWorker> | null;
|
||||||
private _modelManager: WorkerTextModelSyncClient | null;
|
private _modelManager: WorkerTextModelSyncClient | null;
|
||||||
@@ -437,9 +443,11 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien
|
|||||||
private readonly _workerDescriptorOrWorker: WebWorkerDescriptor | Worker | Promise<Worker>,
|
private readonly _workerDescriptorOrWorker: WebWorkerDescriptor | Worker | Promise<Worker>,
|
||||||
keepIdleModels: boolean,
|
keepIdleModels: boolean,
|
||||||
@IModelService modelService: IModelService,
|
@IModelService modelService: IModelService,
|
||||||
|
@IWebWorkerService webWorkerService: IWebWorkerService
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._modelService = modelService;
|
this._modelService = modelService;
|
||||||
|
this._webWorkerService = webWorkerService;
|
||||||
this._keepIdleModels = keepIdleModels;
|
this._keepIdleModels = keepIdleModels;
|
||||||
this._worker = null;
|
this._worker = null;
|
||||||
this._modelManager = null;
|
this._modelManager = null;
|
||||||
@@ -453,7 +461,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien
|
|||||||
private _getOrCreateWorker(): IWebWorkerClient<EditorWorker> {
|
private _getOrCreateWorker(): IWebWorkerClient<EditorWorker> {
|
||||||
if (!this._worker) {
|
if (!this._worker) {
|
||||||
try {
|
try {
|
||||||
this._worker = this._register(createWebWorker<EditorWorker>(this._workerDescriptorOrWorker));
|
this._worker = this._register(this._webWorkerService.createWorkerClient<EditorWorker>(this._workerDescriptorOrWorker));
|
||||||
EditorWorkerHost.setChannel(this._worker, this._createEditorWorkerHost());
|
EditorWorkerHost.setChannel(this._worker, this._createEditorWorkerHost());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logOnceWebWorkerWarning(err);
|
logOnceWebWorkerWarning(err);
|
||||||
|
|||||||
@@ -9,9 +9,6 @@ import { createMonacoEditorAPI } from './standalone/browser/standaloneEditor.js'
|
|||||||
import { createMonacoLanguagesAPI } from './standalone/browser/standaloneLanguages.js';
|
import { createMonacoLanguagesAPI } from './standalone/browser/standaloneLanguages.js';
|
||||||
import { FormattingConflicts } from './contrib/format/browser/format.js';
|
import { FormattingConflicts } from './contrib/format/browser/format.js';
|
||||||
import { getMonacoEnvironment } from '../base/browser/browser.js';
|
import { getMonacoEnvironment } from '../base/browser/browser.js';
|
||||||
import { WebWorkerDescriptor } from '../base/browser/webWorkerFactory.js';
|
|
||||||
|
|
||||||
WebWorkerDescriptor.useBundlerLocationRef();
|
|
||||||
|
|
||||||
// Set defaults for standalone editor
|
// Set defaults for standalone editor
|
||||||
EditorOptions.wrappingIndent.defaultValue = WrappingIndent.None;
|
EditorOptions.wrappingIndent.defaultValue = WrappingIndent.None;
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { getMonacoEnvironment } from '../../../../base/browser/browser.js';
|
||||||
|
import { WebWorkerDescriptor } from '../../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { WebWorkerService } from '../../../../platform/webWorker/browser/webWorkerServiceImpl.js';
|
||||||
|
|
||||||
|
export class StandaloneWebWorkerService extends WebWorkerService {
|
||||||
|
protected override _createWorker(descriptor: WebWorkerDescriptor): Promise<Worker> {
|
||||||
|
const monacoEnvironment = getMonacoEnvironment();
|
||||||
|
if (monacoEnvironment) {
|
||||||
|
if (typeof monacoEnvironment.getWorker === 'function') {
|
||||||
|
const worker = monacoEnvironment.getWorker('workerMain.js', descriptor.label);
|
||||||
|
if (worker !== undefined) {
|
||||||
|
return Promise.resolve(worker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super._createWorker(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override _getUrl(descriptor: WebWorkerDescriptor): string {
|
||||||
|
const monacoEnvironment = getMonacoEnvironment();
|
||||||
|
if (monacoEnvironment) {
|
||||||
|
if (typeof monacoEnvironment.getWorkerUrl === 'function') {
|
||||||
|
const workerUrl = monacoEnvironment.getWorkerUrl('workerMain.js', descriptor.label);
|
||||||
|
if (workerUrl !== undefined) {
|
||||||
|
return workerUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!descriptor.esmModuleLocationBundler) {
|
||||||
|
throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = typeof descriptor.esmModuleLocationBundler === 'function' ? descriptor.esmModuleLocationBundler() : descriptor.esmModuleLocationBundler;
|
||||||
|
const urlStr = url.toString();
|
||||||
|
return urlStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,7 @@ import { IKeybindingService } from '../../../platform/keybinding/common/keybindi
|
|||||||
import { IMarker, IMarkerData, IMarkerService } from '../../../platform/markers/common/markers.js';
|
import { IMarker, IMarkerData, IMarkerService } from '../../../platform/markers/common/markers.js';
|
||||||
import { IOpenerService } from '../../../platform/opener/common/opener.js';
|
import { IOpenerService } from '../../../platform/opener/common/opener.js';
|
||||||
import { MultiDiffEditorWidget } from '../../browser/widget/multiDiffEditor/multiDiffEditorWidget.js';
|
import { MultiDiffEditorWidget } from '../../browser/widget/multiDiffEditor/multiDiffEditorWidget.js';
|
||||||
|
import { IWebWorkerService } from '../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new editor under `domElement`.
|
* Create a new editor under `domElement`.
|
||||||
@@ -332,7 +333,7 @@ export function onDidChangeModelLanguage(listener: (e: { readonly model: ITextMo
|
|||||||
* Specify an AMD module to load that will `create` an object that will be proxied.
|
* Specify an AMD module to load that will `create` an object that will be proxied.
|
||||||
*/
|
*/
|
||||||
export function createWebWorker<T extends object>(opts: IInternalWebWorkerOptions): MonacoWebWorker<T> {
|
export function createWebWorker<T extends object>(opts: IInternalWebWorkerOptions): MonacoWebWorker<T> {
|
||||||
return actualCreateWebWorker<T>(StandaloneServices.get(IModelService), opts);
|
return actualCreateWebWorker<T>(StandaloneServices.get(IModelService), StandaloneServices.get(IWebWorkerService), opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -96,6 +96,8 @@ import { ResourceMap } from '../../../base/common/map.js';
|
|||||||
import { ITreeSitterLibraryService } from '../../common/services/treeSitter/treeSitterLibraryService.js';
|
import { ITreeSitterLibraryService } from '../../common/services/treeSitter/treeSitterLibraryService.js';
|
||||||
import { StandaloneTreeSitterLibraryService } from './standaloneTreeSitterLibraryService.js';
|
import { StandaloneTreeSitterLibraryService } from './standaloneTreeSitterLibraryService.js';
|
||||||
import { IDataChannelService, NullDataChannelService } from '../../../platform/dataChannel/common/dataChannel.js';
|
import { IDataChannelService, NullDataChannelService } from '../../../platform/dataChannel/common/dataChannel.js';
|
||||||
|
import { IWebWorkerService } from '../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
|
import { StandaloneWebWorkerService } from './services/standaloneWebWorkerService.js';
|
||||||
|
|
||||||
class SimpleModel implements IResolvedTextEditorModel {
|
class SimpleModel implements IResolvedTextEditorModel {
|
||||||
|
|
||||||
@@ -1110,6 +1112,7 @@ export interface IEditorOverrideServices {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
registerSingleton(IWebWorkerService, StandaloneWebWorkerService, InstantiationType.Eager);
|
||||||
registerSingleton(ILogService, StandaloneLogService, InstantiationType.Eager);
|
registerSingleton(ILogService, StandaloneLogService, InstantiationType.Eager);
|
||||||
registerSingleton(IConfigurationService, StandaloneConfigurationService, InstantiationType.Eager);
|
registerSingleton(IConfigurationService, StandaloneConfigurationService, InstantiationType.Eager);
|
||||||
registerSingleton(ITextResourceConfigurationService, StandaloneResourceConfigurationService, InstantiationType.Eager);
|
registerSingleton(ITextResourceConfigurationService, StandaloneResourceConfigurationService, InstantiationType.Eager);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { URI } from '../../../base/common/uri.js';
|
import { URI } from '../../../base/common/uri.js';
|
||||||
|
import { IWebWorkerService } from '../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { EditorWorkerClient } from '../../browser/services/editorWorkerService.js';
|
import { EditorWorkerClient } from '../../browser/services/editorWorkerService.js';
|
||||||
import { IModelService } from '../../common/services/model.js';
|
import { IModelService } from '../../common/services/model.js';
|
||||||
|
|
||||||
@@ -11,8 +12,8 @@ import { IModelService } from '../../common/services/model.js';
|
|||||||
* Create a new web worker that has model syncing capabilities built in.
|
* Create a new web worker that has model syncing capabilities built in.
|
||||||
* Specify an AMD module to load that will `create` an object that will be proxied.
|
* Specify an AMD module to load that will `create` an object that will be proxied.
|
||||||
*/
|
*/
|
||||||
export function createWebWorker<T extends object>(modelService: IModelService, opts: IInternalWebWorkerOptions): MonacoWebWorker<T> {
|
export function createWebWorker<T extends object>(modelService: IModelService, webWorkerService: IWebWorkerService, opts: IInternalWebWorkerOptions): MonacoWebWorker<T> {
|
||||||
return new MonacoWebWorkerImpl<T>(modelService, opts);
|
return new MonacoWebWorkerImpl<T>(modelService, webWorkerService, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,8 +56,8 @@ class MonacoWebWorkerImpl<T extends object> extends EditorWorkerClient implement
|
|||||||
private readonly _foreignModuleHost: { [method: string]: Function } | null;
|
private readonly _foreignModuleHost: { [method: string]: Function } | null;
|
||||||
private _foreignProxy: Promise<T>;
|
private _foreignProxy: Promise<T>;
|
||||||
|
|
||||||
constructor(modelService: IModelService, opts: IInternalWebWorkerOptions) {
|
constructor(modelService: IModelService, webWorkerService: IWebWorkerService, opts: IInternalWebWorkerOptions) {
|
||||||
super(opts.worker, opts.keepIdleModels || false, modelService);
|
super(opts.worker, opts.keepIdleModels || false, modelService, webWorkerService);
|
||||||
this._foreignModuleHost = opts.host || null;
|
this._foreignModuleHost = opts.host || null;
|
||||||
this._foreignProxy = this._getProxy().then(proxy => {
|
this._foreignProxy = this._getProxy().then(proxy => {
|
||||||
return new Proxy({}, {
|
return new Proxy({}, {
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../webWorker/browser/webWorkerDescriptor.js';
|
||||||
import { URI } from '../../../base/common/uri.js';
|
import { URI } from '../../../base/common/uri.js';
|
||||||
import { Proxied } from '../../../base/common/worker/webWorker.js';
|
import { Proxied } from '../../../base/common/worker/webWorker.js';
|
||||||
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
|
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
|
||||||
import { createDecorator } from '../../instantiation/common/instantiation.js';
|
import { createDecorator } from '../../instantiation/common/instantiation.js';
|
||||||
|
import { IWebWorkerService } from '../../webWorker/browser/webWorkerService.js';
|
||||||
import { ILogService } from '../../log/common/log.js';
|
import { ILogService } from '../../log/common/log.js';
|
||||||
import { IV8Profile } from '../common/profiling.js';
|
import { IV8Profile } from '../common/profiling.js';
|
||||||
import { BottomUpSample } from '../common/profilingModel.js';
|
import { BottomUpSample } from '../common/profilingModel.js';
|
||||||
@@ -44,11 +45,12 @@ class ProfileAnalysisWorkerService implements IProfileAnalysisWorkerService {
|
|||||||
constructor(
|
constructor(
|
||||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||||
@ILogService private readonly _logService: ILogService,
|
@ILogService private readonly _logService: ILogService,
|
||||||
|
@IWebWorkerService private readonly _webWorkerService: IWebWorkerService,
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
private async _withWorker<R>(callback: (worker: Proxied<IProfileAnalysisWorker>) => Promise<R>): Promise<R> {
|
private async _withWorker<R>(callback: (worker: Proxied<IProfileAnalysisWorker>) => Promise<R>): Promise<R> {
|
||||||
|
|
||||||
const worker = createWebWorker<IProfileAnalysisWorker>(
|
const worker = this._webWorkerService.createWorkerClient<IProfileAnalysisWorker>(
|
||||||
new WebWorkerDescriptor({
|
new WebWorkerDescriptor({
|
||||||
esmModuleLocation: FileAccess.asBrowserUri('vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.js'),
|
esmModuleLocation: FileAccess.asBrowserUri('vs/platform/profiling/electron-browser/profileAnalysisWorkerMain.js'),
|
||||||
label: 'CpuProfileAnalysisWorker'
|
label: 'CpuProfileAnalysisWorker'
|
||||||
|
|||||||
24
src/vs/platform/webWorker/browser/webWorkerDescriptor.ts
Normal file
24
src/vs/platform/webWorker/browser/webWorkerDescriptor.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { URI } from '../../../base/common/uri.js';
|
||||||
|
|
||||||
|
export class WebWorkerDescriptor {
|
||||||
|
public readonly esmModuleLocation: URI | (() => URI) | undefined;
|
||||||
|
public readonly esmModuleLocationBundler: URL | (() => URL) | undefined;
|
||||||
|
public readonly label: string;
|
||||||
|
|
||||||
|
constructor(args: {
|
||||||
|
/** The location of the esm module after transpilation */
|
||||||
|
esmModuleLocation?: URI | (() => URI);
|
||||||
|
/** The location of the esm module when used in a bundler environment. Refer to the typescript file in the src folder and use `?worker`. */
|
||||||
|
esmModuleLocationBundler?: URL | (() => URL);
|
||||||
|
label: string;
|
||||||
|
}) {
|
||||||
|
this.esmModuleLocation = args.esmModuleLocation;
|
||||||
|
this.esmModuleLocationBundler = args.esmModuleLocationBundler;
|
||||||
|
this.label = args.label;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/vs/platform/webWorker/browser/webWorkerService.ts
Normal file
16
src/vs/platform/webWorker/browser/webWorkerService.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { createDecorator } from '../../instantiation/common/instantiation.js';
|
||||||
|
import { IWebWorkerClient } from '../../../base/common/worker/webWorker.js';
|
||||||
|
import { WebWorkerDescriptor } from './webWorkerDescriptor.js';
|
||||||
|
|
||||||
|
export const IWebWorkerService = createDecorator<IWebWorkerService>('IWebWorkerService');
|
||||||
|
|
||||||
|
export interface IWebWorkerService {
|
||||||
|
readonly _serviceBrand: undefined;
|
||||||
|
|
||||||
|
createWorkerClient<T extends object>(workerDescriptor: WebWorkerDescriptor | Worker | Promise<Worker>): IWebWorkerClient<T>;
|
||||||
|
}
|
||||||
181
src/vs/platform/webWorker/browser/webWorkerServiceImpl.ts
Normal file
181
src/vs/platform/webWorker/browser/webWorkerServiceImpl.ts
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { createTrustedTypesPolicy } from '../../../base/browser/trustedTypes.js';
|
||||||
|
import { coalesce } from '../../../base/common/arrays.js';
|
||||||
|
import { onUnexpectedError } from '../../../base/common/errors.js';
|
||||||
|
import { Emitter } from '../../../base/common/event.js';
|
||||||
|
import { Disposable, toDisposable } from '../../../base/common/lifecycle.js';
|
||||||
|
import { COI } from '../../../base/common/network.js';
|
||||||
|
import { IWebWorker, IWebWorkerClient, Message, WebWorkerClient } from '../../../base/common/worker/webWorker.js';
|
||||||
|
import { getNLSLanguage, getNLSMessages } from '../../../nls.js';
|
||||||
|
import { WebWorkerDescriptor } from './webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from './webWorkerService.js';
|
||||||
|
|
||||||
|
export class WebWorkerService implements IWebWorkerService {
|
||||||
|
private static _workerIdPool: number = 0;
|
||||||
|
declare readonly _serviceBrand: undefined;
|
||||||
|
|
||||||
|
createWorkerClient<T extends object>(workerDescriptor: WebWorkerDescriptor | Worker | Promise<Worker>): IWebWorkerClient<T> {
|
||||||
|
let worker: Worker | Promise<Worker>;
|
||||||
|
const id = ++WebWorkerService._workerIdPool;
|
||||||
|
if (workerDescriptor instanceof Worker || isPromiseLike<Worker>(workerDescriptor)) {
|
||||||
|
worker = Promise.resolve(workerDescriptor);
|
||||||
|
} else {
|
||||||
|
worker = this._createWorker(workerDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WebWorkerClient<T>(new WebWorker(worker, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected _createWorker(descriptor: WebWorkerDescriptor): Promise<Worker> {
|
||||||
|
const workerRunnerUrl = this._getUrl(descriptor);
|
||||||
|
|
||||||
|
const workerUrl = getWorkerBootstrapUrl(descriptor.label, workerRunnerUrl);
|
||||||
|
const worker = new Worker(ttPolicy ? ttPolicy.createScriptURL(workerUrl) as unknown as string : workerUrl, { name: descriptor.label, type: 'module' });
|
||||||
|
return whenESMWorkerReady(worker);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected _getUrl(descriptor: WebWorkerDescriptor): string {
|
||||||
|
if (!descriptor.esmModuleLocation) {
|
||||||
|
throw new Error('Missing esmModuleLocation in WebWorkerDescriptor');
|
||||||
|
}
|
||||||
|
const uri = typeof descriptor.esmModuleLocation === 'function' ? descriptor.esmModuleLocation() : descriptor.esmModuleLocation;
|
||||||
|
const urlStr = uri.toString(true);
|
||||||
|
return urlStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ttPolicy = ((): ReturnType<typeof createTrustedTypesPolicy> => {
|
||||||
|
type WorkerGlobalWithPolicy = typeof globalThis & {
|
||||||
|
workerttPolicy?: ReturnType<typeof createTrustedTypesPolicy>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reuse the trusted types policy defined from worker bootstrap
|
||||||
|
// when available.
|
||||||
|
// Refs https://github.com/microsoft/vscode/issues/222193
|
||||||
|
const workerGlobalThis = globalThis as WorkerGlobalWithPolicy;
|
||||||
|
if (typeof self === 'object' && self.constructor && self.constructor.name === 'DedicatedWorkerGlobalScope' && workerGlobalThis.workerttPolicy !== undefined) {
|
||||||
|
return workerGlobalThis.workerttPolicy;
|
||||||
|
} else {
|
||||||
|
return createTrustedTypesPolicy('defaultWorkerFactory', { createScriptURL: value => value });
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
export function createBlobWorker(blobUrl: string, options?: WorkerOptions): Worker {
|
||||||
|
if (!blobUrl.startsWith('blob:')) {
|
||||||
|
throw new URIError('Not a blob-url: ' + blobUrl);
|
||||||
|
}
|
||||||
|
return new Worker(ttPolicy ? ttPolicy.createScriptURL(blobUrl) as unknown as string : blobUrl, { ...options, type: 'module' });
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorkerBootstrapUrl(label: string, workerScriptUrl: string): string {
|
||||||
|
if (/^((http:)|(https:)|(file:))/.test(workerScriptUrl) && workerScriptUrl.substring(0, globalThis.origin.length) !== globalThis.origin) {
|
||||||
|
// this is the cross-origin case
|
||||||
|
// i.e. the webpage is running at a different origin than where the scripts are loaded from
|
||||||
|
} else {
|
||||||
|
const start = workerScriptUrl.lastIndexOf('?');
|
||||||
|
const end = workerScriptUrl.lastIndexOf('#', start);
|
||||||
|
const params = start > 0
|
||||||
|
? new URLSearchParams(workerScriptUrl.substring(start + 1, ~end ? end : undefined))
|
||||||
|
: new URLSearchParams();
|
||||||
|
|
||||||
|
COI.addSearchParam(params, true, true);
|
||||||
|
const search = params.toString();
|
||||||
|
if (!search) {
|
||||||
|
workerScriptUrl = `${workerScriptUrl}#${label}`;
|
||||||
|
} else {
|
||||||
|
workerScriptUrl = `${workerScriptUrl}?${params.toString()}#${label}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In below blob code, we are using JSON.stringify to ensure the passed
|
||||||
|
// in values are not breaking our script. The values may contain string
|
||||||
|
// terminating characters (such as ' or ").
|
||||||
|
const blob = new Blob([coalesce([
|
||||||
|
`/*${label}*/`,
|
||||||
|
`globalThis._VSCODE_NLS_MESSAGES = ${JSON.stringify(getNLSMessages())};`,
|
||||||
|
`globalThis._VSCODE_NLS_LANGUAGE = ${JSON.stringify(getNLSLanguage())};`,
|
||||||
|
`globalThis._VSCODE_FILE_ROOT = ${JSON.stringify(globalThis._VSCODE_FILE_ROOT)};`,
|
||||||
|
`const ttPolicy = globalThis.trustedTypes?.createPolicy('defaultWorkerFactory', { createScriptURL: value => value });`,
|
||||||
|
`globalThis.workerttPolicy = ttPolicy;`,
|
||||||
|
`await import(ttPolicy?.createScriptURL(${JSON.stringify(workerScriptUrl)}) ?? ${JSON.stringify(workerScriptUrl)});`,
|
||||||
|
`globalThis.postMessage({ type: 'vscode-worker-ready' });`,
|
||||||
|
`/*${label}*/`
|
||||||
|
]).join('')], { type: 'application/javascript' });
|
||||||
|
return URL.createObjectURL(blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
function whenESMWorkerReady(worker: Worker): Promise<Worker> {
|
||||||
|
return new Promise<Worker>((resolve, reject) => {
|
||||||
|
worker.onmessage = function (e) {
|
||||||
|
if (e.data.type === 'vscode-worker-ready') {
|
||||||
|
worker.onmessage = null;
|
||||||
|
resolve(worker);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
worker.onerror = reject;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function isPromiseLike<T>(obj: unknown): obj is PromiseLike<T> {
|
||||||
|
return !!obj && typeof (obj as PromiseLike<T>).then === 'function';
|
||||||
|
}
|
||||||
|
|
||||||
|
export class WebWorker extends Disposable implements IWebWorker {
|
||||||
|
private readonly id: number;
|
||||||
|
private worker: Promise<Worker> | null;
|
||||||
|
|
||||||
|
private readonly _onMessage = this._register(new Emitter<Message>());
|
||||||
|
public readonly onMessage = this._onMessage.event;
|
||||||
|
|
||||||
|
private readonly _onError = this._register(new Emitter<MessageEvent | ErrorEvent>());
|
||||||
|
public readonly onError = this._onError.event;
|
||||||
|
|
||||||
|
constructor(worker: Promise<Worker>, id: number) {
|
||||||
|
super();
|
||||||
|
this.id = id;
|
||||||
|
this.worker = worker;
|
||||||
|
this.postMessage('-please-ignore-', []); // TODO: Eliminate this extra message
|
||||||
|
const errorHandler = (ev: ErrorEvent) => {
|
||||||
|
this._onError.fire(ev);
|
||||||
|
};
|
||||||
|
this.worker.then((w) => {
|
||||||
|
w.onmessage = (ev) => {
|
||||||
|
this._onMessage.fire(ev.data);
|
||||||
|
};
|
||||||
|
w.onmessageerror = (ev) => {
|
||||||
|
this._onError.fire(ev);
|
||||||
|
};
|
||||||
|
if (typeof w.addEventListener === 'function') {
|
||||||
|
w.addEventListener('error', errorHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._register(toDisposable(() => {
|
||||||
|
this.worker?.then(w => {
|
||||||
|
w.onmessage = null;
|
||||||
|
w.onmessageerror = null;
|
||||||
|
w.removeEventListener('error', errorHandler);
|
||||||
|
w.terminate();
|
||||||
|
});
|
||||||
|
this.worker = null;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public getId(): number {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public postMessage(message: unknown, transfer: Transferable[]): void {
|
||||||
|
this.worker?.then(w => {
|
||||||
|
try {
|
||||||
|
w.postMessage(message, transfer);
|
||||||
|
} catch (err) {
|
||||||
|
onUnexpectedError(err);
|
||||||
|
onUnexpectedError(new Error(`FAILED to post message to worker`, { cause: err }));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,8 @@
|
|||||||
import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';
|
import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from '../../../../../base/common/lifecycle.js';
|
||||||
import { URI } from '../../../../../base/common/uri.js';
|
import { URI } from '../../../../../base/common/uri.js';
|
||||||
import { IWebWorkerClient, Proxied } from '../../../../../base/common/worker/webWorker.js';
|
import { IWebWorkerClient, Proxied } from '../../../../../base/common/worker/webWorker.js';
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from '../../../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { NotebookCellTextModel } from '../../common/model/notebookCellTextModel.js';
|
import { NotebookCellTextModel } from '../../common/model/notebookCellTextModel.js';
|
||||||
import { CellUri, IMainCellDto, INotebookDiffResult, NotebookCellsChangeType, NotebookRawContentEventDto } from '../../common/notebookCommon.js';
|
import { CellUri, IMainCellDto, INotebookDiffResult, NotebookCellsChangeType, NotebookRawContentEventDto } from '../../common/notebookCommon.js';
|
||||||
import { INotebookService } from '../../common/notebookService.js';
|
import { INotebookService } from '../../common/notebookService.js';
|
||||||
@@ -26,10 +27,11 @@ export class NotebookEditorWorkerServiceImpl extends Disposable implements INote
|
|||||||
constructor(
|
constructor(
|
||||||
@INotebookService notebookService: INotebookService,
|
@INotebookService notebookService: INotebookService,
|
||||||
@IModelService modelService: IModelService,
|
@IModelService modelService: IModelService,
|
||||||
|
@IWebWorkerService webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._workerManager = this._register(new WorkerManager(notebookService, modelService));
|
this._workerManager = this._register(new WorkerManager(notebookService, modelService, webWorkerService));
|
||||||
}
|
}
|
||||||
canComputeDiff(original: URI, modified: URI): boolean {
|
canComputeDiff(original: URI, modified: URI): boolean {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
@@ -55,6 +57,7 @@ class WorkerManager extends Disposable {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly _notebookService: INotebookService,
|
private readonly _notebookService: INotebookService,
|
||||||
private readonly _modelService: IModelService,
|
private readonly _modelService: IModelService,
|
||||||
|
private readonly _webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._editorWorkerClient = null;
|
this._editorWorkerClient = null;
|
||||||
@@ -64,7 +67,7 @@ class WorkerManager extends Disposable {
|
|||||||
withWorker(): Promise<NotebookWorkerClient> {
|
withWorker(): Promise<NotebookWorkerClient> {
|
||||||
// this._lastWorkerUsedTime = (new Date()).getTime();
|
// this._lastWorkerUsedTime = (new Date()).getTime();
|
||||||
if (!this._editorWorkerClient) {
|
if (!this._editorWorkerClient) {
|
||||||
this._editorWorkerClient = new NotebookWorkerClient(this._notebookService, this._modelService);
|
this._editorWorkerClient = new NotebookWorkerClient(this._notebookService, this._modelService, this._webWorkerService);
|
||||||
this._register(this._editorWorkerClient);
|
this._register(this._editorWorkerClient);
|
||||||
}
|
}
|
||||||
return Promise.resolve(this._editorWorkerClient);
|
return Promise.resolve(this._editorWorkerClient);
|
||||||
@@ -240,7 +243,11 @@ class NotebookWorkerClient extends Disposable {
|
|||||||
private _modelManager: NotebookEditorModelManager | null;
|
private _modelManager: NotebookEditorModelManager | null;
|
||||||
|
|
||||||
|
|
||||||
constructor(private readonly _notebookService: INotebookService, private readonly _modelService: IModelService) {
|
constructor(
|
||||||
|
private readonly _notebookService: INotebookService,
|
||||||
|
private readonly _modelService: IModelService,
|
||||||
|
private readonly _webWorkerService: IWebWorkerService,
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this._worker = null;
|
this._worker = null;
|
||||||
this._modelManager = null;
|
this._modelManager = null;
|
||||||
@@ -273,7 +280,7 @@ class NotebookWorkerClient extends Disposable {
|
|||||||
private _getOrCreateWorker(): IWebWorkerClient<NotebookWorker> {
|
private _getOrCreateWorker(): IWebWorkerClient<NotebookWorker> {
|
||||||
if (!this._worker) {
|
if (!this._worker) {
|
||||||
try {
|
try {
|
||||||
this._worker = this._register(createWebWorker<NotebookWorker>(
|
this._worker = this._register(this._webWorkerService.createWorkerClient<NotebookWorker>(
|
||||||
new WebWorkerDescriptor({
|
new WebWorkerDescriptor({
|
||||||
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/contrib/notebook/common/services/notebookWebWorkerMain.js'),
|
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/contrib/notebook/common/services/notebookWebWorkerMain.js'),
|
||||||
label: 'NotebookEditorWorker'
|
label: 'NotebookEditorWorker'
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ import { OUTPUT_MODE_ID, LOG_MODE_ID } from '../../../services/output/common/out
|
|||||||
import { OutputLinkComputer } from '../common/outputLinkComputer.js';
|
import { OutputLinkComputer } from '../common/outputLinkComputer.js';
|
||||||
import { IDisposable, dispose, Disposable } from '../../../../base/common/lifecycle.js';
|
import { IDisposable, dispose, Disposable } from '../../../../base/common/lifecycle.js';
|
||||||
import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js';
|
import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js';
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from '../../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { IWebWorkerClient } from '../../../../base/common/worker/webWorker.js';
|
import { IWebWorkerClient } from '../../../../base/common/worker/webWorker.js';
|
||||||
import { WorkerTextModelSyncClient } from '../../../../editor/common/services/textModelSync/textModelSync.impl.js';
|
import { WorkerTextModelSyncClient } from '../../../../editor/common/services/textModelSync/textModelSync.impl.js';
|
||||||
import { FileAccess } from '../../../../base/common/network.js';
|
import { FileAccess } from '../../../../base/common/network.js';
|
||||||
@@ -29,6 +30,7 @@ export class OutputLinkProvider extends Disposable {
|
|||||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||||
@IModelService private readonly modelService: IModelService,
|
@IModelService private readonly modelService: IModelService,
|
||||||
@ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService,
|
@ILanguageFeaturesService private readonly languageFeaturesService: ILanguageFeaturesService,
|
||||||
|
@IWebWorkerService private readonly webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@@ -70,7 +72,7 @@ export class OutputLinkProvider extends Disposable {
|
|||||||
this.disposeWorkerScheduler.schedule();
|
this.disposeWorkerScheduler.schedule();
|
||||||
|
|
||||||
if (!this.worker) {
|
if (!this.worker) {
|
||||||
this.worker = new OutputLinkWorkerClient(this.contextService, this.modelService);
|
this.worker = new OutputLinkWorkerClient(this.contextService, this.modelService, this.webWorkerService);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.worker;
|
return this.worker;
|
||||||
@@ -96,9 +98,10 @@ class OutputLinkWorkerClient extends Disposable {
|
|||||||
constructor(
|
constructor(
|
||||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||||
@IModelService modelService: IModelService,
|
@IModelService modelService: IModelService,
|
||||||
|
@IWebWorkerService webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._workerClient = this._register(createWebWorker<OutputLinkComputer>(
|
this._workerClient = this._register(webWorkerService.createWorkerClient<OutputLinkComputer>(
|
||||||
new WebWorkerDescriptor({
|
new WebWorkerDescriptor({
|
||||||
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/contrib/output/common/outputLinkComputerMain.js'),
|
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/contrib/output/common/outputLinkComputerMain.js'),
|
||||||
label: 'OutputLinkDetectionWorker'
|
label: 'OutputLinkDetectionWorker'
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import { IStorageService, StorageScope, StorageTarget } from '../../../../platfo
|
|||||||
import { LRUCache } from '../../../../base/common/map.js';
|
import { LRUCache } from '../../../../base/common/map.js';
|
||||||
import { ILogService } from '../../../../platform/log/common/log.js';
|
import { ILogService } from '../../../../platform/log/common/log.js';
|
||||||
import { canASAR } from '../../../../amdX.js';
|
import { canASAR } from '../../../../amdX.js';
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from '../../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { WorkerTextModelSyncClient } from '../../../../editor/common/services/textModelSync/textModelSync.impl.js';
|
import { WorkerTextModelSyncClient } from '../../../../editor/common/services/textModelSync/textModelSync.impl.js';
|
||||||
import { ILanguageDetectionWorker, LanguageDetectionWorkerHost } from './languageDetectionWorker.protocol.js';
|
import { ILanguageDetectionWorker, LanguageDetectionWorkerHost } from './languageDetectionWorker.protocol.js';
|
||||||
|
|
||||||
@@ -62,7 +63,8 @@ export class LanguageDetectionService extends Disposable implements ILanguageDet
|
|||||||
@IEditorService private readonly _editorService: IEditorService,
|
@IEditorService private readonly _editorService: IEditorService,
|
||||||
@ITelemetryService telemetryService: ITelemetryService,
|
@ITelemetryService telemetryService: ITelemetryService,
|
||||||
@IStorageService storageService: IStorageService,
|
@IStorageService storageService: IStorageService,
|
||||||
@ILogService private readonly _logService: ILogService
|
@ILogService private readonly _logService: ILogService,
|
||||||
|
@IWebWorkerService webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
@@ -71,6 +73,7 @@ export class LanguageDetectionService extends Disposable implements ILanguageDet
|
|||||||
modelService,
|
modelService,
|
||||||
languageService,
|
languageService,
|
||||||
telemetryService,
|
telemetryService,
|
||||||
|
webWorkerService,
|
||||||
// TODO See if it's possible to bundle vscode-languagedetection
|
// TODO See if it's possible to bundle vscode-languagedetection
|
||||||
useAsar
|
useAsar
|
||||||
? FileAccess.asBrowserUri(`${moduleLocationAsar}/dist/lib/index.js`).toString(true)
|
? FileAccess.asBrowserUri(`${moduleLocationAsar}/dist/lib/index.js`).toString(true)
|
||||||
@@ -187,6 +190,7 @@ export class LanguageDetectionWorkerClient extends Disposable {
|
|||||||
private readonly _modelService: IModelService,
|
private readonly _modelService: IModelService,
|
||||||
private readonly _languageService: ILanguageService,
|
private readonly _languageService: ILanguageService,
|
||||||
private readonly _telemetryService: ITelemetryService,
|
private readonly _telemetryService: ITelemetryService,
|
||||||
|
private readonly _webWorkerService: IWebWorkerService,
|
||||||
private readonly _indexJsUri: string,
|
private readonly _indexJsUri: string,
|
||||||
private readonly _modelJsonUri: string,
|
private readonly _modelJsonUri: string,
|
||||||
private readonly _weightsUri: string,
|
private readonly _weightsUri: string,
|
||||||
@@ -200,7 +204,7 @@ export class LanguageDetectionWorkerClient extends Disposable {
|
|||||||
workerTextModelSyncClient: WorkerTextModelSyncClient;
|
workerTextModelSyncClient: WorkerTextModelSyncClient;
|
||||||
} {
|
} {
|
||||||
if (!this.worker) {
|
if (!this.worker) {
|
||||||
const workerClient = this._register(createWebWorker<ILanguageDetectionWorker>(
|
const workerClient = this._register(this._webWorkerService.createWorkerClient<ILanguageDetectionWorker>(
|
||||||
new WebWorkerDescriptor({
|
new WebWorkerDescriptor({
|
||||||
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.js'),
|
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/languageDetection/browser/languageDetectionWebWorkerMain.js'),
|
||||||
label: 'LanguageDetectionWorker'
|
label: 'LanguageDetectionWorker'
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { SearchService } from '../common/searchService.js';
|
|||||||
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
|
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
|
||||||
import { IWebWorkerClient, logOnceWebWorkerWarning } from '../../../../base/common/worker/webWorker.js';
|
import { IWebWorkerClient, logOnceWebWorkerWarning } from '../../../../base/common/worker/webWorker.js';
|
||||||
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
|
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from '../../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||||
import { ILocalFileSearchWorker, LocalFileSearchWorkerHost } from '../common/localFileSearchWorkerTypes.js';
|
import { ILocalFileSearchWorker, LocalFileSearchWorkerHost } from '../common/localFileSearchWorkerTypes.js';
|
||||||
import { memoize } from '../../../../base/common/decorators.js';
|
import { memoize } from '../../../../base/common/decorators.js';
|
||||||
@@ -60,6 +61,7 @@ export class LocalFileSearchWorkerClient extends Disposable implements ISearchRe
|
|||||||
constructor(
|
constructor(
|
||||||
@IFileService private fileService: IFileService,
|
@IFileService private fileService: IFileService,
|
||||||
@IUriIdentityService private uriIdentityService: IUriIdentityService,
|
@IUriIdentityService private uriIdentityService: IUriIdentityService,
|
||||||
|
@IWebWorkerService private webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
this._worker = null;
|
this._worker = null;
|
||||||
@@ -187,7 +189,7 @@ export class LocalFileSearchWorkerClient extends Disposable implements ISearchRe
|
|||||||
private _getOrCreateWorker(): IWebWorkerClient<ILocalFileSearchWorker> {
|
private _getOrCreateWorker(): IWebWorkerClient<ILocalFileSearchWorker> {
|
||||||
if (!this._worker) {
|
if (!this._worker) {
|
||||||
try {
|
try {
|
||||||
this._worker = this._register(createWebWorker<ILocalFileSearchWorker>(
|
this._worker = this._register(this.webWorkerService.createWorkerClient<ILocalFileSearchWorker>(
|
||||||
new WebWorkerDescriptor({
|
new WebWorkerDescriptor({
|
||||||
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/search/worker/localFileSearchMain.js'),
|
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/search/worker/localFileSearchMain.js'),
|
||||||
label: 'LocalFileSearchWorker'
|
label: 'LocalFileSearchWorker'
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ import { TextMateWorkerHost } from './worker/textMateWorkerHost.js';
|
|||||||
import { TextMateWorkerTokenizerController } from './textMateWorkerTokenizerController.js';
|
import { TextMateWorkerTokenizerController } from './textMateWorkerTokenizerController.js';
|
||||||
import { IValidGrammarDefinition } from '../../common/TMScopeRegistry.js';
|
import { IValidGrammarDefinition } from '../../common/TMScopeRegistry.js';
|
||||||
import type { IRawTheme } from 'vscode-textmate';
|
import type { IRawTheme } from 'vscode-textmate';
|
||||||
import { createWebWorker, WebWorkerDescriptor } from '../../../../../base/browser/webWorkerFactory.js';
|
import { WebWorkerDescriptor } from '../../../../../platform/webWorker/browser/webWorkerDescriptor.js';
|
||||||
|
import { IWebWorkerService } from '../../../../../platform/webWorker/browser/webWorkerService.js';
|
||||||
import { IWebWorkerClient, Proxied } from '../../../../../base/common/worker/webWorker.js';
|
import { IWebWorkerClient, Proxied } from '../../../../../base/common/worker/webWorker.js';
|
||||||
|
|
||||||
export class ThreadedBackgroundTokenizerFactory implements IDisposable {
|
export class ThreadedBackgroundTokenizerFactory implements IDisposable {
|
||||||
@@ -46,6 +47,7 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable {
|
|||||||
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
|
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
|
||||||
@INotificationService private readonly _notificationService: INotificationService,
|
@INotificationService private readonly _notificationService: INotificationService,
|
||||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||||
|
@IWebWorkerService private readonly _webWorkerService: IWebWorkerService,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,7 +139,7 @@ export class ThreadedBackgroundTokenizerFactory implements IDisposable {
|
|||||||
grammarDefinitions: this._grammarDefinitions,
|
grammarDefinitions: this._grammarDefinitions,
|
||||||
onigurumaWASMUri: FileAccess.asBrowserUri(onigurumaWASM).toString(true),
|
onigurumaWASMUri: FileAccess.asBrowserUri(onigurumaWASM).toString(true),
|
||||||
};
|
};
|
||||||
const worker = this._worker = createWebWorker<TextMateTokenizationWorker>(
|
const worker = this._worker = this._webWorkerService.createWorkerClient<TextMateTokenizationWorker>(
|
||||||
new WebWorkerDescriptor({
|
new WebWorkerDescriptor({
|
||||||
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.js'),
|
esmModuleLocation: FileAccess.asBrowserUri('vs/workbench/services/textMate/browser/backgroundTokenization/worker/textMateTokenizationWorker.workerMain.js'),
|
||||||
label: 'TextMateWorker'
|
label: 'TextMateWorker'
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { IPaneCompositePartService } from '../../panecomposite/browser/panecompo
|
|||||||
import { ViewContainerLocation } from '../../../common/views.js';
|
import { ViewContainerLocation } from '../../../common/views.js';
|
||||||
import { TelemetryTrustedValue } from '../../../../platform/telemetry/common/telemetryUtils.js';
|
import { TelemetryTrustedValue } from '../../../../platform/telemetry/common/telemetryUtils.js';
|
||||||
import { isWeb } from '../../../../base/common/platform.js';
|
import { isWeb } from '../../../../base/common/platform.js';
|
||||||
import { createBlobWorker } from '../../../../base/browser/webWorkerFactory.js';
|
import { createBlobWorker } from '../../../../platform/webWorker/browser/webWorkerServiceImpl.js';
|
||||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||||
import { ITerminalBackendRegistry, TerminalExtensions } from '../../../../platform/terminal/common/terminal.js';
|
import { ITerminalBackendRegistry, TerminalExtensions } from '../../../../platform/terminal/common/terminal.js';
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ import { AllowedExtensionsService } from '../platform/extensionManagement/common
|
|||||||
import { IAllowedMcpServersService, IMcpGalleryService } from '../platform/mcp/common/mcpManagement.js';
|
import { IAllowedMcpServersService, IMcpGalleryService } from '../platform/mcp/common/mcpManagement.js';
|
||||||
import { McpGalleryService } from '../platform/mcp/common/mcpGalleryService.js';
|
import { McpGalleryService } from '../platform/mcp/common/mcpGalleryService.js';
|
||||||
import { AllowedMcpServersService } from '../platform/mcp/common/allowedMcpServersService.js';
|
import { AllowedMcpServersService } from '../platform/mcp/common/allowedMcpServersService.js';
|
||||||
|
import { IWebWorkerService } from '../platform/webWorker/browser/webWorkerService.js';
|
||||||
|
import { WebWorkerService } from '../platform/webWorker/browser/webWorkerServiceImpl.js';
|
||||||
|
|
||||||
registerSingleton(IUserDataSyncLogService, UserDataSyncLogService, InstantiationType.Delayed);
|
registerSingleton(IUserDataSyncLogService, UserDataSyncLogService, InstantiationType.Delayed);
|
||||||
registerSingleton(IAllowedExtensionsService, AllowedExtensionsService, InstantiationType.Delayed);
|
registerSingleton(IAllowedExtensionsService, AllowedExtensionsService, InstantiationType.Delayed);
|
||||||
@@ -173,6 +175,7 @@ registerSingleton(IContextKeyService, ContextKeyService, InstantiationType.Delay
|
|||||||
registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService, InstantiationType.Delayed);
|
registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationService, InstantiationType.Delayed);
|
||||||
registerSingleton(IDownloadService, DownloadService, InstantiationType.Delayed);
|
registerSingleton(IDownloadService, DownloadService, InstantiationType.Delayed);
|
||||||
registerSingleton(IOpenerService, OpenerService, InstantiationType.Delayed);
|
registerSingleton(IOpenerService, OpenerService, InstantiationType.Delayed);
|
||||||
|
registerSingleton(IWebWorkerService, WebWorkerService, InstantiationType.Delayed);
|
||||||
registerSingleton(IMcpGalleryService, McpGalleryService, InstantiationType.Delayed);
|
registerSingleton(IMcpGalleryService, McpGalleryService, InstantiationType.Delayed);
|
||||||
registerSingleton(IAllowedMcpServersService, AllowedMcpServersService, InstantiationType.Delayed);
|
registerSingleton(IAllowedMcpServersService, AllowedMcpServersService, InstantiationType.Delayed);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user