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