UNPKG

@tanstack/query-persist-client-core

Version:

Set of utilities for interacting with persisters, which can save your queryClient for later use

182 lines 5.63 kB
// src/createPersister.ts import { hashKey, matchQuery, notifyManager, partialMatchKey } from "@tanstack/query-core"; var PERSISTER_KEY_PREFIX = "tanstack-query"; function experimental_createQueryPersister({ storage, buster = "", maxAge = 1e3 * 60 * 60 * 24, serialize = JSON.stringify, deserialize = JSON.parse, prefix = PERSISTER_KEY_PREFIX, refetchOnRestore = true, filters }) { function isExpiredOrBusted(persistedQuery) { if (persistedQuery.state.dataUpdatedAt) { const queryAge = Date.now() - persistedQuery.state.dataUpdatedAt; const expired = queryAge > maxAge; const busted = persistedQuery.buster !== buster; if (expired || busted) { return true; } return false; } return true; } async function retrieveQuery(queryHash, afterRestoreMacroTask) { if (storage != null) { const storageKey = `${prefix}-${queryHash}`; try { const storedData = await storage.getItem(storageKey); if (storedData) { const persistedQuery = await deserialize(storedData); if (isExpiredOrBusted(persistedQuery)) { await storage.removeItem(storageKey); } else { if (afterRestoreMacroTask) { notifyManager.schedule( () => afterRestoreMacroTask(persistedQuery) ); } return persistedQuery.state.data; } } } catch (err) { if (process.env.NODE_ENV === "development") { console.error(err); console.warn( "Encountered an error attempting to restore query cache from persisted location." ); } await storage.removeItem(storageKey); } } return; } async function persistQueryByKey(queryKey, queryClient) { if (storage != null) { const query = queryClient.getQueryCache().find({ queryKey }); if (query) { await persistQuery(query); } else { if (process.env.NODE_ENV === "development") { console.warn( "Could not find query to be persisted. QueryKey:", JSON.stringify(queryKey) ); } } } } async function persistQuery(query) { if (storage != null) { const storageKey = `${prefix}-${query.queryHash}`; storage.setItem( storageKey, await serialize({ state: query.state, queryKey: query.queryKey, queryHash: query.queryHash, buster }) ); } } async function persisterFn(queryFn, ctx, query) { const matchesFilter = filters ? matchQuery(filters, query) : true; if (matchesFilter && query.state.data === void 0 && storage != null) { const restoredData = await retrieveQuery( query.queryHash, (persistedQuery) => { query.setState({ dataUpdatedAt: persistedQuery.state.dataUpdatedAt, errorUpdatedAt: persistedQuery.state.errorUpdatedAt }); if (refetchOnRestore === "always" || refetchOnRestore === true && query.isStale()) { query.fetch(); } } ); if (restoredData !== void 0) { return Promise.resolve(restoredData); } } const queryFnResult = await queryFn(ctx); if (matchesFilter && storage != null) { notifyManager.schedule(() => { persistQuery(query); }); } return Promise.resolve(queryFnResult); } async function persisterGc() { if (storage == null ? void 0 : storage.entries) { const entries = await storage.entries(); for (const [key, value] of entries) { if (key.startsWith(prefix)) { const persistedQuery = await deserialize(value); if (isExpiredOrBusted(persistedQuery)) { await storage.removeItem(key); } } } } else if (process.env.NODE_ENV === "development") { throw new Error( "Provided storage does not implement `entries` method. Garbage collection is not possible without ability to iterate over storage items." ); } } async function restoreQueries(queryClient, filters2 = {}) { const { exact, queryKey } = filters2; if (storage == null ? void 0 : storage.entries) { const entries = await storage.entries(); for (const [key, value] of entries) { if (key.startsWith(prefix)) { const persistedQuery = await deserialize(value); if (isExpiredOrBusted(persistedQuery)) { await storage.removeItem(key); continue; } if (queryKey) { if (exact) { if (persistedQuery.queryHash !== hashKey(queryKey)) { continue; } } else if (!partialMatchKey(persistedQuery.queryKey, queryKey)) { continue; } } queryClient.setQueryData( persistedQuery.queryKey, persistedQuery.state.data, { updatedAt: persistedQuery.state.dataUpdatedAt } ); } } } else if (process.env.NODE_ENV === "development") { throw new Error( "Provided storage does not implement `entries` method. Restoration of all stored entries is not possible without ability to iterate over storage items." ); } } return { persisterFn, persistQuery, persistQueryByKey, retrieveQuery, persisterGc, restoreQueries }; } export { PERSISTER_KEY_PREFIX, experimental_createQueryPersister }; //# sourceMappingURL=createPersister.js.map