A decentralized music tracking and discovery platform built on AT Protocol 馃幍 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
96
fork

Configure Feed

Select the types of activity you want to include in your feed.

at feat/pgpull 72 lines 1.7 kB view raw
1import type { CacheResult, DidCache, DidDocument } from "@atproto/identity"; 2import type { Storage } from "unstorage"; 3 4const HOUR = 60e3 * 60; 5const DAY = HOUR * 24; 6 7type CacheVal = { 8 doc: DidDocument; 9 updatedAt: number; 10}; 11 12/** 13 * An unstorage based DidCache with staleness and max TTL 14 */ 15export class StorageCache implements DidCache { 16 public staleTTL: number; 17 public maxTTL: number; 18 public cache: Storage<CacheVal>; 19 private prefix: string; 20 constructor({ 21 store, 22 prefix, 23 staleTTL, 24 maxTTL, 25 }: { 26 store: Storage; 27 prefix: string; 28 staleTTL?: number; 29 maxTTL?: number; 30 }) { 31 this.cache = store as Storage<CacheVal>; 32 this.prefix = prefix; 33 this.staleTTL = staleTTL ?? HOUR; 34 this.maxTTL = maxTTL ?? DAY; 35 } 36 37 async cacheDid(did: string, doc: DidDocument): Promise<void> { 38 await this.cache.set(this.prefix + did, { doc, updatedAt: Date.now() }); 39 } 40 41 async refreshCache( 42 did: string, 43 getDoc: () => Promise<DidDocument | null>, 44 ): Promise<void> { 45 const doc = await getDoc(); 46 if (doc) { 47 await this.cacheDid(did, doc); 48 } 49 } 50 51 async checkCache(did: string): Promise<CacheResult | null> { 52 const val = await this.cache.get<CacheVal>(this.prefix + did); 53 if (!val) return null; 54 const now = Date.now(); 55 const expired = now > val.updatedAt + this.maxTTL; 56 const stale = now > val.updatedAt + this.staleTTL; 57 return { 58 ...val, 59 did, 60 stale, 61 expired, 62 }; 63 } 64 65 async clearEntry(did: string): Promise<void> { 66 await this.cache.remove(this.prefix + did); 67 } 68 69 async clear(): Promise<void> { 70 await this.cache.clear(this.prefix); 71 } 72}