@ventlio/tanstack-query 0.5.12 → 0.5.13

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.
Files changed (55) hide show
  1. package/README.md +178 -150
  2. package/dist/config/bootstrapQueryRequest.d.ts +6 -0
  3. package/dist/config/useEnvironmentVariables.d.ts +4 -0
  4. package/dist/index.mjs +306 -89
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/node_modules/@tanstack/react-store/dist/esm/index.js +1 -1
  7. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim/with-selector.development.js +1 -1
  8. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +1 -0
  9. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim/with-selector.production.js +1 -1
  10. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js.map +1 -0
  11. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim.development.js +1 -1
  12. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +1 -0
  13. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/cjs/use-sync-external-store-shim.production.js +1 -1
  14. package/dist/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +1 -0
  15. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/shim/index.js +1 -1
  16. package/dist/node_modules/use-sync-external-store/shim/index.js.map +1 -0
  17. package/dist/node_modules/{@tanstack/react-store/node_modules/use-sync-external-store → use-sync-external-store}/shim/with-selector.js +1 -1
  18. package/dist/node_modules/use-sync-external-store/shim/with-selector.js.map +1 -0
  19. package/dist/queries/useGetRequest.d.ts +12 -2
  20. package/dist/request/make-request.d.ts +12 -1
  21. package/dist/src/config/bootstrapQueryRequest.js +41 -1
  22. package/dist/src/config/bootstrapQueryRequest.js.map +1 -1
  23. package/dist/src/config/useEnvironmentVariables.js +34 -3
  24. package/dist/src/config/useEnvironmentVariables.js.map +1 -1
  25. package/dist/src/index.js +1 -1
  26. package/dist/src/queries/useDeleteRequest.js +19 -14
  27. package/dist/src/queries/useDeleteRequest.js.map +1 -1
  28. package/dist/src/queries/useGetInfiniteRequest.js +17 -12
  29. package/dist/src/queries/useGetInfiniteRequest.js.map +1 -1
  30. package/dist/src/queries/useGetRequest.js +86 -28
  31. package/dist/src/queries/useGetRequest.js.map +1 -1
  32. package/dist/src/queries/usePatchRequest.js +19 -14
  33. package/dist/src/queries/usePatchRequest.js.map +1 -1
  34. package/dist/src/queries/usePostRequest.js +18 -13
  35. package/dist/src/queries/usePostRequest.js.map +1 -1
  36. package/dist/src/request/make-request.js +75 -6
  37. package/dist/src/request/make-request.js.map +1 -1
  38. package/dist/types/index.d.ts +24 -5
  39. package/package.json +2 -2
  40. package/src/config/bootstrapQueryRequest.ts +47 -2
  41. package/src/config/useEnvironmentVariables.ts +41 -3
  42. package/src/queries/useDeleteRequest.ts +18 -20
  43. package/src/queries/useGetInfiniteRequest.ts +17 -17
  44. package/src/queries/useGetRequest.ts +109 -33
  45. package/src/queries/usePatchRequest.ts +19 -16
  46. package/src/queries/usePostRequest.ts +18 -15
  47. package/src/queries/usePutRequest.ts +16 -15
  48. package/src/request/make-request.ts +112 -15
  49. package/src/types/index.ts +38 -4
  50. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.development.js.map +0 -1
  51. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim/with-selector.production.js.map +0 -1
  52. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.development.js.map +0 -1
  53. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/cjs/use-sync-external-store-shim.production.js.map +0 -1
  54. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/shim/index.js.map +0 -1
  55. package/dist/node_modules/@tanstack/react-store/node_modules/use-sync-external-store/shim/with-selector.js.map +0 -1
package/README.md CHANGED
@@ -19,13 +19,15 @@ But we were not discouraged. So, we set out to find a solution which led to the
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
- - [] Put request
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)
22
+ - [] Put request
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)
26
+ - [✅] Enhanced middleware system with chainable middleware
27
+ - [✅] Cross-framework compatibility (Vite, Next.js, CRA, etc.)
26
28
  - [❌] Server sent events
27
29
  - [❌] Socket implementations
28
- - [] Tests
30
+ - [] Tests
29
31
 
