core-trpc imported AppRouter (type-only) from core-api, which depends on the features, which depend on core-trpc — a cycle that killed every turbo graph walk (lint/build/CI) and an illegal core -> core-composition boundary edge. The tRPC context is now router-agnostic (AnyTRPCRouter); useTRPC takes the router type as a generic and each feature exports a type-only app-slice (e.g. BlogAppSlice) mirroring its mount key, so UI hooks keep full procedure typing without touching the composition layer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { QueryClientProvider } from "@tanstack/react-query";
|
|
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
|
import superjson from "superjson";
|
|
import type { AnyTRPCRouter } from "@trpc/server";
|
|
import { TRPCProvider } from "../client";
|
|
import { getQueryClient } from "../query-client";
|
|
|
|
function getBaseUrl() {
|
|
if (typeof window !== "undefined") return "";
|
|
return `http://localhost:${process.env.PORT ?? 3000}`;
|
|
}
|
|
|
|
export function NextTrpcProvider({
|
|
children,
|
|
trpcUrl = "/api/trpc",
|
|
}: {
|
|
children: React.ReactNode;
|
|
trpcUrl?: string;
|
|
}) {
|
|
const [queryClient] = useState(() => getQueryClient());
|
|
const [trpcClient] = useState(() =>
|
|
// Router-agnostic on purpose: procedure typing comes from useTRPC<TRouter>
|
|
// at the call sites, not from the wire-level client.
|
|
createTRPCClient<AnyTRPCRouter>({
|
|
links: [
|
|
httpBatchLink({
|
|
url: `${getBaseUrl()}${trpcUrl}`,
|
|
transformer: superjson,
|
|
}),
|
|
],
|
|
}),
|
|
);
|
|
|
|
return (
|
|
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
|
|
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
|
</TRPCProvider>
|
|
);
|
|
}
|