UNPKG

@saberhq/sail

Version:

Account caching and batched loading for React-based Solana applications.

80 lines 3 kB
import { startTransition, useEffect, useMemo, useState } from "react"; import { useDebouncedCallback } from "use-debounce"; import { fetchKeysMaybe, getCacheKeyOfPublicKey, SailCacheRefetchError, useAccountsSubscribe, useSail, } from ".."; const loadKeysFromCache = (getDatum, keys) => { const ret = {}; keys.forEach((key) => { if (key) { ret[getCacheKeyOfPublicKey(key)] = getDatum(key); } }); return ret; }; /** * Fetches data of the given accounts. * @param keys Keys to fetch. Ensure that this is memoized or unlikely to change. * * @deprecated use {@link useBatchedParsedAccounts} instead * @returns One of three types: * - Buffer -- the account was found * - null -- account not found or an error occurred while loading the account * - undefined -- account key not provided or not yet loaded */ export const useAccountsData = (keys) => { const { getDatum, onBatchCache, fetchKeys, onError } = useSail(); const [data, setData] = useState(() => loadKeysFromCache(getDatum, keys)); // TODO: add cancellation const fetchAndSetKeys = useDebouncedCallback(async (fetchKeys, keys) => { const keysData = await fetchKeysMaybe(fetchKeys, keys); const nextData = {}; keys.forEach((key, keyIndex) => { if (key) { const keyData = keysData[keyIndex]; if (keyData) { nextData[getCacheKeyOfPublicKey(key)] = keyData.data; } else { nextData[getCacheKeyOfPublicKey(key)] = keyData; } } }); startTransition(() => { setData(nextData); }); }, 100); useEffect(() => { void (async () => { var _a; await ((_a = fetchAndSetKeys(fetchKeys, keys)) === null || _a === void 0 ? void 0 : _a.catch((e) => { onError(new SailCacheRefetchError(e, keys)); })); })(); }, [keys, fetchAndSetKeys, fetchKeys, onError]); useAccountsSubscribe(keys); // refresh from the cache whenever the cache is updated useEffect(() => { return onBatchCache((e) => { var _a; if (keys.find((key) => key && e.hasKey(key))) { void ((_a = fetchAndSetKeys(fetchKeys, keys)) === null || _a === void 0 ? void 0 : _a.catch((e) => { onError(new SailCacheRefetchError(e, keys)); })); } }); }, [keys, fetchAndSetKeys, fetchKeys, onError, onBatchCache]); // unload debounces when the component dismounts useEffect(() => { return () => { fetchAndSetKeys.cancel(); }; }, [fetchAndSetKeys]); return useMemo(() => { return keys.map((key) => { if (key) { return data[getCacheKeyOfPublicKey(key)]; } return key; }); }, [data, keys]); }; //# sourceMappingURL=useAccountsData.js.map