@ventlio/tanstack-query 0.2.76 → 0.2.78

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.
@@ -0,0 +1 @@
1
+ export * from './useUploadProgress';
@@ -0,0 +1,5 @@
1
+ import type { AxiosProgressEvent } from 'axios';
2
+ export declare const useUploadProgress: () => {
3
+ onUploadProgress: (progressEvent: AxiosProgressEvent) => void;
4
+ uploadProgressPercent: number;
5
+ };
@@ -0,0 +1,14 @@
1
+ import { useState } from 'react';
2
+
3
+ const useUploadProgress = () => {
4
+ const [uploadProgressPercent, setUploadProgressPercent] = useState(0);
5
+ const onUploadProgress = (progressEvent) => {
6
+ const { loaded, total } = progressEvent;
7
+ const percentage = Math.round((loaded / total) * 100);
8
+ setUploadProgressPercent(percentage);
9
+ };
10
+ return { onUploadProgress, uploadProgressPercent };
11
+ };
12
+
13
+ export { useUploadProgress };
14
+ //# sourceMappingURL=useUploadProgress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUploadProgress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
package/dist/index.mjs CHANGED
@@ -313,7 +313,7 @@ const successTransformer = (data) => {
313
313
  };
314
314
  };
315
315
 
316
- async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, }) {
316
+ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, onUploadProgress, }) {
317
317
  // check if file is included in mobile app environment and extract all file input to avoid
318
318
  // it being formatted to object using axios formData builder
319
319
  const isApp = appFileConfig?.isApp;
@@ -351,6 +351,7 @@ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, he
351
351
  url: path,
352
352
  method,
353
353
  data: body,
354
+ onUploadProgress,
354
355
  });
355
356
  // get response json
356
357
  const jsonResp = await resp.data;
@@ -435,6 +436,8 @@ const useDeleteRequest = (deleteOptions) => {
435
436
  const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
436
437
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
437
438
  const { getHeaders } = useQueryHeaders();
439
+ const [requestPath, updatePath] = useState(path);
440
+ const [options, setOptions] = useState(queryOptions);
438
441
  let queryClient = useQueryClient();
439
442
  // eslint-disable-next-line react-hooks/exhaustive-deps
440
443
  queryClient = useMemo(() => queryClient, []);
@@ -443,7 +446,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
443
446
  // get request headers
444
447
  const globalHeaders = getHeaders();
445
448
  const getResponse = await makeRequest({
446
- path: pageParam ?? path,
449
+ path: pageParam ?? requestPath,
447
450
  headers: { ...globalHeaders, ...headers },
448
451
  baseURL: baseUrl ?? API_URL,
449
452
  timeout: TIMEOUT,
@@ -464,18 +467,33 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
464
467
  * This pagination implementation is currently tied to our use case
465
468
  */
466
469
  const constructPaginationLink = (direction, lastPage) => {
467
- const [pathname, queryString] = path.split('?');
470
+ const [pathname, queryString] = requestPath.split('?');
468
471
  const queryParams = new URLSearchParams(queryString);
469
472
  const lastPageItem = lastPage.data.pagination[direction];
470
473
  queryParams.set('page', String(lastPageItem));
471
474
  return pathname + '?' + queryParams.toString();
472
475
  };
473
- const query = useInfiniteQuery([path, {}], ({ pageParam = path }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
476
+ const query = useInfiniteQuery([requestPath, {}], ({ pageParam = requestPath }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
474
477
  enabled: load,
475
478
  getNextPageParam: (lastPage) => constructPaginationLink('next_page', lastPage),
476
479
  getPreviousPageParam: (lastPage) => constructPaginationLink('previous_page', lastPage),
477
- ...queryOptions,
480
+ ...options,
478
481
  });
482
+ const setOptionsAsync = async (fetchOptions) => {
483
+ startTransition(() => {
484
+ setOptions(fetchOptions);
485
+ });
486
+ };
487
+ const get = async (link, fetchOptions) => {
488
+ await setOptionsAsync(fetchOptions);
489
+ await updatedPathAsync(link);
490
+ return query.data;
491
+ };
492
+ const updatedPathAsync = async (link) => {
493
+ startTransition(() => {
494
+ updatePath(link);
495
+ });
496
+ };
479
497
  useEffect(() => {
480
498
  if (keyTracker) {
481
499
  // set expiration time for the tracker
@@ -483,10 +501,11 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
483
501
  cacheTime: Infinity,
484
502
  staleTime: Infinity,
485
503
  });
486
- queryClient.setQueryData([keyTracker], [path, {}]);
504
+ queryClient.setQueryData([keyTracker], [requestPath, {}]);
487
505
  }
488
- }, [keyTracker, path, queryClient, queryOptions?.staleTime]);
506
+ }, [keyTracker, requestPath, queryClient, queryOptions?.staleTime]);
489
507
  return {
508
+ get,
490
509
  ...query,
491
510
  };
492
511
  };
