UNPKG

tus-js-client-stall-detection

Version:

A pure JavaScript client for the tus resumable upload protocol (fork with stall detection)

126 lines (97 loc) 2.56 kB
import { readable as isNodeReadableStream } from 'is-stream' import type { HttpProgressHandler, HttpRequest, HttpResponse, HttpStack, SliceType, } from '../options.js' export class XHRHttpStack implements HttpStack { createRequest(method: string, url: string): HttpRequest { return new XHRRequest(method, url) } getName() { return 'XHRHttpStack' } supportsProgressEvents(): boolean { // XMLHttpRequest supports progress events via the upload.onprogress event return true } } class XHRRequest implements HttpRequest { private _xhr = new XMLHttpRequest() private _method: string private _url: string private _headers: Record<string, string> = {} constructor(method: string, url: string) { this._xhr.open(method, url, true) this._method = method this._url = url } getMethod(): string { return this._method } getURL(): string { return this._url } setHeader(header: string, value: string): void { this._xhr.setRequestHeader(header, value) this._headers[header] = value } getHeader(header: string): string { return this._headers[header] } setProgressHandler(progressHandler: HttpProgressHandler): void { // Test support for progress events before attaching an event listener if (!('upload' in this._xhr)) { return } this._xhr.upload.onprogress = (e) => { if (!e.lengthComputable) { return } progressHandler(e.loaded) } } send(body?: SliceType): Promise<HttpResponse> { if (isNodeReadableStream(body)) { throw new Error( 'Using a Node.js readable stream as HTTP request body is not supported using the XMLHttpRequest HTTP stack.', ) } return new Promise((resolve, reject) => { this._xhr.onload = () => { resolve(new XHRResponse(this._xhr)) } this._xhr.onerror = (err) => { reject(err) } this._xhr.send(body) }) } abort(): Promise<void> { this._xhr.abort() return Promise.resolve() } getUnderlyingObject(): XMLHttpRequest { return this._xhr } } class XHRResponse implements HttpResponse { private _xhr: XMLHttpRequest constructor(xhr: XMLHttpRequest) { this._xhr = xhr } getStatus(): number { return this._xhr.status } getHeader(header: string): string | undefined { return this._xhr.getResponseHeader(header) || undefined } getBody(): string { return this._xhr.responseText } getUnderlyingObject(): XMLHttpRequest { return this._xhr } }