@ventlio/tanstack-query 0.2.73 → 0.2.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +69 -8
- package/dist/index.mjs.map +1 -1
- package/dist/queries/index.d.ts +1 -0
- package/dist/queries/queries.interface.d.ts +2 -1
- package/dist/queries/useDeleteRequest.js +4 -3
- package/dist/queries/useDeleteRequest.js.map +1 -1
- package/dist/queries/useGetInfiniteRequest.d.ts +175 -0
- package/dist/queries/useGetInfiniteRequest.js +70 -0
- package/dist/queries/useGetInfiniteRequest.js.map +1 -0
- package/dist/queries/useGetRequest.js +4 -3
- package/dist/queries/useGetRequest.js.map +1 -1
- package/package.json +1 -1
- package/src/queries/index.ts +1 -0
- package/src/queries/queries.interface.ts +8 -1
- package/src/queries/useDeleteRequest.ts +7 -4
- package/src/queries/useGetInfiniteRequest.ts +123 -0
- package/src/queries/useGetRequest.ts +8 -4
package/README.md
CHANGED
|
@@ -18,9 +18,11 @@ But we were not discouraged. So, we set out to find a solution which led to the
|
|
|
18
18
|
- [✅] Requests context implementations
|
|
19
19
|
- [✅] Post, Get, Patch Requests
|
|
20
20
|
- [✅] Query key tracker to track dynamic query and help fetch query cache from any page
|
|
21
|
-
- [
|
|
21
|
+
- [✅] Persistent queries implementation (Not completed)
|
|
22
22
|
- [❌] Put request
|
|
23
23
|
- [❌] Generic return type (this is currently an issue if the API does not return object with the necessary properties required by the library)
|
|
24
|
+
- [❌] Generic Pagination for any response without infinite queries
|
|
25
|
+
- [❌] Infinite Get Query implementation (still using implementation meant for our use case)
|
|
24
26
|
- [❌] Server sent events
|
|
25
27
|
- [❌] Socket implementations
|
|
26
28
|
- [❌] Tests
|
|
@@ -299,10 +301,11 @@ import { usePatchRequest } from '@ventlio/tanstack-query';
|
|
|
299
301
|
|
|
300
302
|
function App() {
|
|
301
303
|
const { patch, isLoading, isError, isSuccess, data } =
|
|
302
|
-
usePatchRequest<
|
|
304
|
+
usePatchRequest <
|
|
305
|
+
User >
|
|
303
306
|
{
|
|
304
307
|
path: '/users/1',
|
|
305
|
-
}
|
|
308
|
+
};
|
|
306
309
|
|
|
307
310
|
const updateUser = async (user: User) => {
|
|
308
311
|
await patch(user);
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { useKeyTrackerModel } from './model/useKeyTrackerModel.js';
|
|
|
9
9
|
export { useQueryModel } from './model/useQueryModel.js';
|
|
10
10
|
export { useRefetchQuery } from './model/useRefetchQuery.js';
|
|
11
11
|
export { useDeleteRequest } from './queries/useDeleteRequest.js';
|
|
12
|
+
export { useGetInfiniteRequest } from './queries/useGetInfiniteRequest.js';
|
|
12
13
|
export { useGetRequest } from './queries/useGetRequest.js';
|
|
13
14
|
export { usePatchRequest } from './queries/usePatchRequest.js';
|
|
14
15
|
export { usePostRequest } from './queries/usePostRequest.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import 'url-search-params-polyfill';
|
|
2
|
-
import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
|
|
2
|
+
import { useQueryClient, useQuery, useInfiniteQuery, useMutation } from '@tanstack/react-query';
|
|
3
3
|
import result from 'lodash.result';
|
|
4
4
|
import lodashSet from 'lodash.set';
|
|
5
5
|
import { useState, useMemo, useEffect, startTransition } from 'react';
|
|
@@ -396,11 +396,12 @@ const useDeleteRequest = (deleteOptions) => {
|
|
|
396
396
|
const [options, setOptions] = useState();
|
|
397
397
|
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
398
398
|
const { getHeaders } = useQueryHeaders();
|
|
399
|
-
const sendRequest = async (res, rej) => {
|
|
399
|
+
const sendRequest = async (res, rej, queryKey) => {
|
|
400
400
|
// get request headers
|
|
401
401
|
const globalHeaders = getHeaders();
|
|
402
|
+
const [url] = (queryKey ?? []);
|
|
402
403
|
const postResponse = await makeRequest({
|
|
403
|
-
path: requestPath,
|
|
404
|
+
path: url ?? requestPath,
|
|
404
405
|
headers: { ...globalHeaders, ...headers },
|
|
405
406
|
method: HttpMethod.DELETE,
|
|
406
407
|
baseURL: baseUrl ?? API_URL,
|
|
@@ -413,7 +414,7 @@ const useDeleteRequest = (deleteOptions) => {
|
|
|
413
414
|
rej(postResponse);
|
|
414
415
|
}
|
|
415
416
|
};
|
|
416
|
-
const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), { enabled: false, ...options });
|
|
417
|
+
const query = useQuery([requestPath, {}], ({ queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey)), { enabled: false, ...options });
|
|
417
418
|
const updatedPathAsync = async (link) => {
|
|
418
419
|
return updateDeletePath(link);
|
|
419
420
|
};
|
|
@@ -431,6 +432,65 @@ const useDeleteRequest = (deleteOptions) => {
|
|
|
431
432
|
return { destroy, ...query };
|
|
432
433
|
};
|
|
433
434
|
|
|
435
|
+
const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
|
|
436
|
+
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
437
|
+
const { getHeaders } = useQueryHeaders();
|
|
438
|
+
let queryClient = useQueryClient();
|
|
439
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
440
|
+
queryClient = useMemo(() => queryClient, []);
|
|
441
|
+
const sendRequest = async (res, rej, pageParam) => {
|
|
442
|
+
if (load) {
|
|
443
|
+
// get request headers
|
|
444
|
+
const globalHeaders = getHeaders();
|
|
445
|
+
const getResponse = await makeRequest({
|
|
446
|
+
path: pageParam ?? path,
|
|
447
|
+
headers: { ...globalHeaders, ...headers },
|
|
448
|
+
baseURL: baseUrl ?? API_URL,
|
|
449
|
+
timeout: TIMEOUT,
|
|
450
|
+
});
|
|
451
|
+
if (getResponse.status) {
|
|
452
|
+
res(getResponse);
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
rej(getResponse);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
else {
|
|
459
|
+
res(null);
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
const query = useInfiniteQuery([path, {}], ({ pageParam = path }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
|
|
463
|
+
enabled: load,
|
|
464
|
+
getNextPageParam: (lastPage, pages) => constructPaginationLink('next_page', lastPage, pages),
|
|
465
|
+
getPreviousPageParam: (lastPage, pages) => constructPaginationLink('previous_page', lastPage, pages),
|
|
466
|
+
...queryOptions,
|
|
467
|
+
});
|
|
468
|
+
/**
|
|
469
|
+
*
|
|
470
|
+
* This pagination implementation is currently tied to our use case
|
|
471
|
+
*/
|
|
472
|
+
const constructPaginationLink = (direction, lastPage, pages) => {
|
|
473
|
+
const [pathname, queryString] = lastPage.split('?');
|
|
474
|
+
const queryParams = new URLSearchParams(queryString);
|
|
475
|
+
const lastPageItem = pages[pages.length - 1];
|
|
476
|
+
queryParams.set('page', String(lastPageItem?.data.pagination[direction]));
|
|
477
|
+
return pathname + '?' + queryParams.toString();
|
|
478
|
+
};
|
|
479
|
+
useEffect(() => {
|
|
480
|
+
if (keyTracker) {
|
|
481
|
+
// set expiration time for the tracker
|
|
482
|
+
queryClient.setQueryDefaults([keyTracker], {
|
|
483
|
+
cacheTime: Infinity,
|
|
484
|
+
staleTime: Infinity,
|
|
485
|
+
});
|
|
486
|
+
queryClient.setQueryData([keyTracker], [path, {}]);
|
|
487
|
+
}
|
|
488
|
+
}, [keyTracker, path, queryClient, queryOptions?.staleTime]);
|
|
489
|
+
return {
|
|
490
|
+
...query,
|
|
491
|
+
};
|
|
492
|
+
};
|
|
493
|
+
|
|
434
494
|
const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
|
|
435
495
|
const [requestPath, updatePath] = useState(path);
|
|
436
496
|
const [options, setOptions] = useState(queryOptions);
|
|
@@ -440,12 +500,13 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
|
|
|
440
500
|
let queryClient = useQueryClient();
|
|
441
501
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
442
502
|
queryClient = useMemo(() => queryClient, []);
|
|
443
|
-
const sendRequest = async (res, rej) => {
|
|
503
|
+
const sendRequest = async (res, rej, queryKey) => {
|
|
444
504
|
if (load) {
|
|
445
505
|
// get request headers
|
|
446
506
|
const globalHeaders = getHeaders();
|
|
507
|
+
const [url] = (queryKey ?? []);
|
|
447
508
|
const getResponse = await makeRequest({
|
|
448
|
-
path: requestPath,
|
|
509
|
+
path: url ?? requestPath,
|
|
449
510
|
headers: { ...globalHeaders, ...headers },
|
|
450
511
|
baseURL: baseUrl ?? API_URL,
|
|
451
512
|
timeout: TIMEOUT,
|
|
@@ -461,7 +522,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
|
|
|
461
522
|
res(null);
|
|
462
523
|
}
|
|
463
524
|
};
|
|
464
|
-
const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), {
|
|
525
|
+
const query = useQuery([requestPath, {}], ({ queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey)), {
|
|
465
526
|
enabled: load,
|
|
466
527
|
...options,
|
|
467
528
|
});
|
|
@@ -624,5 +685,5 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
|
|
|
624
685
|
return { post, ...mutation };
|
|
625
686
|
};
|
|
626
687
|
|
|
627
|
-
export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
|
|
688
|
+
export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetInfiniteRequest, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
|
|
628
689
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/queries/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UseQueryOptions } from '@tanstack/react-query';
|
|
1
|
+
import type { UseInfiniteQueryOptions, UseQueryOptions } from '@tanstack/react-query';
|
|
2
2
|
import type { RawAxiosRequestHeaders } from 'axios';
|
|
3
3
|
import type { IRequestError, IRequestSuccess } from '../request';
|
|
4
4
|
export interface IPagination {
|
|
@@ -10,6 +10,7 @@ export interface IPagination {
|
|
|
10
10
|
total: number;
|
|
11
11
|
}
|
|
12
12
|
export type TanstackQueryOption<TResponse> = UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, Array<any>>;
|
|
13
|
+
export type TanstackInfiniteQueryOption<TResponse> = UseInfiniteQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, Array<any>>;
|
|
13
14
|
export interface DefaultRequestOptions {
|
|
14
15
|
baseUrl?: string;
|
|
15
16
|
headers?: RawAxiosRequestHeaders;
|
|
@@ -13,11 +13,12 @@ const useDeleteRequest = (deleteOptions) => {
|
|
|
13
13
|
const [options, setOptions] = useState();
|
|
14
14
|
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
15
15
|
const { getHeaders } = useQueryHeaders();
|
|
16
|
-
const sendRequest = async (res, rej) => {
|
|
16
|
+
const sendRequest = async (res, rej, queryKey) => {
|
|
17
17
|
// get request headers
|
|
18
18
|
const globalHeaders = getHeaders();
|
|
19
|
+
const [url] = (queryKey ?? []);
|
|
19
20
|
const postResponse = await makeRequest({
|
|
20
|
-
path: requestPath,
|
|
21
|
+
path: url ?? requestPath,
|
|
21
22
|
headers: { ...globalHeaders, ...headers },
|
|
22
23
|
method: HttpMethod.DELETE,
|
|
23
24
|
baseURL: baseUrl ?? API_URL,
|
|
@@ -30,7 +31,7 @@ const useDeleteRequest = (deleteOptions) => {
|
|
|
30
31
|
rej(postResponse);
|
|
31
32
|
}
|
|
32
33
|
};
|
|
33
|
-
const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), { enabled: false, ...options });
|
|
34
|
+
const query = useQuery([requestPath, {}], ({ queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey)), { enabled: false, ...options });
|
|
34
35
|
const updatedPathAsync = async (link) => {
|
|
35
36
|
return updateDeletePath(link);
|
|
36
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDeleteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useDeleteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { IRequestSuccess } from '../request';
|
|
2
|
+
import type { DefaultRequestOptions, TanstackInfiniteQueryOption } from './queries.interface';
|
|
3
|
+
interface Pagination {
|
|
4
|
+
previous_page: number;
|
|
5
|
+
current_page: number;
|
|
6
|
+
next_page: number;
|
|
7
|
+
size: number;
|
|
8
|
+
page_count: number;
|
|
9
|
+
total: number;
|
|
10
|
+
}
|
|
11
|
+
export declare const useGetInfiniteRequest: <TResponse extends Record<string, any>>({ path, load, queryOptions, keyTracker, baseUrl, headers, }: {
|
|
12
|
+
path: string;
|
|
13
|
+
load?: boolean | undefined;
|
|
14
|
+
queryOptions?: TanstackInfiniteQueryOption<TResponse & {
|
|
15
|
+
pagination: Pagination;
|
|
16
|
+
}> | undefined;
|
|
17
|
+
keyTracker?: string | undefined;
|
|
18
|
+
} & DefaultRequestOptions) => {
|
|
19
|
+
data: undefined;
|
|
20
|
+
error: any;
|
|
21
|
+
isError: true;
|
|
22
|
+
isLoading: false;
|
|
23
|
+
isLoadingError: true;
|
|
24
|
+
isRefetchError: false;
|
|
25
|
+
isSuccess: false;
|
|
26
|
+
status: "error";
|
|
27
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
28
|
+
pagination: Pagination;
|
|
29
|
+
}>, any>>;
|
|
30
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
31
|
+
pagination: Pagination;
|
|
32
|
+
}>, any>>;
|
|
33
|
+
hasNextPage?: boolean | undefined;
|
|
34
|
+
hasPreviousPage?: boolean | undefined;
|
|
35
|
+
isFetchingNextPage: boolean;
|
|
36
|
+
isFetchingPreviousPage: boolean;
|
|
37
|
+
dataUpdatedAt: number;
|
|
38
|
+
errorUpdatedAt: number;
|
|
39
|
+
failureCount: number;
|
|
40
|
+
failureReason: any;
|
|
41
|
+
errorUpdateCount: number;
|
|
42
|
+
isFetched: boolean;
|
|
43
|
+
isFetchedAfterMount: boolean;
|
|
44
|
+
isFetching: boolean;
|
|
45
|
+
isInitialLoading: boolean;
|
|
46
|
+
isPaused: boolean;
|
|
47
|
+
isPlaceholderData: boolean;
|
|
48
|
+
isPreviousData: boolean;
|
|
49
|
+
isRefetching: boolean;
|
|
50
|
+
isStale: boolean;
|
|
51
|
+
refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
|
|
52
|
+
pagination: Pagination;
|
|
53
|
+
}>>, any>>;
|
|
54
|
+
remove: () => void;
|
|
55
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
56
|
+
} | {
|
|
57
|
+
data: undefined;
|
|
58
|
+
error: null;
|
|
59
|
+
isError: false;
|
|
60
|
+
isLoading: true;
|
|
61
|
+
isLoadingError: false;
|
|
62
|
+
isRefetchError: false;
|
|
63
|
+
isSuccess: false;
|
|
64
|
+
status: "loading";
|
|
65
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
66
|
+
pagination: Pagination;
|
|
67
|
+
}>, any>>;
|
|
68
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
69
|
+
pagination: Pagination;
|
|
70
|
+
}>, any>>;
|
|
71
|
+
hasNextPage?: boolean | undefined;
|
|
72
|
+
hasPreviousPage?: boolean | undefined;
|
|
73
|
+
isFetchingNextPage: boolean;
|
|
74
|
+
isFetchingPreviousPage: boolean;
|
|
75
|
+
dataUpdatedAt: number;
|
|
76
|
+
errorUpdatedAt: number;
|
|
77
|
+
failureCount: number;
|
|
78
|
+
failureReason: any;
|
|
79
|
+
errorUpdateCount: number;
|
|
80
|
+
isFetched: boolean;
|
|
81
|
+
isFetchedAfterMount: boolean;
|
|
82
|
+
isFetching: boolean;
|
|
83
|
+
isInitialLoading: boolean;
|
|
84
|
+
isPaused: boolean;
|
|
85
|
+
isPlaceholderData: boolean;
|
|
86
|
+
isPreviousData: boolean;
|
|
87
|
+
isRefetching: boolean;
|
|
88
|
+
isStale: boolean;
|
|
89
|
+
refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
|
|
90
|
+
pagination: Pagination;
|
|
91
|
+
}>>, any>>;
|
|
92
|
+
remove: () => void;
|
|
93
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
94
|
+
} | {
|
|
95
|
+
data: import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
|
|
96
|
+
pagination: Pagination;
|
|
97
|
+
}>>;
|
|
98
|
+
error: any;
|
|
99
|
+
isError: true;
|
|
100
|
+
isLoading: false;
|
|
101
|
+
isLoadingError: false;
|
|
102
|
+
isRefetchError: true;
|
|
103
|
+
isSuccess: false;
|
|
104
|
+
status: "error";
|
|
105
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
106
|
+
pagination: Pagination;
|
|
107
|
+
}>, any>>;
|
|
108
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
109
|
+
pagination: Pagination;
|
|
110
|
+
}>, any>>;
|
|
111
|
+
hasNextPage?: boolean | undefined;
|
|
112
|
+
hasPreviousPage?: boolean | undefined;
|
|
113
|
+
isFetchingNextPage: boolean;
|
|
114
|
+
isFetchingPreviousPage: boolean;
|
|
115
|
+
dataUpdatedAt: number;
|
|
116
|
+
errorUpdatedAt: number;
|
|
117
|
+
failureCount: number;
|
|
118
|
+
failureReason: any;
|
|
119
|
+
errorUpdateCount: number;
|
|
120
|
+
isFetched: boolean;
|
|
121
|
+
isFetchedAfterMount: boolean;
|
|
122
|
+
isFetching: boolean;
|
|
123
|
+
isInitialLoading: boolean;
|
|
124
|
+
isPaused: boolean;
|
|
125
|
+
isPlaceholderData: boolean;
|
|
126
|
+
isPreviousData: boolean;
|
|
127
|
+
isRefetching: boolean;
|
|
128
|
+
isStale: boolean;
|
|
129
|
+
refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
|
|
130
|
+
pagination: Pagination;
|
|
131
|
+
}>>, any>>;
|
|
132
|
+
remove: () => void;
|
|
133
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
134
|
+
} | {
|
|
135
|
+
data: import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
|
|
136
|
+
pagination: Pagination;
|
|
137
|
+
}>>;
|
|
138
|
+
error: null;
|
|
139
|
+
isError: false;
|
|
140
|
+
isLoading: false;
|
|
141
|
+
isLoadingError: false;
|
|
142
|
+
isRefetchError: false;
|
|
143
|
+
isSuccess: true;
|
|
144
|
+
status: "success";
|
|
145
|
+
fetchNextPage: (options?: import("@tanstack/react-query").FetchNextPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
146
|
+
pagination: Pagination;
|
|
147
|
+
}>, any>>;
|
|
148
|
+
fetchPreviousPage: (options?: import("@tanstack/react-query").FetchPreviousPageOptions | undefined) => Promise<import("@tanstack/react-query").InfiniteQueryObserverResult<IRequestSuccess<TResponse & {
|
|
149
|
+
pagination: Pagination;
|
|
150
|
+
}>, any>>;
|
|
151
|
+
hasNextPage?: boolean | undefined;
|
|
152
|
+
hasPreviousPage?: boolean | undefined;
|
|
153
|
+
isFetchingNextPage: boolean;
|
|
154
|
+
isFetchingPreviousPage: boolean;
|
|
155
|
+
dataUpdatedAt: number;
|
|
156
|
+
errorUpdatedAt: number;
|
|
157
|
+
failureCount: number;
|
|
158
|
+
failureReason: any;
|
|
159
|
+
errorUpdateCount: number;
|
|
160
|
+
isFetched: boolean;
|
|
161
|
+
isFetchedAfterMount: boolean;
|
|
162
|
+
isFetching: boolean;
|
|
163
|
+
isInitialLoading: boolean;
|
|
164
|
+
isPaused: boolean;
|
|
165
|
+
isPlaceholderData: boolean;
|
|
166
|
+
isPreviousData: boolean;
|
|
167
|
+
isRefetching: boolean;
|
|
168
|
+
isStale: boolean;
|
|
169
|
+
refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
|
|
170
|
+
pagination: Pagination;
|
|
171
|
+
}>>, any>>;
|
|
172
|
+
remove: () => void;
|
|
173
|
+
fetchStatus: import("@tanstack/react-query").FetchStatus;
|
|
174
|
+
};
|
|
175
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
|
|
2
|
+
import { useMemo, useEffect } from 'react';
|
|
3
|
+
import 'url-search-params-polyfill';
|
|
4
|
+
import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
|
|
5
|
+
import { useQueryHeaders } from '../config/useQueryHeaders.js';
|
|
6
|
+
import 'axios';
|
|
7
|
+
import { makeRequest } from '../request/make-request.js';
|
|
8
|
+
import '../request/request.enum.js';
|
|
9
|
+
|
|
10
|
+
const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
|
|
11
|
+
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
12
|
+
const { getHeaders } = useQueryHeaders();
|
|
13
|
+
let queryClient = useQueryClient();
|
|
14
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
15
|
+
queryClient = useMemo(() => queryClient, []);
|
|
16
|
+
const sendRequest = async (res, rej, pageParam) => {
|
|
17
|
+
if (load) {
|
|
18
|
+
// get request headers
|
|
19
|
+
const globalHeaders = getHeaders();
|
|
20
|
+
const getResponse = await makeRequest({
|
|
21
|
+
path: pageParam ?? path,
|
|
22
|
+
headers: { ...globalHeaders, ...headers },
|
|
23
|
+
baseURL: baseUrl ?? API_URL,
|
|
24
|
+
timeout: TIMEOUT,
|
|
25
|
+
});
|
|
26
|
+
if (getResponse.status) {
|
|
27
|
+
res(getResponse);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
rej(getResponse);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
res(null);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const query = useInfiniteQuery([path, {}], ({ pageParam = path }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
|
|
38
|
+
enabled: load,
|
|
39
|
+
getNextPageParam: (lastPage, pages) => constructPaginationLink('next_page', lastPage, pages),
|
|
40
|
+
getPreviousPageParam: (lastPage, pages) => constructPaginationLink('previous_page', lastPage, pages),
|
|
41
|
+
...queryOptions,
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* This pagination implementation is currently tied to our use case
|
|
46
|
+
*/
|
|
47
|
+
const constructPaginationLink = (direction, lastPage, pages) => {
|
|
48
|
+
const [pathname, queryString] = lastPage.split('?');
|
|
49
|
+
const queryParams = new URLSearchParams(queryString);
|
|
50
|
+
const lastPageItem = pages[pages.length - 1];
|
|
51
|
+
queryParams.set('page', String(lastPageItem?.data.pagination[direction]));
|
|
52
|
+
return pathname + '?' + queryParams.toString();
|
|
53
|
+
};
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (keyTracker) {
|
|
56
|
+
// set expiration time for the tracker
|
|
57
|
+
queryClient.setQueryDefaults([keyTracker], {
|
|
58
|
+
cacheTime: Infinity,
|
|
59
|
+
staleTime: Infinity,
|
|
60
|
+
});
|
|
61
|
+
queryClient.setQueryData([keyTracker], [path, {}]);
|
|
62
|
+
}
|
|
63
|
+
}, [keyTracker, path, queryClient, queryOptions?.staleTime]);
|
|
64
|
+
return {
|
|
65
|
+
...query,
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export { useGetInfiniteRequest };
|
|
70
|
+
//# sourceMappingURL=useGetInfiniteRequest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useGetInfiniteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -16,12 +16,13 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
|
|
|
16
16
|
let queryClient = useQueryClient();
|
|
17
17
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18
18
|
queryClient = useMemo(() => queryClient, []);
|
|
19
|
-
const sendRequest = async (res, rej) => {
|
|
19
|
+
const sendRequest = async (res, rej, queryKey) => {
|
|
20
20
|
if (load) {
|
|
21
21
|
// get request headers
|
|
22
22
|
const globalHeaders = getHeaders();
|
|
23
|
+
const [url] = (queryKey ?? []);
|
|
23
24
|
const getResponse = await makeRequest({
|
|
24
|
-
path: requestPath,
|
|
25
|
+
path: url ?? requestPath,
|
|
25
26
|
headers: { ...globalHeaders, ...headers },
|
|
26
27
|
baseURL: baseUrl ?? API_URL,
|
|
27
28
|
timeout: TIMEOUT,
|
|
@@ -37,7 +38,7 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
|
|
|
37
38
|
res(null);
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
|
-
const query = useQuery([requestPath, {}], () => new Promise((res, rej) => sendRequest(res, rej)), {
|
|
41
|
+
const query = useQuery([requestPath, {}], ({ queryKey }) => new Promise((res, rej) => sendRequest(res, rej, queryKey)), {
|
|
41
42
|
enabled: load,
|
|
42
43
|
...options,
|
|
43
44
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGetRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useGetRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
package/src/queries/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UseQueryOptions } from '@tanstack/react-query';
|
|
1
|
+
import type { UseInfiniteQueryOptions, UseQueryOptions } from '@tanstack/react-query';
|
|
2
2
|
import type { RawAxiosRequestHeaders } from 'axios';
|
|
3
3
|
import type { IRequestError, IRequestSuccess } from '../request';
|
|
4
4
|
|
|
@@ -18,6 +18,13 @@ export type TanstackQueryOption<TResponse> = UseQueryOptions<
|
|
|
18
18
|
Array<any>
|
|
19
19
|
>;
|
|
20
20
|
|
|
21
|
+
export type TanstackInfiniteQueryOption<TResponse> = UseInfiniteQueryOptions<
|
|
22
|
+
IRequestSuccess<TResponse | undefined>,
|
|
23
|
+
IRequestError,
|
|
24
|
+
IRequestSuccess<TResponse | undefined>,
|
|
25
|
+
Array<any>
|
|
26
|
+
>;
|
|
27
|
+
|
|
21
28
|
export interface DefaultRequestOptions {
|
|
22
29
|
baseUrl?: string;
|
|
23
30
|
headers?: RawAxiosRequestHeaders;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UseQueryOptions } from '@tanstack/react-query';
|
|
1
|
+
import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
|
|
2
2
|
import { useQuery } from '@tanstack/react-query';
|
|
3
3
|
import type { RawAxiosRequestHeaders } from 'axios';
|
|
4
4
|
import { useState } from 'react';
|
|
@@ -16,12 +16,14 @@ export const useDeleteRequest = <TResponse>(deleteOptions?: DefaultRequestOption
|
|
|
16
16
|
|
|
17
17
|
const { getHeaders } = useQueryHeaders();
|
|
18
18
|
|
|
19
|
-
const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void) => {
|
|
19
|
+
const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void, queryKey?: QueryKey) => {
|
|
20
20
|
// get request headers
|
|
21
21
|
const globalHeaders: RawAxiosRequestHeaders = getHeaders();
|
|
22
22
|
|
|
23
|
+
const [url] = (queryKey ?? []) as string[];
|
|
24
|
+
|
|
23
25
|
const postResponse = await makeRequest<TResponse>({
|
|
24
|
-
path: requestPath,
|
|
26
|
+
path: url ?? requestPath,
|
|
25
27
|
headers: { ...globalHeaders, ...headers },
|
|
26
28
|
method: HttpMethod.DELETE,
|
|
27
29
|
baseURL: baseUrl ?? API_URL,
|
|
@@ -37,7 +39,8 @@ export const useDeleteRequest = <TResponse>(deleteOptions?: DefaultRequestOption
|
|
|
37
39
|
|
|
38
40
|
const query = useQuery<any, any, IRequestSuccess<TResponse>>(
|
|
39
41
|
[requestPath, {}],
|
|
40
|
-
(
|
|
42
|
+
({ queryKey }) =>
|
|
43
|
+
new Promise<IRequestSuccess<TResponse> | IRequestError>((res, rej) => sendRequest(res, rej, queryKey)),
|
|
41
44
|
{ enabled: false, ...options }
|
|
42
45
|
);
|
|
43
46
|
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
|
|
2
|
+
import type { RawAxiosRequestHeaders } from 'axios';
|
|
3
|
+
import { useEffect, useMemo } from 'react';
|
|
4
|
+
import { useEnvironmentVariables, useQueryHeaders } from '../config';
|
|
5
|
+
|
|
6
|
+
import type { IRequestError, IRequestSuccess } from '../request';
|
|
7
|
+
import { makeRequest } from '../request';
|
|
8
|
+
import type { DefaultRequestOptions, TanstackInfiniteQueryOption } from './queries.interface';
|
|
9
|
+
|
|
10
|
+
interface Pagination {
|
|
11
|
+
previous_page: number;
|
|
12
|
+
current_page: number;
|
|
13
|
+
next_page: number;
|
|
14
|
+
size: number;
|
|
15
|
+
page_count: number;
|
|
16
|
+
total: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
|
|
20
|
+
path,
|
|
21
|
+
load = false,
|
|
22
|
+
queryOptions,
|
|
23
|
+
keyTracker,
|
|
24
|
+
baseUrl,
|
|
25
|
+
headers,
|
|
26
|
+
}: {
|
|
27
|
+
path: string;
|
|
28
|
+
load?: boolean;
|
|
29
|
+
queryOptions?: TanstackInfiniteQueryOption<TResponse & { pagination: Pagination }>;
|
|
30
|
+
keyTracker?: string;
|
|
31
|
+
} & DefaultRequestOptions) => {
|
|
32
|
+
const { API_URL, TIMEOUT } = useEnvironmentVariables();
|
|
33
|
+
const { getHeaders } = useQueryHeaders();
|
|
34
|
+
|
|
35
|
+
let queryClient = useQueryClient();
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
|
+
queryClient = useMemo(() => queryClient, []);
|
|
39
|
+
|
|
40
|
+
const sendRequest = async (
|
|
41
|
+
res: (
|
|
42
|
+
value:
|
|
43
|
+
| IRequestError
|
|
44
|
+
| IRequestSuccess<TResponse & { pagination: Pagination }>
|
|
45
|
+
| PromiseLike<IRequestError | IRequestSuccess<TResponse & { pagination: Pagination }>>
|
|
46
|
+
) => void,
|
|
47
|
+
rej: (reason?: any) => void,
|
|
48
|
+
pageParam?: string
|
|
49
|
+
) => {
|
|
50
|
+
if (load) {
|
|
51
|
+
// get request headers
|
|
52
|
+
const globalHeaders: RawAxiosRequestHeaders = getHeaders();
|
|
53
|
+
|
|
54
|
+
const getResponse = await makeRequest<TResponse>({
|
|
55
|
+
path: pageParam ?? path,
|
|
56
|
+
headers: { ...globalHeaders, ...headers },
|
|
57
|
+
baseURL: baseUrl ?? API_URL,
|
|
58
|
+
timeout: TIMEOUT,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (getResponse.status) {
|
|
62
|
+
res(getResponse as IRequestSuccess<TResponse & { pagination: Pagination }>);
|
|
63
|
+
} else {
|
|
64
|
+
rej(getResponse);
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
res(null as any);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const query = useInfiniteQuery<any, any, IRequestSuccess<TResponse & { pagination: Pagination }>>(
|
|
72
|
+
[path, {}],
|
|
73
|
+
({ pageParam = path }) =>
|
|
74
|
+
new Promise<IRequestSuccess<TResponse & { pagination: Pagination }> | IRequestError>((res, rej) =>
|
|
75
|
+
sendRequest(res, rej, pageParam)
|
|
76
|
+
),
|
|
77
|
+
{
|
|
78
|
+
enabled: load,
|
|
79
|
+
getNextPageParam: (lastPage, pages) => constructPaginationLink('next_page', lastPage, pages),
|
|
80
|
+
getPreviousPageParam: (lastPage, pages) => constructPaginationLink('previous_page', lastPage, pages),
|
|
81
|
+
...(queryOptions as any),
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
*
|
|
87
|
+
* This pagination implementation is currently tied to our use case
|
|
88
|
+
*/
|
|
89
|
+
const constructPaginationLink = (
|
|
90
|
+
direction: 'next_page' | 'previous_page',
|
|
91
|
+
lastPage: string,
|
|
92
|
+
pages: IRequestSuccess<
|
|
93
|
+
TResponse & {
|
|
94
|
+
pagination: Pagination;
|
|
95
|
+
}
|
|
96
|
+
>[]
|
|
97
|
+
) => {
|
|
98
|
+
const [pathname, queryString] = lastPage.split('?');
|
|
99
|
+
|
|
100
|
+
const queryParams = new URLSearchParams(queryString);
|
|
101
|
+
const lastPageItem = pages[pages.length - 1];
|
|
102
|
+
|
|
103
|
+
queryParams.set('page', String(lastPageItem?.data.pagination[direction]));
|
|
104
|
+
|
|
105
|
+
return pathname + '?' + queryParams.toString();
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (keyTracker) {
|
|
110
|
+
// set expiration time for the tracker
|
|
111
|
+
queryClient.setQueryDefaults([keyTracker], {
|
|
112
|
+
cacheTime: Infinity,
|
|
113
|
+
staleTime: Infinity,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
queryClient.setQueryData([keyTracker], [path, {}]);
|
|
117
|
+
}
|
|
118
|
+
}, [keyTracker, path, queryClient, queryOptions?.staleTime]);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
...query,
|
|
122
|
+
};
|
|
123
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { UseQueryOptions } from '@tanstack/react-query';
|
|
1
|
+
import type { QueryKey, UseQueryOptions } from '@tanstack/react-query';
|
|
2
2
|
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
|
3
3
|
import { startTransition, useEffect, useMemo, useState } from 'react';
|
|
4
4
|
import type { RawAxiosRequestHeaders } from '../../node_modules/axios/index';
|
|
@@ -37,14 +37,17 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
37
37
|
res: (
|
|
38
38
|
value: IRequestError | IRequestSuccess<TResponse> | PromiseLike<IRequestError | IRequestSuccess<TResponse>>
|
|
39
39
|
) => void,
|
|
40
|
-
rej: (reason?: any) => void
|
|
40
|
+
rej: (reason?: any) => void,
|
|
41
|
+
queryKey?: QueryKey
|
|
41
42
|
) => {
|
|
42
43
|
if (load) {
|
|
43
44
|
// get request headers
|
|
44
45
|
const globalHeaders: RawAxiosRequestHeaders = getHeaders();
|
|
45
46
|
|
|
47
|
+
const [url] = (queryKey ?? []) as string[];
|
|
48
|
+
|
|
46
49
|
const getResponse = await makeRequest<TResponse>({
|
|
47
|
-
path: requestPath,
|
|
50
|
+
path: url ?? requestPath,
|
|
48
51
|
headers: { ...globalHeaders, ...headers },
|
|
49
52
|
baseURL: baseUrl ?? API_URL,
|
|
50
53
|
timeout: TIMEOUT,
|
|
@@ -62,7 +65,8 @@ export const useGetRequest = <TResponse extends Record<string, any>>({
|
|
|
62
65
|
|
|
63
66
|
const query = useQuery<any, any, IRequestSuccess<TResponse>>(
|
|
64
67
|
[requestPath, {}],
|
|
65
|
-
(
|
|
68
|
+
({ queryKey }) =>
|
|
69
|
+
new Promise<IRequestSuccess<TResponse> | IRequestError>((res, rej) => sendRequest(res, rej, queryKey)),
|
|
66
70
|
{
|
|
67
71
|
enabled: load,
|
|
68
72
|
...options,
|