@hyper-fetch/core
Version:
Cache, Queue and Persist your requests no matter if you are online or offline!
93 lines (84 loc) • 2.86 kB
text/typescript
import { RequestInstance } from "../request";
import { getAdapterBindings, AdapterInstance, AdapterType, ResponseReturnType } from "adapter";
export const mocker = async <T extends AdapterInstance = AdapterType>(
request: RequestInstance,
{
onError,
onResponseEnd,
onTimeoutError,
onRequestEnd,
createAbortListener,
onResponseProgress,
onRequestProgress,
onResponseStart,
onBeforeRequest,
onRequestStart,
onSuccess,
}: Pick<
Awaited<ReturnType<typeof getAdapterBindings<T>>>,
| "onError"
| "onResponseEnd"
| "onTimeoutError"
| "onRequestEnd"
| "createAbortListener"
| "onResponseProgress"
| "onRequestProgress"
| "onResponseStart"
| "onBeforeRequest"
| "onRequestStart"
| "onSuccess"
>,
) => {
const mock = request.mock.next();
const result = mock.value instanceof Function ? await mock.value(request) : mock.value;
return new Promise<ResponseReturnType<any, any, any>>((resolve) => {
const { data, status = 200, success = true, extra, config } = result;
const {
requestTime = 20,
responseTime = 20,
totalUploaded = 1,
totalDownloaded = 1,
timeout = false,
} = config || {};
createAbortListener(0 as any, {} as any, () => {}, resolve);
onBeforeRequest();
onRequestStart();
const progress = (totalTime, totalSize, progressFunction: typeof onResponseProgress | typeof onRequestProgress) =>
new Promise((resolveProgress) => {
const interval = 20;
const dataStart = +new Date();
const chunkSize = Math.floor(totalSize / Math.floor(totalTime / Math.min(totalTime, interval)));
let currentlyLoaded = 0;
const timer = setInterval(function handleProgressInterval() {
const currentTime = Math.min(totalTime, +new Date() - dataStart);
currentlyLoaded += currentlyLoaded + chunkSize >= totalSize ? totalSize - currentlyLoaded : chunkSize;
if (currentTime >= totalTime) {
resolveProgress(true);
clearInterval(timer);
} else {
progressFunction({
total: totalSize,
loaded: currentlyLoaded,
});
}
}, interval);
});
const getResponse = async () => {
await progress(requestTime, totalUploaded, onRequestProgress);
onRequestEnd();
onResponseStart();
await progress(responseTime, totalDownloaded, onResponseProgress);
if (success) {
onSuccess(data, status as any, extra || {}, resolve);
} else {
onError(data, status as any, extra || {}, resolve);
}
};
if (timeout) {
setTimeout(() => onTimeoutError(0 as any, extra || {}, resolve), 1);
} else {
setTimeout(getResponse, requestTime + responseTime + 1);
}
onResponseEnd();
});
};