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