@@ -734,9 +734,67 @@ interface Persister {
734
734
}
735
735
736
736
export function createIDBPersister ( idbValidKey : string = STORAGE_KEYS . QUERY_CACHE ) : Persister {
737
+ let lastPersistedHash : string | null = null ;
738
+
739
+ // Extract only the actual query data, excluding metadata that changes on every access
740
+ const extractQueryData = ( client : any ) : any => {
741
+ if ( ! client || ! client . clientState ) {
742
+ return client ;
743
+ }
744
+
745
+ // Create a copy with only the actual data from queries
746
+ const dataOnly = {
747
+ queries : client . clientState . queries ?. map ( ( query : any ) => ( {
748
+ queryKey : query . queryKey ,
749
+ queryHash : query . queryHash ,
750
+ data : query . state ?. data ,
751
+ // Only include error if it exists
752
+ ...( query . state ?. error ? { error : query . state . error } : { } ) ,
753
+ } ) ) ,
754
+ mutations : client . clientState . mutations ?. map ( ( mutation : any ) => ( {
755
+ mutationKey : mutation . mutationKey ,
756
+ state : mutation . state ?. status ,
757
+ data : mutation . state ?. data ,
758
+ error : mutation . state ?. error ,
759
+ } ) ) ,
760
+ } ;
761
+
762
+ return dataOnly ;
763
+ } ;
764
+
765
+ const hashObject = ( obj : any ) : string => {
766
+ const str = JSON . stringify ( obj ) ;
767
+ let hash = 0 ;
768
+ for ( let i = 0 ; i < str . length ; i ++ ) {
769
+ const char = str . charCodeAt ( i ) ;
770
+ hash = ( hash << 5 ) - hash + char ;
771
+ hash = hash & hash ; // Convert to 32bit integer
772
+ }
773
+ return hash . toString ( 36 ) ;
774
+ } ;
775
+
737
776
const debouncedPersist = debounce (
738
777
async ( client : any ) => {
739
778
try {
779
+ // Extract only the data portion for comparison
780
+ const dataOnly = extractQueryData ( client ) ;
781
+ const currentHash = hashObject ( dataOnly ) ;
782
+
783
+ // Debug logging
784
+ console . log ( '[IndexedDB] Hash comparison:' , {
785
+ current : currentHash ,
786
+ last : lastPersistedHash ,
787
+ equal : lastPersistedHash === currentHash ,
788
+ hasClientState : ! ! client ?. clientState ,
789
+ queryCount : client ?. clientState ?. queries ?. length || 0 ,
790
+ } ) ;
791
+
792
+ // Skip persistence if state hasn't changed
793
+ if ( lastPersistedHash === currentHash ) {
794
+ console . log ( '[IndexedDB] Cache state unchanged, skipping persistence' ) ;
795
+ return ;
796
+ }
797
+
740
798
// 🗜️ Compress data before storing
741
799
const compressedData = compressForStorage ( client ) ;
742
800
const originalSize = JSON . stringify ( client ) . length ;
@@ -788,6 +846,9 @@ export function createIDBPersister(idbValidKey: string = STORAGE_KEYS.QUERY_CACH
788
846
789
847
if ( result && 'success' in result && ! result . success ) {
790
848
console . warn ( '[IndexedDB] Persistence operation did not succeed, but continuing gracefully' ) ;
849
+ } else {
850
+ // Update the hash only after successful persistence
851
+ lastPersistedHash = currentHash ;
791
852
}
792
853
} catch ( error ) {
793
854
console . error ( '[IndexedDB] Error persisting to IndexedDB:' , error ) ;
@@ -901,6 +962,8 @@ export function createIDBPersister(idbValidKey: string = STORAGE_KEYS.QUERY_CACH
901
962
removeClient : async ( ) => {
902
963
try {
903
964
await workerOperation ( 'delete' , idbValidKey ) ;
965
+ // Reset the hash when cache is removed
966
+ lastPersistedHash = null ;
904
967
} catch ( error ) {
905
968
console . error ( '[IndexedDB] Error removing from IndexedDB:' , error ) ;
906
969
}
0 commit comments