@trpc/react-query 11.0.0-rc.401 → 11.0.0-rc.403

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,7 +1,7 @@
1
1
  {
2
- "bundleSize": 29431,
3
- "bundleOrigSize": 63440,
4
- "bundleReduction": 53.61,
2
+ "bundleSize": 32270,
3
+ "bundleOrigSize": 68448,
4
+ "bundleReduction": 52.85,
5
5
  "modules": [
6
6
  {
7
7
  "id": "/src/shared/hooks/createHooksInternal.tsx",
@@ -14,7 +14,7 @@
14
14
  "dependents": [
15
15
  "/src/createTRPCReact.tsx"
16
16
  ],
17
- "percent": 46.7,
17
+ "percent": 42.59,
18
18
  "reduction": 12.84
19
19
  },
20
20
  {
@@ -29,7 +29,7 @@
29
29
  "/src/createTRPCQueryUtils.tsx",
30
30
  "/src/shared/hooks/createHooksInternal.tsx"
31
31
  ],
32
- "percent": 12.85,
32
+ "percent": 11.72,
33
33
  "reduction": 6.34
34
34
  },
35
35
  {
@@ -43,7 +43,7 @@
43
43
  "dependents": [
44
44
  "/src/server/index.ts"
45
45
  ],
46
- "percent": 12.48,
46
+ "percent": 11.38,
47
47
  "reduction": 50.38
48
48
  },
49
49
  {
@@ -59,9 +59,21 @@
59
59
  "dependents": [
60
60
  "/src/shared/index.ts"
61
61
  ],
62
- "percent": 9.75,
62
+ "percent": 8.89,
63
63
  "reduction": 74.38
64
64
  },
65
+ {
66
+ "id": "/src/rsc.tsx",
67
+ "size": 2839,
68
+ "origSize": 5008,
69
+ "renderedExports": [
70
+ "createHydrationHelpers"
71
+ ],
72
+ "removedExports": [],
73
+ "dependents": [],
74
+ "percent": 8.8,
75
+ "reduction": 43.31
76
+ },
65
77
  {
66
78
  "id": "/src/internals/getQueryKey.ts",
67
79
  "size": 1999,
@@ -73,12 +85,13 @@
73
85
  "removedExports": [],
74
86
  "dependents": [
75
87
  "/src/index.ts",
88
+ "/src/rsc.tsx",
76
89
  "/src/server/ssgProxy.ts",
77
90
  "/src/shared/proxy/utilsProxy.ts",
78
91
  "/src/shared/proxy/useQueriesProxy.ts",
79
92
  "/src/shared/hooks/createHooksInternal.tsx"
80
93
  ],
81
- "percent": 6.79,
94
+ "percent": 6.19,
82
95
  "reduction": 42.49
83
96
  },
84
97
  {
@@ -93,7 +106,7 @@
93
106
  "dependents": [
94
107
  "/src/index.ts"
95
108
  ],
96
- "percent": 2.89,
109
+ "percent": 2.63,
97
110
  "reduction": 89.28
98
111
  },
99
112
  {
@@ -107,7 +120,7 @@
107
120
  "dependents": [
108
121
  "/src/shared/index.ts"
109
122
  ],
110
- "percent": 2.74,
123
+ "percent": 2.5,
111
124
  "reduction": 23.16
112
125
  },
113
126
  {
@@ -122,7 +135,7 @@
122
135
  "/src/shared/index.ts",
123
136
  "/src/shared/hooks/createHooksInternal.tsx"
124
137
  ],
125
- "percent": 1.93,
138
+ "percent": 1.76,
126
139
  "reduction": 82.03
127
140
  },
128
141
  {
@@ -138,7 +151,7 @@
138
151
  "/src/shared/hooks/createHooksInternal.tsx",
139
152
  "/src/utils/createUtilityFunctions.ts"
140
153
  ],
141
- "percent": 1.61,
154
+ "percent": 1.47,
142
155
  "reduction": 17.31
143
156
  },
144
157
  {
@@ -152,7 +165,7 @@
152
165
  "dependents": [
153
166
  "/src/shared/hooks/createHooksInternal.tsx"
154
167
  ],
155
- "percent": 0.75,
168
+ "percent": 0.69,
156
169
  "reduction": 36.21
157
170
  },
