{"version":3,"file":"QueriesHydration.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  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 = timeout != null && timeout >= 0 ? createTimeoutController(timeout) : 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    queries.forEach((query) => void queryClient.cancelQueries(query))\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) => {\n  let timerId: ReturnType<typeof setTimeout> | undefined\n  return {\n    promise: new Promise<never>((_, reject) => {\n      timerId = setTimeout(() => reject(new Error(`QueriesHydration: timeout after ${ms} ms`)), ms)\n    }),\n    clear: () => timerId != null && clearTimeout(timerId),\n  }\n}\n"],"mappings":";;;;;;;;;;CA8EE;CACA;CACA;CACA;CACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AALF,SAAsB,iBAAiB;;;;iFAqCD;MArCC,EACrC,SACA,UACA,cAAc,IAAIA,kCAAY,GAC9B,iBAAiB,MACjB,kBACG;EAgCH,MAAM,oBAAoB,WAAW,QAAQ,WAAW,IAAI,wBAAwB,OAAO,IAAI;EAC/F,IAAI;GACF,MAAM,iBAAiB,QAAQ,IAC7B,QAAQ,KAAK,UACX,sBAAsB,QAAQ,YAAY,mBAAmB,KAAK,IAAI,YAAY,WAAW,KAAK,CACpG,CACF;GACA,MAAO,qBAAqB,OAAO,QAAQ,KAAK,CAAC,gBAAgB,kBAAkB,OAAO,CAAC,IAAI;GAC/F,gFAAmB,MAAM;EAC3B,kBAAQ;GACN,gFAAmB,MAAM;GACzB,QAAQ,SAAS,UAAU,KAAK,YAAY,cAAc,KAAK,CAAC;GAChE,IAAI,gBACF,OACE,2CAACC,+BAAD;IAAY,UAAU,mBAAmB,OAAO,SAAY,eAAe;IAAW;GAAqB;EAGjH;EACA,OACE,2CAACC,6GAAY;GAAO,4CAAiB,WAAW;GAC7C;GACM;CAEb;;;AAEA,MAAM,2BAA2B,OAAe;CAC9C,IAAI;CACJ,OAAO;EACL,SAAS,IAAI,SAAgB,GAAG,WAAW;GACzC,UAAU,iBAAiB,uBAAO,IAAI,MAAM,mCAAmC,GAAG,IAAI,CAAC,GAAG,EAAE;EAC9F,CAAC;EACD,aAAa,WAAW,QAAQ,aAAa,OAAO;CACtD;AACF"}