@royaltics/ui 1.8.8 → 1.9.0
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.http_query.md +87 -332
- package/dist/core/http/http-actions.d.ts +9 -0
- package/dist/core/http/http-actions.d.ts.map +1 -0
- package/dist/core/http/http-actions.js +207 -0
- package/dist/core/http/http-actions.js.map +1 -0
- package/dist/core/http/http-store.d.ts +5 -41
- package/dist/core/http/http-store.d.ts.map +1 -1
- package/dist/core/http/http-store.js +4 -245
- package/dist/core/http/http-store.js.map +1 -1
- package/dist/core/http/http.client.d.ts +4 -0
- package/dist/core/http/http.client.d.ts.map +1 -0
- package/dist/core/http/http.client.js +118 -0
- package/dist/core/http/http.client.js.map +1 -0
- package/dist/core/http/http.refresh.d.ts +2 -0
- package/dist/core/http/http.refresh.d.ts.map +1 -0
- package/dist/core/http/http.refresh.js +75 -0
- package/dist/core/http/http.refresh.js.map +1 -0
- package/dist/core/http/http.types.d.ts +81 -0
- package/dist/core/http/http.types.d.ts.map +1 -0
- package/dist/core/http/http.types.js +2 -0
- package/dist/core/http/http.types.js.map +1 -0
- package/dist/core/http/http.utils.d.ts +6 -0
- package/dist/core/http/http.utils.d.ts.map +1 -0
- package/dist/core/http/http.utils.js +58 -0
- package/dist/core/http/http.utils.js.map +1 -0
- package/dist/core/http/useHttpsubscriptions.d.ts +16 -0
- package/dist/core/http/useHttpsubscriptions.d.ts.map +1 -0
- package/dist/core/http/useHttpsubscriptions.js +110 -0
- package/dist/core/http/useHttpsubscriptions.js.map +1 -0
- package/dist/forms/Autocomplete.stories.d.ts.map +1 -1
- package/dist/forms/Autocomplete.stories.js.map +1 -1
- package/dist/forms/SelectSearch.stories.d.ts.map +1 -1
- package/dist/forms/SelectSearch.stories.js +5 -8
- package/dist/forms/SelectSearch.stories.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useHttpState.d.ts +2 -38
- package/dist/hooks/useHttpState.d.ts.map +1 -1
- package/dist/hooks/useHttpState.js +27 -315
- package/dist/hooks/useHttpState.js.map +1 -1
- package/dist/hooks/useHttpStore.d.ts +19 -0
- package/dist/hooks/useHttpStore.d.ts.map +1 -0
- package/dist/hooks/useHttpStore.js +29 -0
- package/dist/hooks/useHttpStore.js.map +1 -0
- package/dist/providers/http-provider.d.ts +1 -1
- package/package.json +1 -1
package/README.http_query.md
CHANGED
|
@@ -1,332 +1,87 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
const handleSubmit = (e: FormEvent) => {
|
|
92
|
-
e.preventDefault();
|
|
93
|
-
mutate({
|
|
94
|
-
title: 'Mi nuevo post',
|
|
95
|
-
content: 'Contenido del post'
|
|
96
|
-
});
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<form onSubmit={handleSubmit}>
|
|
101
|
-
<button type="submit" disabled={isLoading}>
|
|
102
|
-
{isLoading ? 'Creando...' : 'Crear Post'}
|
|
103
|
-
</button>
|
|
104
|
-
</form>
|
|
105
|
-
);
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### useInfiniteQuery - Paginación infinita
|
|
110
|
-
|
|
111
|
-
```tsx
|
|
112
|
-
function PostList() {
|
|
113
|
-
const http = useHttpState();
|
|
114
|
-
|
|
115
|
-
const { pages, isLoading, hasNextPage, fetchNextPage, isFetchingNextPage } =
|
|
116
|
-
http.useInfiniteQuery<Post[]>(
|
|
117
|
-
['posts', 'infinite'],
|
|
118
|
-
{
|
|
119
|
-
infiniteOptions: {
|
|
120
|
-
cursorKey: 'cursor' // Nombre del parámetro de paginación
|
|
121
|
-
},
|
|
122
|
-
cacheOptions: {
|
|
123
|
-
staleTime: 2 * 60 * 1000
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
<div>
|
|
130
|
-
{pages.map((page, i) => (
|
|
131
|
-
<div key={i}>
|
|
132
|
-
{page.map(post => (
|
|
133
|
-
<PostCard key={post.id} post={post} />
|
|
134
|
-
))}
|
|
135
|
-
</div>
|
|
136
|
-
))}
|
|
137
|
-
|
|
138
|
-
{hasNextPage && (
|
|
139
|
-
<button onClick={fetchNextPage} disabled={isFetchingNextPage}>
|
|
140
|
-
{isFetchingNextPage ? 'Cargando...' : 'Cargar más'}
|
|
141
|
-
</button>
|
|
142
|
-
)}
|
|
143
|
-
</div>
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Métodos Directos (sin caché)
|
|
149
|
-
|
|
150
|
-
### GET Request
|
|
151
|
-
|
|
152
|
-
```tsx
|
|
153
|
-
const http = useHttpState();
|
|
154
|
-
|
|
155
|
-
http.get(['users', userId], {
|
|
156
|
-
data: { include: 'posts' },
|
|
157
|
-
onSuccess: (user) => console.log(user),
|
|
158
|
-
onError: (message) => console.error(message)
|
|
159
|
-
});
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### POST Request
|
|
163
|
-
|
|
164
|
-
```tsx
|
|
165
|
-
http.post(['posts'], {
|
|
166
|
-
data: { title: 'Nuevo post', content: 'Contenido' },
|
|
167
|
-
onSuccess: (post) => console.log('Creado:', post)
|
|
168
|
-
});
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
### Upload de Archivos
|
|
172
|
-
|
|
173
|
-
```tsx
|
|
174
|
-
// FormData simple
|
|
175
|
-
http.file(['upload'], {
|
|
176
|
-
method: 'POST',
|
|
177
|
-
content_type: 'file',
|
|
178
|
-
data: {
|
|
179
|
-
title: 'Mi imagen',
|
|
180
|
-
description: 'Descripción',
|
|
181
|
-
photo: [fileObject], // Los archivos siempre van al final
|
|
182
|
-
tags: ['tag1', 'tag2']
|
|
183
|
-
},
|
|
184
|
-
onSuccess: (response) => console.log('Subido:', response)
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
// Upload por chunks (archivos grandes)
|
|
188
|
-
http.fileChunks(['upload', 'large'], {
|
|
189
|
-
data: { file: largeFile, metadata: { type: 'video' } },
|
|
190
|
-
chunkSize: 2 * 1024 * 1024, // 2MB por chunk
|
|
191
|
-
onProgress: (percent, display) => {
|
|
192
|
-
console.log(`Progreso: ${percent}% - ${display}`);
|
|
193
|
-
},
|
|
194
|
-
onSuccess: (response) => console.log('Completado:', response)
|
|
195
|
-
});
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## QueryManager API
|
|
199
|
-
|
|
200
|
-
Acceso directo al query manager:
|
|
201
|
-
|
|
202
|
-
```tsx
|
|
203
|
-
const http = useHttpState();
|
|
204
|
-
const { queryManager } = http;
|
|
205
|
-
|
|
206
|
-
// Obtener datos de caché
|
|
207
|
-
const userData = queryManager.getQueryData<User>(['users', userId]);
|
|
208
|
-
|
|
209
|
-
// Actualizar caché manualmente
|
|
210
|
-
queryManager.setQueryData(['users', userId], updatedUser);
|
|
211
|
-
|
|
212
|
-
// Invalidar queries (fuerza refetch)
|
|
213
|
-
queryManager.invalidateQueries(['users']);
|
|
214
|
-
|
|
215
|
-
// Prefetch (cargar en background)
|
|
216
|
-
queryManager.prefetchQuery(
|
|
217
|
-
['posts', 'featured'],
|
|
218
|
-
() => fetch('/api/posts/featured').then(r => r.json())
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
// Reset queries (limpiar caché)
|
|
222
|
-
queryManager.resetQueries(['users']); // Específica
|
|
223
|
-
queryManager.resetQueries(); // Todas
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
## Configuración de Headers
|
|
227
|
-
|
|
228
|
-
```tsx
|
|
229
|
-
const http = useHttpState();
|
|
230
|
-
const { setHeaders } = useHttpContext();
|
|
231
|
-
|
|
232
|
-
// Actualizar headers globalmente
|
|
233
|
-
setHeaders({ authorization: `Bearer ${token}` });
|
|
234
|
-
|
|
235
|
-
// O con función
|
|
236
|
-
setHeaders(prev => ({
|
|
237
|
-
...prev,
|
|
238
|
-
'X-Custom-Header': 'value'
|
|
239
|
-
}));
|
|
240
|
-
|
|
241
|
-
// Headers por request
|
|
242
|
-
http.get(['users'], {
|
|
243
|
-
headers: { 'X-Request-ID': uuid() }
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## buildBody Mejorado
|
|
248
|
-
|
|
249
|
-
La función `buildBody` ahora garantiza que los archivos siempre vayan al final del FormData:
|
|
250
|
-
|
|
251
|
-
```tsx
|
|
252
|
-
const data = {
|
|
253
|
-
title: 'Post con imagen',
|
|
254
|
-
tags: ['tag1', 'tag2'],
|
|
255
|
-
metadata: { author: 'John' },
|
|
256
|
-
photo: [imageFile], // Archivo - irá al final
|
|
257
|
-
z_attached: [pdfFile] // Archivo - irá al final
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
// FormData resultante:
|
|
261
|
-
// 1. title: "Post con imagen"
|
|
262
|
-
// 2. tags: ["tag1","tag2"]
|
|
263
|
-
// 3. metadata: {"author":"John"}
|
|
264
|
-
// 4. photo[]: File (imagen)
|
|
265
|
-
// 5. z_attached[]: File (pdf)
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Esto soluciona el problema donde algunos backends no recibían los datos regulares si los archivos iban primero.
|
|
269
|
-
|
|
270
|
-
## Mejoras vs React Query
|
|
271
|
-
|
|
272
|
-
1. **Menor tamaño**: Sin dependencias innecesarias
|
|
273
|
-
2. **Deduplicación mejorada**: Requests idénticas comparten la misma Promise
|
|
274
|
-
3. **Tipos más estrictos**: Sin `any`, todo tipado con `unknown` o genéricos
|
|
275
|
-
4. **FormData optimizado**: Archivos siempre al final
|
|
276
|
-
5. **API más simple**: Menos configuración, más convenciones
|
|
277
|
-
6. **Retry con backoff**: Espera exponencial entre reintentos (1s, 2s, 3s...)
|
|
278
|
-
7. **Refetch real**: `invalidateQueries` ejecuta el fetch, no solo marca como stale
|
|
279
|
-
|
|
280
|
-
## Tipos TypeScript
|
|
281
|
-
|
|
282
|
-
```tsx
|
|
283
|
-
interface UseHttpResult<T> {
|
|
284
|
-
data: T | null;
|
|
285
|
-
isLoading: boolean;
|
|
286
|
-
error: Error | null;
|
|
287
|
-
refetch?: () => void;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
interface UseInfiniteHttpResult<T> extends UseHttpResult<T> {
|
|
291
|
-
pages: T[];
|
|
292
|
-
fetchNextPage: () => void;
|
|
293
|
-
hasNextPage: boolean;
|
|
294
|
-
isFetchingNextPage: boolean;
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
interface UseMutationResult<T> {
|
|
298
|
-
mutate: (data: Record<string, unknown>) => void;
|
|
299
|
-
isLoading: boolean;
|
|
300
|
-
error: Error | null;
|
|
301
|
-
data: T | null;
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
## Notas de Rendimiento
|
|
306
|
-
|
|
307
|
-
- **Deduplicación**: Múltiples componentes solicitando la misma query comparten el request
|
|
308
|
-
- **Garbage Collection**: Queries sin suscriptores se eliminan después de `gcTime`
|
|
309
|
-
- **Stale Time**: Datos se consideran frescos durante `staleTime`, evitando refetches innecesarios
|
|
310
|
-
- **Window Focus**: Refetch automático al volver a la pestaña (configurable)
|
|
311
|
-
- **Subscripción eficiente**: Solo notifica a componentes suscritos a cada query específica
|
|
312
|
-
|
|
313
|
-
## Migración desde React Query
|
|
314
|
-
|
|
315
|
-
```tsx
|
|
316
|
-
// React Query
|
|
317
|
-
import { useQuery, useMutation } from '@tanstack/react-query';
|
|
318
|
-
|
|
319
|
-
const { data } = useQuery({
|
|
320
|
-
queryKey: ['users', id],
|
|
321
|
-
queryFn: () => fetchUser(id)
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
// Sistema Custom
|
|
325
|
-
const http = useHttpState();
|
|
326
|
-
|
|
327
|
-
const { data } = http.useQuery(['users', id], {
|
|
328
|
-
cacheOptions: { queryKey: ['users', id] }
|
|
329
|
-
});
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
La API es similar pero más simple y directa.
|
|
1
|
+
# @royaltics/ui - HTTP Store & Hooks
|
|
2
|
+
|
|
3
|
+
The new HTTP system replaces the previous `<HttpProvider>` component entirely. It leverages a clean `Zustand` vanilla store to allow initialization at the root module level, drastically increasing integration flexibility and making sure subsequent API requests made outside of React bindings (like React Router loaders) can safely reuse context.
|
|
4
|
+
|
|
5
|
+
## 1. Global Environment Initialization
|
|
6
|
+
To configure your global default `baseUrl`, `headers`, and refresh logic, simply call `initHttpOptions` once before you interact with the system or within your main application entry file (`main.tsx` or `App.tsx` outside of the component render).
|
|
7
|
+
|
|
8
|
+
```tsx
|
|
9
|
+
import { initHttpOptions } from '@royaltics/ui/hooks';
|
|
10
|
+
|
|
11
|
+
// Setup at the root of your project
|
|
12
|
+
initHttpOptions({
|
|
13
|
+
baseUrl: 'https://api.example.com',
|
|
14
|
+
debug: false,
|
|
15
|
+
headers: { 'X-App-Version': '1.0.0' },
|
|
16
|
+
onHttpError: (err) => console.error("Global Catch", err),
|
|
17
|
+
onNotAuth: (url) => window.location.href = '/login',
|
|
18
|
+
refreshConfig: {
|
|
19
|
+
url: '/auth/refresh',
|
|
20
|
+
maxAttempts: 1,
|
|
21
|
+
onSuccess: (res) => console.log('Refreshed token!')
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
```
|
|
25
|
+
*Note: Because this modifies the vanilla store, you no longer need to wrap your components in `<HttpProvider>`.*
|
|
26
|
+
|
|
27
|
+
## 2. Reading State Direct from Store
|
|
28
|
+
Should you need access to the underlying configurations anywhere in a React component, use `useHttpStore`.
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
import { useHttpStore } from '@royaltics/ui/hooks';
|
|
32
|
+
|
|
33
|
+
const AppConfigViewer = () => {
|
|
34
|
+
// Read strictly the properties you need
|
|
35
|
+
const { online, baseUrl } = useHttpStore();
|
|
36
|
+
|
|
37
|
+
return <div>{online ? 'Online' : 'Offline'}</div>
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 3. Data Fetching via useHttpState
|
|
42
|
+
The highly modular `useHttpState` hook powers your data fetching (GET, POST, PATCH, DELETE, FILE) while providing granular component-scoped state properties (`isLoading`, `error`, etc) and automated subscriptions mapping.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { useHttpState } from '@royaltics/ui/hooks';
|
|
46
|
+
|
|
47
|
+
const UsersList = () => {
|
|
48
|
+
const { get, post, isLoading, getInfinite, fetchNextPage } = useHttpState();
|
|
49
|
+
|
|
50
|
+
const fetchUsers = () => {
|
|
51
|
+
get('/users', {
|
|
52
|
+
// Query param formatting
|
|
53
|
+
query: { active: true },
|
|
54
|
+
onSuccess: (data, paginate) => {
|
|
55
|
+
console.log(data, paginate);
|
|
56
|
+
},
|
|
57
|
+
onError: (message) => {
|
|
58
|
+
console.error(message);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const submitUser = () => {
|
|
64
|
+
post('/users', {
|
|
65
|
+
data: { name: 'John Doe' },
|
|
66
|
+
onSuccess: (data) => console.log('Created!')
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div>
|
|
72
|
+
<button onClick={fetchUsers} disabled={isLoading}>Load Users</button>
|
|
73
|
+
<button onClick={submitUser} disabled={isLoading}>Create User</button>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Supported HTTP verbs in `useHttpState`:
|
|
80
|
+
- `get(api, opts)`
|
|
81
|
+
- `getInfinite(api, opts)`
|
|
82
|
+
- `post(api, opts)`
|
|
83
|
+
- `patch(api, opts)`
|
|
84
|
+
- `postPatch(api, id, opts)`
|
|
85
|
+
- `del(api, opts)`
|
|
86
|
+
- `file(api, opts)`
|
|
87
|
+
- `fileChunks(api, opts)`
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HttpStateOptionsProps, QueryKey } from "./http.types.js";
|
|
2
|
+
export declare const executeGet: <T = any>(core: any, api: string | string[], opts: HttpStateOptionsProps<T>) => Promise<T | undefined>;
|
|
3
|
+
export declare const executeGetInfinite: <T = any[]>(core: any, api: string | string[], opts: HttpStateOptionsProps<T>) => Promise<void>;
|
|
4
|
+
export declare const fetchNextPageAction: (core: any, queryKey: QueryKey) => Promise<void>;
|
|
5
|
+
export declare const executeMutation: <T = any>(core: any, api: string | string[], opts: HttpStateOptionsProps<T>, method: "POST" | "PATCH" | "DELETE") => Promise<T | undefined>;
|
|
6
|
+
export declare const refetchAction: (core: any, queryKey: QueryKey, api: string | string[], opts: HttpStateOptionsProps<any>) => Promise<void>;
|
|
7
|
+
export declare const fileAction: <T = any>(core: any, api: string | string[], opts: HttpStateOptionsProps<T>) => Promise<T | undefined>;
|
|
8
|
+
export declare const fileChunksAction: <T = any>(core: any, api: string | string[], opts: HttpStateOptionsProps<T>) => Promise<void>;
|
|
9
|
+
//# sourceMappingURL=http-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-actions.d.ts","sourceRoot":"","sources":["../../../src/core/http/http-actions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,QAAQ,EAAoB,MAAM,iBAAiB,CAAC;AAQpF,eAAO,MAAM,UAAU,GAAU,CAAC,GAAG,GAAG,EACvC,MAAM,GAAG,EACT,KAAK,MAAM,GAAG,MAAM,EAAE,EACtB,MAAM,qBAAqB,CAAC,CAAC,CAAC,2BAqD9B,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAU,CAAC,GAAG,GAAG,EAAE,EACjD,MAAM,GAAG,EACT,KAAK,MAAM,GAAG,MAAM,EAAE,EACtB,MAAM,qBAAqB,CAAC,CAAC,CAAC,kBA2C9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,MAAM,GAAG,EAAE,UAAU,QAAQ,kBA6BtE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,CAAC,GAAG,GAAG,EAC5C,MAAM,GAAG,EACT,KAAK,MAAM,GAAG,MAAM,EAAE,EACtB,MAAM,qBAAqB,CAAC,CAAC,CAAC,EAC9B,QAAQ,MAAM,GAAG,OAAO,GAAG,QAAQ,2BA0CnC,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,MAAM,GAAG,EAAE,UAAU,QAAQ,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,EAAE,MAAM,qBAAqB,CAAC,GAAG,CAAC,kBAoB1H,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,CAAC,GAAG,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,EAAE,MAAM,qBAAqB,CAAC,CAAC,CAAC,2BAgB1G,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,CAAC,GAAG,GAAG,EAAE,MAAM,GAAG,EAAE,KAAK,MAAM,GAAG,MAAM,EAAE,EAAE,MAAM,qBAAqB,CAAC,CAAC,CAAC,kBAUhH,CAAC"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { HttpFetch, uploadFileChunks, httpStore } from "./http-store.js";
|
|
2
|
+
const NOOP = (msg) => { console.error(msg); };
|
|
3
|
+
const generateQueryKey = (api, query, customKey) => {
|
|
4
|
+
return customKey || (query ? [api, query] : [api]);
|
|
5
|
+
};
|
|
6
|
+
export const executeGet = async (core, api, opts) => {
|
|
7
|
+
const { cacheOptions, onSuccess, onError, ...fetchOptions } = opts;
|
|
8
|
+
const online = httpStore.getState().online;
|
|
9
|
+
if (cacheOptions?.enabled) {
|
|
10
|
+
const queryKey = generateQueryKey(api, opts.query, cacheOptions.queryKey);
|
|
11
|
+
core.setupSubscription(queryKey, false, onSuccess, onError);
|
|
12
|
+
if (!online) {
|
|
13
|
+
onError?.("OMIT_OFFLINE", new Error("Offline"));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const cachedData = core.queryManager.getQueryData(queryKey);
|
|
17
|
+
if (cachedData !== null) {
|
|
18
|
+
onSuccess?.(cachedData.data, cachedData.paginate);
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const result = await core.queryManager.fetchQuery(queryKey, () => HttpFetch({ api, ...fetchOptions, method: 'GET' }), cacheOptions);
|
|
22
|
+
if (cachedData === null && result) {
|
|
23
|
+
onSuccess?.(result.data, result.paginate);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
const error = err;
|
|
28
|
+
const _onError = onError || NOOP;
|
|
29
|
+
_onError(error.message, error);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const operationKey = generateQueryKey(api, opts.query);
|
|
35
|
+
core.setOperationLoading('get', operationKey, true);
|
|
36
|
+
try {
|
|
37
|
+
const result = await HttpFetch({ api, ...fetchOptions, method: 'GET' });
|
|
38
|
+
onSuccess?.(result.data, result.paginate);
|
|
39
|
+
return result.data;
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const error = err;
|
|
43
|
+
const _onError = onError || NOOP;
|
|
44
|
+
_onError(error.message, error);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
core.setOperationLoading('get', operationKey, false);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
export const executeGetInfinite = async (core, api, opts) => {
|
|
52
|
+
const { cacheOptions, infiniteOptions, onSuccess, onError, ...fetchOptions } = opts;
|
|
53
|
+
const cursorKey = infiniteOptions?.cursorKey || 'next';
|
|
54
|
+
const queryKey = generateQueryKey(api, opts.query, cacheOptions?.queryKey);
|
|
55
|
+
const keyString = core.generateReadableKey(queryKey);
|
|
56
|
+
const online = httpStore.getState().online;
|
|
57
|
+
core.setupSubscription(queryKey, true, onSuccess, onError);
|
|
58
|
+
if (!online) {
|
|
59
|
+
onError?.("OMIT_OFFLINE", new Error("Offline"));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const cachedData = core.queryManager.getQueryData(queryKey);
|
|
63
|
+
if (cachedData !== null) {
|
|
64
|
+
const firstPage = cachedData.pages?.[0];
|
|
65
|
+
onSuccess?.(cachedData.data, firstPage?.paginate);
|
|
66
|
+
}
|
|
67
|
+
const queryFn = (pageParam) => HttpFetch({
|
|
68
|
+
api,
|
|
69
|
+
...fetchOptions,
|
|
70
|
+
method: 'GET',
|
|
71
|
+
query: { ...opts.query, [cursorKey]: pageParam }
|
|
72
|
+
});
|
|
73
|
+
core.queryFunctionsRef.current.set(keyString, { queryFn, cursorKey });
|
|
74
|
+
try {
|
|
75
|
+
const result = await core.queryManager.fetchInfiniteQuery(queryKey, queryFn, { ...cacheOptions, ...infiniteOptions });
|
|
76
|
+
if (cachedData === null && result) {
|
|
77
|
+
const firstPage = result.pageResponses?.[0];
|
|
78
|
+
onSuccess?.(result.data, firstPage?.paginate);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
const error = err;
|
|
83
|
+
const _onError = onError || NOOP;
|
|
84
|
+
_onError(error.message, error);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
export const fetchNextPageAction = async (core, queryKey) => {
|
|
89
|
+
const keyString = core.generateReadableKey(queryKey);
|
|
90
|
+
const state = core.queryStates[keyString];
|
|
91
|
+
const stored = core.queryFunctionsRef.current.get(keyString);
|
|
92
|
+
const debug = httpStore.getState().debug;
|
|
93
|
+
if (!stored) {
|
|
94
|
+
if (debug)
|
|
95
|
+
console.error('fetchNextPage: No queryFn found. Call getInfinite first.', keyString);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (!state || state.isFetchingNextPage || !state.hasNextPage)
|
|
99
|
+
return;
|
|
100
|
+
core.setQueryStates((prev) => ({
|
|
101
|
+
...prev,
|
|
102
|
+
[keyString]: { ...prev[keyString], isFetchingNextPage: true }
|
|
103
|
+
}));
|
|
104
|
+
try {
|
|
105
|
+
await core.queryManager.fetchNextPage(queryKey, stored.queryFn);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const error = err;
|
|
109
|
+
if (debug)
|
|
110
|
+
console.error('fetchNextPage error:', error.message);
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
core.setQueryStates((prev) => ({
|
|
114
|
+
...prev,
|
|
115
|
+
[keyString]: { ...prev[keyString], isFetchingNextPage: false }
|
|
116
|
+
}));
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
export const executeMutation = async (core, api, opts, method) => {
|
|
120
|
+
const { mutationOptions, onSuccess, onError, ...fetchOptions } = opts;
|
|
121
|
+
if (mutationOptions?.mutation) {
|
|
122
|
+
if (mutationOptions.optimisticData) {
|
|
123
|
+
mutationOptions.invalidateKeys?.forEach(key => {
|
|
124
|
+
core.queryManager.setQueryData(key, mutationOptions.optimisticData);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const result = await HttpFetch({ api, ...fetchOptions, method });
|
|
129
|
+
mutationOptions.invalidateKeys?.forEach(key => core.queryManager.invalidateQueries(key));
|
|
130
|
+
onSuccess?.(result.data, result.paginate);
|
|
131
|
+
return result.data;
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
const error = err;
|
|
135
|
+
if (mutationOptions.optimisticData) {
|
|
136
|
+
mutationOptions.invalidateKeys?.forEach(key => core.queryManager.invalidateQueries(key));
|
|
137
|
+
}
|
|
138
|
+
const _onError = onError || NOOP;
|
|
139
|
+
_onError(error.message, error);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const operationKey = generateQueryKey(api, opts.data);
|
|
144
|
+
core.setOperationLoading(method.toLowerCase(), operationKey, true);
|
|
145
|
+
try {
|
|
146
|
+
const result = await HttpFetch({ api, ...fetchOptions, method });
|
|
147
|
+
onSuccess?.(result.data, result.paginate);
|
|
148
|
+
return result.data;
|
|
149
|
+
}
|
|
150
|
+
catch (err) {
|
|
151
|
+
const error = err;
|
|
152
|
+
const _onError = onError || NOOP;
|
|
153
|
+
_onError(error.message, error);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
core.setOperationLoading(method.toLowerCase(), operationKey, false);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
export const refetchAction = async (core, queryKey, api, opts) => {
|
|
161
|
+
const keyString = core.generateReadableKey(queryKey);
|
|
162
|
+
if (!core.queryStates[keyString])
|
|
163
|
+
return;
|
|
164
|
+
core.setQueryStates((prev) => ({
|
|
165
|
+
...prev,
|
|
166
|
+
[keyString]: { ...prev[keyString], isLoading: true, error: null }
|
|
167
|
+
}));
|
|
168
|
+
try {
|
|
169
|
+
await core.queryManager.fetchQuery(queryKey, () => HttpFetch({ api, ...opts, method: 'GET' }), opts.cacheOptions);
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
const error = err;
|
|
173
|
+
const _onError = opts.onError || NOOP;
|
|
174
|
+
_onError(error.message, error);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
export const fileAction = async (core, api, opts) => {
|
|
179
|
+
const _onError = opts.onError || NOOP;
|
|
180
|
+
const operationKey = generateQueryKey(api, opts.data);
|
|
181
|
+
core.setOperationLoading('post', operationKey, true);
|
|
182
|
+
try {
|
|
183
|
+
const result = await HttpFetch({ ...opts, api, method: opts.method || 'POST', content_type: 'file' });
|
|
184
|
+
opts.onSuccess?.(result.data, result.paginate);
|
|
185
|
+
return result.data;
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
const error = err;
|
|
189
|
+
_onError(error.message, error);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
core.setOperationLoading('post', operationKey, false);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
export const fileChunksAction = async (core, api, opts) => {
|
|
197
|
+
const _onError = opts.onError || NOOP;
|
|
198
|
+
const operationKey = generateQueryKey(api, opts.data);
|
|
199
|
+
core.setOperationLoading('post', operationKey, true);
|
|
200
|
+
try {
|
|
201
|
+
await uploadFileChunks(api, opts.data || {}, opts.headers, opts.withAuth, opts.chunkSize, 'POST', opts.onSuccess, _onError, opts.onProgress);
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
core.setOperationLoading('post', operationKey, false);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
//# sourceMappingURL=http-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-actions.js","sourceRoot":"","sources":["../../../src/core/http/http-actions.ts"],"names":[],"mappings":"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"}
|