UNPKG

@hazae41/glacier

Version:

Yet another React data (re)fetching library

132 lines (129 loc) 5.39 kB
import { Some } from '@hazae41/option'; import { Err, Ok } from '@hazae41/result'; import { Arrays } from '../../../libs/arrays/arrays.mjs'; import { shouldUseCacheIfFresh, shouldUseCacheIfStale, shouldUseNetwork } from '../../../libs/request/index.mjs'; import { AbortSignals } from '../../../libs/signals/index.mjs'; import { Time } from '../../../libs/time/time.mjs'; import { core, MissingFetcherError } from '../../core/core.mjs'; import { Scrollable } from './helper.mjs'; function createScrollableQuery(settings) { if (settings.fetcher == null) return new ScrollableFetcherlessQuery(settings); return new ScrollableFetcherfulQuery(settings); } class ScrollableFetcherfulQuery { settings; cacheKey; constructor(settings) { this.settings = settings; this.cacheKey = Scrollable.getCacheKey(settings.key); } get state() { return core.getOrThrow(this.cacheKey, this.settings); } get aborter() { return core.getAborterSync(this.cacheKey); } async mutateOrThrow(mutator) { return await core.mutateOrThrow(this.cacheKey, mutator, this.settings); } async deleteOrThrow() { return await core.deleteOrThrow(this.cacheKey, this.settings); } async normalizeOrThrow(fetched, more) { if (more.shallow) return; await this.mutateOrThrow(() => new Some(fetched)); } async fetchOrThrow(init) { const { cacheKey, settings } = this; const state = await this.state; if (shouldUseCacheIfFresh(init?.cache) && Time.isAfterNow(state.real?.current.cooldown)) return new Err(state); if (shouldUseCacheIfStale(init?.cache) && Time.isAfterNow(state.real?.current.expiration)) return new Err(state); if (!shouldUseNetwork(init?.cache)) throw new Error(`Could not fetch using the provided cache directive`); const aborter = new AbortController(); const signal = AbortSignal.any([aborter.signal, AbortSignals.getOrNever(init?.signal)]); return new Ok(await core.runOrJoin(cacheKey, aborter, () => Scrollable.fetchOrThrow(cacheKey, signal, settings))); } async refetchOrThrow(init) { const { cacheKey, settings } = this; const state = await this.state; if (shouldUseCacheIfFresh(init?.cache) && Time.isAfterNow(state.real?.current.cooldown)) return new Err(state); if (shouldUseCacheIfStale(init?.cache) && Time.isAfterNow(state.real?.current.expiration)) return new Err(state); if (!shouldUseNetwork(init?.cache)) throw new Error(`Could not fetch using the provided cache directive`); const aborter = new AbortController(); const signal = AbortSignal.any([aborter.signal, AbortSignals.getOrNever(init?.signal)]); return new Ok(await core.runOrReplace(cacheKey, aborter, () => Scrollable.fetchOrThrow(cacheKey, signal, settings))); } async scrollOrThrow(init) { const { cacheKey, settings } = this; const state = await this.state; if (shouldUseCacheIfFresh(init?.cache) && Time.isAfterNow(state.real?.current.cooldown)) return new Err(state); if (shouldUseCacheIfStale(init?.cache) && Time.isAfterNow(state.real?.current.expiration)) return new Err(state); if (!shouldUseNetwork(init?.cache)) throw new Error(`Could not fetch using the provided cache directive`); const aborter = new AbortController(); const signal = AbortSignal.any([aborter.signal, AbortSignals.getOrNever(init?.signal)]); return new Ok(await core.runOrReplace(cacheKey, aborter, () => Scrollable.scrollOrThrow(cacheKey, signal, settings))); } async peekOrNull() { const { settings } = this; const state = await this.state; const pages = state.real?.data?.get(); if (pages == null) return undefined; return settings.scroller(Arrays.last(pages)); } } class ScrollableFetcherlessQuery { settings; cacheKey; constructor(settings) { this.settings = settings; this.cacheKey = Scrollable.getCacheKey(settings.key); } get state() { return core.getOrThrow(this.cacheKey, this.settings); } get aborter() { return core.getAborterSync(this.cacheKey); } async mutateOrThrow(mutator) { return await core.mutateOrThrow(this.cacheKey, mutator, this.settings); } async deleteOrThrow() { return await core.deleteOrThrow(this.cacheKey, this.settings); } async normalizeOrThrow(fetched, more) { if (more.shallow) return; await this.mutateOrThrow(() => new Some(fetched)); } async fetchOrThrow(init) { throw new MissingFetcherError(); } async refetchOrThrow(init) { throw new MissingFetcherError(); } async scrollOrThrow(init) { throw new MissingFetcherError(); } async peekOrNull() { const { settings } = this; const state = await this.state; const pages = state.real?.data?.get(); if (pages == null) return undefined; return settings.scroller(Arrays.last(pages)); } } export { ScrollableFetcherfulQuery, ScrollableFetcherlessQuery, createScrollableQuery }; //# sourceMappingURL=query.mjs.map