refactor: drop dead query helpers and simplify read deadline (WealthLedger/frontend#141) (#149)
This commit was merged in pull request #149.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import {
|
||||
type QueryClient,
|
||||
type QueryFunctionContext,
|
||||
useQueryClient,
|
||||
type UseQueryOptions,
|
||||
} from "@tanstack/react-query";
|
||||
@@ -9,7 +8,6 @@ import { useEffect } from "react";
|
||||
import type { components, paths } from "./generated/schema";
|
||||
|
||||
import { useAuthenticatedQuery } from "./authenticated-query";
|
||||
import { getAuthenticatedSessionSnapshot } from "./client";
|
||||
import { apiErrorCode, isBrokerageAccessLoss } from "./problem-details";
|
||||
|
||||
type InvestmentResourceMeta = components["schemas"]["InvestmentResourceMetaDto"];
|
||||
@@ -31,7 +29,7 @@ type ResourcePath = {
|
||||
type ResourceQueryKey = readonly [
|
||||
"get",
|
||||
ResourcePath,
|
||||
{ params?: { path?: object; query?: { sync?: "observe" } } }?,
|
||||
{ params?: { path?: object; query?: object } }?,
|
||||
];
|
||||
|
||||
function invalidateResourceAccess(
|
||||
@@ -57,22 +55,6 @@ function invalidateResourceAccess(
|
||||
});
|
||||
}
|
||||
|
||||
// Keep endpoint and parameters intact. The generated queryFn accepts the
|
||||
// optional sync mode even for a cache key originally created without init.
|
||||
function observationKey<K extends readonly unknown[]>(key: K): K {
|
||||
const [method, path, init] = key as unknown as [
|
||||
string,
|
||||
string,
|
||||
{ params?: { path?: object; query?: object } }?,
|
||||
];
|
||||
|
||||
return [method, path, {
|
||||
...init,
|
||||
params: { ...init?.params, query: { ...init?.params?.query, sync: "observe" } },
|
||||
}] as unknown as K;
|
||||
}
|
||||
|
||||
// Observation changes transport mode, never the generated cache identity.
|
||||
function useResourceQuery<
|
||||
T extends Resource,
|
||||
E = unknown,
|
||||
@@ -92,50 +74,17 @@ function useResourceQuery<
|
||||
if (group) invalidateResourceAccess(client, group, query.error);
|
||||
}, [client, group, query.error]);
|
||||
|
||||
const observe = async () => {
|
||||
const queryFunction = options.queryFn;
|
||||
if (
|
||||
typeof queryFunction !== "function"
|
||||
|| !query.isEnabled
|
||||
|| !getAuthenticatedSessionSnapshot()
|
||||
)
|
||||
return;
|
||||
// Cancellation is synchronous; start the replacement in the same boundary.
|
||||
void client.cancelQueries({ exact: true, queryKey: options.queryKey });
|
||||
|
||||
return client.query({
|
||||
...options,
|
||||
queryFn: async (context: QueryFunctionContext<K>) => {
|
||||
const queryKey = observationKey(context.queryKey);
|
||||
|
||||
return queryFunction({ ...context, queryKey });
|
||||
},
|
||||
retry: false,
|
||||
// Keep the cache envelope independent of observer projection.
|
||||
select: undefined,
|
||||
staleTime: 0,
|
||||
});
|
||||
};
|
||||
|
||||
const data: T["data"] | undefined = query.data?.data;
|
||||
const meta: T["meta"] | undefined = query.data?.meta;
|
||||
|
||||
// Project resource fields; refetch still returns the transport envelope.
|
||||
// queryKey is kept for screen-sync cache bookkeeping.
|
||||
return {
|
||||
// eslint-disable-next-line @tanstack/query/no-rest-destructuring -- Single projection point; consumers already depend on the whole query state.
|
||||
...query,
|
||||
data: data ?? undefined,
|
||||
error: query.error,
|
||||
fetchStatus: query.fetchStatus,
|
||||
isEnabled: query.isEnabled,
|
||||
isError: query.isError,
|
||||
isFetching: query.isFetching,
|
||||
isLoading: query.isLoading,
|
||||
isPending: query.isPending,
|
||||
isSuccess: query.isSuccess,
|
||||
meta,
|
||||
observe,
|
||||
queryKey: options.queryKey,
|
||||
refetch: query.refetch,
|
||||
status: query.status,
|
||||
sync: query.data && "sync" in query.data ? query.data.sync : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user