@trpc/next 11.0.0-next.91 → 11.0.0-rc.329

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.
Files changed (58) hide show
  1. package/README.md +5 -5
  2. package/dist/app-dir/client.d.ts +3 -3
  3. package/dist/app-dir/client.d.ts.map +1 -1
  4. package/dist/app-dir/client.js +5 -105
  5. package/dist/app-dir/client.mjs +4 -102
  6. package/dist/app-dir/create-action-hook.d.ts +18 -6
  7. package/dist/app-dir/create-action-hook.d.ts.map +1 -1
  8. package/dist/app-dir/create-action-hook.js +108 -0
  9. package/dist/app-dir/create-action-hook.mjs +105 -0
  10. package/dist/app-dir/formDataToObject.js +34 -0
  11. package/dist/app-dir/formDataToObject.mjs +32 -0
  12. package/dist/app-dir/links/nextCache.d.ts +4 -3
  13. package/dist/app-dir/links/nextCache.d.ts.map +1 -1
  14. package/dist/app-dir/links/nextCache.js +9 -10
  15. package/dist/app-dir/links/nextCache.mjs +8 -7
  16. package/dist/app-dir/links/nextHttp.d.ts +11 -5
  17. package/dist/app-dir/links/nextHttp.d.ts.map +1 -1
  18. package/dist/app-dir/links/nextHttp.js +22 -23
  19. package/dist/app-dir/links/nextHttp.mjs +22 -21
  20. package/dist/app-dir/server.d.ts +19 -12
  21. package/dist/app-dir/server.d.ts.map +1 -1
  22. package/dist/app-dir/server.js +39 -55
  23. package/dist/app-dir/server.mjs +29 -43
  24. package/dist/app-dir/shared.d.ts +19 -13
  25. package/dist/app-dir/shared.d.ts.map +1 -1
  26. package/dist/{shared-e49b9cdc.js → app-dir/shared.js} +1 -1
  27. package/dist/{shared-f6996341.mjs → app-dir/shared.mjs} +2 -2
  28. package/dist/app-dir/types.d.ts +23 -11
  29. package/dist/app-dir/types.d.ts.map +1 -1
  30. package/dist/bundle-analysis.json +56 -44
  31. package/dist/createTRPCNext.d.ts +10 -8
  32. package/dist/createTRPCNext.d.ts.map +1 -1
  33. package/dist/createTRPCNext.js +38 -0
  34. package/dist/createTRPCNext.mjs +36 -0
  35. package/dist/index.js +4 -190
  36. package/dist/index.mjs +2 -185
  37. package/dist/ssrPrepass.d.ts +3 -0
  38. package/dist/ssrPrepass.d.ts.map +1 -0
  39. package/dist/ssrPrepass.js +139 -0
  40. package/dist/ssrPrepass.mjs +137 -0
  41. package/dist/withTRPC.d.ts +41 -13
  42. package/dist/withTRPC.d.ts.map +1 -1
  43. package/dist/withTRPC.js +86 -0
  44. package/dist/withTRPC.mjs +84 -0
  45. package/package.json +36 -25
  46. package/src/app-dir/client.ts +4 -4
  47. package/src/app-dir/create-action-hook.tsx +49 -19
  48. package/src/app-dir/links/nextCache.ts +20 -8
  49. package/src/app-dir/links/nextHttp.ts +50 -30
  50. package/src/app-dir/server.ts +86 -34
  51. package/src/app-dir/shared.ts +52 -25
  52. package/src/app-dir/types.ts +41 -29
  53. package/src/createTRPCNext.tsx +25 -16
  54. package/src/ssrPrepass.ts +185 -0
  55. package/src/withTRPC.tsx +102 -180
  56. package/ssrPrepass/index.d.ts +1 -0
  57. package/ssrPrepass/index.js +1 -0
  58. package/dist/shared-642894f4.js +0 -19
package/dist/index.mjs CHANGED
@@ -1,185 +1,2 @@
1
- import { dehydrate, QueryClientProvider, HydrationBoundary } from '@tanstack/react-query';
2
- import { createTRPCUntypedClient } from '@trpc/client';
3
- import { createRootHooks, getQueryClient, createReactQueryUtils, createReactDecoration } from '@trpc/react-query/shared';
4
- import React, { createElement, useState, useMemo } from 'react';
5
- import ssrPrepass from 'react-ssr-prepass';
6
- import { createFlatProxy } from '@trpc/server/shared';
7
-
8
- function transformQueryOrMutationCacheErrors(result) {
9
- const error = result.state.error;
10
- if (error instanceof Error && error.name === 'TRPCClientError') {
11
- const newError = {
12
- message: error.message,
13
- data: error.data,
14
- shape: error.shape
15
- };
16
- return {
17
- ...result,
18
- state: {
19
- ...result.state,
20
- error: newError
21
- }
22
- };
23
- }
24
- return result;
25
- }
26
- function withTRPC(opts) {
27
- const { config: getClientConfig } = opts;
28
- return (AppOrPage)=>{
29
- const trpc = createRootHooks(opts);
30
- const WithTRPC = (props)=>{
31
- const [prepassProps] = useState(()=>{
32
- if (props.trpc) {
33
- return props.trpc;
34
- }
35
- const config = getClientConfig({});
36
- const queryClient = getQueryClient(config);
37
- const trpcClient = trpc.createClient(config);
38
- return {
39
- abortOnUnmount: config.abortOnUnmount,
40
- queryClient,
41
- trpcClient,
42
- ssrState: opts.ssr ? 'mounting' : false,
43
- ssrContext: null
44
- };
45
- });
46
- const { queryClient , trpcClient , ssrState , ssrContext } = prepassProps;
47
- // allow normal components to be wrapped, not just app/pages
48
- const hydratedState = trpc.useDehydratedState(trpcClient, props.pageProps?.trpcState);
49
- return /*#__PURE__*/ React.createElement(trpc.Provider, {
50
- abortOnUnmount: prepassProps.abortOnUnmount ?? false,
51
- client: trpcClient,
52
- queryClient: queryClient,
53
- ssrState: ssrState,
54
- ssrContext: ssrContext
55
- }, /*#__PURE__*/ React.createElement(QueryClientProvider, {
56
- client: queryClient
57
- }, /*#__PURE__*/ React.createElement(HydrationBoundary, {
58
- state: hydratedState
59
- }, /*#__PURE__*/ React.createElement(AppOrPage, Object.assign({}, props)))));
60
- };
61
- if (AppOrPage.getInitialProps ?? opts.ssr) {
62
- WithTRPC.getInitialProps = async (appOrPageCtx)=>{
63
- const AppTree = appOrPageCtx.AppTree;
64
- // Determine if we are wrapping an App component or a Page component.
65
- const isApp = !!appOrPageCtx.Component;
66
- const ctx = isApp ? appOrPageCtx.ctx : appOrPageCtx;
67
- // Run the wrapped component's getInitialProps function.
68
- let pageProps = {};
69
- if (AppOrPage.getInitialProps) {
70
- const originalProps = await AppOrPage.getInitialProps(appOrPageCtx);
71
- const originalPageProps = isApp ? originalProps.pageProps ?? {} : originalProps;
72
- pageProps = {
73
- ...originalPageProps,
74
- ...pageProps
75
- };
76
- }
77
- const getAppTreeProps = (props)=>isApp ? {
78
- pageProps: props
79
- } : props;
80
- if (typeof window !== 'undefined' || !opts.ssr) {
81
- return getAppTreeProps(pageProps);
82
- }
83
- const config = getClientConfig({
84
- ctx
85
- });
86
- const trpcClient = createTRPCUntypedClient(config);
87
- const queryClient = getQueryClient(config);
88
- const trpcProp = {
89
- config,
90
- trpcClient,
91
- queryClient,
92
- ssrState: 'prepass',
93
- ssrContext: ctx
94
- };
95
- const prepassProps = {
96
- pageProps,
97
- trpc: trpcProp
98
- };
99
- // Run the prepass step on AppTree. This will run all trpc queries on the server.
100
- // multiple prepass ensures that we can do batching on the server
101
- while(true){
102
- // render full tree
103
- await ssrPrepass(/*#__PURE__*/ createElement(AppTree, prepassProps));
104
- if (!queryClient.isFetching()) {
105
- break;
106
- }
107
- // wait until the query cache has settled it's promises
108
- await new Promise((resolve)=>{
109
- const unsub = queryClient.getQueryCache().subscribe((event)=>{
110
- if (event?.query.getObserversCount() === 0) {
111
- resolve();
112
- unsub();
113
- }
114
- });
115
- });
116
- }
117
- const dehydratedCache = dehydrate(queryClient, {
118
- shouldDehydrateQuery () {
119
- // makes sure errors are also dehydrated
120
- return true;
121
- }
122
- });
123
- // since error instances can't be serialized, let's make them into `TRPCClientErrorLike`-objects
124
- const dehydratedCacheWithErrors = {
125
- ...dehydratedCache,
126
- queries: dehydratedCache.queries.map(transformQueryOrMutationCacheErrors),
127
- mutations: dehydratedCache.mutations.map(transformQueryOrMutationCacheErrors)
128
- };
129
- // dehydrate query client's state and add it to the props
130
- pageProps.trpcState = trpcClient.runtime.combinedTransformer.output.serialize(dehydratedCacheWithErrors);
131
- const appTreeProps = getAppTreeProps(pageProps);
132
- const meta = opts.responseMeta?.({
133
- ctx,
134
- clientErrors: [
135
- ...dehydratedCache.queries,
136
- ...dehydratedCache.mutations
137
- ].map((v)=>v.state.error).flatMap((err)=>err instanceof Error && err.name === 'TRPCClientError' ? [
138
- err
139
- ] : [])
140
- }) ?? {};
141
- for (const [key, value] of Object.entries(meta.headers ?? {})){
142
- if (typeof value === 'string') {
143
- ctx.res?.setHeader(key, value);
144
- }
145
- }
146
- if (meta.status && ctx.res) {
147
- ctx.res.statusCode = meta.status;
148
- }
149
- return appTreeProps;
150
- };
151
- }
152
- const displayName = AppOrPage.displayName ?? AppOrPage.name ?? 'Component';
153
- WithTRPC.displayName = `withTRPC(${displayName})`;
154
- return WithTRPC;
155
- };
156
- }
157
-
158
- /* istanbul ignore file -- @preserve */ // We're testing this through E2E-testing
159
- function createTRPCNext(opts) {
160
- const hooks = createRootHooks(opts);
161
- // TODO: maybe set TSSRContext to `never` when using `WithTRPCNoSSROptions`
162
- const _withTRPC = withTRPC(opts);
163
- return createFlatProxy((key)=>{
164
- if (key === 'useContext' || key === 'useUtils') {
165
- return ()=>{
166
- const context = hooks.useUtils();
167
- // create a stable reference of the utils context
168
- return useMemo(()=>{
169
- return createReactQueryUtils(context);
170
- }, [
171
- context
172
- ]);
173
- };
174
- }
175
- if (key === 'useQueries') {
176
- return hooks.useQueries;
177
- }
178
- if (key === 'withTRPC') {
179
- return _withTRPC;
180
- }
181
- return createReactDecoration(key, hooks);
182
- });
183
- }
184
-
185
- export { createTRPCNext, withTRPC };
1
+ export { withTRPC } from './withTRPC.mjs';
2
+ export { createTRPCNext } from './createTRPCNext.mjs';
@@ -0,0 +1,3 @@
1
+ import type { TRPCPrepassHelper } from './withTRPC';
2
+ export declare const ssrPrepass: TRPCPrepassHelper;
3
+ //# sourceMappingURL=ssrPrepass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrPrepass.d.ts","sourceRoot":"","sources":["../src/ssrPrepass.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,YAAY,CAAC;AAyBtE,eAAO,MAAM,UAAU,EAAE,iBA0IxB,CAAC"}
@@ -0,0 +1,139 @@
1
+ 'use strict';
2
+
3
+ var reactQuery = require('@tanstack/react-query');
4
+ var client = require('@trpc/client');
5
+ var unstableInternals = require('@trpc/client/unstable-internals');
6
+ var shared = require('@trpc/react-query/shared');
7
+ var React = require('react');
8
+
9
+ function transformQueryOrMutationCacheErrors(result) {
10
+ const error = result.state.error;
11
+ if (error instanceof Error && error.name === 'TRPCClientError') {
12
+ const newError = {
13
+ message: error.message,
14
+ data: error.data,
15
+ shape: error.shape
16
+ };
17
+ return {
18
+ ...result,
19
+ state: {
20
+ ...result.state,
21
+ error: newError
22
+ }
23
+ };
24
+ }
25
+ return result;
26
+ }
27
+ const ssrPrepass = (opts)=>{
28
+ const { parent , WithTRPC , AppOrPage } = opts;
29
+ const transformer = unstableInternals.getTransformer(parent.transformer);
30
+ WithTRPC.getInitialProps = async (appOrPageCtx)=>{
31
+ const shouldSsr = async ()=>{
32
+ if (typeof window !== 'undefined') {
33
+ return false;
34
+ }
35
+ if (typeof parent.ssr === 'function') {
36
+ try {
37
+ return await parent.ssr({
38
+ ctx: appOrPageCtx.ctx
39
+ });
40
+ } catch (e) {
41
+ return false;
42
+ }
43
+ }
44
+ return parent.ssr;
45
+ };
46
+ const ssrEnabled = await shouldSsr();
47
+ const AppTree = appOrPageCtx.AppTree;
48
+ // Determine if we are wrapping an App component or a Page component.
49
+ const isApp = !!appOrPageCtx.Component;
50
+ const ctx = isApp ? appOrPageCtx.ctx : appOrPageCtx;
51
+ // Run the wrapped component's getInitialProps function.
52
+ let pageProps = {};
53
+ if (AppOrPage.getInitialProps) {
54
+ const originalProps = await AppOrPage.getInitialProps(appOrPageCtx);
55
+ const originalPageProps = isApp ? originalProps.pageProps ?? {} : originalProps;
56
+ pageProps = {
57
+ ...originalPageProps,
58
+ ...pageProps
59
+ };
60
+ }
61
+ const getAppTreeProps = (props)=>isApp ? {
62
+ pageProps: props
63
+ } : props;
64
+ if (typeof window !== 'undefined' || !ssrEnabled) {
65
+ return getAppTreeProps(pageProps);
66
+ }
67
+ const config = parent.config({
68
+ ctx
69
+ });
70
+ const trpcClient = client.createTRPCUntypedClient(config);
71
+ const queryClient = shared.getQueryClient(config);
72
+ const trpcProp = {
73
+ config,
74
+ trpcClient,
75
+ queryClient,
76
+ ssrState: 'prepass',
77
+ ssrContext: ctx
78
+ };
79
+ const prepassProps = {
80
+ pageProps,
81
+ trpc: trpcProp
82
+ };
83
+ const reactDomServer = await import('react-dom/server');
84
+ // Run the prepass step on AppTree. This will run all trpc queries on the server.
85
+ // multiple prepass ensures that we can do batching on the server
86
+ while(true){
87
+ // render full tree
88
+ reactDomServer.renderToString(React.createElement(AppTree, prepassProps));
89
+ if (!queryClient.isFetching()) {
90
+ break;
91
+ }
92
+ // wait until the query cache has settled it's promises
93
+ await new Promise((resolve)=>{
94
+ const unsub = queryClient.getQueryCache().subscribe((event)=>{
95
+ if (event?.query.getObserversCount() === 0) {
96
+ resolve();
97
+ unsub();
98
+ }
99
+ });
100
+ });
101
+ }
102
+ const dehydratedCache = reactQuery.dehydrate(queryClient, {
103
+ shouldDehydrateQuery (query) {
104
+ // filter out queries that are marked as trpc: { ssr: false } or are not enabled, but make sure errors are dehydrated
105
+ const isExcludedFromSSr = query.state.fetchStatus === 'idle' && query.state.status === 'pending';
106
+ return !isExcludedFromSSr;
107
+ }
108
+ });
109
+ // since error instances can't be serialized, let's make them into `TRPCClientErrorLike`-objects
110
+ const dehydratedCacheWithErrors = {
111
+ ...dehydratedCache,
112
+ queries: dehydratedCache.queries.map(transformQueryOrMutationCacheErrors),
113
+ mutations: dehydratedCache.mutations.map(transformQueryOrMutationCacheErrors)
114
+ };
115
+ // dehydrate query client's state and add it to the props
116
+ pageProps['trpcState'] = transformer.input.serialize(dehydratedCacheWithErrors);
117
+ const appTreeProps = getAppTreeProps(pageProps);
118
+ const meta = parent.responseMeta?.({
119
+ ctx,
120
+ clientErrors: [
121
+ ...dehydratedCache.queries,
122
+ ...dehydratedCache.mutations
123
+ ].map((v)=>v.state.error).flatMap((err)=>err instanceof Error && err.name === 'TRPCClientError' ? [
124
+ err
125
+ ] : [])
126
+ }) ?? {};
127
+ for (const [key, value] of Object.entries(meta.headers ?? {})){
128
+ if (typeof value === 'string') {
129
+ ctx.res?.setHeader(key, value);
130
+ }
131
+ }
132
+ if (meta.status && ctx.res) {
133
+ ctx.res.statusCode = meta.status;
134
+ }
135
+ return appTreeProps;
136
+ };
137
+ };
138
+
139
+ exports.ssrPrepass = ssrPrepass;
@@ -0,0 +1,137 @@
1
+ import { dehydrate } from '@tanstack/react-query';
2
+ import { createTRPCUntypedClient } from '@trpc/client';
3
+ import { getTransformer } from '@trpc/client/unstable-internals';
4
+ import { getQueryClient } from '@trpc/react-query/shared';
5
+ import { createElement } from 'react';
6
+
7
+ function transformQueryOrMutationCacheErrors(result) {
8
+ const error = result.state.error;
9
+ if (error instanceof Error && error.name === 'TRPCClientError') {
10
+ const newError = {
11
+ message: error.message,
12
+ data: error.data,
13
+ shape: error.shape
14
+ };
15
+ return {
16
+ ...result,
17
+ state: {
18
+ ...result.state,
19
+ error: newError
20
+ }
21
+ };
22
+ }
23
+ return result;
24
+ }
25
+ const ssrPrepass = (opts)=>{
26
+ const { parent , WithTRPC , AppOrPage } = opts;
27
+ const transformer = getTransformer(parent.transformer);
28
+ WithTRPC.getInitialProps = async (appOrPageCtx)=>{
29
+ const shouldSsr = async ()=>{
30
+ if (typeof window !== 'undefined') {
31
+ return false;
32
+ }
33
+ if (typeof parent.ssr === 'function') {
34
+ try {
35
+ return await parent.ssr({
36
+ ctx: appOrPageCtx.ctx
37
+ });
38
+ } catch (e) {
39
+ return false;
40
+ }
41
+ }
42
+ return parent.ssr;
43
+ };
44
+ const ssrEnabled = await shouldSsr();
45
+ const AppTree = appOrPageCtx.AppTree;
46
+ // Determine if we are wrapping an App component or a Page component.
47
+ const isApp = !!appOrPageCtx.Component;
48
+ const ctx = isApp ? appOrPageCtx.ctx : appOrPageCtx;
49
+ // Run the wrapped component's getInitialProps function.
50
+ let pageProps = {};
51
+ if (AppOrPage.getInitialProps) {
52
+ const originalProps = await AppOrPage.getInitialProps(appOrPageCtx);
53
+ const originalPageProps = isApp ? originalProps.pageProps ?? {} : originalProps;
54
+ pageProps = {
55
+ ...originalPageProps,
56
+ ...pageProps
57
+ };
58
+ }
59
+ const getAppTreeProps = (props)=>isApp ? {
60
+ pageProps: props
61
+ } : props;
62
+ if (typeof window !== 'undefined' || !ssrEnabled) {
63
+ return getAppTreeProps(pageProps);
64
+ }
65
+ const config = parent.config({
66
+ ctx
67
+ });
68
+ const trpcClient = createTRPCUntypedClient(config);
69
+ const queryClient = getQueryClient(config);
70
+ const trpcProp = {
71
+ config,
72
+ trpcClient,
73
+ queryClient,
74
+ ssrState: 'prepass',
75
+ ssrContext: ctx
76
+ };
77
+ const prepassProps = {
78
+ pageProps,
79
+ trpc: trpcProp
80
+ };
81
+ const reactDomServer = await import('react-dom/server');
82
+ // Run the prepass step on AppTree. This will run all trpc queries on the server.
83
+ // multiple prepass ensures that we can do batching on the server
84
+ while(true){
85
+ // render full tree
86
+ reactDomServer.renderToString(createElement(AppTree, prepassProps));
87
+ if (!queryClient.isFetching()) {
88
+ break;
89
+ }
90
+ // wait until the query cache has settled it's promises
91
+ await new Promise((resolve)=>{
92
+ const unsub = queryClient.getQueryCache().subscribe((event)=>{
93
+ if (event?.query.getObserversCount() === 0) {
94
+ resolve();
95
+ unsub();
96
+ }
97
+ });
98
+ });
99
+ }
100
+ const dehydratedCache = dehydrate(queryClient, {
101
+ shouldDehydrateQuery (query) {
102
+ // filter out queries that are marked as trpc: { ssr: false } or are not enabled, but make sure errors are dehydrated
103
+ const isExcludedFromSSr = query.state.fetchStatus === 'idle' && query.state.status === 'pending';
104
+ return !isExcludedFromSSr;
105
+ }
106
+ });
107
+ // since error instances can't be serialized, let's make them into `TRPCClientErrorLike`-objects
108
+ const dehydratedCacheWithErrors = {
109
+ ...dehydratedCache,
110
+ queries: dehydratedCache.queries.map(transformQueryOrMutationCacheErrors),
111
+ mutations: dehydratedCache.mutations.map(transformQueryOrMutationCacheErrors)
112
+ };
113
+ // dehydrate query client's state and add it to the props
114
+ pageProps['trpcState'] = transformer.input.serialize(dehydratedCacheWithErrors);
115
+ const appTreeProps = getAppTreeProps(pageProps);
116
+ const meta = parent.responseMeta?.({
117
+ ctx,
118
+ clientErrors: [
119
+ ...dehydratedCache.queries,
120
+ ...dehydratedCache.mutations
121
+ ].map((v)=>v.state.error).flatMap((err)=>err instanceof Error && err.name === 'TRPCClientError' ? [
122
+ err
123
+ ] : [])
124
+ }) ?? {};
125
+ for (const [key, value] of Object.entries(meta.headers ?? {})){
126
+ if (typeof value === 'string') {
127
+ ctx.res?.setHeader(key, value);
128
+ }
129
+ }
130
+ if (meta.status && ctx.res) {
131
+ ctx.res.statusCode = meta.status;
132
+ }
133
+ return appTreeProps;
134
+ };
135
+ };
136
+
137
+ export { ssrPrepass };
@@ -1,27 +1,55 @@
1
- import { CreateTRPCClientOptions } from '@trpc/client';
2
- import { TRPCClientError } from '@trpc/react-query';
3
- import { CreateTRPCReactOptions, CreateTRPCReactQueryClientConfig } from '@trpc/react-query/shared';
4
- import type { AnyRouter } from '@trpc/server';
5
- import type { ResponseMeta } from '@trpc/server/http';
6
- import { NextComponentType, NextPageContext } from 'next/dist/shared/lib/utils';
1
+ /**
2
+ * Heavily based on urql's ssr
3
+ * https://github.com/FormidableLabs/urql/blob/main/packages/next-urql/src/with-urql-client.ts
4
+ */
5
+ import type { QueryClient } from '@tanstack/react-query';
6
+ import type { CreateTRPCClientOptions, TRPCUntypedClient } from '@trpc/client';
7
+ import { type TransformerOptions } from '@trpc/client/unstable-internals';
8
+ import type { TRPCClientError } from '@trpc/react-query';
9
+ import type { CreateTRPCReactOptions, CreateTRPCReactQueryClientConfig } from '@trpc/react-query/shared';
10
+ import type { AnyRouter, inferClientTypes, ResponseMeta } from '@trpc/server/unstable-core-do-not-import';
11
+ import type { NextComponentType, NextPageContext } from 'next/dist/shared/lib/utils';
7
12
  export type WithTRPCConfig<TRouter extends AnyRouter> = CreateTRPCClientOptions<TRouter> & CreateTRPCReactQueryClientConfig & {
8
13
  abortOnUnmount?: boolean;
9
14
  };
