import { AbortableTask } from "@xmcl/task" ; import { AbortSignal } from "./http/abort" ; import { createDownload , Download , DownloadOptions } from "./http/download" ; import { DownloadError } from "./http/error" ; import { StatusController } from "./http/status" ; export class DownloadTask extends AbortableTask < void > implements StatusController { readonly download : Download ; protected abort : ( isCancelled : boolean ) => void = ( ) => { } ; constructor ( options ) { super ( ) ; options . statusController = this ; this . download = createDownload ( options ) ; } reset ( progress , total ) { this . _progress = progress ; this . _total = total ; } onProgress ( chunkSize , progress ) { this . _progress = progress ; this . update ( chunkSize ) ; } protected process ( ) { const listeners = [ ] ; const aborted = ( ) => this . isCancelled || this . isPaused ; const signal = { get aborted ( ) { return aborted ( ) ; } , addEventListener ( event , listener ) { if ( event !== "abort" ) { return this ; } listeners . push ( listener ) ; return this ; } , removeEventListener ( event , listener ) { return this ; } } ; this . abort = ( ) => { listeners . forEach ( ( l ) => l ( ) ) ; } ; return this . download . start ( signal ) ; } protected isAbortedError ( e ) { if ( e instanceof Array ) { e = e [ 0 ] ; } if ( e instanceof DownloadError && e . error === "DownloadAborted" ) { return true ; } return false ; } }