@@ -599,8 +618,19 @@ const useGetRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl,
599
618
  };
600
619
  };
601
620
 
621
+ const useUploadProgress = () => {
622
+ const [uploadProgressPercent, setUploadProgressPercent] = useState(0);
623
+ const onUploadProgress = (progressEvent) => {
624
+ const { loaded, total } = progressEvent;
625
+ const percentage = Math.round((loaded / total) * 100);
626
+ setUploadProgressPercent(percentage);
627
+ };
628
+ return { onUploadProgress, uploadProgressPercent };
629
+ };
630
+
602
631
  const usePatchRequest = ({ path, baseUrl, headers }) => {
603
632
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
633
+ const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
604
634
  const { getHeaders } = useQueryHeaders();
605
635
  const queryClient = useQueryClient();
606
636
  const config = queryClient.getQueryData(['config']);
@@ -614,6 +644,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
614
644
  headers: { ...globalHeaders, ...headers },
615
645
  baseURL: baseUrl ?? API_URL,
616
646
  timeout: TIMEOUT,
647
+ onUploadProgress,
617
648
  });
618
649
  if (patchResponse.status) {
619
650
  // scroll to top after success
@@ -637,7 +668,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
637
668
  const patch = async (data, options) => {
638
669
  return mutation.mutateAsync(data, options);
639
670
  };
640
- return { patch, ...mutation };
671
+ return { patch, uploadProgressPercent, ...mutation };
641
672
  };
642
673
 
643
674
  const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelectors, }) => {
@@ -645,6 +676,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
645
676
  const queryClient = useQueryClient();
646
677
  const { getHeaders } = useQueryHeaders();
647
678
  const { isApp } = useReactNativeEnv();
679
+ const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
648
680
  const sendRequest = async (res, rej, postData) => {
649
681
  // get request headers
650
682
  const globalHeaders = getHeaders();
@@ -661,6 +693,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
661
693
  isApp,
662
694
  fileSelectors,
663
695
  },
696
+ onUploadProgress,
664
697
  });
665
698
  if (postResponse.status) {
666
699
  // scroll to top after success
@@ -682,7 +715,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
682
715
  const post = async (data, options) => {
683
716
  return mutation.mutateAsync(data, options);
684
717
  };
685
- return { post, ...mutation };
718
+ return { post, uploadProgressPercent, ...mutation };
686
719
  };
687
720
 
688
721
  export { ContentType, HttpMethod, axiosInstance, bootstrapQueryRequest, buildFormData, errorTransformer, getDateInFuture, makeRequest, scrollToTop, successTransformer, useDeleteRequest, useEnvironmentVariables, useGetInfiniteRequest, useGetRequest, useKeyTrackerModel, usePatchRequest, usePostRequest, useQueryConfig, useQueryHeaders, useQueryModel, useReactNativeEnv, useRefetchQuery };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,5 @@
1
- import type { IRequestSuccess } from '../request';
1
+ import type { InfiniteData, UseQueryOptions } from '@tanstack/react-query';
2
+ import type { IRequestError, IRequestSuccess } from '../request';
2
3
  import type { DefaultRequestOptions, TanstackInfiniteQueryOption } from './queries.interface';