10
- interface WithTRPCOptions<TRouter extends AnyRouter> extends CreateTRPCReactOptions<TRouter> {
15
+ type WithTRPCOptions<TRouter extends AnyRouter> = CreateTRPCReactOptions<TRouter> & {
11
16
  config: (info: {
12
17
  ctx?: NextPageContext;
13
18
  }) => WithTRPCConfig<TRouter>;
14
- }
15
- export interface WithTRPCSSROptions<TRouter extends AnyRouter> extends WithTRPCOptions<TRouter> {
16
- ssr: true;
19
+ } & TransformerOptions<inferClientTypes<TRouter>>;
20
+ export type TRPCPrepassHelper = (opts: {
21
+ parent: WithTRPCSSROptions<AnyRouter>;
22
+ WithTRPC: NextComponentType<any, any, any>;
23
+ AppOrPage: NextComponentType<any, any, any>;
24
+ }) => void;
25
+ export type WithTRPCSSROptions<TRouter extends AnyRouter> = WithTRPCOptions<TRouter> & {
26
+ /**
27
+ * If you enable this, you also need to add a `ssrPrepass`-prop
28
+ * @link https://trpc.io/docs/client/nextjs/ssr
29
+ */
30
+ ssr: true | ((opts: {
31
+ ctx: NextPageContext;
32
+ }) => boolean | Promise<boolean>);
17
33
  responseMeta?: (opts: {
18
34
  ctx: NextPageContext;
19
35
  clientErrors: TRPCClientError<TRouter>[];
20
36
  }) => ResponseMeta;
21
- }
22
- export interface WithTRPCNoSSROptions<TRouter extends AnyRouter> extends WithTRPCOptions<TRouter> {
37
+ /**
38
+ * use `import { ssrPrepass } from '@trpc/next/ssrPrepass'`
39
+ * @link https://trpc.io/docs/client/nextjs/ssr
40
+ */
41
+ ssrPrepass: TRPCPrepassHelper;
42
+ };
43
+ export type WithTRPCNoSSROptions<TRouter extends AnyRouter> = WithTRPCOptions<TRouter> & {
23
44
  ssr?: false;
24
- }
45
+ };
46
+ export type TRPCPrepassProps<TRouter extends AnyRouter, TSSRContext extends NextPageContext = NextPageContext> = {
47
+ config: WithTRPCConfig<TRouter>;
48
+ queryClient: QueryClient;
49
+ trpcClient: TRPCUntypedClient<TRouter>;
50
+ ssrState: 'prepass';
51
+ ssrContext: TSSRContext;
52
+ };
25
53
  export declare function withTRPC<TRouter extends AnyRouter, TSSRContext extends NextPageContext = NextPageContext>(opts: WithTRPCNoSSROptions<TRouter> | WithTRPCSSROptions<TRouter>): (AppOrPage: NextComponentType<any, any, any>) => NextComponentType;
