refactor: Update useMarket composable to utilize fetchEvents method and improve subscription handling

- Replace direct calls to fetchNotes with the new fetchEvents method in useMarket.ts for better event retrieval.
- Simplify event fetching logic by removing unnecessary filters and enhancing clarity.
- Implement individual relay subscriptions for market updates, allowing for more efficient event handling and cleanup.
This commit is contained in:
padreug 2025-08-02 17:11:23 +02:00
parent 4c31ebaaa5
commit e6607509c5
2 changed files with 90 additions and 18 deletions

View file

@ -2,6 +2,7 @@ import { ref, computed, readonly } from 'vue'
import { useNostrStore } from '@/stores/nostr'
import { useMarketStore, type Market, type Stall, type Product } from '@/stores/market'
import { config } from '@/lib/config'
import { nip19 } from 'nostr-tools'
// Nostr event kinds for market functionality
const MARKET_EVENT_KINDS = {
@ -26,7 +27,7 @@ export function useMarket() {
error.value = null
// Decode naddr
const { type, data } = window.NostrTools.nip19.decode(naddr)
const { type, data } = nip19.decode(naddr)
if (type !== 'naddr' || data.kind !== MARKET_EVENT_KINDS.MARKET) {
throw new Error('Invalid market naddr')
}
@ -70,13 +71,11 @@ export function useMarket() {
const client = nostrStore.getClient()
// Fetch market configuration event
const filters = [{
const events = await client.fetchEvents({
kinds: [MARKET_EVENT_KINDS.MARKET],
authors: [marketData.pubkey],
'#d': [marketData.d]
}]
const events = await client.fetchNotes({ filters })
})
if (events.length > 0) {
const marketEvent = events[0]
@ -103,12 +102,10 @@ export function useMarket() {
const client = nostrStore.getClient()
// Fetch stall events for this market
const filters = [{
const events = await client.fetchEvents({
kinds: [MARKET_EVENT_KINDS.STALL],
authors: [marketPubkey]
}]
const events = await client.fetchNotes({ filters })
})
events.forEach(event => {
try {
@ -145,12 +142,10 @@ export function useMarket() {
if (stallPubkeys.length === 0) return
// Fetch product events from all stalls
const filters = [{
const events = await client.fetchEvents({
kinds: [MARKET_EVENT_KINDS.PRODUCT],
authors: stallPubkeys
}]
const events = await client.fetchNotes({ filters })
})
events.forEach(event => {
try {
@ -198,12 +193,24 @@ export function useMarket() {
}
]
const unsubscribe = client.subscribeToNotes((event) => {
handleMarketEvent(event)
}, filters)
// Subscribe to each relay individually
const unsubscribes = config.market.supportedRelays.map(relay => {
const sub = client.poolInstance.subscribeMany(
[relay],
filters,
{
onevent: (event: any) => {
handleMarketEvent(event)
}
}
)
return () => sub.close()
})
// Store unsubscribe function for cleanup
return unsubscribe
// Return a function that unsubscribes from all relays
return () => {
unsubscribes.forEach(unsub => unsub())
}
} catch (err) {
console.error('Error subscribing to market updates:', err)

View file

@ -29,6 +29,10 @@ export class NostrClient {
return this._isConnected
}
get poolInstance(): SimplePool {
return this.pool
}
async connect(): Promise<void> {
try {
// Try to connect to at least one relay
@ -205,6 +209,67 @@ export class NostrClient {
}
}
/**
* Fetch events by kind
*/
async fetchEvents(options: {
kinds: number[]
authors?: string[]
limit?: number
since?: number
until?: number
'#d'?: string[]
} = {}): Promise<Event[]> {
const {
kinds,
authors,
limit = 100,
since,
until,
'#d': dTags
} = options
const filters: Filter[] = [{
kinds,
limit,
...(authors && { authors }),
...(since && { since }),
...(until && { until }),
...(dTags && { '#d': dTags })
}]
try {
const allEvents: Event[] = []
const subscription = this.pool.subscribeMany(this.relays, filters, {
onevent(event: Event) {
allEvents.push(event)
},
oneose() {
// End of stored events - subscription is complete for initial fetch
}
})
// Wait for events to be collected
await new Promise(resolve => setTimeout(resolve, 2000))
// Close the subscription
subscription.close()
// Deduplicate events by ID
const uniqueEvents = Array.from(
new Map(allEvents.map(event => [event.id, event])).values()
)
return uniqueEvents
.sort((a, b) => b.created_at - a.created_at)
.slice(0, limit)
} catch (error) {
console.error('Failed to fetch events:', error)
throw error
}
}
/**
* Fetch user profiles
*/