@trpc/tanstack-react-query 0.0.0-alpha.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/LICENSE +21 -0
- package/README.md +39 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.mjs +3 -0
- package/dist/internals/Context.d.ts +14 -0
- package/dist/internals/Context.d.ts.map +1 -0
- package/dist/internals/Context.js +52 -0
- package/dist/internals/Context.mjs +31 -0
- package/dist/internals/createOptionsProxy.d.ts +107 -0
- package/dist/internals/createOptionsProxy.d.ts.map +1 -0
- package/dist/internals/createOptionsProxy.js +99 -0
- package/dist/internals/createOptionsProxy.mjs +97 -0
- package/dist/internals/infiniteQueryOptions.d.ts +49 -0
- package/dist/internals/infiniteQueryOptions.d.ts.map +1 -0
- package/dist/internals/infiniteQueryOptions.js +39 -0
- package/dist/internals/infiniteQueryOptions.mjs +37 -0
- package/dist/internals/mutationOptions.d.ts +38 -0
- package/dist/internals/mutationOptions.d.ts.map +1 -0
- package/dist/internals/mutationOptions.js +38 -0
- package/dist/internals/mutationOptions.mjs +36 -0
- package/dist/internals/queryOptions.d.ts +61 -0
- package/dist/internals/queryOptions.d.ts.map +1 -0
- package/dist/internals/queryOptions.js +40 -0
- package/dist/internals/queryOptions.mjs +38 -0
- package/dist/internals/subscriptionOptions.d.ts +77 -0
- package/dist/internals/subscriptionOptions.d.ts.map +1 -0
- package/dist/internals/subscriptionOptions.js +173 -0
- package/dist/internals/subscriptionOptions.mjs +151 -0
- package/dist/internals/types.d.ts +41 -0
- package/dist/internals/types.d.ts.map +1 -0
- package/dist/internals/utils.d.ts +28 -0
- package/dist/internals/utils.d.ts.map +1 -0
- package/dist/internals/utils.js +112 -0
- package/dist/internals/utils.mjs +105 -0
- package/package.json +81 -0
- package/src/index.ts +25 -0
- package/src/internals/Context.tsx +46 -0
- package/src/internals/createOptionsProxy.ts +309 -0
- package/src/internals/infiniteQueryOptions.ts +233 -0
- package/src/internals/mutationOptions.ts +113 -0
- package/src/internals/queryOptions.ts +199 -0
- package/src/internals/subscriptionOptions.ts +286 -0
- package/src/internals/types.ts +47 -0
- package/src/internals/utils.ts +140 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
import { type QueryClient, type QueryFilters } from '@tanstack/react-query';
|
|
2
|
+
import {
|
|
3
|
+
getUntypedClient,
|
|
4
|
+
TRPCUntypedClient,
|
|
5
|
+
type CreateTRPCClient,
|
|
6
|
+
type TRPCRequestOptions,
|
|
7
|
+
} from '@trpc/client';
|
|
8
|
+
import {
|
|
9
|
+
callProcedure,
|
|
10
|
+
type AnyProcedure,
|
|
11
|
+
type inferProcedureInput,
|
|
12
|
+
type inferRouterContext,
|
|
13
|
+
type inferTransformedProcedureOutput,
|
|
14
|
+
type ProcedureType,
|
|
15
|
+
} from '@trpc/server';
|
|
16
|
+
import { createRecursiveProxy } from '@trpc/server/unstable-core-do-not-import';
|
|
17
|
+
import type {
|
|
18
|
+
AnyRootTypes,
|
|
19
|
+
AnyRouter,
|
|
20
|
+
MaybePromise,
|
|
21
|
+
RouterRecord,
|
|
22
|
+
} from '@trpc/server/unstable-core-do-not-import';
|
|
23
|
+
import {
|
|
24
|
+
trpcInfiniteQueryOptions,
|
|
25
|
+
type TRPCInfiniteQueryOptions,
|
|
26
|
+
} from './infiniteQueryOptions';
|
|
27
|
+
import type { MutationOptionsOverride } from './mutationOptions';
|
|
28
|
+
import {
|
|
29
|
+
trpcMutationOptions,
|
|
30
|
+
type TRPCMutationOptions,
|
|
31
|
+
} from './mutationOptions';
|
|
32
|
+
import { trpcQueryOptions, type TRPCQueryOptions } from './queryOptions';
|
|
33
|
+
import {
|
|
34
|
+
trpcSubscriptionOptions,
|
|
35
|
+
type TRPCSubscriptionOptions,
|
|
36
|
+
} from './subscriptionOptions';
|
|
37
|
+
import type {
|
|
38
|
+
QueryType,
|
|
39
|
+
ResolverDef,
|
|
40
|
+
TRPCMutationKey,
|
|
41
|
+
TRPCQueryKey,
|
|
42
|
+
} from './types';
|
|
43
|
+
import {
|
|
44
|
+
getMutationKeyInternal,
|
|
45
|
+
getQueryKeyInternal,
|
|
46
|
+
unwrapLazyArg,
|
|
47
|
+
} from './utils';
|
|
48
|
+
|
|
49
|
+
export interface DecorateQueryKeyable {
|
|
50
|
+
/**
|
|
51
|
+
* Calculate the Tanstack Query Key for a Route
|
|
52
|
+
*
|
|
53
|
+
* @see https://tanstack.com/query/latest/docs/framework/react/guides/query-keys
|
|
54
|
+
*/
|
|
55
|
+
queryKey: () => TRPCQueryKey;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Calculate a Tanstack Query Filter for a Route
|
|
59
|
+
*
|
|
60
|
+
* @see https://tanstack.com/query/latest/docs/framework/react/guides/filters
|
|
61
|
+
*/
|
|
62
|
+
queryFilter: () => QueryFilters;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type InferInput<
|
|
66
|
+
TProcedure extends
|
|
67
|
+
| DecorateQueryProcedure<any>
|
|
68
|
+
| DecorateMutationProcedure<any>,
|
|
69
|
+
> = TProcedure['~types']['input'];
|
|
70
|
+
|
|
71
|
+
export type InferOutput<
|
|
72
|
+
TProcedure extends
|
|
73
|
+
| DecorateQueryProcedure<any>
|
|
74
|
+
| DecorateMutationProcedure<any>,
|
|
75
|
+
> = TProcedure['~types']['output'];
|
|
76
|
+
|
|
77
|
+
export interface DecorateQueryProcedure<TDef extends ResolverDef> {
|
|
78
|
+
/**
|
|
79
|
+
* @internal prefer using InferInput and InferOutput to access types
|
|
80
|
+
*/
|
|
81
|
+
'~types': {
|
|
82
|
+
input: TDef['input'];
|
|
83
|
+
output: TDef['output'];
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @see https://tanstack.com/query/latest/docs/framework/react/reference/queryOptions#queryoptions
|
|
88
|
+
*/
|
|
89
|
+
queryOptions: TRPCQueryOptions<TDef>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @see https://tanstack.com/query/latest/docs/framework/react/reference/infiniteQueryOptions#infinitequeryoptions
|
|
93
|
+
*/
|
|
94
|
+
infiniteQueryOptions: TRPCInfiniteQueryOptions<TDef>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Calculate the Tanstack Query Key for a Query Procedure
|
|
98
|
+
*
|
|
99
|
+
* @see https://tanstack.com/query/latest/docs/framework/react/guides/query-keys
|
|
100
|
+
*/
|
|
101
|
+
queryKey: (input?: TDef['input']) => TRPCQueryKey;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Calculate a Tanstack Query Filter for a Query Procedure
|
|
105
|
+
*
|
|
106
|
+
* @see https://tanstack.com/query/latest/docs/framework/react/guides/filters
|
|
107
|
+
*/
|
|
108
|
+
queryFilter: (input?: TDef['input']) => QueryFilters;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface DecorateMutationProcedure<TDef extends ResolverDef> {
|
|
112
|
+
/**
|
|
113
|
+
* @internal prefer using InferInput and InferOutput to access types
|
|
114
|
+
*/
|
|
115
|
+
'~types': {
|
|
116
|
+
input: TDef['input'];
|
|
117
|
+
output: TDef['output'];
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @see
|
|
122
|
+
*/
|
|
123
|
+
mutationOptions: TRPCMutationOptions<TDef>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Calculate the Tanstack Mutation Key for a Mutation Procedure
|
|
127
|
+
*/
|
|
128
|
+
mutationKey: () => TRPCMutationKey;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface DecorateSubscriptionProcedure<TDef extends ResolverDef> {
|
|
132
|
+
/**
|
|
133
|
+
* @see
|
|
134
|
+
*/
|
|
135
|
+
subscriptionOptions: TRPCSubscriptionOptions<TDef>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type DecorateProcedure<
|
|
139
|
+
TType extends ProcedureType,
|
|
140
|
+
TDef extends ResolverDef,
|
|
141
|
+
> = TType extends 'query'
|
|
142
|
+
? DecorateQueryProcedure<TDef>
|
|
143
|
+
: TType extends 'mutation'
|
|
144
|
+
? DecorateMutationProcedure<TDef>
|
|
145
|
+
: TType extends 'subscription'
|
|
146
|
+
? DecorateSubscriptionProcedure<TDef>
|
|
147
|
+
: never;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
export type DecoratedProcedureUtilsRecord<
|
|
153
|
+
TRoot extends AnyRootTypes,
|
|
154
|
+
TRecord extends RouterRecord,
|
|
155
|
+
> = {
|
|
156
|
+
[TKey in keyof TRecord]: TRecord[TKey] extends infer $Value
|
|
157
|
+
? $Value extends RouterRecord
|
|
158
|
+
? DecoratedProcedureUtilsRecord<TRoot, $Value> & DecorateQueryKeyable
|
|
159
|
+
: $Value extends AnyProcedure
|
|
160
|
+
? DecorateProcedure<
|
|
161
|
+
$Value['_def']['type'],
|
|
162
|
+
{
|
|
163
|
+
input: inferProcedureInput<$Value>;
|
|
164
|
+
output: inferTransformedProcedureOutput<TRoot, $Value>;
|
|
165
|
+
transformer: TRoot['transformer'];
|
|
166
|
+
errorShape: TRoot['errorShape'];
|
|
167
|
+
}
|
|
168
|
+
>
|
|
169
|
+
: never
|
|
170
|
+
: never;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export type TRPCOptionsProxy<TRouter extends AnyRouter> =
|
|
174
|
+
DecoratedProcedureUtilsRecord<
|
|
175
|
+
TRouter['_def']['_config']['$types'],
|
|
176
|
+
TRouter['_def']['record']
|
|
177
|
+
> &
|
|
178
|
+
DecorateQueryKeyable;
|
|
179
|
+
|
|
180
|
+
export interface TRPCOptionsProxyOptionsBase {
|
|
181
|
+
queryClient: QueryClient | (() => QueryClient);
|
|
182
|
+
overrides?: {
|
|
183
|
+
mutations?: MutationOptionsOverride;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
export interface TRPCOptionsProxyOptionsInternal<TRouter extends AnyRouter> {
|
|
188
|
+
router: TRouter;
|
|
189
|
+
ctx:
|
|
190
|
+
| inferRouterContext<TRouter>
|
|
191
|
+
| (() => MaybePromise<inferRouterContext<TRouter>>);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface TRPCOptionsProxyOptionsExternal<TRouter extends AnyRouter> {
|
|
195
|
+
client: TRPCUntypedClient<TRouter> | CreateTRPCClient<TRouter>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export type TRPCOptionsProxyOptions<TRouter extends AnyRouter> =
|
|
199
|
+
TRPCOptionsProxyOptionsBase &
|
|
200
|
+
(
|
|
201
|
+
| TRPCOptionsProxyOptionsInternal<TRouter>
|
|
202
|
+
| TRPCOptionsProxyOptionsExternal<TRouter>
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
type UtilsMethods =
|
|
206
|
+
| keyof DecorateQueryProcedure<any>
|
|
207
|
+
| keyof DecorateMutationProcedure<any>
|
|
208
|
+
| keyof DecorateSubscriptionProcedure<any>;
|
|
209
|
+
|
|
210
|
+
function getQueryType(method: UtilsMethods) {
|
|
211
|
+
const map: Partial<Record<UtilsMethods, QueryType>> = {
|
|
212
|
+
queryOptions: 'query',
|
|
213
|
+
infiniteQueryOptions: 'infinite',
|
|
214
|
+
subscriptionOptions: 'any',
|
|
215
|
+
mutationOptions: 'any',
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
return map[method];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function createTRPCOptionsProxy<TRouter extends AnyRouter>(
|
|
222
|
+
opts: TRPCOptionsProxyOptions<TRouter>,
|
|
223
|
+
): TRPCOptionsProxy<TRouter> {
|
|
224
|
+
const callIt = (type: ProcedureType): any => {
|
|
225
|
+
return (path: string, input: unknown, trpcOpts: TRPCRequestOptions) => {
|
|
226
|
+
if ('router' in opts) {
|
|
227
|
+
return Promise.resolve(unwrapLazyArg(opts.ctx)).then((ctx) =>
|
|
228
|
+
callProcedure({
|
|
229
|
+
procedures: opts.router._def.procedures,
|
|
230
|
+
path: path,
|
|
231
|
+
getRawInput: async () => input,
|
|
232
|
+
ctx: ctx,
|
|
233
|
+
type: type,
|
|
234
|
+
signal: undefined,
|
|
235
|
+
}),
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const untypedClient =
|
|
240
|
+
opts.client instanceof TRPCUntypedClient
|
|
241
|
+
? opts.client
|
|
242
|
+
: getUntypedClient(opts.client);
|
|
243
|
+
|
|
244
|
+
return untypedClient[type](path, input, trpcOpts);
|
|
245
|
+
};
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
return createRecursiveProxy(({ args, path: _path }) => {
|
|
249
|
+
const path = [..._path];
|
|
250
|
+
const utilName = path.pop() as UtilsMethods;
|
|
251
|
+
const [arg1, arg2] = args as any[];
|
|
252
|
+
|
|
253
|
+
const queryType = getQueryType(utilName);
|
|
254
|
+
const queryKey = getQueryKeyInternal(path, arg1, queryType ?? 'any');
|
|
255
|
+
|
|
256
|
+
const contextMap: Record<UtilsMethods, () => unknown> = {
|
|
257
|
+
'~types': undefined as any,
|
|
258
|
+
|
|
259
|
+
mutationKey: () => {
|
|
260
|
+
return getMutationKeyInternal(path);
|
|
261
|
+
},
|
|
262
|
+
queryKey: () => {
|
|
263
|
+
return queryKey;
|
|
264
|
+
},
|
|
265
|
+
queryFilter: (): QueryFilters => {
|
|
266
|
+
return {
|
|
267
|
+
queryKey: queryKey,
|
|
268
|
+
};
|
|
269
|
+
},
|
|
270
|
+
infiniteQueryOptions: () => {
|
|
271
|
+
return trpcInfiniteQueryOptions({
|
|
272
|
+
opts: arg2,
|
|
273
|
+
path,
|
|
274
|
+
queryClient: opts.queryClient,
|
|
275
|
+
queryKey: queryKey,
|
|
276
|
+
query: callIt('query'),
|
|
277
|
+
});
|
|
278
|
+
},
|
|
279
|
+
queryOptions: () => {
|
|
280
|
+
return trpcQueryOptions({
|
|
281
|
+
opts: arg2,
|
|
282
|
+
path,
|
|
283
|
+
queryClient: opts.queryClient,
|
|
284
|
+
queryKey: queryKey,
|
|
285
|
+
query: callIt('query'),
|
|
286
|
+
});
|
|
287
|
+
},
|
|
288
|
+
mutationOptions: () => {
|
|
289
|
+
return trpcMutationOptions({
|
|
290
|
+
opts: arg1,
|
|
291
|
+
path,
|
|
292
|
+
queryClient: opts.queryClient,
|
|
293
|
+
mutate: callIt('mutation'),
|
|
294
|
+
overrides: opts.overrides?.mutations,
|
|
295
|
+
});
|
|
296
|
+
},
|
|
297
|
+
subscriptionOptions: () => {
|
|
298
|
+
return trpcSubscriptionOptions({
|
|
299
|
+
opts: arg2,
|
|
300
|
+
path,
|
|
301
|
+
queryKey: queryKey,
|
|
302
|
+
subscribe: callIt('subscription'),
|
|
303
|
+
});
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
return contextMap[utilName]();
|
|
308
|
+
});
|
|
309
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
DataTag,
|
|
3
|
+
DefinedInitialDataInfiniteOptions,
|
|
4
|
+
InfiniteData,
|
|
5
|
+
QueryFunction,
|
|
6
|
+
UndefinedInitialDataInfiniteOptions,
|
|
7
|
+
UnusedSkipTokenInfiniteOptions,
|
|
8
|
+
} from '@tanstack/react-query';
|
|
9
|
+
import {
|
|
10
|
+
infiniteQueryOptions,
|
|
11
|
+
skipToken,
|
|
12
|
+
type QueryClient,
|
|
13
|
+
type SkipToken,
|
|
14
|
+
} from '@tanstack/react-query';
|
|
15
|
+
import type { TRPCClientErrorLike, TRPCUntypedClient } from '@trpc/client';
|
|
16
|
+
import type { DistributiveOmit } from '@trpc/server/unstable-core-do-not-import';
|
|
17
|
+
import type {
|
|
18
|
+
ExtractCursorType,
|
|
19
|
+
ResolverDef,
|
|
20
|
+
TRPCQueryBaseOptions,
|
|
21
|
+
TRPCQueryKey,
|
|
22
|
+
TRPCQueryOptionsResult,
|
|
23
|
+
} from './types';
|
|
24
|
+
import { createTRPCOptionsResult, getClientArgs } from './utils';
|
|
25
|
+
|
|
26
|
+
type ReservedOptions =
|
|
27
|
+
| 'queryKey'
|
|
28
|
+
| 'queryFn'
|
|
29
|
+
| 'queryHashFn'
|
|
30
|
+
| 'queryHash'
|
|
31
|
+
| 'initialPageParam';
|
|
32
|
+
|
|
33
|
+
interface UndefinedTRPCInfiniteQueryOptionsIn<
|
|
34
|
+
TInput,
|
|
35
|
+
TQueryFnData,
|
|
36
|
+
TData,
|
|
37
|
+
TError,
|
|
38
|
+
> extends DistributiveOmit<
|
|
39
|
+
UndefinedInitialDataInfiniteOptions<
|
|
40
|
+
TQueryFnData,
|
|
41
|
+
TError,
|
|
42
|
+
InfiniteData<TData, NonNullable<ExtractCursorType<TInput>> | null>,
|
|
43
|
+
TRPCQueryKey,
|
|
44
|
+
NonNullable<ExtractCursorType<TInput>> | null
|
|
45
|
+
>,
|
|
46
|
+
ReservedOptions
|
|
47
|
+
>,
|
|
48
|
+
TRPCQueryBaseOptions {
|
|
49
|
+
initialCursor?: NonNullable<ExtractCursorType<TInput>> | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface UndefinedTRPCInfiniteQueryOptionsOut<
|
|
53
|
+
TInput,
|
|
54
|
+
TQueryFnData,
|
|
55
|
+
TData,
|
|
56
|
+
TError,
|
|
57
|
+
> extends DistributiveOmit<
|
|
58
|
+
UndefinedInitialDataInfiniteOptions<
|
|
59
|
+
TQueryFnData,
|
|
60
|
+
TError,
|
|
61
|
+
InfiniteData<TData, NonNullable<ExtractCursorType<TInput>> | null>,
|
|
62
|
+
TRPCQueryKey,
|
|
63
|
+
NonNullable<ExtractCursorType<TInput>> | null
|
|
64
|
+
>,
|
|
65
|
+
'initialPageParam'
|
|
66
|
+
>,
|
|
67
|
+
TRPCQueryOptionsResult {
|
|
68
|
+
queryKey: DataTag<TRPCQueryKey, TData>;
|
|
69
|
+
initialPageParam: NonNullable<ExtractCursorType<TInput>> | null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
interface DefinedTRPCInfiniteQueryOptionsIn<TInput, TQueryFnData, TData, TError>
|
|
73
|
+
extends DistributiveOmit<
|
|
74
|
+
DefinedInitialDataInfiniteOptions<
|
|
75
|
+
TQueryFnData,
|
|
76
|
+
TError,
|
|
77
|
+
InfiniteData<TData, NonNullable<ExtractCursorType<TInput>> | null>,
|
|
78
|
+
TRPCQueryKey,
|
|
79
|
+
NonNullable<ExtractCursorType<TInput>> | null
|
|
80
|
+
>,
|
|
81
|
+
ReservedOptions
|
|
82
|
+
>,
|
|
83
|
+
TRPCQueryBaseOptions {
|
|
84
|
+
initialCursor?: NonNullable<ExtractCursorType<TInput>> | null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface DefinedTRPCInfiniteQueryOptionsOut<
|
|
88
|
+
TInput,
|
|
89
|
+
TQueryFnData,
|
|
90
|
+
TData,
|
|
91
|
+
TError,
|
|
92
|
+
> extends DistributiveOmit<
|
|
93
|
+
DefinedInitialDataInfiniteOptions<
|
|
94
|
+
TQueryFnData,
|
|
95
|
+
TError,
|
|
96
|
+
InfiniteData<TData, NonNullable<ExtractCursorType<TInput>> | null>,
|
|
97
|
+
TRPCQueryKey,
|
|
98
|
+
NonNullable<ExtractCursorType<TInput>> | null
|
|
99
|
+
>,
|
|
100
|
+
'initialPageParam'
|
|
101
|
+
>,
|
|
102
|
+
TRPCQueryOptionsResult {
|
|
103
|
+
queryKey: DataTag<TRPCQueryKey, TData>;
|
|
104
|
+
initialPageParam: NonNullable<ExtractCursorType<TInput>> | null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface UnusedSkipTokenTRPCInfiniteQueryOptionsIn<
|
|
108
|
+
TInput,
|
|
109
|
+
TQueryFnData,
|
|
110
|
+
TData,
|
|
111
|
+
TError,
|
|
112
|
+
> extends DistributiveOmit<
|
|
113
|
+
UnusedSkipTokenInfiniteOptions<
|
|
114
|
+
TQueryFnData,
|
|
115
|
+
TError,
|
|
116
|
+
InfiniteData<TData, NonNullable<ExtractCursorType<TInput>> | null>,
|
|
117
|
+
TRPCQueryKey,
|
|
118
|
+
NonNullable<ExtractCursorType<TInput>> | null
|
|
119
|
+
>,
|
|
120
|
+
ReservedOptions
|
|
121
|
+
>,
|
|
122
|
+
TRPCQueryBaseOptions {
|
|
123
|
+
initialCursor?: NonNullable<ExtractCursorType<TInput>> | null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
interface UnusedSkipTokenTRPCInfiniteQueryOptionsOut<
|
|
127
|
+
TInput,
|
|
128
|
+
TQueryFnData,
|
|
129
|
+
TData,
|
|
130
|
+
TError,
|
|
131
|
+
> extends DistributiveOmit<
|
|
132
|
+
UnusedSkipTokenInfiniteOptions<
|
|
133
|
+
TQueryFnData,
|
|
134
|
+
TError,
|
|
135
|
+
InfiniteData<TData, NonNullable<ExtractCursorType<TInput>> | null>,
|
|
136
|
+
TRPCQueryKey,
|
|
137
|
+
NonNullable<ExtractCursorType<TInput>> | null
|
|
138
|
+
>,
|
|
139
|
+
'initialPageParam'
|
|
140
|
+
>,
|
|
141
|
+
TRPCQueryOptionsResult {
|
|
142
|
+
queryKey: DataTag<TRPCQueryKey, TData>;
|
|
143
|
+
initialPageParam: NonNullable<ExtractCursorType<TInput>> | null;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface TRPCInfiniteQueryOptions<TDef extends ResolverDef> {
|
|
147
|
+
<TQueryFnData extends TDef['output'], TData = TQueryFnData>(
|
|
148
|
+
input: TDef['input'] | SkipToken,
|
|
149
|
+
opts: DefinedTRPCInfiniteQueryOptionsIn<
|
|
150
|
+
TDef['input'],
|
|
151
|
+
TQueryFnData,
|
|
152
|
+
TData,
|
|
153
|
+
TRPCClientErrorLike<TDef>
|
|
154
|
+
>,
|
|
155
|
+
): DefinedTRPCInfiniteQueryOptionsOut<
|
|
156
|
+
TDef['input'],
|
|
157
|
+
TQueryFnData,
|
|
158
|
+
TData,
|
|
159
|
+
TRPCClientErrorLike<TDef>
|
|
160
|
+
>;
|
|
161
|
+
<TQueryFnData extends TDef['output'], TData = TQueryFnData>(
|
|
162
|
+
input: TDef['input'],
|
|
163
|
+
opts: UnusedSkipTokenTRPCInfiniteQueryOptionsIn<
|
|
164
|
+
TDef['input'],
|
|
165
|
+
TQueryFnData,
|
|
166
|
+
TData,
|
|
167
|
+
TRPCClientErrorLike<TDef>
|
|
168
|
+
>,
|
|
169
|
+
): UnusedSkipTokenTRPCInfiniteQueryOptionsOut<
|
|
170
|
+
TDef['input'],
|
|
171
|
+
TQueryFnData,
|
|
172
|
+
TData,
|
|
173
|
+
TRPCClientErrorLike<TDef>
|
|
174
|
+
>;
|
|
175
|
+
<TQueryFnData extends TDef['output'], TData = TQueryFnData>(
|
|
176
|
+
input: TDef['input'] | SkipToken,
|
|
177
|
+
opts?: UndefinedTRPCInfiniteQueryOptionsIn<
|
|
178
|
+
TDef['input'],
|
|
179
|
+
TQueryFnData,
|
|
180
|
+
TData,
|
|
181
|
+
TRPCClientErrorLike<TDef>
|
|
182
|
+
>,
|
|
183
|
+
): UndefinedTRPCInfiniteQueryOptionsOut<
|
|
184
|
+
TDef['input'],
|
|
185
|
+
TQueryFnData,
|
|
186
|
+
TData,
|
|
187
|
+
TRPCClientErrorLike<TDef>
|
|
188
|
+
>;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function trpcInfiniteQueryOptions(args: {
|
|
192
|
+
query: typeof TRPCUntypedClient.prototype.query;
|
|
193
|
+
queryClient: QueryClient | (() => QueryClient);
|
|
194
|
+
path: readonly string[];
|
|
195
|
+
queryKey: TRPCQueryKey;
|
|
196
|
+
opts: UndefinedTRPCInfiniteQueryOptionsIn<unknown, unknown, unknown, unknown>;
|
|
197
|
+
}) {
|
|
198
|
+
const { query, path, queryKey, opts } = args;
|
|
199
|
+
const inputIsSkipToken = queryKey[1]?.input === skipToken;
|
|
200
|
+
|
|
201
|
+
const queryFn: QueryFunction<unknown, TRPCQueryKey, unknown> = async (
|
|
202
|
+
queryFnContext,
|
|
203
|
+
) => {
|
|
204
|
+
const actualOpts = {
|
|
205
|
+
...opts,
|
|
206
|
+
trpc: {
|
|
207
|
+
...opts?.trpc,
|
|
208
|
+
...(opts?.trpc?.abortOnUnmount
|
|
209
|
+
? { signal: queryFnContext.signal }
|
|
210
|
+
: { signal: null }),
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
const result = await query(
|
|
215
|
+
...getClientArgs(queryKey, actualOpts, {
|
|
216
|
+
direction: queryFnContext.direction,
|
|
217
|
+
pageParam: queryFnContext.pageParam,
|
|
218
|
+
}),
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
return result;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
return Object.assign(
|
|
225
|
+
infiniteQueryOptions({
|
|
226
|
+
...opts,
|
|
227
|
+
queryKey,
|
|
228
|
+
queryFn: inputIsSkipToken ? skipToken : queryFn,
|
|
229
|
+
initialPageParam: opts?.initialCursor ?? null,
|
|
230
|
+
}),
|
|
231
|
+
{ trpc: createTRPCOptionsResult({ path }) },
|
|
232
|
+
);
|
|
233
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { MutationFunction } from '@tanstack/react-query';
|
|
2
|
+
import {
|
|
3
|
+
type QueryClient,
|
|
4
|
+
type UseMutationOptions,
|
|
5
|
+
} from '@tanstack/react-query';
|
|
6
|
+
import type { TRPCClientErrorLike, TRPCUntypedClient } from '@trpc/client';
|
|
7
|
+
import type {
|
|
8
|
+
DistributiveOmit,
|
|
9
|
+
MaybePromise,
|
|
10
|
+
} from '@trpc/server/unstable-core-do-not-import';
|
|
11
|
+
import type {
|
|
12
|
+
ResolverDef,
|
|
13
|
+
TRPCMutationKey,
|
|
14
|
+
TRPCQueryBaseOptions,
|
|
15
|
+
TRPCQueryOptionsResult,
|
|
16
|
+
} from './types';
|
|
17
|
+
import {
|
|
18
|
+
createTRPCOptionsResult,
|
|
19
|
+
getClientArgs,
|
|
20
|
+
getMutationKeyInternal,
|
|
21
|
+
unwrapLazyArg,
|
|
22
|
+
} from './utils';
|
|
23
|
+
|
|
24
|
+
type ReservedOptions = 'mutationKey' | 'mutationFn';
|
|
25
|
+
|
|
26
|
+
interface TRPCMutationOptionsIn<TInput, TError, TOutput, TContext>
|
|
27
|
+
extends DistributiveOmit<
|
|
28
|
+
UseMutationOptions<TOutput, TError, TInput, TContext>,
|
|
29
|
+
ReservedOptions
|
|
30
|
+
>,
|
|
31
|
+
TRPCQueryBaseOptions {}
|
|
32
|
+
|
|
33
|
+
interface TRPCMutationOptionsOut<TInput, TError, TOutput, TContext>
|
|
34
|
+
extends UseMutationOptions<TOutput, TError, TInput, TContext>,
|
|
35
|
+
TRPCQueryOptionsResult {
|
|
36
|
+
mutationKey: TRPCMutationKey;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface TRPCMutationOptions<TDef extends ResolverDef> {
|
|
40
|
+
<TContext = unknown>(
|
|
41
|
+
opts?: TRPCMutationOptionsIn<
|
|
42
|
+
TDef['input'],
|
|
43
|
+
TRPCClientErrorLike<TDef>,
|
|
44
|
+
TDef['output'],
|
|
45
|
+
TContext
|
|
46
|
+
>,
|
|
47
|
+
): TRPCMutationOptionsOut<
|
|
48
|
+
TDef['input'],
|
|
49
|
+
TRPCClientErrorLike<TDef>,
|
|
50
|
+
TDef['output'],
|
|
51
|
+
TContext
|
|
52
|
+
>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
export interface MutationOptionsOverride {
|
|
59
|
+
onSuccess: (opts: {
|
|
60
|
+
/**
|
|
61
|
+
* Calls the original function that was defined in the query's `onSuccess` option
|
|
62
|
+
*/
|
|
63
|
+
originalFn: () => MaybePromise<unknown>;
|
|
64
|
+
queryClient: QueryClient;
|
|
65
|
+
/**
|
|
66
|
+
* Meta data passed in from the `useMutation()` hook
|
|
67
|
+
*/
|
|
68
|
+
meta: Record<string, unknown>;
|
|
69
|
+
}) => MaybePromise<unknown>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function trpcMutationOptions(args: {
|
|
73
|
+
mutate: typeof TRPCUntypedClient.prototype.mutation;
|
|
74
|
+
queryClient: QueryClient | (() => QueryClient);
|
|
75
|
+
path: readonly string[];
|
|
76
|
+
opts: TRPCMutationOptionsIn<unknown, unknown, unknown, unknown> | undefined;
|
|
77
|
+
overrides: MutationOptionsOverride | undefined;
|
|
78
|
+
}): TRPCMutationOptionsOut<unknown, unknown, unknown, unknown> {
|
|
79
|
+
const { mutate, path, opts, overrides } = args;
|
|
80
|
+
const queryClient = unwrapLazyArg(args.queryClient);
|
|
81
|
+
|
|
82
|
+
const mutationKey = getMutationKeyInternal(path);
|
|
83
|
+
|
|
84
|
+
const defaultOpts = queryClient.defaultMutationOptions(
|
|
85
|
+
queryClient.getMutationDefaults(mutationKey),
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const mutationSuccessOverride: MutationOptionsOverride['onSuccess'] =
|
|
89
|
+
overrides?.onSuccess ?? ((options) => options.originalFn());
|
|
90
|
+
|
|
91
|
+
const mutationFn: MutationFunction = async (input) => {
|
|
92
|
+
const result = await mutate(...getClientArgs([path, { input }], opts));
|
|
93
|
+
|
|
94
|
+
return result;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
...opts,
|
|
99
|
+
mutationKey: mutationKey,
|
|
100
|
+
mutationFn,
|
|
101
|
+
onSuccess(...args) {
|
|
102
|
+
const originalFn = () =>
|
|
103
|
+
opts?.onSuccess?.(...args) ?? defaultOpts?.onSuccess?.(...args);
|
|
104
|
+
|
|
105
|
+
return mutationSuccessOverride({
|
|
106
|
+
originalFn,
|
|
107
|
+
queryClient,
|
|
108
|
+
meta: opts?.meta ?? defaultOpts?.meta ?? {},
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
trpc: createTRPCOptionsResult({ path }),
|
|
112
|
+
};
|
|
113
|
+
}
|