@trpc/tanstack-react-query 11.0.0-rc.808 → 11.0.0-rc.814

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.
@@ -1,4 +1,9 @@
1
- import type { DataTag, QueryClient, QueryFilters } from '@tanstack/react-query';
1
+ import type {
2
+ DataTag,
3
+ InfiniteData,
4
+ QueryClient,
5
+ QueryFilters,
6
+ } from '@tanstack/react-query';
2
7
  import type { TRPCClient, TRPCRequestOptions } from '@trpc/client';
3
8
  import { getUntypedClient, TRPCUntypedClient } from '@trpc/client';
4
9
  import type {
@@ -28,10 +33,11 @@ import {
28
33
  type TRPCSubscriptionOptions,
29
34
  } from './subscriptionOptions';
30
35
  import type {
31
- QueryType,
36
+ OptionalCursorInput,
32
37
  ResolverDef,
33
38
  TRPCMutationKey,
34
39
  TRPCQueryKey,
40
+ WithRequired,
35
41
  } from './types';
36
42
  import {
37
43
  getMutationKeyInternal,
@@ -39,61 +45,120 @@ import {
39
45
  unwrapLazyArg,
40
46
  } from './utils';
41
47
 
42
- export interface DecorateQueryKeyable {
48
+ export interface DecorateRouterKeyable {
43
49
  /**
44
- * Calculate the TanStack Query Key for a Route
50
+ * Calculate the TanStack Query Key for any path, could be used to invalidate every procedure beneath this path
45
51
  *
46
52
  * @see https://tanstack.com/query/latest/docs/framework/react/guides/query-keys
47
53
  * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryKey
48
54
  */
49
- queryKey: () => TRPCQueryKey;
55
+ pathKey: () => TRPCQueryKey;
50
56
 
51
57
  /**
52
- * Calculate a TanStack Query Filter for a Route
58
+ * Calculate a TanStack Query Filter for any path, could be used to manipulate every procedure beneath this path
53
59
  *
54
60
  * @see https://tanstack.com/query/latest/docs/framework/react/guides/filters
55
61
  * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryFilter
56
62
  */
57
- queryFilter: (input?: undefined, filters?: QueryFilters) => QueryFilters;
63
+ pathFilter: (
64
+ filters?: QueryFilters<unknown, unknown, unknown, TRPCQueryKey>,
65
+ ) => WithRequired<
66
+ QueryFilters<unknown, unknown, unknown, TRPCQueryKey>,
67
+ 'queryKey'
68
+ >;
69
+ }
70
+
71
+ interface TypeHelper<TDef extends ResolverDef> {
72
+ /**
73
+ * @internal prefer using inferInput and inferOutput to access types
74
+ */
75
+ '~types': {
76
+ input: TDef['input'];
77
+ output: TDef['output'];
78
+ errorShape: TDef['errorShape'];
79
+ };
58
80
  }
59
81
 
60
82
  export type inferInput<
61
83
  TProcedure extends
84
+ | DecorateInfiniteQueryProcedure<any>
62
85
  | DecorateQueryProcedure<any>
63
86
  | DecorateMutationProcedure<any>,
64
87
  > = TProcedure['~types']['input'];
65
88
 
66
89
  export type inferOutput<
67
90
  TProcedure extends
91
+ | DecorateInfiniteQueryProcedure<any>
68
92
  | DecorateQueryProcedure<any>
69
93
  | DecorateMutationProcedure<any>,
70
94
  > = TProcedure['~types']['output'];
71
95
 
72
- export interface DecorateQueryProcedure<TDef extends ResolverDef> {
96
+ export interface DecorateInfiniteQueryProcedure<TDef extends ResolverDef>
97
+ extends TypeHelper<TDef> {
73
98
  /**
74
- * @internal prefer using inferInput and inferOutput to access types
99
+ * Create a set of type-safe infinite query options that can be passed to `useInfiniteQuery`, `prefetchInfiniteQuery` etc.
100
+ *
101
+ * @see https://tanstack.com/query/latest/docs/framework/react/reference/infiniteQueryOptions#infinitequeryoptions
102
+ * @see https://trpc.io/docs/client/tanstack-react-query/usage#infiniteQueryOptions
75
103
  */
76
- '~types': {
77
- input: TDef['input'];
78
- output: TDef['output'];
79
- errorShape: TDef['errorShape'];
80
- };
104
+ infiniteQueryOptions: TRPCInfiniteQueryOptions<TDef>;
81
105
 
82
106
  /**
83
- * Create a set of type-safe query options that can be passed to `useQuery`, `prefetchQuery` etc.
107
+ * Calculate the TanStack Query Key for a Infinite Query Procedure
84
108
  *
85
- * @see https://tanstack.com/query/latest/docs/framework/react/reference/queryOptions#queryoptions
86
- * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryOptions
109
+ * @see https://tanstack.com/query/latest/docs/framework/react/guides/query-keys
110
+ * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryKey
87
111
  */
88
- queryOptions: TRPCQueryOptions<TDef>;
112
+ infiniteQueryKey: (
113
+ input?: Partial<TDef['input']>,
114
+ ) => DataTag<
115
+ TRPCQueryKey,
116
+ InfiniteData<TDef['output'], number | null>,
117
+ TDef['errorShape']
118
+ >;
89
119
 
90
120
  /**
91
- * Create a set of type-safe infinite query options that can be passed to `useInfiniteQuery`, `prefetchInfiniteQuery` etc.
121
+ * Calculate a TanStack Query Filter for a Infinite Query Procedure
92
122
  *
93
- * @see https://tanstack.com/query/latest/docs/framework/react/reference/infiniteQueryOptions#infinitequeryoptions
94
- * @see https://trpc.io/docs/client/tanstack-react-query/usage#infiniteQueryOptions
123
+ * @see https://tanstack.com/query/latest/docs/framework/react/guides/filters
124
+ * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryFilter
95
125
  */
96
- infiniteQueryOptions: TRPCInfiniteQueryOptions<TDef>;
126
+ infiniteQueryFilter: (
127
+ input?: Partial<TDef['input']>,
128
+ filters?: QueryFilters<
129
+ InfiniteData<TDef['output'], number | null>,
130
+ TDef['errorShape'],
131
+ InfiniteData<TDef['output'], number | null>,
132
+ DataTag<
133
+ TRPCQueryKey,
134
+ InfiniteData<TDef['output'], number | null>,
135
+ TDef['errorShape']
136
+ >
137
+ >,
138
+ ) => WithRequired<
139
+ QueryFilters<
140
+ InfiniteData<TDef['output'], number | null>,
141
+ TDef['errorShape'],
142
+ InfiniteData<TDef['output'], number | null>,
143
+ DataTag<
144
+ TRPCQueryKey,
145
+ InfiniteData<TDef['output'], number | null>,
146
+ TDef['errorShape']
147
+ >
148
+ >,
149
+ 'queryKey'
150
+ >;
151
+ }
152
+ export interface DecorateQueryProcedure<TDef extends ResolverDef>
153
+ extends TypeHelper<TDef>,
154
+ DecorateRouterKeyable {
155
+ /**
156
+ * Create a set of type-safe query options that can be passed to `useQuery`, `prefetchQuery` etc.
157
+ *
158
+ * @see https://tanstack.com/query/latest/docs/framework/react/reference/queryOptions#queryoptions
159
+ * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryOptions
160
+ */
161
+ queryOptions: TRPCQueryOptions<TDef>;
97
162
 
98
163
  /**
99
164
  * Calculate the TanStack Query Key for a Query Procedure
@@ -102,7 +167,7 @@ export interface DecorateQueryProcedure<TDef extends ResolverDef> {
102
167
  * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryKey
103
168
  */
104
169
  queryKey: (
105
- input?: TDef['input'],
170
+ input?: Partial<TDef['input']>,
106
171
  ) => DataTag<TRPCQueryKey, TDef['output'], TDef['errorShape']>;
107
172
 
108
173
  /**
@@ -112,25 +177,26 @@ export interface DecorateQueryProcedure<TDef extends ResolverDef> {
112
177
  * @see https://trpc.io/docs/client/tanstack-react-query/usage#queryFilter
113
178
  */
114
179
  queryFilter: (
115
- input?: TDef['input'],
116
- filters?: QueryFilters<TDef['output'], TDef['errorShape']>,
117
- ) => QueryFilters<
118
- TDef['output'],
119
- TDef['errorShape'],
120
- TDef['output'],
121
- DataTag<TRPCQueryKey, TDef['output'], TDef['errorShape']>
180
+ input?: Partial<TDef['input']>,
181
+ filters?: QueryFilters<
182
+ TDef['output'],
183
+ TDef['errorShape'],
184
+ TDef['output'],
185
+ DataTag<TRPCQueryKey, TDef['output'], TDef['errorShape']>
186
+ >,
187
+ ) => WithRequired<
188
+ QueryFilters<
189
+ TDef['output'],
190
+ TDef['errorShape'],
191
+ TDef['output'],
192
+ DataTag<TRPCQueryKey, TDef['output'], TDef['errorShape']>
193
+ >,
194
+ 'queryKey'
122
195
  >;
123
196
  }
124
197
 
125
- export interface DecorateMutationProcedure<TDef extends ResolverDef> {
126
- /**
127
- * @internal prefer using inferInput and inferOutput to access types
128
- */
129
- '~types': {
130
- input: TDef['input'];
131
- output: TDef['output'];
132
- };
133
-
198
+ export interface DecorateMutationProcedure<TDef extends ResolverDef>
199
+ extends TypeHelper<TDef> {
134
200
  /**
135
201
  * Create a set of type-safe mutation options that can be passed to `useMutation`
136
202
  *
@@ -159,7 +225,10 @@ export type DecorateProcedure<
159
225
  TType extends TRPCProcedureType,
160
226
  TDef extends ResolverDef,
161
227
  > = TType extends 'query'
162
- ? DecorateQueryProcedure<TDef>
228
+ ? DecorateQueryProcedure<TDef> &
229
+ (TDef['input'] extends OptionalCursorInput
230
+ ? DecorateInfiniteQueryProcedure<TDef>
231
+ : Record<string, never>)
163
232
  : TType extends 'mutation'
164
233
  ? DecorateMutationProcedure<TDef>
165
234
  : TType extends 'subscription'
@@ -169,13 +238,13 @@ export type DecorateProcedure<
169
238
  /**
170
239
  * @internal
171
240
  */
172
- export type DecoratedProcedureUtilsRecord<
241
+ export type DecoratedRouterRecord<
173
242
  TRoot extends AnyTRPCRootTypes,
174
243
  TRecord extends TRPCRouterRecord,
175
244
  > = {
176
245
  [TKey in keyof TRecord]: TRecord[TKey] extends infer $Value
177
246
  ? $Value extends TRPCRouterRecord
178
- ? DecoratedProcedureUtilsRecord<TRoot, $Value> & DecorateQueryKeyable
247
+ ? DecoratedRouterRecord<TRoot, $Value> & DecorateRouterKeyable
179
248
  : $Value extends AnyTRPCProcedure
180
249
  ? DecorateProcedure<
181
250
  $Value['_def']['type'],
@@ -191,11 +260,11 @@ export type DecoratedProcedureUtilsRecord<
191
260
  };
192
261
 
193
262
  export type TRPCOptionsProxy<TRouter extends AnyTRPCRouter> =
194
- DecoratedProcedureUtilsRecord<
263
+ DecoratedRouterRecord<
195
264
  TRouter['_def']['_config']['$types'],
196
265
  TRouter['_def']['record']
197
266
  > &
198
- DecorateQueryKeyable;
267
+ DecorateRouterKeyable;
199
268
 
200
269
  export interface TRPCOptionsProxyOptionsBase {
201
270
  queryClient: QueryClient | (() => QueryClient);
@@ -228,19 +297,10 @@ export type TRPCOptionsProxyOptions<TRouter extends AnyTRPCRouter> =
228
297
 
229
298
  type UtilsMethods =
230
299
  | keyof DecorateQueryProcedure<any>
300
+ | keyof DecorateInfiniteQueryProcedure<any>
231
301
  | keyof DecorateMutationProcedure<any>
232
- | keyof DecorateSubscriptionProcedure<any>;
233
-
234
- function getQueryType(method: UtilsMethods) {
235
- const map: Partial<Record<UtilsMethods, QueryType>> = {
236
- queryOptions: 'query',
237
- infiniteQueryOptions: 'infinite',
238
- subscriptionOptions: 'any',
239
- mutationOptions: 'any',
240
- };
241
-
242
- return map[method];
243
- }
302
+ | keyof DecorateSubscriptionProcedure<any>
303
+ | keyof DecorateRouterKeyable;
244
304
 
245
305
  /**
246
306
  * Create a typed proxy from your router types. Can also be used on the server.
@@ -280,45 +340,59 @@ export function createTRPCOptionsProxy<TRouter extends AnyTRPCRouter>(
280
340
  const utilName = path.pop() as UtilsMethods;
281
341
  const [arg1, arg2] = args as any[];
282
342
 
283
- function getQueryKey() {
284
- const queryType = getQueryType(utilName);
285
-
286
- return getQueryKeyInternal(path, arg1, queryType ?? 'any');
287
- }
288
-
289
343
  const contextMap: Record<UtilsMethods, () => unknown> = {
290
344
  '~types': undefined as any,
291
345
 
292
- mutationKey: () => {
293
- return getMutationKeyInternal(path);
346
+ pathKey: () => {
347
+ return getQueryKeyInternal(path);
348
+ },
349
+ pathFilter: (): QueryFilters => {
350
+ return {
351
+ ...arg1,
352
+ queryKey: getQueryKeyInternal(path),
353
+ };
354
+ },
355
+
356
+ queryOptions: () => {
357
+ return trpcQueryOptions({
358
+ input: arg1,
359
+ opts: arg2,
360
+ path,
361
+ queryClient: opts.queryClient,
362
+ queryKey: getQueryKeyInternal(path, arg1, 'query'),
363
+ query: callIt('query'),
364
+ });
294
365
  },
295
366
  queryKey: () => {
296
- return getQueryKey();
367
+ return getQueryKeyInternal(path, arg1, 'query');
297
368
  },
298
369
  queryFilter: (): QueryFilters => {
299
370
  return {
300
371
  ...arg2,
301
- queryKey: getQueryKey(),
372
+ queryKey: getQueryKeyInternal(path, arg1, 'query'),
302
373
  };
303
374
  },
375
+
304
376
  infiniteQueryOptions: () => {
305
377
  return trpcInfiniteQueryOptions({
378
+ input: arg1,
306
379
  opts: arg2,
307
380
  path,
308
381
  queryClient: opts.queryClient,
309
- queryKey: getQueryKey(),
382
+ queryKey: getQueryKeyInternal(path, arg1, 'infinite'),
310
383
  query: callIt('query'),
311
384
  });
312
385
  },
313
- queryOptions: () => {
314
- return trpcQueryOptions({
315
- opts: arg2,
316
- path,
317
- queryClient: opts.queryClient,
318
- queryKey: getQueryKey(),
319
- query: callIt('query'),
320
- });
386
+ infiniteQueryKey: () => {
387
+ return getQueryKeyInternal(path, arg1, 'infinite');
388
+ },
389
+ infiniteQueryFilter: (): QueryFilters => {
390
+ return {
391
+ ...arg2,
392
+ queryKey: getQueryKeyInternal(path, arg1, 'infinite'),
393
+ };
321
394
  },
395
+
322
396
  mutationOptions: () => {
323
397
  return trpcMutationOptions({
324
398
  opts: arg1,
@@ -328,11 +402,15 @@ export function createTRPCOptionsProxy<TRouter extends AnyTRPCRouter>(
328
402
  overrides: opts.overrides?.mutations,
329
403
  });
330
404
  },
405
+ mutationKey: () => {
406
+ return getMutationKeyInternal(path);
407
+ },
408
+
331
409
  subscriptionOptions: () => {
332
410
  return trpcSubscriptionOptions({
333
411
  opts: arg2,
334
412
  path,
335
- queryKey: getQueryKey(),
413
+ queryKey: getQueryKeyInternal(path, arg1, 'any'),
336
414
  subscribe: callIt('subscription'),
337
415
  });
338
416
  },
@@ -206,14 +206,15 @@ type AnyTRPCInfiniteQueryOptionsOut =
206
206
  | UndefinedTRPCInfiniteQueryOptionsOut<unknown, unknown, unknown, unknown>;
207
207
 
208
208
  export function trpcInfiniteQueryOptions(args: {
209
+ input: unknown;
209
210
  query: typeof TRPCUntypedClient.prototype.query;
210
211
  queryClient: QueryClient | (() => QueryClient);
211
212
  path: readonly string[];
212
213
  queryKey: TRPCQueryKey;
213
214
  opts: AnyTRPCInfiniteQueryOptionsIn;
214
215
  }): AnyTRPCInfiniteQueryOptionsOut {
215
- const { query, path, queryKey, opts } = args;
216
- const inputIsSkipToken = queryKey[1]?.input === skipToken;
216
+ const { input, query, path, queryKey, opts } = args;
217
+ const inputIsSkipToken = input === skipToken;
217
218
 
218
219
  const queryFn: QueryFunction<unknown, TRPCQueryKey, unknown> = async (
219
220
  queryFnContext,
@@ -169,16 +169,17 @@ type AnyTRPCQueryOptionsOut =
169
169
  * @internal
170
170
  */
171
171
  export function trpcQueryOptions(args: {
172
+ input: unknown;
172
173
  query: typeof TRPCUntypedClient.prototype.query;
173
174
  queryClient: QueryClient | (() => QueryClient);
174
175
  path: readonly string[];
175
176
  queryKey: TRPCQueryKey;
176
177
  opts: AnyTRPCQueryOptionsIn;
177
178
  }): AnyTRPCQueryOptionsOut {
178
- const { query, path, queryKey, opts } = args;
179
+ const { input, query, path, queryKey, opts } = args;
179
180
  const queryClient = unwrapLazyArg(args.queryClient);
180
181
 
181
- const inputIsSkipToken = queryKey[1]?.input === skipToken;
182
+ const inputIsSkipToken = input === skipToken;
182
183
 
183
184
  const queryFn: QueryFunction<unknown, TRPCQueryKey> = async (
184
185
  queryFnContext,
@@ -1,5 +1,13 @@
1
1
  import type { TRPCRequestOptions } from '@trpc/client';
2
2
 
3
+ /**
4
+ * Turn a set of optional properties into required
5
+ * @internal
6
+ */
7
+ export type WithRequired<TObj, TKey extends keyof TObj> = TObj & {
8
+ [P in TKey]-?: TObj[P];
9
+ };
10
+
3
11
  /**
4
12
  * @internal
5
13
  */
@@ -10,10 +18,16 @@ export type ResolverDef = {
10
18
  errorShape: any;
11
19
  };
12
20
 
21
+ /**
22
+ * @remark `void` is here due to https://github.com/trpc/trpc/pull/4374
23
+ */
24
+ type CursorInput = { cursor?: any };
25
+ export type OptionalCursorInput = CursorInput | void;
26
+
13
27
  /**
14
28
  * @internal
15
29
  */
16
- export type ExtractCursorType<TInput> = TInput extends { cursor?: any }
30
+ export type ExtractCursorType<TInput> = TInput extends CursorInput
17
31
  ? TInput['cursor']
18
32
  : unknown;
19
33
 
@@ -1,5 +1,4 @@
1
- import type { QueryClient } from '@tanstack/react-query';
2
- import { skipToken } from '@tanstack/react-query';
1
+ import { skipToken, type QueryClient } from '@tanstack/react-query';
3
2
  import { isFunction, isObject } from '@trpc/server/unstable-core-do-not-import';
4
3
  import type {
5
4
  QueryType,
@@ -83,8 +82,8 @@ export async function buildQueryFromAsyncIterable(
83
82
  */
84
83
  export function getQueryKeyInternal(
85
84
  path: readonly string[],
86
- input: unknown,
87
- type: QueryType,
85
+ input?: unknown,
86
+ type?: QueryType,
88
87
  ): TRPCQueryKey {
89
88
  // Construct a query key that is easy to destructure and flexible for
90
89
  // partial selecting etc.
@@ -119,6 +118,7 @@ export function getQueryKeyInternal(
119
118
  },
120
119
  ];
121
120
  }
121
+
122
122
  return [
123
123
  splitPath,
124
124
  {