Skip to content

Commit 3300499

Browse files
authored
feat: infinite query support for tanstack-query (#679)
1 parent 1564fe3 commit 3300499

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

packages/plugins/tanstack-query/src/generator.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,19 @@ function generateQueryHook(
6262
optionalInput: boolean,
6363
overrideReturnType?: string,
6464
overrideInputType?: string,
65-
overrideTypeParameters?: string[]
65+
overrideTypeParameters?: string[],
66+
infinite = false
6667
) {
6768
const capOperation = upperCaseFirst(operation);
6869

6970
const argsType = overrideInputType ?? `Prisma.${model}${capOperation}Args`;
7071
const inputType = `Prisma.SelectSubset<T, ${argsType}>`;
7172
const returnType =
7273
overrideReturnType ?? (returnArray ? `Array<Prisma.${model}GetPayload<T>>` : `Prisma.${model}GetPayload<T>`);
73-
const optionsType = makeQueryOptions(target, returnType);
74+
const optionsType = makeQueryOptions(target, returnType, infinite);
7475

7576
const func = sf.addFunction({
76-
name: `use${capOperation}${model}`,
77+
name: `use${infinite ? 'Infinite' : ''}${capOperation}${model}`,
7778
typeParameters: overrideTypeParameters ?? [`T extends ${argsType}`],
7879
parameters: [
7980
{
@@ -90,7 +91,7 @@ function generateQueryHook(
9091

9192
func.addStatements([
9293
makeGetContext(target),
93-
`return query<${returnType}>('${model}', \`\${endpoint}/${lowerCaseFirst(
94+
`return ${infinite ? 'infiniteQuery' : 'query'}<${returnType}>('${model}', \`\${endpoint}/${lowerCaseFirst(
9495
model
9596
)}/${operation}\`, args, options, fetch);`,
9697
]);
@@ -248,7 +249,10 @@ function generateModelHooks(
248249

249250
// findMany
250251
if (mapping.findMany) {
252+
// regular findMany
251253
generateQueryHook(target, sf, model.name, 'findMany', true, true);
254+
// infinite findMany
255+
generateQueryHook(target, sf, model.name, 'findMany', true, true, undefined, undefined, undefined, true);
252256
}
253257

254258
// findUnique
@@ -431,22 +435,22 @@ function makeGetContext(target: TargetFramework) {
431435

432436
function makeBaseImports(target: TargetFramework) {
433437
const shared = [
434-
`import { query, postMutation, putMutation, deleteMutation } from '@zenstackhq/tanstack-query/runtime/${target}';`,
438+
`import { query, infiniteQuery, postMutation, putMutation, deleteMutation } from '@zenstackhq/tanstack-query/runtime/${target}';`,
435439
`import type { PickEnumerable, CheckSelect } from '@zenstackhq/tanstack-query/runtime';`,
436440
];
437441
switch (target) {
438442
case 'react':
439443
return [
440444
`import { useContext } from 'react';`,
441-
`import type { UseMutationOptions, UseQueryOptions } from '@tanstack/react-query';`,
445+
`import type { UseMutationOptions, UseQueryOptions, UseInfiniteQueryOptions } from '@tanstack/react-query';`,
442446
`import { RequestHandlerContext } from '@zenstackhq/tanstack-query/runtime/${target}';`,
443447
...shared,
444448
];
445449
case 'svelte':
446450
return [
447451
`import { getContext } from 'svelte';`,
448452
`import { derived } from 'svelte/store';`,
449-
`import type { MutationOptions, QueryOptions } from '@tanstack/svelte-query';`,
453+
`import type { MutationOptions, QueryOptions, CreateInfiniteQueryOptions } from '@tanstack/svelte-query';`,
450454
`import { SvelteQueryContextKey, type RequestHandlerContext } from '@zenstackhq/tanstack-query/runtime/${target}';`,
451455
...shared,
452456
];
@@ -455,12 +459,12 @@ function makeBaseImports(target: TargetFramework) {
455459
}
456460
}
457461

458-
function makeQueryOptions(target: string, returnType: string) {
462+
function makeQueryOptions(target: string, returnType: string, infinite: boolean) {
459463
switch (target) {
460464
case 'react':
461-
return `UseQueryOptions<${returnType}>`;
465+
return `Use${infinite ? 'Infinite' : ''}QueryOptions<${returnType}>`;
462466
case 'svelte':
463-
return `QueryOptions<${returnType}>`;
467+
return `${infinite ? 'CreateInfinite' : ''}QueryOptions<${returnType}>`;
464468
default:
465469
throw new PluginError(name, `Unsupported target: ${target}`);
466470
}

packages/plugins/tanstack-query/src/runtime/react.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import {
3+
useInfiniteQuery,
34
useMutation,
45
useQuery,
56
useQueryClient,
67
type MutateFunction,
78
type QueryClient,
9+
type UseInfiniteQueryOptions,
810
type UseMutationOptions,
911
type UseQueryOptions,
1012
} from '@tanstack/react-query';
@@ -41,7 +43,6 @@ export const Provider = RequestHandlerContext.Provider;
4143
* @param options The react-query options object
4244
* @returns useQuery hook
4345
*/
44-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
4546
export function query<R>(model: string, url: string, args?: unknown, options?: UseQueryOptions<R>, fetch?: FetchFn) {
4647
const reqUrl = makeUrl(url, args);
4748
return useQuery<R>({
@@ -51,6 +52,31 @@ export function query<R>(model: string, url: string, args?: unknown, options?: U
5152
});
5253
}
5354

55+
/**
56+
* Creates a react-query infinite query.
57+
*
58+
* @param model The name of the model under query.
59+
* @param url The request URL.
60+
* @param args The initial request args object, URL-encoded and appended as "?q=" parameter
61+
* @param options The react-query infinite query options object
62+
* @returns useInfiniteQuery hook
63+
*/
64+
export function infiniteQuery<R>(
65+
model: string,
66+
url: string,
67+
args?: unknown,
68+
options?: UseInfiniteQueryOptions<R>,
69+
fetch?: FetchFn
70+
) {
71+
return useInfiniteQuery<R>({
72+
queryKey: [QUERY_KEY_PREFIX + model, url, args],
73+
queryFn: ({ pageParam }) => {
74+
return fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false);
75+
},
76+
...options,
77+
});
78+
}
79+
5480
/**
5581
* Creates a POST mutation with react-query.
5682
*

packages/plugins/tanstack-query/src/runtime/svelte.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import {
3+
createInfiniteQuery,
34
createMutation,
45
createQuery,
56
useQueryClient,
7+
type CreateInfiniteQueryOptions,
68
type MutateFunction,
79
type MutationOptions,
810
type QueryClient,
@@ -26,7 +28,6 @@ export const SvelteQueryContextKey = 'zenstack-svelte-query-context';
2628
* @param options The svelte-query options object
2729
* @returns useQuery hook
2830
*/
29-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
3031
export function query<R>(model: string, url: string, args?: unknown, options?: QueryOptions<R>, fetch?: FetchFn) {
3132
const reqUrl = makeUrl(url, args);
3233
return createQuery<R>({
@@ -36,6 +37,29 @@ export function query<R>(model: string, url: string, args?: unknown, options?: Q
3637
});
3738
}
3839

40+
/**
41+
* Creates a svelte-query infinite query.
42+
*
43+
* @param model The name of the model under query.
44+
* @param url The request URL.
45+
* @param args The initial request args object, URL-encoded and appended as "?q=" parameter
46+
* @param options The svelte-query infinite query options object
47+
* @returns useQuery hook
48+
*/
49+
export function infiniteQuery<R>(
50+
model: string,
51+
url: string,
52+
args?: unknown,
53+
options?: CreateInfiniteQueryOptions<R>,
54+
fetch?: FetchFn
55+
) {
56+
return createInfiniteQuery<R>({
57+
queryKey: [QUERY_KEY_PREFIX + model, url, args],
58+
queryFn: ({ pageParam }) => fetcher<R, false>(makeUrl(url, pageParam ?? args), undefined, fetch, false),
59+
...options,
60+
});
61+
}
62+
3963
/**
4064
* Creates a POST mutation with svelte-query.
4165
*

0 commit comments

Comments
 (0)