Something went wrong. Try again.
A Bsky-like frontend using the atprotocol natively.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
import { atprotoClient } from '../api/client';import type { GetPostThreadResponse, GetTimelineResponse, GetFeedResponse, AtUri } from '../api/types';import { cacheSet, cacheGet, threadCacheKey, timelineCacheKey, feedCacheKey } from './cache';
const inflightThreads = new Map<string, Promise<GetPostThreadResponse>>();
export function prefetchThread(uri: string): void { const key = threadCacheKey(uri);
if (cacheGet(key)) return;
if (inflightThreads.has(key)) return;
const promise = atprotoClient.getPostThread(uri) .then((resp) => { cacheSet(key, resp); inflightThreads.delete(key); return resp; }) .catch(() => { inflightThreads.delete(key); return null as never; });
inflightThreads.set(key, promise);}
export function getCachedThread(uri: string): GetPostThreadResponse | undefined { return cacheGet<GetPostThreadResponse>(threadCacheKey(uri));}
let inflightTimeline: Promise<GetTimelineResponse> | null = null;
export function prefetchTimeline(): void { const key = timelineCacheKey();
if (cacheGet(key)) return;
if (inflightTimeline) return;
inflightTimeline = atprotoClient.getTimeline(50) .then((resp) => { cacheSet(key, resp); inflightTimeline = null; return resp; }) .catch(() => { inflightTimeline = null; return null as never; });}
export function getCachedTimeline(): GetTimelineResponse | undefined { return cacheGet<GetTimelineResponse>(timelineCacheKey());}
const inflightFeeds = new Map<string, Promise<GetFeedResponse>>();
export function prefetchFeed(feedUri: AtUri): void { const key = feedCacheKey(feedUri);
if (cacheGet(key)) return;
if (inflightFeeds.has(key)) return;
const promise = atprotoClient.getFeed(feedUri, 50) .then((resp) => { cacheSet(key, resp); inflightFeeds.delete(key); return resp; }) .catch(() => { inflightFeeds.delete(key); return null as never; });
inflightFeeds.set(key, promise);}
export function getCachedFeed(feedUri: AtUri): GetFeedResponse | undefined { return cacheGet<GetFeedResponse>(feedCacheKey(feedUri));}
const inflightProfileTabs = new Map<string, Promise<unknown>>();
export function prefetchProfileTab(actor: string, filter?: string): void { const key = filter ? `profile-tab:${actor}:${filter}` : `profile-tab:${actor}:posts_with_replies`;
if (cacheGet(key)) return; if (inflightProfileTabs.has(key)) return;
const promise = atprotoClient.getAuthorFeed( actor, 30, undefined, filter as 'posts_with_replies' | 'posts_no_replies' | 'posts_with_media' | 'posts_with_video' | undefined, ) .then((resp) => { cacheSet(key, resp); inflightProfileTabs.delete(key); }) .catch(() => { inflightProfileTabs.delete(key); });
inflightProfileTabs.set(key, promise);}
export function prefetchProfileLikes(actor: string, isOwnProfile = true): void { const key = `profile-tab:${actor}:likes`; if (cacheGet(key)) return; if (inflightProfileTabs.has(key)) return;
const promise = (isOwnProfile ? atprotoClient.getActorLikes(actor, 30) : atprotoClient.getActorLikesViaRecords(actor, 25) ) .then((resp) => { cacheSet(key, resp); inflightProfileTabs.delete(key); }) .catch(() => { inflightProfileTabs.delete(key); });
inflightProfileTabs.set(key, promise);}
export function getCachedProfileTab<T>(actor: string, filter: string): T | undefined { return cacheGet<T>(`profile-tab:${actor}:${filter}`);}
export function prefetchFollowers(actor: string): void { const key = `followers:${actor}`; if (cacheGet(key)) return; if (inflightProfileTabs.has(key)) return;
const promise = atprotoClient.getFollowers(actor, 50) .then((resp) => { cacheSet(key, resp); inflightProfileTabs.delete(key); }) .catch(() => { inflightProfileTabs.delete(key); });
inflightProfileTabs.set(key, promise);}
export function prefetchFollows(actor: string): void { const key = `follows:${actor}`; if (cacheGet(key)) return; if (inflightProfileTabs.has(key)) return;
const promise = atprotoClient.getFollows(actor, 50) .then((resp) => { cacheSet(key, resp); inflightProfileTabs.delete(key); }) .catch(() => { inflightProfileTabs.delete(key); });
inflightProfileTabs.set(key, promise);}
const prefetchedModules = new Set<string>();
export function prefetchModule(importFn: () => Promise<any>, key: string): void { if (prefetchedModules.has(key)) return; prefetchedModules.add(key); importFn().catch(() => { prefetchedModules.delete(key); });}