@saberhq/sail
Version:
Account caching and batched loading for React-based Solana applications.
80 lines • 3 kB
JavaScript
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