Files
eranos/src/lib/dmMessageStore.ts
T
Alex Gleason 23e55ffff7 Consolidate IndexedDB into a single 'ditto' database with multiple stores
Replace three separate per-hostname databases (nostr-nip05-cache-*,
nostr-profile-cache-*, nostr-dm-store-*) with one shared 'ditto'
database containing three object stores: nip05, profiles, messages.

A single db.ts module manages the connection and upgrade logic, and
caches the promise so only one connection is created per page lifetime.
2026-03-20 21:59:48 -05:00

95 lines
2.5 KiB
TypeScript

import type { NostrEvent } from '@nostrify/nostrify';
import { openDatabase, STORE } from '@/lib/db';
// ============================================================================
// DM Message IndexedDB Store
// ============================================================================
interface StoredParticipant {
messages: NostrEvent[];
lastActivity: number;
hasNIP4: boolean;
hasNIP17: boolean;
}
export interface MessageStore {
participants: Record<string, StoredParticipant>;
lastSync: {
nip4: number | null;
nip17: number | null;
};
}
// ============================================================================
// Database Operations
// ============================================================================
/**
* Write messages to IndexedDB for a specific user
* Messages are stored in their original encrypted form (kind 4 or kind 13)
*/
export async function writeMessagesToDB(
userPubkey: string,
messageStore: MessageStore
): Promise<void> {
try {
const db = await openDatabase();
// Store messages in their original encrypted form (no NIP-44 wrapper needed)
// Each message content is already encrypted by the sender
await db.put(STORE.MESSAGES, messageStore, userPubkey);
} catch (error) {
console.error('[MessageStore] Error writing to IndexedDB:', error);
throw error;
}
}
/**
* Read messages from IndexedDB for a specific user
* Messages are stored in their original encrypted form (kind 4 or kind 13)
*/
export async function readMessagesFromDB(
userPubkey: string
): Promise<MessageStore | undefined> {
try {
const db = await openDatabase();
const data = await db.get(STORE.MESSAGES, userPubkey);
if (!data) {
return undefined;
}
return data as MessageStore;
} catch (error) {
console.error('[MessageStore] Error reading from IndexedDB:', error);
throw error;
}
}
/**
* Delete messages from IndexedDB for a specific user
*/
export async function deleteMessagesFromDB(userPubkey: string): Promise<void> {
try {
const db = await openDatabase();
await db.delete(STORE.MESSAGES, userPubkey);
} catch (error) {
console.error('[MessageStore] Error deleting from IndexedDB:', error);
throw error;
}
}
/**
* Clear all messages from IndexedDB
*/
export async function clearAllMessages(): Promise<void> {
try {
const db = await openDatabase();
await db.clear(STORE.MESSAGES);
} catch (error) {
console.error('[MessageStore] Error clearing IndexedDB:', error);
throw error;
}
}