@classytic/arc-next 0.2.0 → 0.3.1
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 +25 -20
- package/dist/api.d.ts +1 -2
- package/dist/api.js +11 -4
- package/dist/client.d.ts +18 -2
- package/dist/client.js +11 -5
- package/dist/hooks.d.ts +15 -58
- package/dist/hooks.js +90 -85
- package/dist/mutation.d.ts +6 -3
- package/dist/mutation.js +6 -3
- package/dist/prefetch.d.ts +9 -3
- package/dist/prefetch.js +9 -5
- package/dist/query-client.d.ts +1 -2
- package/dist/query-client.js +2 -2
- package/dist/query.d.ts +18 -5
- package/dist/query.js +54 -19
- package/package.json +9 -3
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js.map +0 -1
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js.map +0 -1
- package/dist/hooks.d.ts.map +0 -1
- package/dist/hooks.js.map +0 -1
- package/dist/mutation.d.ts.map +0 -1
- package/dist/mutation.js.map +0 -1
- package/dist/prefetch.d.ts.map +0 -1
- package/dist/prefetch.js.map +0 -1
- package/dist/query-client.d.ts.map +0 -1
- package/dist/query-client.js.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js.map +0 -1
package/dist/hooks.js
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
import { getAuthContext, getAuthMode } from "./client.js";
|
|
4
4
|
import { isKeysetPagination, isOffsetPagination } from "./api.js";
|
|
5
|
-
import { DEFAULT_QUERY_CONFIG, createCacheUtils,
|
|
6
|
-
import {
|
|
5
|
+
import { DEFAULT_QUERY_CONFIG, createCacheUtils, createQueryKeys, extractItem, getItemId, updateListCache, useDetailQuery, useInfiniteListQuery, useListQuery } from "./query.js";
|
|
6
|
+
import { useMutationWithTransition, useOptimisticMutation } from "./mutation.js";
|
|
7
7
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
|
8
|
-
import { useCallback, useRef } from "react";
|
|
8
|
+
import { useCallback, useMemo, useRef } from "react";
|
|
9
9
|
|
|
10
10
|
//#region src/hooks.ts
|
|
11
11
|
let useRouterHook = null;
|
|
12
12
|
/**
|
|
13
13
|
* Configure the router hook for useNavigation. Call once at app init.
|
|
14
14
|
*
|
|
15
|
+
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
16
|
+
*
|
|
15
17
|
* @example
|
|
16
18
|
* import { useRouter } from "next/navigation";
|
|
17
19
|
* configureNavigation(useRouter);
|
|
@@ -19,8 +21,8 @@ let useRouterHook = null;
|
|
|
19
21
|
function configureNavigation(hook) {
|
|
20
22
|
useRouterHook = hook;
|
|
21
23
|
}
|
|
22
|
-
function createEnabledRule(token, options) {
|
|
23
|
-
if (
|
|
24
|
+
function createEnabledRule(token, options, authMode = getAuthMode()) {
|
|
25
|
+
if (authMode === "cookie" || options.public) return options.enabled ?? true;
|
|
24
26
|
return options.enabled !== void 0 ? options.enabled && !!token : !!token;
|
|
25
27
|
}
|
|
26
28
|
function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks = {}, client }) {
|
|
@@ -28,6 +30,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
28
30
|
const cache = createCacheUtils(KEYS);
|
|
29
31
|
const instanceToast = client?.toast;
|
|
30
32
|
const instanceNavigation = client?.navigation ?? null;
|
|
33
|
+
const resolveAuthMode = () => client?.config?.authMode ?? getAuthMode();
|
|
31
34
|
const config = {
|
|
32
35
|
...DEFAULT_QUERY_CONFIG,
|
|
33
36
|
...defaults,
|
|
@@ -63,7 +66,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
63
66
|
const { organizationId, ...restParams } = params;
|
|
64
67
|
const scope = options._scope || (organizationId ? "tenant" : "super-admin");
|
|
65
68
|
const { request: requestOpts, ...queryOpts } = options;
|
|
66
|
-
return
|
|
69
|
+
return useListQuery({
|
|
67
70
|
queryKey: KEYS.scopedList(scope, {
|
|
68
71
|
organizationId,
|
|
69
72
|
...restParams
|
|
@@ -77,7 +80,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
77
80
|
...requestOpts
|
|
78
81
|
}
|
|
79
82
|
}),
|
|
80
|
-
enabled: createEnabledRule(token, queryOpts),
|
|
83
|
+
enabled: createEnabledRule(token, queryOpts, resolveAuthMode()),
|
|
81
84
|
options: {
|
|
82
85
|
staleTime: queryOpts.staleTime ?? config.staleTime,
|
|
83
86
|
gcTime: queryOpts.gcTime ?? config.gcTime,
|
|
@@ -107,7 +110,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
107
110
|
};
|
|
108
111
|
}
|
|
109
112
|
const { organizationId, params: queryParams, request: requestOpts, ...restOptions } = options;
|
|
110
|
-
return
|
|
113
|
+
return useDetailQuery({
|
|
111
114
|
queryKey: queryParams ? [...KEYS.detail(id || ""), queryParams] : KEYS.detail(id || ""),
|
|
112
115
|
queryFn: ({ signal }) => api.getById({
|
|
113
116
|
id,
|
|
@@ -119,10 +122,11 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
119
122
|
...requestOpts
|
|
120
123
|
}
|
|
121
124
|
}),
|
|
122
|
-
enabled: !!id && createEnabledRule(token, restOptions),
|
|
125
|
+
enabled: !!id && createEnabledRule(token, restOptions, resolveAuthMode()),
|
|
123
126
|
options: {
|
|
124
127
|
staleTime: restOptions.staleTime ?? config.staleTime,
|
|
125
128
|
gcTime: restOptions.gcTime ?? config.gcTime,
|
|
129
|
+
refetchOnWindowFocus: restOptions.refetchOnWindowFocus ?? config.refetchOnWindowFocus,
|
|
126
130
|
structuralSharing: restOptions.structuralSharing ?? config.structuralSharing,
|
|
127
131
|
refetchInterval: restOptions.refetchInterval,
|
|
128
132
|
refetchIntervalInBackground: restOptions.refetchIntervalInBackground
|
|
@@ -134,7 +138,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
134
138
|
const queryClient = useQueryClient();
|
|
135
139
|
const silentRef = useRef(false);
|
|
136
140
|
const shouldToast = useCallback(() => !silentRef.current, []);
|
|
137
|
-
const createMutation =
|
|
141
|
+
const createMutation = useOptimisticMutation({
|
|
138
142
|
mutationFn: ({ token, organizationId, data }) => api.create({
|
|
139
143
|
token,
|
|
140
144
|
organizationId,
|
|
@@ -151,14 +155,14 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
151
155
|
};
|
|
152
156
|
return updateListCache(oldData, (arr) => [optimisticItem, ...arr || []]);
|
|
153
157
|
},
|
|
154
|
-
onSuccess: (
|
|
155
|
-
callbacks.onCreate?.onSuccess?.(
|
|
158
|
+
onSuccess: (raw, variables) => {
|
|
159
|
+
callbacks.onCreate?.onSuccess?.(extractItem(raw), { data: variables.data }, void 0);
|
|
156
160
|
},
|
|
157
161
|
onError: (error, variables) => {
|
|
158
162
|
callbacks.onCreate?.onError?.(error, { data: variables.data }, void 0);
|
|
159
163
|
},
|
|
160
|
-
onSettled: (
|
|
161
|
-
callbacks.onCreate?.onSettled?.(
|
|
164
|
+
onSettled: (raw, error, variables) => {
|
|
165
|
+
callbacks.onCreate?.onSettled?.(raw ? extractItem(raw) : void 0, error, { data: variables.data }, void 0);
|
|
162
166
|
},
|
|
163
167
|
messages: {
|
|
164
168
|
success: config.messages.createSuccess,
|
|
@@ -166,7 +170,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
166
170
|
},
|
|
167
171
|
toastHandler: instanceToast
|
|
168
172
|
});
|
|
169
|
-
const updateMutation =
|
|
173
|
+
const updateMutation = useOptimisticMutation({
|
|
170
174
|
mutationFn: ({ token, organizationId, id, data }) => api.update({
|
|
171
175
|
token,
|
|
172
176
|
organizationId,
|
|
@@ -174,7 +178,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
174
178
|
data
|
|
175
179
|
}),
|
|
176
180
|
queryClient,
|
|
177
|
-
queryKeys: [KEYS.lists()],
|
|
181
|
+
queryKeys: [KEYS.lists(), KEYS.details()],
|
|
178
182
|
shouldToast,
|
|
179
183
|
optimisticUpdate: (oldData, { id, data }) => {
|
|
180
184
|
const updated = updateListCache(oldData, (arr) => (arr || []).map((item) => getItemId(item) === id ? {
|
|
@@ -190,9 +194,9 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
190
194
|
} : current);
|
|
191
195
|
return updated;
|
|
192
196
|
},
|
|
193
|
-
onSuccess: (
|
|
197
|
+
onSuccess: (raw, { id, data: updateData }) => {
|
|
194
198
|
queryClient.invalidateQueries({ queryKey: KEYS.detail(id) });
|
|
195
|
-
callbacks.onUpdate?.onSuccess?.(
|
|
199
|
+
callbacks.onUpdate?.onSuccess?.(extractItem(raw), {
|
|
196
200
|
id,
|
|
197
201
|
data: updateData
|
|
198
202
|
}, void 0);
|
|
@@ -203,8 +207,8 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
203
207
|
data
|
|
204
208
|
}, void 0);
|
|
205
209
|
},
|
|
206
|
-
onSettled: (
|
|
207
|
-
callbacks.onUpdate?.onSettled?.(
|
|
210
|
+
onSettled: (raw, error, { id, data: updateData }) => {
|
|
211
|
+
callbacks.onUpdate?.onSettled?.(raw ? extractItem(raw) : void 0, error, {
|
|
208
212
|
id,
|
|
209
213
|
data: updateData
|
|
210
214
|
}, void 0);
|
|
@@ -215,7 +219,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
215
219
|
},
|
|
216
220
|
toastHandler: instanceToast
|
|
217
221
|
});
|
|
218
|
-
const deleteMutation =
|
|
222
|
+
const deleteMutation = useOptimisticMutation({
|
|
219
223
|
mutationFn: ({ token, organizationId, id }) => api.delete({
|
|
220
224
|
token,
|
|
221
225
|
organizationId,
|
|
@@ -225,10 +229,10 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
225
229
|
queryKeys: [KEYS.lists()],
|
|
226
230
|
shouldToast,
|
|
227
231
|
optimisticUpdate: (oldData, { id }) => {
|
|
228
|
-
queryClient.removeQueries({ queryKey: KEYS.detail(id) });
|
|
229
232
|
return updateListCache(oldData, (arr) => (arr || []).filter((item) => getItemId(item) !== id));
|
|
230
233
|
},
|
|
231
234
|
onSuccess: (data, { id }) => {
|
|
235
|
+
queryClient.removeQueries({ queryKey: KEYS.detail(id) });
|
|
232
236
|
callbacks.onDelete?.onSuccess?.(data, { id }, void 0);
|
|
233
237
|
},
|
|
234
238
|
onError: (error, { id }) => {
|
|
@@ -243,63 +247,60 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
243
247
|
},
|
|
244
248
|
toastHandler: instanceToast
|
|
245
249
|
});
|
|
246
|
-
const resolveAuth = (params) => {
|
|
250
|
+
const resolveAuth = useCallback((params) => {
|
|
247
251
|
const auth = getAuthContext();
|
|
248
252
|
return {
|
|
249
253
|
...params,
|
|
250
254
|
token: params.token ?? auth.token,
|
|
251
255
|
organizationId: params.organizationId ?? auth.organizationId
|
|
252
256
|
};
|
|
253
|
-
};
|
|
254
|
-
const create = async (params, options) => {
|
|
255
|
-
silentRef.current = options?.silent ?? false;
|
|
256
|
-
try {
|
|
257
|
-
const result = await createMutation.mutateAsync(resolveAuth(params));
|
|
258
|
-
options?.onSuccess?.(result);
|
|
259
|
-
options?.onSettled?.(result, null);
|
|
260
|
-
return result;
|
|
261
|
-
} catch (error) {
|
|
262
|
-
options?.onError?.(error);
|
|
263
|
-
options?.onSettled?.(void 0, error);
|
|
264
|
-
throw error;
|
|
265
|
-
} finally {
|
|
266
|
-
silentRef.current = false;
|
|
267
|
-
}
|
|
268
|
-
};
|
|
269
|
-
const update = async (params, options) => {
|
|
270
|
-
silentRef.current = options?.silent ?? false;
|
|
271
|
-
try {
|
|
272
|
-
const result = await updateMutation.mutateAsync(resolveAuth(params));
|
|
273
|
-
options?.onSuccess?.(result);
|
|
274
|
-
options?.onSettled?.(result, null);
|
|
275
|
-
return result;
|
|
276
|
-
} catch (error) {
|
|
277
|
-
options?.onError?.(error);
|
|
278
|
-
options?.onSettled?.(void 0, error);
|
|
279
|
-
throw error;
|
|
280
|
-
} finally {
|
|
281
|
-
silentRef.current = false;
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
const remove = async (params, options) => {
|
|
285
|
-
silentRef.current = options?.silent ?? false;
|
|
286
|
-
try {
|
|
287
|
-
const result = await deleteMutation.mutateAsync(resolveAuth(params));
|
|
288
|
-
options?.onSuccess?.(result);
|
|
289
|
-
options?.onSettled?.(result, null);
|
|
290
|
-
return result;
|
|
291
|
-
} catch (error) {
|
|
292
|
-
options?.onError?.(error);
|
|
293
|
-
options?.onSettled?.(void 0, error);
|
|
294
|
-
throw error;
|
|
295
|
-
} finally {
|
|
296
|
-
silentRef.current = false;
|
|
297
|
-
}
|
|
298
|
-
};
|
|
257
|
+
}, []);
|
|
299
258
|
return {
|
|
300
|
-
create,
|
|
301
|
-
|
|
302
|
-
|
|
259
|
+
create: useCallback(async (params, options) => {
|
|
260
|
+
silentRef.current = options?.silent ?? false;
|
|
261
|
+
try {
|
|
262
|
+
const entity = extractItem(await createMutation.mutateAsync(resolveAuth(params)));
|
|
263
|
+
options?.onSuccess?.(entity);
|
|
264
|
+
options?.onSettled?.(entity, null);
|
|
265
|
+
return entity;
|
|
266
|
+
} catch (error) {
|
|
267
|
+
options?.onError?.(error);
|
|
268
|
+
options?.onSettled?.(void 0, error);
|
|
269
|
+
throw error;
|
|
270
|
+
} finally {
|
|
271
|
+
silentRef.current = false;
|
|
272
|
+
}
|
|
273
|
+
}, [createMutation, resolveAuth]),
|
|
274
|
+
update: useCallback(async (params, options) => {
|
|
275
|
+
silentRef.current = options?.silent ?? false;
|
|
276
|
+
try {
|
|
277
|
+
const entity = extractItem(await updateMutation.mutateAsync(resolveAuth(params)));
|
|
278
|
+
options?.onSuccess?.(entity);
|
|
279
|
+
options?.onSettled?.(entity, null);
|
|
280
|
+
return entity;
|
|
281
|
+
} catch (error) {
|
|
282
|
+
options?.onError?.(error);
|
|
283
|
+
options?.onSettled?.(void 0, error);
|
|
284
|
+
throw error;
|
|
285
|
+
} finally {
|
|
286
|
+
silentRef.current = false;
|
|
287
|
+
}
|
|
288
|
+
}, [updateMutation, resolveAuth]),
|
|
289
|
+
remove: useCallback(async (params, options) => {
|
|
290
|
+
silentRef.current = options?.silent ?? false;
|
|
291
|
+
try {
|
|
292
|
+
const result = await deleteMutation.mutateAsync(resolveAuth(params));
|
|
293
|
+
options?.onSuccess?.(result);
|
|
294
|
+
options?.onSettled?.(result, null);
|
|
295
|
+
return result;
|
|
296
|
+
} catch (error) {
|
|
297
|
+
options?.onError?.(error);
|
|
298
|
+
options?.onSettled?.(void 0, error);
|
|
299
|
+
throw error;
|
|
300
|
+
} finally {
|
|
301
|
+
silentRef.current = false;
|
|
302
|
+
}
|
|
303
|
+
}, [deleteMutation, resolveAuth]),
|
|
303
304
|
isCreating: createMutation.isPending,
|
|
304
305
|
isUpdating: updateMutation.isPending,
|
|
305
306
|
isDeleting: deleteMutation.isPending,
|
|
@@ -327,7 +328,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
327
328
|
const { organizationId, ...restParams } = params;
|
|
328
329
|
const scope = options._scope || (organizationId ? "tenant" : "super-admin");
|
|
329
330
|
const { request: requestOpts, ...queryOpts } = options;
|
|
330
|
-
return
|
|
331
|
+
return useInfiniteListQuery({
|
|
331
332
|
queryKey: [...KEYS.scopedList(scope, {
|
|
332
333
|
organizationId,
|
|
333
334
|
...restParams
|
|
@@ -347,7 +348,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
347
348
|
}
|
|
348
349
|
});
|
|
349
350
|
},
|
|
350
|
-
enabled: createEnabledRule(token, queryOpts),
|
|
351
|
+
enabled: createEnabledRule(token, queryOpts, resolveAuthMode()),
|
|
351
352
|
initialPageParam: restParams.after ? restParams.after : 1,
|
|
352
353
|
getNextPageParam: (lastPage) => {
|
|
353
354
|
const page = lastPage;
|
|
@@ -360,17 +361,18 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
360
361
|
staleTime: queryOpts.staleTime ?? config.staleTime,
|
|
361
362
|
gcTime: queryOpts.gcTime ?? config.gcTime,
|
|
362
363
|
refetchOnWindowFocus: queryOpts.refetchOnWindowFocus ?? config.refetchOnWindowFocus,
|
|
363
|
-
structuralSharing: queryOpts.structuralSharing ?? config.structuralSharing
|
|
364
|
+
structuralSharing: queryOpts.structuralSharing ?? config.structuralSharing,
|
|
365
|
+
refetchInterval: queryOpts.refetchInterval,
|
|
366
|
+
refetchIntervalInBackground: queryOpts.refetchIntervalInBackground
|
|
364
367
|
}
|
|
365
368
|
});
|
|
366
369
|
}
|
|
367
370
|
function useUpload(options) {
|
|
368
|
-
if (!api.upload) throw new Error(`[arc-next] "${entityKey}" api does not define an upload method`);
|
|
369
|
-
const uploadApi = api.upload;
|
|
370
371
|
return useMutationWithTransition({
|
|
371
372
|
mutationFn: ({ data, id, path }) => {
|
|
373
|
+
if (!api.upload) return Promise.reject(/* @__PURE__ */ new Error(`[arc-next] "${entityKey}" api does not define an upload method`));
|
|
372
374
|
const auth = getAuthContext();
|
|
373
|
-
return
|
|
375
|
+
return api.upload({
|
|
374
376
|
token: auth.token,
|
|
375
377
|
organizationId: auth.organizationId,
|
|
376
378
|
data,
|
|
@@ -393,9 +395,9 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
393
395
|
if (!api.search) throw new Error(`[arc-next] "${entityKey}" api does not define a search method`);
|
|
394
396
|
const searchApi = api.search;
|
|
395
397
|
const auth = getAuthContext();
|
|
396
|
-
const token = auth.token;
|
|
398
|
+
const token = params?.token ?? auth.token;
|
|
397
399
|
const organizationId = params?.organizationId ?? auth.organizationId;
|
|
398
|
-
const { organizationId: _, ...restParams } = params ?? {};
|
|
400
|
+
const { organizationId: _, token: _t, ...restParams } = params ?? {};
|
|
399
401
|
const searchParams = {
|
|
400
402
|
q: query,
|
|
401
403
|
...restParams
|
|
@@ -405,7 +407,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
405
407
|
organizationId,
|
|
406
408
|
...searchParams
|
|
407
409
|
} : searchParams;
|
|
408
|
-
return
|
|
410
|
+
return useListQuery({
|
|
409
411
|
queryKey: [
|
|
410
412
|
...KEYS.lists(),
|
|
411
413
|
"search",
|
|
@@ -420,7 +422,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
420
422
|
...requestOpts
|
|
421
423
|
}
|
|
422
424
|
}),
|
|
423
|
-
enabled: query.length > 0 && createEnabledRule(token, queryOpts),
|
|
425
|
+
enabled: query.length > 0 && createEnabledRule(token, queryOpts, resolveAuthMode()),
|
|
424
426
|
options: {
|
|
425
427
|
staleTime: queryOpts.staleTime ?? config.staleTime,
|
|
426
428
|
gcTime: queryOpts.gcTime ?? config.gcTime
|
|
@@ -439,9 +441,13 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
439
441
|
toastHandler: instanceToast
|
|
440
442
|
});
|
|
441
443
|
}
|
|
444
|
+
const resolvedRouterHook = instanceNavigation ?? useRouterHook ?? (() => ({
|
|
445
|
+
push: () => {},
|
|
446
|
+
replace: () => {}
|
|
447
|
+
}));
|
|
442
448
|
function useNavigation() {
|
|
443
449
|
const queryClient = useQueryClient();
|
|
444
|
-
const router = (
|
|
450
|
+
const router = resolvedRouterHook();
|
|
445
451
|
return useCallback((href, item, options = {}) => {
|
|
446
452
|
const id = getItemId(item);
|
|
447
453
|
if (id) queryClient.setQueryData(KEYS.detail(id), { data: item });
|
|
@@ -466,5 +472,4 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
466
472
|
}
|
|
467
473
|
|
|
468
474
|
//#endregion
|
|
469
|
-
export { configureNavigation, createCrudHooks };
|
|
470
|
-
//# sourceMappingURL=hooks.js.map
|
|
475
|
+
export { configureNavigation, createCrudHooks };
|
package/dist/mutation.d.ts
CHANGED
|
@@ -26,6 +26,8 @@ interface TransitionMutationReturn<TData, TVariables> {
|
|
|
26
26
|
/**
|
|
27
27
|
* Configure toast handler. Call once at app init.
|
|
28
28
|
*
|
|
29
|
+
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
30
|
+
*
|
|
29
31
|
* @example
|
|
30
32
|
* import { toast } from "sonner";
|
|
31
33
|
* configureToast({ success: toast.success, error: toast.error });
|
|
@@ -98,7 +100,7 @@ interface CreateOptimisticMutationConfig<TData, TVariables> {
|
|
|
98
100
|
shouldToast?: () => boolean;
|
|
99
101
|
toastHandler?: ToastHandler;
|
|
100
102
|
}
|
|
101
|
-
declare function
|
|
103
|
+
declare function useOptimisticMutation<TData, TVariables>(config: CreateOptimisticMutationConfig<TData, TVariables>): _tanstack_react_query0.UseMutationResult<TData, Error, TVariables, {
|
|
102
104
|
previous: {
|
|
103
105
|
key: readonly unknown[];
|
|
104
106
|
data: [readonly unknown[], unknown][];
|
|
@@ -119,6 +121,7 @@ declare const QUERY_CONFIGS: {
|
|
|
119
121
|
readonly staleTime: 600000;
|
|
120
122
|
};
|
|
121
123
|
};
|
|
124
|
+
/** @deprecated Use `useOptimisticMutation` */
|
|
125
|
+
declare const createOptimisticMutation: typeof useOptimisticMutation;
|
|
122
126
|
//#endregion
|
|
123
|
-
export { CreateOptimisticMutationConfig, MutationCallbacks, MutationMessages, OptimisticMutationConfig, QUERY_CONFIGS,
|
|
124
|
-
//# sourceMappingURL=mutation.d.ts.map
|
|
127
|
+
export { CreateOptimisticMutationConfig, MutationCallbacks, MutationMessages, OptimisticMutationConfig, QUERY_CONFIGS, TransitionMutationConfig, TransitionMutationReturn, configureToast, createOptimisticMutation, useMutationWithOptimistic, useMutationWithTransition, useOptimisticMutation };
|
package/dist/mutation.js
CHANGED
|
@@ -12,6 +12,8 @@ let toastHandler = {
|
|
|
12
12
|
/**
|
|
13
13
|
* Configure toast handler. Call once at app init.
|
|
14
14
|
*
|
|
15
|
+
* **SSR safety:** This sets module-level state. Call only in client-side code.
|
|
16
|
+
*
|
|
15
17
|
* @example
|
|
16
18
|
* import { toast } from "sonner";
|
|
17
19
|
* configureToast({ success: toast.success, error: toast.error });
|
|
@@ -112,7 +114,7 @@ function useMutationWithOptimistic(config) {
|
|
|
112
114
|
reset: mutation.reset
|
|
113
115
|
};
|
|
114
116
|
}
|
|
115
|
-
function
|
|
117
|
+
function useOptimisticMutation(config) {
|
|
116
118
|
const { mutationFn, queryClient, queryKeys, optimisticUpdate, onSuccess, onError, onSettled, messages, toastHandler: instanceToast } = config;
|
|
117
119
|
return useMutation({
|
|
118
120
|
mutationFn,
|
|
@@ -158,7 +160,8 @@ const QUERY_CONFIGS = {
|
|
|
158
160
|
stable: { staleTime: 3e5 },
|
|
159
161
|
static: { staleTime: 6e5 }
|
|
160
162
|
};
|
|
163
|
+
/** @deprecated Use `useOptimisticMutation` */
|
|
164
|
+
const createOptimisticMutation = useOptimisticMutation;
|
|
161
165
|
|
|
162
166
|
//#endregion
|
|
163
|
-
export { QUERY_CONFIGS, configureToast, createOptimisticMutation, useMutationWithOptimistic, useMutationWithTransition };
|
|
164
|
-
//# sourceMappingURL=mutation.js.map
|
|
167
|
+
export { QUERY_CONFIGS, configureToast, createOptimisticMutation, useMutationWithOptimistic, useMutationWithTransition, useOptimisticMutation };
|
package/dist/prefetch.d.ts
CHANGED
|
@@ -4,6 +4,13 @@ import { QueryClient, dehydrate } from "@tanstack/react-query";
|
|
|
4
4
|
interface PrefetchOptions {
|
|
5
5
|
staleTime?: number;
|
|
6
6
|
}
|
|
7
|
+
interface PrefetchDetailOptions extends PrefetchOptions {
|
|
8
|
+
/** Query params (select, populate) — key must match useDetail's params to share cache */
|
|
9
|
+
params?: {
|
|
10
|
+
select?: string;
|
|
11
|
+
populate?: string | string[];
|
|
12
|
+
};
|
|
13
|
+
}
|
|
7
14
|
interface CrudPrefetcher {
|
|
8
15
|
/**
|
|
9
16
|
* Prefetch a list query on the server. Uses the same query keys as useList.
|
|
@@ -20,7 +27,7 @@ interface CrudPrefetcher {
|
|
|
20
27
|
* const queryClient = getQueryClient();
|
|
21
28
|
* await productsPrefetcher.prefetchDetail(queryClient, productId);
|
|
22
29
|
*/
|
|
23
|
-
prefetchDetail: (queryClient: QueryClient, id: string, options?:
|
|
30
|
+
prefetchDetail: (queryClient: QueryClient, id: string, options?: PrefetchDetailOptions) => Promise<void>;
|
|
24
31
|
}
|
|
25
32
|
/**
|
|
26
33
|
* Create server-safe prefetch helpers for CRUD queries.
|
|
@@ -60,5 +67,4 @@ declare function createCrudPrefetcher(api: {
|
|
|
60
67
|
}) => Promise<unknown>;
|
|
61
68
|
}, entityKey: string): CrudPrefetcher;
|
|
62
69
|
//#endregion
|
|
63
|
-
export { CrudPrefetcher, PrefetchOptions, createCrudPrefetcher, dehydrate };
|
|
64
|
-
//# sourceMappingURL=prefetch.d.ts.map
|
|
70
|
+
export { CrudPrefetcher, PrefetchDetailOptions, PrefetchOptions, createCrudPrefetcher, dehydrate };
|
package/dist/prefetch.js
CHANGED
|
@@ -61,16 +61,20 @@ function createCrudPrefetcher(api, entityKey) {
|
|
|
61
61
|
});
|
|
62
62
|
},
|
|
63
63
|
async prefetchDetail(queryClient, id, options = {}) {
|
|
64
|
-
const
|
|
64
|
+
const { params, staleTime } = options;
|
|
65
|
+
const baseKey = detailKey(entityKey, id);
|
|
66
|
+
const queryKey = params ? [...baseKey, params] : baseKey;
|
|
65
67
|
await queryClient.prefetchQuery({
|
|
66
68
|
queryKey,
|
|
67
|
-
queryFn: () => api.getById({
|
|
68
|
-
|
|
69
|
+
queryFn: () => api.getById({
|
|
70
|
+
id,
|
|
71
|
+
...params ? { params } : {}
|
|
72
|
+
}),
|
|
73
|
+
staleTime
|
|
69
74
|
});
|
|
70
75
|
}
|
|
71
76
|
};
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
//#endregion
|
|
75
|
-
export { createCrudPrefetcher, dehydrate };
|
|
76
|
-
//# sourceMappingURL=prefetch.js.map
|
|
80
|
+
export { createCrudPrefetcher, dehydrate };
|
package/dist/query-client.d.ts
CHANGED
|
@@ -21,5 +21,4 @@ interface QueryClientOverrides {
|
|
|
21
21
|
*/
|
|
22
22
|
declare function getQueryClient(overrides?: QueryClientOverrides): QueryClient;
|
|
23
23
|
//#endregion
|
|
24
|
-
export { QueryClientOverrides, getQueryClient };
|
|
25
|
-
//# sourceMappingURL=query-client.d.ts.map
|
|
24
|
+
export { QueryClientOverrides, getQueryClient };
|
package/dist/query-client.js
CHANGED
|
@@ -38,9 +38,9 @@ let browserQueryClient;
|
|
|
38
38
|
function getQueryClient(overrides) {
|
|
39
39
|
if (isServer) return makeQueryClient(overrides);
|
|
40
40
|
if (!browserQueryClient) browserQueryClient = makeQueryClient(overrides);
|
|
41
|
+
else if (overrides) console.warn("[arc-next] getQueryClient(): Browser singleton already exists — overrides are ignored. Pass overrides only on the first call.");
|
|
41
42
|
return browserQueryClient;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
//#endregion
|
|
45
|
-
export { getQueryClient };
|
|
46
|
-
//# sourceMappingURL=query-client.js.map
|
|
46
|
+
export { getQueryClient };
|
package/dist/query.d.ts
CHANGED
|
@@ -2,12 +2,16 @@ import { InfiniteData, QueryClient, QueryKey } from "@tanstack/react-query";
|
|
|
2
2
|
|
|
3
3
|
//#region src/query.d.ts
|
|
4
4
|
interface PaginationData {
|
|
5
|
+
/** Pagination method detected from response (offset | keyset | aggregate) */
|
|
6
|
+
method: 'offset' | 'keyset' | 'aggregate' | null;
|
|
5
7
|
total: number;
|
|
6
8
|
pages: number;
|
|
7
9
|
page: number;
|
|
8
10
|
limit: number;
|
|
9
11
|
hasNext: boolean;
|
|
10
12
|
hasPrev: boolean;
|
|
13
|
+
/** Keyset cursor for next page (keyset pagination only) */
|
|
14
|
+
next?: string | null;
|
|
11
15
|
}
|
|
12
16
|
/** Request-level options passed through to the fetch call */
|
|
13
17
|
interface RequestPassthrough {
|
|
@@ -39,6 +43,7 @@ interface DetailQueryOptions<TData = unknown> {
|
|
|
39
43
|
enabled?: boolean;
|
|
40
44
|
staleTime?: number;
|
|
41
45
|
gcTime?: number;
|
|
46
|
+
refetchOnWindowFocus?: boolean;
|
|
42
47
|
structuralSharing?: boolean;
|
|
43
48
|
refetchInterval?: number | false;
|
|
44
49
|
refetchIntervalInBackground?: boolean;
|
|
@@ -99,6 +104,7 @@ declare const DEFAULT_QUERY_CONFIG: {
|
|
|
99
104
|
readonly retry: 0;
|
|
100
105
|
};
|
|
101
106
|
declare function getItemId(item: unknown): string | null;
|
|
107
|
+
declare function extractItem<T>(data: unknown): T | null;
|
|
102
108
|
declare function updateListCache<T>(listData: unknown, updater: (items: T[]) => T[]): unknown;
|
|
103
109
|
declare function createQueryKeys(entityKey: string): QueryKeys;
|
|
104
110
|
declare function createCacheUtils<T>(KEYS: QueryKeys): CacheUtils<T>;
|
|
@@ -113,7 +119,7 @@ interface CreateListQueryConfig {
|
|
|
113
119
|
detailKeyBuilder?: (id: string) => QueryKey;
|
|
114
120
|
select?: (data: unknown) => unknown;
|
|
115
121
|
}
|
|
116
|
-
declare function
|
|
122
|
+
declare function useListQuery<T>({
|
|
117
123
|
queryKey,
|
|
118
124
|
queryFn,
|
|
119
125
|
enabled,
|
|
@@ -131,7 +137,7 @@ interface CreateDetailQueryConfig {
|
|
|
131
137
|
options?: Record<string, unknown>;
|
|
132
138
|
select?: (data: unknown) => unknown;
|
|
133
139
|
}
|
|
134
|
-
declare function
|
|
140
|
+
declare function useDetailQuery<T>({
|
|
135
141
|
queryKey,
|
|
136
142
|
queryFn,
|
|
137
143
|
enabled,
|
|
@@ -145,6 +151,8 @@ interface InfiniteListQueryOptions {
|
|
|
145
151
|
gcTime?: number;
|
|
146
152
|
refetchOnWindowFocus?: boolean;
|
|
147
153
|
structuralSharing?: boolean;
|
|
154
|
+
refetchInterval?: number | false;
|
|
155
|
+
refetchIntervalInBackground?: boolean;
|
|
148
156
|
_scope?: string;
|
|
149
157
|
request?: RequestPassthrough;
|
|
150
158
|
}
|
|
@@ -176,7 +184,7 @@ interface CreateInfiniteListQueryConfig {
|
|
|
176
184
|
getNextPageParam: (lastPage: unknown) => unknown;
|
|
177
185
|
getPreviousPageParam?: (firstPage: unknown) => unknown;
|
|
178
186
|
}
|
|
179
|
-
declare function
|
|
187
|
+
declare function useInfiniteListQuery<T>({
|
|
180
188
|
queryKey,
|
|
181
189
|
queryFn,
|
|
182
190
|
enabled,
|
|
@@ -185,6 +193,11 @@ declare function createInfiniteListQuery<T>({
|
|
|
185
193
|
getNextPageParam,
|
|
186
194
|
getPreviousPageParam
|
|
187
195
|
}: CreateInfiniteListQueryConfig): InfiniteListQueryResult<T>;
|
|
196
|
+
/** @deprecated Use `useListQuery` */
|
|
197
|
+
declare const createListQuery: typeof useListQuery;
|
|
198
|
+
/** @deprecated Use `useDetailQuery` */
|
|
199
|
+
declare const createDetailQuery: typeof useDetailQuery;
|
|
200
|
+
/** @deprecated Use `useInfiniteListQuery` */
|
|
201
|
+
declare const createInfiniteListQuery: typeof useInfiniteListQuery;
|
|
188
202
|
//#endregion
|
|
189
|
-
export { CacheUtils, CreateDetailQueryConfig, CreateInfiniteListQueryConfig, CreateListQueryConfig, DEFAULT_QUERY_CONFIG, DetailQueryOptions, DetailQueryResult, InfiniteListQueryOptions, InfiniteListQueryResult, ListQueryOptions, ListQueryResult, PaginationData, QueryKeys, RequestPassthrough, createCacheUtils, createDetailQuery, createInfiniteListQuery, createListQuery, createQueryKeys, getItemId, updateListCache };
|
|
190
|
-
//# sourceMappingURL=query.d.ts.map
|
|
203
|
+
export { CacheUtils, CreateDetailQueryConfig, CreateInfiniteListQueryConfig, CreateListQueryConfig, DEFAULT_QUERY_CONFIG, DetailQueryOptions, DetailQueryResult, InfiniteListQueryOptions, InfiniteListQueryResult, ListQueryOptions, ListQueryResult, PaginationData, QueryKeys, RequestPassthrough, createCacheUtils, createDetailQuery, createInfiniteListQuery, createListQuery, createQueryKeys, extractItem, getItemId, updateListCache, useDetailQuery, useInfiniteListQuery, useListQuery };
|