UNPKG

@saberhq/sail

Version:

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

111 lines 4.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useParsedAccountData = exports.useParsedAccountsData = exports.makeParserHooks = exports.makeParsersFromCoder = void 0; const tslib_1 = require("tslib"); const lodash_mapvalues_1 = tslib_1.__importDefault(require("lodash.mapvalues")); const lodash_zip_1 = tslib_1.__importDefault(require("lodash.zip")); const react_1 = require("react"); const __1 = require(".."); const useAccountsData_1 = require("../hooks/useAccountsData"); /** * Makes account parsers from a coder. * @param parsers * @returns */ const makeParsersFromCoder = (parsers) => { return (0, lodash_mapvalues_1.default)(parsers, (p) => (info) => p(info.accountInfo.data)); }; exports.makeParsersFromCoder = makeParsersFromCoder; /** * Makes hooks for parsers. * @param parsers * @returns */ const makeParserHooks = (parsers) => { const sailParsers = (0, exports.makeParsersFromCoder)(parsers); return (0, lodash_mapvalues_1.default)(sailParsers, (parser) => ({ useSingleData: (key) => (0, exports.useParsedAccountData)(key, parser), useData: (keys) => (0, exports.useParsedAccountsData)(keys, parser), })); }; exports.makeParserHooks = makeParserHooks; /** * Parses accounts with the given parser. * * @deprecated use {@link useBatchedParsedAccounts} instead * @param keys * @param parser * @returns */ const useParsedAccountsData = (keys, parser) => { const { onError } = (0, __1.useSail)(); const data = (0, useAccountsData_1.useAccountsData)(keys); const [parsed, setParsed] = (0, react_1.useState)(keys.reduce((acc, k) => { if (k) { acc[(0, __1.getCacheKeyOfPublicKey)(k)] = undefined; } return acc; }, {})); (0, react_1.useEffect)(() => { (0, react_1.startTransition)(() => { setParsed((prevParsed) => { const nextParsed = { ...prevParsed }; (0, lodash_zip_1.default)(keys, data).forEach(([key, datum]) => { if (datum) { const key = (0, __1.getCacheKeyOfPublicKey)(datum.accountId); const prevValue = prevParsed[key]; if (prevValue && prevValue.raw.length === datum.accountInfo.data.length && prevValue.raw.equals(datum.accountInfo.data)) { // preserve referential equality if buffers are equal return; } try { const parsed = parser(datum); nextParsed[key] = { ...datum, accountInfo: { ...datum.accountInfo, data: parsed, }, raw: datum.accountInfo.data, }; } catch (e) { onError(new __1.SailAccountParseError(e, datum)); nextParsed[key] = null; return; } } if (key && datum === null) { nextParsed[(0, __1.getCacheKeyOfPublicKey)(key)] = null; } }); return nextParsed; }); }); }, [data, keys, onError, parser]); return (0, react_1.useMemo)(() => { return keys.map((k) => { if (!k) { return k; } return parsed[(0, __1.getCacheKeyOfPublicKey)(k)]; }); }, [keys, parsed]); }; exports.useParsedAccountsData = useParsedAccountsData; /** * Loads the parsed data of a single account. * @returns */ const useParsedAccountData = (key, parser) => { const theKey = (0, react_1.useMemo)(() => [key], [key]); const [data] = (0, exports.useParsedAccountsData)(theKey, parser); return { loading: key !== undefined && data === undefined, data, }; }; exports.useParsedAccountData = useParsedAccountData; //# sourceMappingURL=useParsedAccountsData.js.map