webapp/src/composables/useNostrclientHub.ts

198 lines
5.5 KiB
TypeScript

import { ref, computed, onUnmounted, readonly } from 'vue'
import { nostrclientHub, type SubscriptionConfig } from '../lib/nostr/nostrclientHub'
export function useNostrclientHub() {
// Reactive state
const isConnected = ref(false)
const isConnecting = ref(false)
const connectionStatus = ref<'connecting' | 'connected' | 'disconnected' | 'error'>('disconnected')
const error = ref<Error | null>(null)
const activeSubscriptions = ref<Set<string>>(new Set())
// Reactive counts
const totalSubscriptionCount = ref(0)
const subscriptionDetails = ref<Array<{ id: string; filters: any[] }>>([])
// Computed properties
const connectionHealth = computed(() => {
return isConnected.value ? 100 : 0
})
// Initialize nostrclient hub
const initialize = async (): Promise<void> => {
try {
connectionStatus.value = 'connecting'
error.value = null
console.log('🔧 NostrclientHub: Initializing...')
await nostrclientHub.initialize()
console.log('🔧 NostrclientHub: Initialization successful')
// Set up event listeners
setupEventListeners()
connectionStatus.value = 'connected'
isConnected.value = true
console.log('🔧 NostrclientHub: Connection status set to connected')
} catch (err) {
const errorObj = err instanceof Error ? err : new Error('Failed to initialize NostrclientHub')
error.value = errorObj
connectionStatus.value = 'error'
isConnected.value = false
console.error('🔧 NostrclientHub: Failed to initialize:', errorObj)
throw errorObj
}
}
// Connect to nostrclient
const connect = async (): Promise<void> => {
try {
connectionStatus.value = 'connecting'
error.value = null
await nostrclientHub.connect()
connectionStatus.value = 'connected'
isConnected.value = true
} catch (err) {
const errorObj = err instanceof Error ? err : new Error('Failed to connect')
error.value = errorObj
connectionStatus.value = 'error'
isConnected.value = false
throw errorObj
}
}
// Disconnect from nostrclient
const disconnect = (): void => {
nostrclientHub.disconnect()
connectionStatus.value = 'disconnected'
isConnected.value = false
error.value = null
}
// Subscribe to events
const subscribe = (config: SubscriptionConfig): (() => void) => {
try {
const unsubscribe = nostrclientHub.subscribe(config)
activeSubscriptions.value.add(config.id)
// Update reactive state
totalSubscriptionCount.value = nostrclientHub.totalSubscriptionCount
subscriptionDetails.value = nostrclientHub.subscriptionDetails
return () => {
unsubscribe()
activeSubscriptions.value.delete(config.id)
totalSubscriptionCount.value = nostrclientHub.totalSubscriptionCount
subscriptionDetails.value = nostrclientHub.subscriptionDetails
}
} catch (err) {
console.error('Failed to subscribe:', err)
throw err
}
}
// Publish an event
const publishEvent = async (event: any): Promise<void> => {
try {
await nostrclientHub.publishEvent(event)
} catch (err) {
console.error('Failed to publish event:', err)
throw err
}
}
// Query events
const queryEvents = async (filters: any[]): Promise<any[]> => {
try {
return await nostrclientHub.queryEvents(filters)
} catch (err) {
console.error('Failed to query events:', err)
throw err
}
}
// Set up event listeners
const setupEventListeners = () => {
nostrclientHub.on('connected', () => {
isConnected.value = true
isConnecting.value = false
connectionStatus.value = 'connected'
error.value = null
})
nostrclientHub.on('disconnected', () => {
isConnected.value = false
isConnecting.value = false
connectionStatus.value = 'disconnected'
})
nostrclientHub.on('error', (err) => {
error.value = err
connectionStatus.value = 'error'
})
nostrclientHub.on('connectionError', (err) => {
error.value = err
connectionStatus.value = 'error'
})
nostrclientHub.on('maxReconnectionAttemptsReached', () => {
error.value = new Error('Max reconnection attempts reached')
connectionStatus.value = 'error'
})
nostrclientHub.on('event', ({ subscriptionId, event }) => {
console.log('Received event for subscription:', subscriptionId, event.id)
})
nostrclientHub.on('eose', ({ subscriptionId }) => {
console.log('EOSE received for subscription:', subscriptionId)
})
nostrclientHub.on('notice', ({ message }) => {
console.log('Notice from nostrclient:', message)
})
nostrclientHub.on('eventPublished', ({ eventId }) => {
console.log('Event published successfully:', eventId)
})
}
// Clean up event listeners
const cleanup = () => {
nostrclientHub.removeAllListeners()
}
// Auto-cleanup on unmount
onUnmounted(() => {
cleanup()
})
return {
// State
isConnected: readonly(isConnected),
isConnecting: readonly(isConnecting),
connectionStatus: readonly(connectionStatus),
error: readonly(error),
activeSubscriptions: readonly(activeSubscriptions),
totalSubscriptionCount: readonly(totalSubscriptionCount),
subscriptionDetails: readonly(subscriptionDetails),
// Computed
connectionHealth: readonly(connectionHealth),
// Methods
initialize,
connect,
disconnect,
subscribe,
publishEvent,
queryEvents,
// Internal
cleanup
}
}