Files
bsky-social-app/src/lib/persisted-query-storage.ts
T
Samuel Newman 4f1d4821c5 Speed up startup by persisting some queries (#9594)
* persist startup queries

* Use IDB for query storage (#9687)

* Add storage abstraction for persisted query data

Introduce a platform-specific storage abstraction layer for react-query
persistence:
- Native: Uses MMKV for high-performance synchronous storage
- Web: Uses IndexedDB via the `idb` library for efficient async storage

This replaces the previous AsyncStorage implementation with more performant
platform-native solutions. The abstraction maintains API compatibility with
@tanstack/query-async-storage-persister.

* Refactor storage abstraction to use factory pattern

Change createPersistedQueryStorage to a factory function that accepts a
storage ID, allowing multiple isolated storage instances:
- Native: Each instance gets its own MMKV store
- Web: Each instance gets its own IndexedDB database

Adopt the factory pattern in:
- react-query.tsx: Uses 'persisted_queries' storage
- ageAssurance/data.tsx: Uses 'age_assurance' storage

This provides better separation between different query client caches
and allows each to be managed independently.

---------

Co-authored-by: Claude <noreply@anthropic.com>

* Refactor to use archival storage

(cherry picked from commit a773b40e41c96f821cd32260919ce1437c0fc3ab)

* Improve archive db types

(cherry picked from commit 80e4959ba2aa00c984c26aed2f7dfae1095720b0)

* rm idb

* clear on logout, bust on app version

* create abstraction for persisting queries, make gcTime infinite

* Rm abstraction

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Eric Bailey <git@esb.lol>
2026-02-02 11:55:01 -06:00

42 lines
1.4 KiB
TypeScript

import {create as createArchiveDB} from '#/storage/archive/db'
/**
* Interface for async storage compatible with @tanstack/query-async-storage-persister
*/
export interface PersistedQueryStorage {
getItem: (key: string) => Promise<string | null>
setItem: (key: string, value: string) => Promise<void>
removeItem: (key: string) => Promise<void>
}
function createId(id: string) {
return `react-query-cache-${id}`
}
/**
* Creates an MMKV-based storage adapter for persisting react-query cache on native platforms.
* Each storage instance uses a separate MMKV store identified by the provided id.
* MMKV provides synchronous access but we wrap it in Promises for API compatibility.
*
* @param id - Unique identifier for this storage instance (used as MMKV store id)
*/
export function createPersistedQueryStorage(id: string): PersistedQueryStorage {
const store = createArchiveDB({id: createId(id)})
return {
getItem: async (key: string): Promise<string | null> => {
return (await store.get(key)) ?? null
},
setItem: async (key: string, value: string): Promise<void> => {
await store.set(key, value)
},
removeItem: async (key: string): Promise<void> => {
await store.delete(key)
},
}
}
export async function clearPersistedQueryStorage(id: string) {
const store = createArchiveDB({id: createId(id)})
await store.clear()
}