Use Query cancellation and native mutation results instead of HTTP registries, access epochs and copied scope state. Keep local auth ordering and mutation identity fences. Allow staged generated files to remain excluded from ESLint. Backend contract: WealthLedger/backend@d698ed9 BREAKING CHANGE: drop investment stateVersion/progress/resources from the client contract and use data/metadata readiness instead of rewritten query status. Cross-tab auth may require re-login.
47 lines
1.0 KiB
TypeScript
47 lines
1.0 KiB
TypeScript
import type { InvestmentResourceMeta } from "@/shared/api";
|
|
|
|
type SectionState = {
|
|
error: boolean;
|
|
hasData: boolean;
|
|
lastSuccessfulAt?: null | string;
|
|
loading: boolean;
|
|
partial?: boolean;
|
|
refreshing: boolean;
|
|
retry: () => void;
|
|
sourceError?: boolean;
|
|
stale?: boolean;
|
|
};
|
|
|
|
function section(
|
|
query: {
|
|
data: unknown;
|
|
isError: boolean;
|
|
isFetching: boolean;
|
|
meta?: InvestmentResourceMeta;
|
|
refetch: () => unknown;
|
|
},
|
|
retry?: () => unknown,
|
|
): SectionState {
|
|
const isError = query.isError || query.meta?.sync.state === "failed";
|
|
|
|
return {
|
|
error: isError,
|
|
hasData: Boolean(query.data),
|
|
lastSuccessfulAt: query.meta?.lastSuccessfulAt,
|
|
loading: !query.data && !isError,
|
|
partial: query.meta?.availability === "partial",
|
|
refreshing:
|
|
Boolean(query.data)
|
|
&& (query.isFetching
|
|
|| query.meta?.sync.state === "running"
|
|
),
|
|
retry: () => {
|
|
void (retry ?? query.refetch)();
|
|
},
|
|
sourceError: query.meta?.sync.state === "failed",
|
|
stale: query.meta?.freshness === "stale",
|
|
};
|
|
}
|
|
|
|
export { section, type SectionState };
|