import LRU from 'lru-cache' import type { mastodon } from 'masto' const cache = new LRU({ max: 1000, }) if (process.dev && process.client) // eslint-disable-next-line no-console console.log({ cache }) export function setCached(key: string, value: any, override = false) { if (override || !cache.has(key)) cache.set(key, value) } function removeCached(key: string) { cache.delete(key) } export function fetchStatus(id: string, force = false): Promise { const server = currentServer.value const userId = currentUser.value?.account.id const key = `${server}:${userId}:status:${id}` const cached = cache.get(key) if (cached && !force) return cached const promise = useMastoClient().v1.statuses.fetch(id) .then((status) => { cacheStatus(status) return status }) cache.set(key, promise) return promise } export function fetchAccountById(id?: string | null): Promise { if (!id) return Promise.resolve(null) const server = currentServer.value const userId = currentUser.value?.account.id const key = `${server}:${userId}:account:${id}` const cached = cache.get(key) if (cached) return cached const domain = currentInstance.value ? getInstanceDomain(currentInstance.value) : null const promise = useMastoClient().v1.accounts.fetch(id) .then((r) => { if (r.acct && !r.acct.includes('@') && domain) r.acct = `${r.acct}@${domain}` cacheAccount(r, server, true) return r }) cache.set(key, promise) return promise } export async function fetchAccountByHandle(acct: string): Promise { const server = currentServer.value const userId = currentUser.value?.account.id const key = `${server}:${userId}:account:${acct}` const cached = cache.get(key) if (cached) return cached const domain = currentInstance.value ? getInstanceDomain(currentInstance.value) : undefined async function lookupAccount() { const client = useMastoClient() let account: mastodon.v1.Account if (!isGotoSocial.value) account = await client.v1.accounts.lookup({ acct }) else account = (await client.v1.search({ q: `@${acct}`, type: 'accounts' })).accounts[0] if (account.acct && !account.acct.includes('@') && domain) account.acct = `${account.acct}@${domain}` return account } const account = lookupAccount() .then((r) => { cacheAccount(r, server, true) return r }) cache.set(key, account) return account } export function useAccountByHandle(acct: string) { return useAsyncState(() => fetchAccountByHandle(acct), null).state } export function useAccountById(id?: string | null) { return useAsyncState(() => fetchAccountById(id), null).state } export function cacheStatus(status: mastodon.v1.Status, server = currentServer.value, override?: boolean) { const userId = currentUser.value?.account.id setCached(`${server}:${userId}:status:${status.id}`, status, override) } export function removeCachedStatus(id: string, server = currentServer.value) { const userId = currentUser.value?.account.id removeCached(`${server}:${userId}:status:${id}`) } export function cacheAccount(account: mastodon.v1.Account, server = currentServer.value, override?: boolean) { const userId = currentUser.value?.account.id setCached(`${server}:${userId}:account:${account.id}`, account, override) setCached(`${server}:${userId}:account:${account.acct}`, account, override) }