Skip to content

Commit 9eccac6

Browse files
authored
Merge pull request #339 from OpenAPI-Qraft/feat/new-tanstack-querysupport
chore: add TanStack Query `><= 5.79.2` Compatibility Layer
2 parents 7c9d40d + e45cdda commit 9eccac6

18 files changed

Lines changed: 273 additions & 42 deletions

File tree

.changeset/strong-schools-say.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@openapi-qraft/tanstack-query-react-plugin': patch
3+
'@openapi-qraft/tanstack-query-react-types': patch
4+
'@openapi-qraft/react': patch
5+
---
6+
7+
Moved `UseSuspenseInfiniteQueryOptions` type import from `@tanstack/react-query` to `@openapi-qraft/tanstack-query-react-types` and optimized generic parameters order for better compatibility with TanStack Query versions 5.79.2 and earlier.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/package-lock.json
2+
node_modules
3+
/src/api
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "typescript-nodenext-nodenext-tanstack-query-5-79-2",
3+
"description": "This test verifies that the current version of OpenAPI Qraft is compatible with TanStack Query 5.79.2 or earlier, due to the removal of TQueryData for UseSuspenseInfiniteQueryOptions in TanStack Query 5.80.0",
4+
"private": true,
5+
"version": "1.0.0",
6+
"main": "dist/index.js",
7+
"type": "module",
8+
"scripts": {
9+
"build": "tsc",
10+
"codegen": "openapi-qraft --plugin tanstack-query-react --plugin openapi-typescript https://raw.githubusercontent.com/swagger-api/swagger-petstore/7767363b841961221a38c0be9c6b1066a5120051/src/main/resources/openapi.yaml --clean -o src/api --openapi-types-import-path '../schema.js' --explicit-import-extensions --openapi-types-file-name schema.ts",
11+
"e2e:pre-build": "npm run codegen",
12+
"e2e:post-build": "node ./dist/index.js"
13+
},
14+
"dependencies": {
15+
"@openapi-qraft/cli": "latest",
16+
"@openapi-qraft/react": "latest",
17+
"@tanstack/react-query": "5.79.2",
18+
"@tanstack/query-core": "5.79.2",
19+
"@types/node": "latest",
20+
"typescript": "latest"
21+
},
22+
"repository": {
23+
"type": "git",
24+
"url": "https://github.com/OpenAPI-Qraft/openapi-qraft.git"
25+
}
26+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import type { components, paths } from './api/index.js';
2+
import { requestFn } from '@openapi-qraft/react';
3+
import * as callbacksIndex from '@openapi-qraft/react/callbacks';
4+
import * as callbacks from '@openapi-qraft/react/callbacks/index';
5+
import { useMutation } from '@openapi-qraft/react/callbacks/useMutation';
6+
import { useQuery } from '@openapi-qraft/react/callbacks/useQuery';
7+
import {
8+
createSecureRequestFn,
9+
QraftSecureRequestFn,
10+
} from '@openapi-qraft/react/Unstable_QraftSecureRequestFn';
11+
import { QueryClient } from '@tanstack/react-query';
12+
import { createAPIClient as createAPIClientMjs } from './api/index.js';
13+
14+
console.log({} satisfies Partial<components>);
15+
console.log({} satisfies Partial<paths>);
16+
17+
if (typeof createAPIClientMjs !== 'undefined') {
18+
console.log('Client is imported successfully from esm project.');
19+
} else {
20+
console.error('Client is not imported from esm project.');
21+
process.exit(1);
22+
}
23+
24+
if (typeof callbacks !== 'undefined') {
25+
console.log('Callbacks are imported successfully from esm project.');
26+
} else {
27+
console.error('Callbacks are not imported from esm project.');
28+
process.exit(1);
29+
}
30+
31+
if (typeof callbacksIndex !== 'undefined') {
32+
console.log('Callbacks index is imported successfully from esm project.');
33+
} else {
34+
console.error('Callbacks index is not imported from esm project.');
35+
process.exit(1);
36+
}
37+
38+
if (typeof useMutation !== 'undefined') {
39+
console.log('useMutation is imported successfully from esm project.');
40+
} else {
41+
console.error('useMutation is not imported from esm project.');
42+
process.exit(1);
43+
}
44+
45+
if (typeof useQuery !== 'undefined') {
46+
console.log('useQuery is imported successfully from esm project.');
47+
} else {
48+
console.error('useQuery is not imported from esm project.');
49+
process.exit(1);
50+
}
51+
52+
if (typeof createSecureRequestFn !== 'undefined') {
53+
console.log(
54+
'createSecureRequestFn is imported successfully from esm project.'
55+
);
56+
} else {
57+
console.error('createSecureRequestFn is not imported from esm project.');
58+
process.exit(1);
59+
}
60+
61+
if (typeof QraftSecureRequestFn !== 'undefined') {
62+
console.log(
63+
'QraftSecureRequestFn is imported successfully from esm project.'
64+
);
65+
} else {
66+
console.error('QraftSecureRequestFn is not imported from esm project.');
67+
process.exit(1);
68+
}
69+
70+
function useTsCheck() {
71+
const client = createAPIClientMjs({
72+
baseUrl: 'https://api.example.com',
73+
queryClient: new QueryClient(),
74+
requestFn,
75+
});
76+
77+
const query = client.pet.findPetsByStatus.useSuspenseInfiniteQuery(
78+
{},
79+
{
80+
initialPageParam: {
81+
query: {
82+
status: 'sold',
83+
},
84+
},
85+
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
86+
// @ts-expect-error - should not be never or any
87+
lastPageParam.query?.status satisfies never;
88+
lastPageParam.query?.status satisfies
89+
| undefined
90+
| 'sold'
91+
| 'available'
92+
| 'pending';
93+
94+
return lastPageParam.query?.status === 'sold'
95+
? {
96+
query: {
97+
status: 'sold',
98+
},
99+
}
100+
: undefined;
101+
},
102+
}
103+
);
104+
105+
query.data.pages[0] satisfies typeof client.pet.findPetsByStatus.types.data;
106+
// @ts-expect-error - should not be never or any
107+
query.data.pages[0] satisfies never;
108+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"compilerOptions": {
3+
"outDir": "./dist",
4+
"rootDir": "./src",
5+
"target": "es2016",
6+
"module": "NodeNext",
7+
"moduleResolution": "NodeNext",
8+
"esModuleInterop": true,
9+
"forceConsistentCasingInFileNames": true,
10+
"strict": true,
11+
"skipLibCheck": true,
12+
"verbatimModuleSyntax": true
13+
}
14+
}

