mirror of
https://github.com/dergigi/boris.git
synced 2026-02-01 05:04:29 +01:00
feat: add caching for nostr-native articles
- Add localStorage caching for kind:30023 articles (same as web articles) - Cache TTL: 7 days - Cache key prefix: article_cache_ - Add bypassCache parameter to fetchArticleByNaddr() - Log cache hits and misses for debugging - Gracefully handle storage errors Articles are now cached locally after first fetch, making subsequent loads instant and reducing relay queries.
This commit is contained in:
@@ -1,3 +1,9 @@
|
||||
---
|
||||
alwaysApply: true
|
||||
description: nostr highlights spec and docs
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
Here's the spec for nostr-native highlights:
|
||||
|
||||
- https://github.com/nostr-protocol/nips/blob/master/84.md
|
||||
- https://nostrbook.dev/kinds/9802
|
||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -5,7 +5,7 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Boris - Nostr Bookmarks</title>
|
||||
<script type="module" crossorigin src="/assets/index-NM0sx0l9.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-BzeJHmVT.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Dljx1pJR.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -20,14 +20,72 @@ export interface ArticleContent {
|
||||
event: NostrEvent
|
||||
}
|
||||
|
||||
interface CachedArticle {
|
||||
content: ArticleContent
|
||||
timestamp: number
|
||||
}
|
||||
|
||||
const CACHE_TTL = 7 * 24 * 60 * 60 * 1000 // 7 days in milliseconds
|
||||
const CACHE_PREFIX = 'article_cache_'
|
||||
|
||||
function getCacheKey(naddr: string): string {
|
||||
return `${CACHE_PREFIX}${naddr}`
|
||||
}
|
||||
|
||||
function getFromCache(naddr: string): ArticleContent | null {
|
||||
try {
|
||||
const cacheKey = getCacheKey(naddr)
|
||||
const cached = localStorage.getItem(cacheKey)
|
||||
if (!cached) return null
|
||||
|
||||
const { content, timestamp }: CachedArticle = JSON.parse(cached)
|
||||
const age = Date.now() - timestamp
|
||||
|
||||
if (age > CACHE_TTL) {
|
||||
localStorage.removeItem(cacheKey)
|
||||
return null
|
||||
}
|
||||
|
||||
console.log('📦 Loaded article from cache:', naddr)
|
||||
return content
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function saveToCache(naddr: string, content: ArticleContent): void {
|
||||
try {
|
||||
const cacheKey = getCacheKey(naddr)
|
||||
const cached: CachedArticle = {
|
||||
content,
|
||||
timestamp: Date.now()
|
||||
}
|
||||
localStorage.setItem(cacheKey, JSON.stringify(cached))
|
||||
console.log('💾 Saved article to cache:', naddr)
|
||||
} catch (err) {
|
||||
console.warn('Failed to cache article:', err)
|
||||
// Silently fail if storage is full or unavailable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a Nostr long-form article (NIP-23) by naddr
|
||||
* @param relayPool - The relay pool to query
|
||||
* @param naddr - The article's naddr
|
||||
* @param bypassCache - If true, skip cache and fetch fresh from relays
|
||||
*/
|
||||
export async function fetchArticleByNaddr(
|
||||
relayPool: RelayPool,
|
||||
naddr: string
|
||||
naddr: string,
|
||||
bypassCache = false
|
||||
): Promise<ArticleContent> {
|
||||
try {
|
||||
// Check cache first unless bypassed
|
||||
if (!bypassCache) {
|
||||
const cached = getFromCache(naddr)
|
||||
if (cached) return cached
|
||||
}
|
||||
|
||||
// Decode the naddr
|
||||
const decoded = nip19.decode(naddr)
|
||||
|
||||
@@ -74,7 +132,7 @@ export async function fetchArticleByNaddr(
|
||||
const published = getArticlePublished(article)
|
||||
const summary = getArticleSummary(article)
|
||||
|
||||
return {
|
||||
const content: ArticleContent = {
|
||||
title,
|
||||
markdown: article.content,
|
||||
image,
|
||||
@@ -83,6 +141,11 @@ export async function fetchArticleByNaddr(
|
||||
author: article.pubkey,
|
||||
event: article
|
||||
}
|
||||
|
||||
// Save to cache before returning
|
||||
saveToCache(naddr, content)
|
||||
|
||||
return content
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch article:', err)
|
||||
throw err
|
||||
|
||||
Reference in New Issue
Block a user