import { NewWorkerMessage , TerminateWorkerMessage } from './NestedWorkerEvents' ; declare function postMessage ( data , transferables ? ) ; declare function importScripts ( url ) ; declare type MessageEventHandler = ( ( ev : MessageEvent < any > ) => any ) | null ; const _bootstrapFnSource = function _bootstrapFn ( workerUrl ) { const listener = ( event ) : void => { self . removeEventListener ( 'message' , listener ) ; const port = < MessagePort > ( < MessageEvent > event ) . data ; Object . defineProperties ( self , { postMessage : { value ( data , transferOrOptions ? ) { port . postMessage ( data , transferOrOptions ) ; } , } , onmessage : { get ( ) { return port . onmessage ; } , set ( value ) { port . onmessage = value ; } , } , } ) ; port . addEventListener ( 'message' , ( msg ) => { self . dispatchEvent ( new MessageEvent ( 'message' , { data : msg . data } ) ) ; } ) ; port . start ( ) ; self . Worker = < any > class { constructor ( ) { throw new TypeError ( 'Nested workers from within nested worker are not supported.' ) ; } } ; importScripts ( workerUrl ) ; } ; self . addEventListener ( 'message' , listener ) ; } . toString ( ) ; export class NestedWorker extends EventTarget implements Worker { onmessage : ( ( this : Worker , ev : MessageEvent < any > ) => any ) | null = null ; onmessageerror : ( ( this : Worker , ev : MessageEvent < any > ) => any ) | null = null ; onerror : ( ( this : AbstractWorker , ev : ErrorEvent ) => any ) | null = null ; readonly terminate : ( ) => void ; readonly postMessage : ( message : any , options ? : any ) => void ; constructor ( nativePostMessage , stringOrUrl , options ? ) { super ( ) ; const bootstrap = `((${ _bootstrapFnSource })('${ stringOrUrl }'))` ; const blob = new Blob ( [ bootstrap ] , { type : 'application/javascript' } ) ; const blobUrl = URL . createObjectURL ( blob ) ; const channel = new MessageChannel ( ) ; const id = blobUrl ; const msg = { type : 'new_worker' , id , port : channel . port2 , url : blobUrl , options , } ; nativePostMessage ( msg , [ channel . port2 ] ) ; this . postMessage = channel . port1 . postMessage . bind ( channel . port1 ) ; this . terminate = ( ) => { const msg = { type : 'terminate_worker' , id , } ; channel . port1 . postMessage ( msg ) ; URL . revokeObjectURL ( blobUrl ) ; channel . port1 . close ( ) ; channel . port2 . close ( ) ; } ; Object . defineProperties ( this , { onmessage : { get ( ) { return channel . port1 . onmessage ; } , set ( value ) { channel . port1 . onmessage = value ; } , } , onmessageerror : { get ( ) { return channel . port1 . onmessageerror ; } , set ( value ) { channel . port1 . onmessageerror = value ; } , } , } ) ; channel . port1 . addEventListener ( 'messageerror' , ( evt ) => { const msgEvent = new MessageEvent ( 'messageerror' , { data : evt . data , } ) ; this . dispatchEvent ( msgEvent ) ; } ) ; channel . port1 . addEventListener ( 'message' , ( evt ) => { const msgEvent = new MessageEvent ( 'message' , { data : evt . data } ) ; this . dispatchEvent ( msgEvent ) ; } ) ; channel . port1 . start ( ) ; } }