Skip to content

Commit e11210e

Browse files
Optimize IndexedDB cache persistence to prevent unnecessary writes.
1 parent b1e5f4d commit e11210e

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/localStorage.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,9 +734,67 @@ interface Persister {
734734
}
735735

736736
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+
737776
const debouncedPersist = debounce(
738777
async (client: any) => {
739778
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+
740798
// 🗜️ Compress data before storing
741799
const compressedData = compressForStorage(client);
742800
const originalSize = JSON.stringify(client).length;
@@ -788,6 +846,9 @@ export function createIDBPersister(idbValidKey: string = STORAGE_KEYS.QUERY_CACH
788846

789847
if (result && 'success' in result && !result.success) {
790848
console.warn('[IndexedDB] Persistence operation did not succeed, but continuing gracefully');
849+
} else {
850+
// Update the hash only after successful persistence
851+
lastPersistedHash = currentHash;
791852
}
792853
} catch (error) {
793854
console.error('[IndexedDB] Error persisting to IndexedDB:', error);
@@ -901,6 +962,8 @@ export function createIDBPersister(idbValidKey: string = STORAGE_KEYS.QUERY_CACH
901962
removeClient: async () => {
902963
try {
903964
await workerOperation('delete', idbValidKey);
965+
// Reset the hash when cache is removed
966+
lastPersistedHash = null;
904967
} catch (error) {
905968
console.error('[IndexedDB] Error removing from IndexedDB:', error);
906969
}

0 commit comments

Comments
 (0)