UNPKG

@hyper-fetch/core

Version:

Cache, Queue and Persist your requests no matter if you are online or offline!

101 lines (82 loc) 2.56 kB
import { xhrExtra, getAdapterBindings, AdapterType, getResponseHeaders, parseResponse, parseErrorResponse, } from "adapter"; import { defaultTimeout } from "./adapter.constants"; export const adapter: AdapterType = async (request, requestId) => { const { makeRequest, fullUrl, config, payload, headers, onError, onResponseEnd, onTimeoutError, onRequestEnd, createAbortListener, onResponseProgress, onRequestProgress, onResponseStart, onBeforeRequest, onRequestStart, onSuccess, } = await getAdapterBindings<AdapterType>(request, requestId, 0, { headers: {}, }); const { method = "GET" } = request; return makeRequest((resolve) => { const xhr = new XMLHttpRequest(); xhr.timeout = defaultTimeout; const abort = () => xhr.abort(); // Inject xhr options Object.entries(config).forEach(([name, value]) => { xhr[name] = value; }); // Open connection xhr.open(method, fullUrl, true); // Set Headers Object.entries(headers).forEach(([name, value]) => xhr.setRequestHeader(name, value as string)); // Listen to abort signal const unmountListener = createAbortListener(0, xhrExtra, abort, resolve); // Request handlers xhr.upload.onprogress = onRequestProgress; // Response handlers xhr.onloadstart = (): void => { onRequestEnd(); onResponseStart(); }; xhr.onprogress = onResponseProgress; xhr.onloadend = () => { onResponseEnd(); unmountListener(); }; xhr.ontimeout = () => onTimeoutError(0, xhrExtra, resolve); // Data handler xhr.onreadystatechange = (e: Event) => { const event = e as unknown as ProgressEvent<XMLHttpRequest>; const finishedState = 4; if (event.target && event.target.readyState === finishedState) { const { status } = event.target; const success = String(status).startsWith("2") || String(status).startsWith("3"); const responseHeaders = getResponseHeaders(xhr.getAllResponseHeaders()); if (success) { const data = parseResponse(event.target.response); onSuccess(data, status, { headers: responseHeaders }, resolve); } else { // delay to finish after onabort/ontimeout const data = parseErrorResponse(event.target.response); onError(data, status, { headers: responseHeaders }, resolve); } } }; // Start request onBeforeRequest(); onRequestStart(); xhr.send(payload); }); };