@umituz/react-native-tanstack 1.2.9 → 1.2.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-tanstack",
3
- "version": "1.2.9",
3
+ "version": "1.2.11",
4
4
  "description": "TanStack Query configuration and utilities for React Native apps - Pre-configured QueryClient with AsyncStorage persistence",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -3,37 +3,33 @@
3
3
  * Presentation layer - Optimistic update helper
4
4
  */
5
5
 
6
- import { useMutation, useQueryClient, type UseMutationOptions } from '@tanstack/react-query';
7
-
8
- /**
9
- * Context type for optimistic updates
10
- */
11
- interface OptimisticContext<TData> {
12
- previousData: TData | undefined;
13
- }
6
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
14
7
 
15
8
  /**
16
9
  * Optimistic update configuration
17
10
  */
18
- export interface OptimisticUpdateConfig<TData, TVariables> {
11
+ export interface OptimisticUpdateConfig<TData, TVariables, TError = Error> {
19
12
  queryKey: readonly unknown[];
20
13
  updater: (oldData: TData | undefined, variables: TVariables) => TData;
21
14
  invalidateOnSuccess?: boolean;
15
+ mutationFn: (variables: TVariables) => Promise<TData>;
16
+ onError?: (error: TError, variables: TVariables, context: unknown) => void;
17
+ onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: unknown) => void;
18
+ onSuccess?: (data: TData, variables: TVariables, context: unknown) => void;
22
19
  }
23
20
 
24
21
  /**
25
22
  * Hook for mutations with optimistic updates and automatic rollback
26
23
  */
