@tanstack/react-query 5.80.2 → 5.80.3

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.
@@ -44,10 +44,9 @@ var HydrationBoundary = ({
44
44
  queryClient
45
45
  }) => {
46
46
  const client = (0, import_QueryClientProvider.useQueryClient)(queryClient);
47
- const [hydrationQueue, setHydrationQueue] = React.useState();
48
47
  const optionsRef = React.useRef(options);
49
48
  optionsRef.current = options;
50
- React.useMemo(() => {
49
+ const hydrationQueue = React.useMemo(() => {
51
50
  if (state) {
52
51
  if (typeof state !== "object") {
53
52
  return;
@@ -62,10 +61,7 @@ var HydrationBoundary = ({
62
61
  newQueries.push(dehydratedQuery);
63
62
  } else {
64
63
  const hydrationIsNewer = dehydratedQuery.state.dataUpdatedAt > existingQuery.state.dataUpdatedAt || dehydratedQuery.promise && existingQuery.state.status !== "pending" && existingQuery.state.fetchStatus !== "fetching" && dehydratedQuery.dehydratedAt !== void 0 && dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt;
65
- const queryAlreadyQueued = hydrationQueue == null ? void 0 : hydrationQueue.find(
66
- (query) => query.queryHash === dehydratedQuery.queryHash
67
- );
68
- if (hydrationIsNewer && (!queryAlreadyQueued || dehydratedQuery.state.dataUpdatedAt > queryAlreadyQueued.state.dataUpdatedAt)) {
64
+ if (hydrationIsNewer) {
69
65
  existingQueries.push(dehydratedQuery);
70
66
  }
71
67
  }
@@ -74,16 +70,14 @@ var HydrationBoundary = ({
74
70
  (0, import_query_core.hydrate)(client, { queries: newQueries }, optionsRef.current);
75
71
  }
76
72
  if (existingQueries.length > 0) {
77
- setHydrationQueue(
78
- (prev) => prev ? [...prev, ...existingQueries] : existingQueries
79
- );
73
+ return existingQueries;
80
74
  }
81
75
  }
82
- }, [client, hydrationQueue, state]);
76
+ return void 0;
77
+ }, [client, state]);
83
78
  React.useEffect(() => {
84
79
  if (hydrationQueue) {
85
80
  (0, import_query_core.hydrate)(client, { queries: hydrationQueue }, optionsRef.current);
86
- setHydrationQueue(void 0);
87
81
  }
88
82
  }, [client, hydrationQueue]);
89
83
  return children;
@@ -1 +1 @@
1
- {"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 @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt)\n\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 // eslint-disable-next-line react-hooks/react-compiler\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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eAAe,cAAc,MAAM;AAEvD,gBAAM,qBAAqB,iDAAgB;AAAA,YACzC,CAAC,UAAU,MAAM,cAAc,gBAAgB;AAAA;AAGjD,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;AAE9B;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":[]}
1
+ {"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\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 const hydrationQueue: DehydratedState['queries'] | undefined =\n React.useMemo(() => {\n if (state) {\n if (typeof state !== 'object') {\n return\n }\n\n const queryCache = client.getQueryCache()\n // State is supplied from the outside and we might as well fail\n // gracefully if it has the wrong shape, so while we type `queries`\n // as required, we still provide a fallback.\n // eslint-disable-next-line @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt >\n existingQuery.state.dataUpdatedAt)\n\n if (hydrationIsNewer) {\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 return existingQueries\n }\n }\n return undefined\n }, [client, state])\n\n React.useEffect(() => {\n if (hydrationQueue) {\n hydrate(client, { queries: hydrationQueue }, optionsRef.current)\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;AAEzC,QAAM,aAAmB,aAAO,OAAO;AACvC,aAAW,UAAU;AAiBrB,QAAM,iBACE,cAAQ,MAAM;AAClB,QAAI,OAAO;AACT,UAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,MACF;AAEA,YAAM,aAAa,OAAO,cAAc;AAKxC,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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eACd,cAAc,MAAM;AAE1B,cAAI,kBAAkB;AACpB,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,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,KAAK,CAAC;AAEpB,EAAM,gBAAU,MAAM;AACpB,QAAI,gBAAgB;AAClB,qCAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAAA,IACjE;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}
@@ -11,10 +11,9 @@ var HydrationBoundary = ({
11
11
  queryClient
12
12
  }) => {
13
13
  const client = useQueryClient(queryClient);
14
- const [hydrationQueue, setHydrationQueue] = React.useState();
15
14
  const optionsRef = React.useRef(options);
16
15
  optionsRef.current = options;
17
- React.useMemo(() => {
16
+ const hydrationQueue = React.useMemo(() => {
18
17
  if (state) {
19
18
  if (typeof state !== "object") {
20
19
  return;
@@ -29,10 +28,7 @@ var HydrationBoundary = ({
29
28
  newQueries.push(dehydratedQuery);
30
29
  } else {
31
30
  const hydrationIsNewer = dehydratedQuery.state.dataUpdatedAt > existingQuery.state.dataUpdatedAt || dehydratedQuery.promise && existingQuery.state.status !== "pending" && existingQuery.state.fetchStatus !== "fetching" && dehydratedQuery.dehydratedAt !== void 0 && dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt;
32
- const queryAlreadyQueued = hydrationQueue == null ? void 0 : hydrationQueue.find(
33
- (query) => query.queryHash === dehydratedQuery.queryHash
34
- );
35
- if (hydrationIsNewer && (!queryAlreadyQueued || dehydratedQuery.state.dataUpdatedAt > queryAlreadyQueued.state.dataUpdatedAt)) {
31
+ if (hydrationIsNewer) {
36
32
  existingQueries.push(dehydratedQuery);
37
33
  }
38
34
  }
@@ -41,16 +37,14 @@ var HydrationBoundary = ({
41
37
  hydrate(client, { queries: newQueries }, optionsRef.current);
42
38
  }
43
39
  if (existingQueries.length > 0) {
44
- setHydrationQueue(
45
- (prev) => prev ? [...prev, ...existingQueries] : existingQueries
46
- );
40
+ return existingQueries;
47
41
  }
48
42
  }
49
- }, [client, hydrationQueue, state]);
43
+ return void 0;
44
+ }, [client, state]);
50
45
  React.useEffect(() => {
51
46
  if (hydrationQueue) {
52
47
  hydrate(client, { queries: hydrationQueue }, optionsRef.current);
53
- setHydrationQueue(void 0);
54
48
  }
55
49
  }, [client, hydrationQueue]);
56
50
  return children;
@@ -1 +1 @@
1
- {"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 @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt)\n\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 // eslint-disable-next-line react-hooks/react-compiler\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":";;;AACA,YAAY,WAAW;AAEvB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAoBxB,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AAAA,EACA;AACF,MAA8B;AAC5B,QAAM,SAAS,eAAe,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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eAAe,cAAc,MAAM;AAEvD,gBAAM,qBAAqB,iDAAgB;AAAA,YACzC,CAAC,UAAU,MAAM,cAAc,gBAAgB;AAAA;AAGjD,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,gBAAQ,QAAQ,EAAE,SAAS,WAAW,GAAG,WAAW,OAAO;AAAA,MAC7D;AACA,UAAI,gBAAgB,SAAS,GAAG;AAE9B;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,cAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAC/D,wBAAkB,MAAS;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}
1
+ {"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\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 const hydrationQueue: DehydratedState['queries'] | undefined =\n React.useMemo(() => {\n if (state) {\n if (typeof state !== 'object') {\n return\n }\n\n const queryCache = client.getQueryCache()\n // State is supplied from the outside and we might as well fail\n // gracefully if it has the wrong shape, so while we type `queries`\n // as required, we still provide a fallback.\n // eslint-disable-next-line @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt >\n existingQuery.state.dataUpdatedAt)\n\n if (hydrationIsNewer) {\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 return existingQueries\n }\n }\n return undefined\n }, [client, state])\n\n React.useEffect(() => {\n if (hydrationQueue) {\n hydrate(client, { queries: hydrationQueue }, optionsRef.current)\n }\n }, [client, hydrationQueue])\n\n return children as React.ReactElement\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAoBxB,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AAAA,EACA;AACF,MAA8B;AAC5B,QAAM,SAAS,eAAe,WAAW;AAEzC,QAAM,aAAmB,aAAO,OAAO;AACvC,aAAW,UAAU;AAiBrB,QAAM,iBACE,cAAQ,MAAM;AAClB,QAAI,OAAO;AACT,UAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,MACF;AAEA,YAAM,aAAa,OAAO,cAAc;AAKxC,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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eACd,cAAc,MAAM;AAE1B,cAAI,kBAAkB;AACpB,4BAAgB,KAAK,eAAe;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,SAAS,GAAG;AAGzB,gBAAQ,QAAQ,EAAE,SAAS,WAAW,GAAG,WAAW,OAAO;AAAA,MAC7D;AACA,UAAI,gBAAgB,SAAS,GAAG;AAC9B,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,KAAK,CAAC;AAEpB,EAAM,gBAAU,MAAM;AACpB,QAAI,gBAAgB;AAClB,cAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAAA,IACjE;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}
@@ -44,10 +44,9 @@ var HydrationBoundary = ({
44
44
  queryClient
45
45
  }) => {
46
46
  const client = (0, import_QueryClientProvider.useQueryClient)(queryClient);
47
- const [hydrationQueue, setHydrationQueue] = React.useState();
48
47
  const optionsRef = React.useRef(options);
49
48
  optionsRef.current = options;
50
- React.useMemo(() => {
49
+ const hydrationQueue = React.useMemo(() => {
51
50
  if (state) {
52
51
  if (typeof state !== "object") {
53
52
  return;
@@ -62,10 +61,7 @@ var HydrationBoundary = ({
62
61
  newQueries.push(dehydratedQuery);
63
62
  } else {
64
63
  const hydrationIsNewer = dehydratedQuery.state.dataUpdatedAt > existingQuery.state.dataUpdatedAt || dehydratedQuery.promise && existingQuery.state.status !== "pending" && existingQuery.state.fetchStatus !== "fetching" && dehydratedQuery.dehydratedAt !== void 0 && dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt;
65
- const queryAlreadyQueued = hydrationQueue?.find(
66
- (query) => query.queryHash === dehydratedQuery.queryHash
67
- );
68
- if (hydrationIsNewer && (!queryAlreadyQueued || dehydratedQuery.state.dataUpdatedAt > queryAlreadyQueued.state.dataUpdatedAt)) {
64
+ if (hydrationIsNewer) {
69
65
  existingQueries.push(dehydratedQuery);
70
66
  }
71
67
  }
@@ -74,16 +70,14 @@ var HydrationBoundary = ({
74
70
  (0, import_query_core.hydrate)(client, { queries: newQueries }, optionsRef.current);
75
71
  }
76
72
  if (existingQueries.length > 0) {
77
- setHydrationQueue(
78
- (prev) => prev ? [...prev, ...existingQueries] : existingQueries
79
- );
73
+ return existingQueries;
80
74
  }
81
75
  }
82
- }, [client, hydrationQueue, state]);
76
+ return void 0;
77
+ }, [client, state]);
83
78
  React.useEffect(() => {
84
79
  if (hydrationQueue) {
85
80
  (0, import_query_core.hydrate)(client, { queries: hydrationQueue }, optionsRef.current);
86
- setHydrationQueue(void 0);
87
81
  }
88
82
  }, [client, hydrationQueue]);
89
83
  return children;
@@ -1 +1 @@
1
- {"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 @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt)\n\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 // eslint-disable-next-line react-hooks/react-compiler\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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eAAe,cAAc,MAAM;AAEvD,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;AAE9B;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":[]}
1
+ {"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\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 const hydrationQueue: DehydratedState['queries'] | undefined =\n React.useMemo(() => {\n if (state) {\n if (typeof state !== 'object') {\n return\n }\n\n const queryCache = client.getQueryCache()\n // State is supplied from the outside and we might as well fail\n // gracefully if it has the wrong shape, so while we type `queries`\n // as required, we still provide a fallback.\n // eslint-disable-next-line @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt >\n existingQuery.state.dataUpdatedAt)\n\n if (hydrationIsNewer) {\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 return existingQueries\n }\n }\n return undefined\n }, [client, state])\n\n React.useEffect(() => {\n if (hydrationQueue) {\n hydrate(client, { queries: hydrationQueue }, optionsRef.current)\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;AAEzC,QAAM,aAAmB,aAAO,OAAO;AACvC,aAAW,UAAU;AAiBrB,QAAM,iBACE,cAAQ,MAAM;AAClB,QAAI,OAAO;AACT,UAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,MACF;AAEA,YAAM,aAAa,OAAO,cAAc;AAKxC,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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eACd,cAAc,MAAM;AAE1B,cAAI,kBAAkB;AACpB,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,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,KAAK,CAAC;AAEpB,EAAM,gBAAU,MAAM;AACpB,QAAI,gBAAgB;AAClB,qCAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAAA,IACjE;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}
@@ -11,10 +11,9 @@ var HydrationBoundary = ({
11
11
  queryClient
12
12
  }) => {
13
13
  const client = useQueryClient(queryClient);
14
- const [hydrationQueue, setHydrationQueue] = React.useState();
15
14
  const optionsRef = React.useRef(options);
16
15
  optionsRef.current = options;
17
- React.useMemo(() => {
16
+ const hydrationQueue = React.useMemo(() => {
18
17
  if (state) {
19
18
  if (typeof state !== "object") {
20
19
  return;
@@ -29,10 +28,7 @@ var HydrationBoundary = ({
29
28
  newQueries.push(dehydratedQuery);
30
29
  } else {
31
30
  const hydrationIsNewer = dehydratedQuery.state.dataUpdatedAt > existingQuery.state.dataUpdatedAt || dehydratedQuery.promise && existingQuery.state.status !== "pending" && existingQuery.state.fetchStatus !== "fetching" && dehydratedQuery.dehydratedAt !== void 0 && dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt;
32
- const queryAlreadyQueued = hydrationQueue?.find(
33
- (query) => query.queryHash === dehydratedQuery.queryHash
34
- );
35
- if (hydrationIsNewer && (!queryAlreadyQueued || dehydratedQuery.state.dataUpdatedAt > queryAlreadyQueued.state.dataUpdatedAt)) {
31
+ if (hydrationIsNewer) {
36
32
  existingQueries.push(dehydratedQuery);
37
33
  }
38
34
  }
@@ -41,16 +37,14 @@ var HydrationBoundary = ({
41
37
  hydrate(client, { queries: newQueries }, optionsRef.current);
42
38
  }
43
39
  if (existingQueries.length > 0) {
44
- setHydrationQueue(
45
- (prev) => prev ? [...prev, ...existingQueries] : existingQueries
46
- );
40
+ return existingQueries;
47
41
  }
48
42
  }
49
- }, [client, hydrationQueue, state]);
43
+ return void 0;
44
+ }, [client, state]);
50
45
  React.useEffect(() => {
51
46
  if (hydrationQueue) {
52
47
  hydrate(client, { queries: hydrationQueue }, optionsRef.current);
53
- setHydrationQueue(void 0);
54
48
  }
55
49
  }, [client, hydrationQueue]);
56
50
  return children;
@@ -1 +1 @@
1
- {"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 @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt)\n\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 // eslint-disable-next-line react-hooks/react-compiler\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":";;;AACA,YAAY,WAAW;AAEvB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAoBxB,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AAAA,EACA;AACF,MAA8B;AAC5B,QAAM,SAAS,eAAe,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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eAAe,cAAc,MAAM;AAEvD,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,gBAAQ,QAAQ,EAAE,SAAS,WAAW,GAAG,WAAW,OAAO;AAAA,MAC7D;AACA,UAAI,gBAAgB,SAAS,GAAG;AAE9B;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,cAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAC/D,wBAAkB,MAAS;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}
1
+ {"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\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 const hydrationQueue: DehydratedState['queries'] | undefined =\n React.useMemo(() => {\n if (state) {\n if (typeof state !== 'object') {\n return\n }\n\n const queryCache = client.getQueryCache()\n // State is supplied from the outside and we might as well fail\n // gracefully if it has the wrong shape, so while we type `queries`\n // as required, we still provide a fallback.\n // eslint-disable-next-line @typescript-eslint/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 (dehydratedQuery.promise &&\n existingQuery.state.status !== 'pending' &&\n existingQuery.state.fetchStatus !== 'fetching' &&\n dehydratedQuery.dehydratedAt !== undefined &&\n dehydratedQuery.dehydratedAt >\n existingQuery.state.dataUpdatedAt)\n\n if (hydrationIsNewer) {\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 return existingQueries\n }\n }\n return undefined\n }, [client, state])\n\n React.useEffect(() => {\n if (hydrationQueue) {\n hydrate(client, { queries: hydrationQueue }, optionsRef.current)\n }\n }, [client, hydrationQueue])\n\n return children as React.ReactElement\n}\n"],"mappings":";;;AACA,YAAY,WAAW;AAEvB,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAoBxB,IAAM,oBAAoB,CAAC;AAAA,EAChC;AAAA,EACA,UAAU,CAAC;AAAA,EACX;AAAA,EACA;AACF,MAA8B;AAC5B,QAAM,SAAS,eAAe,WAAW;AAEzC,QAAM,aAAmB,aAAO,OAAO;AACvC,aAAW,UAAU;AAiBrB,QAAM,iBACE,cAAQ,MAAM;AAClB,QAAI,OAAO;AACT,UAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,MACF;AAEA,YAAM,aAAa,OAAO,cAAc;AAKxC,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,gBACpB,cAAc,MAAM,iBACrB,gBAAgB,WACf,cAAc,MAAM,WAAW,aAC/B,cAAc,MAAM,gBAAgB,cACpC,gBAAgB,iBAAiB,UACjC,gBAAgB,eACd,cAAc,MAAM;AAE1B,cAAI,kBAAkB;AACpB,4BAAgB,KAAK,eAAe;AAAA,UACtC;AAAA,QACF;AAAA,MACF;AAEA,UAAI,WAAW,SAAS,GAAG;AAGzB,gBAAQ,QAAQ,EAAE,SAAS,WAAW,GAAG,WAAW,OAAO;AAAA,MAC7D;AACA,UAAI,gBAAgB,SAAS,GAAG;AAC9B,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,KAAK,CAAC;AAEpB,EAAM,gBAAU,MAAM;AACpB,QAAI,gBAAgB;AAClB,cAAQ,QAAQ,EAAE,SAAS,eAAe,GAAG,WAAW,OAAO;AAAA,IACjE;AAAA,EACF,GAAG,CAAC,QAAQ,cAAc,CAAC;AAE3B,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-query",
3
- "version": "5.80.2",
3
+ "version": "5.80.3",
4
4
  "description": "Hooks for managing, caching and syncing asynchronous and remote data in React",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -56,8 +56,8 @@
56
56
  "react": "^19.0.0",
57
57
  "react-dom": "^19.0.0",
58
58
  "react-error-boundary": "^4.1.2",
59
- "@tanstack/query-persist-client-core": "5.80.2",
60
- "@tanstack/query-test-utils": "0.0.0"
59
+ "@tanstack/query-test-utils": "0.0.0",
60
+ "@tanstack/query-persist-client-core": "5.80.2"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "react": "^18 || ^19"
@@ -29,9 +29,6 @@ export const HydrationBoundary = ({
29
29
  queryClient,
30
30
  }: HydrationBoundaryProps) => {
31
31
  const client = useQueryClient(queryClient)
32
- const [hydrationQueue, setHydrationQueue] = React.useState<
33
- DehydratedState['queries'] | undefined
34
- >()
35
32
 
36
33
  const optionsRef = React.useRef(options)
37
34
  optionsRef.current = options
@@ -51,66 +48,59 @@ export const HydrationBoundary = ({
51
48
  // If the transition is aborted, we will have hydrated any _new_ queries, but
52
49
  // we throw away the fresh data for any existing ones to avoid unexpectedly
53
50
  // updating the UI.
54
- React.useMemo(() => {
55
- if (state) {
56
- if (typeof state !== 'object') {
57
- return
58
- }
59
-
60
- const queryCache = client.getQueryCache()
61
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
62
- const queries = (state as DehydratedState).queries || []
63
-
64
- const newQueries: DehydratedState['queries'] = []
65
- const existingQueries: DehydratedState['queries'] = []
66
- for (const dehydratedQuery of queries) {
67
- const existingQuery = queryCache.get(dehydratedQuery.queryHash)
51
+ const hydrationQueue: DehydratedState['queries'] | undefined =
52
+ React.useMemo(() => {
53
+ if (state) {
54
+ if (typeof state !== 'object') {
55
+ return
56
+ }
68
57
 
69
- if (!existingQuery) {
70
- newQueries.push(dehydratedQuery)
71
- } else {
72
- const hydrationIsNewer =
73
- dehydratedQuery.state.dataUpdatedAt >
74
- existingQuery.state.dataUpdatedAt ||
75
- (dehydratedQuery.promise &&
76
- existingQuery.state.status !== 'pending' &&
77
- existingQuery.state.fetchStatus !== 'fetching' &&
78
- dehydratedQuery.dehydratedAt !== undefined &&
79
- dehydratedQuery.dehydratedAt > existingQuery.state.dataUpdatedAt)
58
+ const queryCache = client.getQueryCache()
59
+ // State is supplied from the outside and we might as well fail
60
+ // gracefully if it has the wrong shape, so while we type `queries`
61
+ // as required, we still provide a fallback.
62
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
63
+ const queries = (state as DehydratedState).queries || []
80
64
 
81
- const queryAlreadyQueued = hydrationQueue?.find(
82
- (query) => query.queryHash === dehydratedQuery.queryHash,
83
- )
65
+ const newQueries: DehydratedState['queries'] = []
66
+ const existingQueries: DehydratedState['queries'] = []
67
+ for (const dehydratedQuery of queries) {
68
+ const existingQuery = queryCache.get(dehydratedQuery.queryHash)
84
69
 
85
- if (
86
- hydrationIsNewer &&
87
- (!queryAlreadyQueued ||
70
+ if (!existingQuery) {
71
+ newQueries.push(dehydratedQuery)
72
+ } else {
73
+ const hydrationIsNewer =
88
74
  dehydratedQuery.state.dataUpdatedAt >
89
- queryAlreadyQueued.state.dataUpdatedAt)
90
- ) {
91
- existingQueries.push(dehydratedQuery)
75
+ existingQuery.state.dataUpdatedAt ||
76
+ (dehydratedQuery.promise &&
77
+ existingQuery.state.status !== 'pending' &&
78
+ existingQuery.state.fetchStatus !== 'fetching' &&
79
+ dehydratedQuery.dehydratedAt !== undefined &&
80
+ dehydratedQuery.dehydratedAt >
81
+ existingQuery.state.dataUpdatedAt)
82
+
83
+ if (hydrationIsNewer) {
84
+ existingQueries.push(dehydratedQuery)
85
+ }
92
86
  }
93
87
  }
94
- }
95
88
 
96
- if (newQueries.length > 0) {
97
- // It's actually fine to call this with queries/state that already exists
98
- // in the cache, or is older. hydrate() is idempotent for queries.
99
- hydrate(client, { queries: newQueries }, optionsRef.current)
100
- }
101
- if (existingQueries.length > 0) {
102
- // eslint-disable-next-line react-hooks/react-compiler
103
- setHydrationQueue((prev) =>
104
- prev ? [...prev, ...existingQueries] : existingQueries,
105
- )
89
+ if (newQueries.length > 0) {
90
+ // It's actually fine to call this with queries/state that already exists
91
+ // in the cache, or is older. hydrate() is idempotent for queries.
92
+ hydrate(client, { queries: newQueries }, optionsRef.current)
93
+ }
94
+ if (existingQueries.length > 0) {
95
+ return existingQueries
96
+ }
106
97
  }
107
- }
108
- }, [client, hydrationQueue, state])
98
+ return undefined
99
+ }, [client, state])
109
100
 
110
101
  React.useEffect(() => {
111
102
  if (hydrationQueue) {
112
103
  hydrate(client, { queries: hydrationQueue }, optionsRef.current)
113
- setHydrationQueue(undefined)
114
104
  }
115
105
  }, [client, hydrationQueue])
116
106