feat: Integrate Relay Hub for centralized Nostr connection management
- Introduce a new composable, useRelayHub, to manage all Nostr WebSocket connections, enhancing connection stability and performance. - Update existing components and composables to utilize the Relay Hub for connecting, publishing events, and subscribing to updates, streamlining the overall architecture. - Add a RelayHubStatus component to display connection status and health metrics, improving user feedback on the connection state. - Implement a RelayHubDemo page to showcase the functionality of the Relay Hub, including connection tests and subscription management. - Ensure proper error handling and logging throughout the integration process to facilitate debugging and user experience.
This commit is contained in:
parent
df7e461c91
commit
7d7bee8e77
14 changed files with 1982 additions and 955 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { ref, readonly } from 'vue'
|
||||
import type { NostrNote } from '@/lib/nostr/client'
|
||||
import { useNostr } from '@/composables/useNostr'
|
||||
import { useRelayHub } from '@/composables/useRelayHub'
|
||||
import { useNostrStore } from '@/stores/nostr'
|
||||
import { config as globalConfig } from '@/lib/config'
|
||||
import { notificationManager } from '@/lib/notifications/manager'
|
||||
|
|
@ -13,7 +13,7 @@ export interface NostrFeedConfig {
|
|||
}
|
||||
|
||||
export function useNostrFeed(config: NostrFeedConfig = {}) {
|
||||
const { getClient } = useNostr(config.relays ? { relays: config.relays } : undefined)
|
||||
const relayHub = useRelayHub()
|
||||
const nostrStore = useNostrStore()
|
||||
|
||||
// State
|
||||
|
|
@ -71,17 +71,16 @@ export function useNostrFeed(config: NostrFeedConfig = {}) {
|
|||
|
||||
error.value = null
|
||||
|
||||
// Connect to Nostr
|
||||
const client = getClient()
|
||||
await client.connect()
|
||||
isConnected.value = client.isConnected
|
||||
// Connect to Nostr using the centralized relay hub
|
||||
await relayHub.connect()
|
||||
isConnected.value = relayHub.isConnected.value
|
||||
|
||||
if (!isConnected.value) {
|
||||
throw new Error('Failed to connect to Nostr relays')
|
||||
}
|
||||
|
||||
// Configure fetch options based on feed type
|
||||
const fetchOptions: Parameters<typeof client.fetchNotes>[0] = {
|
||||
const fetchOptions: any = {
|
||||
limit: config.limit || 50,
|
||||
includeReplies: config.includeReplies || false
|
||||
}
|
||||
|
|
@ -96,8 +95,14 @@ export function useNostrFeed(config: NostrFeedConfig = {}) {
|
|||
}
|
||||
}
|
||||
|
||||
// Fetch new notes
|
||||
const newNotes = await client.fetchNotes(fetchOptions)
|
||||
// Fetch new notes using the relay hub
|
||||
const newNotes = await relayHub.queryEvents([
|
||||
{
|
||||
kinds: [1], // TEXT_NOTE
|
||||
limit: fetchOptions.limit,
|
||||
authors: fetchOptions.authors
|
||||
}
|
||||
])
|
||||
|
||||
// Client-side filtering for 'general' feed (exclude admin posts)
|
||||
let filteredNotes = newNotes
|
||||
|
|
@ -147,35 +152,37 @@ export function useNostrFeed(config: NostrFeedConfig = {}) {
|
|||
|
||||
const subscribeToFeedUpdates = () => {
|
||||
try {
|
||||
const client = getClient()
|
||||
|
||||
// Subscribe to real-time notes
|
||||
unsubscribe = client.subscribeToNotes((newNote) => {
|
||||
// Only process notes newer than last seen
|
||||
if (newNote.created_at > lastSeenTimestamp) {
|
||||
// Check if note should be included based on feed type
|
||||
const shouldInclude = shouldIncludeNote(newNote)
|
||||
if (shouldInclude) {
|
||||
// Add to beginning of notes array
|
||||
notes.value.unshift(newNote)
|
||||
|
||||
// Limit the array size to prevent memory issues
|
||||
if (notes.value.length > 100) {
|
||||
notes.value = notes.value.slice(0, 100)
|
||||
}
|
||||
// Subscribe to real-time notes using the relay hub
|
||||
unsubscribe = relayHub.subscribe({
|
||||
id: `feed-${config.feedType || 'all'}`,
|
||||
filters: [{ kinds: [1] }], // TEXT_NOTE
|
||||
onEvent: (event: any) => {
|
||||
// Only process notes newer than last seen
|
||||
if (event.created_at > lastSeenTimestamp) {
|
||||
// Check if note should be included based on feed type
|
||||
const shouldInclude = shouldIncludeNote(event)
|
||||
if (shouldInclude) {
|
||||
// Add to beginning of notes array
|
||||
notes.value.unshift(event)
|
||||
|
||||
// Limit the array size to prevent memory issues
|
||||
if (notes.value.length > 100) {
|
||||
notes.value = notes.value.slice(0, 100)
|
||||
}
|
||||
|
||||
// Save to localStorage
|
||||
const storageKey = `nostr-feed-${config.feedType || 'all'}`
|
||||
localStorage.setItem(storageKey, JSON.stringify(notes.value))
|
||||
// Save to localStorage
|
||||
const storageKey = `nostr-feed-${config.feedType || 'all'}`
|
||||
localStorage.setItem(storageKey, JSON.stringify(notes.value))
|
||||
}
|
||||
|
||||
// Send notification if appropriate (only for admin announcements when not in announcements feed)
|
||||
if (config.feedType !== 'announcements' && adminPubkeys.includes(event.pubkey)) {
|
||||
notificationManager.notifyForNote(event, nostrStore.account?.pubkey)
|
||||
}
|
||||
|
||||
// Update last seen timestamp
|
||||
lastSeenTimestamp = Math.max(lastSeenTimestamp, event.created_at)
|
||||
}
|
||||
|
||||
// Send notification if appropriate (only for admin announcements when not in announcements feed)
|
||||
if (config.feedType !== 'announcements' && adminPubkeys.includes(newNote.pubkey)) {
|
||||
notificationManager.notifyForNote(newNote, nostrStore.account?.pubkey)
|
||||
}
|
||||
|
||||
// Update last seen timestamp
|
||||
lastSeenTimestamp = Math.max(lastSeenTimestamp, newNote.created_at)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
|
|
@ -197,9 +204,8 @@ export function useNostrFeed(config: NostrFeedConfig = {}) {
|
|||
const connectToFeed = async () => {
|
||||
try {
|
||||
console.log('Connecting to Nostr feed...')
|
||||
const client = getClient()
|
||||
await client.connect()
|
||||
isConnected.value = client.isConnected
|
||||
await relayHub.connect()
|
||||
isConnected.value = relayHub.isConnected.value
|
||||
console.log('Connected to Nostr feed')
|
||||
} catch (err) {
|
||||
console.error('Error connecting to feed:', err)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue