import { QueryClient, useQuery, useQueryClient, UseQueryOptions } from '@tanstack/react-query' import { useCallback, useRef } from 'react' import { get } from 'lib/common/fetch' import { API_URL } from 'lib/constants' import { Project, ResponseError } from 'types' import { projectKeys } from './keys' export type ProjectsVariables = { ref?: string } export async function getProjects(signal?: AbortSignal) { const data = await get(`${API_URL}/projects`, { signal }) if (data.error) throw data.error return data as Project[] } export type ProjectsData = Awaited> export type ProjectsError = ResponseError export const useProjectsQuery = ({ enabled = true, ...options }: UseQueryOptions = {}) => useQuery( projectKeys.list(), ({ signal }) => getProjects(signal), { enabled: enabled, ...options } ) export function prefetchProjects(client: QueryClient) { return client.prefetchQuery(projectKeys.list(), ({ signal }) => getProjects(signal)) } export function useProjectsPrefetch() { const client = useQueryClient() return useCallback(() => { prefetchProjects(client) }, [client]) } export function useAutoProjectsPrefetch() { const prefetch = useProjectsPrefetch() const called = useRef(false) if (called.current === false) { called.current = true prefetch() } } export function invalidateProjectsQuery(client: QueryClient) { return client.invalidateQueries(projectKeys.list()) } export function setProjectStatus( client: QueryClient, projectRef: Project['ref'], status: Project['status'] ) { client.setQueriesData( projectKeys.list(), (old) => { if (!old) return old return old.map((project) => { if (project.ref === projectRef) { return { ...project, status } } return project }) }, { updatedAt: Date.now() } ) client.setQueriesData( projectKeys.detail(projectRef), (old) => { if (!old) return old return { ...old, status } }, { updatedAt: Date.now() } ) } export function setProjectPostgrestStatus( client: QueryClient, projectRef: Project['ref'], status: Project['postgrestStatus'] ) { client.setQueriesData( projectKeys.detail(projectRef), (old) => { if (!old) return old return { ...old, postgrestStatus: status } }, { updatedAt: Date.now() } ) }