import { QueryClient } from "@tanstack/react-query"; import { createFailure } from "../../contracts/errors.js"; export const QUERY_CACHE_DEFAULTS = Object.freeze({ staleTime: 30_000, gcTime: 300_000, refetchOnWindowFocus: true, retry: false, mutationRetry: false, persistence: false, }); export function createQueryClient() { return new QueryClient({ defaultOptions: { queries: { staleTime: QUERY_CACHE_DEFAULTS.staleTime, gcTime: QUERY_CACHE_DEFAULTS.gcTime, refetchOnWindowFocus: QUERY_CACHE_DEFAULTS.refetchOnWindowFocus, retry: QUERY_CACHE_DEFAULTS.retry, }, mutations: { retry: QUERY_CACHE_DEFAULTS.mutationRetry, }, }, }); } /** * @param {QueryClient} queryClient * @returns {import("../../application/ports/query-cache-port.js").QueryCachePort} */ export function createQueryCacheAdapter(queryClient) { return Object.freeze({ read(key) { try { return { ok: true, value: queryClient.getQueryData(key) }; } catch { return cacheFailure("read", key); } }, write(key, value) { try { queryClient.setQueryData(key, structuredClone(value)); return { ok: true }; } catch { return cacheFailure("write", key); } }, async invalidate(namespace) { try { await queryClient.invalidateQueries({ queryKey: namespace, exact: false }); return { ok: true }; } catch { return cacheFailure("invalidate", namespace); } }, }); } /** @param {string} phase @param {readonly unknown[]} key */ function cacheFailure(phase, key) { const namespace = typeof key[0] === "string" ? key[0] : "unknown"; return { ok: /** @type {false} */ (false), error: createFailure("QUERY_CACHE_FAILURE", "QUERY_CACHE", 0, { code: `QUERY_CACHE_${phase.toUpperCase()}_FAILED`, causeClass: `namespace:${namespace}`, }), }; }