query-harbor 0.0.1 → 0.0.3

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
@@ -1,8 +1,350 @@
1
- # React + Vite
1
+ # Query Harbor
2
2
 
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
3
+ A collection of custom React hooks built on top of TanStack Query (formerly React Query) for handling API requests, mutations, and cookie management. These hooks provide a standardized way to handle data fetching, caching, and state management in React applications.
4
4
 
5
- Currently, two official plugins are available:
5
+ ## Table of Contents
6
6
 
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
7
+ - [Installation](#installation)
8
+ - [Hooks Overview](#hooks-overview)
9
+ - [useGlobalQuery](#useglobalquery)
10
+ - [useGlobalMutation](#useglobalmutation)
11
+ - [useGlobalInfiniteQuery](#useglobalinfinitequery)
12
+ - [useCookie](#usecookie)
13
+ - [Usage Examples](#usage-examples)
14
+ - [API Reference](#api-reference)
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ # Install required dependencies
20
+ npm install @tanstack/react-query react-cookie axios
21
+ ```
22
+
23
+ ## Hooks Overview
24
+
25
+ ### useGlobalQuery
26
+
27
+ A custom hook for making standard API requests with built-in caching and state management.
28
+
29
+ #### Features
30
+ - Automatic authentication header handling
31
+ - Configurable cache and stale times
32
+ - Built-in error handling
33
+ - Query invalidation support
34
+
35
+ #### Basic Usage
36
+
37
+ ```javascript
38
+ const {
39
+ queryData,
40
+ isLoading,
41
+ isError,
42
+ error,
43
+ refetchQuery
44
+ } = useGlobalQuery({
45
+ url: '/api/users',
46
+ queryKey: ['users'],
47
+ methodType: 'GET'
48
+ });
49
+ ```
50
+
51
+ ### useGlobalMutation
52
+
53
+ A custom hook for handling data mutations (create, update, delete operations) with support for FormData.
54
+
55
+ #### Features
56
+ - FormData support with nested object handling
57
+ - Automatic query invalidation after successful mutation
58
+ - Priority data support
59
+ - Built-in error handling
60
+
61
+ #### Basic Usage
62
+
63
+ ```javascript
64
+ const {
65
+ runMutation,
66
+ mutationLoading,
67
+ mutationData,
68
+ mutationError,
69
+ isMutationSucceeded
70
+ } = useGlobalMutation({
71
+ url: '/api/users',
72
+ queriesToInvalidate: ['users'],
73
+ methodType: 'POST',
74
+ data: userData
75
+ });
76
+ ```
77
+
78
+ #### FormData Upload Examples
79
+
80
+ ##### Basic FormData Upload
81
+
82
+ ```javascript
83
+ const {
84
+ runMutation,
85
+ mutationLoading
86
+ } = useGlobalMutation({
87
+ url: '/api/upload',
88
+ queriesToInvalidate: ['files'],
89
+ methodType: 'POST',
90
+ isFormData: true,
91
+ data: {
92
+ file: fileObject,
93
+ title: 'My Document'
94
+ }
95
+ });
96
+ ```
97
+
98
+ ##### Complex FormData with Arrays
99
+
100
+ ```javascript
101
+ // Without excludedIndexKeys
102
+ const data = {
103
+ files: [file1, file2],
104
+ metadata: {
105
+ titles: ['Doc 1', 'Doc 2']
106
+ }
107
+ };
108
+
109
+ // This will generate FormData with structure:
110
+ // files[0] = file1
111
+ // files[1] = file2
112
+ // metadata[titles][0] = Doc 1
113
+ // metadata[titles][1] = Doc 2
114
+ ```
115
+
116
+ ##### Using excludedIndexKeys
117
+
118
+ ```javascript
119
+ const MultipleFileUpload = () => {
120
+ const {
121
+ runMutation,
122
+ mutationLoading
123
+ } = useGlobalMutation({
124
+ url: '/api/upload-multiple',
125
+ queriesToInvalidate: ['files'],
126
+ methodType: 'POST',
127
+ isFormData: true,
128
+ // Specify which keys should not include array indices
129
+ excludedIndexKeys: ['files', 'documents'],
130
+ data: {
131
+ files: [file1, file2, file3],
132
+ documents: [docFile1, docFile2],
133
+ metadata: {
134
+ titles: ['Doc 1', 'Doc 2', 'Doc 3'],
135
+ categories: ['Cat 1', 'Cat 2', 'Cat 3']
136
+ }
137
+ }
138
+ });
139
+
140
+ return (
141
+ <button onClick={() => runMutation()}>
142
+ Upload Files
143
+ </button>
144
+ );
145
+ };
146
+ ```
147
+
148
+ The above example will generate FormData with the following structure:
149
+ ```plaintext
150
+ // Keys with excludedIndexKeys:
151
+ files = file1
152
+ files = file2
153
+ files = file3
154
+ documents = docFile1
155
+ documents = docFile2
156
+
157
+ // Regular array keys (maintain indices):
158
+ metadata[titles][0] = Doc 1
159
+ metadata[titles][1] = Doc 2
160
+ metadata[titles][2] = Doc 3
161
+ metadata[categories][0] = Cat 1
162
+ metadata[categories][1] = Cat 2
163
+ metadata[categories][2] = Cat 3
164
+ ```
165
+
166
+ ##### Real-World Example: Multiple File Upload with Metadata
167
+
168
+ ```javascript
169
+ const DocumentUploadForm = () => {
170
+ const [files, setFiles] = useState([]);
171
+ const [metadata, setMetadata] = useState({
172
+ department: 'HR',
173
+ tags: ['confidential', 'employee'],
174
+ });
175
+
176
+ const {
177
+ runMutation,
178
+ mutationLoading,
179
+ isMutationSucceeded
180
+ } = useGlobalMutation({
181
+ url: '/api/documents/upload',
182
+ queriesToInvalidate: ['documents'],
183
+ methodType: 'POST',
184
+ isFormData: true,
185
+ excludedIndexKeys: ['files'], // files will be sent without indices
186
+ data: {
187
+ files: files,
188
+ metadata: metadata,
189
+ timestamp: new Date().toISOString(),
190
+ user: {
191
+ id: currentUserId,
192
+ role: userRole
193
+ }
194
+ }
195
+ });
196
+
197
+ const handleFileChange = (e) => {
198
+ setFiles(Array.from(e.target.files));
199
+ };
200
+
201
+ const handleUpload = () => {
202
+ runMutation();
203
+ };
204
+
205
+ return (
206
+ <div>
207
+ <input
208
+ type="file"
209
+ multiple
210
+ onChange={handleFileChange}
211
+ />
212
+ {mutationLoading ? (
213
+ <p>Uploading...</p>
214
+ ) : (
215
+ <button onClick={handleUpload}>
216
+ Upload Documents
217
+ </button>
218
+ )}
219
+ {isMutationSucceeded && (
220
+ <p>Upload completed successfully!</p>
221
+ )}
222
+ </div>
223
+ );
224
+ };
225
+ ```
226
+
227
+ This will generate FormData where:
228
+ - Multiple files are sent with the same key name ('files')
229
+ - Metadata is properly nested with array indices preserved
230
+ - Additional data is structured appropriately
231
+
232
+ The resulting FormData structure will be:
233
+ ```plaintext
234
+ files = File1
235
+ files = File2
236
+ metadata[department] = HR
237
+ metadata[tags][0] = confidential
238
+ metadata[tags][1] = employee
239
+ timestamp = 2024-02-23T10:00:00.000Z
240
+ user[id] = 123
241
+ user[role] = admin
242
+ ```
243
+
244
+ #### When to Use excludedIndexKeys
245
+
246
+ Use `excludedIndexKeys` when:
247
+ 1. Working with file upload APIs that expect multiple files with the same key
248
+ 2. Dealing with legacy APIs that don't support indexed form fields
249
+ 3. Implementing multi-file upload where the server expects a flat structure
250
+ 4. Handling file arrays where order doesn't matter
251
+
252
+ ### useGlobalInfiniteQuery
253
+
254
+ A custom hook for handling infinite scroll or pagination scenarios.
255
+
256
+ #### Features
257
+ - Automatic pagination handling
258
+ - Built-in cache management
259
+ - Total count tracking
260
+ - Next page detection
261
+
262
+ #### Basic Usage
263
+
264
+ ```javascript
265
+ const {
266
+ queryData,
267
+ isLoading,
268
+ isError,
269
+ error,
270
+ fetchNextPage,
271
+ hasNextPage,
272
+ totalCount
273
+ } = useGlobalInfiniteQuery({
274
+ url: '/api/posts',
275
+ queryKey: ['posts'],
276
+ methodType: 'GET',
277
+ data: { limit: 10 }
278
+ });
279
+ ```
280
+
281
+ ### useCookie
282
+
283
+ A utility hook for managing cookies across the application.
284
+
285
+ #### Features
286
+ - Simple cookie management
287
+ - Type-safe cookie operations
288
+ - Easy integration with authentication
289
+
290
+ #### Basic Usage
291
+
292
+ ```javascript
293
+ const { cookie, setCookie, removeCookie } = useCookie({
294
+ cookieName: 'accessToken'
295
+ });
296
+ ```
297
+
298
+ ## API Reference
299
+
300
+ ### useGlobalQuery Options
301
+
302
+ | Option | Type | Default | Description |
303
+ |--------|------|---------|-------------|
304
+ | url | string | required | API endpoint URL |
305
+ | queryKey | string[] | required | Unique key for caching |
306
+ | methodType | string | required | HTTP method (GET, POST, etc.) |
307
+ | data | object | optional | Request payload |
308
+ | enabled | boolean | true | Whether to enable the query |
309
+ | cacheTime | number | 300000 | Cache duration in ms |
310
+ | staleTime | number | 300000 | Stale data duration in ms |
311
+
312
+ ### useGlobalMutation Options
313
+
314
+ | Option | Type | Default | Description |
315
+ |--------|------|---------|-------------|
316
+ | url | string | required | API endpoint URL |
317
+ | queriesToInvalidate | string[] | required | Queries to refresh after mutation |
318
+ | methodType | string | required | HTTP method (POST, PUT, DELETE) |
319
+ | data | object | optional | Default mutation data |
320
+ | isFormData | boolean | false | Whether to handle as FormData |
321
+ | closePopup | function | optional | Callback after success |
322
+ | excludedIndexKeys | string[] | optional | Keys to exclude from FormData indices |
323
+
324
+ ### useGlobalInfiniteQuery Options
325
+
326
+ | Option | Type | Default | Description |
327
+ |--------|------|---------|-------------|
328
+ | url | string | required | API endpoint URL |
329
+ | queryKey | string[] | required | Unique key for caching |
330
+ | methodType | string | required | HTTP method |
331
+ | data | object | optional | Additional query parameters |
332
+ | enabled | boolean | true | Whether to enable the query |
333
+ | cacheTime | number | 300000 | Cache duration in ms |
334
+ | staleTime | number | 300000 | Stale data duration in ms |
335
+
336
+ ## Best Practices
337
+
338
+ 1. Always provide unique and descriptive query keys
339
+ 2. Set appropriate cache and stale times based on data volatility
340
+ 3. Handle loading and error states in your UI
341
+ 4. Use the refetchQuery function for manual data refresh
342
+ 5. Implement proper error boundaries in your application
343
+
344
+ ## Contributing
345
+
346
+ Contributions are welcome! Please feel free to submit a Pull Request.
347
+
348
+ ## License
349
+
350
+ MIT
@@ -0,0 +1,248 @@
1
+ import { useQueryClient as M, useQuery as L, useMutation as S, useInfiniteQuery as O } from "@tanstack/react-query";
2
+ import { useCookies as j } from "react-cookie";
3
+ import F from "axios";
4
+ const b = ({ cookieName: u }) => {
5
+ const [n, o, c] = j([u]);
6
+ return { cookie: n, setCookie: o, removeCookie: c };
7
+ }, U = ({
8
+ url: u,
9
+ queryKey: n,
10
+ methodType: o,
11
+ data: c,
12
+ enabled: y = !0,
13
+ cacheTime: h = 5 * 60 * 1e3,
14
+ staleTime: E = 5 * 60 * 1e3
15
+ }) => {
16
+ const m = M(), { cookie: e } = b({ cookieName: "accessToken" });
17
+ let t = {};
18
+ e != null && e.accessToken && (t = { Authorization: `Bearer ${e == null ? void 0 : e.accessToken}` });
19
+ const s = L({
20
+ queryKey: n,
21
+ queryFn: async () => {
22
+ try {
23
+ const i = await APIHandler({
24
+ action: o,
25
+ url: u,
26
+ data: c,
27
+ headers: t
28
+ });
29
+ return i != null && i.data ? i.data : { totalCount: 0, data: [] };
30
+ } catch (i) {
31
+ throw console.error("Query Error:", i), i;
32
+ }
33
+ },
34
+ enabled: y,
35
+ cacheTime: h,
36
+ staleTime: E,
37
+ refetchOnWindowFocus: !1
38
+ });
39
+ return {
40
+ refetchQuery: () => {
41
+ m.invalidateQueries({ queryKey: n });
42
+ },
43
+ queryData: s.data,
44
+ isLoading: s.isLoading,
45
+ isError: s.isError,
46
+ error: s.error
47
+ };
48
+ }, G = async ({ action: u, url: n, data: o, headers: c }) => {
49
+ switch (u) {
50
+ case "GET":
51
+ return await F.get(n, {
52
+ headers: c
53
+ });
54
+ case "POST":
55
+ return await F.post(n, o, {
56
+ headers: c
57
+ });
58
+ case "PUT":
59
+ return await F.put(n, o, {
60
+ headers: c
61
+ });
62
+ case "DELETE":
63
+ return await F.delete(n, { data: o, headers: c });
64
+ default:
65
+ throw new Error(`Invalid action: ${u}`);
66
+ }
67
+ }, $ = async ({ action: u, url: n, data: o, headers: c }) => {
68
+ var y, h, E, m, e;
69
+ try {
70
+ const t = await G({ action: u, url: n, data: o, headers: c });
71
+ return t.status >= 200 && t.status <= 299 ? {
72
+ status: !0,
73
+ data: t.data,
74
+ message: t.data.message,
75
+ statusCode: t.status
76
+ } : {
77
+ status: !1,
78
+ error: "API Failed",
79
+ message: "API Failed",
80
+ statusCode: t.status
81
+ };
82
+ } catch (t) {
83
+ return F.isAxiosError(t) ? t.message === "Network Error" ? {
84
+ status: !1,
85
+ error: "Network Error",
86
+ message: "Network Error"
87
+ } : {
88
+ status: !1,
89
+ type: (h = (y = t.response) == null ? void 0 : y.data) == null ? void 0 : h.type,
90
+ message: (E = t.response) == null ? void 0 : E.data.message,
91
+ error: (m = t.response) == null ? void 0 : m.data.error,
92
+ statusCode: (e = t.response) == null ? void 0 : e.status
93
+ } : {
94
+ status: !1,
95
+ error: "API Failed",
96
+ message: "API Failed"
97
+ };
98
+ }
99
+ }, W = ({
100
+ url: u,
101
+ queriesToInvalidate: n,
102
+ methodType: o,
103
+ data: c,
104
+ isFormData: y,
105
+ closePopup: h,
106
+ excludedIndexKeys: E
107
+ }) => {
108
+ var i;
109
+ const m = M(), { cookie: e } = b({ cookieName: "accessToken" });
110
+ let t = {};
111
+ e != null && e.accessToken && (t = { Authorization: `Bearer ${e == null ? void 0 : e.accessToken}` });
112
+ const s = S({
113
+ mutationFn: async ({ isPriorityDataAvailable: l, priorityData: P }) => {
114
+ const p = l ? P : c;
115
+ if (y) {
116
+ let C = new FormData();
117
+ const T = (r, a, g = "", A = {}) => {
118
+ if (a == null) return;
119
+ const { excludedIndexKeys: v = [] } = A;
120
+ Array.isArray(a) ? a.forEach((f, Q) => {
121
+ const N = v.includes(g) ? g : g ? `${g}[${Q}]` : `${Q}`;
122
+ f instanceof File ? r == null || r.append(N, f) : typeof f == "object" && f !== null ? T(r, f, N, A) : r == null || r.append(N, f);
123
+ }) : typeof a == "object" && a !== null ? a instanceof File ? r.append(g, a) : Object.keys(a).forEach((f) => {
124
+ const Q = a[f], q = g ? `${g}[${f}]` : f;
125
+ T(
126
+ r,
127
+ Q,
128
+ q,
129
+ A
130
+ );
131
+ }) : a !== "" && a !== void 0 && a !== null && (r == null || r.append(g, a));
132
+ }, x = {
133
+ excludedIndexKeys: E
134
+ };
135
+ Object.keys(p).forEach((r) => {
136
+ T(C, p[r], r, x);
137
+ });
138
+ const {
139
+ status: w,
140
+ message: d,
141
+ data: k
142
+ } = await $({
143
+ action: o,
144
+ url: u,
145
+ data: C,
146
+ headers: t
147
+ });
148
+ if (w)
149
+ return k;
150
+ throw new Error(d || "Something went wrong!");
151
+ } else {
152
+ const {
153
+ status: C,
154
+ message: T,
155
+ data: x
156
+ } = await $({
157
+ action: o,
158
+ url: u,
159
+ data: p,
160
+ headers: t
161
+ });
162
+ if (C)
163
+ return x;
164
+ throw new Error(T || "Something went wrong!");
165
+ }
166
+ },
167
+ onSuccess: () => {
168
+ m.invalidateQueries({ queryKey: n }), h && h(!1);
169
+ },
170
+ onError: (l) => (console.log("mutationError", l == null ? void 0 : l.message), l == null ? void 0 : l.message)
171
+ });
172
+ return {
173
+ runMutation: ({ isPriorityDataAvailable: l, priorityData: P } = {}) => {
174
+ try {
175
+ s.mutate({ isPriorityDataAvailable: l, priorityData: P });
176
+ } catch (p) {
177
+ console.log("Mutation Error: ", p);
178
+ }
179
+ },
180
+ mutationLoading: s.isPending,
181
+ mutationData: s.data,
182
+ mutationError: (i = s.error) == null ? void 0 : i.message,
183
+ isMutationSucceeded: s.isSuccess
184
+ };
185
+ }, J = ({
186
+ url: u,
187
+ queryKey: n,
188
+ methodType: o,
189
+ data: c,
190
+ enabled: y = !0,
191
+ cacheTime: h = 5 * 60 * 1e3,
192
+ staleTime: E = 5 * 60 * 1e3
193
+ }) => {
194
+ var P, p, C, T, x;
195
+ const m = M(), { cookie: e } = b({ cookieName: "accessToken" });
196
+ let t = {};
197
+ e != null && e.accessToken && (t = { Authorization: `Bearer ${e == null ? void 0 : e.accessToken}` });
198
+ const s = O({
199
+ queryKey: n,
200
+ queryFn: async ({ pageParam: w }) => {
201
+ try {
202
+ const d = await $({
203
+ action: o,
204
+ url: u,
205
+ data: {
206
+ ...c,
207
+ page: w
208
+ },
209
+ headers: t
210
+ });
211
+ if (d != null && d.data) {
212
+ const { data: k, page: r, totalPages: a, totalCount: g } = d == null ? void 0 : d.data, A = r < a;
213
+ return {
214
+ data: k,
215
+ nextPage: A ? r + 1 : void 0,
216
+ hasMore: A,
217
+ totalCount: g
218
+ };
219
+ } else
220
+ return { totalCount: 0, data: [] };
221
+ } catch (d) {
222
+ throw console.error("Query Error:", d), d;
223
+ }
224
+ },
225
+ getNextPageParam: (w) => w.hasMore ? w.nextPage : void 0,
226
+ enabled: y,
227
+ cacheTime: h,
228
+ staleTime: E,
229
+ refetchOnWindowFocus: !1
230
+ }), I = () => {
231
+ m.invalidateQueries({ queryKey: n });
232
+ }, i = ((p = (P = s == null ? void 0 : s.data) == null ? void 0 : P.pages) == null ? void 0 : p.flatMap((w) => w.data)) || [], l = ((x = (T = (C = s == null ? void 0 : s.data) == null ? void 0 : C.pages) == null ? void 0 : T[0]) == null ? void 0 : x.totalCount) ?? 0;
233
+ return {
234
+ refetchQuery: I,
235
+ queryData: i,
236
+ isLoading: s.isLoading,
237
+ isError: s.isError,
238
+ error: s.error,
239
+ fetchNextPage: s.fetchNextPage,
240
+ hasNextPage: s.hasNextPage,
241
+ totalCount: l
242
+ };
243
+ };
244
+ export {
245
+ J as useGlobalInfiniteQuery,
246
+ W as useGlobalMutation,
247
+ U as useGlobalQuery
248
+ };
@@ -0,0 +1 @@
1
+ (function(d,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("@tanstack/react-query"),require("react-cookie"),require("axios")):typeof define=="function"&&define.amd?define(["exports","@tanstack/react-query","react-cookie","axios"],g):(d=typeof globalThis<"u"?globalThis:d||self,g(d.QueryHarbor={},d.ReactQuery,d.ReactCookie,d.axios))})(this,function(d,g,v,I){"use strict";const b=({cookieName:i})=>{const[r,a,u]=v.useCookies([i]);return{cookie:r,setCookie:a,removeCookie:u}},G=({url:i,queryKey:r,methodType:a,data:u,enabled:T=!0,cacheTime:w=3e5,staleTime:p=3e5})=>{const C=g.useQueryClient(),{cookie:e}=b({cookieName:"accessToken"});let t={};e!=null&&e.accessToken&&(t={Authorization:`Bearer ${e==null?void 0:e.accessToken}`});const s=g.useQuery({queryKey:r,queryFn:async()=>{try{const c=await APIHandler({action:a,url:i,data:u,headers:t});return c!=null&&c.data?c.data:{totalCount:0,data:[]}}catch(c){throw console.error("Query Error:",c),c}},enabled:T,cacheTime:w,staleTime:p,refetchOnWindowFocus:!1});return{refetchQuery:()=>{C.invalidateQueries({queryKey:r})},queryData:s.data,isLoading:s.isLoading,isError:s.isError,error:s.error}},j=async({action:i,url:r,data:a,headers:u})=>{switch(i){case"GET":return await I.get(r,{headers:u});case"POST":return await I.post(r,a,{headers:u});case"PUT":return await I.put(r,a,{headers:u});case"DELETE":return await I.delete(r,{data:a,headers:u});default:throw new Error(`Invalid action: ${i}`)}},q=async({action:i,url:r,data:a,headers:u})=>{var T,w,p,C,e;try{const t=await j({action:i,url:r,data:a,headers:u});return t.status>=200&&t.status<=299?{status:!0,data:t.data,message:t.data.message,statusCode:t.status}:{status:!1,error:"API Failed",message:"API Failed",statusCode:t.status}}catch(t){return I.isAxiosError(t)?t.message==="Network Error"?{status:!1,error:"Network Error",message:"Network Error"}:{status:!1,type:(w=(T=t.response)==null?void 0:T.data)==null?void 0:w.type,message:(p=t.response)==null?void 0:p.data.message,error:(C=t.response)==null?void 0:C.data.error,statusCode:(e=t.response)==null?void 0:e.status}:{status:!1,error:"API Failed",message:"API Failed"}}},L=({url:i,queriesToInvalidate:r,methodType:a,data:u,isFormData:T,closePopup:w,excludedIndexKeys:p})=>{var c;const C=g.useQueryClient(),{cookie:e}=b({cookieName:"accessToken"});let t={};e!=null&&e.accessToken&&(t={Authorization:`Bearer ${e==null?void 0:e.accessToken}`});const s=g.useMutation({mutationFn:async({isPriorityDataAvailable:l,priorityData:Q})=>{const P=l?Q:u;if(T){let m=new FormData;const k=(n,o,h="",F={})=>{if(o==null)return;const{excludedIndexKeys:H=[]}=F;Array.isArray(o)?o.forEach((y,x)=>{const $=H.includes(h)?h:h?`${h}[${x}]`:`${x}`;y instanceof File?n==null||n.append($,y):typeof y=="object"&&y!==null?k(n,y,$,F):n==null||n.append($,y)}):typeof o=="object"&&o!==null?o instanceof File?n.append(h,o):Object.keys(o).forEach(y=>{const x=o[y],S=h?`${h}[${y}]`:y;k(n,x,S,F)}):o!==""&&o!==void 0&&o!==null&&(n==null||n.append(h,o))},A={excludedIndexKeys:p};Object.keys(P).forEach(n=>{k(m,P[n],n,A)});const{status:E,message:f,data:N}=await q({action:a,url:i,data:m,headers:t});if(E)return N;throw new Error(f||"Something went wrong!")}else{const{status:m,message:k,data:A}=await q({action:a,url:i,data:P,headers:t});if(m)return A;throw new Error(k||"Something went wrong!")}},onSuccess:()=>{C.invalidateQueries({queryKey:r}),w&&w(!1)},onError:l=>(console.log("mutationError",l==null?void 0:l.message),l==null?void 0:l.message)});return{runMutation:({isPriorityDataAvailable:l,priorityData:Q}={})=>{try{s.mutate({isPriorityDataAvailable:l,priorityData:Q})}catch(P){console.log("Mutation Error: ",P)}},mutationLoading:s.isPending,mutationData:s.data,mutationError:(c=s.error)==null?void 0:c.message,isMutationSucceeded:s.isSuccess}},O=({url:i,queryKey:r,methodType:a,data:u,enabled:T=!0,cacheTime:w=3e5,staleTime:p=3e5})=>{var Q,P,m,k,A;const C=g.useQueryClient(),{cookie:e}=b({cookieName:"accessToken"});let t={};e!=null&&e.accessToken&&(t={Authorization:`Bearer ${e==null?void 0:e.accessToken}`});const s=g.useInfiniteQuery({queryKey:r,queryFn:async({pageParam:E})=>{try{const f=await q({action:a,url:i,data:{...u,page:E},headers:t});if(f!=null&&f.data){const{data:N,page:n,totalPages:o,totalCount:h}=f==null?void 0:f.data,F=n<o;return{data:N,nextPage:F?n+1:void 0,hasMore:F,totalCount:h}}else return{totalCount:0,data:[]}}catch(f){throw console.error("Query Error:",f),f}},getNextPageParam:E=>E.hasMore?E.nextPage:void 0,enabled:T,cacheTime:w,staleTime:p,refetchOnWindowFocus:!1}),M=()=>{C.invalidateQueries({queryKey:r})},c=((P=(Q=s==null?void 0:s.data)==null?void 0:Q.pages)==null?void 0:P.flatMap(E=>E.data))||[],l=((A=(k=(m=s==null?void 0:s.data)==null?void 0:m.pages)==null?void 0:k[0])==null?void 0:A.totalCount)??0;return{refetchQuery:M,queryData:c,isLoading:s.isLoading,isError:s.isError,error:s.error,fetchNextPage:s.fetchNextPage,hasNextPage:s.hasNextPage,totalCount:l}};d.useGlobalInfiniteQuery=O,d.useGlobalMutation=L,d.useGlobalQuery=G,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "query-harbor",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "files": ["dist"],
6
6
  "main": "./dist/query-harbor.umd.js",
@@ -8,6 +8,11 @@
8
8
  "keywords": ["react", "react-query", "hooks", "tanstack", "query", "react-hooks", "harbor", "query-harbor", "react-query-hooks", "custom-hooks"],
9
9
  "author": "Rohit Chaware",
10
10
  "license": "MIT",
11
+ "description": "A React Query utility package for efficient data fetching and caching",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/R4Rohit23/react-query-hooks"
15
+ },
11
16
  "exports": {
12
17
  ".": {
13
18
  "import": "./dist/query-harbor.es.js",
@@ -1 +0,0 @@
1
- (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const e of document.querySelectorAll('link[rel="modulepreload"]'))i(e);new MutationObserver(e=>{for(const r of e)if(r.type==="childList")for(const o of r.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&i(o)}).observe(document,{childList:!0,subtree:!0});function s(e){const r={};return e.integrity&&(r.integrity=e.integrity),e.referrerPolicy&&(r.referrerPolicy=e.referrerPolicy),e.crossOrigin==="use-credentials"?r.credentials="include":e.crossOrigin==="anonymous"?r.credentials="omit":r.credentials="same-origin",r}function i(e){if(e.ep)return;e.ep=!0;const r=s(e);fetch(e.href,r)}})();
package/dist/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>Vite + React</title>
8
- <script type="module" crossorigin src="/assets/index-B5Qt9EMX.js"></script>
9
- </head>
10
- <body>
11
- <div id="root"></div>
12
- </body>
13
- </html>