supermemory/apps/web/lib/file-cache.ts
ishaanxgupta 70955480fd implement Nova chat attachments on the web side (#1004)
- Added attachment draft/shared types and validation in components/chat/attachments.ts.
- Added paperclip upload UI to Nova composer with file chips, size/status, remove, retry, and per-file Save / Chat only toggle.
- Wired uploads before send to /chat/attachments, then sends returned attachment references in chat message metadata.
- Preserved attachment metadata when loading threads and rendered attachment chips on user messages.
- Added attachment support from the home composer into the full chat view.
- Extended chat analytics with attachment counts.

<img width="1905" height="900" alt="image" src="https://github.com/user-attachments/assets/631001b8-7c68-4015-b36b-06c69cdad271" />
<img width="1323" height="1600" alt="image" src="https://github.com/user-attachments/assets/77eee08a-b235-41eb-b03a-f406b81b46e7" />

- ensured responsiveness
2026-06-08 06:18:28 +00:00

51 lines
1 KiB
TypeScript

import { createStore, get, set, del } from "idb-keyval"
const fileCacheStore = createStore("supermemory-file-cache", "blobs")
interface CachedFile {
blob: Blob
mimeType: string
}
export async function cacheFileBlob(
documentId: string,
blob: Blob,
mimeType: string,
): Promise<void> {
try {
await set(
documentId,
{ blob, mimeType } satisfies CachedFile,
fileCacheStore,
)
} catch {
// Storage full or unavailable — non-critical, skip silently
}
}
export async function getCachedFileBlob(
documentId: string,
): Promise<Blob | null> {
try {
const cached = await get<CachedFile>(documentId, fileCacheStore)
return cached?.blob ?? null
} catch {
return null
}
}
export async function getCachedFileUrl(
documentId: string,
): Promise<string | null> {
const blob = await getCachedFileBlob(documentId)
if (!blob) return null
return URL.createObjectURL(blob)
}
export async function removeCachedFile(documentId: string): Promise<void> {
try {
await del(documentId, fileCacheStore)
} catch {
// non-critical
}
}