8 changed files with 268 additions and 26 deletions
@ -0,0 +1,88 @@
@@ -0,0 +1,88 @@
|
||||
/** |
||||
* Markdown rendering cache with IndexedDB persistence |
||||
*/ |
||||
|
||||
import { getDB } from './indexeddb-store.js'; |
||||
|
||||
export interface CachedMarkdown { |
||||
hash: string; |
||||
rendered: string; |
||||
cached_at: number; |
||||
} |
||||
|
||||
/** |
||||
* Simple hash function for content (djb2 algorithm) |
||||
*/ |
||||
function hashContent(content: string): string { |
||||
let hash = 5381; |
||||
for (let i = 0; i < content.length; i++) { |
||||
hash = ((hash << 5) + hash) + content.charCodeAt(i); |
||||
} |
||||
return hash.toString(36); |
||||
} |
||||
|
||||
/** |
||||
* Get cached rendered markdown |
||||
*/ |
||||
export async function getCachedMarkdown(content: string): Promise<string | null> { |
||||
try { |
||||
const hash = hashContent(content); |
||||
const db = await getDB(); |
||||
const cached = await db.get('markdown', hash) as CachedMarkdown | undefined; |
||||
|
||||
if (cached) { |
||||
// Check if cache is still valid (30 days TTL)
|
||||
const maxAge = 30 * 24 * 60 * 60 * 1000; // 30 days
|
||||
if (Date.now() - cached.cached_at < maxAge) { |
||||
return cached.rendered; |
||||
} |
||||
// Cache expired, delete it
|
||||
await db.delete('markdown', hash); |
||||
} |
||||
|
||||
return null; |
||||
} catch (error) { |
||||
console.debug('Error getting cached markdown:', error); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Cache rendered markdown |
||||
*/ |
||||
export async function cacheMarkdown(content: string, rendered: string): Promise<void> { |
||||
try { |
||||
const hash = hashContent(content); |
||||
const db = await getDB(); |
||||
const cached: CachedMarkdown = { |
||||
hash, |
||||
rendered, |
||||
cached_at: Date.now() |
||||
}; |
||||
await db.put('markdown', cached); |
||||
} catch (error) { |
||||
console.debug('Error caching markdown:', error); |
||||
// Don't throw - caching failures shouldn't break the app
|
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Clear old markdown cache entries (older than specified timestamp) |
||||
*/ |
||||
export async function clearOldMarkdownCache(olderThan: number): Promise<void> { |
||||
try { |
||||
const db = await getDB(); |
||||
const tx = db.transaction('markdown', 'readwrite'); |
||||
const index = tx.store.index('cached_at'); |
||||
|
||||
for await (const cursor of index.iterate()) { |
||||
if (cursor.value.cached_at < olderThan) { |
||||
await cursor.delete(); |
||||
} |
||||
} |
||||
|
||||
await tx.done; |
||||
} catch (error) { |
||||
console.debug('Error clearing old markdown cache:', error); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue