@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 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
- - [Not Completed] Persistent queries implementation
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<User>(
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
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,6 @@
1
1
  export * from './queries.interface';
2
2
  export * from './useDeleteRequest';
3
+ export * from './useGetInfiniteRequest';
3
4
  export * from './useGetRequest';
4
5
  export * from './usePatchRequest';
5
6
  export * from './usePostRequest';
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ventlio/tanstack-query",
3
- "version": "0.2.73",
3
+ "version": "0.2.75",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "contributors": [
@@ -1,5 +1,6 @@
1
1
  export * from './queries.interface';
2
2
  export * from './useDeleteRequest';
3
+ export * from './useGetInfiniteRequest';
3
4
  export * from './useGetRequest';
4
5
  export * from './usePatchRequest';
5
6
  export * from './usePostRequest';
@@ -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
- () => new Promise<IRequestSuccess<TResponse> | IRequestError>((res, rej) => sendRequest(res, rej)),
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
- () => new Promise<IRequestSuccess<TResponse> | IRequestError>((res, rej) => sendRequest(res, rej)),
68
+ ({ queryKey }) =>
69
+ new Promise<IRequestSuccess<TResponse> | IRequestError>((res, rej) => sendRequest(res, rej, queryKey)),
66
70
  {
67
71
  enabled: load,
68
72
  ...options,