forked from imbytecat/fullstack-starter
85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
/**
|
||
* ORPC 同构客户端
|
||
*
|
||
* 根据运行环境自动选择最优调用方式:
|
||
* - SSR (服务端): 直接调用 router,无 HTTP 开销
|
||
* - CSR (客户端): 通过 /api/rpc 端点 HTTP 调用
|
||
*
|
||
* 同时配置了 TanStack Query 集成,mutation 成功后自动刷新相关查询。
|
||
*/
|
||
import { createORPCClient } from '@orpc/client'
|
||
import { RPCLink } from '@orpc/client/fetch'
|
||
import { createRouterClient } from '@orpc/server'
|
||
import { createTanstackQueryUtils } from '@orpc/tanstack-query'
|
||
import { createIsomorphicFn } from '@tanstack/react-start'
|
||
import { getRequestHeaders } from '@tanstack/react-start/server'
|
||
import { router } from './router'
|
||
import type { RouterClient } from './types'
|
||
|
||
/**
|
||
* 创建同构 ORPC 客户端
|
||
*
|
||
* 服务端: 直接调用路由处理器
|
||
* 客户端: 通过 HTTP 调用 /api/rpc 端点
|
||
*/
|
||
const getORPCClient = createIsomorphicFn()
|
||
.server(() =>
|
||
createRouterClient(router, {
|
||
context: () => ({
|
||
headers: getRequestHeaders(),
|
||
}),
|
||
}),
|
||
)
|
||
.client(() => {
|
||
const link = new RPCLink({
|
||
url: `${window.location.origin}/api/rpc`,
|
||
})
|
||
return createORPCClient<RouterClient>(link)
|
||
})
|
||
|
||
const client: RouterClient = getORPCClient()
|
||
|
||
/**
|
||
* ORPC + TanStack Query 工具
|
||
*
|
||
* 使用方式:
|
||
* ```tsx
|
||
* // 查询
|
||
* const { data } = useSuspenseQuery(orpc.todo.list.queryOptions())
|
||
*
|
||
* // 变更
|
||
* const mutation = useMutation(orpc.todo.create.mutationOptions())
|
||
* mutation.mutate({ title: '新任务' })
|
||
* ```
|
||
*
|
||
* 配置了自动缓存失效: 创建/更新/删除操作后自动刷新列表
|
||
*/
|
||
export const orpc = createTanstackQueryUtils(client, {
|
||
// 配置 mutation 成功后自动刷新相关查询
|
||
experimental_defaults: {
|
||
todo: {
|
||
create: {
|
||
mutationOptions: {
|
||
onSuccess: (_, __, ___, ctx) => {
|
||
ctx.client.invalidateQueries({ queryKey: orpc.todo.list.key() })
|
||
},
|
||
},
|
||
},
|
||
update: {
|
||
mutationOptions: {
|
||
onSuccess: (_, __, ___, ctx) => {
|
||
ctx.client.invalidateQueries({ queryKey: orpc.todo.list.key() })
|
||
},
|
||
},
|
||
},
|
||
remove: {
|
||
mutationOptions: {
|
||
onSuccess: (_, __, ___, ctx) => {
|
||
ctx.client.invalidateQueries({ queryKey: orpc.todo.list.key() })
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
})
|