66import { transformErrorForSerialization } from 'vs/base/common/errors' ;
77import { Disposable , IDisposable } from 'vs/base/common/lifecycle' ;
88import { isWeb } from 'vs/base/common/platform' ;
9- import { getAllPropertyNames } from 'vs/base/common/types' ;
9+ import * as types from 'vs/base/common/types' ;
1010
1111const INITIALIZE = '$initialize' ;
1212
@@ -173,17 +173,22 @@ class SimpleWorkerProtocol {
173173 }
174174}
175175
176+ export interface IWorkerClient < W > {
177+ getProxyObject ( ) : Promise < W > ;
178+ dispose ( ) : void ;
179+ }
180+
176181/**
177182 * Main thread side
178183 */
179- export class SimpleWorkerClient < T > extends Disposable {
184+ export class SimpleWorkerClient < W extends object , H extends object > extends Disposable implements IWorkerClient < W > {
180185
181- private _worker : IWorker ;
182- private _onModuleLoaded : Promise < string [ ] > ;
183- private _protocol : SimpleWorkerProtocol ;
184- private _lazyProxy : Promise < T > ;
186+ private readonly _worker : IWorker ;
187+ private readonly _onModuleLoaded : Promise < string [ ] > ;
188+ private readonly _protocol : SimpleWorkerProtocol ;
189+ private readonly _lazyProxy : Promise < W > ;
185190
186- constructor ( workerFactory : IWorkerFactory , moduleId : string ) {
191+ constructor ( workerFactory : IWorkerFactory , moduleId : string , host : H ) {
187192 super ( ) ;
188193
189194 let lazyProxyReject : ( ( err : any ) => void ) | null = null ;
@@ -207,8 +212,15 @@ export class SimpleWorkerClient<T> extends Disposable {
207212 this . _worker . postMessage ( msg ) ;
208213 } ,
209214 handleMessage : ( method : string , args : any [ ] ) : Promise < any > => {
210- // Intentionally not supporting worker -> main requests
211- return Promise . resolve ( null ) ;
215+ if ( typeof host [ method ] !== 'function' ) {
216+ return Promise . reject ( new Error ( 'Missing method ' + method + ' on main thread host.' ) ) ;
217+ }
218+
219+ try {
220+ return Promise . resolve ( host [ method ] . apply ( host , args ) ) ;
221+ } catch ( e ) {
222+ return Promise . reject ( e ) ;
223+ }
212224 }
213225 } ) ;
214226 this . _protocol . setWorkerId ( this . _worker . getId ( ) ) ;
@@ -223,41 +235,33 @@ export class SimpleWorkerClient<T> extends Disposable {
223235 loaderConfiguration = ( < any > self ) . requirejs . s . contexts . _ . config ;
224236 }
225237
238+ const hostMethods = types . getAllMethodNames ( host ) ;
239+
226240 // Send initialize message
227241 this . _onModuleLoaded = this . _protocol . sendMessage ( INITIALIZE , [
228242 this . _worker . getId ( ) ,
243+ loaderConfiguration ,
229244 moduleId ,
230- loaderConfiguration
245+ hostMethods ,
231246 ] ) ;
232247
233- this . _lazyProxy = new Promise < T > ( ( resolve , reject ) => {
248+ // Create proxy to loaded code
249+ const proxyMethodRequest = ( method : string , args : any [ ] ) : Promise < any > => {
250+ return this . _request ( method , args ) ;
251+ } ;
252+
253+ this . _lazyProxy = new Promise < W > ( ( resolve , reject ) => {
234254 lazyProxyReject = reject ;
235255 this . _onModuleLoaded . then ( ( availableMethods : string [ ] ) => {
236- let proxy = < T > { } ;
237- for ( const methodName of availableMethods ) {
238- ( proxy as any ) [ methodName ] = createProxyMethod ( methodName , proxyMethodRequest ) ;
239- }
240- resolve ( proxy ) ;
256+ resolve ( types . createProxyObject < W > ( availableMethods , proxyMethodRequest ) ) ;
241257 } , ( e ) => {
242258 reject ( e ) ;
243259 this . _onError ( 'Worker failed to load ' + moduleId , e ) ;
244260 } ) ;
245261 } ) ;
246-
247- // Create proxy to loaded code
248- const proxyMethodRequest = ( method : string , args : any [ ] ) : Promise < any > => {
249- return this . _request ( method , args ) ;
250- } ;
251-
252- const createProxyMethod = ( method : string , proxyMethodRequest : ( method : string , args : any [ ] ) => Promise < any > ) : ( ) => Promise < any > => {
253- return function ( ) {
254- let args = Array . prototype . slice . call ( arguments , 0 ) ;
255- return proxyMethodRequest ( method , args ) ;
256- } ;
257- } ;
258262 }
259263
260- public getProxyObject ( ) : Promise < T > {
264+ public getProxyObject ( ) : Promise < W > {
261265 return this . _lazyProxy ;
262266 }
263267
@@ -280,16 +284,22 @@ export interface IRequestHandler {
280284 [ prop : string ] : any ;
281285}
282286
287+ export interface IRequestHandlerFactory < H > {
288+ ( host : H ) : IRequestHandler ;
289+ }
290+
283291/**
284292 * Worker side
285293 */
286- export class SimpleWorkerServer {
294+ export class SimpleWorkerServer < H extends object > {
287295
296+ private _requestHandlerFactory : IRequestHandlerFactory < H > | null ;
288297 private _requestHandler : IRequestHandler | null ;
289298 private _protocol : SimpleWorkerProtocol ;
290299
291- constructor ( postSerializedMessage : ( msg : string ) => void , requestHandler : IRequestHandler | null ) {
292- this . _requestHandler = requestHandler ;
300+ constructor ( postSerializedMessage : ( msg : string ) => void , requestHandlerFactory : IRequestHandlerFactory < H > | null ) {
301+ this . _requestHandlerFactory = requestHandlerFactory ;
302+ this . _requestHandler = null ;
293303 this . _protocol = new SimpleWorkerProtocol ( {
294304 sendMessage : ( msg : string ) : void => {
295305 postSerializedMessage ( msg ) ;
@@ -304,7 +314,7 @@ export class SimpleWorkerServer {
304314
305315 private _handleMessage ( method : string , args : any [ ] ) : Promise < any > {
306316 if ( method === INITIALIZE ) {
307- return this . initialize ( < number > args [ 0 ] , < string > args [ 1 ] , < any > args [ 2 ] ) ;
317+ return this . initialize ( < number > args [ 0 ] , < any > args [ 1 ] , < string > args [ 2 ] , < string [ ] > args [ 3 ] ) ;
308318 }
309319
310320 if ( ! this . _requestHandler || typeof this . _requestHandler [ method ] !== 'function' ) {
@@ -318,18 +328,19 @@ export class SimpleWorkerServer {
318328 }
319329 }
320330
321- private initialize ( workerId : number , moduleId : string , loaderConfig : any ) : Promise < string [ ] > {
331+ private initialize ( workerId : number , loaderConfig : any , moduleId : string , hostMethods : string [ ] ) : Promise < string [ ] > {
322332 this . _protocol . setWorkerId ( workerId ) ;
323333
324- if ( this . _requestHandler ) {
334+ const proxyMethodRequest = ( method : string , args : any [ ] ) : Promise < any > => {
335+ return this . _protocol . sendMessage ( method , args ) ;
336+ } ;
337+
338+ const hostProxy = types . createProxyObject < H > ( hostMethods , proxyMethodRequest ) ;
339+
340+ if ( this . _requestHandlerFactory ) {
325341 // static request handler
326- let methods : string [ ] = [ ] ;
327- for ( const prop of getAllPropertyNames ( this . _requestHandler ) ) {
328- if ( typeof this . _requestHandler [ prop ] === 'function' ) {
329- methods . push ( prop ) ;
330- }
331- }
332- return Promise . resolve ( methods ) ;
342+ this . _requestHandler = this . _requestHandlerFactory ( hostProxy ) ;
343+ return Promise . resolve ( types . getAllMethodNames ( this . _requestHandler ) ) ;
333344 }
334345
335346 if ( loaderConfig ) {
@@ -350,23 +361,15 @@ export class SimpleWorkerServer {
350361
351362 return new Promise < string [ ] > ( ( resolve , reject ) => {
352363 // Use the global require to be sure to get the global config
353- ( < any > self ) . require ( [ moduleId ] , ( ...result : any [ ] ) => {
354- let handlerModule = result [ 0 ] ;
355- this . _requestHandler = handlerModule . create ( ) ;
364+ ( < any > self ) . require ( [ moduleId ] , ( module : { create : IRequestHandlerFactory < H > } ) => {
365+ this . _requestHandler = module . create ( hostProxy ) ;
356366
357367 if ( ! this . _requestHandler ) {
358368 reject ( new Error ( `No RequestHandler!` ) ) ;
359369 return ;
360370 }
361371
362- let methods : string [ ] = [ ] ;
363- for ( const prop of getAllPropertyNames ( this . _requestHandler ) ) {
364- if ( typeof this . _requestHandler [ prop ] === 'function' ) {
365- methods . push ( prop ) ;
366- }
367- }
368-
369- resolve ( methods ) ;
372+ resolve ( types . getAllMethodNames ( this . _requestHandler ) ) ;
370373 } , reject ) ;
371374 } ) ;
372375 }
@@ -375,6 +378,6 @@ export class SimpleWorkerServer {
375378/**
376379 * Called on the worker side
377380 */
378- export function create ( postMessage : ( msg : string ) => void ) : SimpleWorkerServer {
381+ export function create ( postMessage : ( msg : string ) => void ) : SimpleWorkerServer < any > {
379382 return new SimpleWorkerServer ( postMessage , null ) ;
380383}
0 commit comments