30
32
  ## Installation
31
33
 
@@ -85,6 +87,9 @@ REACT_APP_API_TIMEOUT=300000
85
87
  NEXT_PUBLIC_API_URL='https://api.example.com'
86
88
  NEXT_PUBLIC_API_TIMEOUT=300000
87
89
 
90
+ # For Vite (New!)
91
+ VITE_API_URL='https://api.example.com'
92
+ VITE_API_TIMEOUT=300000
88
93
  ```
89
94
 
90
95
  ```js
@@ -107,6 +112,68 @@ bootstrapQueryRequest(queryClient, {
107
112
  modelConfig: {
108
113
  idColumn: 'id', // used for useQueryModel to uniquely identify query data in a collection/array instance
109
114
  },
115
+ // NEW: Configure custom pagination
116
+ pagination: {
117
+ pageParamName: 'page', // default page parameter name
118
+ // Custom function to extract pagination data from response
119
+ extractPagination: (response) => {
120
+ // Example for a different API format
121
+ return {
122
+ current_page: response.data.meta.currentPage,
123
+ next_page: response.data.meta.currentPage + 1,
124
+ previous_page: response.data.meta.currentPage - 1,
125
+ size: response.data.meta.perPage,
126
+ page_count: response.data.meta.lastPage,
127
+ total: response.data.meta.total,
128
+ };
129
+ },
130
+ // Custom function to build pagination URL
131
+ buildPaginationUrl: (url, page) => {
132
+ // Custom implementation
133
+ const [pathname, queryString] = url.split('?');
134
+ const queryParams = new URLSearchParams(queryString || '');
135
+ queryParams.set('page', String(page));
136
+ return pathname + '?' + queryParams.toString();
137
+ },
138
+ },
139
+ // NEW: Enhanced middleware system
140
+ middleware: [
141
+ // Array of middleware functions that will be executed in order
142
+ async (context, next) => {
143
+ // Log request
144
+ console.log('Request:', context.path);
145
+
146
+ // Continue to next middleware or make the request
147
+ const response = await next();
148
+
149
+ // Log response
150
+ console.log('Response:', response);
151
+
152
+ return response;
153
+ },
154
+ // Authentication middleware
155
+ async (context, next) => {
156
+ // Add authentication token if available
157
+ const token = localStorage.getItem('auth_token');
158
+ if (token) {
159
+ context.headers = {
160
+ ...context.headers,
161
+ Authorization: `Bearer ${token}`,
162
+ };
163
+ }
164
+
165
+ // Continue to next middleware or make the request
166
+ const response = await next();
167
+
168
+ // Handle 401 errors
169
+ if (response.statusCode === 401) {
170
+ // Redirect to login or refresh token
171
+ window.location.href = '/login';
172
+ }
173
+
174
+ return response;
175
+ },
176
+ ],
110
177
  });
111
178
  ```
112
179
 
@@ -146,6 +213,111 @@ function LoginPage() {
146
213
  }
147
214
  ```
148
215
 
