phundrak.com/content/.vuepress/components/Cache.vue
Lucien Cartier-Tilet 1678100198
feat: improve caching of individual repositories
This commit adds the possibility to provide to the caching component data already known and to be
cached immediately without the need of a callback function. This allows caching individual
repositories without having to rely on additional API calls. However, repos can also be retrieved
individually from the GitHub API based on their full name.
2023-05-08 11:19:41 +02:00

64 lines
1.4 KiB
Vue

<template>
<slot />
</template>
<script setup lang="ts">
import { Observable, of } from 'rxjs';
const props = defineProps({
name: {
required: true,
type: String,
},
callback: {
required: true,
type: Function,
},
lifetime: {
default: 1000 * 60 * 60, // one hour
required: false,
type: Number,
},
data: {
default: null,
type: Object,
},
});
const emits = defineEmits(['cached']);
const isDataOutdated = (name: string): boolean => {
const lastUpdated: number = +localStorage.getItem(name + '-timestamp');
const elapsedTime: number = Date.now() - lastUpdated;
return elapsedTime > props.lifetime;
};
const storeInCache = (
callback: Function,
data: any,
name: string
): Observable<any> => {
let response: Observable<any> = data ? of(data) : callback();
response.subscribe({
next: (response) => {
localStorage.setItem(name, JSON.stringify(response));
localStorage.setItem(name + '-timestamp', `${Date.now()}`);
},
});
return response;
};
if (isDataOutdated(props.name)) {
emits('cached', storeInCache(props.callback, props.data, props.name));
} else {
let data = localStorage.getItem(props.name);
try {
emits('cached', of(JSON.parse(data)));
} catch (err) {
console.error(`Could not parse data found in cache: ${err}`);
emits('cached', storeInCache(props.callback, props.data, props.name));
}
}
</script>