27
24
  export function useOptimisticUpdate<TData = unknown, TVariables = unknown, TError = Error>(
28
- config: OptimisticUpdateConfig<TData, TVariables> &
29
- Omit<UseMutationOptions<TData, TError, TVariables, OptimisticContext<TData>>, 'onMutate'>,
25
+ config: OptimisticUpdateConfig<TData, TVariables, TError>,
30
26
  ) {
31
27
  const queryClient = useQueryClient();
32
- const { queryKey, updater, invalidateOnSuccess = true, onError, onSettled, ...mutationOptions } = config;
28
+ const { queryKey, updater, invalidateOnSuccess = true, onError, onSettled, onSuccess, mutationFn } = config;
33
29
 
34
- return useMutation<TData, TError, TVariables, OptimisticContext<TData>>({
35
- ...mutationOptions,
36
- onMutate: async (variables) => {
30
+ return useMutation({
31
+ mutationFn,
32
+ onMutate: async (variables: TVariables) => {
37
33
  await queryClient.cancelQueries({ queryKey });
38
34
  const previousData = queryClient.getQueryData<TData>(queryKey);
39
35
 
@@ -49,9 +45,11 @@ export function useOptimisticUpdate<TData = unknown, TVariables = unknown, TErro
49
45
 
50
46
  return { previousData };
51
47
  },
52
- onError: (error, variables, context) => {
53
- if (context?.previousData !== undefined) {
54
- queryClient.setQueryData(queryKey, context.previousData);
48
+ onError: (error: TError, variables: TVariables, context: unknown) => {
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ const ctx = context as any;
51
+ if (ctx?.previousData !== undefined) {
52
+ queryClient.setQueryData(queryKey, ctx.previousData);
55
53
 
56
54
  if (__DEV__) {
57
55
  // eslint-disable-next-line no-console
@@ -63,7 +61,12 @@ export function useOptimisticUpdate<TData = unknown, TVariables = unknown, TErro
63
61
  onError(error, variables, context);
64
62
  }
65
63
  },
66
- onSettled: (data, error, variables, context) => {
64
+ onSuccess: (data: TData, variables: TVariables, context: unknown) => {
65
+ if (onSuccess) {
66
+ onSuccess(data, variables, context);
67
+ }
68
+ },
69
+ onSettled: (data: TData | undefined, error: TError | null, variables: TVariables, context: unknown) => {
67
70
  if (invalidateOnSuccess && !error) {
68
71
  queryClient.invalidateQueries({ queryKey });
69
72
  }
@@ -79,8 +82,7 @@ export function useOptimisticUpdate<TData = unknown, TVariables = unknown, TErro
79
82
  * Hook for list mutations with optimistic updates
80
83
  */
81
84
  export function useOptimisticListUpdate<TData extends unknown[], TVariables = unknown>(
82
- config: OptimisticUpdateConfig<TData, TVariables> &
83
- Omit<UseMutationOptions<TData, Error, TVariables, OptimisticContext<TData>>, 'onMutate'>,
85
+ config: OptimisticUpdateConfig<TData, TVariables, Error>,
84
86
  ) {
85
- return useOptimisticUpdate<TData, TVariables>(config);
87
+ return useOptimisticUpdate<TData, TVariables, Error>(config);
86
88
  }
@@ -3,10 +3,7 @@
3
3
  * Presentation layer - Pagination helper
4
4
  */
5
5
 
6
- import {
7
- useInfiniteQuery,
8
- type UseInfiniteQueryOptions,
9
- } from '@tanstack/react-query';
6
+ import { useInfiniteQuery } from '@tanstack/react-query';
10
7
  import { useMemo } from 'react';
11
8
 
12
9
  /**
@@ -44,31 +41,31 @@ export interface OffsetPaginatedResponse<TData> {
44
41
  limit: number;
45
42
  }
46
43
 
44
+ /**
45
+ * Cursor pagination options
46
+ */
47
+ export interface CursorPaginationOptions<TData> {
48
+ queryKey: readonly unknown[];
49
+ queryFn: (context: { pageParam?: string }) => Promise<CursorPaginatedResponse<TData>>;
50
+ limit?: number;
51
+ enabled?: boolean;
52
+ staleTime?: number;
53
+ gcTime?: number;
54
+ }
55
+
47
56
  /**
48
57
  * Hook for cursor-based infinite scroll
49
58
  */
50
- export function useCursorPagination<TData>(
51
- options: Omit<
52
- UseInfiniteQueryOptions<
53
- CursorPaginatedResponse<TData>,
54
- Error,
55
- CursorPaginatedResponse<TData>,
56
- CursorPaginatedResponse<TData>,
57
- readonly unknown[],
58
- string | undefined
59
- >,
60
- 'getNextPageParam' | 'initialPageParam'
61
- > & {
62
- limit?: number;
63
- },
64
- ) {
65
- const { limit: _limit = 20, ...queryOptions } = options;
59
+ export function useCursorPagination<TData>(options: CursorPaginationOptions<TData>) {
60
+ const { queryKey, queryFn, limit: _limit = 20, ...restOptions } = options;
66
61
 
67
62
  const result = useInfiniteQuery({
68
- ...queryOptions,
69
- initialPageParam: undefined,
63
+ queryKey,
64
+ queryFn: ({ pageParam }) => queryFn({ pageParam }),
65
+ initialPageParam: undefined as string | undefined,
70
66
  getNextPageParam: (lastPage: CursorPaginatedResponse<TData>) =>
71
67
  lastPage.hasMore ? lastPage.nextCursor : undefined,
68
+ ...restOptions,
72
69
  });
73
70
 
74
71
  const flatData = useMemo(() => {
@@ -83,33 +80,33 @@ export function useCursorPagination<TData>(
83
80
  };
84
81
  }
85
82
 
83
+ /**
84
+ * Offset pagination options
85
+ */
86
+ export interface OffsetPaginationOptions<TData> {
87
+ queryKey: readonly unknown[];
88
+ queryFn: (context: { pageParam: OffsetPageParam }) => Promise<OffsetPaginatedResponse<TData>>;
89
+ limit?: number;
90
+ enabled?: boolean;
91
+ staleTime?: number;
92
+ gcTime?: number;
93
+ }
94
+
86
95
  /**
87
96
  * Hook for offset-based pagination
88
97
  */
89
- export function useOffsetPagination<TData>(
90
- options: Omit<
91
- UseInfiniteQueryOptions<
92
- OffsetPaginatedResponse<TData>,
93
- Error,
94
- OffsetPaginatedResponse<TData>,
95
- OffsetPaginatedResponse<TData>,
96
- readonly unknown[],
97
- OffsetPageParam
98
- >,
99
- 'getNextPageParam' | 'initialPageParam'
100
- > & {
101
- limit?: number;
102
- },
103
- ) {
104
- const { limit = 20, ...queryOptions } = options;
98
+ export function useOffsetPagination<TData>(options: OffsetPaginationOptions<TData>) {
99
+ const { queryKey, queryFn, limit = 20, ...restOptions } = options;
105
100
 
106
101
  const result = useInfiniteQuery({
107
- ...queryOptions,
102
+ queryKey,
103
+ queryFn: ({ pageParam }) => queryFn({ pageParam }),
108
104
  initialPageParam: { offset: 0, limit },
109
105
  getNextPageParam: (lastPage: OffsetPaginatedResponse<TData>) => {
110
106
  const nextOffset = lastPage.offset + lastPage.limit;
111
107
  return nextOffset < lastPage.total ? { offset: nextOffset, limit } : undefined;
112
108
  },
109
+ ...restOptions,
113
110
  });
114
111
 
115
112
  const flatData = useMemo(() => {