UNPKG

@canlooks/ajax

Version:
158 lines (157 loc) 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.core = core; const error_1 = require("./error"); const utility_1 = require("./utility"); async function core(config) { let { url, params, onUploadProgress, onDownloadProgress, timeout = !onUploadProgress && !onDownloadProgress ? 60_000 : void 0, responseType = onDownloadProgress ? 'none' : 'json', ...init } = config; /** * ------------------------------------------------------------------ * URL */ if (!url) { throw new TypeError(`"url" is required`); } if (params.size) { url += `${url.includes('?') ? '&' : '?'}${params}`; } /** * ------------------------------------------------------------------ * 超时与中断 */ let abortController; let timeoutId; if (timeout) { abortController ||= new AbortController(); timeoutId = setTimeout(() => { abortController.abort(new error_1.TimeoutError(void 0, { config })); }, timeout); } if (config.signal) { abortController ||= new AbortController(); config.signal.addEventListener('abort', () => { abortController.abort(new error_1.AbortError(void 0, { config })); }); } /** * ------------------------------------------------------------------ * 请求 */ let response; const { body } = init; try { response = await fetch(url, { ...init, body: (0, utility_1.bodyTransform)(body), signal: abortController?.signal, }); } catch (e) { throw (0, utility_1.catchCommonError)(e, message => new error_1.NetworkError(message, { config, response })); } if (!response.ok) { throw new error_1.NetworkError(`request failed with status ${response.status}`, { config, response }); } let result; /** * ------------------------------------------------------------------ * 进度 */ try { if (onUploadProgress) { const blob = body instanceof ReadableStream ? await new Response(body).blob() : (0, utility_1.findBodyFiles)(body); if (blob) { const reader = blob.stream().getReader(); let loaded = 0; const total = blob.size; const read = async () => { const { done, value } = await reader.read(); if (done) { return; } onUploadProgress({ loaded: loaded += value.byteLength, total, chunk: value }); await read(); }; await read(); } } if (onDownloadProgress) { const contentLength = response.headers.get('content-length'); if (contentLength && response.body) { let data = new Uint8Array(); const writableStream = new WritableStream({ write(chunk) { const totalLength = data.byteLength + chunk.byteLength; const newData = new Uint8Array(totalLength); newData.set(data); newData.set(chunk, data.byteLength); data = newData; onDownloadProgress({ loaded: data.byteLength, total: +contentLength, chunk }); }, close() { result = data; } }); await response.body.pipeTo(writableStream); } } } catch (e) { throw (0, utility_1.catchCommonError)(e, message => new error_1.AjaxError(message, { config, response })); } /** * ------------------------------------------------------------------ * 响应 */ clearTimeout(timeoutId); if (onDownloadProgress) { switch (responseType) { case 'arrayBuffer': result = result.buffer; break; case 'blob': const blob = new Blob([result]); result = blob; break; case 'none': case void 0: break; default: throw new error_1.AjaxError(`responseType: "${responseType}" is not supported when "onDownloadProgress" specified`, { config, response }); } } else { try { switch (responseType) { case 'json': result = await response.json(); break; case 'text': result = await response.text(); break; case 'blob': result = await response.blob(); break; case 'arrayBuffer': result = await response.arrayBuffer(); break; case 'formData': result = await response.formData(); } } catch (e) { throw (0, utility_1.catchCommonError)(e, message => new error_1.AjaxError(message, { config, response })); } } return { result, response, config }; }