Files
polylan-submitter/polylan_submitter/src/queries.ts
T

46 lines
1.8 KiB
TypeScript

import { QueryClient } from "@tanstack/vue-query";
import { persistQueryClient } from "@tanstack/query-persist-client-core";
import { createSyncStoragePersister } from "@tanstack/query-sync-storage-persister";
import {
gamesApiListEventGamesOptions,
polylanSubmitterApiGetUserInfoOptions,
polylanSubmitterApiGetUserInfoQueryKey,
} from "@/api/@tanstack/vue-query.gen";
// Exported (not just provided by VueQueryPlugin) so Pinia stores can
// fetchQuery() through the same cache.
export const queryClient = new QueryClient();
// Login/logout are full-page redirects, so the user can't change within a
// page load - only refetched once after a reload (see restoreQueryCache).
export const userQuery = () => ({
...polylanSubmitterApiGetUserInfoOptions(),
staleTime: Infinity,
});
// Games only change when staff enable/disable one, a few minutes of
// staleness is fine.
export const eventGamesQuery = (eventPath: string) => ({
...gamesApiListEventGamesOptions({ path: { event_path: eventPath } }),
staleTime: 5 * 60 * 1000,
});
const PERSISTED_QUERIES = new Set(["polylanSubmitterApiGetUserInfo", "gamesApiListEventGames"]);
// Restores user + games from localStorage before the app mounts, so pages
// render right away on reload instead of waiting on the API.
export const restoreQueryCache = (client: QueryClient) =>
persistQueryClient({
queryClient: client,
persister: createSyncStoragePersister({ storage: window.localStorage }),
dehydrateOptions: {
shouldDehydrateQuery: (query) =>
query.state.status === "success" &&
PERSISTED_QUERIES.has((query.queryKey[0] as { _id: string })._id),
},
});
// The restored user is only a placeholder until the real one comes back.
export const onQueryCacheRestored = (client: QueryClient) =>
client.invalidateQueries({ queryKey: polylanSubmitterApiGetUserInfoQueryKey() });