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