Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- export interface CachedResource<I extends any[], V> {
- load(...input: I): Promise<V>
- loadSuspended(...input: I): V
- has(...input: I): boolean
- get(...input: I): V | undefined
- set(item: V, ...input: I): void
- invalidate(...input: I): void
- clear(): void
- }
- export default function createCachedResource<I extends any[], V>(
- loadResource: (...input: I) => Promise<V>,
- hashInput?: (...input: I) => string,
- ): CachedResource<I, V> {
- const cache = new Map<string, V>()
- const errors = new Map<string, any>()
- const getKeyFromInput = (...input: I) =>
- hashInput ? hashInput(...input) : input.join("-")
- async function load(...input: I) {
- const key = getKeyFromInput(...input)
- try {
- errors.delete(key)
- const data = cache.get(key) || (await loadResource(...input))
- cache.set(key, data)
- return data
- } catch (error) {
- errors.set(key, error)
- throw error
- }
- }
- return {
- load,
- loadSuspended(...input: I) {
- const key = getKeyFromInput(...input)
- const data = cache.get(key)
- if (data) return data
- const error = errors.get(key)
- if (error) throw error
- throw load(...input) // 👀
- },
- has(...input: I) {
- return cache.has(getKeyFromInput(...input))
- },
- get(...input: I) {
- return cache.get(getKeyFromInput(...input))
- },
- set(item: V, ...input: I) {
- cache.set(getKeyFromInput(...input), item)
- },
- invalidate(...input: I) {
- cache.delete(getKeyFromInput(...input))
- },
- clear() {
- cache.clear()
- },
- }
- }
Add Comment
Please, Sign In to add comment