From e19f0c17a743dab01e09943e0cdd21f71aac4047 Mon Sep 17 00:00:00 2001 From: Dorian Maliszewski Date: Wed, 13 Jul 2022 16:13:42 +0200 Subject: [PATCH] fix: use-dataloader types improvement --- .../use-dataloader/src/DataLoaderProvider.tsx | 23 ++++++----- .../src/__tests__/useDataLoader.test.tsx | 2 +- packages/use-dataloader/src/dataloader.ts | 6 +-- packages/use-dataloader/src/types.ts | 40 ++++++++++--------- packages/use-dataloader/src/useDataLoader.ts | 9 ++--- .../src/usePaginatedDataLoader.ts | 12 +++--- 6 files changed, 51 insertions(+), 41 deletions(-) diff --git a/packages/use-dataloader/src/DataLoaderProvider.tsx b/packages/use-dataloader/src/DataLoaderProvider.tsx index 81ef3e085..500f05f64 100644 --- a/packages/use-dataloader/src/DataLoaderProvider.tsx +++ b/packages/use-dataloader/src/DataLoaderProvider.tsx @@ -17,10 +17,10 @@ import { OnErrorFn, PromiseType } from './types' type CachedData = Record type Reloads = Record Promise> -type Requests = Record +type Requests = Record> -type UseDataLoaderInitializerArgs = { - method: () => PromiseType +type UseDataLoaderInitializerArgs = { + method: () => PromiseType /** * Max time before data from previous success is considered as outdated (in millisecond) */ @@ -38,19 +38,24 @@ type GetReloadsFn = { (key?: string): (() => Promise) | undefined } -export interface IDataLoaderContext { - addRequest: (key: string, args: UseDataLoaderInitializerArgs) => DataLoader - getOrAddRequest: ( +export type IDataLoaderContext = { + addRequest: ( key: string, - args: UseDataLoaderInitializerArgs, - ) => DataLoader + args: UseDataLoaderInitializerArgs, + ) => DataLoader + getOrAddRequest: ( + key: string, + args: UseDataLoaderInitializerArgs, + ) => DataLoader cacheKeyPrefix?: string onError?: (error: Error) => void | Promise clearAllCachedData: () => void clearCachedData: (key: string) => void getCachedData: GetCachedDataFn getReloads: GetReloadsFn - getRequest: (key: string) => DataLoader + getRequest: ( + key: string, + ) => DataLoader reload: (key?: string) => Promise reloadAll: () => Promise } diff --git a/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx b/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx index 00f90d090..a73c71082 100644 --- a/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx +++ b/packages/use-dataloader/src/__tests__/useDataLoader.test.tsx @@ -7,7 +7,7 @@ import { UseDataLoaderConfig } from '../types' import useDataLoader from '../useDataLoader' type UseDataLoaderHookProps = { - config: UseDataLoaderConfig + config: UseDataLoaderConfig key: string method: () => Promise children?: ReactNode diff --git a/packages/use-dataloader/src/dataloader.ts b/packages/use-dataloader/src/dataloader.ts index 4dad0814e..d53f6b6ce 100644 --- a/packages/use-dataloader/src/dataloader.ts +++ b/packages/use-dataloader/src/dataloader.ts @@ -1,14 +1,14 @@ import { DEFAULT_MAX_CONCURRENT_REQUESTS, StatusEnum } from './constants' import { PromiseType } from './types' -export type DataLoaderConstructorArgs = { +export type DataLoaderConstructorArgs = { key: string - method: () => PromiseType + method: () => PromiseType enabled?: boolean notifyChanges?: () => void } -class DataLoader { +class DataLoader { public static maxConcurrent = DEFAULT_MAX_CONCURRENT_REQUESTS public static started = 0 diff --git a/packages/use-dataloader/src/types.ts b/packages/use-dataloader/src/types.ts index e03a3d984..2a0421e87 100644 --- a/packages/use-dataloader/src/types.ts +++ b/packages/use-dataloader/src/types.ts @@ -2,12 +2,16 @@ export class PromiseType extends Promise { public cancel?: () => void } -export type OnErrorFn = ((err: Error) => void | Promise) | undefined -export type OnSuccessFn = - | ((result: T) => void | Promise) +export type OnErrorFn = + | ((err: ErrorType) => void | Promise) + | undefined +export type OnSuccessFn = + | ((result: ResultType) => void | Promise) | undefined export type OnCancelFn = (() => void | Promise) | undefined -export type NeedPollingType = boolean | ((data?: T) => boolean) +export type NeedPollingType = + | boolean + | ((data?: ResultType) => boolean) /** * @typedef {Object} UseDataLoaderConfig @@ -20,15 +24,15 @@ export type NeedPollingType = boolean | ((data?: T) => boolean) * @property {number} [dataLifetime=undefined] Time before data from previous success is considered as outdated (in millisecond) * @property {NeedPollingType} [needPolling=true] When pollingInterval is set you can set a set a custom callback to know if polling is enabled */ -export interface UseDataLoaderConfig { +export interface UseDataLoaderConfig { enabled?: boolean - initialData?: T + initialData?: ResultType keepPreviousData?: boolean - onError?: OnErrorFn - onSuccess?: OnSuccessFn + onError?: OnErrorFn + onSuccess?: OnSuccessFn pollingInterval?: number dataLifetime?: number - needPolling?: NeedPollingType + needPolling?: NeedPollingType } /** @@ -43,15 +47,15 @@ export interface UseDataLoaderConfig { * @property {string} error the error occured during the request * @property {Function} reload reload the data */ -export interface UseDataLoaderResult { - data?: T +export interface UseDataLoaderResult { + data?: ResultType error?: ErrorType isError: boolean isIdle: boolean isLoading: boolean isPolling: boolean isSuccess: boolean - previousData?: T + previousData?: ResultType reload: () => Promise } @@ -63,16 +67,16 @@ export type UsePaginatedDataLoaderMethodParams = { perPage: number } -export type UsePaginatedDataLoaderConfig = - UseDataLoaderConfig & { +export type UsePaginatedDataLoaderConfig = + UseDataLoaderConfig & { initialPage?: number perPage?: number } -export type UsePaginatedDataLoaderResult = { - pageData?: T - data?: Record - error?: Error +export type UsePaginatedDataLoaderResult = { + pageData?: ResultType + data?: Record + error?: ErrorType isError: boolean isIdle: boolean isLoading: boolean diff --git a/packages/use-dataloader/src/useDataLoader.ts b/packages/use-dataloader/src/useDataLoader.ts index 355db7376..5956b3000 100644 --- a/packages/use-dataloader/src/useDataLoader.ts +++ b/packages/use-dataloader/src/useDataLoader.ts @@ -1,10 +1,9 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useDataLoaderContext } from './DataLoaderProvider' import { StatusEnum } from './constants' -import DataLoader from './dataloader' import { PromiseType, UseDataLoaderConfig, UseDataLoaderResult } from './types' -function useDataLoader( +function useDataLoader( fetchKey: string, method: () => PromiseType, { @@ -16,7 +15,7 @@ function useDataLoader( pollingInterval, initialData, dataLifetime, - }: UseDataLoaderConfig = {}, + }: UseDataLoaderConfig = {}, ): UseDataLoaderResult { const { getOrAddRequest, onError: onGlobalError } = useDataLoaderContext() const methodRef = useRef(method) @@ -28,10 +27,10 @@ function useDataLoader( setCounter(current => current + 1) }, []) - const request = getOrAddRequest(fetchKey, { + const request = getOrAddRequest(fetchKey, { enabled, method: methodRef.current, - }) as DataLoader + }) useEffect(() => { request.addObserver(forceRerender) diff --git a/packages/use-dataloader/src/usePaginatedDataLoader.ts b/packages/use-dataloader/src/usePaginatedDataLoader.ts index a2df1be76..54e41479a 100644 --- a/packages/use-dataloader/src/usePaginatedDataLoader.ts +++ b/packages/use-dataloader/src/usePaginatedDataLoader.ts @@ -14,9 +14,11 @@ import useDataLoader from './useDataLoader' * @param {useDataLoaderConfig} config hook configuration * @returns {useDataLoaderResult} hook result containing data, request state, and method to reload the data */ -const usePaginatedDataLoader = ( +const usePaginatedDataLoader = ( baseFetchKey: string, - method: (params: UsePaginatedDataLoaderMethodParams) => PromiseType, + method: ( + params: UsePaginatedDataLoaderMethodParams, + ) => PromiseType, { enabled = true, initialData, @@ -28,13 +30,13 @@ const usePaginatedDataLoader = ( needPolling, initialPage, perPage = 1, - }: UsePaginatedDataLoaderConfig = {}, -): UsePaginatedDataLoaderResult => { + }: UsePaginatedDataLoaderConfig = {}, +): UsePaginatedDataLoaderResult => { if (typeof baseFetchKey !== 'string') { throw new Error(KEY_IS_NOT_STRING_ERROR) } - const [data, setData] = useState>({}) + const [data, setData] = useState>({}) const [page, setPage] = useState(initialPage ?? 1) const pageMethod = useCallback(