UNPKG

wretch

Version:

A tiny wrapper built around fetch with an intuitive syntax.

114 lines 4.15 kB
function toStream(requestOrResponse, bodySize, callback) { try { const contentLength = requestOrResponse.headers.get("content-length"); let total = bodySize || (contentLength ? +contentLength : 0); let loaded = 0; const transform = new TransformStream({ start() { callback === null || callback === void 0 ? void 0 : callback(loaded, total); }, transform(chunk, controller) { loaded += chunk.length; if (total < loaded) { total = loaded; } callback === null || callback === void 0 ? void 0 : callback(loaded, total); controller.enqueue(chunk); } }); const stream = requestOrResponse.body.pipeThrough(transform); if ("status" in requestOrResponse) { return new Response(stream, requestOrResponse); } else { // @ts-expect-error RequestInit does not yet include duplex return new Request(requestOrResponse, { body: stream, duplex: "half" }); } } catch (_a) { return requestOrResponse; } } const defaultGetUploadTotal = async (url, opts) => { let total = opts.body instanceof ArrayBuffer ? +opts.body.byteLength : opts.body instanceof Blob ? +opts.body.size : 0; try { // Try to determine body size by reading it as a blob total || (total = (await new Request(url, opts).blob()).size); } catch (_a) { // Cannot determine body size } return total; }; /** * Adds the ability to monitor progress when downloading a response. * * _Compatible with all platforms implementing the [TransformStream WebAPI](https://developer.mozilla.org/en-US/docs/Web/API/TransformStream#browser_compatibility)._ * * ```js * import ProgressAddon from "wretch/addons/progress" * * wretch("some_url") * // Register the addon * .addon(ProgressAddon()) * .get() * // Log the progress as a percentage of completion * .progress((loaded, total) => console.log(`${(loaded / total * 100).toFixed(0)}%`)) * ``` */ const progress = ({ getUploadTotal = defaultGetUploadTotal } = {}) => { function downloadMiddleware(state) { return next => (url, opts) => { return next(url, opts).then(response => { if (!state.progress) { return response; } return toStream(response, 0, state.progress); }); }; } function uploadMiddleware(state) { return next => async (url, opts) => { const body = opts.body; if (!body || !state.upload) { return next(url, opts); } const streameableRequest = toStream(new Request(url, opts), await getUploadTotal(url, opts), state.upload); return next(url, streameableRequest); }; } return { beforeRequest(wretch, options, state) { const middlewares = []; if (options.__uploadProgressCallback) { state.upload = options.__uploadProgressCallback; delete options.__uploadProgressCallback; } if (options.__downloadProgressCallback) { state.progress = options.__downloadProgressCallback; delete options.__downloadProgressCallback; } middlewares.push(uploadMiddleware(state)); middlewares.push(downloadMiddleware(state)); return wretch.middlewares(middlewares); }, wretch: { onUpload(onUpload) { return this.options({ __uploadProgressCallback: onUpload }); }, onDownload(onDownload) { return this.options({ __downloadProgressCallback: onDownload }); } }, resolver: { progress(onProgress) { this._sharedState.progress = onProgress; return this; } }, }; }; export default progress; //# sourceMappingURL=progress.js.map