e2e/projects/typescript-nodenext-nodenext/src/index.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { components, paths } from './api/index.js';
2+
import { requestFn } from '@openapi-qraft/react';
23
import * as callbacksIndex from '@openapi-qraft/react/callbacks';
34
import * as callbacks from '@openapi-qraft/react/callbacks/index';
45
import { useMutation } from '@openapi-qraft/react/callbacks/useMutation';
@@ -7,6 +8,7 @@ import {
78
createSecureRequestFn,
89
QraftSecureRequestFn,
910
} from '@openapi-qraft/react/Unstable_QraftSecureRequestFn';
11+
import { QueryClient } from '@tanstack/react-query';
1012
import { createAPIClient as createAPIClientMjs } from './api/index.js';
1113

1214
console.log({} satisfies Partial<components>);
@@ -64,3 +66,43 @@ if (typeof QraftSecureRequestFn !== 'undefined') {
6466
console.error('QraftSecureRequestFn is not imported from esm project.');
6567
process.exit(1);
6668
}
69+
70+
function useTsCheck() {
71+
const client = createAPIClientMjs({
72+
baseUrl: 'https://api.example.com',
73+
queryClient: new QueryClient(),
74+
requestFn,
75+
});
76+
77+
const query = client.pet.findPetsByStatus.useSuspenseInfiniteQuery(
78+
{},
79+
{
80+
initialPageParam: {
81+
query: {
82+
status: 'sold',
83+
},
84+
},
85+
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
86+
// @ts-expect-error - should not be never or any
87+
lastPageParam.query?.status satisfies never;
88+
lastPageParam.query?.status satisfies
89+
| undefined
90+
| 'sold'
91+
| 'available'
92+
| 'pending';
93+
94+
return lastPageParam.query?.status === 'sold'
95+
? {
96+
query: {
97+
status: 'sold',
98+
},
99+
}
100+
: undefined;
101+
},
102+
}
103+
);
104+
105+
query.data.pages[0] satisfies typeof client.pet.findPetsByStatus.types.data;
106+
// @ts-expect-error - should not be never or any
107+
query.data.pages[0] satisfies never;
108+
}

