⏬
download.ts
import axios from 'axios'
export interface IDownloadOptions {
timeout?: number
// UI update or logs record
onCancel?: () => void
}
export interface IDownloadResult {
cancel: () => void
download: Promise<Blob>
}
export const createDownload = (url: string, options: IDownloadOptions = {}): IDownloadResult => {
const { timeout = 1000 * 60 * 5, onCancel } = options
const abortController = new AbortController()
const timeoutId = setTimeout(() => {
abortController.abort()
onCancel?.()
}, timeout)
const download = (async () => {
try {
const response = await axios.get<Blob>(url, {
signal: abortController.signal,
responseType: 'blob',
})
clearTimeout(timeoutId)
return response.data
} catch (error) {
clearTimeout(timeoutId)
throw error
}
})()
return {
cancel: () => {
abortController.abort()
clearTimeout(timeoutId)
onCancel?.()
},
download,
}
}
Discussion