src/vs/base/common/worker/simpleWorker.ts/SimpleWorkerClient/constructor
class SimpleWorkerClient:	constructor(workerFactory: IWorkerFactory, moduleId: string, host: H) {
		super();

		let lazyProxyReject: ((err: any) => void) | null = null;

		this._worker = this._register(workerFactory.create(
			'vs/base/common/worker/simpleWorker',
			(msg: any) => {
				this._protocol.handleMessage(msg);
			},
			(err: any) => {
				// in Firefox, web workers fail lazily :(
				// we will reject the proxy
				if (lazyProxyReject) {
					lazyProxyReject(err);
				}
			}
		));

		this._protocol = new SimpleWorkerProtocol({
			sendMessage: (msg: any, transfer: ArrayBuffer[]): void => {
				this._worker.postMessage(msg, transfer);
			},
			handleMessage: (method: string, args: any[]): Promise<any> => {
				if (typeof (host as any)[method] !== 'function') {
					return Promise.reject(new Error('Missing method ' + method + ' on main thread host.'));
				}

				try {
					return Promise.resolve((host as any)[method].apply(host, args));
				} catch (e) {
					return Promise.reject(e);
				}
			}
		});
		this._protocol.setWorkerId(this._worker.getId());

		// Gather loader configuration
		let loaderConfiguration: any = null;
		if (typeof (<any>self).require !== 'undefined' && typeof (<any>self).require.getConfig === 'function') {
			// Get the configuration from the Monaco AMD Loader
			loaderConfiguration = (<any>self).require.getConfig();
		} else if (typeof (<any>self).requirejs !== 'undefined') {
			// Get the configuration from requirejs
			loaderConfiguration = (<any>self).requirejs.s.contexts._.config;
		}

		const hostMethods = types.getAllMethodNames(host);

		// Send initialize message
		this._onModuleLoaded = this._protocol.sendMessage(INITIALIZE, [
			this._worker.getId(),
			JSON.parse(JSON.stringify(loaderConfiguration)),
			moduleId,
			hostMethods,
		]);

		// Create proxy to loaded code
		const proxyMethodRequest = (method: string, args: any[]): Promise<any> => {
			return this._request(method, args);
		};

		this._lazyProxy = new Promise<W>((resolve, reject) => {
			lazyProxyReject = reject;
			this._onModuleLoaded.then((availableMethods: string[]) => {
				resolve(types.createProxyObject<W>(availableMethods, proxyMethodRequest));
			}, (e) => {
				reject(e);
				this._onError('Worker failed to load ' + moduleId, e);
			});
		});
	}