diff --git a/package-lock.json b/package-lock.json
index 9de81f7..834db50 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,7 +29,7 @@
"@fontsource/roboto": "^5.1.1",
"@mui/icons-material": "^7.2.0",
"@mui/material": "^7.2.0",
- "@tanstack/react-query": "^4.0.0",
+ "@tanstack/react-query": "^5.0.0",
"@ts-rest/react-query": "^3.51.0",
"@types/cors": "^2.8.17",
"@types/express": "^4.0.0",
@@ -1793,9 +1793,9 @@
}
},
"node_modules/@tanstack/query-core": {
- "version": "4.40.0",
- "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.40.0.tgz",
- "integrity": "sha512-7MJTtZkCSuehMC7IxMOCGsLvHS3jHx4WjveSrGsG1Nc1UQLjaFwwkpLA2LmPfvOAxnH4mszMOBFD6LlZE+aB+Q==",
+ "version": "5.81.5",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.81.5.tgz",
+ "integrity": "sha512-ZJOgCy/z2qpZXWaj/oxvodDx07XcQa9BF92c0oINjHkoqUPsmm3uG08HpTaviviZ/N9eP1f9CM7mKSEkIo7O1Q==",
"dev": true,
"license": "MIT",
"funding": {
@@ -1804,31 +1804,20 @@
}
},
"node_modules/@tanstack/react-query": {
- "version": "4.40.1",
- "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.40.1.tgz",
- "integrity": "sha512-mgD07S5N8e5v81CArKDWrHE4LM7HxZ9k/KLeD3+NUD9WimGZgKIqojUZf/rXkfAMYZU9p0Chzj2jOXm7xpgHHQ==",
+ "version": "5.81.5",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.81.5.tgz",
+ "integrity": "sha512-lOf2KqRRiYWpQT86eeeftAGnjuTR35myTP8MXyvHa81VlomoAWNEd8x5vkcAfQefu0qtYCvyqLropFZqgI2EQw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@tanstack/query-core": "4.40.0",
- "use-sync-external-store": "^1.2.0"
+ "@tanstack/query-core": "5.81.5"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react-native": "*"
- },
- "peerDependenciesMeta": {
- "react-dom": {
- "optional": true
- },
- "react-native": {
- "optional": true
- }
+ "react": "^18 || ^19"
}
},
"node_modules/@tanstack/react-table": {
@@ -5303,16 +5292,6 @@
"browserslist": ">= 4.21.0"
}
},
- "node_modules/use-sync-external-store": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
- "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- }
- },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
diff --git a/package.json b/package.json
index ed423df..f745d27 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"@fontsource/roboto": "^5.1.1",
"@mui/icons-material": "^7.2.0",
"@mui/material": "^7.2.0",
- "@tanstack/react-query": "^4.0.0",
+ "@tanstack/react-query": "^5.0.0",
"@ts-rest/react-query": "^3.51.0",
"@types/cors": "^2.8.17",
"@types/express": "^4.0.0",
diff --git a/src/client/App.tsx b/src/client/App.tsx
index bef0c26..b5a6ff8 100644
--- a/src/client/App.tsx
+++ b/src/client/App.tsx
@@ -9,6 +9,7 @@ import { StrictMode } from "react";
import { ThemeProvider } from "@emotion/react";
import { CssBaseline } from "@mui/material";
import theme from "./theme";
+import { tsr } from "./client";
import { SessionDetails } from "./SessionDetails";
import { Root } from "./Root";
@@ -20,17 +21,19 @@ export function App() {
-
-
- }>
- } />
- }
- />
-
-
-
+
+
+
+ }>
+ } />
+ }
+ />
+
+
+
+
diff --git a/src/client/SessionDetails.tsx b/src/client/SessionDetails.tsx
index f6854a3..724d6b9 100644
--- a/src/client/SessionDetails.tsx
+++ b/src/client/SessionDetails.tsx
@@ -1,5 +1,5 @@
import { useParams } from "react-router";
-import { client } from "./client";
+import { tsr } from "./client";
import {
Autocomplete,
Button,
@@ -16,12 +16,7 @@ import {
TextField,
Typography,
} from "@mui/material";
-import {
- Fragment,
- useCallback,
- useMemo,
- useState,
-} from "react";
+import { Fragment, useCallback, useMemo, useState } from "react";
import {
createMRTColumnHelper,
MaterialReactTable,
@@ -41,8 +36,11 @@ export function SessionDetails() {
throw new Error("session id is required");
}
- const getSessionQuery = client.getSession.useQuery(["session", sessionId], {
- params: { id: sessionId },
+ const getSessionQuery = tsr.getSession.useQuery({
+ queryKey: ["session", sessionId],
+ queryData: {
+ params: { id: sessionId },
+ },
});
const columns = useMemo(
@@ -101,17 +99,15 @@ export function SessionDetails() {
[]
);
- const getCategoriesQuery = client.getCategories.useQuery(
- ["get-categories", sessionId],
- {
+ const getCategoriesQuery = tsr.getCategories.useQuery({
+ queryKey: ["get-categories", sessionId],
+ enabled: isExportDialogOpen,
+ queryData: {
query: {
sessionId,
},
},
- {
- enabled: isExportDialogOpen,
- }
- );
+ });
const [selectedCategory, setSelectedCategory] = useState("");
const handleSelectedCategoryChange = useCallback(
@@ -123,18 +119,13 @@ export function SessionDetails() {
const queryClient = useQueryClient();
const onExport = useCallback(() => {
- client.getEntries
- .fetchQuery(
- queryClient,
- ["get-entries", sessionId, selectedCategory],
- {
- params: { sessionId },
- query: { category: selectedCategory },
+ tsr.getEntries
+ .query({
+ params: {
+ sessionId,
},
- {
- meta: { causeDownload: true },
- }
- )
+ query: { category: selectedCategory },
+ })
.then((data) => {
const json = JSON.stringify(data.body, null, 2);
const blob = new Blob([json], { type: "application/json" });
@@ -162,13 +153,13 @@ export function SessionDetails() {
Game:{" "}
- {getSessionQuery.status === "loading"
+ {getSessionQuery.status === "pending"
? "..."
: getSessionQuery.data.body.game_name}
Version{" "}
- {getSessionQuery.status === "loading"
+ {getSessionQuery.status === "pending"
? "..."
: getSessionQuery.data.body.version}
diff --git a/src/client/Sessions.tsx b/src/client/Sessions.tsx
index b437be2..315b47c 100644
--- a/src/client/Sessions.tsx
+++ b/src/client/Sessions.tsx
@@ -1,4 +1,4 @@
-import { client } from "./client";
+import { tsr } from "./client";
import {
MaterialReactTable,
MRT_ColumnFiltersState,
@@ -15,6 +15,7 @@ import { Typography } from "@mui/material";
import { useAtom } from "jotai";
import { shortGuidsAtom } from "./configuration";
import { formatGuid } from "./guid";
+import { keepPreviousData } from "@tanstack/react-query";
export function Sessions() {
const [paginationState, setPaginationState] = useState({
@@ -25,9 +26,10 @@ export function Sessions() {
[]
);
- const getSessionsQuery = client.getSessions.useQuery(
- ["sessions", { columnFilters, paginationState }],
- {
+ const getSessionsQuery = tsr.getSessions.useQuery({
+ queryKey: ["sessions", { columnFilters, paginationState }],
+ placeholderData: keepPreviousData,
+ queryData: {
query: {
skip: paginationState.pageIndex * paginationState.pageSize,
count: paginationState.pageSize,
@@ -36,23 +38,20 @@ export function Sessions() {
| undefined,
},
},
- {
- keepPreviousData: true,
- }
- );
+ });
return getSessionsQuery.status === "error" ? (
Error
) : (
{formatGuid(save_id, shortGuids)},
+ }) => (
+
+ {formatGuid(save_id, shortGuids)}
+
+ ),
},
{
accessorKey: "id",
@@ -99,7 +102,9 @@ function SessionsTable({
row: {
original: { id },
},
- }) => {formatGuid(id, shortGuids)},
+ }) => (
+ {formatGuid(id, shortGuids)}
+ ),
},
{
accessorKey: "game_name",
diff --git a/src/client/client.ts b/src/client/client.ts
index 54dbf5d..bd56337 100644
--- a/src/client/client.ts
+++ b/src/client/client.ts
@@ -1,5 +1,5 @@
// client.ts
-import { initQueryClient } from "@ts-rest/react-query";
+import { initTsrReactQuery } from "@ts-rest/react-query/v5";
import { contract } from "../common/contract";
export const serverRoot =
@@ -7,7 +7,7 @@ export const serverRoot =
? "http://localhost:9283"
: window.location.protocol + "//" + window.location.host;
-export const client = initQueryClient(contract, {
+export const tsr = initTsrReactQuery(contract, {
baseUrl: serverRoot,
baseHeaders: {},
});