mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 23:16:21 +00:00
useClubGifts + useNitroEventInvalidator: close the catalogOptions bag
This commit drains the last field out of ICatalogOptions (clubGifts) and deletes the interface — useCatalog no longer owns a catch-all mutable object that downstream components stuff data into. Two pieces: 1) New useNitroEventInvalidator(eventType, queryKey, accept?) — a small companion to useNitroQuery for the case where the server pushes the same event unprompted (e.g. ClubGiftInfoEvent fires both as the response to GetClubGiftInfo and again after the user claims a gift via SelectClubGiftComposer). It calls queryClient.invalidateQueries() on each matching push so the next render of any subscriber triggers a fresh queryFn. 2) New useClubGifts() — useNitroQuery on the ClubGiftInfoEvent pair, paired with useNitroEventInvalidator so server-driven pushes refresh the cache automatically. CatalogLayoutVipGiftsView now consumes the query directly. The local optimistic 'giftsAvailable--' mutation (which side-effected the parser object passed back to the catalog state!) is dropped — the server's authoritative ClubGiftInfoEvent push is the single source of truth via the invalidator. useCatalog drops the matching listener + the GetClubGiftInfo dispatch from the catalog-open effect. ICatalogOptions is now empty and deleted; the catalogOptions / setCatalogOptions state + return-shape field are removed from useCatalog along with the import.
This commit is contained in:
@@ -1 +1,2 @@
|
||||
export * from './createNitroQuery';
|
||||
export * from './useNitroEventInvalidator';
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { IMessageEvent, MessageEvent } from '@nitrots/nitro-renderer';
|
||||
import { QueryKey, useQueryClient } from '@tanstack/react-query';
|
||||
import { useMessageEvent } from '../../hooks/events/useMessageEvent';
|
||||
|
||||
/**
|
||||
* Invalidate a TanStack query slot every time the renderer pushes the
|
||||
* matching parser event. Companion to useNitroQuery for the case where
|
||||
* the server can push fresh data unprompted (e.g. ClubGiftInfoEvent
|
||||
* fires both as the response to GetClubGiftInfo and again after the
|
||||
* user claims a gift via SelectClubGiftComposer).
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* const { data: clubGifts } = useNitroQuery({
|
||||
* key: ['nitro', 'catalog', 'clubGifts'],
|
||||
* request: () => new GetClubGiftInfo(),
|
||||
* parser: ClubGiftInfoEvent,
|
||||
* select: e => e.getParser(),
|
||||
* });
|
||||
*
|
||||
* // re-fetch on every server push:
|
||||
* useNitroEventInvalidator(ClubGiftInfoEvent, ['nitro', 'catalog', 'clubGifts']);
|
||||
*
|
||||
* Optional `accept` predicate filters out events that don't belong to
|
||||
* this query slot — useful when the same parser is multiplexed across
|
||||
* multiple correlated queries (mirrors useNitroQuery.accept).
|
||||
*
|
||||
* Implementation: the renderer push triggers `queryClient.invalidateQueries`,
|
||||
* which marks the slot stale; the next subscriber render triggers a
|
||||
* fresh fetch via useNitroQuery's queryFn. If nobody is currently
|
||||
* subscribed, the invalidation is a no-op (TanStack drops stale entries
|
||||
* with no active observers per its garbage-collection policy).
|
||||
*/
|
||||
export const useNitroEventInvalidator = <T extends IMessageEvent>(
|
||||
eventType: typeof MessageEvent,
|
||||
queryKey: QueryKey,
|
||||
accept?: (event: T) => boolean
|
||||
) =>
|
||||
{
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
useMessageEvent<T>(eventType, event =>
|
||||
{
|
||||
if(accept && !accept(event)) return;
|
||||
|
||||
queryClient.invalidateQueries({ queryKey });
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user