veza/apps/web/src/hooks/useQueryInvalidation.ts

81 lines
2.3 KiB
TypeScript

/**
* 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 <YourApp />;
* }
* ```
*/
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<ResourceType, (string | number)[][]> = {
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]);
}