packages/react-client/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
"@openapi-qraft/rollup-config": "workspace:*",
3030
"@openapi-qraft/tanstack-query-react-plugin": "workspace:*",
3131
"@openapi-qraft/test-fixtures": "workspace:*",
32-
"@tanstack/query-core": "^5.66.3",
33-
"@tanstack/react-query": "^5.66.3",
32+
"@tanstack/query-core": "^5.80.6",
33+
"@tanstack/react-query": "^5.80.6",
3434
"@testing-library/dom": "^10.4.0",
3535
"@testing-library/react": "^16.2.0",
3636
"@types/jscodeshift": "^0.11.11",

packages/react-client/src/callbacks/useQueries.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export const useQueries: (
2929
return useQueriesTanstack(
3030
{
3131
...options,
32-
// @ts-expect-error - Too complex to type
3332
queries: options.queries.map((queryOptions) => {
3433
const optionsWithQueryKey =
3534
'parameters' in queryOptions

packages/tanstack-query-react-plugin/src/__snapshots__/explicit-import-extensions/services/ApprovalPoliciesService.ts.snapshot.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*/
55

66
import type { paths } from "../../openapi.js";
7-
import type { DeepReadonly, InvalidateQueryFilters, MutationFiltersByMutationKey, MutationFiltersByParameters, MutationVariables, OperationError, OperationInfiniteData, PartialParameters, QueryFiltersByParameters, QueryFiltersByQueryKey, QueryFnOptionsByParameters, QueryFnOptionsByQueryKey, RequestFnResponse, ServiceOperationEnsureInfiniteQueryDataOptions, ServiceOperationEnsureQueryDataOptions, ServiceOperationFetchInfiniteQueryOptions, ServiceOperationFetchQueryOptions, ServiceOperationInfiniteQueryKey, ServiceOperationMutationFnOptions, ServiceOperationMutationKey, ServiceOperationQueryKey, ServiceOperationUseMutationOptions, UseQueryOptionsForUseQueries, UseQueryOptionsForUseSuspenseQuery, WithOptional, QraftServiceOperationsToken } from "@openapi-qraft/tanstack-query-react-types";
8-
import type { CancelOptions, DefinedInitialDataInfiniteOptions, DefinedInitialDataOptions, DefinedUseInfiniteQueryResult, DefinedUseQueryResult, InfiniteQueryPageParamsOptions, InvalidateOptions, Mutation, MutationState, NoInfer, QueryState, RefetchOptions, ResetOptions, SetDataOptions, UndefinedInitialDataInfiniteOptions, UndefinedInitialDataOptions, Updater, UseInfiniteQueryResult, UseMutationResult, UseQueryResult, UseSuspenseInfiniteQueryOptions, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
7+
import type { DeepReadonly, InvalidateQueryFilters, MutationFiltersByMutationKey, MutationFiltersByParameters, MutationVariables, OperationError, OperationInfiniteData, PartialParameters, QueryFiltersByParameters, QueryFiltersByQueryKey, QueryFnOptionsByParameters, QueryFnOptionsByQueryKey, RequestFnResponse, ServiceOperationEnsureInfiniteQueryDataOptions, ServiceOperationEnsureQueryDataOptions, ServiceOperationFetchInfiniteQueryOptions, ServiceOperationFetchQueryOptions, ServiceOperationInfiniteQueryKey, ServiceOperationMutationFnOptions, ServiceOperationMutationKey, ServiceOperationQueryKey, ServiceOperationUseMutationOptions, UseQueryOptionsForUseQueries, UseQueryOptionsForUseSuspenseQuery, UseSuspenseInfiniteQueryOptions, WithOptional, QraftServiceOperationsToken } from "@openapi-qraft/tanstack-query-react-types";
8+
import type { CancelOptions, DefinedInitialDataInfiniteOptions, DefinedInitialDataOptions, DefinedUseInfiniteQueryResult, DefinedUseQueryResult, InfiniteQueryPageParamsOptions, InvalidateOptions, Mutation, MutationState, NoInfer, QueryState, RefetchOptions, ResetOptions, SetDataOptions, UndefinedInitialDataInfiniteOptions, UndefinedInitialDataOptions, Updater, UseInfiniteQueryResult, UseMutationResult, UseQueryResult, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
99
export interface ApprovalPoliciesService {
1010
/**
1111
* @summary Get an approval policy by ID
@@ -438,7 +438,7 @@ export interface ApprovalPoliciesService {
438438
* fetchNextPage(); // Fetch the next page
439439
* ```
440440
*/
441-
useSuspenseInfiniteQuery<TPageParam extends GetApprovalPoliciesIdParameters, TData = GetApprovalPoliciesIdData>(parameters: ServiceOperationInfiniteQueryKey<GetApprovalPoliciesIdSchema, GetApprovalPoliciesIdParameters> | (DeepReadonly<GetApprovalPoliciesIdParameters>), options: Omit<UseSuspenseInfiniteQueryOptions<GetApprovalPoliciesIdData, GetApprovalPoliciesIdError, OperationInfiniteData<TData, GetApprovalPoliciesIdParameters>, GetApprovalPoliciesIdData, ServiceOperationInfiniteQueryKey<GetApprovalPoliciesIdSchema, GetApprovalPoliciesIdParameters>, PartialParameters<DeepReadonly<TPageParam>>>, "queryKey" | "getPreviousPageParam" | "getNextPageParam" | "initialPageParam"> & InfiniteQueryPageParamsOptions<GetApprovalPoliciesIdData, PartialParameters<DeepReadonly<TPageParam>>>): UseSuspenseInfiniteQueryResult<OperationInfiniteData<TData, GetApprovalPoliciesIdParameters>, OperationError<GetApprovalPoliciesIdError>>;
441+
useSuspenseInfiniteQuery<TPageParam extends GetApprovalPoliciesIdParameters, TData = GetApprovalPoliciesIdData>(parameters: ServiceOperationInfiniteQueryKey<GetApprovalPoliciesIdSchema, GetApprovalPoliciesIdParameters> | (DeepReadonly<GetApprovalPoliciesIdParameters>), options: Omit<UseSuspenseInfiniteQueryOptions<GetApprovalPoliciesIdData, GetApprovalPoliciesIdError, OperationInfiniteData<TData, GetApprovalPoliciesIdParameters>, ServiceOperationInfiniteQueryKey<GetApprovalPoliciesIdSchema, GetApprovalPoliciesIdParameters>, PartialParameters<DeepReadonly<TPageParam>>>, "queryKey" | "getPreviousPageParam" | "getNextPageParam" | "initialPageParam"> & InfiniteQueryPageParamsOptions<GetApprovalPoliciesIdData, PartialParameters<DeepReadonly<TPageParam>>>): UseSuspenseInfiniteQueryResult<OperationInfiniteData<TData, GetApprovalPoliciesIdParameters>, OperationError<GetApprovalPoliciesIdError>>;
442442
/**
443443
* Allows you to execute multiple asynchronous data fetching operations concurrently with Suspense support.
444444
* Similar to useQueries but integrates with React Suspense for loading states.

packages/tanstack-query-react-plugin/src/__snapshots__/explicit-import-extensions/services/FilesService.ts.snapshot.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
*/
55

66
import type { paths } from "../../openapi.js";
7-
import type { DeepReadonly, InvalidateQueryFilters, MutationFiltersByMutationKey, MutationFiltersByParameters, MutationVariables, OperationError, OperationInfiniteData, PartialParameters, QueryFiltersByParameters, QueryFiltersByQueryKey, QueryFnOptionsByParameters, QueryFnOptionsByQueryKey, RequestFnResponse, ServiceOperationEnsureInfiniteQueryDataOptions, ServiceOperationEnsureQueryDataOptions, ServiceOperationFetchInfiniteQueryOptions, ServiceOperationFetchQueryOptions, ServiceOperationInfiniteQueryKey, ServiceOperationMutationFnOptions, ServiceOperationMutationKey, ServiceOperationQueryKey, ServiceOperationUseMutationOptions, UseQueryOptionsForUseQueries, UseQueryOptionsForUseSuspenseQuery, WithOptional, QraftServiceOperationsToken } from "@openapi-qraft/tanstack-query-react-types";
8-
import type { CancelOptions, DefinedInitialDataInfiniteOptions, DefinedInitialDataOptions, DefinedUseInfiniteQueryResult, DefinedUseQueryResult, InfiniteQueryPageParamsOptions, InvalidateOptions, Mutation, MutationState, NoInfer, QueryState, RefetchOptions, ResetOptions, SetDataOptions, UndefinedInitialDataInfiniteOptions, UndefinedInitialDataOptions, Updater, UseInfiniteQueryResult, UseMutationResult, UseQueryResult, UseSuspenseInfiniteQueryOptions, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
7+
import type { DeepReadonly, InvalidateQueryFilters, MutationFiltersByMutationKey, MutationFiltersByParameters, MutationVariables, OperationError, OperationInfiniteData, PartialParameters, QueryFiltersByParameters, QueryFiltersByQueryKey, QueryFnOptionsByParameters, QueryFnOptionsByQueryKey, RequestFnResponse, ServiceOperationEnsureInfiniteQueryDataOptions, ServiceOperationEnsureQueryDataOptions, ServiceOperationFetchInfiniteQueryOptions, ServiceOperationFetchQueryOptions, ServiceOperationInfiniteQueryKey, ServiceOperationMutationFnOptions, ServiceOperationMutationKey, ServiceOperationQueryKey, ServiceOperationUseMutationOptions, UseQueryOptionsForUseQueries, UseQueryOptionsForUseSuspenseQuery, UseSuspenseInfiniteQueryOptions, WithOptional, QraftServiceOperationsToken } from "@openapi-qraft/tanstack-query-react-types";
8+
import type { CancelOptions, DefinedInitialDataInfiniteOptions, DefinedInitialDataOptions, DefinedUseInfiniteQueryResult, DefinedUseQueryResult, InfiniteQueryPageParamsOptions, InvalidateOptions, Mutation, MutationState, NoInfer, QueryState, RefetchOptions, ResetOptions, SetDataOptions, UndefinedInitialDataInfiniteOptions, UndefinedInitialDataOptions, Updater, UseInfiniteQueryResult, UseMutationResult, UseQueryResult, UseSuspenseInfiniteQueryResult, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
99
export interface FilesService {
1010
/** @summary Get a files by ID */
1111
getFiles: {
@@ -315,7 +315,7 @@ export interface FilesService {
315315
* fetchNextPage(); // Fetch the next page
316316
* ```
317317
*/
318-
useSuspenseInfiniteQuery<TPageParam extends GetFilesParameters, TData = GetFilesData>(parameters: ServiceOperationInfiniteQueryKey<GetFilesSchema, GetFilesParameters> | (DeepReadonly<GetFilesParameters>), options: Omit<UseSuspenseInfiniteQueryOptions<GetFilesData, GetFilesError, OperationInfiniteData<TData, GetFilesParameters>, GetFilesData, ServiceOperationInfiniteQueryKey<GetFilesSchema, GetFilesParameters>, PartialParameters<DeepReadonly<TPageParam>>>, "queryKey" | "getPreviousPageParam" | "getNextPageParam" | "initialPageParam"> & InfiniteQueryPageParamsOptions<GetFilesData, PartialParameters<DeepReadonly<TPageParam>>>): UseSuspenseInfiniteQueryResult<OperationInfiniteData<TData, GetFilesParameters>, OperationError<GetFilesError>>;
318+
useSuspenseInfiniteQuery<TPageParam extends GetFilesParameters, TData = GetFilesData>(parameters: ServiceOperationInfiniteQueryKey<GetFilesSchema, GetFilesParameters> | (DeepReadonly<GetFilesParameters>), options: Omit<UseSuspenseInfiniteQueryOptions<GetFilesData, GetFilesError, OperationInfiniteData<TData, GetFilesParameters>, ServiceOperationInfiniteQueryKey<GetFilesSchema, GetFilesParameters>, PartialParameters<DeepReadonly<TPageParam>>>, "queryKey" | "getPreviousPageParam" | "getNextPageParam" | "initialPageParam"> & InfiniteQueryPageParamsOptions<GetFilesData, PartialParameters<DeepReadonly<TPageParam>>>): UseSuspenseInfiniteQueryResult<OperationInfiniteData<TData, GetFilesParameters>, OperationError<GetFilesError>>;
319319
/**
320320
* Allows you to execute multiple asynchronous data fetching operations concurrently with Suspense support.
321321
* Similar to useQueries but integrates with React Suspense for loading states.
@@ -1148,7 +1148,7 @@ export interface FilesService {
11481148
* fetchNextPage(); // Fetch the next page
11491149
* ```
11501150
*/
1151-
useSuspenseInfiniteQuery<TPageParam extends GetFileListParameters, TData = GetFileListData>(parameters: ServiceOperationInfiniteQueryKey<GetFileListSchema, GetFileListParameters> | (DeepReadonly<GetFileListParameters> | void), options: Omit<UseSuspenseInfiniteQueryOptions<GetFileListData, GetFileListError, OperationInfiniteData<TData, GetFileListParameters>, GetFileListData, ServiceOperationInfiniteQueryKey<GetFileListSchema, GetFileListParameters>, PartialParameters<DeepReadonly<TPageParam>>>, "queryKey" | "getPreviousPageParam" | "getNextPageParam" | "initialPageParam"> & InfiniteQueryPageParamsOptions<GetFileListData, PartialParameters<DeepReadonly<TPageParam>>>): UseSuspenseInfiniteQueryResult<OperationInfiniteData<TData, GetFileListParameters>, OperationError<GetFileListError>>;
1151+
useSuspenseInfiniteQuery<TPageParam extends GetFileListParameters, TData = GetFileListData>(parameters: ServiceOperationInfiniteQueryKey<GetFileListSchema, GetFileListParameters> | (DeepReadonly<GetFileListParameters> | void), options: Omit<UseSuspenseInfiniteQueryOptions<GetFileListData, GetFileListError, OperationInfiniteData<TData, GetFileListParameters>, ServiceOperationInfiniteQueryKey<GetFileListSchema, GetFileListParameters>, PartialParameters<DeepReadonly<TPageParam>>>, "queryKey" | "getPreviousPageParam" | "getNextPageParam" | "initialPageParam"> & InfiniteQueryPageParamsOptions<GetFileListData, PartialParameters<DeepReadonly<TPageParam>>>): UseSuspenseInfiniteQueryResult<OperationInfiniteData<TData, GetFileListParameters>, OperationError<GetFileListError>>;
11521152
/**
11531153
* Allows you to execute multiple asynchronous data fetching operations concurrently with Suspense support.
11541154
* Similar to useQueries but integrates with React Suspense for loading states.

0 commit comments

Comments
 (0)