@tanstack/router-ssr-query-core 1.166.7 → 1.166.9

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.
@@ -1,138 +1,113 @@
1
- "use strict";
2
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const queryCore = require("@tanstack/query-core");
4
- const routerCore = require("@tanstack/router-core");
5
- const isServer = require("@tanstack/router-core/isServer");
6
- function setupCoreRouterSsrQueryIntegration({
7
- router,
8
- queryClient,
9
- handleRedirects = true
10
- }) {
11
- const ogHydrate = router.options.hydrate;
12
- const ogDehydrate = router.options.dehydrate;
13
- if (isServer.isServer ?? router.isServer) {
14
- const sentQueries = /* @__PURE__ */ new Set();
15
- const queryStream = createPushableStream();
16
- let unsubscribe = void 0;
17
- router.options.dehydrate = async () => {
18
- router.serverSsr.onRenderFinished(() => {
19
- queryStream.close();
20
- unsubscribe?.();
21
- unsubscribe = void 0;
22
- });
23
- const ogDehydrated = await ogDehydrate?.();
24
- const dehydratedRouter = {
25
- ...ogDehydrated,
26
- // prepare the stream for queries coming up during rendering
27
- queryStream: queryStream.stream
28
- };
29
- const dehydratedQueryClient = queryCore.dehydrate(queryClient);
30
- if (dehydratedQueryClient.queries.length > 0) {
31
- dehydratedQueryClient.queries.forEach((query) => {
32
- sentQueries.add(query.queryHash);
33
- });
34
- dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient;
35
- }
36
- return dehydratedRouter;
37
- };
38
- const ogClientOptions = queryClient.getDefaultOptions();
39
- queryClient.setDefaultOptions({
40
- ...ogClientOptions,
41
- dehydrate: {
42
- shouldDehydrateQuery: () => true,
43
- ...ogClientOptions.dehydrate
44
- }
45
- });
46
- unsubscribe = queryClient.getQueryCache().subscribe((event) => {
47
- if (!router.serverSsr?.isDehydrated()) {
48
- return;
49
- }
50
- if (sentQueries.has(event.query.queryHash)) {
51
- return;
52
- }
53
- if (!event.query.promise) {
54
- return;
55
- }
56
- if (queryStream.isClosed()) {
57
- console.warn(
58
- `tried to stream query ${event.query.queryHash} after stream was already closed`
59
- );
60
- return;
61
- }
62
- sentQueries.add(event.query.queryHash);
63
- queryStream.enqueue(
64
- queryCore.dehydrate(queryClient, {
65
- shouldDehydrateQuery: (query) => {
66
- if (query.queryHash === event.query.queryHash) {
67
- return ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true;
68
- }
69
- return false;
70
- }
71
- })
72
- );
73
- });
74
- } else {
75
- router.options.hydrate = async (dehydrated) => {
76
- await ogHydrate?.(dehydrated);
77
- if (dehydrated.dehydratedQueryClient) {
78
- queryCore.hydrate(queryClient, dehydrated.dehydratedQueryClient);
79
- }
80
- const reader = dehydrated.queryStream.getReader();
81
- reader.read().then(async function handle({ done, value }) {
82
- queryCore.hydrate(queryClient, value);
83
- if (done) {
84
- return;
85
- }
86
- const result = await reader.read();
87
- return handle(result);
88
- }).catch((err) => {
89
- console.error("Error reading query stream:", err);
90
- });
91
- };
92
- if (handleRedirects) {
93
- const ogMutationCacheConfig = queryClient.getMutationCache().config;
94
- queryClient.getMutationCache().config = {
95
- ...ogMutationCacheConfig,
96
- onError: (error, ...rest) => {
97
- if (routerCore.isRedirect(error)) {
98
- error.options._fromLocation = router.state.location;
99
- return router.navigate(router.resolveRedirect(error).options);
100
- }
101
- return ogMutationCacheConfig.onError?.(error, ...rest);
102
- }
103
- };
104
- const ogQueryCacheConfig = queryClient.getQueryCache().config;
105
- queryClient.getQueryCache().config = {
106
- ...ogQueryCacheConfig,
107
- onError: (error, ...rest) => {
108
- if (routerCore.isRedirect(error)) {
109
- error.options._fromLocation = router.state.location;
110
- return router.navigate(router.resolveRedirect(error).options);
111
- }
112
- return ogQueryCacheConfig.onError?.(error, ...rest);
113
- }
114
- };
115
- }
116
- }
2
+ let _tanstack_query_core = require("@tanstack/query-core");
3
+ let _tanstack_router_core = require("@tanstack/router-core");
4
+ let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
5
+ //#region src/index.ts
6
+ function setupCoreRouterSsrQueryIntegration({ router, queryClient, handleRedirects = true }) {
7
+ const ogHydrate = router.options.hydrate;
8
+ const ogDehydrate = router.options.dehydrate;
9
+ if (_tanstack_router_core_isServer.isServer ?? router.isServer) {
10
+ const sentQueries = /* @__PURE__ */ new Set();
11
+ const queryStream = createPushableStream();
12
+ let unsubscribe = void 0;
13
+ router.options.dehydrate = async () => {
14
+ router.serverSsr.onRenderFinished(() => {
15
+ queryStream.close();
16
+ unsubscribe?.();
17
+ unsubscribe = void 0;
18
+ });
19
+ const dehydratedRouter = {
20
+ ...await ogDehydrate?.(),
21
+ queryStream: queryStream.stream
22
+ };
23
+ const dehydratedQueryClient = (0, _tanstack_query_core.dehydrate)(queryClient);
24
+ if (dehydratedQueryClient.queries.length > 0) {
25
+ dehydratedQueryClient.queries.forEach((query) => {
26
+ sentQueries.add(query.queryHash);
27
+ });
28
+ dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient;
29
+ }
30
+ return dehydratedRouter;
31
+ };
32
+ const ogClientOptions = queryClient.getDefaultOptions();
33
+ queryClient.setDefaultOptions({
34
+ ...ogClientOptions,
35
+ dehydrate: {
36
+ shouldDehydrateQuery: () => true,
37
+ ...ogClientOptions.dehydrate
38
+ }
39
+ });
40
+ unsubscribe = queryClient.getQueryCache().subscribe((event) => {
41
+ if (!router.serverSsr?.isDehydrated()) return;
42
+ if (sentQueries.has(event.query.queryHash)) return;
43
+ if (!event.query.promise) return;
44
+ if (queryStream.isClosed()) {
45
+ console.warn(`tried to stream query ${event.query.queryHash} after stream was already closed`);
46
+ return;
47
+ }
48
+ sentQueries.add(event.query.queryHash);
49
+ queryStream.enqueue((0, _tanstack_query_core.dehydrate)(queryClient, { shouldDehydrateQuery: (query) => {
50
+ if (query.queryHash === event.query.queryHash) return ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true;
51
+ return false;
52
+ } }));
53
+ });
54
+ } else {
55
+ router.options.hydrate = async (dehydrated) => {
56
+ await ogHydrate?.(dehydrated);
57
+ if (dehydrated.dehydratedQueryClient) (0, _tanstack_query_core.hydrate)(queryClient, dehydrated.dehydratedQueryClient);
58
+ const reader = dehydrated.queryStream.getReader();
59
+ reader.read().then(async function handle({ done, value }) {
60
+ (0, _tanstack_query_core.hydrate)(queryClient, value);
61
+ if (done) return;
62
+ return handle(await reader.read());
63
+ }).catch((err) => {
64
+ console.error("Error reading query stream:", err);
65
+ });
66
+ };
67
+ if (handleRedirects) {
68
+ const ogMutationCacheConfig = queryClient.getMutationCache().config;
69
+ queryClient.getMutationCache().config = {
70
+ ...ogMutationCacheConfig,
71
+ onError: (error, ...rest) => {
72
+ if ((0, _tanstack_router_core.isRedirect)(error)) {
73
+ error.options._fromLocation = router.state.location;
74
+ return router.navigate(router.resolveRedirect(error).options);
75
+ }
76
+ return ogMutationCacheConfig.onError?.(error, ...rest);
77
+ }
78
+ };
79
+ const ogQueryCacheConfig = queryClient.getQueryCache().config;
80
+ queryClient.getQueryCache().config = {
81
+ ...ogQueryCacheConfig,
82
+ onError: (error, ...rest) => {
83
+ if ((0, _tanstack_router_core.isRedirect)(error)) {
84
+ error.options._fromLocation = router.state.location;
85
+ return router.navigate(router.resolveRedirect(error).options);
86
+ }
87
+ return ogQueryCacheConfig.onError?.(error, ...rest);
88
+ }
89
+ };
90
+ }
91
+ }
117
92
  }
118
93
  function createPushableStream() {
119
- let controllerRef;
120
- const stream = new ReadableStream({
121
- start(controller) {
122
- controllerRef = controller;
123
- }
124
- });
125
- let _isClosed = false;
126
- return {
127
- stream,
128
- enqueue: (chunk) => controllerRef.enqueue(chunk),
129
- close: () => {
130
- controllerRef.close();
131
- _isClosed = true;
132
- },
133
- isClosed: () => _isClosed,
134
- error: (err) => controllerRef.error(err)
135
- };
94
+ let controllerRef;
95
+ const stream = new ReadableStream({ start(controller) {
96
+ controllerRef = controller;
97
+ } });
98
+ let _isClosed = false;
99
+ return {
100
+ stream,
101
+ enqueue: (chunk) => controllerRef.enqueue(chunk),
102
+ close: () => {
103
+ controllerRef.close();
104
+ _isClosed = true;
105
+ },
106
+ isClosed: () => _isClosed,
107
+ error: (err) => controllerRef.error(err)
108
+ };
136
109
  }
110
+ //#endregion
137
111
  exports.setupCoreRouterSsrQueryIntegration = setupCoreRouterSsrQueryIntegration;
138
- //# sourceMappingURL=index.cjs.map
112
+
113
+ //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import {\n dehydrate as queryDehydrate,\n hydrate as queryHydrate,\n} from '@tanstack/query-core'\nimport { isRedirect } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport type { AnyRouter } from '@tanstack/router-core'\nimport type {\n QueryClient,\n DehydratedState as QueryDehydratedState,\n} from '@tanstack/query-core'\n\nexport type RouterSsrQueryOptions<TRouter extends AnyRouter> = {\n router: TRouter\n queryClient: QueryClient\n\n /**\n * If `true`, the QueryClient will handle errors thrown by `redirect()` inside of mutations and queries.\n *\n * @default true\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction)\n */\n handleRedirects?: boolean\n}\n\ntype DehydratedRouterQueryState = {\n dehydratedQueryClient?: QueryDehydratedState\n queryStream: ReadableStream<QueryDehydratedState>\n}\n\nexport function setupCoreRouterSsrQueryIntegration<TRouter extends AnyRouter>({\n router,\n queryClient,\n handleRedirects = true,\n}: RouterSsrQueryOptions<TRouter>) {\n const ogHydrate = router.options.hydrate\n const ogDehydrate = router.options.dehydrate\n\n if (isServer ?? router.isServer) {\n const sentQueries = new Set<string>()\n const queryStream = createPushableStream()\n let unsubscribe: (() => void) | undefined = undefined\n router.options.dehydrate =\n async (): Promise<DehydratedRouterQueryState> => {\n router.serverSsr!.onRenderFinished(() => {\n queryStream.close()\n unsubscribe?.()\n unsubscribe = undefined\n })\n const ogDehydrated = await ogDehydrate?.()\n\n const dehydratedRouter = {\n ...ogDehydrated,\n // prepare the stream for queries coming up during rendering\n queryStream: queryStream.stream,\n }\n\n const dehydratedQueryClient = queryDehydrate(queryClient)\n if (dehydratedQueryClient.queries.length > 0) {\n dehydratedQueryClient.queries.forEach((query) => {\n sentQueries.add(query.queryHash)\n })\n dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient\n }\n\n return dehydratedRouter\n }\n\n const ogClientOptions = queryClient.getDefaultOptions()\n queryClient.setDefaultOptions({\n ...ogClientOptions,\n dehydrate: {\n shouldDehydrateQuery: () => true,\n ...ogClientOptions.dehydrate,\n },\n })\n\n unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n // before rendering starts, we do not stream individual queries\n // instead we dehydrate the entire query client in router's dehydrate()\n // if attachRouterServerSsrUtils() has not been called yet, `router.serverSsr` will be undefined and we also do not stream\n if (!router.serverSsr?.isDehydrated()) {\n return\n }\n if (sentQueries.has(event.query.queryHash)) {\n return\n }\n // promise not yet set on the query, so we cannot stream it yet\n if (!event.query.promise) {\n return\n }\n if (queryStream.isClosed()) {\n console.warn(\n `tried to stream query ${event.query.queryHash} after stream was already closed`,\n )\n return\n }\n sentQueries.add(event.query.queryHash)\n queryStream.enqueue(\n queryDehydrate(queryClient, {\n shouldDehydrateQuery: (query) => {\n if (query.queryHash === event.query.queryHash) {\n return (\n ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true\n )\n }\n return false\n },\n }),\n )\n })\n // on the client\n } else {\n router.options.hydrate = async (dehydrated: DehydratedRouterQueryState) => {\n await ogHydrate?.(dehydrated)\n // hydrate the query client with the dehydrated data (if it was dehydrated on the server)\n if (dehydrated.dehydratedQueryClient) {\n queryHydrate(queryClient, dehydrated.dehydratedQueryClient)\n }\n\n // read the query stream and hydrate the queries as they come in\n const reader = dehydrated.queryStream.getReader()\n reader\n .read()\n .then(async function handle({ done, value }) {\n queryHydrate(queryClient, value)\n if (done) {\n return\n }\n const result = await reader.read()\n return handle(result)\n })\n .catch((err) => {\n console.error('Error reading query stream:', err)\n })\n }\n if (handleRedirects) {\n const ogMutationCacheConfig = queryClient.getMutationCache().config\n queryClient.getMutationCache().config = {\n ...ogMutationCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogMutationCacheConfig.onError?.(error, ...rest)\n },\n }\n\n const ogQueryCacheConfig = queryClient.getQueryCache().config\n queryClient.getQueryCache().config = {\n ...ogQueryCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogQueryCacheConfig.onError?.(error, ...rest)\n },\n }\n }\n }\n}\n\ntype PushableStream = {\n stream: ReadableStream\n enqueue: (chunk: unknown) => void\n close: () => void\n isClosed: () => boolean\n error: (err: unknown) => void\n}\n\nfunction createPushableStream(): PushableStream {\n let controllerRef: ReadableStreamDefaultController\n const stream = new ReadableStream({\n start(controller) {\n controllerRef = controller\n },\n })\n let _isClosed = false\n\n return {\n stream,\n enqueue: (chunk) => controllerRef.enqueue(chunk),\n close: () => {\n controllerRef.close()\n _isClosed = true\n },\n isClosed: () => _isClosed,\n error: (err: unknown) => controllerRef.error(err),\n }\n}\n"],"names":["isServer","queryDehydrate","queryHydrate","isRedirect"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import {\n dehydrate as queryDehydrate,\n hydrate as queryHydrate,\n} from '@tanstack/query-core'\nimport { isRedirect } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport type { AnyRouter } from '@tanstack/router-core'\nimport type {\n QueryClient,\n DehydratedState as QueryDehydratedState,\n} from '@tanstack/query-core'\n\nexport type RouterSsrQueryOptions<TRouter extends AnyRouter> = {\n router: TRouter\n queryClient: QueryClient\n\n /**\n * If `true`, the QueryClient will handle errors thrown by `redirect()` inside of mutations and queries.\n *\n * @default true\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction)\n */\n handleRedirects?: boolean\n}\n\ntype DehydratedRouterQueryState = {\n dehydratedQueryClient?: QueryDehydratedState\n queryStream: ReadableStream<QueryDehydratedState>\n}\n\nexport function setupCoreRouterSsrQueryIntegration<TRouter extends AnyRouter>({\n router,\n queryClient,\n handleRedirects = true,\n}: RouterSsrQueryOptions<TRouter>) {\n const ogHydrate = router.options.hydrate\n const ogDehydrate = router.options.dehydrate\n\n if (isServer ?? router.isServer) {\n const sentQueries = new Set<string>()\n const queryStream = createPushableStream()\n let unsubscribe: (() => void) | undefined = undefined\n router.options.dehydrate =\n async (): Promise<DehydratedRouterQueryState> => {\n router.serverSsr!.onRenderFinished(() => {\n queryStream.close()\n unsubscribe?.()\n unsubscribe = undefined\n })\n const ogDehydrated = await ogDehydrate?.()\n\n const dehydratedRouter = {\n ...ogDehydrated,\n // prepare the stream for queries coming up during rendering\n queryStream: queryStream.stream,\n }\n\n const dehydratedQueryClient = queryDehydrate(queryClient)\n if (dehydratedQueryClient.queries.length > 0) {\n dehydratedQueryClient.queries.forEach((query) => {\n sentQueries.add(query.queryHash)\n })\n dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient\n }\n\n return dehydratedRouter\n }\n\n const ogClientOptions = queryClient.getDefaultOptions()\n queryClient.setDefaultOptions({\n ...ogClientOptions,\n dehydrate: {\n shouldDehydrateQuery: () => true,\n ...ogClientOptions.dehydrate,\n },\n })\n\n unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n // before rendering starts, we do not stream individual queries\n // instead we dehydrate the entire query client in router's dehydrate()\n // if attachRouterServerSsrUtils() has not been called yet, `router.serverSsr` will be undefined and we also do not stream\n if (!router.serverSsr?.isDehydrated()) {\n return\n }\n if (sentQueries.has(event.query.queryHash)) {\n return\n }\n // promise not yet set on the query, so we cannot stream it yet\n if (!event.query.promise) {\n return\n }\n if (queryStream.isClosed()) {\n console.warn(\n `tried to stream query ${event.query.queryHash} after stream was already closed`,\n )\n return\n }\n sentQueries.add(event.query.queryHash)\n queryStream.enqueue(\n queryDehydrate(queryClient, {\n shouldDehydrateQuery: (query) => {\n if (query.queryHash === event.query.queryHash) {\n return (\n ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true\n )\n }\n return false\n },\n }),\n )\n })\n // on the client\n } else {\n router.options.hydrate = async (dehydrated: DehydratedRouterQueryState) => {\n await ogHydrate?.(dehydrated)\n // hydrate the query client with the dehydrated data (if it was dehydrated on the server)\n if (dehydrated.dehydratedQueryClient) {\n queryHydrate(queryClient, dehydrated.dehydratedQueryClient)\n }\n\n // read the query stream and hydrate the queries as they come in\n const reader = dehydrated.queryStream.getReader()\n reader\n .read()\n .then(async function handle({ done, value }) {\n queryHydrate(queryClient, value)\n if (done) {\n return\n }\n const result = await reader.read()\n return handle(result)\n })\n .catch((err) => {\n console.error('Error reading query stream:', err)\n })\n }\n if (handleRedirects) {\n const ogMutationCacheConfig = queryClient.getMutationCache().config\n queryClient.getMutationCache().config = {\n ...ogMutationCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogMutationCacheConfig.onError?.(error, ...rest)\n },\n }\n\n const ogQueryCacheConfig = queryClient.getQueryCache().config\n queryClient.getQueryCache().config = {\n ...ogQueryCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogQueryCacheConfig.onError?.(error, ...rest)\n },\n }\n }\n }\n}\n\ntype PushableStream = {\n stream: ReadableStream\n enqueue: (chunk: unknown) => void\n close: () => void\n isClosed: () => boolean\n error: (err: unknown) => void\n}\n\nfunction createPushableStream(): PushableStream {\n let controllerRef: ReadableStreamDefaultController\n const stream = new ReadableStream({\n start(controller) {\n controllerRef = controller\n },\n })\n let _isClosed = false\n\n return {\n stream,\n enqueue: (chunk) => controllerRef.enqueue(chunk),\n close: () => {\n controllerRef.close()\n _isClosed = true\n },\n isClosed: () => _isClosed,\n error: (err: unknown) => controllerRef.error(err),\n }\n}\n"],"mappings":";;;;;AA8BA,SAAgB,mCAA8D,EAC5E,QACA,aACA,kBAAkB,QACe;CACjC,MAAM,YAAY,OAAO,QAAQ;CACjC,MAAM,cAAc,OAAO,QAAQ;AAEnC,KAAI,+BAAA,YAAY,OAAO,UAAU;EAC/B,MAAM,8BAAc,IAAI,KAAa;EACrC,MAAM,cAAc,sBAAsB;EAC1C,IAAI,cAAwC,KAAA;AAC5C,SAAO,QAAQ,YACb,YAAiD;AAC/C,UAAO,UAAW,uBAAuB;AACvC,gBAAY,OAAO;AACnB,mBAAe;AACf,kBAAc,KAAA;KACd;GAGF,MAAM,mBAAmB;IACvB,GAHmB,MAAM,eAAe;IAKxC,aAAa,YAAY;IAC1B;GAED,MAAM,yBAAA,GAAA,qBAAA,WAAuC,YAAY;AACzD,OAAI,sBAAsB,QAAQ,SAAS,GAAG;AAC5C,0BAAsB,QAAQ,SAAS,UAAU;AAC/C,iBAAY,IAAI,MAAM,UAAU;MAChC;AACF,qBAAiB,wBAAwB;;AAG3C,UAAO;;EAGX,MAAM,kBAAkB,YAAY,mBAAmB;AACvD,cAAY,kBAAkB;GAC5B,GAAG;GACH,WAAW;IACT,4BAA4B;IAC5B,GAAG,gBAAgB;IACpB;GACF,CAAC;AAEF,gBAAc,YAAY,eAAe,CAAC,WAAW,UAAU;AAI7D,OAAI,CAAC,OAAO,WAAW,cAAc,CACnC;AAEF,OAAI,YAAY,IAAI,MAAM,MAAM,UAAU,CACxC;AAGF,OAAI,CAAC,MAAM,MAAM,QACf;AAEF,OAAI,YAAY,UAAU,EAAE;AAC1B,YAAQ,KACN,yBAAyB,MAAM,MAAM,UAAU,kCAChD;AACD;;AAEF,eAAY,IAAI,MAAM,MAAM,UAAU;AACtC,eAAY,SAAA,GAAA,qBAAA,WACK,aAAa,EAC1B,uBAAuB,UAAU;AAC/B,QAAI,MAAM,cAAc,MAAM,MAAM,UAClC,QACE,gBAAgB,WAAW,uBAAuB,MAAM,IAAI;AAGhE,WAAO;MAEV,CAAC,CACH;IACD;QAEG;AACL,SAAO,QAAQ,UAAU,OAAO,eAA2C;AACzE,SAAM,YAAY,WAAW;AAE7B,OAAI,WAAW,sBACb,EAAA,GAAA,qBAAA,SAAa,aAAa,WAAW,sBAAsB;GAI7D,MAAM,SAAS,WAAW,YAAY,WAAW;AACjD,UACG,MAAM,CACN,KAAK,eAAe,OAAO,EAAE,MAAM,SAAS;AAC3C,KAAA,GAAA,qBAAA,SAAa,aAAa,MAAM;AAChC,QAAI,KACF;AAGF,WAAO,OADQ,MAAM,OAAO,MAAM,CACb;KACrB,CACD,OAAO,QAAQ;AACd,YAAQ,MAAM,+BAA+B,IAAI;KACjD;;AAEN,MAAI,iBAAiB;GACnB,MAAM,wBAAwB,YAAY,kBAAkB,CAAC;AAC7D,eAAY,kBAAkB,CAAC,SAAS;IACtC,GAAG;IACH,UAAU,OAAO,GAAG,SAAS;AAC3B,UAAA,GAAA,sBAAA,YAAe,MAAM,EAAE;AACrB,YAAM,QAAQ,gBAAgB,OAAO,MAAM;AAC3C,aAAO,OAAO,SAAS,OAAO,gBAAgB,MAAM,CAAC,QAAQ;;AAG/D,YAAO,sBAAsB,UAAU,OAAO,GAAG,KAAK;;IAEzD;GAED,MAAM,qBAAqB,YAAY,eAAe,CAAC;AACvD,eAAY,eAAe,CAAC,SAAS;IACnC,GAAG;IACH,UAAU,OAAO,GAAG,SAAS;AAC3B,UAAA,GAAA,sBAAA,YAAe,MAAM,EAAE;AACrB,YAAM,QAAQ,gBAAgB,OAAO,MAAM;AAC3C,aAAO,OAAO,SAAS,OAAO,gBAAgB,MAAM,CAAC,QAAQ;;AAG/D,YAAO,mBAAmB,UAAU,OAAO,GAAG,KAAK;;IAEtD;;;;AAaP,SAAS,uBAAuC;CAC9C,IAAI;CACJ,MAAM,SAAS,IAAI,eAAe,EAChC,MAAM,YAAY;AAChB,kBAAgB;IAEnB,CAAC;CACF,IAAI,YAAY;AAEhB,QAAO;EACL;EACA,UAAU,UAAU,cAAc,QAAQ,MAAM;EAChD,aAAa;AACX,iBAAc,OAAO;AACrB,eAAY;;EAEd,gBAAgB;EAChB,QAAQ,QAAiB,cAAc,MAAM,IAAI;EAClD"}
package/dist/esm/index.js CHANGED
@@ -1,138 +1,112 @@
1
1
  import { dehydrate, hydrate } from "@tanstack/query-core";
2
2
  import { isRedirect } from "@tanstack/router-core";
3
3
  import { isServer } from "@tanstack/router-core/isServer";
4
- function setupCoreRouterSsrQueryIntegration({
5
- router,
6
- queryClient,
7
- handleRedirects = true
8
- }) {
9
- const ogHydrate = router.options.hydrate;
10
- const ogDehydrate = router.options.dehydrate;
11
- if (isServer ?? router.isServer) {
12
- const sentQueries = /* @__PURE__ */ new Set();
13
- const queryStream = createPushableStream();
14
- let unsubscribe = void 0;
15
- router.options.dehydrate = async () => {
16
- router.serverSsr.onRenderFinished(() => {
17
- queryStream.close();
18
- unsubscribe?.();
19
- unsubscribe = void 0;
20
- });
21
- const ogDehydrated = await ogDehydrate?.();
22
- const dehydratedRouter = {
23
- ...ogDehydrated,
24
- // prepare the stream for queries coming up during rendering
25
- queryStream: queryStream.stream
26
- };
27
- const dehydratedQueryClient = dehydrate(queryClient);
28
- if (dehydratedQueryClient.queries.length > 0) {
29
- dehydratedQueryClient.queries.forEach((query) => {
30
- sentQueries.add(query.queryHash);
31
- });
32
- dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient;
33
- }
34
- return dehydratedRouter;
35
- };
36
- const ogClientOptions = queryClient.getDefaultOptions();
37
- queryClient.setDefaultOptions({
38
- ...ogClientOptions,
39
- dehydrate: {
40
- shouldDehydrateQuery: () => true,
41
- ...ogClientOptions.dehydrate
42
- }
43
- });
44
- unsubscribe = queryClient.getQueryCache().subscribe((event) => {
45
- if (!router.serverSsr?.isDehydrated()) {
46
- return;
47
- }
48
- if (sentQueries.has(event.query.queryHash)) {
49
- return;
50
- }
51
- if (!event.query.promise) {
52
- return;
53
- }
54
- if (queryStream.isClosed()) {
55
- console.warn(
56
- `tried to stream query ${event.query.queryHash} after stream was already closed`
57
- );
58
- return;
59
- }
60
- sentQueries.add(event.query.queryHash);
61
- queryStream.enqueue(
62
- dehydrate(queryClient, {
63
- shouldDehydrateQuery: (query) => {
64
- if (query.queryHash === event.query.queryHash) {
65
- return ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true;
66
- }
67
- return false;
68
- }
69
- })
70
- );
71
- });
72
- } else {
73
- router.options.hydrate = async (dehydrated) => {
74
- await ogHydrate?.(dehydrated);
75
- if (dehydrated.dehydratedQueryClient) {
76
- hydrate(queryClient, dehydrated.dehydratedQueryClient);
77
- }
78
- const reader = dehydrated.queryStream.getReader();
79
- reader.read().then(async function handle({ done, value }) {
80
- hydrate(queryClient, value);
81
- if (done) {
82
- return;
83
- }
84
- const result = await reader.read();
85
- return handle(result);
86
- }).catch((err) => {
87
- console.error("Error reading query stream:", err);
88
- });
89
- };
90
- if (handleRedirects) {
91
- const ogMutationCacheConfig = queryClient.getMutationCache().config;
92
- queryClient.getMutationCache().config = {
93
- ...ogMutationCacheConfig,
94
- onError: (error, ...rest) => {
95
- if (isRedirect(error)) {
96
- error.options._fromLocation = router.state.location;
97
- return router.navigate(router.resolveRedirect(error).options);
98
- }
99
- return ogMutationCacheConfig.onError?.(error, ...rest);
100
- }
101
- };
102
- const ogQueryCacheConfig = queryClient.getQueryCache().config;
103
- queryClient.getQueryCache().config = {
104
- ...ogQueryCacheConfig,
105
- onError: (error, ...rest) => {
106
- if (isRedirect(error)) {
107
- error.options._fromLocation = router.state.location;
108
- return router.navigate(router.resolveRedirect(error).options);
109
- }
110
- return ogQueryCacheConfig.onError?.(error, ...rest);
111
- }
112
- };
113
- }
114
- }
4
+ //#region src/index.ts
5
+ function setupCoreRouterSsrQueryIntegration({ router, queryClient, handleRedirects = true }) {
6
+ const ogHydrate = router.options.hydrate;
7
+ const ogDehydrate = router.options.dehydrate;
8
+ if (isServer ?? router.isServer) {
9
+ const sentQueries = /* @__PURE__ */ new Set();
10
+ const queryStream = createPushableStream();
11
+ let unsubscribe = void 0;
12
+ router.options.dehydrate = async () => {
13
+ router.serverSsr.onRenderFinished(() => {
14
+ queryStream.close();
15
+ unsubscribe?.();
16
+ unsubscribe = void 0;
17
+ });
18
+ const dehydratedRouter = {
19
+ ...await ogDehydrate?.(),
20
+ queryStream: queryStream.stream
21
+ };
22
+ const dehydratedQueryClient = dehydrate(queryClient);
23
+ if (dehydratedQueryClient.queries.length > 0) {
24
+ dehydratedQueryClient.queries.forEach((query) => {
25
+ sentQueries.add(query.queryHash);
26
+ });
27
+ dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient;
28
+ }
29
+ return dehydratedRouter;
30
+ };
31
+ const ogClientOptions = queryClient.getDefaultOptions();
32
+ queryClient.setDefaultOptions({
33
+ ...ogClientOptions,
34
+ dehydrate: {
35
+ shouldDehydrateQuery: () => true,
36
+ ...ogClientOptions.dehydrate
37
+ }
38
+ });
39
+ unsubscribe = queryClient.getQueryCache().subscribe((event) => {
40
+ if (!router.serverSsr?.isDehydrated()) return;
41
+ if (sentQueries.has(event.query.queryHash)) return;
42
+ if (!event.query.promise) return;
43
+ if (queryStream.isClosed()) {
44
+ console.warn(`tried to stream query ${event.query.queryHash} after stream was already closed`);
45
+ return;
46
+ }
47
+ sentQueries.add(event.query.queryHash);
48
+ queryStream.enqueue(dehydrate(queryClient, { shouldDehydrateQuery: (query) => {
49
+ if (query.queryHash === event.query.queryHash) return ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true;
50
+ return false;
51
+ } }));
52
+ });
53
+ } else {
54
+ router.options.hydrate = async (dehydrated) => {
55
+ await ogHydrate?.(dehydrated);
56
+ if (dehydrated.dehydratedQueryClient) hydrate(queryClient, dehydrated.dehydratedQueryClient);
57
+ const reader = dehydrated.queryStream.getReader();
58
+ reader.read().then(async function handle({ done, value }) {
59
+ hydrate(queryClient, value);
60
+ if (done) return;
61
+ return handle(await reader.read());
62
+ }).catch((err) => {
63
+ console.error("Error reading query stream:", err);
64
+ });
65
+ };
66
+ if (handleRedirects) {
67
+ const ogMutationCacheConfig = queryClient.getMutationCache().config;
68
+ queryClient.getMutationCache().config = {
69
+ ...ogMutationCacheConfig,
70
+ onError: (error, ...rest) => {
71
+ if (isRedirect(error)) {
72
+ error.options._fromLocation = router.state.location;
73
+ return router.navigate(router.resolveRedirect(error).options);
74
+ }
75
+ return ogMutationCacheConfig.onError?.(error, ...rest);
76
+ }
77
+ };
78
+ const ogQueryCacheConfig = queryClient.getQueryCache().config;
79
+ queryClient.getQueryCache().config = {
80
+ ...ogQueryCacheConfig,
81
+ onError: (error, ...rest) => {
82
+ if (isRedirect(error)) {
83
+ error.options._fromLocation = router.state.location;
84
+ return router.navigate(router.resolveRedirect(error).options);
85
+ }
86
+ return ogQueryCacheConfig.onError?.(error, ...rest);
87
+ }
88
+ };
89
+ }
90
+ }
115
91
  }
116
92
  function createPushableStream() {
117
- let controllerRef;
118
- const stream = new ReadableStream({
119
- start(controller) {
120
- controllerRef = controller;
121
- }
122
- });
123
- let _isClosed = false;
124
- return {
125
- stream,
126
- enqueue: (chunk) => controllerRef.enqueue(chunk),
127
- close: () => {
128
- controllerRef.close();
129
- _isClosed = true;
130
- },
131
- isClosed: () => _isClosed,
132
- error: (err) => controllerRef.error(err)
133
- };
93
+ let controllerRef;
94
+ const stream = new ReadableStream({ start(controller) {
95
+ controllerRef = controller;
96
+ } });
97
+ let _isClosed = false;
98
+ return {
99
+ stream,
100
+ enqueue: (chunk) => controllerRef.enqueue(chunk),
101
+ close: () => {
102
+ controllerRef.close();
103
+ _isClosed = true;
104
+ },
105
+ isClosed: () => _isClosed,
106
+ error: (err) => controllerRef.error(err)
107
+ };
134
108
  }
135
- export {
136
- setupCoreRouterSsrQueryIntegration
137
- };
138
- //# sourceMappingURL=index.js.map
109
+ //#endregion
110
+ export { setupCoreRouterSsrQueryIntegration };
111
+
112
+ //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["import {\n dehydrate as queryDehydrate,\n hydrate as queryHydrate,\n} from '@tanstack/query-core'\nimport { isRedirect } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport type { AnyRouter } from '@tanstack/router-core'\nimport type {\n QueryClient,\n DehydratedState as QueryDehydratedState,\n} from '@tanstack/query-core'\n\nexport type RouterSsrQueryOptions<TRouter extends AnyRouter> = {\n router: TRouter\n queryClient: QueryClient\n\n /**\n * If `true`, the QueryClient will handle errors thrown by `redirect()` inside of mutations and queries.\n *\n * @default true\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction)\n */\n handleRedirects?: boolean\n}\n\ntype DehydratedRouterQueryState = {\n dehydratedQueryClient?: QueryDehydratedState\n queryStream: ReadableStream<QueryDehydratedState>\n}\n\nexport function setupCoreRouterSsrQueryIntegration<TRouter extends AnyRouter>({\n router,\n queryClient,\n handleRedirects = true,\n}: RouterSsrQueryOptions<TRouter>) {\n const ogHydrate = router.options.hydrate\n const ogDehydrate = router.options.dehydrate\n\n if (isServer ?? router.isServer) {\n const sentQueries = new Set<string>()\n const queryStream = createPushableStream()\n let unsubscribe: (() => void) | undefined = undefined\n router.options.dehydrate =\n async (): Promise<DehydratedRouterQueryState> => {\n router.serverSsr!.onRenderFinished(() => {\n queryStream.close()\n unsubscribe?.()\n unsubscribe = undefined\n })\n const ogDehydrated = await ogDehydrate?.()\n\n const dehydratedRouter = {\n ...ogDehydrated,\n // prepare the stream for queries coming up during rendering\n queryStream: queryStream.stream,\n }\n\n const dehydratedQueryClient = queryDehydrate(queryClient)\n if (dehydratedQueryClient.queries.length > 0) {\n dehydratedQueryClient.queries.forEach((query) => {\n sentQueries.add(query.queryHash)\n })\n dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient\n }\n\n return dehydratedRouter\n }\n\n const ogClientOptions = queryClient.getDefaultOptions()\n queryClient.setDefaultOptions({\n ...ogClientOptions,\n dehydrate: {\n shouldDehydrateQuery: () => true,\n ...ogClientOptions.dehydrate,\n },\n })\n\n unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n // before rendering starts, we do not stream individual queries\n // instead we dehydrate the entire query client in router's dehydrate()\n // if attachRouterServerSsrUtils() has not been called yet, `router.serverSsr` will be undefined and we also do not stream\n if (!router.serverSsr?.isDehydrated()) {\n return\n }\n if (sentQueries.has(event.query.queryHash)) {\n return\n }\n // promise not yet set on the query, so we cannot stream it yet\n if (!event.query.promise) {\n return\n }\n if (queryStream.isClosed()) {\n console.warn(\n `tried to stream query ${event.query.queryHash} after stream was already closed`,\n )\n return\n }\n sentQueries.add(event.query.queryHash)\n queryStream.enqueue(\n queryDehydrate(queryClient, {\n shouldDehydrateQuery: (query) => {\n if (query.queryHash === event.query.queryHash) {\n return (\n ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true\n )\n }\n return false\n },\n }),\n )\n })\n // on the client\n } else {\n router.options.hydrate = async (dehydrated: DehydratedRouterQueryState) => {\n await ogHydrate?.(dehydrated)\n // hydrate the query client with the dehydrated data (if it was dehydrated on the server)\n if (dehydrated.dehydratedQueryClient) {\n queryHydrate(queryClient, dehydrated.dehydratedQueryClient)\n }\n\n // read the query stream and hydrate the queries as they come in\n const reader = dehydrated.queryStream.getReader()\n reader\n .read()\n .then(async function handle({ done, value }) {\n queryHydrate(queryClient, value)\n if (done) {\n return\n }\n const result = await reader.read()\n return handle(result)\n })\n .catch((err) => {\n console.error('Error reading query stream:', err)\n })\n }\n if (handleRedirects) {\n const ogMutationCacheConfig = queryClient.getMutationCache().config\n queryClient.getMutationCache().config = {\n ...ogMutationCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogMutationCacheConfig.onError?.(error, ...rest)\n },\n }\n\n const ogQueryCacheConfig = queryClient.getQueryCache().config\n queryClient.getQueryCache().config = {\n ...ogQueryCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogQueryCacheConfig.onError?.(error, ...rest)\n },\n }\n }\n }\n}\n\ntype PushableStream = {\n stream: ReadableStream\n enqueue: (chunk: unknown) => void\n close: () => void\n isClosed: () => boolean\n error: (err: unknown) => void\n}\n\nfunction createPushableStream(): PushableStream {\n let controllerRef: ReadableStreamDefaultController\n const stream = new ReadableStream({\n start(controller) {\n controllerRef = controller\n },\n })\n let _isClosed = false\n\n return {\n stream,\n enqueue: (chunk) => controllerRef.enqueue(chunk),\n close: () => {\n controllerRef.close()\n _isClosed = true\n },\n isClosed: () => _isClosed,\n error: (err: unknown) => controllerRef.error(err),\n }\n}\n"],"names":["queryDehydrate","queryHydrate"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/index.ts"],"sourcesContent":["import {\n dehydrate as queryDehydrate,\n hydrate as queryHydrate,\n} from '@tanstack/query-core'\nimport { isRedirect } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport type { AnyRouter } from '@tanstack/router-core'\nimport type {\n QueryClient,\n DehydratedState as QueryDehydratedState,\n} from '@tanstack/query-core'\n\nexport type RouterSsrQueryOptions<TRouter extends AnyRouter> = {\n router: TRouter\n queryClient: QueryClient\n\n /**\n * If `true`, the QueryClient will handle errors thrown by `redirect()` inside of mutations and queries.\n *\n * @default true\n * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction)\n */\n handleRedirects?: boolean\n}\n\ntype DehydratedRouterQueryState = {\n dehydratedQueryClient?: QueryDehydratedState\n queryStream: ReadableStream<QueryDehydratedState>\n}\n\nexport function setupCoreRouterSsrQueryIntegration<TRouter extends AnyRouter>({\n router,\n queryClient,\n handleRedirects = true,\n}: RouterSsrQueryOptions<TRouter>) {\n const ogHydrate = router.options.hydrate\n const ogDehydrate = router.options.dehydrate\n\n if (isServer ?? router.isServer) {\n const sentQueries = new Set<string>()\n const queryStream = createPushableStream()\n let unsubscribe: (() => void) | undefined = undefined\n router.options.dehydrate =\n async (): Promise<DehydratedRouterQueryState> => {\n router.serverSsr!.onRenderFinished(() => {\n queryStream.close()\n unsubscribe?.()\n unsubscribe = undefined\n })\n const ogDehydrated = await ogDehydrate?.()\n\n const dehydratedRouter = {\n ...ogDehydrated,\n // prepare the stream for queries coming up during rendering\n queryStream: queryStream.stream,\n }\n\n const dehydratedQueryClient = queryDehydrate(queryClient)\n if (dehydratedQueryClient.queries.length > 0) {\n dehydratedQueryClient.queries.forEach((query) => {\n sentQueries.add(query.queryHash)\n })\n dehydratedRouter.dehydratedQueryClient = dehydratedQueryClient\n }\n\n return dehydratedRouter\n }\n\n const ogClientOptions = queryClient.getDefaultOptions()\n queryClient.setDefaultOptions({\n ...ogClientOptions,\n dehydrate: {\n shouldDehydrateQuery: () => true,\n ...ogClientOptions.dehydrate,\n },\n })\n\n unsubscribe = queryClient.getQueryCache().subscribe((event) => {\n // before rendering starts, we do not stream individual queries\n // instead we dehydrate the entire query client in router's dehydrate()\n // if attachRouterServerSsrUtils() has not been called yet, `router.serverSsr` will be undefined and we also do not stream\n if (!router.serverSsr?.isDehydrated()) {\n return\n }\n if (sentQueries.has(event.query.queryHash)) {\n return\n }\n // promise not yet set on the query, so we cannot stream it yet\n if (!event.query.promise) {\n return\n }\n if (queryStream.isClosed()) {\n console.warn(\n `tried to stream query ${event.query.queryHash} after stream was already closed`,\n )\n return\n }\n sentQueries.add(event.query.queryHash)\n queryStream.enqueue(\n queryDehydrate(queryClient, {\n shouldDehydrateQuery: (query) => {\n if (query.queryHash === event.query.queryHash) {\n return (\n ogClientOptions.dehydrate?.shouldDehydrateQuery?.(query) ?? true\n )\n }\n return false\n },\n }),\n )\n })\n // on the client\n } else {\n router.options.hydrate = async (dehydrated: DehydratedRouterQueryState) => {\n await ogHydrate?.(dehydrated)\n // hydrate the query client with the dehydrated data (if it was dehydrated on the server)\n if (dehydrated.dehydratedQueryClient) {\n queryHydrate(queryClient, dehydrated.dehydratedQueryClient)\n }\n\n // read the query stream and hydrate the queries as they come in\n const reader = dehydrated.queryStream.getReader()\n reader\n .read()\n .then(async function handle({ done, value }) {\n queryHydrate(queryClient, value)\n if (done) {\n return\n }\n const result = await reader.read()\n return handle(result)\n })\n .catch((err) => {\n console.error('Error reading query stream:', err)\n })\n }\n if (handleRedirects) {\n const ogMutationCacheConfig = queryClient.getMutationCache().config\n queryClient.getMutationCache().config = {\n ...ogMutationCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogMutationCacheConfig.onError?.(error, ...rest)\n },\n }\n\n const ogQueryCacheConfig = queryClient.getQueryCache().config\n queryClient.getQueryCache().config = {\n ...ogQueryCacheConfig,\n onError: (error, ...rest) => {\n if (isRedirect(error)) {\n error.options._fromLocation = router.state.location\n return router.navigate(router.resolveRedirect(error).options)\n }\n\n return ogQueryCacheConfig.onError?.(error, ...rest)\n },\n }\n }\n }\n}\n\ntype PushableStream = {\n stream: ReadableStream\n enqueue: (chunk: unknown) => void\n close: () => void\n isClosed: () => boolean\n error: (err: unknown) => void\n}\n\nfunction createPushableStream(): PushableStream {\n let controllerRef: ReadableStreamDefaultController\n const stream = new ReadableStream({\n start(controller) {\n controllerRef = controller\n },\n })\n let _isClosed = false\n\n return {\n stream,\n enqueue: (chunk) => controllerRef.enqueue(chunk),\n close: () => {\n controllerRef.close()\n _isClosed = true\n },\n isClosed: () => _isClosed,\n error: (err: unknown) => controllerRef.error(err),\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-ssr-query-core",
3
- "version": "1.166.7",
3
+ "version": "1.166.9",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -49,7 +49,7 @@
49
49
  "node": ">=20.19"
50
50
  },
51
51
  "devDependencies": {
52
- "@tanstack/router-core": ">=1.127.0",
52
+ "@tanstack/router-core": ">=1.167.2",
53
53
  "@tanstack/query-core": ">=5.90.0",
54
54
  "vite": "*"
55
55
  },