@suspensive/react-query-4
Version:
Suspensive interfaces for @tanstack/react-query@4
118 lines (116 loc) • 4.34 kB
JavaScript
import { _objectWithoutProperties } from "./_virtual/_@oxc-project_runtime@0.130.0/helpers/objectWithoutProperties.mjs";
import { ClientOnly } from "./components/ClientOnly.mjs";
import { _objectSpread2 } from "./_virtual/_@oxc-project_runtime@0.130.0/helpers/objectSpread2.mjs";
import { _asyncToGenerator } from "./_virtual/_@oxc-project_runtime@0.130.0/helpers/asyncToGenerator.mjs";
import { Hydrate, QueryClient, dehydrate } from "@tanstack/react-query";
import { jsx } from "react/jsx-runtime";
//#region src/QueriesHydration.tsx
const _excluded = [
"queries",
"children",
"queryClient",
"skipSsrOnError",
"timeout"
];
/**
* A server component that fetches multiple queries on the server and hydrates them to the client.
*
* @experimental This component is experimental and may be changed or removed in the future.
*
* @description
* QueriesHydration is designed for React Server Components (RSC).
* It pre-fetches multiple queries on the server side and automatically hydrates
* the data to the client, enabling seamless data synchronization between server and client.
*
* When errors occur during server-side fetching, the component gracefully falls back
* to client-side rendering, ensuring your application remains resilient.
*
* @example
* ```tsx
* // app/page.tsx (Server Component)
* import { Suspense } from 'react'
* import { QueriesHydration } from '@suspensive/react-query'
* import { queryOptions } from '@tanstack/react-query'
*
* const userQueryOptions = (userId: string) => queryOptions({
* queryKey: ['user', userId],
* queryFn: () => fetchUser(userId)
* })
*
* const postsQueryOptions = () => queryOptions({
* queryKey: ['posts'],
* queryFn: () => fetchPosts()
* })
*
* export default function Page({ userId }: { userId: string }) {
* return (
* <>
* <Suspense fallback={<div>Loading user...</div>}>
* <QueriesHydration queries={[userQueryOptions(userId)]}>
* <UserProfile />
* </QueriesHydration>
* </Suspense>
*
* <Suspense fallback={<div>Loading posts...</div>}>
* <QueriesHydration queries={[postsQueryOptions()]}>
* <PostsList />
* </QueriesHydration>
* </Suspense>
* </>
* )
* }
* ```
*
* @example
* ```tsx
* // With custom error fallback
* <Suspense fallback={<div>Loading user...</div>}>
* <QueriesHydration
* queries={[userQueryOptions(userId)]}
* skipSsrOnError={{ fallback: <div>Fetching on client...</div> }}
* >
* <UserProfile />
* </QueriesHydration>
* </Suspense>
* ```
*
* @see {@link https://suspensive.org/docs/react-query/QueriesHydration Documentation}
*/
function QueriesHydration(_x) {
return _QueriesHydration.apply(this, arguments);
}
function _QueriesHydration() {
_QueriesHydration = _asyncToGenerator(function* (_ref) {
let { queries, children, queryClient = new QueryClient(), skipSsrOnError = true, timeout } = _ref, props = _objectWithoutProperties(_ref, _excluded);
const timeoutController = timeout != null && timeout >= 0 ? createTimeoutController(timeout) : void 0;
try {
const queriesPromise = Promise.all(queries.map((query) => "getNextPageParam" in query ? queryClient.fetchInfiniteQuery(query) : queryClient.fetchQuery(query)));
yield timeoutController != null ? Promise.race([queriesPromise, timeoutController.promise]) : queriesPromise;
timeoutController === null || timeoutController === void 0 || timeoutController.clear();
} catch (_unused) {
timeoutController === null || timeoutController === void 0 || timeoutController.clear();
queries.forEach((query) => void queryClient.cancelQueries(query));
if (skipSsrOnError) return /* @__PURE__ */ jsx(ClientOnly, {
fallback: skipSsrOnError === true ? void 0 : skipSsrOnError.fallback,
children
});
}
return /* @__PURE__ */ jsx(Hydrate, _objectSpread2(_objectSpread2({}, props), {}, {
state: dehydrate(queryClient),
children
}));
});
return _QueriesHydration.apply(this, arguments);
}
const createTimeoutController = (ms) => {
let timerId;
return {
promise: new Promise((_, reject) => {
timerId = setTimeout(() => reject(/* @__PURE__ */ new Error(`QueriesHydration: timeout after ${ms} ms`)), ms);
}),
clear: () => timerId != null && clearTimeout(timerId)
};
};
//#endregion
export { QueriesHydration };
//# sourceMappingURL=QueriesHydration.mjs.map