@suspensive/react-query-4 3.18.0 → 3.19.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/dist/{IsFetching-CThOxeZB.d.cts → IsFetching-CmAXgxBe.d.cts} +3 -3
- package/dist/{IsFetching-CThOxeZB.d.cts.map → IsFetching-CmAXgxBe.d.cts.map} +1 -1
- package/dist/IsFetching.d.cts +1 -1
- package/dist/{PrefetchInfiniteQuery-C4FsMPPo.d.cts → PrefetchInfiniteQuery-BewcG5rR.d.cts} +3 -3
- package/dist/{PrefetchInfiniteQuery-C4FsMPPo.d.cts.map → PrefetchInfiniteQuery-BewcG5rR.d.cts.map} +1 -1
- package/dist/PrefetchInfiniteQuery.d.cts +1 -1
- package/dist/{PrefetchQuery-DFwiRhmK.d.cts → PrefetchQuery-C3h9DidM.d.cts} +3 -3
- package/dist/{PrefetchQuery-DFwiRhmK.d.cts.map → PrefetchQuery-C3h9DidM.d.cts.map} +1 -1
- package/dist/PrefetchQuery.d.cts +1 -1
- package/dist/{QueriesHydration-BrMSJHsz.mjs → QueriesHydration-27lFZeB8.mjs} +18 -4
- package/dist/QueriesHydration-27lFZeB8.mjs.map +1 -0
- package/dist/{QueriesHydration-BARmyHJu.cjs → QueriesHydration-BYKU-Mte.cjs} +18 -4
- package/dist/QueriesHydration-BYKU-Mte.cjs.map +1 -0
- package/dist/{QueriesHydration-M2zoVGgJ.d.mts → QueriesHydration-BeMkJU3l.d.mts} +8 -1
- package/dist/QueriesHydration-BeMkJU3l.d.mts.map +1 -0
- package/dist/{QueriesHydration-99AzKj29.d.cts → QueriesHydration-DQiuolCU.d.cts} +10 -3
- package/dist/QueriesHydration-DQiuolCU.d.cts.map +1 -0
- package/dist/QueriesHydration.cjs +1 -1
- package/dist/QueriesHydration.d.cts +1 -1
- package/dist/QueriesHydration.d.mts +1 -1
- package/dist/QueriesHydration.mjs +1 -1
- package/dist/{QueryClientConsumer-BGHJsJCv.d.cts → QueryClientConsumer-D3h25GmM.d.cts} +3 -3
- package/dist/{QueryClientConsumer-BGHJsJCv.d.cts.map → QueryClientConsumer-D3h25GmM.d.cts.map} +1 -1
- package/dist/QueryClientConsumer.d.cts +1 -1
- package/dist/{SuspenseInfiniteQuery-BwSKmJgm.d.cts → SuspenseInfiniteQuery-CBf92CTq.d.cts} +3 -3
- package/dist/{SuspenseInfiniteQuery-BwSKmJgm.d.cts.map → SuspenseInfiniteQuery-CBf92CTq.d.cts.map} +1 -1
- package/dist/SuspenseInfiniteQuery.d.cts +1 -1
- package/dist/{SuspenseQueries-B-UR1dnn.d.cts → SuspenseQueries-wO-fCk30.d.cts} +3 -3
- package/dist/{SuspenseQueries-B-UR1dnn.d.cts.map → SuspenseQueries-wO-fCk30.d.cts.map} +1 -1
- package/dist/SuspenseQueries.d.cts +1 -1
- package/dist/{SuspenseQuery-BT6EsguP.d.cts → SuspenseQuery-DzwOaqvu.d.cts} +3 -3
- package/dist/{SuspenseQuery-BT6EsguP.d.cts.map → SuspenseQuery-DzwOaqvu.d.cts.map} +1 -1
- package/dist/SuspenseQuery.d.cts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
- package/src/QueriesHydration.spec.tsx +38 -1
- package/src/QueriesHydration.tsx +25 -1
- package/dist/QueriesHydration-99AzKj29.d.cts.map +0 -1
- package/dist/QueriesHydration-BARmyHJu.cjs.map +0 -1
- package/dist/QueriesHydration-BrMSJHsz.mjs.map +0 -1
- package/dist/QueriesHydration-M2zoVGgJ.d.mts.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime7 from "react/jsx-runtime";
|
|
2
2
|
import { QueryFilters, useIsFetching } from "@tanstack/react-query";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ declare const IsFetching: ({
|
|
|
10
10
|
children
|
|
11
11
|
}: QueryFilters & {
|
|
12
12
|
children: (isFetching: ReturnType<typeof useIsFetching>) => ReactNode;
|
|
13
|
-
}) =>
|
|
13
|
+
}) => react_jsx_runtime7.JSX.Element;
|
|
14
14
|
//#endregion
|
|
15
15
|
export { IsFetching as t };
|
|
16
|
-
//# sourceMappingURL=IsFetching-
|
|
16
|
+
//# sourceMappingURL=IsFetching-CmAXgxBe.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IsFetching-
|
|
1
|
+
{"version":3,"file":"IsFetching-CmAXgxBe.d.cts","names":[],"sources":["../src/IsFetching.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAQa,cAAA,UAIZ,EAAA,CAAA;EAAA;CAAA,EAFE,YAEF,GAAA;EAJ0B,QAAA,EAAA,CAAA,UAAA,EAEgB,UAFhB,CAAA,OAEkC,aAFlC,CAAA,EAAA,GAEqD,SAFrD;CAExB,EAAA,GAAwF,kBAAA,CAAA,GAAA,CAAA,OAAxF"}
|
package/dist/IsFetching.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as IsFetching } from "./IsFetching-
|
|
1
|
+
import { t as IsFetching } from "./IsFetching-CmAXgxBe.cjs";
|
|
2
2
|
export { IsFetching };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
2
|
import { FetchInfiniteQueryOptions, QueryKey } from "@tanstack/react-query";
|
|
3
3
|
|
|
4
4
|
//#region src/PrefetchInfiniteQuery.d.ts
|
|
@@ -11,7 +11,7 @@ import { FetchInfiniteQueryOptions, QueryKey } from "@tanstack/react-query";
|
|
|
11
11
|
* <PrefetchInfiniteQuery queryKey={['queryKey']} queryFn={queryFn} />
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
|
-
declare function PrefetchInfiniteQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>):
|
|
14
|
+
declare function PrefetchInfiniteQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: FetchInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey>): react_jsx_runtime0.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { PrefetchInfiniteQuery as t };
|
|
17
|
-
//# sourceMappingURL=PrefetchInfiniteQuery-
|
|
17
|
+
//# sourceMappingURL=PrefetchInfiniteQuery-BewcG5rR.d.cts.map
|
package/dist/{PrefetchInfiniteQuery-C4FsMPPo.d.cts.map → PrefetchInfiniteQuery-BewcG5rR.d.cts.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrefetchInfiniteQuery-
|
|
1
|
+
{"version":3,"file":"PrefetchInfiniteQuery-BewcG5rR.d.cts","names":[],"sources":["../src/PrefetchInfiniteQuery.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAaA;;;;;AAKmD,iBALnC,qBAKmC,CAAA,eAAA,OAAA,EAAA,SAAA,OAAA,EAAA,QAFzC,YAEyC,EAAA,kBAD/B,QAC+B,GADpB,QACoB,CAAA,CAAA,OAAA,EAAxC,yBAAwC,CAAd,YAAc,EAAA,MAAA,EAAQ,KAAR,EAAe,SAAf,CAAA,CAAA,EAAyB,kBAAA,CAAA,GAAA,CAAA,OAAzB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as PrefetchInfiniteQuery } from "./PrefetchInfiniteQuery-
|
|
1
|
+
import { t as PrefetchInfiniteQuery } from "./PrefetchInfiniteQuery-BewcG5rR.cjs";
|
|
2
2
|
export { PrefetchInfiniteQuery };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime1 from "react/jsx-runtime";
|
|
2
2
|
import { FetchQueryOptions, QueryKey } from "@tanstack/react-query";
|
|
3
3
|
|
|
4
4
|
//#region src/PrefetchQuery.d.ts
|
|
@@ -11,7 +11,7 @@ import { FetchQueryOptions, QueryKey } from "@tanstack/react-query";
|
|
|
11
11
|
* <PrefetchQuery queryKey={['queryKey']} queryFn={queryFn} />
|
|
12
12
|
* ```
|
|
13
13
|
*/
|
|
14
|
-
declare function PrefetchQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>):
|
|
14
|
+
declare function PrefetchQuery<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(options: FetchQueryOptions<TQueryFnData, TError, TData, TQueryKey>): react_jsx_runtime1.JSX.Element;
|
|
15
15
|
//#endregion
|
|
16
16
|
export { PrefetchQuery as t };
|
|
17
|
-
//# sourceMappingURL=PrefetchQuery-
|
|
17
|
+
//# sourceMappingURL=PrefetchQuery-C3h9DidM.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PrefetchQuery-
|
|
1
|
+
{"version":3,"file":"PrefetchQuery-C3h9DidM.d.cts","names":[],"sources":["../src/PrefetchQuery.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAaA;;;;;AAK2C,iBAL3B,aAK2B,CAAA,eAAA,OAAA,EAAA,SAAA,OAAA,EAAA,QAFjC,YAEiC,EAAA,kBADvB,QACuB,GADZ,QACY,CAAA,CAAA,OAAA,EAAhC,iBAAgC,CAAd,YAAc,EAAA,MAAA,EAAQ,KAAR,EAAe,SAAf,CAAA,CAAA,EAAyB,kBAAA,CAAA,GAAA,CAAA,OAAzB"}
|
package/dist/PrefetchQuery.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as PrefetchQuery } from "./PrefetchQuery-
|
|
1
|
+
import { t as PrefetchQuery } from "./PrefetchQuery-C3h9DidM.cjs";
|
|
2
2
|
export { PrefetchQuery };
|
|
@@ -36,7 +36,8 @@ const _excluded = [
|
|
|
36
36
|
"queries",
|
|
37
37
|
"children",
|
|
38
38
|
"queryClient",
|
|
39
|
-
"skipSsrOnError"
|
|
39
|
+
"skipSsrOnError",
|
|
40
|
+
"timeout"
|
|
40
41
|
];
|
|
41
42
|
/**
|
|
42
43
|
* A server component that fetches multiple queries on the server and hydrates them to the client.
|
|
@@ -107,10 +108,14 @@ function QueriesHydration(_x) {
|
|
|
107
108
|
}
|
|
108
109
|
function _QueriesHydration() {
|
|
109
110
|
_QueriesHydration = _asyncToGenerator(function* (_ref) {
|
|
110
|
-
let { queries, children, queryClient = new QueryClient(), skipSsrOnError = true } = _ref, props = _objectWithoutProperties(_ref, _excluded);
|
|
111
|
+
let { queries, children, queryClient = new QueryClient(), skipSsrOnError = true, timeout } = _ref, props = _objectWithoutProperties(_ref, _excluded);
|
|
112
|
+
const timeoutController = timeout != null && timeout >= 0 ? createTimeoutController(timeout, `QueriesHydration: timeout after ${timeout} ms)`) : void 0;
|
|
111
113
|
try {
|
|
112
|
-
|
|
114
|
+
const queriesPromise = Promise.all(queries.map((query) => "getNextPageParam" in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)));
|
|
115
|
+
yield timeoutController != null ? Promise.race([queriesPromise, timeoutController.promise]) : queriesPromise;
|
|
116
|
+
timeoutController === null || timeoutController === void 0 || timeoutController.clear();
|
|
113
117
|
} catch (_unused) {
|
|
118
|
+
timeoutController === null || timeoutController === void 0 || timeoutController.clear();
|
|
114
119
|
if (skipSsrOnError) return /* @__PURE__ */ jsx(ClientOnly, {
|
|
115
120
|
fallback: skipSsrOnError === true ? void 0 : skipSsrOnError.fallback,
|
|
116
121
|
children
|
|
@@ -123,7 +128,16 @@ function _QueriesHydration() {
|
|
|
123
128
|
});
|
|
124
129
|
return _QueriesHydration.apply(this, arguments);
|
|
125
130
|
}
|
|
131
|
+
const createTimeoutController = (ms, errorMessage) => {
|
|
132
|
+
let timerId;
|
|
133
|
+
return {
|
|
134
|
+
promise: new Promise((_, reject) => {
|
|
135
|
+
timerId = setTimeout(() => reject(new Error(errorMessage)), ms);
|
|
136
|
+
}),
|
|
137
|
+
clear: () => timerId != null && clearTimeout(timerId)
|
|
138
|
+
};
|
|
139
|
+
};
|
|
126
140
|
|
|
127
141
|
//#endregion
|
|
128
142
|
export { QueriesHydration as t };
|
|
129
|
-
//# sourceMappingURL=QueriesHydration-
|
|
143
|
+
//# sourceMappingURL=QueriesHydration-27lFZeB8.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueriesHydration-27lFZeB8.mjs","names":["timerId: ReturnType<typeof setTimeout> | undefined"],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":["import {\n Hydrate,\n type HydrateProps,\n type OmitKeyof,\n QueryClient,\n type QueryOptions,\n type UseInfiniteQueryOptions,\n type WithRequired,\n dehydrate,\n} from '@tanstack/react-query'\nimport type { ReactNode } from 'react'\nimport { ClientOnly } from './components/ClientOnly'\n\n/**\n * A server component that fetches multiple queries on the server and hydrates them to the client.\n *\n * @experimental This component is experimental and may be changed or removed in the future.\n *\n * @description\n * QueriesHydration is designed for React Server Components (RSC).\n * It pre-fetches multiple queries on the server side and automatically hydrates\n * the data to the client, enabling seamless data synchronization between server and client.\n *\n * When errors occur during server-side fetching, the component gracefully falls back\n * to client-side rendering, ensuring your application remains resilient.\n *\n * @example\n * ```tsx\n * // app/page.tsx (Server Component)\n * import { Suspense } from 'react'\n * import { QueriesHydration } from '@suspensive/react-query'\n * import { queryOptions } from '@tanstack/react-query'\n *\n * const userQueryOptions = (userId: string) => queryOptions({\n * queryKey: ['user', userId],\n * queryFn: () => fetchUser(userId)\n * })\n *\n * const postsQueryOptions = () => queryOptions({\n * queryKey: ['posts'],\n * queryFn: () => fetchPosts()\n * })\n *\n * export default function Page({ userId }: { userId: string }) {\n * return (\n * <>\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration queries={[userQueryOptions(userId)]}>\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n *\n * <Suspense fallback={<div>Loading posts...</div>}>\n * <QueriesHydration queries={[postsQueryOptions()]}>\n * <PostsList />\n * </QueriesHydration>\n * </Suspense>\n * </>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom error fallback\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration\n * queries={[userQueryOptions(userId)]}\n * skipSsrOnError={{ fallback: <div>Fetching on client...</div> }}\n * >\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n * ```\n *\n * @see {@link https://suspensive.org/docs/react-query/QueriesHydration Documentation}\n */\nexport async function QueriesHydration({\n queries,\n children,\n queryClient = new QueryClient(),\n skipSsrOnError = true,\n timeout,\n ...props\n}: {\n /**\n * The QueryClient instance to use for fetching queries.\n */\n queryClient?: QueryClient\n /**\n * An array of query options or infinite query options to be fetched on the server. Each query must include a `queryKey`.\n * You can mix regular queries and infinite queries in the same array.\n */\n queries: (\n | WithRequired<QueryOptions<any, any, any, any>, 'queryKey'>\n | WithRequired<UseInfiniteQueryOptions<any, any, any, any, any>, 'queryKey'>\n )[]\n /**\n * Controls error handling behavior:\n * - `true` (default): Skips SSR and falls back to client-side rendering when server fetch fails\n * - `false`: Proceeds with SSR without hydration (retry fetching on client component server rendering)\n * - `{ fallback: ReactNode }`: Skips SSR with custom fallback UI during client-side rendering\n */\n skipSsrOnError?:\n | boolean\n | {\n fallback: ReactNode\n }\n /**\n * The timeout in milliseconds for the query.\n * If the query takes longer than the timeout, it will be considered as an error.\n * When not set, no timeout is applied.\n */\n timeout?: number\n} & OmitKeyof<HydrateProps, 'state'>) {\n const timeoutController =\n timeout != null && timeout >= 0\n ? createTimeoutController(timeout, `QueriesHydration: timeout after ${timeout} ms)`)\n : undefined\n try {\n const queriesPromise = Promise.all(\n queries.map((query) =>\n 'getNextPageParam' in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)\n )\n )\n await (timeoutController != null ? Promise.race([queriesPromise, timeoutController.promise]) : queriesPromise)\n timeoutController?.clear()\n } catch {\n timeoutController?.clear()\n if (skipSsrOnError) {\n return (\n <ClientOnly fallback={skipSsrOnError === true ? undefined : skipSsrOnError.fallback}>{children}</ClientOnly>\n )\n }\n }\n return (\n <Hydrate {...props} state={dehydrate(queryClient)}>\n {children}\n </Hydrate>\n )\n}\n\nconst createTimeoutController = (ms: number, errorMessage: string) => {\n let timerId: ReturnType<typeof setTimeout> | undefined\n return {\n promise: new Promise<never>((_, reject) => {\n timerId = setTimeout(() => reject(new Error(errorMessage)), ms)\n }),\n clear: () => timerId != null && clearTimeout(timerId),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8EE;CACA;CACA;CACA;CACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AALF,SAAsB,iBAAiB;;;;wDAqCD;MArCC,EACrC,SACA,UACA,cAAc,IAAI,aAAa,EAC/B,iBAAiB,MACjB,kBACG;EAgCH,MAAM,oBACJ,WAAW,QAAQ,WAAW,IAC1B,wBAAwB,SAAS,mCAAmC,QAAQ,MAAM,GAClF;AACN,MAAI;GACF,MAAM,iBAAiB,QAAQ,IAC7B,QAAQ,KAAK,UACX,sBAAsB,QAAQ,YAAY,mBAAmB,MAAM,GAAG,YAAY,WAAW,MAAM,CACpG,CACF;AACD,SAAO,qBAAqB,OAAO,QAAQ,KAAK,CAAC,gBAAgB,kBAAkB,QAAQ,CAAC,GAAG;AAC/F,mFAAmB,OAAO;oBACpB;AACN,mFAAmB,OAAO;AAC1B,OAAI,eACF,QACE,oBAAC;IAAW,UAAU,mBAAmB,OAAO,SAAY,eAAe;IAAW;KAAsB;;AAIlH,SACE,oBAAC,2CAAY;GAAO,OAAO,UAAU,YAAY;GAC9C;KACO;;;;AAId,MAAM,2BAA2B,IAAY,iBAAyB;CACpE,IAAIA;AACJ,QAAO;EACL,SAAS,IAAI,SAAgB,GAAG,WAAW;AACzC,aAAU,iBAAiB,OAAO,IAAI,MAAM,aAAa,CAAC,EAAE,GAAG;IAC/D;EACF,aAAa,WAAW,QAAQ,aAAa,QAAQ;EACtD"}
|
|
@@ -36,7 +36,8 @@ const _excluded = [
|
|
|
36
36
|
"queries",
|
|
37
37
|
"children",
|
|
38
38
|
"queryClient",
|
|
39
|
-
"skipSsrOnError"
|
|
39
|
+
"skipSsrOnError",
|
|
40
|
+
"timeout"
|
|
40
41
|
];
|
|
41
42
|
/**
|
|
42
43
|
* A server component that fetches multiple queries on the server and hydrates them to the client.
|
|
@@ -107,10 +108,14 @@ function QueriesHydration(_x) {
|
|
|
107
108
|
}
|
|
108
109
|
function _QueriesHydration() {
|
|
109
110
|
_QueriesHydration = _asyncToGenerator(function* (_ref) {
|
|
110
|
-
let { queries, children, queryClient = new __tanstack_react_query.QueryClient(), skipSsrOnError = true } = _ref, props = require_objectWithoutProperties._objectWithoutProperties(_ref, _excluded);
|
|
111
|
+
let { queries, children, queryClient = new __tanstack_react_query.QueryClient(), skipSsrOnError = true, timeout } = _ref, props = require_objectWithoutProperties._objectWithoutProperties(_ref, _excluded);
|
|
112
|
+
const timeoutController = timeout != null && timeout >= 0 ? createTimeoutController(timeout, `QueriesHydration: timeout after ${timeout} ms)`) : void 0;
|
|
111
113
|
try {
|
|
112
|
-
|
|
114
|
+
const queriesPromise = Promise.all(queries.map((query) => "getNextPageParam" in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)));
|
|
115
|
+
yield timeoutController != null ? Promise.race([queriesPromise, timeoutController.promise]) : queriesPromise;
|
|
116
|
+
timeoutController === null || timeoutController === void 0 || timeoutController.clear();
|
|
113
117
|
} catch (_unused) {
|
|
118
|
+
timeoutController === null || timeoutController === void 0 || timeoutController.clear();
|
|
114
119
|
if (skipSsrOnError) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_ClientOnly.ClientOnly, {
|
|
115
120
|
fallback: skipSsrOnError === true ? void 0 : skipSsrOnError.fallback,
|
|
116
121
|
children
|
|
@@ -123,6 +128,15 @@ function _QueriesHydration() {
|
|
|
123
128
|
});
|
|
124
129
|
return _QueriesHydration.apply(this, arguments);
|
|
125
130
|
}
|
|
131
|
+
const createTimeoutController = (ms, errorMessage) => {
|
|
132
|
+
let timerId;
|
|
133
|
+
return {
|
|
134
|
+
promise: new Promise((_, reject) => {
|
|
135
|
+
timerId = setTimeout(() => reject(new Error(errorMessage)), ms);
|
|
136
|
+
}),
|
|
137
|
+
clear: () => timerId != null && clearTimeout(timerId)
|
|
138
|
+
};
|
|
139
|
+
};
|
|
126
140
|
|
|
127
141
|
//#endregion
|
|
128
142
|
Object.defineProperty(exports, 'QueriesHydration', {
|
|
@@ -131,4 +145,4 @@ Object.defineProperty(exports, 'QueriesHydration', {
|
|
|
131
145
|
return QueriesHydration;
|
|
132
146
|
}
|
|
133
147
|
});
|
|
134
|
-
//# sourceMappingURL=QueriesHydration-
|
|
148
|
+
//# sourceMappingURL=QueriesHydration-BYKU-Mte.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueriesHydration-BYKU-Mte.cjs","names":["QueryClient","ClientOnly","Hydrate","timerId: ReturnType<typeof setTimeout> | undefined"],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":["import {\n Hydrate,\n type HydrateProps,\n type OmitKeyof,\n QueryClient,\n type QueryOptions,\n type UseInfiniteQueryOptions,\n type WithRequired,\n dehydrate,\n} from '@tanstack/react-query'\nimport type { ReactNode } from 'react'\nimport { ClientOnly } from './components/ClientOnly'\n\n/**\n * A server component that fetches multiple queries on the server and hydrates them to the client.\n *\n * @experimental This component is experimental and may be changed or removed in the future.\n *\n * @description\n * QueriesHydration is designed for React Server Components (RSC).\n * It pre-fetches multiple queries on the server side and automatically hydrates\n * the data to the client, enabling seamless data synchronization between server and client.\n *\n * When errors occur during server-side fetching, the component gracefully falls back\n * to client-side rendering, ensuring your application remains resilient.\n *\n * @example\n * ```tsx\n * // app/page.tsx (Server Component)\n * import { Suspense } from 'react'\n * import { QueriesHydration } from '@suspensive/react-query'\n * import { queryOptions } from '@tanstack/react-query'\n *\n * const userQueryOptions = (userId: string) => queryOptions({\n * queryKey: ['user', userId],\n * queryFn: () => fetchUser(userId)\n * })\n *\n * const postsQueryOptions = () => queryOptions({\n * queryKey: ['posts'],\n * queryFn: () => fetchPosts()\n * })\n *\n * export default function Page({ userId }: { userId: string }) {\n * return (\n * <>\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration queries={[userQueryOptions(userId)]}>\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n *\n * <Suspense fallback={<div>Loading posts...</div>}>\n * <QueriesHydration queries={[postsQueryOptions()]}>\n * <PostsList />\n * </QueriesHydration>\n * </Suspense>\n * </>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom error fallback\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration\n * queries={[userQueryOptions(userId)]}\n * skipSsrOnError={{ fallback: <div>Fetching on client...</div> }}\n * >\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n * ```\n *\n * @see {@link https://suspensive.org/docs/react-query/QueriesHydration Documentation}\n */\nexport async function QueriesHydration({\n queries,\n children,\n queryClient = new QueryClient(),\n skipSsrOnError = true,\n timeout,\n ...props\n}: {\n /**\n * The QueryClient instance to use for fetching queries.\n */\n queryClient?: QueryClient\n /**\n * An array of query options or infinite query options to be fetched on the server. Each query must include a `queryKey`.\n * You can mix regular queries and infinite queries in the same array.\n */\n queries: (\n | WithRequired<QueryOptions<any, any, any, any>, 'queryKey'>\n | WithRequired<UseInfiniteQueryOptions<any, any, any, any, any>, 'queryKey'>\n )[]\n /**\n * Controls error handling behavior:\n * - `true` (default): Skips SSR and falls back to client-side rendering when server fetch fails\n * - `false`: Proceeds with SSR without hydration (retry fetching on client component server rendering)\n * - `{ fallback: ReactNode }`: Skips SSR with custom fallback UI during client-side rendering\n */\n skipSsrOnError?:\n | boolean\n | {\n fallback: ReactNode\n }\n /**\n * The timeout in milliseconds for the query.\n * If the query takes longer than the timeout, it will be considered as an error.\n * When not set, no timeout is applied.\n */\n timeout?: number\n} & OmitKeyof<HydrateProps, 'state'>) {\n const timeoutController =\n timeout != null && timeout >= 0\n ? createTimeoutController(timeout, `QueriesHydration: timeout after ${timeout} ms)`)\n : undefined\n try {\n const queriesPromise = Promise.all(\n queries.map((query) =>\n 'getNextPageParam' in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)\n )\n )\n await (timeoutController != null ? Promise.race([queriesPromise, timeoutController.promise]) : queriesPromise)\n timeoutController?.clear()\n } catch {\n timeoutController?.clear()\n if (skipSsrOnError) {\n return (\n <ClientOnly fallback={skipSsrOnError === true ? undefined : skipSsrOnError.fallback}>{children}</ClientOnly>\n )\n }\n }\n return (\n <Hydrate {...props} state={dehydrate(queryClient)}>\n {children}\n </Hydrate>\n )\n}\n\nconst createTimeoutController = (ms: number, errorMessage: string) => {\n let timerId: ReturnType<typeof setTimeout> | undefined\n return {\n promise: new Promise<never>((_, reject) => {\n timerId = setTimeout(() => reject(new Error(errorMessage)), ms)\n }),\n clear: () => timerId != null && clearTimeout(timerId),\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8EE;CACA;CACA;CACA;CACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AALF,SAAsB,iBAAiB;;;;wDAqCD;MArCC,EACrC,SACA,UACA,cAAc,IAAIA,oCAAa,EAC/B,iBAAiB,MACjB,kBACG;EAgCH,MAAM,oBACJ,WAAW,QAAQ,WAAW,IAC1B,wBAAwB,SAAS,mCAAmC,QAAQ,MAAM,GAClF;AACN,MAAI;GACF,MAAM,iBAAiB,QAAQ,IAC7B,QAAQ,KAAK,UACX,sBAAsB,QAAQ,YAAY,mBAAmB,MAAM,GAAG,YAAY,WAAW,MAAM,CACpG,CACF;AACD,SAAO,qBAAqB,OAAO,QAAQ,KAAK,CAAC,gBAAgB,kBAAkB,QAAQ,CAAC,GAAG;AAC/F,mFAAmB,OAAO;oBACpB;AACN,mFAAmB,OAAO;AAC1B,OAAI,eACF,QACE,2CAACC;IAAW,UAAU,mBAAmB,OAAO,SAAY,eAAe;IAAW;KAAsB;;AAIlH,SACE,2CAACC,8GAAY;GAAO,6CAAiB,YAAY;GAC9C;KACO;;;;AAId,MAAM,2BAA2B,IAAY,iBAAyB;CACpE,IAAIC;AACJ,QAAO;EACL,SAAS,IAAI,SAAgB,GAAG,WAAW;AACzC,aAAU,iBAAiB,OAAO,IAAI,MAAM,aAAa,CAAC,EAAE,GAAG;IAC/D;EACF,aAAa,WAAW,QAAQ,aAAa,QAAQ;EACtD"}
|
|
@@ -73,6 +73,7 @@ declare function QueriesHydration({
|
|
|
73
73
|
children,
|
|
74
74
|
queryClient,
|
|
75
75
|
skipSsrOnError,
|
|
76
|
+
timeout,
|
|
76
77
|
...props
|
|
77
78
|
}: {
|
|
78
79
|
/**
|
|
@@ -93,7 +94,13 @@ declare function QueriesHydration({
|
|
|
93
94
|
skipSsrOnError?: boolean | {
|
|
94
95
|
fallback: ReactNode;
|
|
95
96
|
};
|
|
97
|
+
/**
|
|
98
|
+
* The timeout in milliseconds for the query.
|
|
99
|
+
* If the query takes longer than the timeout, it will be considered as an error.
|
|
100
|
+
* When not set, no timeout is applied.
|
|
101
|
+
*/
|
|
102
|
+
timeout?: number;
|
|
96
103
|
} & OmitKeyof<HydrateProps, 'state'>): Promise<react_jsx_runtime3.JSX.Element>;
|
|
97
104
|
//#endregion
|
|
98
105
|
export { QueriesHydration as t };
|
|
99
|
-
//# sourceMappingURL=QueriesHydration-
|
|
106
|
+
//# sourceMappingURL=QueriesHydration-BeMkJU3l.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueriesHydration-BeMkJU3l.d.mts","names":[],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AA6EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,gBAAA;;;;;;;;;;;gBAWN;;;;;YAMV,aAAa,gDACb,aAAa;;;;;;;;cAWD;;;;;;;;IAQd,UAAU,yBAAsB,QAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime2 from "react/jsx-runtime";
|
|
2
2
|
import { HydrateProps, OmitKeyof, QueryClient, QueryOptions, UseInfiniteQueryOptions, WithRequired } from "@tanstack/react-query";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
@@ -73,6 +73,7 @@ declare function QueriesHydration({
|
|
|
73
73
|
children,
|
|
74
74
|
queryClient,
|
|
75
75
|
skipSsrOnError,
|
|
76
|
+
timeout,
|
|
76
77
|
...props
|
|
77
78
|
}: {
|
|
78
79
|
/**
|
|
@@ -93,7 +94,13 @@ declare function QueriesHydration({
|
|
|
93
94
|
skipSsrOnError?: boolean | {
|
|
94
95
|
fallback: ReactNode;
|
|
95
96
|
};
|
|
96
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The timeout in milliseconds for the query.
|
|
99
|
+
* If the query takes longer than the timeout, it will be considered as an error.
|
|
100
|
+
* When not set, no timeout is applied.
|
|
101
|
+
*/
|
|
102
|
+
timeout?: number;
|
|
103
|
+
} & OmitKeyof<HydrateProps, 'state'>): Promise<react_jsx_runtime2.JSX.Element>;
|
|
97
104
|
//#endregion
|
|
98
105
|
export { QueriesHydration as t };
|
|
99
|
-
//# sourceMappingURL=QueriesHydration-
|
|
106
|
+
//# sourceMappingURL=QueriesHydration-DQiuolCU.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueriesHydration-DQiuolCU.d.cts","names":[],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AA6EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,gBAAA;;;;;;;;;;;gBAWN;;;;;YAMV,aAAa,gDACb,aAAa;;;;;;;;cAWD;;;;;;;;IAQd,UAAU,yBAAsB,QAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as QueriesHydration } from "./QueriesHydration-
|
|
1
|
+
import { t as QueriesHydration } from "./QueriesHydration-DQiuolCU.cjs";
|
|
2
2
|
export { QueriesHydration };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as QueriesHydration } from "./QueriesHydration-
|
|
1
|
+
import { t as QueriesHydration } from "./QueriesHydration-BeMkJU3l.mjs";
|
|
2
2
|
export { QueriesHydration };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime3 from "react/jsx-runtime";
|
|
2
2
|
import { QueryClient } from "@tanstack/react-query";
|
|
3
3
|
import { Context, ReactNode } from "react";
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ declare function QueryClientConsumer({
|
|
|
12
12
|
}: {
|
|
13
13
|
children: (queryClient: QueryClient) => ReactNode;
|
|
14
14
|
context?: Context<QueryClient | undefined>;
|
|
15
|
-
}):
|
|
15
|
+
}): react_jsx_runtime3.JSX.Element;
|
|
16
16
|
//#endregion
|
|
17
17
|
export { QueryClientConsumer as t };
|
|
18
|
-
//# sourceMappingURL=QueryClientConsumer-
|
|
18
|
+
//# sourceMappingURL=QueryClientConsumer-D3h25GmM.d.cts.map
|
package/dist/{QueryClientConsumer-BGHJsJCv.d.cts.map → QueryClientConsumer-D3h25GmM.d.cts.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryClientConsumer-
|
|
1
|
+
{"version":3,"file":"QueryClientConsumer-D3h25GmM.d.cts","names":[],"sources":["../src/QueryClientConsumer.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAQgB,iBAAA,mBAAA,CAAmB;EAAA,QAAA;EAAA;CAAA,EAAA;EACjC,QAAA,EAAA,CAAA,WAAA,EAGwB,WAHxB,EAAA,GAGwC,SAHxC;EACA,OAAA,CAAA,EAGU,OAHV,CAGkB,WAHlB,GAAA,SAAA,CAAA;CAEwB,CAAA,EAEzB,kBAAA,CAAA,GAAA,CAAA,OAFyB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as QueryClientConsumer } from "./QueryClientConsumer-
|
|
1
|
+
import { t as QueryClientConsumer } from "./QueryClientConsumer-D3h25GmM.cjs";
|
|
2
2
|
export { QueryClientConsumer };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as UseSuspenseInfiniteQueryOptions } from "./useSuspenseInfiniteQuery-xXu-A7cX.cjs";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime4 from "react/jsx-runtime";
|
|
3
3
|
import { QueryKey, UseSuspenseInfiniteQueryResult } from "@tanstack/react-query";
|
|
4
4
|
import { ReactNode } from "react";
|
|
5
5
|
|
|
@@ -26,7 +26,7 @@ declare const SuspenseInfiniteQuery: <TQueryFnData = unknown, TError = unknown,
|
|
|
26
26
|
...options
|
|
27
27
|
}: UseSuspenseInfiniteQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
|
|
28
28
|
children: (query: UseSuspenseInfiniteQueryResult<TData, TError>) => ReactNode;
|
|
29
|
-
}) =>
|
|
29
|
+
}) => react_jsx_runtime4.JSX.Element;
|
|
30
30
|
//#endregion
|
|
31
31
|
export { SuspenseInfiniteQuery as t };
|
|
32
|
-
//# sourceMappingURL=SuspenseInfiniteQuery-
|
|
32
|
+
//# sourceMappingURL=SuspenseInfiniteQuery-CBf92CTq.d.cts.map
|
package/dist/{SuspenseInfiniteQuery-BwSKmJgm.d.cts.map → SuspenseInfiniteQuery-CBf92CTq.d.cts.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuspenseInfiniteQuery-
|
|
1
|
+
{"version":3,"file":"SuspenseInfiniteQuery-CBf92CTq.d.cts","names":[],"sources":["../src/SuspenseInfiniteQuery.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;;AAqBA;;;;;;;;;;;;;AASsE,cATzD,qBASyD,EAAA,CAAA,eAAA,OAAA,EAAA,SAAA,OAAA,EAAA,QAN5D,YAM4D,EAAA,kBALlD,QAKkD,GALvC,QAKuC,CAAA,CAAA;EAAA,QAAA;EAAA,GAAA;CAAA,EADnE,+BACmE,CADnC,YACmC,EADrB,MACqB,EADb,KACa,EADN,SACM,CAAA,GAAA;EACrE,QAAA,EAAA,CAAA,KAAA,EADmB,8BACnB,CADkD,KAClD,EADyD,MACzD,CAAA,EAAA,GADqE,SACrE;CAAuD,EAAA,GAAvD,kBAAA,CAAA,GAAA,CAAA,OAAuD"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as SuspenseInfiniteQuery } from "./SuspenseInfiniteQuery-
|
|
1
|
+
import { t as SuspenseInfiniteQuery } from "./SuspenseInfiniteQuery-CBf92CTq.cjs";
|
|
2
2
|
export { SuspenseInfiniteQuery };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime5 from "react/jsx-runtime";
|
|
2
2
|
import { SuspenseQueriesOptions, SuspenseQueriesResults } from "@tanstack/react-query";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ declare function SuspenseQueries<T extends any[]>({
|
|
|
25
25
|
}: {
|
|
26
26
|
queries: readonly [...SuspenseQueriesOptions<T>];
|
|
27
27
|
children: (queries: SuspenseQueriesResults<T>) => ReactNode;
|
|
28
|
-
}):
|
|
28
|
+
}): react_jsx_runtime5.JSX.Element;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { SuspenseQueries as t };
|
|
31
|
-
//# sourceMappingURL=SuspenseQueries-
|
|
31
|
+
//# sourceMappingURL=SuspenseQueries-wO-fCk30.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuspenseQueries-
|
|
1
|
+
{"version":3,"file":"SuspenseQueries-wO-fCk30.d.cts","names":[],"sources":["../src/SuspenseQueries.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AAoBA;;;;;;;;;;;;iBAAgB;;;;wBAIQ,uBAAuB;sBACzB,uBAAuB,OAAO;IACnD,kBAAA,CAAA,GAAA,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as SuspenseQueries } from "./SuspenseQueries-
|
|
1
|
+
import { t as SuspenseQueries } from "./SuspenseQueries-wO-fCk30.cjs";
|
|
2
2
|
export { SuspenseQueries };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react_jsx_runtime6 from "react/jsx-runtime";
|
|
2
2
|
import { QueryKey, UseSuspenseQueryOptions, UseSuspenseQueryResult } from "@tanstack/react-query";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
|
|
@@ -25,7 +25,7 @@ declare const SuspenseQuery: <TQueryFnData = unknown, TError = unknown, TData =
|
|
|
25
25
|
...options
|
|
26
26
|
}: UseSuspenseQueryOptions<TQueryFnData, TError, TData, TQueryKey> & {
|
|
27
27
|
children: (queryResult: UseSuspenseQueryResult<TData, TError>) => ReactNode;
|
|
28
|
-
}) =>
|
|
28
|
+
}) => react_jsx_runtime6.JSX.Element;
|
|
29
29
|
//#endregion
|
|
30
30
|
export { SuspenseQuery as t };
|
|
31
|
-
//# sourceMappingURL=SuspenseQuery-
|
|
31
|
+
//# sourceMappingURL=SuspenseQuery-DzwOaqvu.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuspenseQuery-
|
|
1
|
+
{"version":3,"file":"SuspenseQuery-DzwOaqvu.d.cts","names":[],"sources":["../src/SuspenseQuery.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AA0BA;;;;;;;;;;;;;AASoE,cATvD,aASuD,EAAA,CAAA,eAAA,OAAA,EAAA,SAAA,OAAA,EAAA,QAN1D,YAM0D,EAAA,kBALhD,QAKgD,GALrC,QAKqC,CAAA,CAAA;EAAA,QAAA;EAAA,GAAA;CAAA,EADjE,uBACiE,CADzC,YACyC,EAD3B,MAC2B,EADnB,KACmB,EADZ,SACY,CAAA,GAAA;EACnE,QAAA,EAAA,CAAA,WAAA,EADyB,sBACzB,CADgD,KAChD,EADuD,MACvD,CAAA,EAAA,GADmE,SACnE;CAA+C,EAAA,GAA/C,kBAAA,CAAA,GAAA,CAAA,OAA+C"}
|
package/dist/SuspenseQuery.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as SuspenseQuery } from "./SuspenseQuery-
|
|
1
|
+
import { t as SuspenseQuery } from "./SuspenseQuery-DzwOaqvu.cjs";
|
|
2
2
|
export { SuspenseQuery };
|
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ const require_usePrefetchInfiniteQuery = require('./usePrefetchInfiniteQuery-BmZ
|
|
|
4
4
|
const require_PrefetchInfiniteQuery = require('./PrefetchInfiniteQuery-cCSXqKVR.cjs');
|
|
5
5
|
const require_usePrefetchQuery = require('./usePrefetchQuery-woiivAJc.cjs');
|
|
6
6
|
const require_PrefetchQuery = require('./PrefetchQuery-0pdYNtpS.cjs');
|
|
7
|
-
const require_QueriesHydration = require('./QueriesHydration-
|
|
7
|
+
const require_QueriesHydration = require('./QueriesHydration-BYKU-Mte.cjs');
|
|
8
8
|
const require_QueryClientConsumer = require('./QueryClientConsumer-mF0OUwkq.cjs');
|
|
9
9
|
const require_SuspenseInfiniteQuery = require('./SuspenseInfiniteQuery-Dq97Dear.cjs');
|
|
10
10
|
const require_SuspenseQueries = require('./SuspenseQueries-Brk6gtMw.cjs');
|
package/dist/index.d.cts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { t as IsFetching } from "./IsFetching-
|
|
1
|
+
import { t as IsFetching } from "./IsFetching-CmAXgxBe.cjs";
|
|
2
2
|
import { t as Mutation } from "./Mutation-Dt5kUsd8.cjs";
|
|
3
|
-
import { t as PrefetchInfiniteQuery } from "./PrefetchInfiniteQuery-
|
|
4
|
-
import { t as PrefetchQuery } from "./PrefetchQuery-
|
|
5
|
-
import { t as QueriesHydration } from "./QueriesHydration-
|
|
6
|
-
import { t as QueryClientConsumer } from "./QueryClientConsumer-
|
|
3
|
+
import { t as PrefetchInfiniteQuery } from "./PrefetchInfiniteQuery-BewcG5rR.cjs";
|
|
4
|
+
import { t as PrefetchQuery } from "./PrefetchQuery-C3h9DidM.cjs";
|
|
5
|
+
import { t as QueriesHydration } from "./QueriesHydration-DQiuolCU.cjs";
|
|
6
|
+
import { t as QueryClientConsumer } from "./QueryClientConsumer-D3h25GmM.cjs";
|
|
7
7
|
import { n as UseSuspenseInfiniteQueryResult, r as useSuspenseInfiniteQuery, t as UseSuspenseInfiniteQueryOptions } from "./useSuspenseInfiniteQuery-xXu-A7cX.cjs";
|
|
8
|
-
import { t as SuspenseInfiniteQuery } from "./SuspenseInfiniteQuery-
|
|
9
|
-
import { t as SuspenseQueries } from "./SuspenseQueries-
|
|
10
|
-
import { t as SuspenseQuery } from "./SuspenseQuery-
|
|
8
|
+
import { t as SuspenseInfiniteQuery } from "./SuspenseInfiniteQuery-CBf92CTq.cjs";
|
|
9
|
+
import { t as SuspenseQueries } from "./SuspenseQueries-wO-fCk30.cjs";
|
|
10
|
+
import { t as SuspenseQuery } from "./SuspenseQuery-DzwOaqvu.cjs";
|
|
11
11
|
import { t as createGetQueryClient } from "./createGetQueryClient-iXoXO7so.cjs";
|
|
12
12
|
import { n as UnSelectedInfiniteOptions, r as infiniteQueryOptions, t as SelectedInfiniteOptions } from "./infiniteQueryOptions-Be7VYTUR.cjs";
|
|
13
13
|
import { n as UnSelectedQueryOptions, r as queryOptions, t as SelectedQueryOptions } from "./queryOptions-DNGHeGX5.cjs";
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { t as IsFetching } from "./IsFetching-D3xmE2Kn.mjs";
|
|
|
2
2
|
import { t as Mutation } from "./Mutation-CGpbCg54.mjs";
|
|
3
3
|
import { t as PrefetchInfiniteQuery } from "./PrefetchInfiniteQuery-Dzjm5lf8.mjs";
|
|
4
4
|
import { t as PrefetchQuery } from "./PrefetchQuery-DAqAWOeP.mjs";
|
|
5
|
-
import { t as QueriesHydration } from "./QueriesHydration-
|
|
5
|
+
import { t as QueriesHydration } from "./QueriesHydration-BeMkJU3l.mjs";
|
|
6
6
|
import { t as QueryClientConsumer } from "./QueryClientConsumer-BW1kmzJX.mjs";
|
|
7
7
|
import { n as UseSuspenseInfiniteQueryResult, r as useSuspenseInfiniteQuery, t as UseSuspenseInfiniteQueryOptions } from "./useSuspenseInfiniteQuery-Bh0nh8Kc.mjs";
|
|
8
8
|
import { t as SuspenseInfiniteQuery } from "./SuspenseInfiniteQuery-B6hHnPDQ.mjs";
|
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { t as usePrefetchInfiniteQuery } from "./usePrefetchInfiniteQuery-CQSN-P
|
|
|
4
4
|
import { t as PrefetchInfiniteQuery } from "./PrefetchInfiniteQuery-RS3Qz-7B.mjs";
|
|
5
5
|
import { t as usePrefetchQuery } from "./usePrefetchQuery-CtrJciA6.mjs";
|
|
6
6
|
import { t as PrefetchQuery } from "./PrefetchQuery-uh4idoXK.mjs";
|
|
7
|
-
import { t as QueriesHydration } from "./QueriesHydration-
|
|
7
|
+
import { t as QueriesHydration } from "./QueriesHydration-27lFZeB8.mjs";
|
|
8
8
|
import { t as QueryClientConsumer } from "./QueryClientConsumer-e7PyaFF3.mjs";
|
|
9
9
|
import { t as SuspenseInfiniteQuery } from "./SuspenseInfiniteQuery-DwW5I_M2.mjs";
|
|
10
10
|
import { t as SuspenseQueries } from "./SuspenseQueries-C0mF_XD_.mjs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suspensive/react-query-4",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
4
4
|
"description": "Suspensive interfaces for @tanstack/react-query@4",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"suspensive",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"@types/react": "^19.2.7",
|
|
44
44
|
"react": "^19.2.3",
|
|
45
45
|
"@suspensive/eslint-config": "0.0.1",
|
|
46
|
-
"@suspensive/
|
|
47
|
-
"@suspensive/
|
|
46
|
+
"@suspensive/tsdown": "0.0.0",
|
|
47
|
+
"@suspensive/tsconfig": "0.0.0-development"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@tanstack/react-query": "*",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { QueryClient, dehydrate, infiniteQueryOptions } from '@tanstack/react-query'
|
|
1
|
+
import { QueryClient, QueryClientProvider, dehydrate, infiniteQueryOptions } from '@tanstack/react-query'
|
|
2
2
|
import { render, screen } from '@testing-library/react'
|
|
3
3
|
import type { ComponentProps, ReactNode } from 'react'
|
|
4
4
|
import { describe, expect, it, vi } from 'vitest'
|
|
@@ -351,4 +351,41 @@ describe('<QueriesHydration/>', () => {
|
|
|
351
351
|
pageParams: [undefined],
|
|
352
352
|
})
|
|
353
353
|
})
|
|
354
|
+
|
|
355
|
+
it('should timeout when query takes longer than the timeout', async () => {
|
|
356
|
+
const serverQueryClient = new QueryClient()
|
|
357
|
+
const timeoutMs = 100
|
|
358
|
+
const queryDelayMs = 200
|
|
359
|
+
const mockQueryFn = vi
|
|
360
|
+
.fn()
|
|
361
|
+
.mockImplementation(
|
|
362
|
+
() => new Promise((resolve) => setTimeout(() => resolve({ data: 'test-data' }), queryDelayMs))
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
const queries = [
|
|
366
|
+
{
|
|
367
|
+
queryKey: ['test-query'],
|
|
368
|
+
queryFn: mockQueryFn,
|
|
369
|
+
},
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
const ClientChild = () => {
|
|
373
|
+
return <div>Client Child</div>
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const result = await QueriesHydration({
|
|
377
|
+
queries,
|
|
378
|
+
queryClient: serverQueryClient,
|
|
379
|
+
timeout: timeoutMs,
|
|
380
|
+
children: <ClientChild />,
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
expect(mockQueryFn).toHaveBeenCalledTimes(1)
|
|
384
|
+
expect(screen.queryByText('Client Child')).not.toBeInTheDocument()
|
|
385
|
+
|
|
386
|
+
const clientQueryClient = new QueryClient()
|
|
387
|
+
render(<QueryClientProvider client={clientQueryClient}>{result}</QueryClientProvider>)
|
|
388
|
+
expect(screen.getByTestId('client-only')).toBeInTheDocument()
|
|
389
|
+
expect(screen.getByText('Client Child')).toBeInTheDocument()
|
|
390
|
+
})
|
|
354
391
|
})
|
package/src/QueriesHydration.tsx
CHANGED
|
@@ -80,6 +80,7 @@ export async function QueriesHydration({
|
|
|
80
80
|
children,
|
|
81
81
|
queryClient = new QueryClient(),
|
|
82
82
|
skipSsrOnError = true,
|
|
83
|
+
timeout,
|
|
83
84
|
...props
|
|
84
85
|
}: {
|
|
85
86
|
/**
|
|
@@ -105,14 +106,27 @@ export async function QueriesHydration({
|
|
|
105
106
|
| {
|
|
106
107
|
fallback: ReactNode
|
|
107
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* The timeout in milliseconds for the query.
|
|
111
|
+
* If the query takes longer than the timeout, it will be considered as an error.
|
|
112
|
+
* When not set, no timeout is applied.
|
|
113
|
+
*/
|
|
114
|
+
timeout?: number
|
|
108
115
|
} & OmitKeyof<HydrateProps, 'state'>) {
|
|
116
|
+
const timeoutController =
|
|
117
|
+
timeout != null && timeout >= 0
|
|
118
|
+
? createTimeoutController(timeout, `QueriesHydration: timeout after ${timeout} ms)`)
|
|
119
|
+
: undefined
|
|
109
120
|
try {
|
|
110
|
-
|
|
121
|
+
const queriesPromise = Promise.all(
|
|
111
122
|
queries.map((query) =>
|
|
112
123
|
'getNextPageParam' in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)
|
|
113
124
|
)
|
|
114
125
|
)
|
|
126
|
+
await (timeoutController != null ? Promise.race([queriesPromise, timeoutController.promise]) : queriesPromise)
|
|
127
|
+
timeoutController?.clear()
|
|
115
128
|
} catch {
|
|
129
|
+
timeoutController?.clear()
|
|
116
130
|
if (skipSsrOnError) {
|
|
117
131
|
return (
|
|
118
132
|
<ClientOnly fallback={skipSsrOnError === true ? undefined : skipSsrOnError.fallback}>{children}</ClientOnly>
|
|
@@ -125,3 +139,13 @@ export async function QueriesHydration({
|
|
|
125
139
|
</Hydrate>
|
|
126
140
|
)
|
|
127
141
|
}
|
|
142
|
+
|
|
143
|
+
const createTimeoutController = (ms: number, errorMessage: string) => {
|
|
144
|
+
let timerId: ReturnType<typeof setTimeout> | undefined
|
|
145
|
+
return {
|
|
146
|
+
promise: new Promise<never>((_, reject) => {
|
|
147
|
+
timerId = setTimeout(() => reject(new Error(errorMessage)), ms)
|
|
148
|
+
}),
|
|
149
|
+
clear: () => timerId != null && clearTimeout(timerId),
|
|
150
|
+
}
|
|
151
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueriesHydration-99AzKj29.d.cts","names":[],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AA6EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,gBAAA;;;;;;;;;;gBAUN;;;;;YAMV,aAAa,gDACb,aAAa;;;;;;;;cAWD;;IAEd,UAAU,yBAAsB,QAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueriesHydration-BARmyHJu.cjs","names":["QueryClient","ClientOnly","Hydrate"],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":["import {\n Hydrate,\n type HydrateProps,\n type OmitKeyof,\n QueryClient,\n type QueryOptions,\n type UseInfiniteQueryOptions,\n type WithRequired,\n dehydrate,\n} from '@tanstack/react-query'\nimport type { ReactNode } from 'react'\nimport { ClientOnly } from './components/ClientOnly'\n\n/**\n * A server component that fetches multiple queries on the server and hydrates them to the client.\n *\n * @experimental This component is experimental and may be changed or removed in the future.\n *\n * @description\n * QueriesHydration is designed for React Server Components (RSC).\n * It pre-fetches multiple queries on the server side and automatically hydrates\n * the data to the client, enabling seamless data synchronization between server and client.\n *\n * When errors occur during server-side fetching, the component gracefully falls back\n * to client-side rendering, ensuring your application remains resilient.\n *\n * @example\n * ```tsx\n * // app/page.tsx (Server Component)\n * import { Suspense } from 'react'\n * import { QueriesHydration } from '@suspensive/react-query'\n * import { queryOptions } from '@tanstack/react-query'\n *\n * const userQueryOptions = (userId: string) => queryOptions({\n * queryKey: ['user', userId],\n * queryFn: () => fetchUser(userId)\n * })\n *\n * const postsQueryOptions = () => queryOptions({\n * queryKey: ['posts'],\n * queryFn: () => fetchPosts()\n * })\n *\n * export default function Page({ userId }: { userId: string }) {\n * return (\n * <>\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration queries={[userQueryOptions(userId)]}>\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n *\n * <Suspense fallback={<div>Loading posts...</div>}>\n * <QueriesHydration queries={[postsQueryOptions()]}>\n * <PostsList />\n * </QueriesHydration>\n * </Suspense>\n * </>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom error fallback\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration\n * queries={[userQueryOptions(userId)]}\n * skipSsrOnError={{ fallback: <div>Fetching on client...</div> }}\n * >\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n * ```\n *\n * @see {@link https://suspensive.org/docs/react-query/QueriesHydration Documentation}\n */\nexport async function QueriesHydration({\n queries,\n children,\n queryClient = new QueryClient(),\n skipSsrOnError = true,\n ...props\n}: {\n /**\n * The QueryClient instance to use for fetching queries.\n */\n queryClient?: QueryClient\n /**\n * An array of query options or infinite query options to be fetched on the server. Each query must include a `queryKey`.\n * You can mix regular queries and infinite queries in the same array.\n */\n queries: (\n | WithRequired<QueryOptions<any, any, any, any>, 'queryKey'>\n | WithRequired<UseInfiniteQueryOptions<any, any, any, any, any>, 'queryKey'>\n )[]\n /**\n * Controls error handling behavior:\n * - `true` (default): Skips SSR and falls back to client-side rendering when server fetch fails\n * - `false`: Proceeds with SSR without hydration (retry fetching on client component server rendering)\n * - `{ fallback: ReactNode }`: Skips SSR with custom fallback UI during client-side rendering\n */\n skipSsrOnError?:\n | boolean\n | {\n fallback: ReactNode\n }\n} & OmitKeyof<HydrateProps, 'state'>) {\n try {\n await Promise.all(\n queries.map((query) =>\n 'getNextPageParam' in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)\n )\n )\n } catch {\n if (skipSsrOnError) {\n return (\n <ClientOnly fallback={skipSsrOnError === true ? undefined : skipSsrOnError.fallback}>{children}</ClientOnly>\n )\n }\n }\n return (\n <Hydrate {...props} state={dehydrate(queryClient)}>\n {children}\n </Hydrate>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8EE;CACA;CACA;CACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAJF,SAAsB,iBAAiB;;;;wDA8BD;MA9BC,EACrC,SACA,UACA,cAAc,IAAIA,oCAAa,EAC/B,iBAAiB,eACd;AA0BH,MAAI;AACF,SAAM,QAAQ,IACZ,QAAQ,KAAK,UACX,sBAAsB,QAAQ,YAAY,mBAAmB,MAAM,GAAG,YAAY,WAAW,MAAM,CACpG,CACF;oBACK;AACN,OAAI,eACF,QACE,2CAACC;IAAW,UAAU,mBAAmB,OAAO,SAAY,eAAe;IAAW;KAAsB;;AAIlH,SACE,2CAACC,8GAAY;GAAO,6CAAiB,YAAY;GAC9C;KACO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueriesHydration-BrMSJHsz.mjs","names":[],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":["import {\n Hydrate,\n type HydrateProps,\n type OmitKeyof,\n QueryClient,\n type QueryOptions,\n type UseInfiniteQueryOptions,\n type WithRequired,\n dehydrate,\n} from '@tanstack/react-query'\nimport type { ReactNode } from 'react'\nimport { ClientOnly } from './components/ClientOnly'\n\n/**\n * A server component that fetches multiple queries on the server and hydrates them to the client.\n *\n * @experimental This component is experimental and may be changed or removed in the future.\n *\n * @description\n * QueriesHydration is designed for React Server Components (RSC).\n * It pre-fetches multiple queries on the server side and automatically hydrates\n * the data to the client, enabling seamless data synchronization between server and client.\n *\n * When errors occur during server-side fetching, the component gracefully falls back\n * to client-side rendering, ensuring your application remains resilient.\n *\n * @example\n * ```tsx\n * // app/page.tsx (Server Component)\n * import { Suspense } from 'react'\n * import { QueriesHydration } from '@suspensive/react-query'\n * import { queryOptions } from '@tanstack/react-query'\n *\n * const userQueryOptions = (userId: string) => queryOptions({\n * queryKey: ['user', userId],\n * queryFn: () => fetchUser(userId)\n * })\n *\n * const postsQueryOptions = () => queryOptions({\n * queryKey: ['posts'],\n * queryFn: () => fetchPosts()\n * })\n *\n * export default function Page({ userId }: { userId: string }) {\n * return (\n * <>\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration queries={[userQueryOptions(userId)]}>\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n *\n * <Suspense fallback={<div>Loading posts...</div>}>\n * <QueriesHydration queries={[postsQueryOptions()]}>\n * <PostsList />\n * </QueriesHydration>\n * </Suspense>\n * </>\n * )\n * }\n * ```\n *\n * @example\n * ```tsx\n * // With custom error fallback\n * <Suspense fallback={<div>Loading user...</div>}>\n * <QueriesHydration\n * queries={[userQueryOptions(userId)]}\n * skipSsrOnError={{ fallback: <div>Fetching on client...</div> }}\n * >\n * <UserProfile />\n * </QueriesHydration>\n * </Suspense>\n * ```\n *\n * @see {@link https://suspensive.org/docs/react-query/QueriesHydration Documentation}\n */\nexport async function QueriesHydration({\n queries,\n children,\n queryClient = new QueryClient(),\n skipSsrOnError = true,\n ...props\n}: {\n /**\n * The QueryClient instance to use for fetching queries.\n */\n queryClient?: QueryClient\n /**\n * An array of query options or infinite query options to be fetched on the server. Each query must include a `queryKey`.\n * You can mix regular queries and infinite queries in the same array.\n */\n queries: (\n | WithRequired<QueryOptions<any, any, any, any>, 'queryKey'>\n | WithRequired<UseInfiniteQueryOptions<any, any, any, any, any>, 'queryKey'>\n )[]\n /**\n * Controls error handling behavior:\n * - `true` (default): Skips SSR and falls back to client-side rendering when server fetch fails\n * - `false`: Proceeds with SSR without hydration (retry fetching on client component server rendering)\n * - `{ fallback: ReactNode }`: Skips SSR with custom fallback UI during client-side rendering\n */\n skipSsrOnError?:\n | boolean\n | {\n fallback: ReactNode\n }\n} & OmitKeyof<HydrateProps, 'state'>) {\n try {\n await Promise.all(\n queries.map((query) =>\n 'getNextPageParam' in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)\n )\n )\n } catch {\n if (skipSsrOnError) {\n return (\n <ClientOnly fallback={skipSsrOnError === true ? undefined : skipSsrOnError.fallback}>{children}</ClientOnly>\n )\n }\n }\n return (\n <Hydrate {...props} state={dehydrate(queryClient)}>\n {children}\n </Hydrate>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8EE;CACA;CACA;CACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAJF,SAAsB,iBAAiB;;;;wDA8BD;MA9BC,EACrC,SACA,UACA,cAAc,IAAI,aAAa,EAC/B,iBAAiB,eACd;AA0BH,MAAI;AACF,SAAM,QAAQ,IACZ,QAAQ,KAAK,UACX,sBAAsB,QAAQ,YAAY,mBAAmB,MAAM,GAAG,YAAY,WAAW,MAAM,CACpG,CACF;oBACK;AACN,OAAI,eACF,QACE,oBAAC;IAAW,UAAU,mBAAmB,OAAO,SAAY,eAAe;IAAW;KAAsB;;AAIlH,SACE,oBAAC,2CAAY;GAAO,OAAO,UAAU,YAAY;GAC9C;KACO"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"QueriesHydration-M2zoVGgJ.d.mts","names":[],"sources":["../src/QueriesHydration.tsx"],"sourcesContent":[],"mappings":";;;;;;;;;AA6EA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAsB,gBAAA;;;;;;;;;;gBAUN;;;;;YAMV,aAAa,gDACb,aAAa;;;;;;;;cAWD;;IAEd,UAAU,yBAAsB,QAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
|