refactor: remove core-trpc from main (scaffoldable via gen core-package trpc)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-09 14:10:48 +02:00
parent d216250ccd
commit c8116ac3f4
21 changed files with 3 additions and 381 deletions

View File

@@ -8,7 +8,6 @@ const nextConfig = {
"@repo/core-api", "@repo/core-api",
"@repo/core-cms", "@repo/core-cms",
"@repo/core-shared", "@repo/core-shared",
"@repo/core-trpc",
"@repo/core-ui", "@repo/core-ui",
"@repo/marketing-pages", "@repo/marketing-pages",
"@repo/media", "@repo/media",

View File

@@ -19,7 +19,6 @@
"@repo/core-api": "workspace:*", "@repo/core-api": "workspace:*",
"@repo/core-cms": "workspace:*", "@repo/core-cms": "workspace:*",
"@repo/core-shared": "workspace:*", "@repo/core-shared": "workspace:*",
"@repo/core-trpc": "workspace:*",
"@repo/core-ui": "workspace:*", "@repo/core-ui": "workspace:*",
"@repo/marketing-pages": "workspace:*", "@repo/marketing-pages": "workspace:*",
"@repo/media": "workspace:*", "@repo/media": "workspace:*",

View File

@@ -1,15 +0,0 @@
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "@repo/core-api";
import { bindAll } from "../../../../server/bind-production";
const handler = async (req: Request) => {
await bindAll();
return fetchRequestHandler({
endpoint: "/api/trpc",
req,
router: appRouter,
createContext: () => ({}),
});
};
export { handler as GET, handler as POST };

View File

@@ -1,7 +1,5 @@
"use client"; "use client";
import { NextTrpcProvider } from "@repo/core-trpc/next";
export function Providers({ children }: { children: React.ReactNode }) { export function Providers({ children }: { children: React.ReactNode }) {
return <NextTrpcProvider trpcUrl="/api/trpc">{children}</NextTrpcProvider>; return <>{children}</>;
} }

File diff suppressed because one or more lines are too long

View File

@@ -15,7 +15,6 @@
"@repo/blog": "workspace:*", "@repo/blog": "workspace:*",
"@repo/core-api": "workspace:*", "@repo/core-api": "workspace:*",
"@repo/core-shared": "workspace:*", "@repo/core-shared": "workspace:*",
"@repo/core-trpc": "workspace:*",
"@repo/core-ui": "workspace:*", "@repo/core-ui": "workspace:*",
"@repo/marketing-pages": "workspace:*", "@repo/marketing-pages": "workspace:*",
"@repo/navigation": "workspace:*", "@repo/navigation": "workspace:*",

View File

@@ -1,10 +1,5 @@
import { Outlet, createRootRoute } from "@tanstack/react-router"; import { Outlet, createRootRoute } from "@tanstack/react-router";
import { TanstackTrpcProvider } from "@repo/core-trpc/tanstack";
export const Route = createRootRoute({ export const Route = createRootRoute({
component: () => ( component: () => <Outlet />,
<TanstackTrpcProvider trpcUrl="http://localhost:3000/api/trpc">
<Outlet />
</TanstackTrpcProvider>
),
}); });

View File

@@ -1,6 +1,4 @@
import { createFileRoute } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router";
import { useQuery } from "@tanstack/react-query";
import { useTRPC } from "@repo/core-trpc";
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
export const Route = createFileRoute("/" as any)({ export const Route = createFileRoute("/" as any)({
@@ -8,35 +6,8 @@ export const Route = createFileRoute("/" as any)({
}); });
function Home() { function Home() {
const trpc = useTRPC();
const siteSettings = useQuery(trpc.marketingPages.siteSettings.queryOptions({}));
const header = useQuery(trpc.navigation.header.queryOptions({}));
if (siteSettings.isPending || header.isPending) {
return <main>Loading</main>;
}
if (siteSettings.error || header.error) {
return (
<main>
Failed to load: {siteSettings.error?.message ?? header.error?.message}
</main>
);
}
return ( return (
<main> <main>
<header>
<h1>{siteSettings.data?.siteName} TanStack edition</h1>
<nav>
<ul>
{header.data?.items.map((item) => (
<li key={item.href}>
<a href={item.href}>{item.label}</a>
</li>
))}
</ul>
</nav>
</header>
<p>This page is rendered by TanStack Router and consumes the same feature packages as the Next.js app.</p> <p>This page is rendered by TanStack Router and consumes the same feature packages as the Next.js app.</p>
</main> </main>
); );

View File

@@ -1,56 +0,0 @@
# AGENTS.md — core-trpc
**Tag:** core-composition
Frontend tRPC platform providing the client and framework-specific providers (Next.js, TanStack). Bridges typed backend (`@repo/core-api`) to frontend applications. Tagged `core-composition` (not `core`) because it transitively reaches features through `core-api`'s `AppRouter` type.
## Responsibilities
- **Create tRPC React client** — `createTRPCReact<AppRouter>()` for use in React apps
- **Query client factory** — TanStack React Query setup per app
- **Framework-specific providers** — Next.js App Router provider + TanStack Start provider
- **No business logic** — purely framework integration
## Must NOT import
- Any feature package (`@repo/auth`, `@repo/blog`, etc.)
- Any app package
- `@repo/core-api`, `@repo/core-cms`, `@repo/core-ui`
## Public exports
From `package.json`:
- `.` — client + query client factory
- `./next` — Next.js App Router provider
- `./tanstack` — TanStack Start provider
Example usage:
```typescript
// In Next.js app
import { TrpcProvider } from "@repo/core-trpc/next";
// In TanStack Start app
import { TrpcProvider } from "@repo/core-trpc/tanstack";
// In client components
import { useTRPC } from "@repo/core-trpc";
const trpc = useTRPC();
```
## Test conventions
- No unit tests (provider layer)
- Verify at app boot: `pnpm dev --filter @repo/web-next` or `pnpm dev --filter @repo/web-tanstack` succeeds
- Verify client type safety: `pnpm typecheck` confirms `AppRouter` is imported and typed correctly
## Structure
```
src/
client.ts # createTRPCReact<AppRouter>()
query-client.ts # makeQueryClient()
providers/
next-provider.tsx # 'use client' provider for Next.js
tanstack-provider.tsx # Provider for TanStack Start
index.ts # re-exports client + factories
```

View File

@@ -1,3 +0,0 @@
import baseConfig from "@repo/core-eslint/base";
export default baseConfig;

View File

@@ -1,37 +0,0 @@
{
"name": "@repo/core-trpc",
"private": true,
"version": "0.0.0",
"type": "module",
"exports": {
".": "./src/index.ts",
"./next": "./src/providers/next-provider.tsx",
"./tanstack": "./src/providers/tanstack-provider.tsx"
},
"scripts": {
"build": "tsc --noEmit",
"lint": "eslint .",
"typecheck": "tsc --noEmit",
"test": "vitest run --passWithNoTests"
},
"dependencies": {
"@repo/core-api": "workspace:*",
"@trpc/client": "^11.0.0",
"@trpc/react-query": "^11.0.0",
"@trpc/server": "^11.0.0",
"@trpc/tanstack-react-query": "^11.1.0",
"@tanstack/react-query": "^5.66.0",
"react": "^19.0.0",
"superjson": "^2.2.1"
},
"devDependencies": {
"@repo/core-eslint": "workspace:*",
"@repo/core-testing": "workspace:*",
"@repo/core-typescript": "workspace:*",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.0",
"@types/react": "^19.0.0",
"jsdom": "^25.0.0",
"vitest": "^3.0.0"
}
}

View File

@@ -1,12 +0,0 @@
import { describe, it, expect } from "vitest";
import { useTRPC, TRPCProvider } from "./client";
describe("core-trpc client exports", () => {
it("exports useTRPC hook", () => {
expect(useTRPC).toBeTypeOf("function");
});
it("exports TRPCProvider component", () => {
expect(TRPCProvider).toBeTypeOf("function");
});
});

View File

@@ -1,6 +0,0 @@
"use client";
import { createTRPCContext } from "@trpc/tanstack-react-query";
import type { AppRouter } from "@repo/core-api";
export const { TRPCProvider, useTRPC } = createTRPCContext<AppRouter>();

View File

@@ -1,3 +0,0 @@
export { useTRPC, TRPCProvider } from "./client";
export { getQueryClient } from "./query-client";
export type { AppRouter } from "@repo/core-api";

View File

@@ -1,32 +0,0 @@
"use client";
import { useState } from "react";
import { QueryClientProvider } from "@tanstack/react-query";
import { createTRPCClient, httpBatchLink } from "@trpc/client";
import superjson from "superjson";
import type { AppRouter } from "@repo/core-api";
import { TRPCProvider } from "../client";
import { getQueryClient } from "../query-client";
export function NextTrpcProvider({
children,
trpcUrl = "/api/trpc",
}: {
children: React.ReactNode;
trpcUrl?: string;
}) {
const [queryClient] = useState(() => getQueryClient());
const [trpcClient] = useState(() =>
createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: trpcUrl, transformer: superjson })],
}),
);
return (
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</TRPCProvider>
);
}

