@trpc/next
Version:
83 lines (80 loc) • 3.56 kB
JavaScript
import { QueryClientProvider, HydrationBoundary } from '@tanstack/react-query';
import { getTransformer } from '@trpc/client/unstable-internals';
import { createRootHooks, getQueryClient } from '@trpc/react-query/shared';
import React, { useState } from 'react';
function withTRPC(opts) {
const { config: getClientConfig } = opts;
const transformer = getTransformer(opts.transformer);
return (AppOrPage)=>{
const trpc = createRootHooks(opts);
const WithTRPC = (props)=>{
const [prepassProps] = useState(()=>{
if (props.trpc) {
return props.trpc;
}
const config = getClientConfig({});
const queryClient = getQueryClient(config);
const trpcClient = trpc.createClient(config);
return {
abortOnUnmount: config.abortOnUnmount,
queryClient,
trpcClient,
ssrState: opts.ssr ? 'mounting' : false,
ssrContext: null
};
});
const { queryClient, trpcClient, ssrState, ssrContext } = prepassProps;
// allow normal components to be wrapped, not just app/pages
const trpcState = props.pageProps?.trpcState;
const hydratedState = React.useMemo(()=>{
if (!trpcState) {
return trpcState;
}
return transformer.input.deserialize(trpcState);
}, [
trpcState
]);
return /*#__PURE__*/ React.createElement(trpc.Provider, {
abortOnUnmount: prepassProps.abortOnUnmount ?? false,
client: trpcClient,
queryClient: queryClient,
ssrState: ssrState,
ssrContext: ssrContext
}, /*#__PURE__*/ React.createElement(QueryClientProvider, {
client: queryClient
}, /*#__PURE__*/ React.createElement(HydrationBoundary, {
state: hydratedState
}, /*#__PURE__*/ React.createElement(AppOrPage, props))));
};
if (opts.ssr) {
opts.ssrPrepass({
parent: opts,
AppOrPage,
WithTRPC
});
} else if (AppOrPage.getInitialProps) {
// Allow combining `getServerSideProps` and `getInitialProps`
WithTRPC.getInitialProps = async (appOrPageCtx)=>{
// Determine if we are wrapping an App component or a Page component.
const isApp = !!appOrPageCtx.Component;
// Run the wrapped component's getInitialProps function.
let pageProps = {};
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const originalProps = await AppOrPage.getInitialProps(appOrPageCtx);
const originalPageProps = isApp ? originalProps.pageProps ?? {} : originalProps;
pageProps = {
...originalPageProps,
...pageProps
};
const getAppTreeProps = (props)=>isApp ? {
pageProps: props
} : props;
return getAppTreeProps(pageProps);
};
}
const displayName = AppOrPage.displayName ?? AppOrPage.name ?? 'Component';
WithTRPC.displayName = `withTRPC(${displayName})`;
return WithTRPC;
};
}
export { withTRPC };