3
4
  interface Pagination {
4
5
  previous_page: number;
@@ -48,11 +49,14 @@ export declare const useGetInfiniteRequest: <TResponse extends Record<string, an
48
49
  isPreviousData: boolean;
49
50
  isRefetching: boolean;
50
51
  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
+ refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<InfiniteData<IRequestSuccess<TResponse & {
52
53
  pagination: Pagination;
53
54
  }>>, any>>;
54
55
  remove: () => void;
55
56
  fetchStatus: import("@tanstack/react-query").FetchStatus;
57
+ get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<InfiniteData<IRequestSuccess<TResponse & {
58
+ pagination: Pagination;
59
+ }>> | undefined>;
56
60
  } | {
57
61
  data: undefined;
58
62
  error: null;
@@ -86,13 +90,16 @@ export declare const useGetInfiniteRequest: <TResponse extends Record<string, an
86
90
  isPreviousData: boolean;
87
91
  isRefetching: boolean;
88
92
  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 & {
93
+ refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<InfiniteData<IRequestSuccess<TResponse & {
90
94
  pagination: Pagination;
91
95
  }>>, any>>;
92
96
  remove: () => void;
93
97
  fetchStatus: import("@tanstack/react-query").FetchStatus;
98
+ get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<InfiniteData<IRequestSuccess<TResponse & {
99
+ pagination: Pagination;
100
+ }>> | undefined>;
94
101
  } | {
95
- data: import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
102
+ data: InfiniteData<IRequestSuccess<TResponse & {
96
103
  pagination: Pagination;
97
104
  }>>;
98
105
  error: any;
@@ -126,13 +133,16 @@ export declare const useGetInfiniteRequest: <TResponse extends Record<string, an
126
133
  isPreviousData: boolean;
127
134
  isRefetching: boolean;
128
135
  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 & {
136
+ refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<InfiniteData<IRequestSuccess<TResponse & {
130
137
  pagination: Pagination;
131
138
  }>>, any>>;
132
139
  remove: () => void;
133
140
  fetchStatus: import("@tanstack/react-query").FetchStatus;
141
+ get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<InfiniteData<IRequestSuccess<TResponse & {
142
+ pagination: Pagination;
143
+ }>> | undefined>;
134
144
  } | {
135
- data: import("@tanstack/react-query").InfiniteData<IRequestSuccess<TResponse & {
145
+ data: InfiniteData<IRequestSuccess<TResponse & {
136
146
  pagination: Pagination;
137
147
  }>>;
138
148
  error: null;
@@ -166,10 +176,13 @@ export declare const useGetInfiniteRequest: <TResponse extends Record<string, an
166
176
  isPreviousData: boolean;
167
177
  isRefetching: boolean;
168
178
  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 & {
179
+ refetch: <TPageData>(options?: (import("@tanstack/react-query").RefetchOptions & import("@tanstack/react-query").RefetchQueryFilters<TPageData>) | undefined) => Promise<import("@tanstack/react-query").QueryObserverResult<InfiniteData<IRequestSuccess<TResponse & {
170
180
  pagination: Pagination;
171
181
  }>>, any>>;
172
182
  remove: () => void;
173
183
  fetchStatus: import("@tanstack/react-query").FetchStatus;
184
+ get: (link: string, fetchOptions?: UseQueryOptions<IRequestSuccess<TResponse | undefined>, IRequestError, IRequestSuccess<TResponse | undefined>, any[]> | undefined) => Promise<InfiniteData<IRequestSuccess<TResponse & {
185
+ pagination: Pagination;
186
+ }>> | undefined>;
174
187
  };
175
188
  export {};
@@ -1,5 +1,5 @@
1
1
  import { useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
2
- import { useMemo, useEffect } from 'react';
2
+ import { useState, useMemo, useEffect, startTransition } from 'react';
3
3
  import 'url-search-params-polyfill';
4
4
  import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
5
5
  import { useQueryHeaders } from '../config/useQueryHeaders.js';
@@ -10,6 +10,8 @@ import '../request/request.enum.js';
10
10
  const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, baseUrl, headers, }) => {
11
11
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
12
12
  const { getHeaders } = useQueryHeaders();
13
+ const [requestPath, updatePath] = useState(path);
14
+ const [options, setOptions] = useState(queryOptions);
13
15
  let queryClient = useQueryClient();
14
16
  // eslint-disable-next-line react-hooks/exhaustive-deps
15
17
  queryClient = useMemo(() => queryClient, []);
@@ -18,7 +20,7 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
18
20
  // get request headers
19
21
  const globalHeaders = getHeaders();
20
22
  const getResponse = await makeRequest({
21
- path: pageParam ?? path,
23
+ path: pageParam ?? requestPath,
22
24
  headers: { ...globalHeaders, ...headers },
23
25
  baseURL: baseUrl ?? API_URL,
24
26
  timeout: TIMEOUT,
@@ -39,18 +41,33 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
39
41
  * This pagination implementation is currently tied to our use case
40
42
  */
41
43
  const constructPaginationLink = (direction, lastPage) => {
42
- const [pathname, queryString] = path.split('?');
44
+ const [pathname, queryString] = requestPath.split('?');
43
45
  const queryParams = new URLSearchParams(queryString);
44
46
  const lastPageItem = lastPage.data.pagination[direction];
45
47
  queryParams.set('page', String(lastPageItem));
46
48
  return pathname + '?' + queryParams.toString();
47
49
  };
48
- const query = useInfiniteQuery([path, {}], ({ pageParam = path }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
50
+ const query = useInfiniteQuery([requestPath, {}], ({ pageParam = requestPath }) => new Promise((res, rej) => sendRequest(res, rej, pageParam)), {
49
51
  enabled: load,
50
52
  getNextPageParam: (lastPage) => constructPaginationLink('next_page', lastPage),
51
53
  getPreviousPageParam: (lastPage) => constructPaginationLink('previous_page', lastPage),
52
- ...queryOptions,
54
+ ...options,
53
55
  });
56
+ const setOptionsAsync = async (fetchOptions) => {
57
+ startTransition(() => {
58
+ setOptions(fetchOptions);
59
+ });
60
+ };
61
+ const get = async (link, fetchOptions) => {
62
+ await setOptionsAsync(fetchOptions);
63
+ await updatedPathAsync(link);
64
+ return query.data;
65
+ };
66
+ const updatedPathAsync = async (link) => {
67
+ startTransition(() => {
68
+ updatePath(link);
69
+ });
70
+ };
54
71
  useEffect(() => {
55
72
  if (keyTracker) {
56
73
  // set expiration time for the tracker
@@ -58,10 +75,11 @@ const useGetInfiniteRequest = ({ path, load = false, queryOptions, keyTracker, b
58
75
  cacheTime: Infinity,
59
76
  staleTime: Infinity,
60
77
  });
61
- queryClient.setQueryData([keyTracker], [path, {}]);
78
+ queryClient.setQueryData([keyTracker], [requestPath, {}]);
62
79
  }
63
- }, [keyTracker, path, queryClient, queryOptions?.staleTime]);
80
+ }, [keyTracker, requestPath, queryClient, queryOptions?.staleTime]);
64
81
  return {
82
+ get,
65
83
  ...query,
66
84
  };
67
85
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useGetInfiniteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"useGetInfiniteRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -20,6 +20,7 @@ export declare const usePatchRequest: <TResponse>({ path, baseUrl, headers }: {
20
20
  variables: void | undefined;
21
21
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
22
22
  patch: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
23
+ uploadProgressPercent: number;
23
24
  } | {
24
25
  data: undefined;
25
26
  error: null;
@@ -37,6 +38,7 @@ export declare const usePatchRequest: <TResponse>({ path, baseUrl, headers }: {
37
38
  variables: void | undefined;
38
39
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
39
40
  patch: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
41
+ uploadProgressPercent: number;
40
42
  } | {
41
43
  data: undefined;
42
44
  error: IRequestError;
@@ -54,6 +56,7 @@ export declare const usePatchRequest: <TResponse>({ path, baseUrl, headers }: {
54
56
  variables: void | undefined;
55
57
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
56
58
  patch: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
59
+ uploadProgressPercent: number;
57
60
  } | {
58
61
  data: IRequestSuccess<TResponse>;
59
62
  error: null;
@@ -71,4 +74,5 @@ export declare const usePatchRequest: <TResponse>({ path, baseUrl, headers }: {
71
74
  variables: void | undefined;
72
75
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
73
76
  patch: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
77
+ uploadProgressPercent: number;
74
78
  };
@@ -3,12 +3,14 @@ import 'url-search-params-polyfill';
3
3
  import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
4
4
  import { useQueryHeaders } from '../config/useQueryHeaders.js';
5
5
  import { scrollToTop } from '../helpers/scrollToTop.js';
6
+ import { useUploadProgress } from '../hooks/useUploadProgress.js';
6
7
  import 'axios';
7
8
  import { makeRequest } from '../request/make-request.js';
8
9
  import { HttpMethod } from '../request/request.enum.js';
9
10
 
10
11
  const usePatchRequest = ({ path, baseUrl, headers }) => {
11
12
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
13
+ const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
12
14
  const { getHeaders } = useQueryHeaders();
13
15
  const queryClient = useQueryClient();
14
16
  const config = queryClient.getQueryData(['config']);
@@ -22,6 +24,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
22
24
  headers: { ...globalHeaders, ...headers },
23
25
  baseURL: baseUrl ?? API_URL,
24
26
  timeout: TIMEOUT,
27
+ onUploadProgress,
25
28
  });
26
29
  if (patchResponse.status) {
27
30
  // scroll to top after success
@@ -45,7 +48,7 @@ const usePatchRequest = ({ path, baseUrl, headers }) => {
45
48
  const patch = async (data, options) => {
46
49
  return mutation.mutateAsync(data, options);
47
50
  };
48
- return { patch, ...mutation };
51
+ return { patch, uploadProgressPercent, ...mutation };
49
52
  };
50
53
 
51
54
  export { usePatchRequest };
@@ -1 +1 @@
1
- {"version":3,"file":"usePatchRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"usePatchRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -22,6 +22,7 @@ export declare const usePostRequest: <TResponse>({ path, isFormData, baseUrl, he
22
22
  variables: void | undefined;
23
23
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
24
24
  post: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
25
+ uploadProgressPercent: number;
25
26
  } | {
26
27
  data: undefined;
27
28
  error: null;
@@ -39,6 +40,7 @@ export declare const usePostRequest: <TResponse>({ path, isFormData, baseUrl, he
39
40
  variables: void | undefined;
40
41
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
41
42
  post: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
43
+ uploadProgressPercent: number;
42
44
  } | {
43
45
  data: undefined;
44
46
  error: IRequestError;
@@ -56,6 +58,7 @@ export declare const usePostRequest: <TResponse>({ path, isFormData, baseUrl, he
56
58
  variables: void | undefined;
57
59
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
58
60
  post: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
61
+ uploadProgressPercent: number;
59
62
  } | {
60
63
  data: IRequestSuccess<TResponse>;
61
64
  error: null;
@@ -73,4 +76,5 @@ export declare const usePostRequest: <TResponse>({ path, isFormData, baseUrl, he
73
76
  variables: void | undefined;
74
77
  mutateAsync: import("@tanstack/react-query").UseMutateAsyncFunction<IRequestSuccess<TResponse>, IRequestError, void, unknown>;
75
78
  post: (data: any, options?: MutateOptions<IRequestSuccess<TResponse>, IRequestError, void, unknown> | undefined) => Promise<IRequestSuccess<TResponse>>;
79
+ uploadProgressPercent: number;
76
80
  };
@@ -4,6 +4,7 @@ import { useEnvironmentVariables } from '../config/useEnvironmentVariables.js';
4
4
  import { useQueryHeaders } from '../config/useQueryHeaders.js';
5
5
  import { useReactNativeEnv } from '../config/useReactNativeEnv.js';
6
6
  import { scrollToTop } from '../helpers/scrollToTop.js';
7
+ import { useUploadProgress } from '../hooks/useUploadProgress.js';
7
8
  import 'axios';
8
9
  import { makeRequest } from '../request/make-request.js';
9
10
  import { HttpMethod } from '../request/request.enum.js';
@@ -13,6 +14,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
13
14
  const queryClient = useQueryClient();
14
15
  const { getHeaders } = useQueryHeaders();
15
16
  const { isApp } = useReactNativeEnv();
17
+ const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
16
18
  const sendRequest = async (res, rej, postData) => {
17
19
  // get request headers
18
20
  const globalHeaders = getHeaders();
@@ -29,6 +31,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
29
31
  isApp,
30
32
  fileSelectors,
31
33
  },
34
+ onUploadProgress,
32
35
  });
33
36
  if (postResponse.status) {
34
37
  // scroll to top after success
@@ -50,7 +53,7 @@ const usePostRequest = ({ path, isFormData = false, baseUrl, headers, fileSelect
50
53
  const post = async (data, options) => {
51
54
  return mutation.mutateAsync(data, options);
52
55
  };
53
- return { post, ...mutation };
56
+ return { post, uploadProgressPercent, ...mutation };
54
57
  };
55
58
 
56
59
  export { usePostRequest };
@@ -1 +1 @@
1
- {"version":3,"file":"usePostRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"usePostRequest.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,2 +1,2 @@
1
1
  import type { IMakeRequest } from './request.interface';
2
- export declare function makeRequest<TResponse>({ body, method, path, isFormData, headers, baseURL, timeout, appFileConfig, }: IMakeRequest): Promise<import("./request.interface").IRequestError>;
2
+ export declare function makeRequest<TResponse>({ body, method, path, isFormData, headers, baseURL, timeout, appFileConfig, onUploadProgress, }: IMakeRequest): Promise<import("./request.interface").IRequestError>;
@@ -3,7 +3,7 @@ import { axiosInstance } from './axios-instance.js';
3
3
  import { ContentType, HttpMethod } from './request.enum.js';
4
4
  import { errorTransformer, successTransformer } from './transformer.js';
5
5
 
6
- async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, }) {
6
+ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, headers = {}, baseURL, timeout, appFileConfig, onUploadProgress, }) {
7
7
  // check if file is included in mobile app environment and extract all file input to avoid
8
8
  // it being formatted to object using axios formData builder
9
9
  const isApp = appFileConfig?.isApp;
@@ -41,6 +41,7 @@ async function makeRequest({ body, method = HttpMethod.GET, path, isFormData, he
41
41
  url: path,
42
42
  method,
43
43
  data: body,
44
+ onUploadProgress,
44
45
  });
45
46
  // get response json
46
47
  const jsonResp = await resp.data;
@@ -1 +1 @@
1
- {"version":3,"file":"make-request.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"make-request.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import type { RawAxiosRequestHeaders } from 'axios';
1
+ import type { AxiosProgressEvent, RawAxiosRequestHeaders } from 'axios';
2
2
  import type { HttpMethod } from './request.enum';
3
3
  export interface IMakeRequest {
4
4
  baseURL: string;
@@ -9,6 +9,7 @@ export interface IMakeRequest {
9
9
  isFormData?: boolean;
10
10
  headers: RawAxiosRequestHeaders;
11
11
  appFileConfig?: AppFileConfig;
12
+ onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
12
13
  }
13
14
  export interface AppFileConfig {
14
15
  fileSelectors?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ventlio/tanstack-query",
3
- "version": "0.2.76",
3
+ "version": "0.2.78",
4
4
  "license": "MIT",
5
5
  "main": "dist/index.js",
6
6
  "contributors": [
@@ -0,0 +1 @@
1
+ export * from './useUploadProgress';
@@ -0,0 +1,15 @@
1
+ import type { AxiosProgressEvent } from 'axios';
2
+ import { useState } from 'react';
3
+
4
+ export const useUploadProgress = () => {
5
+ const [uploadProgressPercent, setUploadProgressPercent] = useState<number>(0);
6
+
7
+ const onUploadProgress = (progressEvent: AxiosProgressEvent) => {
8
+ const { loaded, total } = progressEvent;
9
+ const percentage = Math.round((loaded / (total as number)) * 100);
10
+
11
+ setUploadProgressPercent(percentage);
12
+ };
13
+
14
+ return { onUploadProgress, uploadProgressPercent };
15
+ };
@@ -1,6 +1,7 @@
1
+ import type { InfiniteData, UseQueryOptions } from '@tanstack/react-query';
1
2
  import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
2
3
  import type { RawAxiosRequestHeaders } from 'axios';
3
- import { useEffect, useMemo } from 'react';
4
+ import { startTransition, useEffect, useMemo, useState } from 'react';
4
5
  import { useEnvironmentVariables, useQueryHeaders } from '../config';
5
6
 
6
7
  import type { IRequestError, IRequestSuccess } from '../request';
@@ -31,6 +32,9 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
31
32
  } & DefaultRequestOptions) => {
32
33
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
33
34
  const { getHeaders } = useQueryHeaders();
35
+ const [requestPath, updatePath] = useState<string>(path);
36
+
37
+ const [options, setOptions] = useState<any>(queryOptions);
34
38
 
35
39
  let queryClient = useQueryClient();
36
40
 
@@ -52,7 +56,7 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
52
56
  const globalHeaders: RawAxiosRequestHeaders = getHeaders();
53
57
 
54
58
  const getResponse = await makeRequest<TResponse>({
55
- path: pageParam ?? path,
59
+ path: pageParam ?? requestPath,
56
60
  headers: { ...globalHeaders, ...headers },
57
61
  baseURL: baseUrl ?? API_URL,
58
62
  timeout: TIMEOUT,
@@ -80,7 +84,7 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
80
84
  }
81
85
  >
82
86
  ) => {
83
- const [pathname, queryString] = path.split('?');
87
+ const [pathname, queryString] = requestPath.split('?');
84
88
 
85
89
  const queryParams = new URLSearchParams(queryString);
86
90
  const lastPageItem = lastPage.data.pagination[direction];
@@ -91,8 +95,8 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
91
95
  };
92
96
 
93
97
  const query = useInfiniteQuery<any, any, IRequestSuccess<TResponse & { pagination: Pagination }>>(
94
- [path, {}],
95
- ({ pageParam = path }) =>
98
+ [requestPath, {}],
99
+ ({ pageParam = requestPath }) =>
96
100
  new Promise<IRequestSuccess<TResponse & { pagination: Pagination }> | IRequestError>((res, rej) =>
97
101
  sendRequest(res, rej, pageParam)
98
102
  ),
@@ -100,10 +104,46 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
100
104
  enabled: load,
101
105
  getNextPageParam: (lastPage) => constructPaginationLink('next_page', lastPage),
102
106
  getPreviousPageParam: (lastPage) => constructPaginationLink('previous_page', lastPage),
103
- ...(queryOptions as any),
107
+ ...options,
104
108
  }
105
109
  );
106
110
 
111
+ const setOptionsAsync = async (fetchOptions: any) => {
112
+ startTransition(() => {
113
+ setOptions(fetchOptions);
114
+ });
115
+ };
116
+
117
+ const get = async (
118
+ link: string,
119
+ fetchOptions?: UseQueryOptions<
120
+ IRequestSuccess<TResponse | undefined>,
121
+ IRequestError,
122
+ IRequestSuccess<TResponse | undefined>,
123
+ Array<any>
124
+ >
125
+ ): Promise<
126
+ | InfiniteData<
127
+ IRequestSuccess<
128
+ TResponse & {
129
+ pagination: Pagination;
130
+ }
131
+ >
132
+ >
133
+ | undefined
134
+ > => {
135
+ await setOptionsAsync(fetchOptions);
136
+ await updatedPathAsync(link);
137
+
138
+ return query.data;
139
+ };
140
+
141
+ const updatedPathAsync = async (link: string) => {
142
+ startTransition(() => {
143
+ updatePath(link);
144
+ });
145
+ };
146
+
107
147
  useEffect(() => {
108
148
  if (keyTracker) {
109
149
  // set expiration time for the tracker
@@ -112,11 +152,12 @@ export const useGetInfiniteRequest = <TResponse extends Record<string, any>>({
112
152
  staleTime: Infinity,
113
153
  });
114
154
 
115
- queryClient.setQueryData([keyTracker], [path, {}]);
155
+ queryClient.setQueryData([keyTracker], [requestPath, {}]);
116
156
  }
117
- }, [keyTracker, path, queryClient, queryOptions?.staleTime]);
157
+ }, [keyTracker, requestPath, queryClient, queryOptions?.staleTime]);
118
158
 
119
159
  return {
160
+ get,
120
161
  ...query,
121
162
  };
122
163
  };
@@ -3,6 +3,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
3
3
  import type { RawAxiosRequestHeaders } from 'axios';
4
4
  import { useEnvironmentVariables, useQueryHeaders } from '../config';
5
5
  import { scrollToTop } from '../helpers';
6
+ import { useUploadProgress } from '../hooks';
6
7
  import { HttpMethod, makeRequest } from '../request';
7
8
  import type { IRequestError, IRequestSuccess } from '../request/request.interface';
8
9
  import type { TanstackQueryConfig } from '../types';
@@ -10,6 +11,7 @@ import type { DefaultRequestOptions } from './queries.interface';
10
11
 
11
12
  export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: string } & DefaultRequestOptions) => {
12
13
  const { API_URL, TIMEOUT } = useEnvironmentVariables();
14
+ const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
13
15
 
14
16
  const { getHeaders } = useQueryHeaders();
15
17
  const queryClient = useQueryClient();
@@ -27,6 +29,7 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
27
29
  headers: { ...globalHeaders, ...headers },
28
30
  baseURL: baseUrl ?? API_URL,
29
31
  timeout: TIMEOUT,
32
+ onUploadProgress,
30
33
  });
31
34
 
32
35
  if (patchResponse.status) {
@@ -59,5 +62,5 @@ export const usePatchRequest = <TResponse>({ path, baseUrl, headers }: { path: s
59
62
  return mutation.mutateAsync(data, options);
60
63
  };
61
64
 
62
- return { patch, ...mutation };
65
+ return { patch, uploadProgressPercent, ...mutation };
63
66
  };
@@ -4,6 +4,7 @@ import { useEnvironmentVariables, useQueryHeaders, useReactNativeEnv } from '../
4
4
 
5
5
  import type { RawAxiosRequestHeaders } from 'axios';
6
6
  import { scrollToTop } from '../helpers';
7
+ import { useUploadProgress } from '../hooks';
7
8
  import type { IRequestError, IRequestSuccess } from '../request';
8
9
  import { HttpMethod, makeRequest } from '../request';
9
10
  import type { TanstackQueryConfig } from '../types';
@@ -24,6 +25,8 @@ export const usePostRequest = <TResponse>({
24
25
  const queryClient = useQueryClient();
25
26
  const { getHeaders } = useQueryHeaders();
26
27
  const { isApp } = useReactNativeEnv();
28
+ const { uploadProgressPercent, onUploadProgress } = useUploadProgress();
29
+
27
30
  const sendRequest = async (res: (value: any) => void, rej: (reason?: any) => void, postData: any) => {
28
31
  // get request headers
29
32
  const globalHeaders: RawAxiosRequestHeaders = getHeaders();
@@ -41,6 +44,7 @@ export const usePostRequest = <TResponse>({
41
44
  isApp,
42
45
  fileSelectors,
43
46
  },
47
+ onUploadProgress,
44
48
  });
45
49
 
46
50
  if (postResponse.status) {
@@ -70,5 +74,5 @@ export const usePostRequest = <TResponse>({
70
74
  return mutation.mutateAsync(data, options);
71
75
  };
72
76
 
73
- return { post, ...mutation };
77
+ return { post, uploadProgressPercent, ...mutation };
74
78
  };
@@ -14,6 +14,7 @@ export async function makeRequest<TResponse>({
14
14
  baseURL,
15
15
  timeout,
16
16
  appFileConfig,
17
+ onUploadProgress,
17
18
  }: IMakeRequest) {
18
19
  // check if file is included in mobile app environment and extract all file input to avoid
19
20
  // it being formatted to object using axios formData builder
@@ -53,6 +54,7 @@ export async function makeRequest<TResponse>({
53
54
  url: path,
54
55
  method,
55
56
  data: body,
57
+ onUploadProgress,
56
58
  });
57
59
 
58
60
  // get response json
@@ -1,4 +1,4 @@
1
- import type { RawAxiosRequestHeaders } from 'axios';
1
+ import type { AxiosProgressEvent, RawAxiosRequestHeaders } from 'axios';
2
2
  import type { HttpMethod } from './request.enum';
3
3
 
4
4
  export interface IMakeRequest {
@@ -10,12 +10,14 @@ export interface IMakeRequest {
10
10
  isFormData?: boolean;
11
11
  headers: RawAxiosRequestHeaders;
12
12
  appFileConfig?: AppFileConfig;
13
+ onUploadProgress?: (progressEvent: AxiosProgressEvent) => void;
13
14
  }
14
15
 
15
16
  export interface AppFileConfig {
16
17
  fileSelectors?: string[];
17
18
  isApp: boolean;
18
19
  }
20
+
19
21
  export interface AxiosInstanceOption {
20
22
  bearerToken?: string;
21
23
  contentType?: string;