1- import { useCallback } from "react" ;
1+ import { useCallback , useEffect } from "react" ;
22
33import { OpenApiQueryConfig } from "@povio/openapi-codegen-cli" ;
44import { QueryKey , useQueryClient } from "@tanstack/react-query" ;
55
66import { QueryModule } from "./queryModules" ;
7+ import { broadcastQueryInvalidation , setupCrossTabListener } from "./useCrossTabQueryInvalidation" ;
78
89export interface MutationEffectsOptions {
910 invalidateCurrentModule ?: boolean ;
11+ crossTabInvalidation ?: boolean ;
12+ invalidationMap ?: Record < string , ( context : Record < string , string > ) => QueryKey [ ] > ;
1013 invalidateModules ?: QueryModule [ ] ;
1114 invalidateKeys ?: QueryKey [ ] ;
1215 preferUpdate ?: boolean ;
@@ -20,6 +23,11 @@ export function useMutationEffects({ currentModule }: UseMutationEffectsProps) {
2023 const queryClient = useQueryClient ( ) ;
2124 const config = OpenApiQueryConfig . useConfig ( ) ;
2225
26+ useEffect ( ( ) => {
27+ if ( ! config . crossTabInvalidation ) return ;
28+ setupCrossTabListener ( queryClient ) ;
29+ } , [ queryClient , config . crossTabInvalidation ] ) ;
30+
2331 const runMutationEffects = useCallback (
2432 async < TData > ( data : TData , options : MutationEffectsOptions = { } , updateKeys ?: QueryKey [ ] ) => {
2533 const { invalidateCurrentModule = true , invalidateModules, invalidateKeys, preferUpdate } = options ;
@@ -30,6 +38,8 @@ export function useMutationEffects({ currentModule }: UseMutationEffectsProps) {
3038 const isQueryKeyEqual = ( keyA : QueryKey , keyB : QueryKey ) =>
3139 keyA . length === keyB . length && keyA . every ( ( item , index ) => item === keyB [ index ] ) ;
3240
41+ const invalidatedQueryKeys : QueryKey [ ] = [ ] ;
42+
3343 queryClient . invalidateQueries ( {
3444 predicate : ( { queryKey } ) => {
3545 const isUpdateKey = updateKeys ?. some ( ( key ) => isQueryKeyEqual ( queryKey , key ) ) ;
@@ -40,15 +50,29 @@ export function useMutationEffects({ currentModule }: UseMutationEffectsProps) {
4050 const isCurrentModule = shouldInvalidateCurrentModule && queryKey [ 0 ] === currentModule ;
4151 const isInvalidateModule = ! ! invalidateModules && invalidateModules . some ( ( module ) => queryKey [ 0 ] === module ) ;
4252 const isInvalidateKey = ! ! invalidateKeys && invalidateKeys . some ( ( key ) => isQueryKeyEqual ( queryKey , key ) ) ;
43- return isCurrentModule || isInvalidateModule || isInvalidateKey ;
53+
54+ const map = config . invalidationMap ?. [ currentModule ] ?.( data ) ;
55+ const isMappedKey = ! ! map && map . some ( ( key ) => isQueryKeyEqual ( queryKey , key ) ) ;
56+
57+ const shouldInvalidate = isCurrentModule || isInvalidateModule || isInvalidateKey || isMappedKey ;
58+
59+ if ( shouldInvalidate && config . crossTabInvalidation ) {
60+ invalidatedQueryKeys . push ( [ ...queryKey ] ) ;
61+ }
62+
63+ return shouldInvalidate ;
4464 } ,
4565 } ) ;
4666
67+ if ( config . crossTabInvalidation && invalidatedQueryKeys . length > 0 ) {
68+ broadcastQueryInvalidation ( invalidatedQueryKeys ) ;
69+ }
70+
4771 if ( shouldUpdate && updateKeys ) {
4872 updateKeys . map ( ( queryKey ) => queryClient . setQueryData ( queryKey , data ) ) ;
4973 }
5074 } ,
51- [ queryClient , currentModule , config . preferUpdate ] ,
75+ [ queryClient , currentModule , config . preferUpdate , config . invalidationMap , config . crossTabInvalidation ] ,
5276 ) ;
5377
5478 return { runMutationEffects } ;
0 commit comments