From 61cca511e6023eb0325e1460f018b12063205aa5 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Wed, 25 Sep 2024 13:18:20 +0200 Subject: [PATCH] Fix react query config --- .../Availability/AvailabilityReservations.tsx | 17 ++++++++-- .../Availability/useAvailabilityMutation.ts | 5 +-- .../Availailibities/Availabilities.tsx | 29 +++++++++++++--- src/components/Debug/Debug.tsx | 12 +++++++ .../NodeIndicator/NodeIndicator.tsx | 15 +++++++- .../NodeSpaceAllocation.tsx | 34 +++++++++++++------ .../useStorageRequestMutation.ts | 7 ++-- src/hooks/useData.tsx | 11 ++++++ src/routes/dashboard/purchases.tsx | 26 +++++++++----- 9 files changed, 123 insertions(+), 33 deletions(-) diff --git a/src/components/Availability/AvailabilityReservations.tsx b/src/components/Availability/AvailabilityReservations.tsx index 24210f1..5cdc540 100644 --- a/src/components/Availability/AvailabilityReservations.tsx +++ b/src/components/Availability/AvailabilityReservations.tsx @@ -41,10 +41,23 @@ export function AvailabilityReservations({ .reservations(availability!.id) .then((s) => Promises.rejectOnError(s)), queryKey: ["reservations"], - retry: 0, - staleTime: 0, + initialData: [], + + // Enable only when the availability exists enabled: !!availability, + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. + retry: false, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, }); if (!availability) { diff --git a/src/components/Availability/useAvailabilityMutation.ts b/src/components/Availability/useAvailabilityMutation.ts index a2d74a3..8a36fcb 100644 --- a/src/components/Availability/useAvailabilityMutation.ts +++ b/src/components/Availability/useAvailabilityMutation.ts @@ -21,7 +21,7 @@ export function useAvailabilityMutation( const [error, setError] = useState(null); const { mutateAsync } = useMutation({ - mutationKey: ["debug"], + mutationKey: ["availabilities"], mutationFn: ({ totalSize, totalSizeUnit, @@ -47,12 +47,13 @@ export function useAvailabilityMutation( }).then((s) => Promises.rejectOnError(s)); }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ["availabilities"] }); queryClient.invalidateQueries({ queryKey: ["space"] }); WebStorage.delete("availability"); WebStorage.delete("availability-step"); + setError(null); + dispatch({ type: "next", step: state.step, diff --git a/src/components/Availailibities/Availabilities.tsx b/src/components/Availailibities/Availabilities.tsx index a6921f9..87adc09 100644 --- a/src/components/Availailibities/Availabilities.tsx +++ b/src/components/Availailibities/Availabilities.tsx @@ -28,9 +28,19 @@ export function Availabilities() { .then((s) => Promises.rejectOnError(s)) .then((res) => res.sort((a, b) => b.totalSize - a.totalSize)), queryKey: ["availabilities"], - refetchOnWindowFocus: false, + initialData: [], + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. retry: false, - throwOnError: true, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, }); // Error will be catched in ErrorBounday @@ -38,8 +48,19 @@ export function Availabilities() { queryFn: () => CodexSdk.data.space().then((s) => Promises.rejectOnError(s)), queryKey: ["space"], - // TODO comment staleTime - staleTime: 24 * 60 * 60 * 1000, + initialData: defaultSpace, + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. + retry: false, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, }); const allocation = availabilities diff --git a/src/components/Debug/Debug.tsx b/src/components/Debug/Debug.tsx index a64e489..fb01fca 100644 --- a/src/components/Debug/Debug.tsx +++ b/src/components/Debug/Debug.tsx @@ -8,6 +8,18 @@ export function Debug() { const { data, isPending, isError, error } = useQuery({ queryFn: () => CodexSdk.debug.info().then((s) => Promises.rejectOnError(s)), queryKey: ["debug"], + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. + retry: false, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, }); if (isPending) { diff --git a/src/components/NodeIndicator/NodeIndicator.tsx b/src/components/NodeIndicator/NodeIndicator.tsx index fa6f59c..7241896 100644 --- a/src/components/NodeIndicator/NodeIndicator.tsx +++ b/src/components/NodeIndicator/NodeIndicator.tsx @@ -20,8 +20,21 @@ export function NodeIndicator() { queryKey: ["spr"], queryFn: async () => CodexSdk.node.spr().then((data) => Promises.rejectOnError(data, report)), - retry: false, refetchInterval: 5000, + + // No need to retry because we defined a refetch interval + retry: false, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, + + // Cache is not useful for the spr endpoint + gcTime: 0, }); const isCodexOnline = !isError && !!data; diff --git a/src/components/NodeSpaceAllocation/NodeSpaceAllocation.tsx b/src/components/NodeSpaceAllocation/NodeSpaceAllocation.tsx index 84415fd..8459298 100644 --- a/src/components/NodeSpaceAllocation/NodeSpaceAllocation.tsx +++ b/src/components/NodeSpaceAllocation/NodeSpaceAllocation.tsx @@ -2,27 +2,39 @@ import { useQuery } from "@tanstack/react-query"; import Loader from "../../assets/loader.svg"; import { CodexSdk } from "../../sdk/codex"; import { SpaceAllocation } from "@codex-storage/marketplace-ui-components"; +import { Promises } from "../../utils/promises"; + +const defaultSpace = { + quotaMaxBytes: 0, + quotaReservedBytes: 0, + quotaUsedBytes: 0, + totalBlocks: 0, +}; export function NodeSpaceAllocation() { const { data: space, isPending } = useQuery({ - queryFn: () => CodexSdk.data.space(), + queryFn: () => CodexSdk.data.space().then((s) => Promises.rejectOnError(s)), queryKey: ["space"], - refetchOnMount: true, + initialData: defaultSpace, + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. + retry: false, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, }); if (isPending || !space) { return Loader; } - if (space.error) { - return ""; - } - - const { - quotaMaxBytes = 0, - quotaReservedBytes = 0, - quotaUsedBytes = 0, - } = space.data; + const { quotaMaxBytes, quotaReservedBytes, quotaUsedBytes } = space; return ( , state: StepperState ) { - const queryClient = useQueryClient(); const [error, setError] = useState(null); const { mutateAsync } = useMutation({ - mutationKey: ["debug"], + mutationKey: ["purchases"], mutationFn: (input: CodexCreateStorageRequestInput) => CodexSdk.marketplace .createStorageRequest(input) .then((s) => Promises.rejectOnError(s)), onSuccess: async () => { - queryClient.invalidateQueries({ queryKey: ["purchases"] }); - // if (!requestId.startsWith("0x")) { // requestId = "0x" + requestId; // } @@ -34,6 +31,8 @@ export function useStorageRequestMutation( WebStorage.delete("storage-request-step"); WebStorage.delete("storage-request"); + setError(null); + // PurchaseStorage.set(requestId, cid); // WebStorage.set("storage-request-step", SUCCESS_STEP); dispatch({ diff --git a/src/hooks/useData.tsx b/src/hooks/useData.tsx index f59d28a..835dc4d 100644 --- a/src/hooks/useData.tsx +++ b/src/hooks/useData.tsx @@ -58,6 +58,17 @@ export function useData() { }); }, queryKey: ["cids"], + initialData: [], + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. + retry: false, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Don't expect something new when coming back to the UI refetchOnWindowFocus: false, }); diff --git a/src/routes/dashboard/purchases.tsx b/src/routes/dashboard/purchases.tsx index 7e70a5a..54c6173 100644 --- a/src/routes/dashboard/purchases.tsx +++ b/src/routes/dashboard/purchases.tsx @@ -6,19 +6,28 @@ import { StorageRequestStepper } from "../../components/StorageRequestSetup/Stor import "./purchases.css"; import { FileCell } from "../../components/FileCellRender/FileCell"; import { CustomStateCellRender } from "../../components/CustomStateCellRender/CustomStateCellRender"; -import prettyMilliseconds from "pretty-ms"; import { ErrorBoundary } from "../../components/ErrorBoundary/ErrorBoundary"; import { Promises } from "../../utils/promises"; import { TruncateCell } from "../../components/TruncateCell/TruncateCell"; +import { Times } from "../../utils/times"; const Purchases = () => { const { data, isPending } = useQuery({ queryFn: () => CodexSdk.marketplace.purchases().then((s) => Promises.rejectOnError(s)), queryKey: ["purchases"], - refetchOnWindowFocus: false, + + // No need to retry because if the connection to the node + // is back again, all the queries will be invalidated. retry: false, - throwOnError: true, + + // The client node should be local, so display the cache value while + // making a background request looks good. + staleTime: 0, + + // Refreshing when focus returns can be useful if a user comes back + // to the UI after performing an operation in the terminal. + refetchOnWindowFocus: true, }); if (isPending) { @@ -39,21 +48,20 @@ const Purchases = () => { "state", ]; - const sorted = [...(data || [])].reverse(); const cells = - sorted.map((p, index) => { + (data ?? []).map((p, index) => { const r = p.request; const ask = p.request.ask; - const duration = parseInt(p.request.ask.duration, 10) * 1000; - const pf = parseInt(p.request.ask.proofProbability, 10) * 1000; + const duration = parseInt(p.request.ask.duration, 10); + const pf = parseInt(p.request.ask.proofProbability, 10); return [ , , - , + , , , - , + , , ]; }) || [];