Config
The generated client accepts a config object with options for headers, retry, timeout, lifecycle hooks, and more.
Basic
import { createRpcClient } from './rpc-client';
const rpc = createRpcClient({
baseUrl: '/api',
});Full options
const rpc = createRpcClient({
baseUrl: '/api',
// Custom fetch (SSR, testing)
fetch: customFetch,
// Static or async headers
headers: { Authorization: 'Bearer token' },
// or: headers: async () => ({ Authorization: await getToken() }),
// Lifecycle hooks
onRequest: (ctx) => {
console.log(`→ ${ctx.procedure}`);
},
onResponse: (ctx) => {
console.log(`← ${ctx.procedure} (${ctx.duration}ms)`);
},
onError: (ctx) => {
if (ctx.willRetry) console.log(`Retrying ${ctx.procedure}...`);
},
// Retry policy
retry: {
attempts: 3,
delay: (n) => Math.min(1000 * 2 ** n, 10000),
retryOn: [408, 429, 500, 502, 503, 504],
},
// Timeout (ms)
timeout: 10000,
// Request deduplication
dedupe: true,
// Cancellation
signal: controller.signal,
// Custom serialization
serialize: JSON.stringify,
deserialize: JSON.parse,
});Lifecycle hook types
onRequest fires before the fetch — you can mutate ctx.headers. onResponse fires after a successful response. onError fires on failure — check ctx.willRetry to know if the client will
retry.
interface RequestContext {
procedure: string;
method: 'GET' | 'POST';
url: string;
headers: Record<string, string>; // mutable
input: unknown;
}
interface ResponseContext {
procedure: string;
method: 'GET' | 'POST';
url: string;
response: Response;
data: unknown;
duration: number;
}
interface ErrorContext {
procedure: string;
method: 'GET' | 'POST';
url: string;
error: unknown;
attempt: number;
willRetry: boolean;
}