26
54
  export {};
27
55
  //# sourceMappingURL=withTRPC.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"withTRPC.d.ts","sourceRoot":"","sources":["../src/withTRPC.tsx"],"names":[],"mappings":"AAWA,OAAO,EACL,uBAAuB,EAGxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,eAAe,EAAuB,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAEL,sBAAsB,EACtB,gCAAgC,EAEjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAGL,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AA2BpC,MAAM,MAAM,cAAc,CAAC,OAAO,SAAS,SAAS,IAClD,uBAAuB,CAAC,OAAO,CAAC,GAC9B,gCAAgC,GAAG;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEN,UAAU,eAAe,CAAC,OAAO,SAAS,SAAS,CACjD,SAAQ,sBAAsB,CAAC,OAAO,CAAC;IACvC,MAAM,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,CAAC,EAAE,eAAe,CAAA;KAAE,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,kBAAkB,CAAC,OAAO,SAAS,SAAS,CAC3D,SAAQ,eAAe,CAAC,OAAO,CAAC;IAChC,GAAG,EAAE,IAAI,CAAC;IACV,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QACpB,GAAG,EAAE,eAAe,CAAC;QACrB,YAAY,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;KAC1C,KAAK,YAAY,CAAC;CACpB;AACD,MAAM,WAAW,oBAAoB,CAAC,OAAO,SAAS,SAAS,CAC7D,SAAQ,eAAe,CAAC,OAAO,CAAC;IAChC,GAAG,CAAC,EAAE,KAAK,CAAC;CACb;AAED,wBAAgB,QAAQ,CACtB,OAAO,SAAS,SAAS,EACzB,WAAW,SAAS,eAAe,GAAG,eAAe,EACrD,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,eAU9C,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,KAAG,iBAAiB,CA+KxE"}
