@rt_lite/api
Version:
An unoficial rotten tomatoes REST api
84 lines (61 loc) • 2.33 kB
text/typescript
import { Cache } from '~/models/cache.model';
import type { Immutable } from '~/models/immutable.model';
import logger from '~/modules/logger';
import scraper from '~/modules/scraper';
import type { SearchResults } from '@rt_lite/scraper/dist/models/search-results';
import { time } from '~/utilities/time.utility';
import type {
MediaSet,
Movie,
TVSeries
} from '@rt_lite/common/models';
/* eslint-disable @typescript-eslint/no-magic-numbers */
const DEFAULT_CACHE_ARGS = {
maxSize: 100,
ttl: time(6).hours
};
/* eslint-enable @typescript-eslint/no-magic-numbers */
let frontPageSets: MediaSet[] = [];
let frontPageSetsTimestamp = Infinity;
const searchCache = new Cache<SearchResults>({ ...DEFAULT_CACHE_ARGS });
const moviesCache = new Cache<Movie[]>({ ...DEFAULT_CACHE_ARGS });
const tvCache = new Cache<TVSeries[]>({ ...DEFAULT_CACHE_ARGS });
const refreshFrontPageSets = async (): Promise<void> => {
logger.info('Refreshing front page sets');
const sets = await scraper.getFrontPageSets();
if (sets.length < 1) return;
frontPageSets = [...sets];
frontPageSetsTimestamp = Date.now();
};
const generateSearch = <T> (
cache: Immutable<Cache<T>>,
fetcher: (terms: string) => Promise<T>
): (terms: string) => Promise<T> => async (terms: string): Promise<T> => {
const updateCache = async (): Promise<T> => {
const fetchedResults = await fetcher(terms);
cache.set(terms, fetchedResults);
return fetchedResults;
};
if (cache.has(terms)) {
const cachedResults = cache.get(terms);
if (cachedResults !== null) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
updateCache();
return cachedResults;
}
}
const results = await updateCache();
return results;
};
export const search = generateSearch(searchCache, scraper.findMedia.bind(scraper));
export const searchMovies = generateSearch(moviesCache, scraper.findMovies.bind(scraper));
export const searchTV = generateSearch(tvCache, scraper.findTVSeries.bind(scraper));
export const frontPage = async (): Promise<MediaSet[]> => {
if (frontPageSets.length > 0) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
if (Date.now() - frontPageSetsTimestamp > DEFAULT_CACHE_ARGS.ttl) refreshFrontPageSets();
return frontPageSets;
}
await refreshFrontPageSets();
return frontPageSets;
};