From 4e6d35bc45d8356226a3611d5c16b3dad2d60687 Mon Sep 17 00:00:00 2001 From: oskarrough Date: Mon, 19 Jun 2023 09:38:38 +0200 Subject: [PATCH] Add a simple client side cache --- src/components/r4-app.js | 8 +++++++ src/libs/browse.js | 3 +-- src/libs/cache.js | 33 +++++++++++++++++++++++++++++ src/pages/base-channel.js | 3 +-- src/pages/r4-page-channel-tracks.js | 3 ++- src/pages/r4-page-channel.js | 3 ++- 6 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 src/libs/cache.js diff --git a/src/components/r4-app.js b/src/components/r4-app.js index 39cd11f1..f3b2b25f 100644 --- a/src/components/r4-app.js +++ b/src/components/r4-app.js @@ -3,8 +3,10 @@ import {ref, createRef} from 'lit/directives/ref.js' import {sdk} from '@radio4000/sdk' import page from 'page/page.mjs' import DatabaseListeners from '../libs/db-listeners' +import Cache from '../libs/cache.js' import '../pages/' + export default class R4App extends LitElement { playerRef = createRef() @@ -44,6 +46,7 @@ export default class R4App extends LitElement { userChannels: this.userChannels, followers: this.followers, following: this.following, + cache: this.cache } } set store(val) { @@ -66,6 +69,11 @@ export default class R4App extends LitElement { return this.userChannels.find((c) => c.slug === this.selectedSlug) } + constructor() { + super() + this.cache = new Cache() + } + async connectedCallback() { super.connectedCallback() diff --git a/src/libs/browse.js b/src/libs/browse.js index 6a9427d1..0c3cef79 100644 --- a/src/libs/browse.js +++ b/src/libs/browse.js @@ -106,8 +106,7 @@ export async function query({ const {from, to, limit: l} = getBrowseParams({page, limit}) query = query.range(from, to).limit(l) - console.log('browse.query', query.url.search) - + console.log('browse.query()', query.url.search) return query } diff --git a/src/libs/cache.js b/src/libs/cache.js new file mode 100644 index 00000000..95dc56fc --- /dev/null +++ b/src/libs/cache.js @@ -0,0 +1,33 @@ +export default class Cache { + constructor() { + this.data = new Map() + } + + async get(key, fetcher, ttl = 60000) { + const now = Date.now() + if (!this.data.has(key)) { + // If the key is not in the cache, fetch it and store the Promise. + return this.refresh(key, fetcher, ttl) + } else { + const {timestamp, dataPromise} = this.data.get(key) + // If the key is in the cache, but it is expired, refresh it in the background. + if (now - timestamp > ttl) { + this.refresh(key, fetcher, ttl) + } + // If the key is in the cache and it is not expired, return the cached data. + console.log('using cache', key, ttl) + return dataPromise + } + } + + async refresh(key, fetcher, ttl) { + console.log('cache refresh', key, ttl) + const dataPromise = fetcher().catch((err) => { + // If an error occurs, remove the Promise from the cache. + this.data.delete(key) + throw err + }) + this.data.set(key, {dataPromise, timestamp: Date.now()}) + return dataPromise + } +} diff --git a/src/pages/base-channel.js b/src/pages/base-channel.js index bc294949..fa71cbb6 100644 --- a/src/pages/base-channel.js +++ b/src/pages/base-channel.js @@ -63,8 +63,7 @@ export default class BaseChannel extends LitElement { return } - console.log('setting channel', slug, this.channel) - const {data, error} = await sdk.channels.readChannel(slug) + const {data, error} = await this.store.cache.get(`channel/${slug}`, () => sdk.channels.readChannel(slug)) if (error) { try { diff --git a/src/pages/r4-page-channel-tracks.js b/src/pages/r4-page-channel-tracks.js index 5b70056a..47bfe446 100644 --- a/src/pages/r4-page-channel-tracks.js +++ b/src/pages/r4-page-channel-tracks.js @@ -46,7 +46,8 @@ export default class R4PageChannelTracks extends BaseChannel { urlUtils.updateSearchParams(q, ['table', 'select']) const filtersWithDefaults = [...(q.filters || []), ...this.defaultFilters] q.filters = filtersWithDefaults - const res = await query(q) + const key = JSON.stringify(q) + const res = await this.store.cache.get(`tracks_${key}`, () => query(q)) this.count = res.count this.tracks = res.data this.lastQuery = q diff --git a/src/pages/r4-page-channel.js b/src/pages/r4-page-channel.js index fa091b21..85f0ab2a 100644 --- a/src/pages/r4-page-channel.js +++ b/src/pages/r4-page-channel.js @@ -39,7 +39,8 @@ export default class R4PageChannel extends BaseChannel { } async onQuery({detail}) { - this.tracks = (await query(detail)).data + const res = await this.store.cache.get(`${this.params.slug}/latesttracks`, () => query(detail)) + this.tracks = res.data } render() {