216
+ ## New Features
217
+
218
+ ### 1. Enhanced Middleware System
219
+
220
+ The library now supports a chainable middleware system that allows you to intercept and modify requests and responses:
221
+
222
+ ```jsx
223
+ // Define middleware functions
224
+ const loggingMiddleware = async (context, next) => {
225
+ console.log('Request:', context.path);
226
+ const response = await next();
227
+ console.log('Response:', response);
228
+ return response;
229
+ };
230
+
231
+ const authMiddleware = async (context, next) => {
232
+ // Add authentication token
233
+ const token = localStorage.getItem('auth_token');
234
+ if (token) {
235
+ context.headers = {
236
+ ...context.headers,
237
+ Authorization: `Bearer ${token}`,
238
+ };
239
+ }
240
+
241
+ return await next();
242
+ };
243
+
244
+ // Use middleware in bootstrap
245
+ bootstrapQueryRequest(queryClient, {
246
+ middleware: [loggingMiddleware, authMiddleware],
247
+ });
248
+ ```
249
+
250
+ ### 2. Configurable Pagination
251
+
252
+ The library now supports custom pagination configuration to work with any API format:
253
+
254
+ ```jsx
255
+ // Global pagination configuration
256
+ bootstrapQueryRequest(queryClient, {
257
+ pagination: {
258
+ pageParamName: 'page', // default page parameter name
259
+ extractPagination: (response) => {
260
+ // Custom extraction for your API format
261
+ return {
262
+ current_page: response.data.meta.current,
263
+ next_page: response.data.meta.current + 1,
264
+ previous_page: response.data.meta.current - 1,
265
+ size: response.data.meta.per_page,
266
+ page_count: response.data.meta.last_page,
267
+ total: response.data.meta.total,
268
+ };
269
+ },
270
+ buildPaginationUrl: (url, page) => {
271
+ // Custom URL builder
272
+ const [pathname, queryString] = url.split('?');
273
+ const queryParams = new URLSearchParams(queryString || '');
274
+ queryParams.set('page', String(page));
275
+ return pathname + '?' + queryParams.toString();
276
+ },
277
+ },
278
+ });
279
+
280
+ // Per-request pagination configuration
281
+ const { data, nextPage, prevPage } = useGetRequest({
282
+ path: '/api/users',
283
+ load: true,
284
+ paginationConfig: {
285
+ // Override global pagination config for this specific request
286
+ pageParamName: 'p', // Use 'p' instead of 'page' for this API
287
+ extractPagination: (response) => {
288
+ // Custom extraction for this specific API
289
+ return {
290
+ current_page: response.data.page,
291
+ next_page: response.data.page + 1,
292
+ previous_page: response.data.page - 1,
293
+ size: response.data.limit,
294
+ page_count: Math.ceil(response.data.total / response.data.limit),
295
+ total: response.data.total,
296
+ };
297
+ },
298
+ },
299
+ });
300
+ ```
301
+
302
+ ### 3. Cross-Framework Compatibility
303
+
304
+ The library now automatically detects and works with various React frameworks:
305
+
306
+ - Create React App (CRA)
307
+ - Next.js
308
+ - Vite
309
+ - React Native
310
+ - Expo
311
+
312
+ Environment variables are automatically detected based on the framework's conventions:
313
+
314
+ ```js
315
+ // For CRA: REACT_APP_API_URL
316
+ // For Next.js: NEXT_PUBLIC_API_URL
317
+ // For Vite: VITE_API_URL
318
+ // For React Native: Provided in the bootstrap config
319
+ ```
320
+
149
321
  # Hooks
150
322
 
151
323
  ## useGetRequest Hook
@@ -390,148 +562,4 @@ const { refetchQuery } = useRefetchQuery(['myQueryKey']);
390
562
  const { data } = await refetchQuery<MyDataType>();