158
171
  {
@@ -166,7 +179,7 @@
166
179
  "dependents": [
167
180
  "/src/index.ts"
168
181
  ],
169
- "percent": 0.55,
182
+ "percent": 0.5,
170
183
  "reduction": 66.6
171
184
  },
172
185
  {
@@ -184,7 +197,7 @@
184
197
  "/src/shared/proxy/utilsProxy.ts",
185
198
  "/src/shared/hooks/createHooksInternal.tsx"
186
199
  ],
187
- "percent": 0.52,
200
+ "percent": 0.48,
188
201
  "reduction": 97.59
189
202
  },
190
203
  {
@@ -198,7 +211,7 @@
198
211
  "dependents": [
199
212
  "/src/shared/index.ts"
200
213
  ],
201
- "percent": 0.44,
214
+ "percent": 0.4,
202
215
  "reduction": 74.9
203
216
  },
204
217
  {
@@ -236,5 +249,5 @@
236
249
  "reduction": 100
237
250
  }
238
251
  ],
239
- "moduleCount": 16
252
+ "moduleCount": 17
240
253
  }
package/dist/rsc.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ import { type QueryClient } from '@tanstack/react-query';
2
+ import type { TRPCClientError } from '@trpc/client';
3
+ import type { inferTransformedProcedureOutput } from '@trpc/server';
4
+ import { type AnyRouter, type inferProcedureInput, type RouterRecord } from '@trpc/server/unstable-core-do-not-import';
5
+ import type { AnyProcedure, AnyRootTypes, inferProcedureOutput, inferRouterRootTypes, RouterCaller, TypeError } from '@trpc/server/unstable-core-do-not-import';
6
+ import * as React from 'react';
7
+ import type { TRPCFetchInfiniteQueryOptions, TRPCFetchQueryOptions } from './shared';
8
+ type DecorateProcedure<TRoot extends AnyRootTypes, TProcedure extends AnyProcedure> = {
9
+ (input: inferProcedureInput<TProcedure>): Promise<inferProcedureOutput<TProcedure>>;
10
+ prefetch: (input: inferProcedureInput<TProcedure>, opts?: TRPCFetchQueryOptions<inferTransformedProcedureOutput<TRoot, TProcedure>, TRPCClientError<TRoot>>) => Promise<void>;
11
+ prefetchInfinite: (input: inferProcedureInput<TProcedure>, opts?: TRPCFetchInfiniteQueryOptions<inferProcedureInput<TProcedure>, inferTransformedProcedureOutput<TRoot, TProcedure>, TRPCClientError<TRoot>>) => Promise<void>;
12
+ };
13
+ type DecorateRouterRecord<TRoot extends AnyRootTypes, TRecord extends RouterRecord> = {
14
+ [TKey in keyof TRecord]: TRecord[TKey] extends AnyProcedure ? DecorateProcedure<TRoot, TRecord[TKey]> : TRecord[TKey] extends RouterRecord ? DecorateRouterRecord<TRoot, TRecord[TKey]> : never;
15
+ };
16
+ type Caller<TRouter extends AnyRouter> = ReturnType<RouterCaller<inferRouterRootTypes<TRouter>, TRouter['_def']['record']>>;
17
+ /**
18
+ * @note This requires `@tanstack/react-query@^5.45.0`
19
+ */
20
+ export declare function createHydrationHelpers<TRouter extends AnyRouter>(caller: AnyRouter extends TRouter ? TypeError<'Generic parameter missing in `createHydrationHelpers<HERE>`'> : Caller<TRouter>, getQueryClient: () => QueryClient): {
21
+ /***
22
+ * Wrapped caller with prefetch helpers
23
+ * Can be used as a regular [server-side caller](https://trpc.io/docs/server/server-side-calls)
24
+ * or using prefetch helpers to put the promise into the QueryClient cache
25
+ * @example
26
+ * ```ts
27
+ * const data = await trpc.post.get("postId");
28
+ *
29
+ * // or
30
+ * void trpc.post.get.prefetch("postId");
31
+ * ```
32
+ */
33
+ trpc: DecorateRouterRecord<inferRouterRootTypes<TRouter>, TRouter["_def"]["record"]>;
34
+ /**
35
+ * HoC to hydrate the query client for a client component
36
+ * to pick up the prefetched promise and skip an initial
37
+ * client-side fetch.
38
+ * @example
39
+ * ```tsx
40
+ * // MyRSC.tsx
41
+ * const MyRSC = ({ params }) => {
42
+ * void trpc.post.get.prefetch(params.postId);
43
+ *
44
+ * return (
45
+ * <HydrateClient>
46
+ * <MyCC postId={params.postId} />
47
+ * </HydrateClient>
48
+ * );
49
+ * };
50
+ *
51
+ * // MyCC.tsx
52
+ * "use client"
53
+ * const MyCC = ({ postId }) => {
54
+ * const { data: post } = trpc.post.get.useQuery(postId);
55
+ * return <div>{post.title}</div>;
56
+ * };
57
+ * ```
58
+ */
59
+ HydrateClient: (props: {
60
+ children: React.ReactNode;
61
+ }) => React.JSX.Element;
62
+ };
63
+ export {};
64
+ //# sourceMappingURL=rsc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../src/rsc.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAEL,KAAK,SAAS,EACd,KAAK,mBAAmB,EACxB,KAAK,YAAY,EAClB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EAEpB,YAAY,EACZ,SAAS,EACV,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EACV,6BAA6B,EAC7B,qBAAqB,EACtB,MAAM,UAAU,CAAC;AAIlB,KAAK,iBAAiB,CACpB,KAAK,SAAS,YAAY,EAC1B,UAAU,SAAS,YAAY,IAC7B;IACF,CAAC,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,OAAO,CAC/C,oBAAoB,CAAC,UAAU,CAAC,CACjC,CAAC;IACF,QAAQ,EAAE,CACR,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,EACtC,IAAI,CAAC,EAAE,qBAAqB,CAC1B,+BAA+B,CAAC,KAAK,EAAE,UAAU,CAAC,EAClD,eAAe,CAAC,KAAK,CAAC,CACvB,KACE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,gBAAgB,EAAE,CAChB,KAAK,EAAE,mBAAmB,CAAC,UAAU,CAAC,EACtC,IAAI,CAAC,EAAE,6BAA6B,CAClC,mBAAmB,CAAC,UAAU,CAAC,EAC/B,+BAA+B,CAAC,KAAK,EAAE,UAAU,CAAC,EAClD,eAAe,CAAC,KAAK,CAAC,CACvB,KACE,OAAO,CAAC,IAAI,CAAC,CAAC;CACpB,CAAC;AAEF,KAAK,oBAAoB,CACvB,KAAK,SAAS,YAAY,EAC1B,OAAO,SAAS,YAAY,IAC1B;KACD,IAAI,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,YAAY,GACvD,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GACvC,OAAO,CAAC,IAAI,CAAC,SAAS,YAAY,GAClC,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAC1C,KAAK;CACV,CAAC;AAEF,KAAK,MAAM,CAAC,OAAO,SAAS,SAAS,IAAI,UAAU,CACjD,YAAY,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,CACvE,CAAC;AAGF;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,SAAS,SAAS,EAC9D,MAAM,EAAE,SAAS,SAAS,OAAO,GAC7B,SAAS,CAAC,6DAA6D,CAAC,GACxE,MAAM,CAAC,OAAO,CAAC,EACnB,cAAc,EAAE,MAAM,WAAW;IA2D/B;;;;;;;;;;;OAWG;;IAEH;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;2BAhDyB;QAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;KAAE;EAmD5D"}
package/dist/rsc.js ADDED
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+
3
+ var reactQuery = require('@tanstack/react-query');
4
+ var unstableCoreDoNotImport = require('@trpc/server/unstable-core-do-not-import');
5
+ var React = require('react');
6
+ var getQueryKey = require('./internals/getQueryKey.js');
7
+
8
+ function _interopNamespaceDefault(e) {
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
26
+
27
+ const HELPERS = [
28
+ 'prefetch',
29
+ 'prefetchInfinite'
30
+ ];
31
+ // ts-prune-ignore-next
32
+ /**
33
+ * @note This requires `@tanstack/react-query@^5.45.0`
34
+ */ function createHydrationHelpers(caller, getQueryClient) {
35
+ const wrappedProxy = unstableCoreDoNotImport.createRecursiveProxy(async ({ path , args })=>{
36
+ const proc = path.reduce((acc, key)=>// @ts-expect-error - ??
37
+ HELPERS.includes(key) ? acc : acc[key], caller);
38
+ const input = args[0];
39
+ const promise = proc(input);
40
+ const queryFn = async ()=>{
41
+ const def = await caller._def();
42
+ const transformer = def._config.transformer;
43
+ return promise.then((value)=>transformer.output.serialize(value));
44
+ };
45
+ const helper = path.pop();
46
+ if (helper === 'prefetch') {
47
+ const args1 = args[1];
48
+ return getQueryClient().prefetchQuery({
49
+ ...args1,
50
+ queryKey: getQueryKey.getQueryKeyInternal(path, input, 'query'),
51
+ queryFn
52
+ });
53
+ }
54
+ if (helper === 'prefetchInfinite') {
55
+ const args11 = args[1];
56
+ return getQueryClient().prefetchInfiniteQuery({
57
+ ...args11,
58
+ queryKey: getQueryKey.getQueryKeyInternal(path, input, 'infinite'),
59
+ queryFn,
60
+ initialPageParam: args11?.initialCursor ?? null
61
+ });
62
+ }
63
+ return promise;
64
+ });
65
+ function HydrateClient(props) {
66
+ const dehydratedState = reactQuery.dehydrate(getQueryClient());
67
+ return /*#__PURE__*/ React__namespace.createElement(reactQuery.HydrationBoundary, {
68
+ state: dehydratedState
69
+ }, props.children);
70
+ }
71
+ return {
72
+ /***
73
+ * Wrapped caller with prefetch helpers
74
+ * Can be used as a regular [server-side caller](https://trpc.io/docs/server/server-side-calls)
75
+ * or using prefetch helpers to put the promise into the QueryClient cache
76
+ * @example
77
+ * ```ts
78
+ * const data = await trpc.post.get("postId");
79
+ *
80
+ * // or
81
+ * void trpc.post.get.prefetch("postId");
82
+ * ```
83
+ */ trpc: wrappedProxy,
84
+ /**
85
+ * HoC to hydrate the query client for a client component
86
+ * to pick up the prefetched promise and skip an initial
87
+ * client-side fetch.
88
+ * @example
89
+ * ```tsx
90
+ * // MyRSC.tsx
91
+ * const MyRSC = ({ params }) => {
92
+ * void trpc.post.get.prefetch(params.postId);
93
+ *
94
+ * return (
95
+ * <HydrateClient>
96
+ * <MyCC postId={params.postId} />
97
+ * </HydrateClient>
98
+ * );
99
+ * };
100
+ *
101
+ * // MyCC.tsx
102
+ * "use client"
103
+ * const MyCC = ({ postId }) => {
104
+ * const { data: post } = trpc.post.get.useQuery(postId);
105
+ * return <div>{post.title}</div>;
106
+ * };
107
+ * ```
108
+ */ HydrateClient
109
+ };
110
+ }
111
+
112
+ exports.createHydrationHelpers = createHydrationHelpers;
package/dist/rsc.mjs ADDED
@@ -0,0 +1,91 @@
1
+ import { dehydrate, HydrationBoundary } from '@tanstack/react-query';
2
+ import { createRecursiveProxy } from '@trpc/server/unstable-core-do-not-import';
3
+ import * as React from 'react';
4
+ import { getQueryKeyInternal } from './internals/getQueryKey.mjs';
5
+
6
+ const HELPERS = [
7
+ 'prefetch',
8
+ 'prefetchInfinite'
9
+ ];
10
+ // ts-prune-ignore-next
11
+ /**
12
+ * @note This requires `@tanstack/react-query@^5.45.0`
13
+ */ function createHydrationHelpers(caller, getQueryClient) {
14
+ const wrappedProxy = createRecursiveProxy(async ({ path , args })=>{
15
+ const proc = path.reduce((acc, key)=>// @ts-expect-error - ??
16
+ HELPERS.includes(key) ? acc : acc[key], caller);
17
+ const input = args[0];
18
+ const promise = proc(input);
19
+ const queryFn = async ()=>{
20
+ const def = await caller._def();
21
+ const transformer = def._config.transformer;
22
+ return promise.then((value)=>transformer.output.serialize(value));
23
+ };
24
+ const helper = path.pop();
25
+ if (helper === 'prefetch') {
26
+ const args1 = args[1];
27
+ return getQueryClient().prefetchQuery({
28
+ ...args1,
29
+ queryKey: getQueryKeyInternal(path, input, 'query'),
30
+ queryFn
31
+ });
32
+ }
33
+ if (helper === 'prefetchInfinite') {
34
+ const args11 = args[1];
35
+ return getQueryClient().prefetchInfiniteQuery({
36
+ ...args11,
37
+ queryKey: getQueryKeyInternal(path, input, 'infinite'),
38
+ queryFn,
39
+ initialPageParam: args11?.initialCursor ?? null
40
+ });
41
+ }
42
+ return promise;
43
+ });
44
+ function HydrateClient(props) {
45
+ const dehydratedState = dehydrate(getQueryClient());
46
+ return /*#__PURE__*/ React.createElement(HydrationBoundary, {
47
+ state: dehydratedState
48
+ }, props.children);
49
+ }
50
+ return {
51
+ /***
52
+ * Wrapped caller with prefetch helpers
53
+ * Can be used as a regular [server-side caller](https://trpc.io/docs/server/server-side-calls)
54
+ * or using prefetch helpers to put the promise into the QueryClient cache
55
+ * @example
56
+ * ```ts
57
+ * const data = await trpc.post.get("postId");
58
+ *
59
+ * // or
60
+ * void trpc.post.get.prefetch("postId");
61
+ * ```
62
+ */ trpc: wrappedProxy,
63
+ /**
64
+ * HoC to hydrate the query client for a client component
65
+ * to pick up the prefetched promise and skip an initial
66
+ * client-side fetch.
67
+ * @example
68
+ * ```tsx
69
+ * // MyRSC.tsx
70
+ * const MyRSC = ({ params }) => {
71
+ * void trpc.post.get.prefetch(params.postId);
72
+ *
73
+ * return (
74
+ * <HydrateClient>
75
+ * <MyCC postId={params.postId} />
76
+ * </HydrateClient>
77
+ * );
78
+ * };
79
+ *
80
+ * // MyCC.tsx
81
+ * "use client"
82
+ * const MyCC = ({ postId }) => {
83
+ * const { data: post } = trpc.post.get.useQuery(postId);
84
+ * return <div>{post.title}</div>;
85
+ * };
86
+ * ```
87
+ */ HydrateClient
88
+ };
89
+ }
90
+
91
+ export { createHydrationHelpers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trpc/react-query",
3
- "version": "11.0.0-rc.401+91720833b",
3
+ "version": "11.0.0-rc.403+ab71a1be6",
4
4
  "description": "The tRPC React library",
5
5
  "author": "KATT",
6
6
  "license": "MIT",
@@ -27,6 +27,11 @@
27
27
  "require": "./dist/index.js",
28
28
  "default": "./dist/index.js"
29
29
  },
30
+ "./rsc": {
31
+ "import": "./dist/rsc.mjs",
32
+ "require": "./dist/rsc.js",
33
+ "default": "./dist/rsc.js"
34
+ },
30
35
  "./server": {
31
36
  "import": "./dist/server/index.mjs",
32
37
  "require": "./dist/server/index.js",
@@ -43,6 +48,7 @@
43
48
  "src",
44
49
  "README.md",
45
50
  "package.json",
51
+ "rsc",
46
52
  "server",
47
53
  "shared",
48
54
  "!**/*.test.*"
@@ -57,16 +63,16 @@
57
63
  }
58
64
  },
