198 lines
5.5 KiB
TypeScript
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
|
|
}
|
|
}
|