begin migration to trpc/react-query integration
This commit is contained in:
+193
-136
@@ -22,165 +22,222 @@ import { useDisclosure } from "@mantine/hooks";
|
||||
import theme from "./theme.js";
|
||||
import logoUrl from "../assets/logo.svg";
|
||||
import { useStore } from "../state.js";
|
||||
import { useEffect } from "react";
|
||||
import { trpc } from "../trpc/client.js";
|
||||
import { useEffect, useState } from "react";
|
||||
import { TRPCProvider, useTRPC } from "../trpc/client.js";
|
||||
import { usePageContext } from "vike-react/usePageContext";
|
||||
import "./hover.css";
|
||||
import {
|
||||
QueryClient,
|
||||
QueryClientProvider,
|
||||
useMutation,
|
||||
useQuery,
|
||||
} from "@tanstack/react-query";
|
||||
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
||||
import type { AppRouter } from "../trpc/router.js";
|
||||
|
||||
function makeQueryClient() {
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
// With SSR, we usually want to set some default staleTime
|
||||
// above 0 to avoid refetching immediately on the client
|
||||
staleTime: 60 * 1000,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let browserQueryClient: QueryClient | undefined = undefined;
|
||||
function getQueryClient() {
|
||||
if (typeof window === "undefined") {
|
||||
// Server: always make a new query client
|
||||
return makeQueryClient();
|
||||
}
|
||||
// Browser: make a new query client if we don't already have one
|
||||
// This is very important, so we don't re-make a new client if React
|
||||
// suspends during the initial render. This may not be needed if we
|
||||
// have a suspense boundary BELOW the creation of the query client
|
||||
if (!browserQueryClient) browserQueryClient = makeQueryClient();
|
||||
return browserQueryClient;
|
||||
}
|
||||
|
||||
export default function LayoutDefault({
|
||||
children,
|
||||
}: { children: React.ReactNode }) {
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const pageContext = usePageContext();
|
||||
const { urlPathname } = pageContext;
|
||||
const [opened, { toggle }] = useDisclosure();
|
||||
const conversations = useStore((state) => state.conversations);
|
||||
const setConversations = useStore((state) => state.setConversations);
|
||||
|
||||
const queryClient = getQueryClient();
|
||||
const [trpc] = useState(() =>
|
||||
createTRPCClient<AppRouter>({
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: "/api/trpc",
|
||||
methodOverride: "POST",
|
||||
}),
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<TRPCProvider trpcClient={trpc} queryClient={queryClient}>
|
||||
<MantineProvider theme={theme}>
|
||||
<AppShell
|
||||
header={{ height: 60 }}
|
||||
navbar={{
|
||||
width: 300,
|
||||
breakpoint: "sm",
|
||||
collapsed: { mobile: !opened },
|
||||
}}
|
||||
padding="lg"
|
||||
>
|
||||
<AppShell.Header>
|
||||
<Group h="100%" px="md">
|
||||
<Burger
|
||||
opened={opened}
|
||||
onClick={toggle}
|
||||
hiddenFrom="sm"
|
||||
size="sm"
|
||||
/>
|
||||
<a href="/">
|
||||
{" "}
|
||||
<Image h={50} fit="contain" src={logoUrl} />{" "}
|
||||
</a>
|
||||
</Group>
|
||||
</AppShell.Header>
|
||||
<AppShell.Navbar p="md">
|
||||
<NavLink href="/" label="Welcome" active={urlPathname === "/"} />
|
||||
<NavLink
|
||||
href="/todo"
|
||||
label="Todo"
|
||||
active={urlPathname === "/todo"}
|
||||
/>
|
||||
<NavLink
|
||||
href="/star-wars"
|
||||
label="Data Fetching"
|
||||
active={urlPathname.startsWith("/star-wars")}
|
||||
/>
|
||||
<NavLinkChat key="chat-new" />
|
||||
</AppShell.Navbar>
|
||||
<AppShell.Main> {children} </AppShell.Main>
|
||||
</AppShell>
|
||||
</MantineProvider>
|
||||
</TRPCProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
function NavLinkChat() {
|
||||
const pageContext = usePageContext();
|
||||
const { urlPathname } = pageContext;
|
||||
const trpc = useTRPC();
|
||||
// const
|
||||
const startConversation = useMutation(
|
||||
trpc.chat.conversations.start.mutationOptions()
|
||||
);
|
||||
const deleteConversation = useMutation(
|
||||
trpc.chat.conversations.deleteOne.mutationOptions()
|
||||
);
|
||||
const { data: conversations } = useQuery(
|
||||
trpc.chat.conversations.fetchAll.queryOptions()
|
||||
);
|
||||
// TODO: should we be using zustand for this, or trpc/react-query's useMutation?
|
||||
const addConversation = useStore((state) => state.addConversation);
|
||||
const removeConversation = useStore((state) => state.removeConversation);
|
||||
const conversationId = useStore((state) => state.selectedConversationId);
|
||||
|
||||
useEffect(() => {
|
||||
trpc.chat.conversations.fetchAll.query().then((res) => {
|
||||
setConversations(res);
|
||||
});
|
||||
}, [setConversations]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (isConversationListExpanded) {
|
||||
// trpc.chat.listConversations.query().then((res) => {
|
||||
// setConversations(res);
|
||||
// });
|
||||
// }
|
||||
// }, [isConversationListExpanded]);
|
||||
|
||||
async function handleDeleteConversation(conversationId: string) {
|
||||
removeConversation(conversationId);
|
||||
await trpc.chat.conversations.deleteOne.mutate({ id: conversationId });
|
||||
const res = await trpc.chat.conversations.start.mutate();
|
||||
await deleteConversation.mutateAsync({ id: conversationId });
|
||||
const res = await startConversation.mutateAsync();
|
||||
if (!res?.id) return;
|
||||
addConversation(res);
|
||||
await navigate(`/chat/${res.id}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<MantineProvider theme={theme}>
|
||||
<AppShell
|
||||
header={{ height: 60 }}
|
||||
navbar={{
|
||||
width: 300,
|
||||
breakpoint: "sm",
|
||||
collapsed: { mobile: !opened },
|
||||
}}
|
||||
padding="lg"
|
||||
>
|
||||
<AppShell.Header>
|
||||
<Group h="100%" px="md">
|
||||
<Burger
|
||||
opened={opened}
|
||||
onClick={toggle}
|
||||
hiddenFrom="sm"
|
||||
size="sm"
|
||||
/>
|
||||
<a href="/">
|
||||
{" "}
|
||||
<Image h={50} fit="contain" src={logoUrl} />{" "}
|
||||
</a>
|
||||
</Group>
|
||||
</AppShell.Header>
|
||||
<AppShell.Navbar p="md">
|
||||
<NavLink href="/" label="Welcome" active={urlPathname === "/"} />
|
||||
<NavLink href="/todo" label="Todo" active={urlPathname === "/todo"} />
|
||||
<NavLink
|
||||
href="/star-wars"
|
||||
label="Data Fetching"
|
||||
active={urlPathname.startsWith("/star-wars")}
|
||||
<NavLink
|
||||
key="chat-new"
|
||||
href="#required-for-focus-management"
|
||||
label={
|
||||
<Group justify="space-between">
|
||||
<span>Chats</span>
|
||||
<IconPlus
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
className="border-on-hover"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
startConversation.mutateAsync().then((res) => {
|
||||
if (!res?.id) return;
|
||||
addConversation(res);
|
||||
navigate(`/chat/${res.id}`);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<NavLink
|
||||
key="chat-new"
|
||||
href="#required-for-focus-management"
|
||||
label={
|
||||
<Group justify="space-between">
|
||||
<span>Chats</span>
|
||||
<IconPlus
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
className="border-on-hover"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
trpc.chat.conversations.start.mutate().then((res) => {
|
||||
if (!res?.id) return;
|
||||
addConversation(res);
|
||||
navigate(`/chat/${res.id}`);
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Group>
|
||||
}
|
||||
leftSection={<IconActivity size={16} stroke={1.5} />}
|
||||
rightSection={
|
||||
<IconChevronRight
|
||||
size={12}
|
||||
</Group>
|
||||
}
|
||||
leftSection={<IconActivity size={16} stroke={1.5} />}
|
||||
rightSection={
|
||||
<IconChevronRight
|
||||
size={12}
|
||||
stroke={1.5}
|
||||
className="mantine-rotate-rtl"
|
||||
/>
|
||||
}
|
||||
variant="subtle"
|
||||
active={urlPathname.startsWith("/chat")}
|
||||
defaultOpened={true}
|
||||
>
|
||||
{conversations?.map((conversation) => (
|
||||
<NavLink
|
||||
key={conversation.id}
|
||||
href={`/chat/${conversation.id}`}
|
||||
label={conversation.title}
|
||||
className="hover-container"
|
||||
leftSection={
|
||||
<>
|
||||
<IconCircle size={16} stroke={1.5} className="show-by-default" />
|
||||
<IconCircleFilled
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
className="mantine-rotate-rtl"
|
||||
className="show-on-hover"
|
||||
/>
|
||||
}
|
||||
variant="subtle"
|
||||
active={urlPathname.startsWith("/chat")}
|
||||
defaultOpened={true}
|
||||
>
|
||||
{conversations.map((conversation) => (
|
||||
<NavLink
|
||||
key={conversation.id}
|
||||
href={`/chat/${conversation.id}`}
|
||||
label={conversation.title}
|
||||
className="hover-container"
|
||||
leftSection={
|
||||
<>
|
||||
<IconCircle
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
className="show-by-default"
|
||||
/>
|
||||
<IconCircleFilled
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
className="show-on-hover"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
rightSection={
|
||||
<>
|
||||
<IconTrash
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
handleDeleteConversation(conversation.id);
|
||||
}}
|
||||
className="show-by-default"
|
||||
/>
|
||||
<IconTrashFilled
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
handleDeleteConversation(conversation.id);
|
||||
}}
|
||||
className="show-on-hover border-on-hover"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
variant="subtle"
|
||||
active={conversation.id === conversationId}
|
||||
</>
|
||||
}
|
||||
rightSection={
|
||||
<>
|
||||
<IconTrash
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
handleDeleteConversation(conversation.id);
|
||||
}}
|
||||
className="show-by-default"
|
||||
/>
|
||||
))}
|
||||
</NavLink>
|
||||
</AppShell.Navbar>
|
||||
<AppShell.Main> {children} </AppShell.Main>
|
||||
</AppShell>
|
||||
</MantineProvider>
|
||||
<IconTrashFilled
|
||||
size={16}
|
||||
stroke={1.5}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
handleDeleteConversation(conversation.id);
|
||||
}}
|
||||
className="show-on-hover border-on-hover"
|
||||
/>
|
||||
</>
|
||||
}
|
||||
variant="subtle"
|
||||
active={conversation.id === conversationId}
|
||||
/>
|
||||
))}
|
||||
</NavLink>
|
||||
);
|
||||
}
|
||||
|
||||
+4
-2
@@ -20,8 +20,10 @@
|
||||
"@openrouter/ai-sdk-provider": "^1.1.2",
|
||||
"@sinclair/typebox": "^0.34.37",
|
||||
"@tabler/icons-react": "^3.34.1",
|
||||
"@trpc/client": "^11.4.2",
|
||||
"@trpc/server": "^11.4.2",
|
||||
"@tanstack/react-query": "^5.85.3",
|
||||
"@trpc/client": "^11.4.4",
|
||||
"@trpc/server": "^11.4.4",
|
||||
"@trpc/tanstack-react-query": "^11.4.4",
|
||||
"@universal-middleware/core": "^0.4.8",
|
||||
"@universal-middleware/hono": "^0.4.14",
|
||||
"@vitejs/plugin-react": "^4.6.0",
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Card, Textarea } from "@mantine/core";
|
||||
import { useState } from "react";
|
||||
import { useTRPC } from "../../trpc/client";
|
||||
|
||||
export default function ChatPage() {
|
||||
const [inputMessage, setInputMessage] = useState("");
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [outputMessage, setOutputMessage] = useState("");
|
||||
const trpc = useTRPC();
|
||||
|
||||
async function handleSendMessage() {
|
||||
setLoading(true);
|
||||
const response = await trpc.chat.streamMessage.subscribe(
|
||||
{
|
||||
message: inputMessage,
|
||||
},
|
||||
{}
|
||||
);
|
||||
for await (const chunk of response) {
|
||||
setOutputMessage(chunk);
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<Card>{outputMessage}</Card>
|
||||
<Textarea
|
||||
resize="vertical"
|
||||
placeholder="Type your message here..."
|
||||
value={inputMessage}
|
||||
disabled={loading}
|
||||
onChange={(e) => setInputMessage(e.target.value)}
|
||||
onKeyDown={async (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+12
-12
@@ -10,7 +10,6 @@ import {
|
||||
Textarea,
|
||||
useMantineTheme,
|
||||
} from "@mantine/core";
|
||||
import { trpc } from "../../../trpc/client";
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
defaultParameters,
|
||||
@@ -23,13 +22,20 @@ import type { Data } from "./+data";
|
||||
import type { CommittedMessage, DraftMessage } from "../../../types";
|
||||
import Markdown from "react-markdown";
|
||||
import { IconTrash, IconEdit, IconCheck, IconX } from "@tabler/icons-react";
|
||||
import { useTRPCClient } from "../../../trpc/client";
|
||||
|
||||
export default function ChatPage() {
|
||||
const pageContext = usePageContext();
|
||||
const conversationId = pageContext.routeParams.id;
|
||||
const conversationTitle = useStore(
|
||||
(state) => state.conversations.find((c) => c.id === conversationId)?.title
|
||||
);
|
||||
|
||||
const {
|
||||
conversation,
|
||||
messages: initialMessages,
|
||||
facts: initialFacts,
|
||||
factTriggers: initialFactTriggers,
|
||||
} = useData<Data>();
|
||||
const conversationTitle = conversation?.title;
|
||||
|
||||
const messages = useStore((state) => state.messages);
|
||||
const message = useStore((state) => state.message);
|
||||
const systemPrompt = useStore((state) => state.systemPrompt);
|
||||
@@ -48,6 +54,7 @@ export default function ChatPage() {
|
||||
const removeFact = useStore((state) => state.removeFact);
|
||||
const removeFactTrigger = useStore((state) => state.removeFactTrigger);
|
||||
const setLoading = useStore((state) => state.setLoading);
|
||||
const trpc = useTRPCClient();
|
||||
|
||||
// State for editing facts
|
||||
const [editingFactId, setEditingFactId] = useState<string | null>(null);
|
||||
@@ -84,13 +91,6 @@ export default function ChatPage() {
|
||||
};
|
||||
}, [editingFactId, editingFactTriggerId]);
|
||||
|
||||
const {
|
||||
conversation,
|
||||
messages: initialMessages,
|
||||
facts: initialFacts,
|
||||
factTriggers: initialFactTriggers,
|
||||
} = useData<Data>();
|
||||
|
||||
useEffect(() => {
|
||||
setConversationId(conversationId);
|
||||
}, [conversationId, setConversationId]);
|
||||
@@ -162,7 +162,7 @@ export default function ChatPage() {
|
||||
<span>Conversation #{conversationId} - </span>
|
||||
<input
|
||||
type="text"
|
||||
value={conversationTitle || ""}
|
||||
defaultValue={conversationTitle || ""}
|
||||
onChange={(e) => {
|
||||
setConversationTitle(e.target.value);
|
||||
}}
|
||||
|
||||
+18
-1
@@ -3,7 +3,7 @@ import {
|
||||
publicProcedure,
|
||||
createCallerFactory,
|
||||
} from "../../trpc/server.js";
|
||||
import { generateObject, generateText, jsonSchema } from "ai";
|
||||
import { generateObject, generateText, jsonSchema, streamText } from "ai";
|
||||
import type {
|
||||
OtherParameters,
|
||||
CommittedMessage,
|
||||
@@ -47,6 +47,23 @@ export const chat = router({
|
||||
messages,
|
||||
facts,
|
||||
factTriggers,
|
||||
streamMessage: publicProcedure
|
||||
.input(
|
||||
(x) =>
|
||||
x as {
|
||||
message: string;
|
||||
}
|
||||
)
|
||||
.subscription(async function* ({ input, signal }) {
|
||||
const result = streamText({
|
||||
model: openrouter(MODEL_NAME),
|
||||
messages: [{ role: "user" as const, content: input.message }],
|
||||
abortSignal: signal,
|
||||
});
|
||||
for await (const chunk of result.textStream) {
|
||||
yield chunk;
|
||||
}
|
||||
}),
|
||||
sendMessage: publicProcedure
|
||||
.input(
|
||||
(x) =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { trpc } from "../../trpc/client";
|
||||
import { useState } from "react";
|
||||
import { useTRPCClient } from "../../trpc/client";
|
||||
|
||||
export function TodoList({
|
||||
initialTodoItems,
|
||||
@@ -8,6 +8,8 @@ export function TodoList({
|
||||
}) {
|
||||
const [todoItems, setTodoItems] = useState(initialTodoItems);
|
||||
const [newTodo, setNewTodo] = useState("");
|
||||
const trpc = useTRPCClient();
|
||||
|
||||
return (
|
||||
<>
|
||||
<ul>
|
||||
|
||||
Generated
+52
-12
@@ -35,12 +35,18 @@ importers:
|
||||
'@tabler/icons-react':
|
||||
specifier: ^3.34.1
|
||||
version: 3.34.1(react@19.1.0)
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.85.3
|
||||
version: 5.85.3(react@19.1.0)
|
||||
'@trpc/client':
|
||||
specifier: ^11.4.2
|
||||
version: 11.4.2(@trpc/server@11.4.2(typescript@5.8.3))(typescript@5.8.3)
|
||||
specifier: ^11.4.4
|
||||
version: 11.4.4(@trpc/server@11.4.4(typescript@5.8.3))(typescript@5.8.3)
|
||||
'@trpc/server':
|
||||
specifier: ^11.4.2
|
||||
version: 11.4.2(typescript@5.8.3)
|
||||
specifier: ^11.4.4
|
||||
version: 11.4.4(typescript@5.8.3)
|
||||
'@trpc/tanstack-react-query':
|
||||
specifier: ^11.4.4
|
||||
version: 11.4.4(@tanstack/react-query@5.85.3(react@19.1.0))(@trpc/client@11.4.4(@trpc/server@11.4.4(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.4.4(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)
|
||||
'@universal-middleware/core':
|
||||
specifier: ^0.4.8
|
||||
version: 0.4.8(@cloudflare/workers-types@4.20250627.0)(@hattip/core@0.0.49)(hono@4.8.3)
|
||||
@@ -1150,17 +1156,35 @@ packages:
|
||||
'@tabler/icons@3.34.1':
|
||||
resolution: {integrity: sha512-9gTnUvd7Fd/DmQgr3MKY+oJLa1RfNsQo8c/ir3TJAWghOuZXodbtbVp0QBY2DxWuuvrSZFys0HEbv1CoiI5y6A==}
|
||||
|
||||
'@trpc/client@11.4.2':
|
||||
resolution: {integrity: sha512-Eep1rorAsATs9bxgaXf+BV34CRs4lAKQmwumUL4CNdNDkJItyfuWUr3xWx0np1w3EzUDVA0YDMK93iKDBBA0KQ==}
|
||||
'@tanstack/query-core@5.85.3':
|
||||
resolution: {integrity: sha512-9Ne4USX83nHmRuEYs78LW+3lFEEO2hBDHu7mrdIgAFx5Zcrs7ker3n/i8p4kf6OgKExmaDN5oR0efRD7i2J0DQ==}
|
||||
|
||||
'@tanstack/react-query@5.85.3':
|
||||
resolution: {integrity: sha512-AqU8TvNh5GVIE8I+TUU0noryBRy7gOY0XhSayVXmOPll4UkZeLWKDwi0rtWOZbwLRCbyxorfJ5DIjDqE7GXpcQ==}
|
||||
peerDependencies:
|
||||
'@trpc/server': 11.4.2
|
||||
react: ^18 || ^19
|
||||
|
||||
'@trpc/client@11.4.4':
|
||||
resolution: {integrity: sha512-86OZl+Y+Xlt9ITGlhCMImERcsWCOrVzpNuzg3XBlsDSmSs9NGsghKjeCpJQlE36XaG3aze+o9pRukiYYvBqxgQ==}
|
||||
peerDependencies:
|
||||
'@trpc/server': 11.4.4
|
||||
typescript: '>=5.7.2'
|
||||
|
||||
'@trpc/server@11.4.2':
|
||||
resolution: {integrity: sha512-THyq/V5bSFDHeWEAk6LqHF0IVTGk6voGwWsFEipzRRKOWWMIZINCsKZ4cISG6kWO2X9jBfMWv/S2o9hnC0zQ0w==}
|
||||
'@trpc/server@11.4.4':
|
||||
resolution: {integrity: sha512-VkJb2xnb4rCynuwlCvgPBh5aM+Dco6fBBIo6lWAdJJRYVwtyE5bxNZBgUvRRz/cFSEAy0vmzLxF7aABDJfK5Rg==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.7.2'
|
||||
|
||||
'@trpc/tanstack-react-query@11.4.4':
|
||||
resolution: {integrity: sha512-Rf7jhPfwAHqmQdQlxTiMolNRon85bPEsBNa5JGpjSvhrTmiaFu5UEhEwHDF2myL7IRYxuYHLc4H0bQ+19qjdHQ==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^5.80.3
|
||||
'@trpc/client': 11.4.4
|
||||
'@trpc/server': 11.4.4
|
||||
react: '>=18.2.0'
|
||||
react-dom: '>=18.2.0'
|
||||
typescript: '>=5.7.2'
|
||||
|
||||
'@trysound/sax@0.2.0':
|
||||
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
@@ -3895,15 +3919,31 @@ snapshots:
|
||||
|
||||
'@tabler/icons@3.34.1': {}
|
||||
|
||||
'@trpc/client@11.4.2(@trpc/server@11.4.2(typescript@5.8.3))(typescript@5.8.3)':
|
||||
'@tanstack/query-core@5.85.3': {}
|
||||
|
||||
'@tanstack/react-query@5.85.3(react@19.1.0)':
|
||||
dependencies:
|
||||
'@trpc/server': 11.4.2(typescript@5.8.3)
|
||||
'@tanstack/query-core': 5.85.3
|
||||
react: 19.1.0
|
||||
|
||||
'@trpc/client@11.4.4(@trpc/server@11.4.4(typescript@5.8.3))(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@trpc/server': 11.4.4(typescript@5.8.3)
|
||||
typescript: 5.8.3
|
||||
|
||||
'@trpc/server@11.4.2(typescript@5.8.3)':
|
||||
'@trpc/server@11.4.4(typescript@5.8.3)':
|
||||
dependencies:
|
||||
typescript: 5.8.3
|
||||
|
||||
'@trpc/tanstack-react-query@11.4.4(@tanstack/react-query@5.85.3(react@19.1.0))(@trpc/client@11.4.4(@trpc/server@11.4.4(typescript@5.8.3))(typescript@5.8.3))(@trpc/server@11.4.4(typescript@5.8.3))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@tanstack/react-query': 5.85.3(react@19.1.0)
|
||||
'@trpc/client': 11.4.4(@trpc/server@11.4.4(typescript@5.8.3))(typescript@5.8.3)
|
||||
'@trpc/server': 11.4.4(typescript@5.8.3)
|
||||
react: 19.1.0
|
||||
react-dom: 19.1.0(react@19.1.0)
|
||||
typescript: 5.8.3
|
||||
|
||||
'@trysound/sax@0.2.0': {}
|
||||
|
||||
'@types/babel__core@7.20.5':
|
||||
|
||||
+13
-9
@@ -1,11 +1,15 @@
|
||||
import { createTRPCProxyClient, httpBatchLink } from "@trpc/client";
|
||||
// import { createTRPCProxyClient, httpBatchLink } from "@trpc/client";
|
||||
import { createTRPCContext } from "@trpc/tanstack-react-query";
|
||||
import type { AppRouter } from "./router.js";
|
||||
|
||||
export const trpc = createTRPCProxyClient<AppRouter>({
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: "/api/trpc",
|
||||
methodOverride: "POST",
|
||||
}),
|
||||
],
|
||||
});
|
||||
export const { TRPCProvider, useTRPC, useTRPCClient } =
|
||||
createTRPCContext<AppRouter>();
|
||||
|
||||
// export const trpc = createTRPCProxyClient<AppRouter>({
|
||||
// links: [
|
||||
// httpBatchLink({
|
||||
// url: "/api/trpc",
|
||||
// methodOverride: "POST",
|
||||
// }),
|
||||
// ],
|
||||
// });
|
||||
|
||||
+12
-1
@@ -6,7 +6,18 @@ import { initTRPC, TRPCError } from "@trpc/server";
|
||||
* Initialization of tRPC backend
|
||||
* Should be done only once per backend!
|
||||
*/
|
||||
const t = initTRPC.context<object>().create();
|
||||
const t = initTRPC.context<object>().create(/*{
|
||||
sse: {
|
||||
maxDurationMs: 5 * 60 * 1_000, // 5 minutes
|
||||
ping: {
|
||||
enabled: true,
|
||||
intervalMs: 3_000,
|
||||
},
|
||||
client: {
|
||||
reconnectAfterInactivityMs: 5_000,
|
||||
},
|
||||
},
|
||||
}*/);
|
||||
|
||||
/**
|
||||
* Export reusable router and procedure helpers
|
||||
|
||||
Reference in New Issue
Block a user