59
65
  "peerDependencies": {
60
- "@tanstack/react-query": "^5.25.0",
61
- "@trpc/client": "11.0.0-rc.401+91720833b",
62
- "@trpc/server": "11.0.0-rc.401+91720833b",
66
+ "@tanstack/react-query": "^5.40.0",
67
+ "@trpc/client": "11.0.0-rc.403+ab71a1be6",
68
+ "@trpc/server": "11.0.0-rc.403+ab71a1be6",
63
69
  "react": ">=18.2.0",
64
70
  "react-dom": ">=18.2.0"
65
71
  },
66
72
  "devDependencies": {
67
- "@tanstack/react-query": "^5.25.0",
68
- "@trpc/client": "11.0.0-rc.401+91720833b",
69
- "@trpc/server": "11.0.0-rc.401+91720833b",
73
+ "@tanstack/react-query": "^5.45.0",
74
+ "@trpc/client": "11.0.0-rc.403+ab71a1be6",
75
+ "@trpc/server": "11.0.0-rc.403+ab71a1be6",
70
76
  "@types/express": "^4.17.17",
71
77
  "@types/node": "^20.10.0",
72
78
  "@types/react": "^18.3.1",
@@ -86,5 +92,5 @@
86
92
  "funding": [
87
93
  "https://trpc.io/sponsor"
88
94
  ],
89
- "gitHead": "91720833b050e7ba5130dd51b3e03c4e860ed159"
95
+ "gitHead": "ab71a1be689e84b7503c6adbcd98c3c424217920"
90
96
  }
