{"version":3,"sources":["../src/cache-module.ts","../src/conversation.ts","../src/messenger.ts","../src/protocols/nip17.ts","../src/storage/cache-module.ts","../src/storage/memory.ts"],"sourcesContent":["import type { CacheModuleDefinition } from \"@nostr-dev-kit/ndk\";\n\n/**\n * Cache module definition for the messages package\n */\nexport const messagesCacheModule: CacheModuleDefinition = {\n    namespace: \"messages\",\n    version: 1,\n\n    collections: {\n        messages: {\n            primaryKey: \"id\",\n            indexes: [\"conversationId\", \"timestamp\", \"sender\", \"recipient\"],\n            compoundIndexes: [\n                [\"conversationId\", \"timestamp\"], // For fetching conversation messages in order\n                [\"recipient\", \"read\"], // For fetching unread messages for a user\n            ],\n            schema: {\n                id: \"string\",\n                content: \"string\",\n                sender: \"string\", // pubkey\n                recipient: \"string?\", // pubkey, optional for group messages\n                timestamp: \"number\",\n                protocol: \"string\",\n                read: \"boolean\",\n                rumor: \"object?\",\n                conversationId: \"string\",\n            },\n        },\n\n        conversations: {\n            primaryKey: \"id\",\n            indexes: [\"lastMessageAt\"],\n            compoundIndexes: [\n                [\"participants\"], // For finding conversations by participant\n            ],\n            schema: {\n                id: \"string\",\n                participants: \"string[]\", // array of pubkeys\n                name: \"string?\",\n                avatar: \"string?\",\n                lastMessageAt: \"number?\",\n                unreadCount: \"number\",\n                protocol: \"string\",\n                metadata: \"object?\",\n            },\n        },\n\n        // For future MLS support\n        mlsGroups: {\n            primaryKey: \"id\",\n            indexes: [\"createdAt\"],\n            schema: {\n                id: \"string\",\n                groupId: \"string\",\n                epoch: \"number\",\n                members: \"string[]\",\n                createdAt: \"number\",\n                updatedAt: \"number\",\n                treeHash: \"string\",\n                confirmedTranscriptHash: \"string\",\n                interimTranscriptHash: \"string\",\n                groupContext: \"string\", // serialized binary\n            },\n        },\n\n        // Track which relays are used for DMs\n        dmRelays: {\n            primaryKey: \"pubkey\",\n            indexes: [\"updatedAt\"],\n            schema: {\n                pubkey: \"string\",\n                relays: \"string[]\",\n                updatedAt: \"number\",\n            },\n        },\n    },\n\n    migrations: {\n        1: async (context) => {\n            // Initial setup - create all collections\n            await context.createCollection(\"messages\", messagesCacheModule.collections.messages);\n            await context.createCollection(\"conversations\", messagesCacheModule.collections.conversations);\n            await context.createCollection(\"mlsGroups\", messagesCacheModule.collections.mlsGroups);\n            await context.createCollection(\"dmRelays\", messagesCacheModule.collections.dmRelays);\n        },\n\n        // Future migrations would go here\n        // 2: async (context) => {\n        //     // Add new field or index\n        //     await context.addIndex('messages', 'newField');\n        // }\n    },\n};\n\n/**\n * Type definitions derived from the schema\n */\nexport interface CachedMessage {\n    id: string;\n    content: string;\n    sender: string;\n    recipient?: string;\n    timestamp: number;\n    protocol: \"nip17\" | \"mls\";\n    read: boolean;\n    rumor?: any;\n    conversationId: string;\n}\n\nexport interface CachedConversation {\n    id: string;\n    participants: string[];\n    name?: string;\n    avatar?: string;\n    lastMessageAt?: number;\n    unreadCount: number;\n    protocol: \"nip17\" | \"mls\";\n    metadata?: Record<string, any>;\n}\n\nexport interface CachedMLSGroup {\n    id: string;\n    groupId: string;\n    epoch: number;\n    members: string[];\n    createdAt: number;\n    updatedAt: number;\n    treeHash: string;\n    confirmedTranscriptHash: string;\n    interimTranscriptHash: string;\n    groupContext: string;\n}\n\nexport interface CachedDMRelay {\n    pubkey: string;\n    relays: string[];\n    updatedAt: number;\n}\n","import { NDKUser } from \"@nostr-dev-kit/ndk\";\nimport { EventEmitter } from \"eventemitter3\";\nimport type { NIP17Protocol } from \"./protocols/nip17\";\nimport type {\n    ConversationEventType,\n    ErrorEvent,\n    MessageProtocol,\n    NDKMessage,\n    StateChangeEvent,\n    StorageAdapter,\n} from \"./types\";\n\n/**\n * Represents a conversation between users.\n * Emits events for real-time updates.\n */\nexport class NDKConversation extends EventEmitter {\n    readonly id: string;\n    readonly participants: NDKUser[];\n    readonly protocol: MessageProtocol;\n    private messages: NDKMessage[] = [];\n    private storage: StorageAdapter;\n    private nip17?: NIP17Protocol;\n    private myPubkey: string;\n\n    constructor(\n        id: string,\n        participants: NDKUser[],\n        protocol: MessageProtocol,\n        storage: StorageAdapter,\n        myPubkey: string,\n        nip17?: NIP17Protocol,\n    ) {\n        super();\n        this.id = id;\n        this.participants = participants;\n        this.protocol = protocol;\n        this.storage = storage;\n        this.myPubkey = myPubkey;\n        this.nip17 = nip17;\n    }\n\n    /**\n     * Send a message in this conversation\n     */\n    async sendMessage(content: string): Promise<NDKMessage> {\n        if (this.protocol === \"nip17\" && this.nip17) {\n            // For NIP-17, send to the other participant\n            const recipient = this.participants.find((p) => p.pubkey !== this.myPubkey);\n            if (!recipient) {\n                throw new Error(\"No recipient found in conversation\");\n            }\n\n            try {\n                // Send the message\n                const wrappedEvent = await this.nip17.sendMessage(recipient, content);\n\n                // Create NDKMessage from the sent message\n                const message: NDKMessage = {\n                    id: wrappedEvent.id || \"\",\n                    content,\n                    sender: new NDKUser({ pubkey: this.myPubkey }),\n                    recipient,\n                    timestamp: Math.floor(Date.now() / 1000),\n                    protocol: \"nip17\",\n                    read: true, // Our own messages are always \"read\"\n                    conversationId: this.id,\n                };\n\n                // Save to storage\n                await this.storage.saveMessage(message);\n\n                // Add to local messages\n                this.messages.push(message);\n\n                // Emit the message event\n                this.emit(\"message\", message);\n\n                return message;\n            } catch (error) {\n                const errorEvent: ErrorEvent = {\n                    type: \"send-failed\",\n                    message: `Failed to send message: ${error}`,\n                    error: error as Error,\n                };\n                this.emit(\"error\", errorEvent);\n                throw error;\n            }\n        } else {\n            throw new Error(`Protocol ${this.protocol} not supported yet`);\n        }\n    }\n\n    /**\n     * Get messages in this conversation\n     */\n    async getMessages(limit?: number): Promise<NDKMessage[]> {\n        // Load from storage if not already loaded\n        if (this.messages.length === 0) {\n            this.messages = await this.storage.getMessages(this.id, limit);\n        }\n\n        if (limit && this.messages.length > limit) {\n            return this.messages.slice(-limit);\n        }\n\n        return [...this.messages];\n    }\n\n    /**\n     * Mark all messages as read\n     */\n    async markAsRead(): Promise<void> {\n        const unreadMessages = this.messages.filter((m) => !m.read);\n        if (unreadMessages.length > 0) {\n            const messageIds = unreadMessages.map((m) => m.id);\n            await this.storage.markAsRead(messageIds);\n\n            // Update local messages\n            unreadMessages.forEach((m) => (m.read = true));\n        }\n    }\n\n    /**\n     * Get unread count\n     */\n    getUnreadCount(): number {\n        return this.messages.filter((m) => !m.read && m.sender.pubkey !== this.myPubkey).length;\n    }\n\n    /**\n     * Get the other participant in a two-person conversation\n     */\n    getOtherParticipant(): NDKUser | undefined {\n        return this.participants.find((p) => p.pubkey !== this.myPubkey);\n    }\n\n    /**\n     * Get the last message in the conversation\n     */\n    getLastMessage(): NDKMessage | undefined {\n        return this.messages[this.messages.length - 1];\n    }\n\n    /**\n     * Handle an incoming message (called by NDKMessenger)\n     */\n    async _handleIncomingMessage(message: NDKMessage): Promise<void> {\n        // Check for duplicates\n        const exists = this.messages.find((m) => m.id === message.id);\n        if (!exists) {\n            // Add to messages\n            this.messages.push(message);\n\n            // Sort by timestamp\n            this.messages.sort((a, b) => a.timestamp - b.timestamp);\n\n            // Save to storage\n            await this.storage.saveMessage(message);\n\n            // Emit event\n            this.emit(\"message\", message);\n        }\n    }\n\n    /**\n     * Handle a state change (for future MLS support)\n     */\n    _handleStateChange(event: StateChangeEvent): void {\n        this.emit(\"state-change\", event);\n    }\n\n    /**\n     * Handle an error\n     */\n    _handleError(error: ErrorEvent): void {\n        this.emit(\"error\", error);\n    }\n\n    /**\n     * Clean up resources\n     */\n    destroy(): void {\n        this.removeAllListeners();\n        this.messages = [];\n    }\n}\n","import type NDK from \"@nostr-dev-kit/ndk\";\nimport { giftUnwrap, type NDKEvent, NDKKind, NDKRelaySet, type NDKSubscription, NDKUser } from \"@nostr-dev-kit/ndk\";\nimport { EventEmitter } from \"eventemitter3\";\nimport { NDKConversation } from \"./conversation\";\nimport { NIP17Protocol } from \"./protocols/nip17\";\nimport { CacheModuleStorage } from \"./storage/cache-module\";\nimport { MemoryAdapter } from \"./storage/memory\";\nimport type { ConversationMeta, ErrorEvent, MessengerOptions, NDKMessage, StorageAdapter } from \"./types\";\n\n/**\n * Main orchestrator class for messaging functionality.\n * Manages conversations, handles incoming messages, and coordinates protocols.\n */\nexport class NDKMessenger extends EventEmitter {\n    ndk: NDK;\n    private storage: StorageAdapter;\n    private nip17: NIP17Protocol;\n    private conversations: Map<string, NDKConversation> = new Map();\n    private subscription?: NDKSubscription;\n    myPubkey?: string;\n    private started = false;\n\n    constructor(ndk: NDK, options?: MessengerOptions) {\n        super();\n        this.ndk = ndk;\n\n        if (!ndk.signer) {\n            throw new Error(\"NDK must have a signer configured\");\n        }\n\n        // Auto-detect cache adapter if no storage provided\n        // Note: CacheModuleStorage requires the pubkey, which we'll get during start()\n        this.storage = options?.storage || new MemoryAdapter();\n\n        this.nip17 = new NIP17Protocol(ndk, ndk.signer);\n\n        if (options?.autoStart) {\n            this.start().catch(console.error);\n        }\n    }\n\n    /**\n     * Start the messenger (begin listening for messages)\n     */\n    async start(): Promise<void> {\n        if (this.started) return;\n\n        if (!this.ndk.signer) {\n            throw new Error(\"NDK signer not configured\");\n        }\n\n        const user = await this.ndk.signer.user();\n        this.myPubkey = user.pubkey;\n\n        // Upgrade to cache-based storage if NDK has a cache adapter and we're using MemoryAdapter\n        if (this.storage instanceof MemoryAdapter && this.ndk.cacheAdapter?.registerModule) {\n            this.storage = new CacheModuleStorage(this.ndk.cacheAdapter, this.myPubkey);\n        }\n\n        // Load existing conversations from storage\n        await this.loadConversations();\n\n        // Subscribe to incoming gift-wrapped messages\n        await this.subscribeToMessages();\n\n        this.started = true;\n    }\n\n    /**\n     * Stop the messenger\n     */\n    stop(): void {\n        if (this.subscription) {\n            this.subscription.stop();\n            this.subscription = undefined;\n        }\n        this.started = false;\n    }\n\n    /**\n     * Send a direct message to a user\n     */\n    async sendMessage(recipient: NDKUser, content: string): Promise<NDKMessage> {\n        if (!this.myPubkey) {\n            await this.start();\n        }\n\n        // Get or create conversation\n        const conversation = await this.getConversation(recipient);\n\n        // Send the message through the conversation\n        return conversation.sendMessage(content);\n    }\n\n    /**\n     * Get or create a conversation with a user\n     */\n    async getConversation(user: NDKUser): Promise<NDKConversation> {\n        if (!this.myPubkey) {\n            await this.start();\n        }\n\n        // Create conversation ID (sorted pubkeys)\n        const conversationId = [this.myPubkey!, user.pubkey].sort().join(\":\");\n\n        // Check if conversation exists\n        let conversation = this.conversations.get(conversationId);\n        if (conversation) {\n            return conversation;\n        }\n\n        // Create new conversation\n        conversation = new NDKConversation(\n            conversationId,\n            [new NDKUser({ pubkey: this.myPubkey! }), user],\n            \"nip17\", // Default to NIP-17 for now\n            this.storage,\n            this.myPubkey!,\n            this.nip17,\n        );\n\n        // Save conversation metadata\n        const meta: ConversationMeta = {\n            id: conversationId,\n            participants: [this.myPubkey!, user.pubkey],\n            protocol: \"nip17\",\n            unreadCount: 0,\n        };\n        await this.storage.saveConversation(meta);\n\n        // Store conversation\n        this.conversations.set(conversationId, conversation);\n\n        // Forward conversation events to messenger\n        conversation.on(\"message\", (message: NDKMessage) => {\n            this.emit(\"message\", message);\n        });\n\n        conversation.on(\"error\", (error: ErrorEvent) => {\n            this.emit(\"error\", error);\n        });\n\n        return conversation;\n    }\n\n    /**\n     * Get all conversations\n     */\n    async getConversations(): Promise<NDKConversation[]> {\n        if (!this.myPubkey) {\n            await this.start();\n        }\n\n        // Load conversations from storage if not already loaded\n        await this.loadConversations();\n\n        return Array.from(this.conversations.values());\n    }\n\n    /**\n     * Publish DM relay list (kind 10050)\n     */\n    async publishDMRelays(relays: string[]): Promise<NDKEvent> {\n        return this.nip17.publishDMRelayList(relays);\n    }\n\n    /**\n     * Load conversations from storage\n     */\n    private async loadConversations(): Promise<void> {\n        if (!this.myPubkey) return;\n\n        const metas = await this.storage.getConversations(this.myPubkey);\n\n        for (const meta of metas) {\n            // Skip if already loaded\n            if (this.conversations.has(meta.id)) {\n                continue;\n            }\n            // Create NDKUser objects for participants\n            const participants = meta.participants.map((pubkey) => new NDKUser({ pubkey }));\n\n            // Create conversation instance\n            const conversation = new NDKConversation(\n                meta.id,\n                participants,\n                meta.protocol,\n                this.storage,\n                this.myPubkey,\n                this.nip17,\n            );\n\n            // Load messages into the conversation\n            const messages = await this.storage.getMessages(meta.id);\n            for (const message of messages) {\n                // Recreate NDKUser objects for sender/recipient\n                message.sender = new NDKUser({ pubkey: message.sender.pubkey });\n                if (message.recipient) {\n                    message.recipient = new NDKUser({ pubkey: message.recipient.pubkey });\n                }\n                await conversation._handleIncomingMessage(message);\n            }\n\n            // Store conversation\n            this.conversations.set(meta.id, conversation);\n\n            // Forward events\n            conversation.on(\"message\", (message: NDKMessage) => {\n                this.emit(\"message\", message);\n            });\n\n            conversation.on(\"error\", (error: ErrorEvent) => {\n                this.emit(\"error\", error);\n            });\n        }\n    }\n\n    /**\n     * Subscribe to incoming messages\n     */\n    private async subscribeToMessages(): Promise<void> {\n        if (!this.myPubkey || !this.ndk.signer) return;\n\n        const user = await this.ndk.signer.user();\n\n        // Get the user's DM relays\n        const userRelays = await this.nip17.getUserDMRelays(user);\n\n        // Create subscription options\n        const subOptions: any = {\n            closeOnEose: false,\n        };\n\n        // Use specific relays if available\n        if (userRelays.length > 0) {\n            const relaySet = NDKRelaySet.fromRelayUrls(userRelays, this.ndk);\n            subOptions.relaySet = relaySet;\n        }\n\n        // Subscribe to gift-wrapped events (kind 1059) tagged with our pubkey\n        this.subscription = this.ndk.subscribe(\n            {\n                kinds: [NDKKind.GiftWrap],\n                \"#p\": [this.myPubkey],\n            },\n            subOptions,\n        );\n\n        this.subscription.on(\"event\", async (wrappedEvent: NDKEvent) => {\n            await this.handleIncomingMessage(wrappedEvent);\n        });\n\n        this.subscription.on(\"eose\", () => {\n            console.log(\"Messages subscription active\");\n        });\n    }\n\n    /**\n     * Handle an incoming gift-wrapped message\n     */\n    private async handleIncomingMessage(wrappedEvent: NDKEvent): Promise<void> {\n        if (!this.myPubkey || !this.ndk.signer) return;\n\n        try {\n            // Unwrap the message\n            const rumor = await this.nip17.unwrapMessage(wrappedEvent);\n            if (!rumor) return;\n\n            // Convert to NDKMessage\n            const message = this.nip17.rumorToMessage(rumor, this.myPubkey);\n\n            // Get or create conversation\n            const otherPubkey =\n                message.sender.pubkey === this.myPubkey ? message.recipient?.pubkey : message.sender.pubkey;\n\n            if (!otherPubkey) return;\n\n            const otherUser = new NDKUser({ pubkey: otherPubkey });\n            const conversation = await this.getConversation(otherUser);\n\n            // Add message to conversation\n            await conversation._handleIncomingMessage(message);\n\n            // Emit global message event\n            this.emit(\"message\", message);\n\n            // Check if this creates a new conversation\n            if (conversation.getMessages.length === 1) {\n                this.emit(\"conversation-created\", conversation);\n            }\n        } catch (error) {\n            const errorEvent: ErrorEvent = {\n                type: \"decryption-failed\",\n                message: `Failed to decrypt message: ${error}`,\n                error: error as Error,\n            };\n            this.emit(\"error\", errorEvent);\n        }\n    }\n\n    /**\n     * Clean up resources\n     */\n    destroy(): void {\n        this.stop();\n        this.conversations.forEach((conv) => conv.destroy());\n        this.conversations.clear();\n        this.removeAllListeners();\n    }\n}\n","import type NDK from \"@nostr-dev-kit/ndk\";\nimport {\n    giftUnwrap,\n    giftWrap,\n    NDKEvent,\n    NDKKind,\n    NDKRelaySet,\n    type NDKSigner,\n    NDKUser,\n    type NostrEvent,\n} from \"@nostr-dev-kit/ndk\";\nimport { getEventHash } from \"nostr-tools/pure\";\nimport type { NDKMessage } from \"../types\";\n\n/**\n * NIP-17 Protocol Handler\n * Handles gift-wrapped private direct messages\n */\nexport class NIP17Protocol {\n    constructor(\n        private ndk: NDK,\n        private signer: NDKSigner,\n    ) {}\n\n    /**\n     * Send a NIP-17 direct message\n     */\n    async sendMessage(recipient: NDKUser, content: string): Promise<NDKEvent> {\n        const sender = await this.signer.user();\n\n        // Create the rumor (unsigned kind 14 event)\n        const rumor = new NDKEvent(this.ndk);\n        rumor.kind = NDKKind.PrivateDirectMessage;\n        rumor.content = content;\n        rumor.created_at = Math.floor(Date.now() / 1000);\n        rumor.pubkey = sender.pubkey; // Must set pubkey for rumor\n        rumor.tags = [[\"p\", recipient.pubkey]];\n\n        // Gift wrap the rumor\n        const wrappedEvent = await giftWrap(rumor, recipient, this.signer);\n\n        // Get relay URLs for both sender and recipient\n        const recipientRelays = await this.getRecipientDMRelays(recipient);\n        const senderRelays = await this.getUserDMRelays(sender);\n\n        // Combine and deduplicate\n        const allRelays = [...new Set([...recipientRelays, ...senderRelays])];\n\n        // Publish to relays\n        if (allRelays.length > 0) {\n            const relaySet = NDKRelaySet.fromRelayUrls(allRelays, this.ndk);\n            await wrappedEvent.publish(relaySet);\n        } else {\n            // Fallback to all connected relays\n            await wrappedEvent.publish();\n        }\n\n        return wrappedEvent;\n    }\n\n    /**\n     * Unwrap a received gift-wrapped message\n     */\n    async unwrapMessage(wrappedEvent: NDKEvent): Promise<NostrEvent | null> {\n        try {\n            const rumor = await giftUnwrap(wrappedEvent, undefined, this.signer);\n\n            // Verify it's a kind 14 message\n            if (rumor.kind !== NDKKind.PrivateDirectMessage) {\n                return null;\n            }\n\n            return rumor.rawEvent();\n        } catch (error) {\n            console.error(\"Failed to unwrap message:\", error);\n            return null;\n        }\n    }\n\n    /**\n     * Convert a rumor event to NDKMessage format\n     */\n    rumorToMessage(rumor: NostrEvent, myPubkey: string): NDKMessage {\n        // Compute ID if not present\n        if (!rumor.id) {\n            rumor.id = getEventHash(rumor);\n        }\n\n        // Determine if this is incoming or outgoing\n        const isOutgoing = rumor.pubkey === myPubkey;\n        const otherPubkey = isOutgoing ? rumor.tags.find((t) => t[0] === \"p\")?.[1] || \"\" : rumor.pubkey;\n\n        // Create conversation ID (sorted pubkeys for consistency)\n        const conversationId = [myPubkey, otherPubkey].sort().join(\":\");\n\n        return {\n            id: rumor.id,\n            content: rumor.content || \"\",\n            sender: new NDKUser({ pubkey: rumor.pubkey }),\n            recipient: isOutgoing ? new NDKUser({ pubkey: otherPubkey }) : new NDKUser({ pubkey: myPubkey }),\n            timestamp: rumor.created_at || Math.floor(Date.now() / 1000),\n            protocol: \"nip17\",\n            read: isOutgoing, // Outgoing messages are automatically \"read\"\n            rumor,\n            conversationId,\n        };\n    }\n\n    /**\n     * Get DM relays for a recipient (kind 10050)\n     */\n    async getRecipientDMRelays(recipient: NDKUser): Promise<string[]> {\n        try {\n            // Try to fetch the recipient's DM relay list (kind 10050)\n            const dmRelayList = await this.ndk.fetchEvent({\n                kinds: [NDKKind.DirectMessageReceiveRelayList],\n                authors: [recipient.pubkey],\n            });\n\n            if (dmRelayList) {\n                const relays = dmRelayList.getMatchingTags(\"relay\").map((t) => t[1]);\n                if (relays.length > 0) {\n                    return relays;\n                }\n            }\n\n            // Fallback to general relay list (kind 10002)\n            const relayList = await this.ndk.fetchEvent({\n                kinds: [10002],\n                authors: [recipient.pubkey],\n            });\n\n            if (relayList) {\n                const relays = relayList.getMatchingTags(\"r\").map((t) => t[1]);\n                if (relays.length > 0) {\n                    return relays.slice(0, 3); // Use first 3 relays\n                }\n            }\n\n            return [];\n        } catch (error) {\n            console.error(\"Failed to fetch recipient relays:\", error);\n            return [];\n        }\n    }\n\n    /**\n     * Get DM relays for the current user (kind 10050)\n     */\n    async getUserDMRelays(user: NDKUser): Promise<string[]> {\n        try {\n            // Try to fetch the user's DM relay list (kind 10050)\n            const dmRelayList = await this.ndk.fetchEvent({\n                kinds: [NDKKind.DirectMessageReceiveRelayList],\n                authors: [user.pubkey],\n            });\n\n            if (dmRelayList) {\n                const relays = dmRelayList.getMatchingTags(\"relay\").map((t) => t[1]);\n                if (relays.length > 0) {\n                    return relays;\n                }\n            }\n\n            // Fallback to general relay list (kind 10002)\n            const relayList = await this.ndk.fetchEvent({\n                kinds: [10002],\n                authors: [user.pubkey],\n            });\n\n            if (relayList) {\n                const relays = relayList.getMatchingTags(\"r\").map((t) => t[1]);\n                if (relays.length > 0) {\n                    return relays.slice(0, 3); // Use first 3 relays\n                }\n            }\n\n            return [];\n        } catch (error) {\n            console.error(\"Failed to fetch user relays:\", error);\n            return [];\n        }\n    }\n\n    /**\n     * Publish the user's DM relay list (kind 10050)\n     */\n    async publishDMRelayList(relays: string[]): Promise<NDKEvent> {\n        const event = new NDKEvent(this.ndk);\n        event.kind = NDKKind.DirectMessageReceiveRelayList;\n        event.tags = relays.map((relay) => [\"relay\", relay]);\n        event.created_at = Math.floor(Date.now() / 1000);\n\n        await event.sign(this.signer);\n        await event.publish();\n\n        return event;\n    }\n}\n","import type { CacheModuleCollection, NDKCacheAdapter } from \"@nostr-dev-kit/ndk\";\nimport { NDKUser } from \"@nostr-dev-kit/ndk\";\nimport { type CachedConversation, type CachedMessage, messagesCacheModule } from \"../cache-module\";\nimport type { ConversationMeta, NDKMessage, StorageAdapter } from \"../types\";\n\n/**\n * Storage adapter that uses the NDK cache module system\n */\nexport class CacheModuleStorage implements StorageAdapter {\n    private messagesCollection?: CacheModuleCollection<CachedMessage>;\n    private conversationsCollection?: CacheModuleCollection<CachedConversation>;\n    private initialized = false;\n\n    constructor(\n        private cache: NDKCacheAdapter,\n        private myPubkey: string,\n    ) {}\n\n    /**\n     * Initialize the storage by registering the module and getting collections\n     */\n    private async ensureInitialized(): Promise<void> {\n        if (this.initialized) return;\n\n        // Register the module if the cache supports it\n        if (this.cache.registerModule) {\n            await this.cache.registerModule(messagesCacheModule);\n        }\n\n        // Get collections if the cache supports modules\n        if (this.cache.getModuleCollection) {\n            this.messagesCollection = await this.cache.getModuleCollection<CachedMessage>(\"messages\", \"messages\");\n            this.conversationsCollection = await this.cache.getModuleCollection<CachedConversation>(\n                \"messages\",\n                \"conversations\",\n            );\n        }\n\n        this.initialized = true;\n    }\n\n    async saveMessage(message: NDKMessage): Promise<void> {\n        await this.ensureInitialized();\n        if (!this.messagesCollection) return;\n\n        const cachedMessage: CachedMessage = {\n            id: message.id,\n            content: message.content,\n            sender: message.sender.pubkey,\n            recipient: message.recipient?.pubkey,\n            timestamp: message.timestamp,\n            protocol: message.protocol,\n            read: message.read,\n            rumor: message.rumor,\n            conversationId: message.conversationId,\n        };\n\n        await this.messagesCollection.save(cachedMessage);\n\n        // Update conversation metadata\n        await this.updateConversationForMessage(message);\n    }\n\n    private async updateConversationForMessage(message: NDKMessage): Promise<void> {\n        if (!this.conversationsCollection) return;\n\n        const conversation = await this.conversationsCollection.get(message.conversationId);\n\n        if (conversation) {\n            // Update existing conversation\n            conversation.lastMessageAt = message.timestamp;\n\n            // Update unread count if this is an incoming unread message\n            if (!message.read && message.sender.pubkey !== this.myPubkey) {\n                conversation.unreadCount++;\n            }\n\n            await this.conversationsCollection.save(conversation);\n        } else {\n            // Create new conversation\n            const participants = [message.sender.pubkey];\n            if (message.recipient) {\n                participants.push(message.recipient.pubkey);\n            }\n\n            const newConversation: CachedConversation = {\n                id: message.conversationId,\n                participants: [...new Set(participants)], // Deduplicate\n                lastMessageAt: message.timestamp,\n                unreadCount: !message.read && message.sender.pubkey !== this.myPubkey ? 1 : 0,\n                protocol: message.protocol,\n            };\n\n            await this.conversationsCollection.save(newConversation);\n        }\n    }\n\n    async getMessages(conversationId: string, limit?: number): Promise<NDKMessage[]> {\n        await this.ensureInitialized();\n        if (!this.messagesCollection) return [];\n\n        // Find messages for this conversation, sorted by timestamp\n        const cachedMessages = await this.messagesCollection.findBy(\"conversationId\", conversationId);\n\n        // Sort by timestamp\n        cachedMessages.sort((a, b) => a.timestamp - b.timestamp);\n\n        // Apply limit if specified\n        let messages = cachedMessages;\n        if (limit && messages.length > limit) {\n            messages = messages.slice(-limit);\n        }\n\n        // Convert back to NDKMessage format\n        return messages.map((cached) => ({\n            id: cached.id,\n            content: cached.content,\n            sender: new NDKUser({ pubkey: cached.sender }),\n            recipient: cached.recipient ? new NDKUser({ pubkey: cached.recipient }) : undefined,\n            timestamp: cached.timestamp,\n            protocol: cached.protocol,\n            read: cached.read,\n            rumor: cached.rumor,\n            conversationId: cached.conversationId,\n        }));\n    }\n\n    async markAsRead(messageIds: string[]): Promise<void> {\n        await this.ensureInitialized();\n        if (!this.messagesCollection || !this.conversationsCollection) return;\n\n        // Update each message\n        for (const id of messageIds) {\n            const message = await this.messagesCollection.get(id);\n            if (message && !message.read) {\n                message.read = true;\n                await this.messagesCollection.save(message);\n\n                // Update conversation unread count\n                const conversation = await this.conversationsCollection.get(message.conversationId);\n                if (conversation && conversation.unreadCount > 0) {\n                    conversation.unreadCount--;\n                    await this.conversationsCollection.save(conversation);\n                }\n            }\n        }\n    }\n\n    async getConversations(userId: string): Promise<ConversationMeta[]> {\n        await this.ensureInitialized();\n        if (!this.conversationsCollection) return [];\n\n        // Get all conversations\n        const allConversations = await this.conversationsCollection.all();\n\n        // Filter for conversations that include this user\n        const userConversations = allConversations.filter((conv) => conv.participants.includes(userId));\n\n        // Sort by last message timestamp (most recent first)\n        userConversations.sort((a, b) => (b.lastMessageAt || 0) - (a.lastMessageAt || 0));\n\n        // Convert to ConversationMeta format\n        return userConversations.map((conv) => ({\n            id: conv.id,\n            participants: conv.participants,\n            name: conv.name,\n            avatar: conv.avatar,\n            lastMessageAt: conv.lastMessageAt,\n            unreadCount: conv.unreadCount,\n        }));\n    }\n\n    async saveConversation(conversation: ConversationMeta): Promise<void> {\n        await this.ensureInitialized();\n        if (!this.conversationsCollection) return;\n\n        const cachedConversation: CachedConversation = {\n            id: conversation.id,\n            participants: conversation.participants,\n            name: conversation.name,\n            avatar: conversation.avatar,\n            lastMessageAt: conversation.lastMessageAt,\n            unreadCount: conversation.unreadCount,\n            protocol: \"nip17\", // Default for now\n        };\n\n        await this.conversationsCollection.save(cachedConversation);\n    }\n\n    async deleteMessage(messageId: string): Promise<void> {\n        await this.ensureInitialized();\n        if (!this.messagesCollection) return;\n\n        const message = await this.messagesCollection.get(messageId);\n        if (message) {\n            // Update conversation unread count if needed\n            if (!message.read && this.conversationsCollection) {\n                const conversation = await this.conversationsCollection.get(message.conversationId);\n                if (conversation && conversation.unreadCount > 0) {\n                    conversation.unreadCount--;\n                    await this.conversationsCollection.save(conversation);\n                }\n            }\n\n            // Delete the message\n            await this.messagesCollection.delete(messageId);\n        }\n    }\n\n    async clear(): Promise<void> {\n        await this.ensureInitialized();\n\n        if (this.messagesCollection) {\n            await this.messagesCollection.clear();\n        }\n\n        if (this.conversationsCollection) {\n            await this.conversationsCollection.clear();\n        }\n    }\n}\n","import type { ConversationMeta, NDKMessage, StorageAdapter } from \"../types\";\n\n/**\n * In-memory storage adapter for messages and conversations.\n * Data is lost when the application restarts.\n */\nexport class MemoryAdapter implements StorageAdapter {\n    private messages: Map<string, NDKMessage> = new Map();\n    private conversations: Map<string, ConversationMeta> = new Map();\n    private messagesByConversation: Map<string, Set<string>> = new Map();\n\n    async saveMessage(message: NDKMessage): Promise<void> {\n        // Store the message\n        this.messages.set(message.id, message);\n\n        // Add to conversation index\n        if (!this.messagesByConversation.has(message.conversationId)) {\n            this.messagesByConversation.set(message.conversationId, new Set());\n        }\n        this.messagesByConversation.get(message.conversationId)!.add(message.id);\n\n        // Update conversation metadata\n        const conversation = this.conversations.get(message.conversationId);\n        if (conversation) {\n            conversation.lastMessageAt = message.timestamp;\n            if (!message.read) {\n                conversation.unreadCount++;\n            }\n        }\n    }\n\n    async getMessages(conversationId: string, limit?: number): Promise<NDKMessage[]> {\n        const messageIds = this.messagesByConversation.get(conversationId);\n        if (!messageIds) {\n            return [];\n        }\n\n        const messages: NDKMessage[] = [];\n        for (const id of messageIds) {\n            const message = this.messages.get(id);\n            if (message) {\n                messages.push(message);\n            }\n        }\n\n        // Sort by timestamp\n        messages.sort((a, b) => a.timestamp - b.timestamp);\n\n        // Apply limit if specified\n        if (limit && messages.length > limit) {\n            return messages.slice(-limit);\n        }\n\n        return messages;\n    }\n\n    async markAsRead(messageIds: string[]): Promise<void> {\n        for (const id of messageIds) {\n            const message = this.messages.get(id);\n            if (message) {\n                const wasUnread = !message.read;\n                message.read = true;\n\n                // Update conversation unread count\n                if (wasUnread) {\n                    const conversation = this.conversations.get(message.conversationId);\n                    if (conversation && conversation.unreadCount > 0) {\n                        conversation.unreadCount--;\n                    }\n                }\n            }\n        }\n    }\n\n    async getConversations(userId: string): Promise<ConversationMeta[]> {\n        const userConversations: ConversationMeta[] = [];\n\n        for (const conversation of this.conversations.values()) {\n            if (conversation.participants.includes(userId)) {\n                userConversations.push({ ...conversation });\n            }\n        }\n\n        // Sort by last message timestamp\n        userConversations.sort((a, b) => (b.lastMessageAt || 0) - (a.lastMessageAt || 0));\n\n        return userConversations;\n    }\n\n    async saveConversation(conversation: ConversationMeta): Promise<void> {\n        this.conversations.set(conversation.id, { ...conversation });\n    }\n\n    async deleteMessage(messageId: string): Promise<void> {\n        const message = this.messages.get(messageId);\n        if (message) {\n            // Remove from conversation index\n            const messageIds = this.messagesByConversation.get(message.conversationId);\n            if (messageIds) {\n                messageIds.delete(messageId);\n            }\n\n            // Update conversation unread count if necessary\n            if (!message.read) {\n                const conversation = this.conversations.get(message.conversationId);\n                if (conversation && conversation.unreadCount > 0) {\n                    conversation.unreadCount--;\n                }\n            }\n\n            // Delete the message\n            this.messages.delete(messageId);\n        }\n    }\n\n    async clear(): Promise<void> {\n        this.messages.clear();\n        this.conversations.clear();\n        this.messagesByConversation.clear();\n    }\n\n    /**\n     * Get a single message by ID (helper method)\n     */\n    async getMessage(messageId: string): Promise<NDKMessage | undefined> {\n        return this.messages.get(messageId);\n    }\n\n    /**\n     * Check if a message exists (helper method for deduplication)\n     */\n    async hasMessage(messageId: string): Promise<boolean> {\n        return this.messages.has(messageId);\n    }\n}\n"],"mappings":"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","names":["NDKKind","NDKRelaySet","NDKUser","EventEmitter","NDKUser","NDKUser","NDKUser","EventEmitter","NDKUser","NDKRelaySet","NDKKind"]}