Path: blob/main/src/vs/editor/standalone/browser/standaloneWebWorker.ts
5241 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { URI } from '../../../base/common/uri.js';6import { IWebWorkerService } from '../../../platform/webWorker/browser/webWorkerService.js';7import { EditorWorkerClient } from '../../browser/services/editorWorkerService.js';8import { IModelService } from '../../common/services/model.js';910/**11* Create a new web worker that has model syncing capabilities built in.12* Specify an AMD module to load that will `create` an object that will be proxied.13*/14export function createWebWorker<T extends object>(modelService: IModelService, webWorkerService: IWebWorkerService, opts: IInternalWebWorkerOptions): MonacoWebWorker<T> {15return new MonacoWebWorkerImpl<T>(modelService, webWorkerService, opts);16}1718/**19* A web worker that can provide a proxy to an arbitrary file.20*/21export interface MonacoWebWorker<T> {22/**23* Terminate the web worker, thus invalidating the returned proxy.24*/25dispose(): void;26/**27* Get a proxy to the arbitrary loaded code.28*/29getProxy(): Promise<T>;30/**31* Synchronize (send) the models at `resources` to the web worker,32* making them available in the monaco.worker.getMirrorModels().33*/34withSyncedResources(resources: URI[]): Promise<T>;35}3637export interface IInternalWebWorkerOptions {38/**39* The worker.40*/41worker: Worker | Promise<Worker>;42/**43* An object that can be used by the web worker to make calls back to the main thread.44*/45host?: Record<string, Function>;46/**47* Keep idle models.48* Defaults to false, which means that idle models will stop syncing after a while.49*/50keepIdleModels?: boolean;51}5253class MonacoWebWorkerImpl<T extends object> extends EditorWorkerClient implements MonacoWebWorker<T> {5455private readonly _foreignModuleHost: { [method: string]: Function } | null;56private _foreignProxy: Promise<T>;5758constructor(modelService: IModelService, webWorkerService: IWebWorkerService, opts: IInternalWebWorkerOptions) {59super(opts.worker, opts.keepIdleModels || false, modelService, webWorkerService);60this._foreignModuleHost = opts.host || null;61this._foreignProxy = this._getProxy().then(proxy => {62return new Proxy({}, {63get(target, prop, receiver) {64if (prop === 'then') {65// Don't forward the call when the proxy is returned in an async function and the runtime tries to .then it.66return undefined;67}68if (typeof prop !== 'string') {69throw new Error(`Not supported`);70}71return (...args: unknown[]) => {72return proxy.$fmr(prop, args);73};74}75}) as T;76});77}7879// foreign host request80public override fhr(method: string, args: unknown[]): Promise<unknown> {81if (!this._foreignModuleHost || typeof this._foreignModuleHost[method] !== 'function') {82return Promise.reject(new Error('Missing method ' + method + ' or missing main thread foreign host.'));83}8485try {86return Promise.resolve(this._foreignModuleHost[method].apply(this._foreignModuleHost, args));87} catch (e) {88return Promise.reject(e);89}90}9192public getProxy(): Promise<T> {93return this._foreignProxy;94}9596public withSyncedResources(resources: URI[]): Promise<T> {97return this.workerWithSyncedResources(resources).then(_ => this.getProxy());98}99}100101102