diff --git a/examples/next-app-router/app/ssr/client-component.tsx b/examples/next-app-router/app/ssr/client-component.tsx index 9ffd976f..981eb3e4 100644 --- a/examples/next-app-router/app/ssr/client-component.tsx +++ b/examples/next-app-router/app/ssr/client-component.tsx @@ -1,7 +1,7 @@ "use client"; import React, { useState } from "react"; -import { ExtractAdapterReturnType, RequestInstance } from "@hyper-fetch/core"; +import { ExtractAdapterResolvedType, RequestInstance } from "@hyper-fetch/core"; import { UseFetchRequest, useFetch } from "@hyper-fetch/react"; import { Stack, Button } from "@mui/material"; import IconButton from "@mui/material/IconButton"; @@ -14,7 +14,7 @@ import { Request } from "../../components/request"; import { getUser } from "../../api"; export const ClientComponents: React.FC<{ - fallback: Partial>>; + fallback: Partial>>; }> = (props) => { const [dep, setDep] = useState(+new Date()); const [disabled, setDisabled] = useState(true); diff --git a/packages/core/src/cache/cache.ts b/packages/core/src/cache/cache.ts index 72709133..f2b0a974 100644 --- a/packages/core/src/cache/cache.ts +++ b/packages/core/src/cache/cache.ts @@ -1,6 +1,6 @@ import EventEmitter from "events"; -import { AdapterInstance, ResponseType } from "adapter"; +import { AdapterInstance, ExtractAdapterMethodType, ResponseType } from "adapter"; import { ClientInstance } from "client"; import { ResponseDetailsType, LoggerType } from "managers"; import { @@ -81,7 +81,7 @@ export class Cache { // Once refresh error occurs we don't want to override already valid data in our cache with the thrown error // We need to check it against cache and return last valid data we have - const processedResponse = typeof response === "function" ? response(cachedData) : response; + const processedResponse = typeof response === "function" ? response(cachedData || null) : response; const data = getCacheData(cachedData, processedResponse); const newCacheData: CacheValueType> = { @@ -92,7 +92,7 @@ export class Cache { queueKey: request.queueKey, effectKey: request.effectKey, endpoint: request.endpoint, - method: request.method, + method: request.method as ExtractAdapterMethodType>, garbageCollection, }; @@ -140,7 +140,8 @@ export class Cache { ExtractAdapterType >(cacheKey); - const processedResponse = typeof partialResponse === "function" ? partialResponse(cachedData) : partialResponse; + const processedResponse = + typeof partialResponse === "function" ? partialResponse(cachedData || null) : partialResponse; if (cachedData) { this.set(request, { ...cachedData, ...processedResponse }); } diff --git a/packages/core/src/cache/cache.types.ts b/packages/core/src/cache/cache.types.ts index c9aa72e3..dab8008d 100644 --- a/packages/core/src/cache/cache.types.ts +++ b/packages/core/src/cache/cache.types.ts @@ -1,5 +1,5 @@ import { Cache } from "cache"; -import { AdapterInstance, ResponseType } from "adapter"; +import { AdapterInstance, ExtractAdapterMethodType, ResponseType } from "adapter"; import { ResponseDetailsType } from "managers"; import { ClientInstance } from "../client"; import { RequestInstance } from "request"; @@ -47,7 +47,7 @@ export type CacheValueType< queueKey: string; effectKey: string; endpoint: string; - method: string; + method: ExtractAdapterMethodType; garbageCollection: number; }; diff --git a/packages/core/src/cache/cache.utils.ts b/packages/core/src/cache/cache.utils.ts index 2460f91e..e265df54 100644 --- a/packages/core/src/cache/cache.utils.ts +++ b/packages/core/src/cache/cache.utils.ts @@ -1,11 +1,11 @@ import { ResponseDetailsType } from "managers"; import { RequestInstance } from "request"; -import { ExtractAdapterReturnType } from "types"; +import { ExtractAdapterResolvedType } from "types"; export const getCacheData = ( - previousResponse: ExtractAdapterReturnType | undefined, - response: ExtractAdapterReturnType & ResponseDetailsType, -): ExtractAdapterReturnType & ResponseDetailsType => { + previousResponse: ExtractAdapterResolvedType | undefined, + response: ExtractAdapterResolvedType & ResponseDetailsType, +): ExtractAdapterResolvedType & ResponseDetailsType => { const { data, success } = response; const previousData = !success && previousResponse ? previousResponse.data : null; diff --git a/packages/core/src/client/client.ts b/packages/core/src/client/client.ts index 7e07da80..85b42bdf 100644 --- a/packages/core/src/client/client.ts +++ b/packages/core/src/client/client.ts @@ -44,9 +44,7 @@ import { ExtractAdapterType, NegativeTypes } from "types"; export class Client< GlobalErrorType extends ClientErrorType = Error, Adapter extends AdapterInstance = AdapterType, - EndpointMapper extends DefaultEndpointMapper = ( - endpoint: ExtractAdapterEndpointType, - ) => ExtractAdapterEndpointType, + EndpointMapper extends DefaultEndpointMapper = (endpoint: any) => any, > { readonly url: string; public debug: boolean; @@ -506,7 +504,7 @@ export class Client< LocalError, EndpointType extends string ? EndpointType : typeof endpoint, Client - >(this as any, mappedParams); + >(this as unknown as Client, mappedParams); }; }; } diff --git a/packages/core/src/client/client.types.ts b/packages/core/src/client/client.types.ts index d8475937..bf28c3ca 100644 --- a/packages/core/src/client/client.types.ts +++ b/packages/core/src/client/client.types.ts @@ -50,4 +50,4 @@ export type StringifyCallbackType = (queryParams: QueryParamsType | string | Neg // Mapper -export type DefaultEndpointMapper = (endpoint: any) => EndpointType; +export type DefaultEndpointMapper = (endpoint: EndpointType) => string; diff --git a/packages/core/src/managers/request/request.manager.events.ts b/packages/core/src/managers/request/request.manager.events.ts index dbc84337..4eb3f55f 100644 --- a/packages/core/src/managers/request/request.manager.events.ts +++ b/packages/core/src/managers/request/request.manager.events.ts @@ -33,6 +33,7 @@ import { } from "managers"; import { AdapterInstance } from "adapter"; import { ExtendRequest, RequestInstance } from "request"; +import { Client } from "client"; export const getRequestManagerEvents = (emitter: EventEmitter) => ({ /** @@ -72,7 +73,7 @@ export const getRequestManagerEvents = (emitter: EventEmitter) => ({ // Response emitResponse: ( - data: RequestResponseEventType>, + data: RequestResponseEventType }>>, ): void => { emitter.emit(getResponseKey(), data); emitter.emit(getResponseByIdKey(data.requestId), data); diff --git a/packages/core/src/request/request.ts b/packages/core/src/request/request.ts index 9e19562d..dc82ce83 100644 --- a/packages/core/src/request/request.ts +++ b/packages/core/src/request/request.ts @@ -15,16 +15,11 @@ import { } from "request"; import { ClientErrorType, ClientInstance } from "client"; import { getUniqueRequestId } from "utils"; -import { - ExtractAdapterMethodType, - ExtractAdapterOptionsType, - QueryParamsType, - ResponseType, - ExtractAdapterEndpointType, -} from "adapter"; +import { ExtractAdapterMethodType, ExtractAdapterOptionsType, QueryParamsType, ResponseType } from "adapter"; import { ExtractClientAdapterType, ExtractClientGlobalError, + ExtractEndpointType, ExtractParamsType, ExtractPayloadType, ExtractQueryParamsType, @@ -56,7 +51,7 @@ export class Request< Payload, QueryParams, LocalError extends ClientErrorType, // Additional Error for specific endpoint - Endpoint extends ExtractAdapterEndpointType>, + Endpoint extends string, Client extends ClientInstance, HasData extends true | false = false, HasParams extends true | false = false, @@ -397,8 +392,12 @@ export class Request< public toJSON(): RequestJSON { return { - requestOptions: this.requestOptions, - endpoint: this.endpoint, + requestOptions: this.requestOptions as RequestOptionsType< + ExtractEndpointType, + ExtractAdapterOptionsType>, + ExtractAdapterMethodType> + >, + endpoint: this.endpoint as ExtractEndpointType, headers: this.headers, auth: this.auth, method: this.method, diff --git a/packages/core/src/request/request.types.ts b/packages/core/src/request/request.types.ts index 3cde0e63..8bf060fb 100644 --- a/packages/core/src/request/request.types.ts +++ b/packages/core/src/request/request.types.ts @@ -34,11 +34,11 @@ export type AdapterProgressType = { */ export type RequestJSON = { requestOptions: RequestOptionsType< - ExtractAdapterEndpointType>, + ExtractEndpointType, ExtractAdapterOptionsType>, ExtractAdapterMethodType> >; - endpoint: ExtractAdapterEndpointType>; + endpoint: ExtractEndpointType; method: ExtractAdapterMethodType>; headers?: HeadersInit; auth: boolean; @@ -170,7 +170,7 @@ export type RequestConfigurationType< Payload, Params, QueryParams, - GenericEndpoint, + GenericEndpoint extends string, AdapterOptions, MethodsType = HttpMethodsType, > = { @@ -291,11 +291,7 @@ export type ExtendRequest< TypeWithDefaults>, TypeWithDefaults>, TypeWithDefaults>, - Properties["endpoint"] extends ExtractAdapterEndpointType> - ? Properties["endpoint"] - : ExtractEndpointType extends ExtractAdapterEndpointType> - ? ExtractEndpointType - : never, + Properties["endpoint"] extends string ? Properties["endpoint"] : ExtractEndpointType, Properties["client"] extends ClientInstance ? Properties["client"] : ExtractClientType, Properties["hasData"] extends true ? true : ExtractHasDataType, Properties["hasParams"] extends true ? true : ExtractHasParamsType, diff --git a/packages/core/src/request/request.utils.ts b/packages/core/src/request/request.utils.ts index 55f13fca..b03887f2 100644 --- a/packages/core/src/request/request.utils.ts +++ b/packages/core/src/request/request.utils.ts @@ -145,7 +145,7 @@ export const sendRequest = ( const { details, response } = values; isResolved = true; - const mapping = request.responseMapper?.(response); + const mapping = request.__responseMapper?.(response); const isOfflineStatus = request.offline && details.isOffline; const willRetry = canRetryRequest(details.retries, request.retry); diff --git a/packages/core/src/types/fetch.types.ts b/packages/core/src/types/fetch.types.ts index 63c0cf42..572d8b41 100644 --- a/packages/core/src/types/fetch.types.ts +++ b/packages/core/src/types/fetch.types.ts @@ -2,7 +2,7 @@ import { ResponseType } from "adapter"; import { ExtractRouteParams, Request, RequestInstance } from "request"; import { ExtractClientAdapterType, ExtractClientGlobalError } from "./client.types"; -export type ExtractAdapterReturnType = ResponseType< +export type ExtractAdapterResolvedType = ResponseType< ExtractResponseType, ExtractErrorType, ExtractAdapterType diff --git a/packages/react/__tests__/features/use-submit/use-submit.debounce.spec.ts b/packages/react/__tests__/features/use-submit/use-submit.debounce.spec.ts index f8a66289..e515f70c 100644 --- a/packages/react/__tests__/features/use-submit/use-submit.debounce.spec.ts +++ b/packages/react/__tests__/features/use-submit/use-submit.debounce.spec.ts @@ -1,4 +1,4 @@ -import { RequestInstance, ExtractAdapterReturnType } from "@hyper-fetch/core"; +import { RequestInstance, ExtractAdapterResolvedType } from "@hyper-fetch/core"; import { act, waitFor } from "@testing-library/react"; import { createHttpMockingServer } from "@hyper-fetch/testing"; @@ -85,7 +85,7 @@ describe("useSubmit [ Bounce ]", () => { mockRequest(request); const response = renderUseSubmit(request, hookDebounceOptions); - let value: ExtractAdapterReturnType[] = []; + let value: ExtractAdapterResolvedType[] = []; await act(async () => { const promiseOne = await response.result.current.submit(); await waitForRender(1); @@ -99,7 +99,7 @@ describe("useSubmit [ Bounce ]", () => { }); expect(value).toHaveLength(4); - const isResponse = (res: ExtractAdapterReturnType) => { + const isResponse = (res: ExtractAdapterResolvedType) => { return !!res.data && !res.error && res.status === 200 && res.extra; }; expect(value).toSatisfyAny(isResponse); @@ -229,7 +229,7 @@ describe("useSubmit [ Bounce ]", () => { mockRequest(request); const response = renderUseSubmit(request, hookThrottleOptions); - let value: ExtractAdapterReturnType[] = []; + let value: ExtractAdapterResolvedType[] = []; await act(async () => { const promiseOne = await response.result.current.submit(); await waitForRender(1); @@ -243,7 +243,7 @@ describe("useSubmit [ Bounce ]", () => { }); expect(value).toHaveLength(4); - const isResponse = (res: ExtractAdapterReturnType) => { + const isResponse = (res: ExtractAdapterResolvedType) => { return !!res.data && !res.error && res.status === 200 && !!res.extra; }; expect(value).toSatisfyAny(isResponse); diff --git a/packages/react/src/helpers/use-tracked-state/use-tracked-state.types.ts b/packages/react/src/helpers/use-tracked-state/use-tracked-state.types.ts index 7b70cdb4..be26d75b 100644 --- a/packages/react/src/helpers/use-tracked-state/use-tracked-state.types.ts +++ b/packages/react/src/helpers/use-tracked-state/use-tracked-state.types.ts @@ -8,7 +8,7 @@ import { ExtractAdapterType, ExtractAdapterStatusType, ExtractAdapterExtraType, - ExtractAdapterReturnType, + ExtractAdapterResolvedType, NullableType, } from "@hyper-fetch/core"; @@ -17,7 +17,7 @@ import { isEqual } from "utils"; export type UseTrackedStateProps = { request: T; logger: LoggerType; - initialData: NullableType>>; + initialData: NullableType>>; dispatcher: Dispatcher; dependencyTracking: boolean; defaultCacheEmitting?: boolean; diff --git a/packages/react/src/helpers/use-tracked-state/use-tracked-state.utils.ts b/packages/react/src/helpers/use-tracked-state/use-tracked-state.utils.ts index 4c453f77..9dcbc1ee 100644 --- a/packages/react/src/helpers/use-tracked-state/use-tracked-state.utils.ts +++ b/packages/react/src/helpers/use-tracked-state/use-tracked-state.utils.ts @@ -4,7 +4,7 @@ import { RequestInstance, ExtractResponseType, ExtractErrorType, - ExtractAdapterReturnType, + ExtractAdapterResolvedType, Dispatcher, ExtractAdapterType, ExtractAdapterExtraType, @@ -33,7 +33,7 @@ export const isStaleCacheData = (cacheTime: number, cacheTimestamp: NullableType export const getValidCacheData = ( request: T, - initialData: NullableType>>, + initialData: NullableType>>, cacheData: NullableType, ExtractErrorType, ExtractAdapterType>>, ): CacheValueType, ExtractErrorType, ExtractAdapterType> | null => { const isStale = isStaleCacheData(request.cacheTime, cacheData?.timestamp); @@ -49,7 +49,7 @@ export const getValidCacheData = ( status: null, success: true, extra: null, - ...((initialData || {}) as Partial>), + ...((initialData || {}) as Partial>), ...getDetailsState(), cacheTime: 1000, clearKey: request.client.cache.clearKey, @@ -70,7 +70,7 @@ export const getTimestamp = (timestamp?: NullableType) => { }; export const getInitialState = ( - initialData: NullableType>>, + initialData: NullableType>>, dispatcher: Dispatcher, request: T, ): UseTrackedStateType => { diff --git a/packages/react/src/hooks/use-fetch/use-fetch.types.ts b/packages/react/src/hooks/use-fetch/use-fetch.types.ts index 8fa6306e..8b82a322 100644 --- a/packages/react/src/hooks/use-fetch/use-fetch.types.ts +++ b/packages/react/src/hooks/use-fetch/use-fetch.types.ts @@ -1,7 +1,7 @@ import { RequestInstance, NullableType, - ExtractAdapterReturnType, + ExtractAdapterResolvedType, ExtendRequest, ExtractPayloadType, ExtractParamsType, @@ -40,7 +40,7 @@ export type UseFetchOptionsType = { /** * If cache is empty we can use placeholder data. */ - initialData?: NullableType>>; + initialData?: NullableType>>; /** * Enable/disable refresh data */ diff --git a/packages/react/src/hooks/use-submit/use-submit.hooks.ts b/packages/react/src/hooks/use-submit/use-submit.hooks.ts index 0e34df6f..1539009c 100644 --- a/packages/react/src/hooks/use-submit/use-submit.hooks.ts +++ b/packages/react/src/hooks/use-submit/use-submit.hooks.ts @@ -2,7 +2,7 @@ import { useMemo, useRef } from "react"; import { Request, getRequestKey, - ExtractAdapterReturnType, + ExtractAdapterResolvedType, RequestInstance, sendRequest, ResponseType, @@ -126,7 +126,7 @@ export const useSubmit = ( }); }; - return new Promise>((resolve) => { + return new Promise>((resolve) => { const performSubmit = async () => { logger.debug(`Submitting request`, { disabled, submitOptions }); if (bounce) { diff --git a/packages/react/src/hooks/use-submit/use-submit.types.ts b/packages/react/src/hooks/use-submit/use-submit.types.ts index 3cc1cf8e..774763e1 100644 --- a/packages/react/src/hooks/use-submit/use-submit.types.ts +++ b/packages/react/src/hooks/use-submit/use-submit.types.ts @@ -1,4 +1,4 @@ -import { ExtractAdapterReturnType, NullableType, RequestInstance, RequestSendType } from "@hyper-fetch/core"; +import { ExtractAdapterResolvedType, NullableType, RequestInstance, RequestSendType } from "@hyper-fetch/core"; import { isEqual } from "utils"; import { @@ -20,7 +20,7 @@ export type UseSubmitOptionsType = { /** * If cache is empty we can use placeholder data. */ - initialData?: NullableType>>; + initialData?: NullableType>>; /** * Enable/disable debouncing for often changing keys or refreshing, to limit requests to server. */