From 1724429fb04343d2f89dbd3adea377f4d9be2fe5 Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Mon, 2 Mar 2026 19:12:17 +0100 Subject: [PATCH] refactor: ensure server preloading --- .../repositories/routes/snapshot-details.tsx | 10 ++++- .../components/org-members-section.tsx | 6 +-- .../components/sso/sso-settings-section.tsx | 9 +++-- .../modules/settings/routes/settings.tsx | 7 ++-- .../(dashboard)/backups/$backupId/index.tsx | 2 + .../$repositoryId/$snapshotId/index.tsx | 27 ++++++++++--- .../repositories/$repositoryId/index.tsx | 7 ++-- app/routes/(dashboard)/route.tsx | 5 +++ app/routes/(dashboard)/settings/index.tsx | 38 +++++++++++++------ app/routes/__root.tsx | 2 + bun.lock | 21 ++++++---- package.json | 1 + 12 files changed, 95 insertions(+), 40 deletions(-) diff --git a/app/client/modules/repositories/routes/snapshot-details.tsx b/app/client/modules/repositories/routes/snapshot-details.tsx index 6674eae4..1d1d14c5 100644 --- a/app/client/modules/repositories/routes/snapshot-details.tsx +++ b/app/client/modules/repositories/routes/snapshot-details.tsx @@ -4,6 +4,7 @@ import { getSnapshotDetailsOptions, listBackupSchedulesOptions, } from "~/client/api-client/@tanstack/react-query.gen"; +import type { GetSnapshotDetailsResponse } from "~/client/api-client/types.gen"; import { Button } from "~/client/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "~/client/components/ui/card"; import { SnapshotFileBrowser } from "~/client/modules/backups/components/snapshot-file-browser"; @@ -49,7 +50,13 @@ const SnapshotFileBrowserSkeleton = () => ( ); -export function SnapshotDetailsPage({ repositoryId, snapshotId }: { repositoryId: string; snapshotId: string }) { +type Props = { + repositoryId: string; + snapshotId: string; + initialSnapshot?: GetSnapshotDetailsResponse; +}; + +export function SnapshotDetailsPage({ repositoryId, snapshotId, initialSnapshot }: Props) { const [showAllPaths, setShowAllPaths] = useState(false); const { data: repository } = useSuspenseQuery({ @@ -62,6 +69,7 @@ export function SnapshotDetailsPage({ repositoryId, snapshotId }: { repositoryId const { data, error } = useQuery({ ...getSnapshotDetailsOptions({ path: { shortId: repositoryId, snapshotId: snapshotId } }), + initialData: initialSnapshot, }); const backupSchedule = schedules?.find((s) => data?.tags?.includes(s.shortId)); diff --git a/app/client/modules/settings/components/org-members-section.tsx b/app/client/modules/settings/components/org-members-section.tsx index c9594762..8ae2112b 100644 --- a/app/client/modules/settings/components/org-members-section.tsx +++ b/app/client/modules/settings/components/org-members-section.tsx @@ -2,12 +2,12 @@ import { useMutation, useSuspenseQuery } from "@tanstack/react-query"; import { Shield, ShieldAlert, Trash2 } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; -import type { GetOrgMembersResponse } from "~/client/api-client"; import { getOrgMembersOptions, removeOrgMemberMutation, updateMemberRoleMutation, } from "~/client/api-client/@tanstack/react-query.gen"; +import type { GetOrgMembersResponse } from "~/client/api-client/types.gen"; import { AlertDialog, AlertDialogAction, @@ -25,11 +25,11 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "~ import { useOrganizationContext } from "~/client/hooks/use-org-context"; import { cn } from "~/client/lib/utils"; -type OrgMembersSectionProps = { +type Props = { initialMembers?: GetOrgMembersResponse; }; -export function OrgMembersSection({ initialMembers }: OrgMembersSectionProps) { +export function OrgMembersSection({ initialMembers }: Props) { const { activeMember } = useOrganizationContext(); const [memberToRemove, setMemberToRemove] = useState<{ id: string; name: string } | null>(null); diff --git a/app/client/modules/settings/components/sso/sso-settings-section.tsx b/app/client/modules/settings/components/sso/sso-settings-section.tsx index ec98d675..6b5adcad 100644 --- a/app/client/modules/settings/components/sso/sso-settings-section.tsx +++ b/app/client/modules/settings/components/sso/sso-settings-section.tsx @@ -9,6 +9,7 @@ import { getSsoSettingsOptions, updateSsoProviderAutoLinkingMutation, } from "~/client/api-client/@tanstack/react-query.gen"; +import type { GetSsoSettingsResponse } from "~/client/api-client/types.gen"; import { AlertDialog, AlertDialogAction, @@ -33,17 +34,17 @@ import { getOrigin } from "~/client/functions/get-origin"; import { authClient } from "~/client/lib/auth-client"; import { cn } from "~/client/lib/utils"; import { useServerFn } from "@tanstack/react-start"; -import type { GetSsoSettingsResponse } from "~/client/api-client"; type InvitationRole = "member" | "admin" | "owner"; -type SsoSettingsSectionProps = { +type Props = { initialSettings?: GetSsoSettingsResponse; + initialOrigin?: string; }; -export function SsoSettingsSection({ initialSettings }: SsoSettingsSectionProps) { +export function SsoSettingsSection({ initialSettings, initialOrigin }: Props) { const originQuery = useServerFn(getOrigin); - const { data } = useSuspenseQuery({ queryKey: ["app-origin"], queryFn: originQuery }); + const { data } = useSuspenseQuery({ queryKey: ["app-origin"], queryFn: originQuery, initialData: initialOrigin }); const navigate = useNavigate(); const { activeOrganization } = useOrganizationContext(); diff --git a/app/client/modules/settings/routes/settings.tsx b/app/client/modules/settings/routes/settings.tsx index 797b8281..3a304c8b 100644 --- a/app/client/modules/settings/routes/settings.tsx +++ b/app/client/modules/settings/routes/settings.tsx @@ -3,6 +3,7 @@ import { Download, KeyRound, User, X, Settings as SettingsIcon, Building2 } from import { useState } from "react"; import { toast } from "sonner"; import { downloadResticPasswordMutation } from "~/client/api-client/@tanstack/react-query.gen"; +import type { GetOrgMembersResponse, GetSsoSettingsResponse } from "~/client/api-client/types.gen"; import { Button } from "~/client/components/ui/button"; import { Card, CardContent, CardDescription, CardTitle } from "~/client/components/ui/card"; import { @@ -24,15 +25,15 @@ import { useNavigate, useSearch } from "@tanstack/react-router"; import { SsoSettingsSection } from "../components/sso/sso-settings-section"; import { OrgMembersSection } from "../components/org-members-section"; import { useOrganizationContext } from "~/client/hooks/use-org-context"; -import type { GetOrgMembersResponse, GetSsoSettingsResponse } from "~/client/api-client"; type Props = { appContext: AppContext; initialMembers?: GetOrgMembersResponse; initialSsoSettings?: GetSsoSettingsResponse; + initialOrigin?: string; }; -export function SettingsPage({ appContext, initialMembers, initialSsoSettings }: Props) { +export function SettingsPage({ appContext, initialMembers, initialSsoSettings, initialOrigin }: Props) { const [currentPassword, setCurrentPassword] = useState(""); const [newPassword, setNewPassword] = useState(""); const [confirmPassword, setConfirmPassword] = useState(""); @@ -312,7 +313,7 @@ export function SettingsPage({ appContext, initialMembers, initialSsoSettings }: Configure OIDC provider settings - + diff --git a/app/routes/(dashboard)/backups/$backupId/index.tsx b/app/routes/(dashboard)/backups/$backupId/index.tsx index 84f2a9ad..842a17de 100644 --- a/app/routes/(dashboard)/backups/$backupId/index.tsx +++ b/app/routes/(dashboard)/backups/$backupId/index.tsx @@ -1,6 +1,7 @@ import { createFileRoute } from "@tanstack/react-router"; import { type } from "arktype"; import { + getBackupProgressOptions, getBackupScheduleOptions, getScheduleMirrorsOptions, getScheduleNotificationsOptions, @@ -24,6 +25,7 @@ export const Route = createFileRoute("/(dashboard)/backups/$backupId/")({ context.queryClient.ensureQueryData({ ...listRepositoriesOptions() }), context.queryClient.ensureQueryData({ ...getScheduleNotificationsOptions({ path: { shortId: backupId } }) }), context.queryClient.ensureQueryData({ ...getScheduleMirrorsOptions({ path: { shortId: backupId } }) }), + context.queryClient.ensureQueryData({ ...getBackupProgressOptions({ path: { shortId: backupId } }) }), ]); const snapshotOptions = listSnapshotsOptions({ diff --git a/app/routes/(dashboard)/repositories/$repositoryId/$snapshotId/index.tsx b/app/routes/(dashboard)/repositories/$repositoryId/$snapshotId/index.tsx index 92c289aa..98cbc480 100644 --- a/app/routes/(dashboard)/repositories/$repositoryId/$snapshotId/index.tsx +++ b/app/routes/(dashboard)/repositories/$repositoryId/$snapshotId/index.tsx @@ -1,16 +1,30 @@ import { createFileRoute } from "@tanstack/react-router"; -import { getRepositoryOptions } from "~/client/api-client/@tanstack/react-query.gen"; +import { + getRepositoryOptions, + getSnapshotDetailsOptions, + listBackupSchedulesOptions, +} from "~/client/api-client/@tanstack/react-query.gen"; import { SnapshotDetailsPage } from "~/client/modules/repositories/routes/snapshot-details"; +import { prefetchOrSkip } from "~/utils/prefetch"; export const Route = createFileRoute("/(dashboard)/repositories/$repositoryId/$snapshotId/")({ component: RouteComponent, errorComponent: (e) =>
{e.error.message}
, loader: async ({ params, context }) => { - const res = await context.queryClient.ensureQueryData({ - ...getRepositoryOptions({ path: { shortId: params.repositoryId } }), - }); + const [res] = await Promise.all([ + context.queryClient.ensureQueryData({ ...getRepositoryOptions({ path: { shortId: params.repositoryId } }) }), + context.queryClient.ensureQueryData({ ...listBackupSchedulesOptions() }), + ]); - return res; + const snapshotOptions = getSnapshotDetailsOptions({ + path: { shortId: params.repositoryId, snapshotId: params.snapshotId }, + }); + await prefetchOrSkip(context.queryClient, snapshotOptions); + + return { + ...res, + snapshot: context.queryClient.getQueryData(snapshotOptions.queryKey), + }; }, staticData: { breadcrumb: (match) => [ @@ -32,6 +46,7 @@ export const Route = createFileRoute("/(dashboard)/repositories/$repositoryId/$s function RouteComponent() { const { repositoryId, snapshotId } = Route.useParams(); + const { snapshot } = Route.useLoaderData(); - return ; + return ; } diff --git a/app/routes/(dashboard)/repositories/$repositoryId/index.tsx b/app/routes/(dashboard)/repositories/$repositoryId/index.tsx index 86c5c125..0e7158f6 100644 --- a/app/routes/(dashboard)/repositories/$repositoryId/index.tsx +++ b/app/routes/(dashboard)/repositories/$repositoryId/index.tsx @@ -14,20 +14,19 @@ export const Route = createFileRoute("/(dashboard)/repositories/$repositoryId/") errorComponent: (e) =>
{e.error.message}
, loader: async ({ params, context }) => { const snapshotOptions = listSnapshotsOptions({ path: { shortId: params.repositoryId } }); - const schedulesOptions = listBackupSchedulesOptions(); const statsOptions = getRepositoryStatsOptions({ path: { shortId: params.repositoryId } }); - const [res] = await Promise.all([ + const [res, schedules] = await Promise.all([ context.queryClient.ensureQueryData(getRepositoryOptions({ path: { shortId: params.repositoryId } })), + context.queryClient.ensureQueryData(listBackupSchedulesOptions()), prefetchOrSkip(context.queryClient, snapshotOptions), - prefetchOrSkip(context.queryClient, schedulesOptions), prefetchOrSkip(context.queryClient, statsOptions), ]); return { ...res, snapshots: context.queryClient.getQueryData(snapshotOptions.queryKey), - backupSchedules: context.queryClient.getQueryData(schedulesOptions.queryKey), + backupSchedules: schedules, stats: context.queryClient.getQueryData(statsOptions.queryKey), }; }, diff --git a/app/routes/(dashboard)/route.tsx b/app/routes/(dashboard)/route.tsx index 1b4e9ab4..0c26a03c 100644 --- a/app/routes/(dashboard)/route.tsx +++ b/app/routes/(dashboard)/route.tsx @@ -6,6 +6,7 @@ import { SIDEBAR_COOKIE_NAME } from "~/client/components/ui/sidebar"; import { authMiddleware } from "~/middleware/auth"; import { auth } from "~/server/lib/auth"; import { getOrganizationContext } from "~/server/lib/functions/organization-context"; +import { getServerConstants } from "~/server/lib/functions/server-constants"; import { authService } from "~/server/modules/auth/auth.service"; export const fetchUser = createServerFn({ method: "GET" }).handler(async () => { @@ -32,6 +33,10 @@ export const Route = createFileRoute("/(dashboard)")({ queryKey: ["organization-context"], queryFn: () => getOrganizationContext(), }), + context.queryClient.ensureQueryData({ + queryKey: ["server-constants"], + queryFn: () => getServerConstants(), + }), ]); return authContext; diff --git a/app/routes/(dashboard)/settings/index.tsx b/app/routes/(dashboard)/settings/index.tsx index f3adff3c..f7816c2e 100644 --- a/app/routes/(dashboard)/settings/index.tsx +++ b/app/routes/(dashboard)/settings/index.tsx @@ -12,23 +12,32 @@ export const Route = createFileRoute("/(dashboard)/settings/")({ validateSearch: type({ tab: "string?" }), errorComponent: () =>
Failed to load settings
, loader: async ({ context }) => { - const authContext = await fetchUser(); - const orgContext = await getOrganizationContext(); + const [authContext, orgContext] = await Promise.all([ + fetchUser(), + context.queryClient.ensureQueryData({ + queryKey: ["organization-context"], + queryFn: () => getOrganizationContext(), + }), + ]); const orgRole = orgContext.activeMember?.role; + const shouldPrefetchOrgQueries = authContext.user?.role === "admin" || orgRole === "owner" || orgRole === "admin"; - let org, members; - - if (authContext.user?.role === "admin" || orgRole === "owner" || orgRole === "admin") { - const promises = await Promise.all([ + if (shouldPrefetchOrgQueries) { + const [org, members, appOrigin] = await Promise.all([ context.queryClient.ensureQueryData({ ...getSsoSettingsOptions() }), context.queryClient.ensureQueryData({ ...getOrgMembersOptions() }), context.queryClient.ensureQueryData({ queryKey: ["app-origin"], queryFn: () => getOrigin() }), ]); - org = promises[0]; - members = promises[1]; + + return { + authContext: authContext as AppContext, + org, + members, + appOrigin, + }; } - return { authContext: authContext as AppContext, org, members }; + return { authContext: authContext as AppContext }; }, staticData: { breadcrumb: () => [{ label: "Settings" }], @@ -36,7 +45,14 @@ export const Route = createFileRoute("/(dashboard)/settings/")({ }); function RouteComponent() { - const { authContext, org, members } = Route.useLoaderData(); + const { authContext, members, org, appOrigin } = Route.useLoaderData(); - return ; + return ( + + ); } diff --git a/app/routes/__root.tsx b/app/routes/__root.tsx index 2f001b50..7b56550b 100644 --- a/app/routes/__root.tsx +++ b/app/routes/__root.tsx @@ -2,6 +2,7 @@ import { Outlet, HeadContent, Scripts, createRootRouteWithContext } from "@tanst import appCss from "../app.css?url"; import { apiClientMiddleware } from "~/middleware/api-client"; import type { QueryClient } from "@tanstack/react-query"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; import { Toaster } from "~/client/components/ui/sonner"; import { useServerEvents } from "~/client/hooks/use-server-events"; import { useEffect } from "react"; @@ -58,6 +59,7 @@ function RootLayout() { + diff --git a/bun.lock b/bun.lock index c64d8d45..40f66153 100644 --- a/bun.lock +++ b/bun.lock @@ -30,6 +30,7 @@ "@scalar/hono-api-reference": "^0.9.45", "@tanstack/react-hotkeys": "^0.3.0", "@tanstack/react-query": "^5.90.21", + "@tanstack/react-query-devtools": "^5.91.3", "@tanstack/react-router": "^1.162.9", "@tanstack/react-router-ssr-query": "^1.162.9", "@tanstack/react-start": "^1.162.9", @@ -822,10 +823,14 @@ "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="], + "@tanstack/query-devtools": ["@tanstack/query-devtools@5.93.0", "", {}, "sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg=="], + "@tanstack/react-hotkeys": ["@tanstack/react-hotkeys@0.3.0", "", { "dependencies": { "@tanstack/hotkeys": "0.3.0", "@tanstack/react-store": "^0.9.1" }, "peerDependencies": { "react": ">=16.8", "react-dom": ">=16.8" } }, "sha512-DkSu+8lDwUGzZLk1WVgT6XtfxTa7mFWOGmiDYK+2pe7GqbnuQgUIQPRdo82yCuHYzNoEJgjoYo/HJ8frD4mmcA=="], "@tanstack/react-query": ["@tanstack/react-query@5.90.21", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg=="], + "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.3", "", { "dependencies": { "@tanstack/query-devtools": "5.93.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.20", "react": "^18 || ^19" } }, "sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA=="], + "@tanstack/react-router": ["@tanstack/react-router@1.162.9", "", { "dependencies": { "@tanstack/history": "1.161.4", "@tanstack/react-store": "^0.9.1", "@tanstack/router-core": "1.162.9", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-APbwKAF+YgSNpHAaA+FdgrmfI/7+qa9hApuVO9+P0IVksJayNIWFQ/6AFG90WQiTYWk64RI1R9cFV2K9Z+j2pQ=="], "@tanstack/react-router-ssr-query": ["@tanstack/react-router-ssr-query@1.162.9", "", { "dependencies": { "@tanstack/router-ssr-query-core": "1.162.9" }, "peerDependencies": { "@tanstack/query-core": ">=5.90.0", "@tanstack/react-query": ">=5.90.0", "@tanstack/react-router": ">=1.127.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-1j9BfYoS02Xjml3s0EkTnhuloINnI41rQI/oQPaV9ctiL/vjDOCX3JjsNox+JpFMoa446TMPTce3NoAgPE62cQ=="], @@ -1782,7 +1787,7 @@ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], - "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + "tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], @@ -1856,7 +1861,7 @@ "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], - "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], + "webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], "webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="], @@ -1864,7 +1869,7 @@ "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], - "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], + "whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], @@ -1982,8 +1987,6 @@ "libsql/detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="], - "mongodb-connection-string-url/whatwg-url": ["whatwg-url@14.2.0", "", { "dependencies": { "tr46": "^5.1.0", "webidl-conversions": "^7.0.0" } }, "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw=="], - "mssql/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="], "mssql/tedious": ["tedious@18.6.2", "", { "dependencies": { "@azure/core-auth": "^1.7.2", "@azure/identity": "^4.2.1", "@azure/keyvault-keys": "^4.4.0", "@js-joda/core": "^5.6.1", "@types/node": ">=18", "bl": "^6.0.11", "iconv-lite": "^0.6.3", "js-md4": "^0.3.2", "native-duplexpair": "^1.0.0", "sprintf-js": "^1.1.3" } }, "sha512-g7jC56o3MzLkE3lHkaFe2ZdOVFBahq5bsB60/M4NYUbocw/MCrS89IOEQUFr+ba6pb8ZHczZ/VqCyYeYq0xBAg=="], @@ -2014,14 +2017,16 @@ "@tanstack/router-plugin/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], - "mongodb-connection-string-url/whatwg-url/tr46": ["tr46@5.1.1", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw=="], - - "mongodb-connection-string-url/whatwg-url/webidl-conversions": ["webidl-conversions@7.0.0", "", {}, "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="], + "cross-fetch/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], "mssql/tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "@prisma/config/c12/chokidar/readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "@tanstack/router-plugin/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "cross-fetch/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], + + "cross-fetch/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], } } diff --git a/package.json b/package.json index 3f57ab16..6a28da95 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "@scalar/hono-api-reference": "^0.9.45", "@tanstack/react-hotkeys": "^0.3.0", "@tanstack/react-query": "^5.90.21", + "@tanstack/react-query-devtools": "^5.91.3", "@tanstack/react-router": "^1.162.9", "@tanstack/react-router-ssr-query": "^1.162.9", "@tanstack/react-start": "^1.162.9",