@trpc/next
Version:
90 lines (81 loc) • 2.48 kB
text/typescript
import type {
HTTPBatchLinkOptions,
HTTPLinkOptions,
TRPCLink,
} from '@trpc/client';
import { httpBatchLink, httpLink } from '@trpc/client';
import type {
AnyRootTypes,
AnyRouter,
} from '@trpc/server/unstable-core-do-not-import';
import { generateCacheTags } from '../shared';
interface NextLinkBaseOptions {
/**
* How many seconds Next.js caches a response. `false` caches it until it is
* revalidated. A call can override this with `context.revalidate`.
* @default false
*/
revalidate?: number | false;
/**
* Send each call with `httpBatchLink` instead of `httpLink`. Each call
* gets its own link, so calls aren't combined into one request.
*/
batch?: boolean;
}
type NextLinkSingleOptions<TRoot extends AnyRootTypes> = NextLinkBaseOptions &
Omit<HTTPLinkOptions<TRoot>, 'fetch'> & {
batch?: false;
};
type NextLinkBatchOptions<TRoot extends AnyRootTypes> = NextLinkBaseOptions &
Omit<HTTPBatchLinkOptions<TRoot>, 'fetch'> & {
batch: true;
};
/**
* A terminating link that sends calls over HTTP with Next.js cache tags, so
* they can be revalidated.
*
* @see https://trpc.io/docs/client/nextjs/app-router-setup
*/
// ts-prune-ignore-next
export function experimental_nextHttpLink<TRouter extends AnyRouter>(
opts:
| NextLinkSingleOptions<TRouter['_def']['_config']['$types']>
| NextLinkBatchOptions<TRouter['_def']['_config']['$types']>,
): TRPCLink<TRouter> {
return (runtime) => {
return (ctx) => {
const { path, input, context } = ctx.op;
const cacheTags = generateCacheTags(path, input);
// Let per-request revalidate override global revalidate
const requestRevalidate =
typeof context['revalidate'] === 'number' ||
context['revalidate'] === false
? context['revalidate']
: undefined;
const revalidate = requestRevalidate ?? opts.revalidate ?? false;
const _fetch: NonNullable<HTTPLinkOptions<AnyRootTypes>['fetch']> = (
url,
fetchOpts,
) => {
return fetch(url, {
...fetchOpts,
// cache: 'no-cache',
next: {
revalidate,
tags: cacheTags,
},
});
};
const link = opts.batch
? httpBatchLink({
...(opts as any),
fetch: _fetch,
})
: httpLink({
...(opts as any),
fetch: _fetch,
});
return link(runtime)(ctx);
};
};
}