refactor: clarify frontend module ownership
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
import {
|
||||
type QueryClient,
|
||||
type QueryFunctionContext,
|
||||
type QueryKey,
|
||||
useQueryClient,
|
||||
type UseQueryOptions,
|
||||
type UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
import { useEffect } from "react";
|
||||
|
||||
import type { components } from "./generated/schema";
|
||||
import type { components, paths } from "./generated/schema";
|
||||
|
||||
import { useAuthenticatedQuery } from "./authenticated-query";
|
||||
import { getAuthenticatedSessionSnapshot } from "./client";
|
||||
@@ -23,6 +22,19 @@ type Resource = {
|
||||
meta: InvestmentResourceMeta;
|
||||
};
|
||||
|
||||
type ResourcePath = {
|
||||
[P in keyof paths]: paths[P]["get"] extends {
|
||||
// eslint-disable-next-line @typescript-eslint/no-magic-numbers -- HTTP success response in the generated contract.
|
||||
responses: { 200: { content: { "application/json": Resource } } };
|
||||
} ? P : never;
|
||||
}[keyof paths];
|
||||
|
||||
type ResourceQueryKey = readonly [
|
||||
"get",
|
||||
ResourcePath,
|
||||
{ params?: { path?: object; query?: { sync?: "observe" } } }?,
|
||||
];
|
||||
|
||||
function invalidateResourceAccess(
|
||||
client: QueryClient,
|
||||
group: string,
|
||||
@@ -58,6 +70,17 @@ 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 ResourceQueryKey>(key: K): K {
|
||||
const [method, path, init] = key;
|
||||
|
||||
return [method, path, {
|
||||
...init,
|
||||
params: { ...init?.params, query: { ...init?.params?.query, sync: "observe" } },
|
||||
}] as unknown as K;
|
||||
}
|
||||
|
||||
function unwrapResourceResult<T extends Resource, E>(
|
||||
result: UseQueryResult<T, E>,
|
||||
) {
|
||||
@@ -86,7 +109,7 @@ function unwrapResourceResult<T extends Resource, E>(
|
||||
}
|
||||
|
||||
// Observation changes transport mode, never the generated cache identity.
|
||||
function useResourceQuery<T extends Resource, E, K extends QueryKey>(
|
||||
function useResourceQuery<T extends Resource, E, K extends ResourceQueryKey>(
|
||||
options: UseQueryOptions<T, E, T, K>,
|
||||
) {
|
||||
const client = useQueryClient();
|
||||
@@ -137,23 +160,7 @@ function useResourceQuery<T extends Resource, E, K extends QueryKey>(
|
||||
return client.query({
|
||||
...options,
|
||||
queryFn: async (context: QueryFunctionContext<K>) => {
|
||||
const [method, path, input] = context.queryKey;
|
||||
|
||||
const init = input as
|
||||
undefined
|
||||
| { params?: { query?: Record<string, unknown> } };
|
||||
|
||||
const queryKey = [
|
||||
method,
|
||||
path,
|
||||
{
|
||||
...init,
|
||||
params: {
|
||||
...init?.params,
|
||||
query: { ...init?.params?.query, sync: "observe" },
|
||||
},
|
||||
},
|
||||
] as unknown as K;
|
||||
const queryKey = observationKey(context.queryKey);
|
||||
|
||||
const response = await queryFunction({ ...context, queryKey });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user