UNPKG

@trpc/next

Version:

The tRPC Next.js library

61 lines (58 loc) 2.89 kB
import { TRPCClientError } from '@trpc/client'; import { getTransformer } from '@trpc/client/unstable-internals'; import { observable } from '@trpc/server/observable'; import { callProcedure } from '@trpc/server/unstable-core-do-not-import'; import { unstable_cache } from 'next/cache'; import { generateCacheTag } from '../shared.mjs'; // import "server-only"; // ts-prune-ignore-next function experimental_nextCacheLink(opts) { const transformer = getTransformer(opts.transformer); return ()=>({ op })=>observable((observer)=>{ const { path, input, type, context } = op; const cacheTag = generateCacheTag(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 promise = opts.createContext().then(async (ctx)=>{ const callProc = async (_cachebuster)=>{ // // _cachebuster is not used by us but to make sure // // that calls with different tags are properly separated // // @link https://github.com/trpc/trpc/issues/4622 const procedureResult = await callProcedure({ router: opts.router, path, getRawInput: async ()=>input, ctx: ctx, type, signal: undefined }); // We need to serialize cause the cache only accepts JSON return transformer.input.serialize(procedureResult); }; if (type === 'query') { return unstable_cache(callProc, path.split('.'), { revalidate, tags: [ cacheTag ] })(cacheTag); } return callProc(); }).catch((cause)=>{ observer.error(TRPCClientError.from(cause)); }); promise.then((data)=>{ const transformedResult = transformer.output.deserialize(data); observer.next({ result: { data: transformedResult } }); observer.complete(); }).catch((cause)=>{ observer.error(TRPCClientError.from(cause)); }); }); } export { experimental_nextCacheLink };