@hazae41/glacier
Version:
Yet another React data (re)fetching library
115 lines (112 loc) • 4.73 kB
JavaScript
import { Some } from '@hazae41/option';
import { Err, Ok } from '@hazae41/result';
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 { Simple } from './helper.mjs';
function createQuery(settings) {
if (settings.fetcher == null)
return new SimpleFetcherlessQuery(settings);
else
return new SimpleFetcherfulQuery(settings);
}
class SimpleFetcherlessQuery {
settings;
cacheKey;
constructor(settings) {
this.settings = settings;
this.cacheKey = Simple.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(aborter = new AbortController()) {
throw new MissingFetcherError();
}
async refetchOrThrow(aborter = new AbortController()) {
throw new MissingFetcherError();
}
async updateOrThrow(updater, aborter = new AbortController()) {
throw new MissingFetcherError();
}
}
class SimpleFetcherfulQuery {
settings;
cacheKey;
constructor(settings) {
this.settings = settings;
this.cacheKey = Simple.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, () => Simple.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, () => Simple.fetchOrThrow(cacheKey, signal, settings)));
}
async updateOrThrow(updater, 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 signal = AbortSignals.getOrNever(init?.signal);
return new Ok(await Simple.updateOrThrow(cacheKey, updater, signal, settings));
}
}
export { SimpleFetcherfulQuery, SimpleFetcherlessQuery, createQuery };
//# sourceMappingURL=query.mjs.map