Skip to content

Instantly share code, notes, and snippets.

@SIMULATAN
Created August 6, 2023 19:15
Show Gist options
  • Save SIMULATAN/1c676211db4e6e6475b53de920bc8e76 to your computer and use it in GitHub Desktop.
Save SIMULATAN/1c676211db4e6e6475b53de920bc8e76 to your computer and use it in GitHub Desktop.
svelte store that has caching or something
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