UNPKG

@hyper-fetch/core

Version:

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

956 lines (924 loc) 79.9 kB
import EventEmitter from 'events'; type NegativeTypes = null | undefined; type NullableType<T> = T | NegativeTypes; type NullableKeys<T> = { [P in keyof T]-?: NullableType<T[P]>; }; type NonNullableKeys<T> = { [P in keyof T]-?: NonNullable<T[P]>; }; type RequiredKeys<T> = { [P in keyof T]-?: Exclude<T[P], NegativeTypes>; }; type HttpMethodsType = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"; type HttpStatusType = number; declare const adapter: AdapterType; /** * App manager handles main application states - focus and online. Those two values can answer questions: * - Is the tab or current view instance focused and visible for user? * - Is our application online or offline? * With the app manager it is not a problem to get the valid answer for this question. * * @caution * Make sure to apply valid focus/online handlers for different environments like for example for native mobile applications. */ declare class AppManager { options?: AppManagerOptionsType; emitter: EventEmitter; events: { emitFocus: () => void; emitBlur: () => void; emitOnline: () => void; emitOffline: () => void; onFocus: (callback: () => void) => VoidFunction; onBlur: (callback: () => void) => VoidFunction; onOnline: (callback: () => void) => VoidFunction; onOffline: (callback: () => void) => VoidFunction; }; isBrowser: boolean; isOnline: boolean; isFocused: boolean; constructor(options?: AppManagerOptionsType); private setInitialFocus; private setInitialOnline; setFocused: (isFocused: boolean) => void; setOnline: (isOnline: boolean) => void; } type AppManagerOptionsType = { initiallyFocused?: boolean | (() => boolean | Promise<boolean>); initiallyOnline?: boolean | (() => boolean | Promise<boolean>); focusEvent?: (setFocused: (isFocused: boolean) => void) => void; onlineEvent?: (setOnline: (isOnline: boolean) => void) => void; }; declare const hasWindow: () => boolean; declare const hasDocument: () => boolean; declare const onWindowEvent: <K extends keyof WindowEventMap>(key: K, listener: (this: Window, ev: WindowEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined) => void; declare const onDocumentEvent: <K extends keyof DocumentEventMap>(key: K, listener: (this: Document, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined) => void; declare const getAppManagerEvents: (emitter: EventEmitter) => { emitFocus: () => void; emitBlur: () => void; emitOnline: () => void; emitOffline: () => void; onFocus: (callback: () => void) => VoidFunction; onBlur: (callback: () => void) => VoidFunction; onOnline: (callback: () => void) => VoidFunction; onOffline: (callback: () => void) => VoidFunction; }; declare enum AppEvents { focus = "focus", blur = "blur", online = "online", offline = "offline" } declare const appManagerInitialOptions: RequiredKeys<AppManagerOptionsType>; /** * **Request Manager** is used to emit `request lifecycle events` like - request start, request end, upload and download progress. * It is also the place of `request aborting` system, here we store all the keys and controllers that are isolated for each client instance. */ declare class RequestManager { emitter: EventEmitter; events: { emitLoading: (queueKey: string, requestId: string, values: RequestLoadingEventType) => void; emitRequestStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void; emitResponseStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void; emitUploadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void; emitDownloadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void; emitResponse: <Adapter extends AdapterInstance>(cacheKey: string, requestId: string, response: ResponseReturnType<unknown, unknown, Adapter>, details: ResponseDetailsType) => void; emitAbort: (abortKey: string, requestId: string, request: RequestInstance) => void; emitRemove: <T extends RequestInstance>(queueKey: string, requestId: string, details: RequestEventType<T>) => void; onLoading: (queueKey: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction; onLoadingById: (requestId: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction; onRequestStart: <T_1 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_1>) => void) => VoidFunction; onRequestStartById: <T_2 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_2>) => void) => VoidFunction; onResponseStart: <T_3 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_3>) => void) => VoidFunction; onResponseStartById: <T_4 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_4>) => void) => VoidFunction; onUploadProgress: <T_5 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_5>) => void) => VoidFunction; onUploadProgressById: <T_6 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_6>) => void) => VoidFunction; onDownloadProgress: <T_7 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_7>) => void) => VoidFunction; onDownloadProgressById: <T_8 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_8>) => void) => VoidFunction; onResponse: <Response_1, ErrorType, Adapter_1 extends AdapterInstance>(cacheKey: string, callback: (response: ResponseReturnType<Response_1, ErrorType, Adapter_1>, details: ResponseDetailsType) => void) => VoidFunction; onResponseById: <Response_2, ErrorType_1, Adapter_2 extends AdapterInstance>(requestId: string, callback: (response: ResponseReturnType<Response_2, ErrorType_1, Adapter_2>, details: ResponseDetailsType) => void) => VoidFunction; onAbort: (abortKey: string, callback: (request: RequestInstance) => void) => VoidFunction; onAbortById: (requestId: string, callback: (request: RequestInstance) => void) => VoidFunction; onRemove: <T_9 extends RequestInstance = RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_9>) => void) => VoidFunction; onRemoveById: <T_10 extends RequestInstance = RequestInstance>(requestId: string, callback: (details: RequestEventType<T_10>) => void) => VoidFunction; }; abortControllers: Map<string, Map<string, AbortController>>; addAbortController: (abortKey: string, requestId: string) => void; getAbortController: (abortKey: string, requestId: string) => AbortController; removeAbortController: (abortKey: string, requestId: string) => void; useAbortController: (abortKey: string, requestId: string) => void; abortByKey: (abortKey: string) => void; abortByRequestId: (abortKey: string, requestId: string) => void; abortAll: () => void; } declare const getLoadingEventKey: (key: string) => string; declare const getLoadingIdEventKey: (key: string) => string; declare const getRemoveEventKey: (key: string) => string; declare const getRemoveIdEventKey: (key: string) => string; declare const getAbortEventKey: (key: string) => string; declare const getAbortByIdEventKey: (key: string) => string; declare const getResponseEventKey: (key: string) => string; declare const getResponseIdEventKey: (key: string) => string; declare const getRequestStartEventKey: (key: string) => string; declare const getRequestStartIdEventKey: (key: string) => string; declare const getResponseStartEventKey: (key: string) => string; declare const getResponseStartIdEventKey: (key: string) => string; declare const getUploadProgressEventKey: (key: string) => string; declare const getUploadProgressIdEventKey: (key: string) => string; declare const getDownloadProgressEventKey: (key: string) => string; declare const getDownloadProgressIdEventKey: (key: string) => string; declare const getRequestManagerEvents: (emitter: EventEmitter) => { /** * Emiter */ emitLoading: (queueKey: string, requestId: string, values: RequestLoadingEventType) => void; emitRequestStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void; emitResponseStart: (queueKey: string, requestId: string, details: RequestEventType<RequestInstance>) => void; emitUploadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void; emitDownloadProgress: (queueKey: string, requestId: string, values: ProgressType, details: RequestEventType<RequestInstance>) => void; emitResponse: <Adapter extends AdapterInstance>(cacheKey: string, requestId: string, response: ResponseReturnType<unknown, unknown, Adapter>, details: ResponseDetailsType) => void; emitAbort: (abortKey: string, requestId: string, request: RequestInstance) => void; emitRemove: <T extends RequestInstance>(queueKey: string, requestId: string, details: RequestEventType<T>) => void; /** * Listeners */ onLoading: (queueKey: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction; onLoadingById: (requestId: string, callback: (values: RequestLoadingEventType) => void) => VoidFunction; onRequestStart: <T_1 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_1>) => void) => VoidFunction; onRequestStartById: <T_2 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_2>) => void) => VoidFunction; onResponseStart: <T_3 extends RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_3>) => void) => VoidFunction; onResponseStartById: <T_4 extends RequestInstance>(requestId: string, callback: (details: RequestEventType<T_4>) => void) => VoidFunction; onUploadProgress: <T_5 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_5>) => void) => VoidFunction; onUploadProgressById: <T_6 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_6>) => void) => VoidFunction; onDownloadProgress: <T_7 extends RequestInstance = RequestInstance>(queueKey: string, callback: (values: ProgressType, details: RequestEventType<T_7>) => void) => VoidFunction; onDownloadProgressById: <T_8 extends RequestInstance = RequestInstance>(requestId: string, callback: (values: ProgressType, details: RequestEventType<T_8>) => void) => VoidFunction; onResponse: <Response_1, ErrorType, Adapter_1 extends AdapterInstance>(cacheKey: string, callback: (response: ResponseReturnType<Response_1, ErrorType, Adapter_1>, details: ResponseDetailsType) => void) => VoidFunction; onResponseById: <Response_2, ErrorType_1, Adapter_2 extends AdapterInstance>(requestId: string, callback: (response: ResponseReturnType<Response_2, ErrorType_1, Adapter_2>, details: ResponseDetailsType) => void) => VoidFunction; onAbort: (abortKey: string, callback: (request: RequestInstance) => void) => VoidFunction; onAbortById: (requestId: string, callback: (request: RequestInstance) => void) => VoidFunction; onRemove: <T_9 extends RequestInstance = RequestInstance>(queueKey: string, callback: (details: RequestEventType<T_9>) => void) => VoidFunction; onRemoveById: <T_10 extends RequestInstance = RequestInstance>(requestId: string, callback: (details: RequestEventType<T_10>) => void) => VoidFunction; }; type RequestLoadingEventType = { queueKey: string; requestId: string; loading: boolean; isRetry: boolean; isOffline: boolean; }; type RequestEventType<T extends RequestInstance> = { requestId: string; request: T; }; type ResponseDetailsType = { retries: number; timestamp: number; isCanceled: boolean; isOffline: boolean; }; type RequestRemoveDataType = { queueKey: string; requestId: string; }; /** * This class is used across the Hyper Fetch library to provide unified logging system with necessary setup per each client. * We can set up the logging level based on available values. This manager enable to initialize the logging instance per individual module * like Client, Request etc. Which can give you better feedback on the logging itself. */ declare class LoggerManager { private client; private options?; logger: LoggerFunctionType; severity: SeverityType; emitter: EventEmitter; constructor(client: Pick<ClientInstance, "debug">, options?: LoggerOptionsType); setSeverity: (severity: SeverityType) => void; init: (module: string) => LoggerType; } declare const getTime: () => string; declare const logger: LoggerFunctionType; type SeverityType = 0 | 1 | 2 | 3; type LoggerType = Record<LoggerLevelType, (message: LoggerMessageType, ...extra: LoggerMessageType[]) => void>; type LoggerFunctionType = (log: LogType) => void; type LoggerOptionsType = { logger?: LoggerFunctionType; severity?: SeverityType; }; type LogType = { module: string; level: LoggerLevelType; message: LoggerMessageType; extra?: LoggerMessageType[]; enabled: boolean; severity: SeverityType; }; type LoggerLevelType = "error" | "warning" | "info" | "debug"; type LoggerMessageType = string | Record<string, unknown> | Array<unknown>; type LoggerRequestEventData = { requestId: string; request: RequestInstance; }; type LoggerResponseEventData<Adapter extends AdapterInstance> = { requestId: string; request: RequestInstance; response: ResponseReturnType<unknown, unknown, Adapter>; details: ResponseDetailsType; }; declare const loggerStyles: Record<LoggerLevelType, string>; declare const loggerIconLevels: Record<LoggerLevelType, string>; declare const severity: Record<LoggerLevelType, number>; /** * Cache class handles the data exchange with the dispatchers. * * @note * Keys used to save the values are created dynamically on the Request class * */ declare class Cache<C extends ClientInstance> { client: C; options?: CacheOptionsType; emitter: EventEmitter; events: ReturnType<typeof getCacheEvents>; storage: CacheStorageType; lazyStorage?: CacheAsyncStorageType; clearKey: string; garbageCollectors: Map<string, NodeJS.Timeout>; private logger; constructor(client: C, options?: CacheOptionsType); /** * Set the cache data to the storage * @param request * @param response * @returns */ set: <Request_1 extends RequestInstance>(request: RequestInstance | RequestJSON<any>, response: CacheMethodType<ResponseReturnType<ExtractResponseType<Request_1>, ExtractErrorType<Request_1>, ExtractAdapterType<Request_1>> & ResponseDetailsType>) => void; /** * Update the cache data with partial response data * @param request * @param partialResponse * @returns */ update: <Request_1 extends RequestInstance>(request: RequestInstance | RequestJSON<RequestInstance>, partialResponse: CacheMethodType<Partial<ResponseReturnType<ExtractResponseType<Request_1>, ExtractErrorType<Request_1>, ExtractAdapterType<Request_1>> & ResponseDetailsType>>) => void; /** * Get particular record from storage by cacheKey. It will trigger lazyStorage to emit lazy load event for reading it's data. * @param cacheKey * @returns */ get: <Response_1, Error_1, Adapter extends AdapterInstance>(cacheKey: string) => CacheValueType<Response_1, Error_1, Adapter>; /** * Get sync storage keys, lazyStorage keys will not be included * @returns */ keys: () => string[]; /** * Delete record from storages and trigger invalidation event * @param cacheKey */ delete: (cacheKey: string) => void; /** * Invalidate cache by cacheKey or partial matching with RegExp * @param cacheKey */ invalidate: (cacheKey: string | RegExp) => Promise<void>; /** * Used to receive data from lazy storage * @param cacheKey */ getLazyResource: <Response_1, Error_1, Adapter extends AdapterInstance>(cacheKey: string) => Promise<CacheValueType<Response_1, Error_1, Adapter>>; /** * Used to receive keys from sync storage and lazy storage * @param cacheKey */ getLazyKeys: () => Promise<string[]>; /** * Schedule garbage collection for given key * @param cacheKey * @returns */ scheduleGarbageCollector: (cacheKey: string) => Promise<void>; /** * Clear cache storages */ clear: () => Promise<void>; } type CacheOptionsType<C extends ClientInstance = ClientInstance> = { /** * Assign your custom sync storage */ storage?: CacheStorageType; /** * Lazy loading from remote resources - possibly persistent */ lazyStorage?: CacheAsyncStorageType; /** * Key to clear lazy storage data */ clearKey?: string; /** * Initialization callback */ onInitialization?: (cache: Cache<C>) => void; /** * Callback for every change in the storage */ onChange?: <Response = any, Error = any, Adapter extends AdapterInstance = AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => void; /** * Callback for every delete in the storage */ onDelete?: (key: string) => void; }; type CacheValueType<Response = any, Error = any, Adapter extends AdapterInstance = AdapterInstance> = ResponseReturnType<Response, Error, Adapter> & ResponseDetailsType & { cacheTime: number; clearKey: string; garbageCollection: number; }; type CacheAsyncStorageType = { set: <Response, Error, Adapter extends AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => Promise<void>; get: <Response, Error, Adapter extends AdapterInstance>(key: string) => Promise<CacheValueType<Response, Error, Adapter> | undefined>; keys: () => Promise<string[] | IterableIterator<string> | string[]>; delete: (key: string) => Promise<void>; }; type CacheStorageType = { set: <Response, Error, Adapter extends AdapterInstance>(key: string, data: CacheValueType<Response, Error, Adapter>) => void; get: <Response, Error, Adapter extends AdapterInstance>(key: string) => CacheValueType<Response, Error, Adapter> | undefined; keys: () => string[] | IterableIterator<string> | string[]; delete: (key: string) => void; clear: () => void; }; type CacheInitialData = Record<string, CacheValueType>; type CacheMethodType<CacheData> = CacheData | ((previousData: CacheData | null) => CacheData); declare const getCacheData: <T extends RequestInstance>(previousResponse: ExtractAdapterReturnType<T>, response: ExtractAdapterReturnType<T> & ResponseDetailsType) => ExtractAdapterReturnType<T> & ResponseDetailsType; declare const getInvalidateEventKey: (key: string) => string; declare const getCacheKey: (key: string) => string; declare const getCacheIdKey: (key: string) => string; declare const getCacheEvents: (emitter: EventEmitter) => { /** * Set cache data * @param cacheKey * @param data */ emitCacheData: <Response_1, Error_1, Adapter extends AdapterInstance>(cacheKey: string, data: CacheValueType<Response_1, Error_1, Adapter>) => void; /** * Invalidate cache values event */ emitInvalidation: (cacheKey: string) => void; /** StatusType * Cache data listener * @param cacheKey * @param callback * @returns */ onData: <Response_2, Error_2, Adapter_1 extends AdapterInstance>(cacheKey: string, callback: (data: CacheValueType<Response_2, Error_2, Adapter_1>) => void) => VoidFunction; /** * Cache invalidation listener * @param cacheKey * @param callback * @returns */ onInvalidate: (cacheKey: string, callback: () => void) => VoidFunction; }; declare enum DispatcherRequestType { oneByOne = "one-by-one", allAtOnce = "all-at-once", previousCanceled = "previous-canceled", deduplicated = "deduplicated" } declare const getDispatcherEvents: (emitter: EventEmitter) => { setDrained: <Request_1 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_1>) => void; setQueueStatus: <Request_2 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_2>) => void; setQueueChanged: <Request_3 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_3>) => void; onDrained: <Request_4 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_4>) => void) => VoidFunction; onQueueStatus: <Request_5 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_5>) => void) => VoidFunction; onQueueChange: <Request_6 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_6>) => void) => VoidFunction; }; /** * Dispatcher class was made to store controlled request Fetches, and firing them all-at-once or one-by-one in request queue. * Generally requests should be flushed at the same time, the queue provide mechanism to fire them in the order. */ declare class Dispatcher { client: ClientInstance; options?: DispatcherOptionsType; emitter: EventEmitter; events: { setDrained: <Request_1 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_1>) => void; setQueueStatus: <Request_2 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_2>) => void; setQueueChanged: <Request_3 extends RequestInstance>(queueKey: string, values: QueueDataType<Request_3>) => void; onDrained: <Request_4 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_4>) => void) => VoidFunction; onQueueStatus: <Request_5 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_5>) => void) => VoidFunction; onQueueChange: <Request_6 extends RequestInstance>(queueKey: string, callback: (values: QueueDataType<Request_6>) => void) => VoidFunction; }; storage: DispatcherStorageType; private requestCount; private runningRequests; private logger; constructor(client: ClientInstance, options?: DispatcherOptionsType); /** * Start request handling by queueKey */ start: (queueKey: string) => void; /** * Pause request queue, but not cancel already started requests */ pause: (queueKey: string) => void; /** * Stop request queue and cancel all started requests - those will be treated like not started */ stop: (queueKey: string) => void; /** * Return all */ getQueuesKeys: () => string[]; /** * Return queue state object */ getQueue: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string) => QueueDataType<Request_1>; /** * Return request from queue state */ getRequest: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string, requestId: string) => QueueElementType<Request_1>; /** * Get value of the active queue status based on the stopped status */ getIsActiveQueue: (queueKey: string) => boolean; /** * Add new element to storage */ addQueueElement: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string, dispatcherDump: QueueElementType<Request_1>) => void; /** * Set new queue storage value */ setQueue: <Request_1 extends RequestInstance = RequestInstance>(queueKey: string, queue: QueueDataType<Request_1>) => QueueDataType<Request_1>; /** * Clear requests from queue cache */ clearQueue: (queueKey: string) => { requests: any[]; stopped: boolean; }; /** * Method used to flush the queue requests */ flushQueue: (queueKey: string) => Promise<void>; /** * Flush all available requests from all queues */ flush: () => Promise<void>; /** * Clear all running requests and storage */ clear: () => void; /** * Start particular request */ startRequest: (queueKey: string, requestId: string) => void; /** * Stop particular request */ stopRequest: (queueKey: string, requestId: string) => void; /** * Get currently running requests from all queueKeys */ getAllRunningRequest: () => RunningRequestValueType[]; /** * Get currently running requests */ getRunningRequests: (queueKey: string) => RunningRequestValueType[]; /** * Get running request by id */ getRunningRequest: (queueKey: string, requestId: string) => RunningRequestValueType; /** * Add request to the running requests list */ addRunningRequest: (queueKey: string, requestId: string, request: RequestInstance) => void; /** * Get the value based on the currently running requests */ hasRunningRequests: (queueKey: string) => boolean; /** * Check if request is currently processing */ hasRunningRequest: (queueKey: string, requestId: string) => boolean; /** * Cancel all started requests, but do NOT remove it from main storage */ cancelRunningRequests: (queueKey: string) => void; /** * Cancel started request, but do NOT remove it from main storage */ cancelRunningRequest: (queueKey: string, requestId: string) => void; /** * Delete all started requests, but do NOT clear it from queue and do NOT cancel them */ deleteRunningRequests: (queueKey: string) => void; /** * Delete request by id, but do NOT clear it from queue and do NOT cancel them */ deleteRunningRequest: (queueKey: string, requestId: string) => void; /** * Get count of requests from the same queueKey */ getQueueRequestCount: (queueKey: string) => number; /** * Add request count to the queueKey */ incrementQueueRequestCount: (queueKey: string) => void; /** * Create storage element from request */ createStorageElement: <Request_1 extends RequestInstance>(request: Request_1) => QueueElementType<Request_1>; /** * Add request to the dispatcher handler */ add: (request: RequestInstance) => string; /** * Delete from the storage and cancel request */ delete: (queueKey: string, requestId: string, abortKey: string) => QueueDataType<RequestInstance>; /** * Request can run for some time, once it's done, we have to check if it's successful or if it was aborted * It can be different once the previous call was set as cancelled and removed from queue before this request got resolved */ performRequest: (storageElement: QueueElementType) => Promise<void | QueueDataType<RequestInstance>>; } type DispatcherOptionsType = { storage?: DispatcherStorageType; onInitialization?: (dispatcherInstance: Dispatcher) => void; onUpdateStorage?: <Request extends RequestInstance>(queueKey: string, data: QueueDataType<Request>) => void; onDeleteFromStorage?: <Request extends RequestInstance>(queueKey: string, data: QueueDataType<Request>) => void; onClearStorage?: (dispatcherInstance: Dispatcher) => void; }; type QueueElementType<Request extends RequestInstance = RequestInstance> = { requestId: string; request: Request; retries: number; timestamp: number; stopped: boolean; }; type QueueDataType<Request extends RequestInstance = RequestInstance> = { requests: QueueElementType<Request>[]; stopped: boolean; }; type DispatcherStorageType = { set: <Request extends RequestInstance = RequestInstance>(key: string, data: QueueDataType<Request>) => void; get: <Request extends RequestInstance = RequestInstance>(key: string) => QueueDataType<Request> | undefined; keys: () => string[] | IterableIterator<string>; delete: (key: string) => void; clear: () => void; }; type RunningRequestValueType = { requestId: string; request: RequestInstance; timestamp: number; }; declare const getDispatcherDrainedEventKey: (key: string) => string; declare const getDispatcherStatusEventKey: (key: string) => string; declare const getDispatcherChangeEventKey: (key: string) => string; declare const getIsEqualTimestamp: (currentTimestamp: number, threshold: number, queueTimestamp?: number) => boolean; declare const canRetryRequest: (currentRetries: number, retry: number | undefined) => boolean; declare const getRequestType: (request: RequestInstance, latestRequest: QueueElementType | undefined) => DispatcherRequestType; /** * **Client** is a class that allows you to configure the connection with the server and then use it to create * requests which, when called using the appropriate method, will cause the server to be queried for the endpoint and * method specified in the request. */ declare class Client<GlobalErrorType extends ClientErrorType = Error, Adapter extends AdapterInstance = AdapterType, EndpointMapper extends DefaultEndpointMapper = DefaultEndpointMapper> { options: ClientOptionsType<Client<GlobalErrorType, Adapter, EndpointMapper>>; readonly url: string; debug: boolean; __onErrorCallbacks: ResponseInterceptorType[]; __onSuccessCallbacks: ResponseInterceptorType[]; __onResponseCallbacks: ResponseInterceptorType[]; __onAuthCallbacks: RequestInterceptorType[]; __onRequestCallbacks: RequestInterceptorType[]; requestManager: RequestManager; appManager: AppManager; loggerManager: LoggerManager; adapter: Adapter; cache: Cache<this>; fetchDispatcher: Dispatcher; submitDispatcher: Dispatcher; defaultMethod: ExtractAdapterMethodType<Adapter>; defaultExtra: ExtractAdapterExtraType<Adapter>; isMockEnabled: boolean; effects: RequestEffectInstance[]; queryParamsConfig?: QueryStringifyOptionsType; adapterDefaultOptions?: (request: RequestInstance) => ExtractAdapterOptionsType<Adapter>; requestDefaultOptions?: (options: RequestOptionsType<string, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>) => Partial<RequestOptionsType<string, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>>; abortKeyMapper?: (request: RequestInstance) => string; cacheKeyMapper?: (request: RequestInstance) => string; queueKeyMapper?: (request: RequestInstance) => string; effectKeyMapper?: (request: RequestInstance) => string; /** * Method to stringify query params from objects. */ stringifyQueryParams: StringifyCallbackType; /** * Method to get default headers and to map them based on the data format exchange, by default it handles FormData / JSON formats. */ headerMapper: HeaderMappingType; /** * Method to get request data and transform them to the required format. It handles FormData and JSON by default. */ payloadMapper: AdapterPayloadMappingType; /** * Method to get request data and transform them to the required format. It handles FormData and JSON by default. */ endpointMapper: EndpointMapper; logger: LoggerType; constructor(options: ClientOptionsType<Client<GlobalErrorType, Adapter, EndpointMapper>>); /** * This method allows to configure global defaults for the request configuration like method, auth, deduplication etc. */ setRequestDefaultOptions: (callback: (request: RequestInstance) => Partial<RequestOptionsType<string, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>>) => Client<GlobalErrorType, Adapter, EndpointMapper>; setAdapterDefaultOptions: (callback: (request: RequestInstance) => ExtractAdapterOptionsType<Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * This method enables the logger usage and display the logs in console */ setDebug: (debug: boolean) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set the logger severity of the messages displayed to the console */ setLoggerSeverity: (severity: SeverityType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set the new logger instance to the Client */ setLogger: (callback: (Client: ClientInstance) => LoggerManager) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set config for the query params stringify method, we can set here, among others, arrayFormat, skipNull, encode, skipEmptyString and more */ setQueryParamsConfig: (queryParamsConfig: QueryStringifyOptionsType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set the custom query params stringify method to the Client * @param stringifyFn Custom callback handling query params stringify */ setStringifyQueryParams: (stringifyFn: StringifyCallbackType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set the custom header mapping function */ setHeaderMapper: (headerMapper: HeaderMappingType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set the request payload mapping function which get triggered before request get send */ setPayloadMapper: (payloadMapper: AdapterPayloadMappingType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Set globally if mocking should be enabled or disabled for all client requests. * @param isMockEnabled */ setEnableGlobalMocking: (isMockEnabled: boolean) => this; /** * Set the request payload mapping function which get triggered before request get send */ setEndpointMapper: <NewEndpointMapper extends DefaultEndpointMapper>(endpointMapper: NewEndpointMapper) => Client<GlobalErrorType, Adapter, NewEndpointMapper>; /** * Set custom http adapter to handle graphql, rest, firebase or others */ setAdapter: <NewAdapter extends AdapterInstance, Returns extends AdapterInstance | ClientInstance>(callback: (client: this) => Returns extends AdapterInstance ? NewAdapter : Client<GlobalErrorType, NewAdapter, EndpointMapper>) => Client<GlobalErrorType, Returns extends AdapterInstance ? NewAdapter : ExtractAdapterType<NewAdapter>, EndpointMapper>; /** * Set default method for requests. */ setDefaultMethod: (defaultMethod: ExtractAdapterMethodType<Adapter>) => ClientInstance; /** * Set default additional data for initial state. */ setDefaultExtra: (defaultExtra: ExtractAdapterExtraType<Adapter>) => ClientInstance; /** * Method of manipulating requests before sending the request. We can for example add custom header with token to the request which request had the auth set to true. */ onAuth: (callback: RequestInterceptorType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for removing listeners on auth. * */ removeOnAuthInterceptors: (callbacks: RequestInterceptorType[]) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for intercepting error responses. It can be used for example to refresh tokens. */ onError: <ErrorType = null>(callback: ResponseInterceptorType<any, GlobalErrorType | ErrorType, Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for removing listeners on error. * */ removeOnErrorInterceptors: (callbacks: ResponseInterceptorType<any, null | GlobalErrorType, Adapter>[]) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for intercepting success responses. */ onSuccess: <ErrorType = null>(callback: ResponseInterceptorType<any, GlobalErrorType | ErrorType, Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for removing listeners on success. * */ removeOnSuccessInterceptors: (callbacks: ResponseInterceptorType<any, null | GlobalErrorType, Adapter>[]) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method of manipulating requests before sending the request. */ onRequest: (callback: RequestInterceptorType) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for removing listeners on request. * */ removeOnRequestInterceptors: (callbacks: RequestInterceptorType[]) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for intercepting any responses. */ onResponse: <ErrorType = null>(callback: ResponseInterceptorType<any, GlobalErrorType | ErrorType, Adapter>) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Method for removing listeners on request. * */ removeOnResponseInterceptors: (callbacks: ResponseInterceptorType<any, null | GlobalErrorType, Adapter>[]) => Client<GlobalErrorType, Adapter, EndpointMapper>; /** * Add persistent effects which trigger on the request lifecycle */ addEffect: (effect: RequestEffectInstance | RequestEffectInstance[]) => this; /** * Remove effects from Client */ removeEffect: (effect: RequestEffectInstance | string) => this; /** * Key setters */ setAbortKeyMapper: (callback: (request: RequestInstance) => string) => void; setCacheKeyMapper: (callback: (request: RequestInstance) => string) => void; setQueueKeyMapper: (callback: (request: RequestInstance) => string) => void; setEffectKeyMapper: (callback: (request: RequestInstance) => string) => void; /** * Helper used by http adapter to apply the modifications on response error */ __modifyAuth: (request: RequestInstance) => Promise<RequestInstance>; /** * Private helper to run async pre-request processing */ __modifyRequest: (request: RequestInstance) => Promise<RequestInstance>; /** * Private helper to run async on-error response processing */ __modifyErrorResponse: (response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>; /** * Private helper to run async on-success response processing */ __modifySuccessResponse: (response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>; /** * Private helper to run async response processing */ __modifyResponse: (response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>; /** * Clears the Client instance and remove all listeners on it's dependencies */ clear: () => void; /** * Create requests based on the Client setup */ createRequest: <Response_1, Payload = undefined, LocalError = undefined, QueryParams = ExtractAdapterQueryParamsType<Adapter>>() => <EndpointType extends ExtractAdapterEndpointType<Adapter>, AdapterOptions extends ExtractAdapterOptionsType<Adapter>, MethodType extends ExtractAdapterMethodType<Adapter>>(params: RequestOptionsType<EndpointType, AdapterOptions, MethodType>) => Request<Response_1, Payload, QueryParams, GlobalErrorType, LocalError, EndpointType extends string ? EndpointType : string, ExtractUnionAdapter<Adapter, { method: MethodType; options: AdapterOptions; queryParams: QueryParams; }> extends null ? Adapter : ExtractUnionAdapter<Adapter, { method: MethodType; options: AdapterOptions; queryParams: QueryParams; }>, false, false, false>; } type ClientErrorType = Record<string, any> | string; type ClientInstance = Client<any, AdapterType<any, any, any, any>>; type ExtractAdapterTypeFromClient<T> = T extends Client<any, infer A> ? A : never; /** * Configuration setup for the client */ type ClientOptionsType<C extends ClientInstance> = { /** * Url to your server */ url: string; /** * Custom adapter initialization prop */ adapter?: AdapterType; /** * Custom cache initialization prop */ cache?: (client: C) => C["cache"]; /** * Custom app manager initialization prop */ appManager?: (client: C) => C["appManager"]; /** * Custom fetch dispatcher initialization prop */ fetchDispatcher?: (client: C) => C["submitDispatcher"]; /** * Custom submit dispatcher initialization prop */ submitDispatcher?: (client: C) => C["fetchDispatcher"]; }; type RequestInterceptorType = (request: RequestInstance) => Promise<RequestInstance> | RequestInstance; type ResponseInterceptorType<Response = any, Error = any, Adapter extends AdapterInstance = AdapterType> = (response: ResponseReturnType<Response, Error, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, any, Adapter>> | ResponseReturnType<any, any, Adapter>; type StringifyCallbackType = (queryParams: QueryParamsType | string | NegativeTypes) => string; type DefaultEndpointMapper = (endpoint: any) => string; declare const stringifyValue: (response: string | unknown) => string; declare const interceptRequest: (interceptors: RequestInterceptorType[], request: RequestInstance) => Promise<RequestInstance>; declare const interceptResponse: <GlobalErrorType, Adapter extends AdapterInstance>(interceptors: ResponseInterceptorType[], response: ResponseReturnType<any, GlobalErrorType, Adapter>, request: RequestInstance) => Promise<ResponseReturnType<any, GlobalErrorType, Adapter>>; declare const getAdapterHeaders: (request: RequestInstance) => HeadersInit; declare const getAdapterPayload: (data: unknown) => string | FormData; declare const stringifyQueryParams: (queryParams: QueryParamsType | string | NegativeTypes, options?: QueryStringifyOptionsType) => string; declare const stringifyDefaultOptions: { readonly strict: true; readonly encode: true; readonly arrayFormat: "bracket"; readonly arraySeparator: "bracket"; readonly sort: false; readonly skipNull: true; readonly skipEmptyString: true; }; declare const mocker: <T extends AdapterInstance = AdapterType<Partial<XMLHttpRequest>, HttpMethodsType, number, AdapterExtraType, string | QueryParamsType, string>>(request: RequestInstance, { onError, onResponseEnd, onTimeoutError, onRequestEnd, createAbortListener, onResponseProgress, onRequestProgress, onResponseStart, onBeforeRequest, onRequestStart, onSuccess, }: Pick<{ fullUrl: string; data: any; headers: HeadersInit; payload: any; config: ExtractAdapterOptionsType<T>; getAbortController: () => AbortController; getRequestStartTimestamp: () => number; getResponseStartTimestamp: () => number; createAbortListener: (status: ExtractAdapterStatusType<T>, abortExtra: ExtractAdapterExtraType<T>, callback: () => void, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => () => void; onBeforeRequest: () => void; onRequestStart: (progress?: ProgressDataType) => number; onRequestProgress: (progress: ProgressDataType) => number; onRequestEnd: () => number; onResponseStart: (progress?: ProgressDataType) => number; onResponseProgress: (progress: ProgressDataType) => number; onResponseEnd: () => number; onSuccess: (responseData: any, status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<any, T>) => void) => Promise<ResponseReturnSuccessType<ExtractResponseType<T>, T>>; onAbortError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>; onTimeoutError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>; onUnexpectedError: (status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<ExtractErrorType<T>, T>) => void) => Promise<ResponseReturnErrorType<any, T>>; onError: (error: any, status: ExtractAdapterStatusType<T>, extra: ExtractAdapterExtraType<T>, resolve: (value: ResponseReturnErrorType<any, T>) => void) => Promise<ResponseReturnErrorType<any, T>>; makeRequest: (apiCall: (resolve: (value: ResponseReturnType<any, any, T> | PromiseLike<ResponseReturnType<any, any, T>>) => void) => void) => Promise<ResponseReturnType<any, any, T>>; }, "onRequestStart" | "onResponseStart" | "onError" | "onSuccess" | "onResponseEnd" | "onTimeoutError" | "onRequestEnd" | "createAbortListener" | "onResponseProgress" | "onRequestProgress" | "onBeforeRequest">) => Promise<ResponseReturnType<any, any, any>>; type RequestMockType<Response> = { data: Response | Response[] | (() => Response); status?: number | string; success?: boolean; config?: { timeout?: boolean; requestTime?: number; responseTime?: number; totalUploaded?: number; totalDownloaded?: number; }; extra?: any; }; type RequestDataMockTypes<Response, Request extends RequestInstance> = RequestMockType<Response> | RequestMockType<Response>[] | ((r: Request) => RequestMockType<Response>) | ((r: Request) => RequestMockType<Response>)[] | ((r: Request) => Promise<RequestMockType<Response>>) | ((r: Request) => Promise<RequestMockType<Response>>)[]; type GeneratorReturnMockTypes<Response, Request extends RequestInstance> = RequestMockType<Response> | ((r: Request) => RequestMockType<Response>) | ((r: Request) => Promise<RequestMockType<Response>>); /** * Fetch request it is designed to prepare the necessary setup to execute the request to the server. * We can set up basic options for example endpoint, method, headers and advanced settings like cache, invalidation patterns, concurrency, retries and much, much more. * :::info Usage * We should not use this class directly in the standard development flow. We can initialize it using the `createRequest` method on the **Client** class. * ::: * * @attention * The most important thing about the request is that it keeps data in the format that can be dumped. This is necessary for the persistence and different dispatcher storage types. * This class doesn't have any callback methods by design and communicate with dispatcher and cache by events. */ declare class Request<Response, Payload, QueryParams, GlobalError, // Global Error Type LocalError, // Additional Error for specific endpoint Endpoint extends string, Adapter extends AdapterInstance = AdapterType, HasData extends true | false = false, HasParams extends true | false = false, HasQuery extends true | false = false> { readonly client: Client<GlobalError, Adapter>; readonly requestOptions: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>; readonly requestJSON?: RequestCurrentType<Payload, QueryParams, Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>> | undefined; endpoint: Endpoint; headers?: HeadersInit; auth: boolean; method: ExtractAdapterMethodType<Adapter>; params: ExtractRouteParams<Endpoint> | NegativeTypes; data: PayloadType<Payload>; queryParams: QueryParams | NegativeTypes; options?: ExtractAdapterOptionsType<Adapter> | undefined; cancelable: boolean; retry: number; retryTime: number; garbageCollection: number; cache: boolean; cacheTime: number; queued: boolean; offline: boolean; abortKey: string; cacheKey: string; queueKey: string; effectKey: string; used: boolean; deduplicate: boolean; deduplicateTime: number; dataMapper?: PayloadMapperType<Payload>; mock?: Generator<GeneratorReturnMockTypes<Response, this>, GeneratorReturnMockTypes<Response, this>, GeneratorReturnMockTypes<Response, this>>; mockData?: RequestDataMockTypes<Response, this>; isMockEnabled: boolean; requestMapper?: RequestMapper<this, any>; responseMapper?: ResponseMapper<this, any, any>; private updatedAbortKey; private updatedCacheKey; private updatedQueueKey; private updatedEffectKey; constructor(client: Client<GlobalError, Adapter>, requestOptions: RequestOptionsType<Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>>, requestJSON?: RequestCurrentType<Payload, QueryParams, Endpoint, ExtractAdapterOptionsType<Adapter>, ExtractAdapterMethodType<Adapter>> | undefined); setHeaders: (headers: HeadersInit) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>; setAuth: (auth: boolean) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, HasQuery>; setParams: <P extends ExtractRouteParams<Endpoint>>(params: P) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, P extends null ? false : true, HasQuery>; setData: <D extends Payload>(data: D) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, D extends null ? false : true, HasParams, HasQuery>; setQueryParams: (queryParams: QueryParams) => Request<Response, Payload, QueryParams, GlobalError, LocalError, Endpoint, Adapter, HasData, HasParams, true>; setOptions: (options: ExtractAdapterOptionsType<Adapter>) => Request<Response, Payload, QueryParams, GlobalErr