{"version":3,"sources":["../../src/HydrationBoundary.tsx"],"sourcesContent":["'use client'\nimport * as React from 'react'\n\nimport { hydrate } from '@tanstack/query-core'\nimport { useQueryClient } from './QueryClientProvider'\nimport type {\n  DehydratedState,\n  HydrateOptions,\n  OmitKeyof,\n  QueryClient,\n} from '@tanstack/query-core'\n\nexport interface HydrationBoundaryProps {\n  state?: unknown\n  options?: OmitKeyof<HydrateOptions, 'defaultOptions'> & {\n    defaultOptions?: OmitKeyof<\n      Exclude<HydrateOptions['defaultOptions'], undefined>,\n      'mutations'\n    >\n  }\n  children?: React.ReactNode\n  queryClient?: QueryClient\n}\n\nexport const HydrationBoundary = ({\n  children,\n  options = {},\n  state,\n  queryClient,\n}: HydrationBoundaryProps) => {\n  const client = useQueryClient(queryClient)\n  const [hydrationQueue, setHydrationQueue] = React.useState<\n    DehydratedState['queries'] | undefined\n  >()\n\n  const optionsRef = React.useRef(options)\n  optionsRef.current = options\n\n  // This useMemo is for performance reasons only, everything inside it _must_\n  // be safe to run in every render and code here should be read as \"in render\".\n  //\n  // This code needs to happen during the render phase, because after initial\n  // SSR, hydration needs to happen _before_ children render. Also, if hydrating\n  // during a transition, we want to hydrate as much as is safe in render so\n  // we can prerender as much as possible.\n  //\n  // For any queries that already exist in the cache, we want to hold back on\n  // hydrating until _after_ the render phase. The reason for this is that during\n  // transitions, we don't want the existing queries and observers to update to\n  // the new data on the current page, only _after_ the transition is committed.\n  // If the transition is aborted, we will have hydrated any _new_ queries, but\n  // we throw away the fresh data for any existing ones to avoid unexpectedly\n  // updating the UI.\n  React.useMemo(() => {\n    if (state) {\n      if (typeof state !== 'object') {\n        return\n      }\n\n      const queryCache = client.getQueryCache()\n      // eslint-disable-next-line ts/no-unnecessary-condition\n      const queries = (state as DehydratedState).queries || []\n\n      const newQueries: DehydratedState['queries'] = []\n      const existingQueries: DehydratedState['queries'] = []\n      for (const dehydratedQuery of queries) {\n        const existingQuery = queryCache.get(dehydratedQuery.queryHash)\n\n        if (!existingQuery) {\n          newQueries.push(dehydratedQuery)\n        } else {\n          const hydrationIsNewer =\n            dehydratedQuery.state.dataUpdatedAt >\n            existingQuery.state.dataUpdatedAt\n          const queryAlreadyQueued = hydrationQueue?.find(\n            (query) => query.queryHash === dehydratedQuery.queryHash,\n          )\n\n          if (\n            hydrationIsNewer &&\n            (!queryAlreadyQueued ||\n              dehydratedQuery.state.dataUpdatedAt >\n                queryAlreadyQueued.state.dataUpdatedAt)\n          ) {\n            existingQueries.push(dehydratedQuery)\n          }\n        }\n      }\n\n      if (newQueries.length > 0) {\n        // It's actually fine to call this with queries/state that already exists\n        // in the cache, or is older. hydrate() is idempotent for queries.\n        hydrate(client, { queries: newQueries }, optionsRef.current)\n      }\n      if (existingQueries.length > 0) {\n        setHydrationQueue((prev) =>\n          prev ? [...prev, ...existingQueries] : existingQueries,\n        )\n      }\n    }\n  }, [client, hydrationQueue, state])\n\n  React.useEffect(() => {\n    if (hydrationQueue) {\n      hydrate(client, { queries: hydrationQueue }, optionsRef.current)\n      setHydrationQueue(undefined)\n    }\n  }, [client, hydrationQueue])\n\n  return children as React.ReactElement\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,YAAuB;AAEvB,wBAAwB;AACxB,iCAA+B;AAoBxB,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AAAA,EACA;AACF,MAA8B;AAC5B,QAAM,aAAS,2CAAe,WAAW;AACzC,QAAM,CAAC,gBAAgB,iBAAiB,IAAU,eAEhD;AAEF,QAAM,aAAmB,aAAO,OAAO;AACvC,aAAW,UAAU;AAiBrB,EAAM,cAAQ,MAAM;AAClB,QAAI,OAAO;AACT,UAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,MACF;AAEA,YAAM,aAAa,OAAO,cAAc;AAExC,YAAM,UAAW,MAA0B,WAAW,CAAC;AAEvD,YAAM,aAAyC,CAAC;AAChD,YAAM,kBAA8C,CAAC;AACrD,iBAAW,mBAAmB,SAAS;AACrC,cAAM,gBAAgB,WAAW,IAAI,gBAAgB,SAAS;AAE9D,YAAI,CAAC,eAAe;AAClB,qBAAW,KAAK,eAAe;AAAA,QACjC,OAAO;AACL,gBAAM,mBACJ,gBAAgB,MAAM,gBACtB,cAAc,MAAM;AACtB,gBAAM,qBAAqB,gBAAgB;AAAA,YACzC,CAAC,UAAU,MAAM,cAAc,gBAAgB;AAAA,UACjD;AAEA,cACE,qBACC,CAAC,sBACA,gBAAgB,MAAM,gBACpB,mBAAmB,MAAM,gBAC7B;AACA,4BAAgB,KAAK,eAAe;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,SAAS,GAAG;AAGzB,uCAAQ,QAAQ,EAAE,SAAS,WAAW,GAAG,WAAW,OAAO;AAAA,MAC7D;AACA,UAAI,gBAAgB,SAAS,GAAG;AAC9B;AAAA,UAAkB,CAAC,SACjB,OAAO,CAAC,GAAG,MAAM,GAAG,eAAe,IAAI;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,gBAAgB,KAAK,CAAC;AAElC,EAAM,gBAAU,MAAM;AACpB,QAAI,gBAAgB;AAClB,qCAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAC/D,wBAAkB,MAAS;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}