@hazae41/glacier
Version:
Yet another React data (re)fetching library
75 lines (72 loc) • 2.64 kB
JavaScript
import { Some } from '@hazae41/option';
import { Arrays } from '../../../libs/arrays/arrays.mjs';
import { equals } from '../../../libs/equals/index.mjs';
import { core } from '../../core/core.mjs';
import { Fetched } from '../../fetched/fetched.mjs';
var _a;
class ScrollError extends Error {
#class = _a;
name = this.#class.name;
constructor() {
super(`Could not scroll`);
}
}
_a = ScrollError;
var Scrollable;
(function (Scrollable) {
function getCacheKey(key) {
if (typeof key === "string")
return key;
return `scroll:${JSON.stringify(key)}`;
}
Scrollable.getCacheKey = getCacheKey;
/**
* Fetch first page and compare it to the previous first page
* @param core
* @param scroller
* @param cacheKey
* @param fetcher
* @param aborter
* @param settings
* @returns
*/
async function fetchOrThrow(cacheKey, signal, settings) {
const fetched = Fetched.from(await settings.fetcher(settings.key, { signal }));
return await core.mutateOrThrow(cacheKey, async (previous) => {
if (fetched.isErr())
return new Some(fetched);
const prenormalized = await core.prenormalizeOrThrow(fetched, settings);
if (prenormalized?.isData() && previous.real?.data && equals(prenormalized.get(), previous.real.data.get()))
return new Some(previous.real.data);
return new Some(fetched);
}, settings);
}
Scrollable.fetchOrThrow = fetchOrThrow;
/**
* Scroll to the next page
* @param core
* @param scroller
* @param cacheKey
* @param fetcher
* @param aborter
* @param settings
* @returns
*/
async function scrollOrThrow(cacheKey, signal, settings) {
const previous = await core.getOrThrow(cacheKey, settings);
const previousPages = previous.real?.data?.get() ?? [];
const previousPage = Arrays.last(previousPages);
const key = settings.scroller(previousPage);
if (key == null)
throw new ScrollError();
const fetched = Fetched.from(await settings.fetcher(key, { signal }));
return await core.mutateOrThrow(cacheKey, async (previous) => {
const previousPages = previous.real?.data?.get() ?? [];
const paginated = fetched.mapSync(data => [...previousPages, ...data]);
return new Some(paginated);
}, settings);
}
Scrollable.scrollOrThrow = scrollOrThrow;
})(Scrollable || (Scrollable = {}));
export { ScrollError, Scrollable };
//# sourceMappingURL=helper.mjs.map