package/rsc/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from '../dist/rsc';
package/rsc/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('../dist/rsc');
package/src/rsc.tsx ADDED
@@ -0,0 +1,178 @@
1
+ import {
2
+ dehydrate,
3
+ HydrationBoundary,
4
+ type QueryClient,
5
+ } from '@tanstack/react-query';
6
+ import type { TRPCClientError } from '@trpc/client';
7
+ import type { inferTransformedProcedureOutput } from '@trpc/server';
8
+ import {
9
+ createRecursiveProxy,
10
+ type AnyRouter,
11
+ type inferProcedureInput,
12
+ type RouterRecord,
13
+ } from '@trpc/server/unstable-core-do-not-import';
14
+ import type {
15
+ AnyProcedure,
16
+ AnyRootTypes,
17
+ inferProcedureOutput,
18
+ inferRouterRootTypes,
19
+ Maybe,
20
+ RouterCaller,
21
+ TypeError,
22
+ } from '@trpc/server/unstable-core-do-not-import';
23
+ import * as React from 'react';
24
+ import { getQueryKeyInternal } from './internals/getQueryKey';
25
+ import type {
26
+ TRPCFetchInfiniteQueryOptions,
27
+ TRPCFetchQueryOptions,
28
+ } from './shared';
29
+
30
+ const HELPERS = ['prefetch', 'prefetchInfinite'];
31
+
32
+ type DecorateProcedure<
33
+ TRoot extends AnyRootTypes,
34
+ TProcedure extends AnyProcedure,
35
+ > = {
36
+ (input: inferProcedureInput<TProcedure>): Promise<
37
+ inferProcedureOutput<TProcedure>
38
+ >;
39
+ prefetch: (
40
+ input: inferProcedureInput<TProcedure>,
41
+ opts?: TRPCFetchQueryOptions<
42
+ inferTransformedProcedureOutput<TRoot, TProcedure>,
43
+ TRPCClientError<TRoot>
44
+ >,
45
+ ) => Promise<void>;
46
+ prefetchInfinite: (
47
+ input: inferProcedureInput<TProcedure>,
48
+ opts?: TRPCFetchInfiniteQueryOptions<
49
+ inferProcedureInput<TProcedure>,
50
+ inferTransformedProcedureOutput<TRoot, TProcedure>,
51
+ TRPCClientError<TRoot>
52
+ >,
53
+ ) => Promise<void>;
54
+ };
55
+
56
+ type DecorateRouterRecord<
57
+ TRoot extends AnyRootTypes,
58
+ TRecord extends RouterRecord,
59
+ > = {
60
+ [TKey in keyof TRecord]: TRecord[TKey] extends AnyProcedure
61
+ ? DecorateProcedure<TRoot, TRecord[TKey]>
62
+ : TRecord[TKey] extends RouterRecord
63
+ ? DecorateRouterRecord<TRoot, TRecord[TKey]>
64
+ : never;
65
+ };
66
+
67
+ type Caller<TRouter extends AnyRouter> = ReturnType<
68
+ RouterCaller<inferRouterRootTypes<TRouter>, TRouter['_def']['record']>
69
+ >;
70
+
71
+ // ts-prune-ignore-next
72
+ /**
73
+ * @note This requires `@tanstack/react-query@^5.45.0`
74
+ */
75
+ export function createHydrationHelpers<TRouter extends AnyRouter>(
76
+ caller: AnyRouter extends TRouter
77
+ ? TypeError<'Generic parameter missing in `createHydrationHelpers<HERE>`'>
78
+ : Caller<TRouter>,
79
+ getQueryClient: () => QueryClient,
80
+ ) {
81
+ type RootTypes = inferRouterRootTypes<TRouter>;
82
+ const wrappedProxy = createRecursiveProxy(async ({ path, args }) => {
83
+ const proc = path.reduce(
84
+ (acc, key) =>
85
+ // @ts-expect-error - ??
86
+ HELPERS.includes(key) ? acc : acc[key],
87
+ caller,
88
+ ) as unknown as DecorateProcedure<RootTypes, AnyProcedure>;
89
+
90
+ const input = args[0];
91
+ const promise = proc(input);
92
+
93
+ const queryFn = async () => {
94
+ const def: AnyRouter['_def'] = await (caller as any)._def();
95
+ const transformer = def._config.transformer;
96
+ return promise.then((value) => transformer.output.serialize(value));
97
+ };
98
+
99
+ const helper = path.pop();
100
+ if (helper === 'prefetch') {
101
+ const args1 = args[1] as Maybe<
102
+ TRPCFetchInfiniteQueryOptions<any, any, any>
103
+ >;
104
+
105
+ return getQueryClient().prefetchQuery({
106
+ ...args1,
107
+ queryKey: getQueryKeyInternal(path, input, 'query'),
108
+ queryFn,
109
+ });
110
+ }
111
+ if (helper === 'prefetchInfinite') {
112
+ const args1 = args[1] as Maybe<
113
+ TRPCFetchInfiniteQueryOptions<any, any, any>
114
+ >;
115
+
116
+ return getQueryClient().prefetchInfiniteQuery({
117
+ ...args1,
118
+ queryKey: getQueryKeyInternal(path, input, 'infinite'),
119
+ queryFn,
120
+ initialPageParam: args1?.initialCursor ?? null,
121
+ });
122
+ }
123
+
124
+ return promise;
125
+ }) as DecorateRouterRecord<RootTypes, TRouter['_def']['record']>;
126
+
127
+ function HydrateClient(props: { children: React.ReactNode }) {
128
+ const dehydratedState = dehydrate(getQueryClient());
129
+
130
+ return (
131
+ <HydrationBoundary state={dehydratedState}>
132
+ {props.children}
133
+ </HydrationBoundary>
134
+ );
135
+ }
136
+
137
+ return {
138
+ /***
139
+ * Wrapped caller with prefetch helpers
140
+ * Can be used as a regular [server-side caller](https://trpc.io/docs/server/server-side-calls)
141
+ * or using prefetch helpers to put the promise into the QueryClient cache
142
+ * @example
143
+ * ```ts
144
+ * const data = await trpc.post.get("postId");
145
+ *
146
+ * // or
147
+ * void trpc.post.get.prefetch("postId");
148
+ * ```
149
+ */
150
+ trpc: wrappedProxy,
151
+ /**
152
+ * HoC to hydrate the query client for a client component
153
+ * to pick up the prefetched promise and skip an initial
154
+ * client-side fetch.
155
+ * @example
156
+ * ```tsx
157
+ * // MyRSC.tsx
158
+ * const MyRSC = ({ params }) => {
159
+ * void trpc.post.get.prefetch(params.postId);
160
+ *
161
+ * return (
162
+ * <HydrateClient>
163
+ * <MyCC postId={params.postId} />
164
+ * </HydrateClient>
165
+ * );
166
+ * };
167
+ *
168
+ * // MyCC.tsx
169
+ * "use client"
170
+ * const MyCC = ({ postId }) => {
171
+ * const { data: post } = trpc.post.get.useQuery(postId);
172
+ * return <div>{post.title}</div>;
173
+ * };
174
+ * ```
175
+ */
176
+ HydrateClient,
177
+ };
178
+ }