1
+ {"version":3,"file":"withTRPC.d.ts","sourceRoot":"","sources":["../src/withTRPC.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAE/E,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EACV,sBAAsB,EACtB,gCAAgC,EACjC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EACV,SAAS,EAET,gBAAgB,EAChB,YAAY,EACb,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAGV,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAIpC,MAAM,MAAM,cAAc,CAAC,OAAO,SAAS,SAAS,IAClD,uBAAuB,CAAC,OAAO,CAAC,GAC9B,gCAAgC,GAAG;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEN,KAAK,eAAe,CAAC,OAAO,SAAS,SAAS,IAC5C,sBAAsB,CAAC,OAAO,CAAC,GAAG;IAChC,MAAM,EAAE,CAAC,IAAI,EAAE;QAAE,GAAG,CAAC,EAAE,eAAe,CAAA;KAAE,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC;CACtE,GAAG,kBAAkB,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACtC,QAAQ,EAAE,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC3C,SAAS,EAAE,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;CAC7C,KAAK,IAAI,CAAC;AACX,MAAM,MAAM,kBAAkB,CAAC,OAAO,SAAS,SAAS,IACtD,eAAe,CAAC,OAAO,CAAC,GAAG;IACzB;;;OAGG;IACH,GAAG,EACC,IAAI,GACJ,CAAC,CAAC,IAAI,EAAE;QAAE,GAAG,EAAE,eAAe,CAAA;KAAE,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE;QACpB,GAAG,EAAE,eAAe,CAAC;QACrB,YAAY,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;KAC1C,KAAK,YAAY,CAAC;IACnB;;;OAGG;IACH,UAAU,EAAE,iBAAiB,CAAC;CAC/B,CAAC;AAEJ,MAAM,MAAM,oBAAoB,CAAC,OAAO,SAAS,SAAS,IACxD,eAAe,CAAC,OAAO,CAAC,GAAG;IACzB,GAAG,CAAC,EAAE,KAAK,CAAC;CACb,CAAC;AAEJ,MAAM,MAAM,gBAAgB,CAC1B,OAAO,SAAS,SAAS,EACzB,WAAW,SAAS,eAAe,GAAG,eAAe,IACnD;IACF,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACvC,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,wBAAgB,QAAQ,CACtB,OAAO,SAAS,SAAS,EACzB,WAAW,SAAS,eAAe,GAAG,eAAe,EACrD,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,eAO9C,kBAAkB,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,KAAG,iBAAiB,CAgGxE"}
@@ -0,0 +1,86 @@
1
+ 'use strict';
2
+
3
+ var reactQuery = require('@tanstack/react-query');
4
+ var unstableInternals = require('@trpc/client/unstable-internals');
5
+ var shared = require('@trpc/react-query/shared');
6
+ var React = require('react');
7
+
8
+ function withTRPC(opts) {
9
+ const { config: getClientConfig } = opts;
10
+ const transformer = unstableInternals.getTransformer(opts.transformer);
11
+ return (AppOrPage)=>{
12
+ const trpc = shared.createRootHooks(opts);
13
+ const WithTRPC = (props)=>{
14
+ const [prepassProps] = React.useState(()=>{
15
+ if (props.trpc) {
16
+ return props.trpc;
17
+ }
18
+ const config = getClientConfig({});
19
+ const queryClient = shared.getQueryClient(config);
20
+ const trpcClient = trpc.createClient(config);
21
+ return {
22
+ abortOnUnmount: config.abortOnUnmount,
23
+ queryClient,
24
+ trpcClient,
25
+ ssrState: opts.ssr ? 'mounting' : false,
26
+ ssrContext: null
27
+ };
28
+ });
29
+ const { queryClient , trpcClient , ssrState , ssrContext } = prepassProps;
30
+ // allow normal components to be wrapped, not just app/pages
31
+ const trpcState = props.pageProps?.trpcState;
32
+ const hydratedState = React.useMemo(()=>{
33
+ if (!trpcState) {
34
+ return trpcState;
35
+ }
36
+ return transformer.input.deserialize(trpcState);
37
+ // eslint-disable-next-line react-hooks/exhaustive-deps
38
+ }, [
39
+ trpcState,
40
+ trpcClient
41
+ ]);
42
+ return /*#__PURE__*/ React.createElement(trpc.Provider, {
43
+ abortOnUnmount: prepassProps.abortOnUnmount ?? false,
44
+ client: trpcClient,
45
+ queryClient: queryClient,
46
+ ssrState: ssrState,
47
+ ssrContext: ssrContext
48
+ }, /*#__PURE__*/ React.createElement(reactQuery.QueryClientProvider, {
49
+ client: queryClient
50
+ }, /*#__PURE__*/ React.createElement(reactQuery.HydrationBoundary, {
51
+ state: hydratedState
52
+ }, /*#__PURE__*/ React.createElement(AppOrPage, Object.assign({}, props)))));
53
+ };
54
+ if (opts.ssr) {
55
+ opts.ssrPrepass({
56
+ parent: opts,
57
+ AppOrPage,
58
+ WithTRPC
59
+ });
60
+ } else if (AppOrPage.getInitialProps) {
61
+ // Allow combining `getServerSideProps` and `getInitialProps`
62
+ WithTRPC.getInitialProps = async (appOrPageCtx)=>{
63
+ // Determine if we are wrapping an App component or a Page component.
64
+ const isApp = !!appOrPageCtx.Component;
65
+ // Run the wrapped component's getInitialProps function.
66
+ let pageProps = {};
67
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
68
+ const originalProps = await AppOrPage.getInitialProps(appOrPageCtx);
69
+ const originalPageProps = isApp ? originalProps.pageProps ?? {} : originalProps;
70
+ pageProps = {
71
+ ...originalPageProps,
72
+ ...pageProps
73
+ };
74
+ const getAppTreeProps = (props)=>isApp ? {
75
+ pageProps: props
76
+ } : props;
77
+ return getAppTreeProps(pageProps);
78
+ };
79
+ }
80
+ const displayName = AppOrPage.displayName ?? AppOrPage.name ?? 'Component';
81
+ WithTRPC.displayName = `withTRPC(${displayName})`;
82
+ return WithTRPC;
83
+ };
84
+ }
85
+
86
+ exports.withTRPC = withTRPC;