View File

@@ -1,32 +0,0 @@
"use client";
import { useState } from "react";
import { QueryClientProvider } from "@tanstack/react-query";
import { createTRPCClient, httpBatchLink } from "@trpc/client";
import superjson from "superjson";
import type { AppRouter } from "@repo/core-api";
import { TRPCProvider } from "../client";
import { getQueryClient } from "../query-client";
export function TanstackTrpcProvider({
children,
trpcUrl,
}: {
children: React.ReactNode;
trpcUrl: string;
}) {
const [queryClient] = useState(() => getQueryClient());
const [trpcClient] = useState(() =>
createTRPCClient<AppRouter>({
links: [httpBatchLink({ url: trpcUrl, transformer: superjson })],
}),
);
return (
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</TRPCProvider>
);
}

View File

@@ -1,22 +0,0 @@
import { QueryClient } from "@tanstack/react-query";
let clientQueryClient: QueryClient | undefined;
const defaultOptions = {
queries: {
staleTime: 30 * 1000,
refetchOnWindowFocus: false,
},
};
export function getQueryClient(): QueryClient {
if (typeof window === "undefined") {
// Server: always create a new instance per request
return new QueryClient({ defaultOptions });
}
// Browser: singleton
if (!clientQueryClient) {
clientQueryClient = new QueryClient({ defaultOptions });
}
return clientQueryClient;
}

