3.7 KiB
Per-profile cache system
This document explains how bitvid caches profile metadata across the app, what data is stored, and when it is persisted or refreshed.
Cache layers
bitvid uses two app-wide caches plus a comment-thread cache:
- Profile metadata cache (
bitvid:profileCache:v1)- Short-lived metadata cache persisted to
localStorage. - Owned by
js/state/cache.js, surfaced viaAuthService.
- Short-lived metadata cache persisted to
- Saved profiles list (
bitvid:savedProfiles:v1)- Long-lived list of accounts authenticated in this browser.
- Stored in
localStorageand described indocs/nostr-auth.md.
- Comment thread profile cache (in-memory only)
- Per-thread cache inside
js/services/commentThreadService.js. - Seeds from the app-wide profile cache when available.
- Per-thread cache inside
Profile metadata cache (bitvid:profileCache:v1)
Storage and lifetime
- In-memory:
profileCachemap injs/state/cache.js. - Persistent:
localStoragekeybitvid:profileCache:v1. - TTL: 10 minutes (
PROFILE_CACHE_TTL_MS). - Eviction: Entries are filtered/removed on load, read, and persist when they exceed TTL.
Stored data (per pubkey)
Entries are normalized before storage and include:
namepicture(sanitized viasanitizeProfileMediaUrl)- Optional fields:
about,website,banner,lud16,lud06,lightningAddress timestamp(cache timestamp)
When it is loaded
AuthService.hydrateFromStorage() hydrates the cache at startup by calling
loadProfileCacheFromStorage() in js/state/cache.js.
When it is written
The cache is updated through AuthService.setProfileCacheEntry(), which:
- Writes the normalized entry to the cache.
- Persists it to
localStorage(unless disabled). - Syncs cached
name/pictureto the saved profiles list (if present). - Emits
profile:updatedevents for UI consumers.
Common write sources:
- Own profile load: fast relays, background refresh, or fallback in
AuthService.loadOwnProfile. - General profile fetch:
AuthService.fetchProfilewhen a relay response is received. - Batch profile hydration: utilities that call
setProfileCacheEntry(e.g., profile batch fetchers in list or thread hydration).
Cache reads
AuthService.fetchProfile short-circuits to the cache if a non-expired entry
is available and emits a profile:updated event with reason cache-hit.
Saved profiles list (bitvid:savedProfiles:v1)
The saved profiles list is the persistent “recently authenticated accounts” store and is not TTL-based. It contains auth metadata plus cached display data to keep the profile switcher responsive.
Stored data (per entry)
See docs/nostr-auth.md for the full JSON schema. At a high level, each entry
stores:
pubkey(hex)npub(optional)namepictureauthType
The payload also stores activePubkey.
Sync behavior from the profile cache
Whenever AuthService.setProfileCacheEntry writes a new profile cache entry,
it calls syncSavedProfileFromCache to update the corresponding saved profile
entry’s name and picture if the profile exists in the saved list.
Comment thread profile cache (in-memory)
CommentThreadService maintains an in-memory profileCache map scoped to the
active comment thread. It is reset on thread changes and is not persisted
to storage.
How it hydrates
- When a comment author pubkey is encountered, the thread checks the app-wide
profile cache via
getProfileCacheEntry. - If found, it is copied into the thread cache.
- If not found, the pubkey is queued for batch hydration and later written
back through the app-wide
setProfileCacheEntrycallback.
This keeps comment rendering responsive without repeatedly re-fetching metadata within a single thread session.