@trpc/next
Version:
61 lines (58 loc) • 2.89 kB
JavaScript
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 };