View File

@@ -1,17 +0,0 @@
{
"extends": "@repo/core-typescript/base.json",
"compilerOptions": {
"outDir": "dist",
"rootDir": ".",
"lib": ["ES2022", "DOM"],
"jsx": "preserve",
"declaration": false,
"declarationMap": false,
"types": ["vitest/globals", "@testing-library/jest-dom"],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

View File

@@ -1,4 +0,0 @@
{
"extends": ["//"],
"tags": ["core-composition"]
}

View File

@@ -1,7 +0,0 @@
import path from "node:path";
import { mergeConfig } from "vitest/config";
import { jsdomVitestConfig } from "@repo/core-typescript/vitest.base.jsdom";
export default mergeConfig(jsdomVitestConfig, {
resolve: { alias: { "@": path.resolve(__dirname, "./src") } },
});

93
pnpm-lock.yaml generated
View File

@@ -157,9 +157,6 @@ importers:
'@repo/core-shared': '@repo/core-shared':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/core-shared version: link:../../packages/core-shared
'@repo/core-trpc':
specifier: workspace:*
version: link:../../packages/core-trpc
'@repo/core-ui': '@repo/core-ui':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/core-ui version: link:../../packages/core-ui
@@ -254,9 +251,6 @@ importers:
'@repo/core-shared': '@repo/core-shared':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/core-shared version: link:../../packages/core-shared
'@repo/core-trpc':
specifier: workspace:*
version: link:../../packages/core-trpc
'@repo/core-ui': '@repo/core-ui':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/core-ui version: link:../../packages/core-ui
@@ -629,58 +623,6 @@ importers:
specifier: ^5.8.0 specifier: ^5.8.0
version: 5.9.3 version: 5.9.3
packages/core-trpc:
dependencies:
'@repo/core-api':
specifier: workspace:*
version: link:../core-api
'@tanstack/react-query':
specifier: ^5.66.0
version: 5.96.2(react@19.2.4)
'@trpc/client':
specifier: ^11.0.0
version: 11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/react-query':
specifier: ^11.0.0
version: 11.17.0(@tanstack/react-query@5.96.2(react@19.2.4))(@trpc/client@11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.16.0(typescript@5.9.3))(react@19.2.4)(typescript@5.9.3)
'@trpc/server':
specifier: ^11.0.0
version: 11.16.0(typescript@5.9.3)
'@trpc/tanstack-react-query':
specifier: ^11.1.0
version: 11.16.0(@tanstack/react-query@5.96.2(react@19.2.4))(@trpc/client@11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.16.0(typescript@5.9.3))(react@19.2.4)(typescript@5.9.3)
react:
specifier: ^19.0.0
version: 19.2.4
superjson:
specifier: ^2.2.1
version: 2.2.6
devDependencies:
'@repo/core-eslint':
specifier: workspace:*
version: link:../core-eslint
'@repo/core-testing':
specifier: workspace:*
version: link:../core-testing
'@repo/core-typescript':
specifier: workspace:*
version: link:../core-typescript
'@testing-library/jest-dom':
specifier: ^6.5.0
version: 6.9.1
'@testing-library/react':
specifier: ^16.0.0
version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@types/react':
specifier: ^19.0.0
version: 19.2.14
jsdom:
specifier: ^25.0.0
version: 25.0.1
vitest:
specifier: ^3.0.0
version: 3.2.4(@types/debug@4.1.13)(@types/node@25.5.2)(happy-dom@20.8.9)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.32.0)(sass@1.99.0)(terser@5.46.2)(tsx@4.21.0)
packages/core-typescript: packages/core-typescript:
devDependencies: devDependencies:
'@vitest/coverage-v8': '@vitest/coverage-v8':
@@ -3617,31 +3559,12 @@ packages:
'@trpc/server': 11.16.0 '@trpc/server': 11.16.0
typescript: '>=5.7.2' typescript: '>=5.7.2'
'@trpc/react-query@11.17.0':
resolution: {integrity: sha512-AGcl5YAF8NnhBmyJ6PqJqKb1M5VTGSoNRNqJ3orct4o4epdcg0GWhW+qT9q6gPzs/2ImIwYCdfFpgNGdZ9yLHA==}
peerDependencies:
'@tanstack/react-query': ^5.80.3
'@trpc/client': 11.17.0
'@trpc/server': 11.17.0
react: '>=18.2.0'
typescript: '>=5.7.2'
'@trpc/server@11.16.0': '@trpc/server@11.16.0':
resolution: {integrity: sha512-XgGuUMddrUTd04+za/WE5GFuZ1/YU9XQG0t3VL5WOIu2JspkOlq6k4RYEiqS6HSJt+S0RXaPdIoE2anIP/BBRQ==} resolution: {integrity: sha512-XgGuUMddrUTd04+za/WE5GFuZ1/YU9XQG0t3VL5WOIu2JspkOlq6k4RYEiqS6HSJt+S0RXaPdIoE2anIP/BBRQ==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
typescript: '>=5.7.2' typescript: '>=5.7.2'
'@trpc/tanstack-react-query@11.16.0':
resolution: {integrity: sha512-kfNYJ5NCk67tmRCO/QWCycJmRamuEKmZf1HRG8yCBl8aTJdTwVq7l6AffFIMab3Q+NmQzwP8XXkAEK/EelKYOA==}
hasBin: true
peerDependencies:
'@tanstack/react-query': ^5.80.3
'@trpc/client': 11.16.0
'@trpc/server': 11.16.0
react: '>=18.2.0'
typescript: '>=5.7.2'
'@turbo/darwin-64@2.9.4': '@turbo/darwin-64@2.9.4':
resolution: {integrity: sha512-ZSlPqJ5Vqg/wgVw8P3AOVCIosnbBilOxLq7TMz3MN/9U46DUYfdG2jtfevNDufyxyrg98pcPs/GBgDRaaids6g==} resolution: {integrity: sha512-ZSlPqJ5Vqg/wgVw8P3AOVCIosnbBilOxLq7TMz3MN/9U46DUYfdG2jtfevNDufyxyrg98pcPs/GBgDRaaids6g==}
cpu: [x64] cpu: [x64]
@@ -10706,26 +10629,10 @@ snapshots:
'@trpc/server': 11.16.0(typescript@5.9.3) '@trpc/server': 11.16.0(typescript@5.9.3)
typescript: 5.9.3 typescript: 5.9.3
'@trpc/react-query@11.17.0(@tanstack/react-query@5.96.2(react@19.2.4))(@trpc/client@11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.16.0(typescript@5.9.3))(react@19.2.4)(typescript@5.9.3)':
dependencies:
'@tanstack/react-query': 5.96.2(react@19.2.4)
'@trpc/client': 11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/server': 11.16.0(typescript@5.9.3)
react: 19.2.4
typescript: 5.9.3
'@trpc/server@11.16.0(typescript@5.9.3)': '@trpc/server@11.16.0(typescript@5.9.3)':
dependencies: dependencies:
typescript: 5.9.3 typescript: 5.9.3
'@trpc/tanstack-react-query@11.16.0(@tanstack/react-query@5.96.2(react@19.2.4))(@trpc/client@11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.16.0(typescript@5.9.3))(react@19.2.4)(typescript@5.9.3)':
dependencies:
'@tanstack/react-query': 5.96.2(react@19.2.4)
'@trpc/client': 11.16.0(@trpc/server@11.16.0(typescript@5.9.3))(typescript@5.9.3)
'@trpc/server': 11.16.0(typescript@5.9.3)
react: 19.2.4
typescript: 5.9.3
'@turbo/darwin-64@2.9.4': '@turbo/darwin-64@2.9.4':
optional: true optional: true