Path: blob/main/src/vs/editor/standalone/browser/standaloneWebWorker.ts
3294 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 { EditorWorkerClient } from '../../browser/services/editorWorkerService.js';7import { IModelService } from '../../common/services/model.js';89/**10* Create a new web worker that has model syncing capabilities built in.11* Specify an AMD module to load that will `create` an object that will be proxied.12*/13export function createWebWorker<T extends object>(modelService: IModelService, opts: IInternalWebWorkerOptions): MonacoWebWorker<T> {14return new MonacoWebWorkerImpl<T>(modelService, opts);15}1617/**18* A web worker that can provide a proxy to an arbitrary file.19*/20export interface MonacoWebWorker<T> {21/**22* Terminate the web worker, thus invalidating the returned proxy.23*/24dispose(): void;25/**26* Get a proxy to the arbitrary loaded code.27*/28getProxy(): Promise<T>;29/**30* Synchronize (send) the models at `resources` to the web worker,31* making them available in the monaco.worker.getMirrorModels().32*/33withSyncedResources(resources: URI[]): Promise<T>;34}3536export interface IInternalWebWorkerOptions {37/**38* The worker.39*/40worker: Worker | Promise<Worker>;41/**42* An object that can be used by the web worker to make calls back to the main thread.43*/44host?: any;45/**46* Keep idle models.47* Defaults to false, which means that idle models will stop syncing after a while.48*/49keepIdleModels?: boolean;50}5152class MonacoWebWorkerImpl<T extends object> extends EditorWorkerClient implements MonacoWebWorker<T> {5354private readonly _foreignModuleHost: { [method: string]: Function } | null;55private _foreignProxy: Promise<T>;5657constructor(modelService: IModelService, opts: IInternalWebWorkerOptions) {58super(opts.worker, opts.keepIdleModels || false, modelService);59this._foreignModuleHost = opts.host || null;60this._foreignProxy = this._getProxy().then(proxy => {61return new Proxy({}, {62get(target, prop, receiver) {63if (prop === 'then') {64// Don't forward the call when the proxy is returned in an async function and the runtime tries to .then it.65return undefined;66}67if (typeof prop !== 'string') {68throw new Error(`Not supported`);69}70return (...args: any[]) => {71return proxy.$fmr(prop, args);72};73}74}) as T;75});76}7778// foreign host request79public override fhr(method: string, args: any[]): Promise<any> {80if (!this._foreignModuleHost || typeof this._foreignModuleHost[method] !== 'function') {81return Promise.reject(new Error('Missing method ' + method + ' or missing main thread foreign host.'));82}8384try {85return Promise.resolve(this._foreignModuleHost[method].apply(this._foreignModuleHost, args));86} catch (e) {87return Promise.reject(e);88}89}9091public getProxy(): Promise<T> {92return this._foreignProxy;93}9495public withSyncedResources(resources: URI[]): Promise<T> {96return this.workerWithSyncedResources(resources).then(_ => this.getProxy());97}98}99100101