query-optimistic 0.1.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.md +371 -0
- package/dist/core/index.d.mts +211 -0
- package/dist/core/index.d.ts +211 -0
- package/dist/core/index.js +245 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +237 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +513 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +503 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +213 -0
- package/dist/react/index.d.ts +213 -0
- package/dist/react/index.js +378 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +375 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/types-BRxQA1mR.d.mts +63 -0
- package/dist/types-BRxQA1mR.d.ts +63 -0
- package/package.json +76 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { C as CollectionDef, Q as QueryOptions, a as Optimistic, E as EntityDef, M as MutationDef } from '../types-BRxQA1mR.mjs';
|
|
2
|
+
|
|
3
|
+
/** Options for useQuery hook */
|
|
4
|
+
interface UseQueryHookOptions<TParams> extends QueryOptions {
|
|
5
|
+
/** Parameters to pass to the fetch function */
|
|
6
|
+
params?: TParams;
|
|
7
|
+
/** Enable pagination mode (infinite query) */
|
|
8
|
+
paginated?: boolean;
|
|
9
|
+
/** For paginated: get params for each page */
|
|
10
|
+
getPageParams?: (context: {
|
|
11
|
+
pageParam: number;
|
|
12
|
+
}) => TParams;
|
|
13
|
+
/** Custom query key (defaults to [def.name, params]) */
|
|
14
|
+
queryKey?: readonly unknown[];
|
|
15
|
+
}
|
|
16
|
+
/** Query state object (second element of tuple) */
|
|
17
|
+
interface QueryState {
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
isFetching: boolean;
|
|
20
|
+
isError: boolean;
|
|
21
|
+
error: Error | null;
|
|
22
|
+
refetch: () => void;
|
|
23
|
+
}
|
|
24
|
+
/** Pagination state object (third element of paginated tuple) */
|
|
25
|
+
interface PaginationState {
|
|
26
|
+
hasNextPage: boolean;
|
|
27
|
+
fetchNextPage: () => void;
|
|
28
|
+
isFetchingNextPage: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Return type for collection queries: [data, queryState] */
|
|
31
|
+
type QueryResult<T> = [
|
|
32
|
+
Optimistic<T>[] | undefined,
|
|
33
|
+
QueryState
|
|
34
|
+
];
|
|
35
|
+
/** Return type for paginated queries: [data, queryState, paginationState] */
|
|
36
|
+
type PaginatedQueryResult<T> = [
|
|
37
|
+
Optimistic<T>[] | undefined,
|
|
38
|
+
QueryState,
|
|
39
|
+
PaginationState
|
|
40
|
+
];
|
|
41
|
+
/** Return type for entity queries: [data, queryState] */
|
|
42
|
+
type EntityResult<T> = [
|
|
43
|
+
Optimistic<T> | undefined,
|
|
44
|
+
QueryState
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Unified query hook for fetching data
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Simple collection query
|
|
51
|
+
* const [data, query] = useQuery(postsQuery, { params: { limit: 10 } })
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Paginated query
|
|
55
|
+
* const [data, query, pagination] = useQuery(postsQuery, {
|
|
56
|
+
* paginated: true,
|
|
57
|
+
* getPageParams: ({ pageParam }) => ({ page: pageParam, limit: 10 })
|
|
58
|
+
* })
|
|
59
|
+
* // pagination.fetchNextPage(), pagination.hasNextPage
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Entity query
|
|
63
|
+
* const [user, query] = useQuery(userEntity, { params: userId })
|
|
64
|
+
*/
|
|
65
|
+
declare function useQuery<TData, TParams>(def: CollectionDef<TData, TParams>, options?: UseQueryHookOptions<TParams> & {
|
|
66
|
+
paginated: true;
|
|
67
|
+
}): PaginatedQueryResult<TData>;
|
|
68
|
+
declare function useQuery<TData, TParams>(def: CollectionDef<TData, TParams>, options?: UseQueryHookOptions<TParams>): QueryResult<TData>;
|
|
69
|
+
declare function useQuery<TData, TParams>(def: EntityDef<TData, TParams>, options?: UseQueryHookOptions<TParams>): EntityResult<TData>;
|
|
70
|
+
|
|
71
|
+
/** Extract entity type from a collection or entity definition */
|
|
72
|
+
type InferEntity<T> = T extends CollectionDef<infer TData, any> ? TData & {} : T extends EntityDef<infer TData, any> ? TData & {} : never;
|
|
73
|
+
/** Base optimistic config with shared properties */
|
|
74
|
+
interface OptimisticConfigBase<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> {
|
|
75
|
+
/** Target collection/entity to update */
|
|
76
|
+
target: TTarget;
|
|
77
|
+
/** Whether to sync with server response (replace optimistic with real data) */
|
|
78
|
+
sync?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** Config for prepend/append actions - requires full entity */
|
|
81
|
+
interface OptimisticPrependAppendConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
82
|
+
action: 'prepend' | 'append';
|
|
83
|
+
/** Data to prepend/append - must be a full entity */
|
|
84
|
+
data: (params: TParams) => NoInfer<InferEntity<TTarget>>;
|
|
85
|
+
}
|
|
86
|
+
/** Config for replace action */
|
|
87
|
+
interface OptimisticReplaceConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
88
|
+
action: 'replace';
|
|
89
|
+
/** Data for replacement */
|
|
90
|
+
data: (params: TParams) => NoInfer<InferEntity<TTarget>>;
|
|
91
|
+
/** ID of item to replace */
|
|
92
|
+
id?: string | ((params: TParams) => string);
|
|
93
|
+
/** Filter function to find items to replace */
|
|
94
|
+
where?: (item: NoInfer<InferEntity<TTarget>>) => boolean;
|
|
95
|
+
}
|
|
96
|
+
/** Config for update action */
|
|
97
|
+
interface OptimisticUpdateConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
98
|
+
action: 'update';
|
|
99
|
+
/** Partial data for update */
|
|
100
|
+
data?: (params: TParams) => Partial<NoInfer<InferEntity<TTarget>>>;
|
|
101
|
+
/** ID of item to update */
|
|
102
|
+
id?: string | ((params: TParams) => string);
|
|
103
|
+
/** Filter function to find items to update */
|
|
104
|
+
where?: (item: NoInfer<InferEntity<TTarget>>) => boolean;
|
|
105
|
+
/** Update function */
|
|
106
|
+
update?: (item: NoInfer<InferEntity<TTarget>>, params: TParams) => NoInfer<InferEntity<TTarget>>;
|
|
107
|
+
}
|
|
108
|
+
/** Config for delete action */
|
|
109
|
+
interface OptimisticDeleteConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
110
|
+
action: 'delete';
|
|
111
|
+
/** ID of item to delete */
|
|
112
|
+
id?: string | ((params: TParams) => string);
|
|
113
|
+
/** Filter function to find items to delete */
|
|
114
|
+
where?: (item: NoInfer<InferEntity<TTarget>>) => boolean;
|
|
115
|
+
}
|
|
116
|
+
/** Optimistic update configuration - type inferred from target */
|
|
117
|
+
type OptimisticConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> = OptimisticPrependAppendConfig<TTarget, TParams> | OptimisticReplaceConfig<TTarget, TParams> | OptimisticUpdateConfig<TTarget, TParams> | OptimisticDeleteConfig<TTarget, TParams>;
|
|
118
|
+
/** Internal transaction type for batched mutations */
|
|
119
|
+
interface MutationTransaction {
|
|
120
|
+
target: CollectionDef<any, any> | EntityDef<any, any>;
|
|
121
|
+
action: 'prepend' | 'append' | 'update' | 'delete' | 'replace';
|
|
122
|
+
data?: any;
|
|
123
|
+
id?: string;
|
|
124
|
+
where?: (item: any) => boolean;
|
|
125
|
+
update?: (item: any) => any;
|
|
126
|
+
sync?: boolean;
|
|
127
|
+
}
|
|
128
|
+
/** Internal collection channel for batched mutations */
|
|
129
|
+
declare class BatchedCollectionChannel<TEntity> {
|
|
130
|
+
private readonly target;
|
|
131
|
+
private readonly transactions;
|
|
132
|
+
constructor(target: CollectionDef<TEntity, any>, transactions: MutationTransaction[]);
|
|
133
|
+
prepend(data: TEntity, options?: {
|
|
134
|
+
sync?: boolean;
|
|
135
|
+
}): this;
|
|
136
|
+
append(data: TEntity, options?: {
|
|
137
|
+
sync?: boolean;
|
|
138
|
+
}): this;
|
|
139
|
+
update(id: string, updateFn: (item: TEntity) => TEntity, options?: {
|
|
140
|
+
sync?: boolean;
|
|
141
|
+
}): this;
|
|
142
|
+
delete(id: string): this;
|
|
143
|
+
}
|
|
144
|
+
/** Internal entity channel for batched mutations */
|
|
145
|
+
declare class BatchedEntityChannel<TEntity> {
|
|
146
|
+
private readonly target;
|
|
147
|
+
private readonly transactions;
|
|
148
|
+
constructor(target: EntityDef<TEntity, any>, transactions: MutationTransaction[]);
|
|
149
|
+
update(updateFn: (item: TEntity) => TEntity, options?: {
|
|
150
|
+
sync?: boolean;
|
|
151
|
+
}): this;
|
|
152
|
+
replace(data: TEntity, options?: {
|
|
153
|
+
sync?: boolean;
|
|
154
|
+
}): this;
|
|
155
|
+
}
|
|
156
|
+
/** Internal batched channel type */
|
|
157
|
+
interface BatchedChannel {
|
|
158
|
+
<TEntity>(target: CollectionDef<TEntity, any>): BatchedCollectionChannel<TEntity>;
|
|
159
|
+
<TEntity>(target: EntityDef<TEntity, any>): BatchedEntityChannel<TEntity>;
|
|
160
|
+
}
|
|
161
|
+
/** Options for useMutation hook */
|
|
162
|
+
interface UseMutationOptions<TParams, TResponse> {
|
|
163
|
+
/** Called when mutation starts */
|
|
164
|
+
onMutate?: (params: TParams) => void;
|
|
165
|
+
/** Called on success */
|
|
166
|
+
onSuccess?: (data: TResponse, params: TParams) => void;
|
|
167
|
+
/** Called on error */
|
|
168
|
+
onError?: (error: Error, params: TParams) => void;
|
|
169
|
+
}
|
|
170
|
+
/** Return type for useMutation */
|
|
171
|
+
interface MutationResult<TParams, TResponse> {
|
|
172
|
+
mutate: (params: TParams) => void;
|
|
173
|
+
mutateAsync: (params: TParams) => Promise<TResponse>;
|
|
174
|
+
isLoading: boolean;
|
|
175
|
+
isPending: boolean;
|
|
176
|
+
isError: boolean;
|
|
177
|
+
isSuccess: boolean;
|
|
178
|
+
error: Error | null;
|
|
179
|
+
data: TResponse | undefined;
|
|
180
|
+
reset: () => void;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Mutation hook with simplified optimistic updates
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* // Simple mutation
|
|
187
|
+
* const { mutate } = useMutation(createPost)
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* // With optimistic update
|
|
191
|
+
* const { mutate } = useMutation(createPost, {
|
|
192
|
+
* optimistic: {
|
|
193
|
+
* target: postsQuery,
|
|
194
|
+
* action: 'prepend',
|
|
195
|
+
* data: (params) => ({ ...params, _id: 'temp-id' })
|
|
196
|
+
* }
|
|
197
|
+
* })
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* // Multiple optimistic updates
|
|
201
|
+
* const { mutate } = useMutation(deletePost, {
|
|
202
|
+
* optimistic: [
|
|
203
|
+
* { target: postsQuery, action: 'delete', id: (p) => p.postId },
|
|
204
|
+
* { target: userStatsEntity, action: 'update', update: (stats) => ({ ...stats, postCount: stats.postCount - 1 }) }
|
|
205
|
+
* ]
|
|
206
|
+
* })
|
|
207
|
+
*/
|
|
208
|
+
declare function useMutation<TParams, TResponse>(def: MutationDef<TParams, TResponse>, options?: UseMutationOptions<TParams, TResponse> & {
|
|
209
|
+
/** Optimistic update configuration - receives channel and params */
|
|
210
|
+
optimistic?: (channel: BatchedChannel, params: TParams) => void;
|
|
211
|
+
}): MutationResult<TParams, TResponse>;
|
|
212
|
+
|
|
213
|
+
export { type EntityResult, type MutationResult, type OptimisticConfig, type PaginatedQueryResult, type PaginationState, type QueryResult, type QueryState, type UseMutationOptions, type UseQueryHookOptions, useMutation, useQuery };
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { C as CollectionDef, Q as QueryOptions, a as Optimistic, E as EntityDef, M as MutationDef } from '../types-BRxQA1mR.js';
|
|
2
|
+
|
|
3
|
+
/** Options for useQuery hook */
|
|
4
|
+
interface UseQueryHookOptions<TParams> extends QueryOptions {
|
|
5
|
+
/** Parameters to pass to the fetch function */
|
|
6
|
+
params?: TParams;
|
|
7
|
+
/** Enable pagination mode (infinite query) */
|
|
8
|
+
paginated?: boolean;
|
|
9
|
+
/** For paginated: get params for each page */
|
|
10
|
+
getPageParams?: (context: {
|
|
11
|
+
pageParam: number;
|
|
12
|
+
}) => TParams;
|
|
13
|
+
/** Custom query key (defaults to [def.name, params]) */
|
|
14
|
+
queryKey?: readonly unknown[];
|
|
15
|
+
}
|
|
16
|
+
/** Query state object (second element of tuple) */
|
|
17
|
+
interface QueryState {
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
isFetching: boolean;
|
|
20
|
+
isError: boolean;
|
|
21
|
+
error: Error | null;
|
|
22
|
+
refetch: () => void;
|
|
23
|
+
}
|
|
24
|
+
/** Pagination state object (third element of paginated tuple) */
|
|
25
|
+
interface PaginationState {
|
|
26
|
+
hasNextPage: boolean;
|
|
27
|
+
fetchNextPage: () => void;
|
|
28
|
+
isFetchingNextPage: boolean;
|
|
29
|
+
}
|
|
30
|
+
/** Return type for collection queries: [data, queryState] */
|
|
31
|
+
type QueryResult<T> = [
|
|
32
|
+
Optimistic<T>[] | undefined,
|
|
33
|
+
QueryState
|
|
34
|
+
];
|
|
35
|
+
/** Return type for paginated queries: [data, queryState, paginationState] */
|
|
36
|
+
type PaginatedQueryResult<T> = [
|
|
37
|
+
Optimistic<T>[] | undefined,
|
|
38
|
+
QueryState,
|
|
39
|
+
PaginationState
|
|
40
|
+
];
|
|
41
|
+
/** Return type for entity queries: [data, queryState] */
|
|
42
|
+
type EntityResult<T> = [
|
|
43
|
+
Optimistic<T> | undefined,
|
|
44
|
+
QueryState
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Unified query hook for fetching data
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Simple collection query
|
|
51
|
+
* const [data, query] = useQuery(postsQuery, { params: { limit: 10 } })
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* // Paginated query
|
|
55
|
+
* const [data, query, pagination] = useQuery(postsQuery, {
|
|
56
|
+
* paginated: true,
|
|
57
|
+
* getPageParams: ({ pageParam }) => ({ page: pageParam, limit: 10 })
|
|
58
|
+
* })
|
|
59
|
+
* // pagination.fetchNextPage(), pagination.hasNextPage
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* // Entity query
|
|
63
|
+
* const [user, query] = useQuery(userEntity, { params: userId })
|
|
64
|
+
*/
|
|
65
|
+
declare function useQuery<TData, TParams>(def: CollectionDef<TData, TParams>, options?: UseQueryHookOptions<TParams> & {
|
|
66
|
+
paginated: true;
|
|
67
|
+
}): PaginatedQueryResult<TData>;
|
|
68
|
+
declare function useQuery<TData, TParams>(def: CollectionDef<TData, TParams>, options?: UseQueryHookOptions<TParams>): QueryResult<TData>;
|
|
69
|
+
declare function useQuery<TData, TParams>(def: EntityDef<TData, TParams>, options?: UseQueryHookOptions<TParams>): EntityResult<TData>;
|
|
70
|
+
|
|
71
|
+
/** Extract entity type from a collection or entity definition */
|
|
72
|
+
type InferEntity<T> = T extends CollectionDef<infer TData, any> ? TData & {} : T extends EntityDef<infer TData, any> ? TData & {} : never;
|
|
73
|
+
/** Base optimistic config with shared properties */
|
|
74
|
+
interface OptimisticConfigBase<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> {
|
|
75
|
+
/** Target collection/entity to update */
|
|
76
|
+
target: TTarget;
|
|
77
|
+
/** Whether to sync with server response (replace optimistic with real data) */
|
|
78
|
+
sync?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** Config for prepend/append actions - requires full entity */
|
|
81
|
+
interface OptimisticPrependAppendConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
82
|
+
action: 'prepend' | 'append';
|
|
83
|
+
/** Data to prepend/append - must be a full entity */
|
|
84
|
+
data: (params: TParams) => NoInfer<InferEntity<TTarget>>;
|
|
85
|
+
}
|
|
86
|
+
/** Config for replace action */
|
|
87
|
+
interface OptimisticReplaceConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
88
|
+
action: 'replace';
|
|
89
|
+
/** Data for replacement */
|
|
90
|
+
data: (params: TParams) => NoInfer<InferEntity<TTarget>>;
|
|
91
|
+
/** ID of item to replace */
|
|
92
|
+
id?: string | ((params: TParams) => string);
|
|
93
|
+
/** Filter function to find items to replace */
|
|
94
|
+
where?: (item: NoInfer<InferEntity<TTarget>>) => boolean;
|
|
95
|
+
}
|
|
96
|
+
/** Config for update action */
|
|
97
|
+
interface OptimisticUpdateConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
98
|
+
action: 'update';
|
|
99
|
+
/** Partial data for update */
|
|
100
|
+
data?: (params: TParams) => Partial<NoInfer<InferEntity<TTarget>>>;
|
|
101
|
+
/** ID of item to update */
|
|
102
|
+
id?: string | ((params: TParams) => string);
|
|
103
|
+
/** Filter function to find items to update */
|
|
104
|
+
where?: (item: NoInfer<InferEntity<TTarget>>) => boolean;
|
|
105
|
+
/** Update function */
|
|
106
|
+
update?: (item: NoInfer<InferEntity<TTarget>>, params: TParams) => NoInfer<InferEntity<TTarget>>;
|
|
107
|
+
}
|
|
108
|
+
/** Config for delete action */
|
|
109
|
+
interface OptimisticDeleteConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> extends OptimisticConfigBase<TTarget, TParams> {
|
|
110
|
+
action: 'delete';
|
|
111
|
+
/** ID of item to delete */
|
|
112
|
+
id?: string | ((params: TParams) => string);
|
|
113
|
+
/** Filter function to find items to delete */
|
|
114
|
+
where?: (item: NoInfer<InferEntity<TTarget>>) => boolean;
|
|
115
|
+
}
|
|
116
|
+
/** Optimistic update configuration - type inferred from target */
|
|
117
|
+
type OptimisticConfig<TTarget extends CollectionDef<any, any> | EntityDef<any, any>, TParams> = OptimisticPrependAppendConfig<TTarget, TParams> | OptimisticReplaceConfig<TTarget, TParams> | OptimisticUpdateConfig<TTarget, TParams> | OptimisticDeleteConfig<TTarget, TParams>;
|
|
118
|
+
/** Internal transaction type for batched mutations */
|
|
119
|
+
interface MutationTransaction {
|
|
120
|
+
target: CollectionDef<any, any> | EntityDef<any, any>;
|
|
121
|
+
action: 'prepend' | 'append' | 'update' | 'delete' | 'replace';
|
|
122
|
+
data?: any;
|
|
123
|
+
id?: string;
|
|
124
|
+
where?: (item: any) => boolean;
|
|
125
|
+
update?: (item: any) => any;
|
|
126
|
+
sync?: boolean;
|
|
127
|
+
}
|
|
128
|
+
/** Internal collection channel for batched mutations */
|
|
129
|
+
declare class BatchedCollectionChannel<TEntity> {
|
|
130
|
+
private readonly target;
|
|
131
|
+
private readonly transactions;
|
|
132
|
+
constructor(target: CollectionDef<TEntity, any>, transactions: MutationTransaction[]);
|
|
133
|
+
prepend(data: TEntity, options?: {
|
|
134
|
+
sync?: boolean;
|
|
135
|
+
}): this;
|
|
136
|
+
append(data: TEntity, options?: {
|
|
137
|
+
sync?: boolean;
|
|
138
|
+
}): this;
|
|
139
|
+
update(id: string, updateFn: (item: TEntity) => TEntity, options?: {
|
|
140
|
+
sync?: boolean;
|
|
141
|
+
}): this;
|
|
142
|
+
delete(id: string): this;
|
|
143
|
+
}
|
|
144
|
+
/** Internal entity channel for batched mutations */
|
|
145
|
+
declare class BatchedEntityChannel<TEntity> {
|
|
146
|
+
private readonly target;
|
|
147
|
+
private readonly transactions;
|
|
148
|
+
constructor(target: EntityDef<TEntity, any>, transactions: MutationTransaction[]);
|
|
149
|
+
update(updateFn: (item: TEntity) => TEntity, options?: {
|
|
150
|
+
sync?: boolean;
|
|
151
|
+
}): this;
|
|
152
|
+
replace(data: TEntity, options?: {
|
|
153
|
+
sync?: boolean;
|
|
154
|
+
}): this;
|
|
155
|
+
}
|
|
156
|
+
/** Internal batched channel type */
|
|
157
|
+
interface BatchedChannel {
|
|
158
|
+
<TEntity>(target: CollectionDef<TEntity, any>): BatchedCollectionChannel<TEntity>;
|
|
159
|
+
<TEntity>(target: EntityDef<TEntity, any>): BatchedEntityChannel<TEntity>;
|
|
160
|
+
}
|
|
161
|
+
/** Options for useMutation hook */
|
|
162
|
+
interface UseMutationOptions<TParams, TResponse> {
|
|
163
|
+
/** Called when mutation starts */
|
|
164
|
+
onMutate?: (params: TParams) => void;
|
|
165
|
+
/** Called on success */
|
|
166
|
+
onSuccess?: (data: TResponse, params: TParams) => void;
|
|
167
|
+
/** Called on error */
|
|
168
|
+
onError?: (error: Error, params: TParams) => void;
|
|
169
|
+
}
|
|
170
|
+
/** Return type for useMutation */
|
|
171
|
+
interface MutationResult<TParams, TResponse> {
|
|
172
|
+
mutate: (params: TParams) => void;
|
|
173
|
+
mutateAsync: (params: TParams) => Promise<TResponse>;
|
|
174
|
+
isLoading: boolean;
|
|
175
|
+
isPending: boolean;
|
|
176
|
+
isError: boolean;
|
|
177
|
+
isSuccess: boolean;
|
|
178
|
+
error: Error | null;
|
|
179
|
+
data: TResponse | undefined;
|
|
180
|
+
reset: () => void;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Mutation hook with simplified optimistic updates
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* // Simple mutation
|
|
187
|
+
* const { mutate } = useMutation(createPost)
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* // With optimistic update
|
|
191
|
+
* const { mutate } = useMutation(createPost, {
|
|
192
|
+
* optimistic: {
|
|
193
|
+
* target: postsQuery,
|
|
194
|
+
* action: 'prepend',
|
|
195
|
+
* data: (params) => ({ ...params, _id: 'temp-id' })
|
|
196
|
+
* }
|
|
197
|
+
* })
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* // Multiple optimistic updates
|
|
201
|
+
* const { mutate } = useMutation(deletePost, {
|
|
202
|
+
* optimistic: [
|
|
203
|
+
* { target: postsQuery, action: 'delete', id: (p) => p.postId },
|
|
204
|
+
* { target: userStatsEntity, action: 'update', update: (stats) => ({ ...stats, postCount: stats.postCount - 1 }) }
|
|
205
|
+
* ]
|
|
206
|
+
* })
|
|
207
|
+
*/
|
|
208
|
+
declare function useMutation<TParams, TResponse>(def: MutationDef<TParams, TResponse>, options?: UseMutationOptions<TParams, TResponse> & {
|
|
209
|
+
/** Optimistic update configuration - receives channel and params */
|
|
210
|
+
optimistic?: (channel: BatchedChannel, params: TParams) => void;
|
|
211
|
+
}): MutationResult<TParams, TResponse>;
|
|
212
|
+
|
|
213
|
+
export { type EntityResult, type MutationResult, type OptimisticConfig, type PaginatedQueryResult, type PaginationState, type QueryResult, type QueryState, type UseMutationOptions, type UseQueryHookOptions, useMutation, useQuery };
|