@hyper-fetch/core
Version:
Cache, Queue and Persist your requests no matter if you are online or offline!
88 lines (80 loc) • 2.84 kB
text/typescript
import type { RequestEventType, RequestProgressEventType, RequestResponseEventType } from "managers";
import type { RequestInstance } from "./request.types";
type HookName =
| "onBeforeSent"
| "onRequestStart"
| "onResponseStart"
| "onUploadProgress"
| "onDownloadProgress"
| "onResponse"
| "onRemove";
export interface RequestHooks<R extends RequestInstance> {
onBeforeSent: (cb: (eventData: RequestEventType<R>) => void) => () => void;
onRequestStart: (cb: (eventData: RequestEventType<R>) => void) => () => void;
onResponseStart: (cb: (eventData: RequestEventType<R>) => void) => () => void;
onUploadProgress: (cb: (eventData: RequestProgressEventType<R>) => void) => () => void;
onDownloadProgress: (cb: (eventData: RequestProgressEventType<R>) => void) => () => void;
onResponse: (cb: (eventData: RequestResponseEventType<R>) => void) => () => void;
onRemove: (cb: (eventData: RequestEventType<R>) => void) => () => void;
/** @internal Invoke all registered listeners for a given hook */
__emit: (name: HookName, data: any) => void;
/** @internal Get a snapshot of all registered listeners (used by clone) */
__snapshot: () => Record<HookName, Array<(...args: any[]) => void>>;
}
const HOOK_NAMES: HookName[] = [
"onBeforeSent",
"onRequestStart",
"onResponseStart",
"onUploadProgress",
"onDownloadProgress",
"onResponse",
"onRemove",
];
export function createRequestHooks<R extends RequestInstance>(
initial?: Record<HookName, Array<(...args: any[]) => void>>,
): RequestHooks<R> {
const listeners: Record<HookName, Array<(...args: any[]) => void>> = {
onBeforeSent: [],
onRequestStart: [],
onResponseStart: [],
onUploadProgress: [],
onDownloadProgress: [],
onResponse: [],
onRemove: [],
};
if (initial) {
HOOK_NAMES.forEach((name) => {
listeners[name] = [...initial[name]];
});
}
const subscribe = (name: HookName) => {
return (cb: (...args: any[]) => void) => {
listeners[name].push(cb);
return () => {
const idx = listeners[name].indexOf(cb);
if (idx !== -1) listeners[name].splice(idx, 1);
};
};
};
return {
onBeforeSent: subscribe("onBeforeSent"),
onRequestStart: subscribe("onRequestStart"),
onResponseStart: subscribe("onResponseStart"),
onUploadProgress: subscribe("onUploadProgress"),
onDownloadProgress: subscribe("onDownloadProgress"),
onResponse: subscribe("onResponse"),
onRemove: subscribe("onRemove"),
__emit(name: HookName, data: any) {
listeners[name].forEach((cb) => {
cb(data);
});
},
__snapshot() {
const snap = {} as Record<HookName, Array<(...args: any[]) => void>>;
HOOK_NAMES.forEach((name) => {
snap[name] = [...listeners[name]];
});
return snap;
},
};
}