Created
August 6, 2023 19:15
-
-
Save SIMULATAN/1c676211db4e6e6475b53de920bc8e76 to your computer and use it in GitHub Desktop.
svelte store that has caching or something
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Options as BaseOptions } from './persisted_store' | |
import type {Unsubscriber, Updater, Writable} from "svelte/store"; | |
import {persisted} from "./persisted_store"; | |
export interface Options<T> extends BaseOptions<CachedState<T>>{ | |
/** The time in milliseconds to cache the value for */ | |
cacheTime: number, | |
/** The value getter function */ | |
getter: () => Promise<T> | |
} | |
export interface CachedState<T> { | |
value: T, | |
lastUpdated: number, | |
isRefreshing: boolean | |
} | |
export function optionalCached<T>(key: string, options: Options<T>): Writable<T | null> { | |
return _cached(key, {value: null, lastUpdated: 0}, options); | |
} | |
export function cached<T>(key: string, initialValue: T, options: Options<T>): Writable<T> { | |
return _cached(key, {value: initialValue, lastUpdated: Date.now()}, options); | |
} | |
function _cached<T>(key: string, initialValue: { value: T, lastUpdated: number }, options: Options<T>): Writable<T> { | |
const store = persisted<CachedState<T>>(key, { ...initialValue, isRefreshing: false }, options); | |
const subscribeImpl = (run: (value: T) => void): Unsubscriber => { | |
return store.subscribe(cachedState => { | |
if (Date.now() - cachedState.lastUpdated > options.cacheTime) { | |
store.set({...cachedState, isRefreshing: true}); | |
options.getter().then(value => { | |
store.set({ | |
value, | |
lastUpdated: Date.now(), | |
isRefreshing: false | |
}); | |
}); | |
} | |
run(cachedState.value); | |
}) | |
} | |
return { | |
subscribe: subscribeImpl, | |
set: (value: T) => { | |
store.set({ | |
value, | |
lastUpdated: Date.now(), | |
isRefreshing: false | |
}); | |
}, | |
update(updater: Updater<T>) { | |
store.update(cachedState => { | |
const value = updater(cachedState.value); | |
return { | |
value, | |
lastUpdated: Date.now(), | |
isRefreshing: false | |
}; | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment