/** * Query Invalidation Hook * FE-STATE-004: Hook to listen for query invalidation events * * This hook listens for state invalidation events and invalidates * TanStack Query queries accordingly. */ import { useEffect } from 'react'; import { useQueryClient } from '@tanstack/react-query'; import type { ResourceType } from '@/utils/stateInvalidation'; /** * FE-STATE-004: Hook to handle query invalidation events * * This hook should be used in your root component to automatically * invalidate TanStack Query queries when state invalidation events are dispatched. * * @example * ```typescript * function App() { * useQueryInvalidation(); * return ; * } * ``` */ export function useQueryInvalidation(): void { const queryClient = useQueryClient(); useEffect(() => { const handleInvalidation = (event: CustomEvent) => { const { queryKeys, resourceType, resourceId } = event.detail as { queryKeys?: (string | number)[][]; resourceType?: ResourceType; resourceId?: string; }; // Invalidate specific query keys if (queryKeys && queryKeys.length > 0) { for (const queryKey of queryKeys) { queryClient.invalidateQueries({ queryKey }); } } // Invalidate by resource type if (resourceType) { const resourceQueryKeys: Record = { tracks: [['tracks'], ['track'], ['library']], playlists: [['playlists'], ['playlist']], users: [['users'], ['user'], ['auth']], conversations: [['conversations'], ['conversation'], ['chat']], roles: [['roles'], ['role']], library: [['library'], ['tracks'], ['favorites']], auth: [['auth'], ['user']], ui: [], all: [], }; const keys = resourceQueryKeys[resourceType] || []; for (const key of keys) { queryClient.invalidateQueries({ queryKey: resourceId ? [...key, resourceId] : key, }); } } }; window.addEventListener( 'veza:invalidate-queries', handleInvalidation as EventListener, ); return () => { window.removeEventListener( 'veza:invalidate-queries', handleInvalidation as EventListener, ); }; }, [queryClient]); }