391
563
  ```
392
564
 
393
- If you want to refetch a different query, you can pass a different `queryKey` parameter to `refetchQuery` function:
394
-
395
- ```javascript
396
- const { data } = (await refetchQuery) < MyDataType > ['myOtherQueryKey'];
397
- ```
398
-
399
- If you want to perform additional operations after refetching the query, you can use the `data` returned by `refetchQuery` function:
400
-
401
- ```javascript
402
- const { data } = await refetchQuery<MyDataType>();
403
- // Perform additional operations with data
404
- ```
405
-
406
- ## Parameters
407
-
408
- - `queryKey`: An array of any types that uniquely identifies the query.
409
-
410
- ## Return Value
411
-
412
- - `refetchQuery`: A function that refetches the query and retrieves updated data.
413
-
414
- ## Example
415
-
416
- ```javascript
417
- import { useQueryClient } from '@tanstack/react-query';
418
- import { useRefetchQuery } from '@ventlio/tanstack-query';
419
-
420
- const MyComponent = () => {
421
- const queryClient = useQueryClient();
422
-
423
- const { refetchQuery } = useRefetchQuery(['myQueryKey']);
424
-
425
- const handleClick = async () => {
426
- try {
427
- // Refetch the query and retrieve updated data
428
- const { data } = await refetchQuery<MyDataType>();
429
-
430
- // Perform additional operations with data
431
- console.log(data);
432
- } catch (error) {
433
- // Handle error
434
- console.error(error);
435
- }
436
- };
437
-
438
- return (
439
- <button onClick={handleClick}>
440
- Refetch Query
441
- </button>
442
- );
443
- };
444
- ```
445
-
446
- # useKeyTrackerModel
447
-
448
- A custom hook that utilizes `useQueryClient` hook from `@tanstack/react-query` and `useState` hook from `react` to track a query key and retrieve query data.
449
-
450
- ## Usage
451
-
452
- 1. Import `useKeyTrackerModel` from @ventlio/tanstack-query:
453
-
454
- ```javascript
455
- import { useKeyTrackerModel } from '@ventlio/tanstack-query';
456
- ```
457
-
458
- 2. Call `useKeyTrackerModel` with a `keyTracker` parameter which is a string that uniquely identifies the query key:
459
-
460
- ```javascript
461
- const { refetchQuery, getQueryKey, queryKey, data } = useKeyTrackerModel < MyDataType > 'myKeyTracker';
462
- ```
463
-
464
- 3. Invoke `getQueryKey` function to retrieve the query key:
465
-
466
- ```javascript
467
- const key = getQueryKey();
468
- ```
469
-
470
- 4. Invoke `refetchQuery` function to retrieve query data:
471
-
472
- ```javascript
473
- const queryData = refetchQuery();
474
- ```
475
-
476
- 5. Use `queryKey` and `data` as needed in your component:
477
-
478
- ```javascript
479
- return (
480
- <div>
481
- <p>Query Key: {queryKey}</p>
482
- <p>Query Data: {data}</p>
483
- </div>
484
- );
485
- ```
486
-
487
- ## Parameters
488
-
489
- - `keyTracker`: A string that uniquely identifies the query key.
490
-
491
- ## Return Value
492
-
493
- - `refetchQuery`: A function that retrieves query data.
494
- - `getQueryKey`: A function that retrieves the query key.
495
- - `queryKey`: The query key.
496
- - `data`: The query data.
497
-
498
- ## Example
499
-
500
- ```javascript
501
- import { useQueryClient } from '@tanstack/react-query';
502
- import { useState } from 'react';
503
- import { useKeyTrackerModel } from '@ventlio/tanstack-query';
504
-
505
- const MyComponent = () => {
506
- const queryClient = useQueryClient();
507
-
508
- const { refetchQuery, getQueryKey, queryKey, data } = useKeyTrackerModel < MyDataType > 'myKeyTracker';
509
-
510
- const handleClick = async () => {
511
- // Retrieve the query key
512
- const key = getQueryKey();
513
-
514
- // Retrieve query data
515
- const queryData = refetchQuery();
516
-
517
- // Perform additional operations with query key and data
518
- console.log(key, queryData);
519
- };
520
-
521
- return (
522
- <div>
523
- <button onClick={handleClick}>Get Query Data</button>
524
- <p>Query Key: {queryKey}</p>
525
- <p>Query Data: {data}</p>
526
- </div>
527
- );
528
- };
529
- ```
530
-
531
- ## Contributing
532
-
533
- Contributions to this codebase are welcome. If you find any issues or have any suggestions, please feel free to create an issue or pull request.
534
-
535
- ## License
536
-
537
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
565
+ If you want to refetch a different query, you can pass a different `
@@ -1,4 +1,10 @@
1
1
  import type { QueryClient } from '@tanstack/react-query';
2
2
  import 'url-search-params-polyfill';
3
3
  import type { BootstrapConfig } from '../types';
4
+ /**
5
+ * Bootstrap the query request system with configuration options
6
+ *
7
+ * @param queryClient - TanStack Query client instance
8
+ * @param options - Configuration options
9
+ */
4
10
  export declare const bootstrapQueryRequest: (queryClient: QueryClient, options?: BootstrapConfig) => Promise<void>;
@@ -1,2 +1,6 @@
1
1
  import type { IConfig } from './config.interface';
2
+ /**
3
+ * Hook to access environment variables across different frameworks
4
+ * Supports React (CRA), Next.js, Vite, and React Native
5
+ */
2
6
  export declare const useEnvironmentVariables: () => IConfig;