@@ -227,6 +227,10 @@ interface ThrownValue {
227227type SerializedThrownValue =
228228 | { isError : true ; value : Error }
229229 | { isError : false ; value : unknown } ;
230+ type PendingListenersMap = Map <
231+ string ,
232+ ( value : WireValue | PromiseLike < WireValue > ) => void
233+ > ;
230234
231235/**
232236 * Internal transfer handler to handle thrown exceptions.
@@ -392,7 +396,26 @@ function closeEndPoint(endpoint: Endpoint) {
392396}
393397
394398export function wrap < T > ( ep : Endpoint , target ?: any ) : Remote < T > {
395- return createProxy < T > ( ep , [ ] , target ) as any ;
399+ const pendingListeners : PendingListenersMap = new Map ( ) ;
400+
401+ ep . addEventListener ( "message" , function handleMessage ( ev : Event ) {
402+ const { data } = ev as MessageEvent ;
403+ if ( ! data || ! data . id ) {
404+ return ;
405+ }
406+ const resolver = pendingListeners . get ( data . id ) ;
407+ if ( ! resolver ) {
408+ return ;
409+ }
410+
411+ try {
412+ resolver ( data ) ;
413+ } finally {
414+ pendingListeners . delete ( data . id ) ;
415+ }
416+ } ) ;
417+
418+ return createProxy < T > ( ep , pendingListeners , [ ] , target ) as any ;
396419}
397420
398421function throwIfProxyReleased ( isReleased : boolean ) {
@@ -402,7 +425,7 @@ function throwIfProxyReleased(isReleased: boolean) {
402425}
403426
404427function releaseEndpoint ( ep : Endpoint ) {
405- return requestResponseMessage ( ep , {
428+ return requestResponseMessage ( ep , new Map ( ) , {
406429 type : MessageType . RELEASE ,
407430 } ) . then ( ( ) => {
408431 closeEndPoint ( ep ) ;
@@ -447,6 +470,7 @@ function unregisterProxy(proxy: object) {
447470
448471function createProxy < T > (
449472 ep : Endpoint ,
473+ pendingListeners : PendingListenersMap ,
450474 path : ( string | number | symbol ) [ ] = [ ] ,
451475 target : object = function ( ) { }
452476) : Remote < T > {
@@ -458,20 +482,21 @@ function createProxy<T>(
458482 return ( ) => {
459483 unregisterProxy ( proxy ) ;
460484 releaseEndpoint ( ep ) ;
485+ pendingListeners . clear ( ) ;
461486 isProxyReleased = true ;
462487 } ;
463488 }
464489 if ( prop === "then" ) {
465490 if ( path . length === 0 ) {
466491 return { then : ( ) => proxy } ;
467492 }
468- const r = requestResponseMessage ( ep , {
493+ const r = requestResponseMessage ( ep , pendingListeners , {
469494 type : MessageType . GET ,
470495 path : path . map ( ( p ) => p . toString ( ) ) ,
471496 } ) . then ( fromWireValue ) ;
472497 return r . then . bind ( r ) ;
473498 }
474- return createProxy ( ep , [ ...path , prop ] ) ;
499+ return createProxy ( ep , pendingListeners , [ ...path , prop ] ) ;
475500 } ,
476501 set ( _target , prop , rawValue ) {
477502 throwIfProxyReleased ( isProxyReleased ) ;
@@ -480,6 +505,7 @@ function createProxy<T>(
480505 const [ value , transferables ] = toWireValue ( rawValue ) ;
481506 return requestResponseMessage (
482507 ep ,
508+ pendingListeners ,
483509 {
484510 type : MessageType . SET ,
485511 path : [ ...path , prop ] . map ( ( p ) => p . toString ( ) ) ,
@@ -492,17 +518,18 @@ function createProxy<T>(
492518 throwIfProxyReleased ( isProxyReleased ) ;
493519 const last = path [ path . length - 1 ] ;
494520 if ( ( last as any ) === createEndpoint ) {
495- return requestResponseMessage ( ep , {
521+ return requestResponseMessage ( ep , pendingListeners , {
496522 type : MessageType . ENDPOINT ,
497523 } ) . then ( fromWireValue ) ;
498524 }
499525 // We just pretend that `bind()` didn’t happen.
500526 if ( last === "bind" ) {
501- return createProxy ( ep , path . slice ( 0 , - 1 ) ) ;
527+ return createProxy ( ep , pendingListeners , path . slice ( 0 , - 1 ) ) ;
502528 }
503529 const [ argumentList , transferables ] = processArguments ( rawArgumentList ) ;
504530 return requestResponseMessage (
505531 ep ,
532+ pendingListeners ,
506533 {
507534 type : MessageType . APPLY ,
508535 path : path . map ( ( p ) => p . toString ( ) ) ,
@@ -516,6 +543,7 @@ function createProxy<T>(
516543 const [ argumentList , transferables ] = processArguments ( rawArgumentList ) ;
517544 return requestResponseMessage (
518545 ep ,
546+ pendingListeners ,
519547 {
520548 type : MessageType . CONSTRUCT ,
521549 path : path . map ( ( p ) => p . toString ( ) ) ,
@@ -595,22 +623,17 @@ function fromWireValue(value: WireValue): any {
595623
596624function requestResponseMessage (
597625 ep : Endpoint ,
626+ pendingListeners : PendingListenersMap ,
598627 msg : Message ,
599628 transfers ?: Transferable [ ]
600629) : Promise < WireValue > {
601630 return new Promise ( ( resolve ) => {
602631 const id = Math . trunc ( Math . random ( ) * Number . MAX_SAFE_INTEGER ) . toString ( ) ;
603- ep . addEventListener ( "message" , function l ( ev : MessageEvent ) {
604- if ( ! ev . data || ! ev . data . id || ev . data . id !== id ) {
605- return ;
606- }
607- ep . removeEventListener ( "message" , l as any ) ;
608- resolve ( ev . data ) ;
609- } as any ) ;
632+ pendingListeners . set ( id , resolve ) ;
610633 if ( ep . start ) {
611634 ep . start ( ) ;
612635 }
613636 ep . postMessage ( { id, ...msg } , transfers ) ;
614- } ) ;
637+ } ) ;
615638}
616639
0 commit comments