153 lines
3.8 KiB
Markdown
153 lines
3.8 KiB
Markdown
# Patterns de subscription Nostr
|
|
|
|
**Date** : 2024-12-19
|
|
**Auteur** : Équipe 4NK
|
|
|
|
## Introduction
|
|
|
|
Ce document décrit les patterns à utiliser pour créer des subscriptions Nostr avec rotation de relais et gestion des événements.
|
|
|
|
## Pattern recommandé : Utilisation de createSyncSubscription
|
|
|
|
### Subscription simple avec relay rotation
|
|
|
|
```typescript
|
|
import { createSyncSubscription } from '@/lib/helpers/syncSubscriptionHelper'
|
|
import type { SimplePoolWithSub } from '@/types/nostr-tools-extended'
|
|
import type { Filter } from 'nostr-tools'
|
|
|
|
async function fetchEvents(
|
|
pool: SimplePoolWithSub,
|
|
filters: Filter[]
|
|
): Promise<Event[]> {
|
|
const result = await createSyncSubscription({
|
|
pool,
|
|
filters,
|
|
timeout: 10000,
|
|
})
|
|
|
|
return result.events
|
|
}
|
|
```
|
|
|
|
### Subscription avec filtrage d'événements
|
|
|
|
```typescript
|
|
const result = await createSyncSubscription({
|
|
pool,
|
|
filters,
|
|
eventFilter: (event: Event): boolean => {
|
|
const tags = extractTagsFromEvent(event)
|
|
return tags.type === 'publication' && !tags.hidden
|
|
},
|
|
timeout: 10000,
|
|
})
|
|
```
|
|
|
|
### Subscription avec callbacks
|
|
|
|
```typescript
|
|
const result = await createSyncSubscription({
|
|
pool,
|
|
filters,
|
|
onEvent: (event: Event): void => {
|
|
console.log('Received event:', event.id)
|
|
// Traitement immédiat si nécessaire
|
|
},
|
|
onComplete: async (events: Event[]): Promise<void> => {
|
|
console.log(`Received ${events.length} events`)
|
|
// Traitement final de tous les événements
|
|
},
|
|
timeout: 10000,
|
|
})
|
|
```
|
|
|
|
### Subscription avec mise à jour du progrès
|
|
|
|
```typescript
|
|
const result = await createSyncSubscription({
|
|
pool,
|
|
filters,
|
|
updateProgress: (relayUrl: string): void => {
|
|
// Mise à jour personnalisée du progrès
|
|
console.log('Using relay:', relayUrl)
|
|
},
|
|
timeout: 10000,
|
|
})
|
|
```
|
|
|
|
## Gestion des erreurs
|
|
|
|
Les erreurs de subscription sont gérées automatiquement :
|
|
- Rotation automatique vers le relais suivant en cas d'échec
|
|
- Fallback vers le relais principal si tous les relais échouent
|
|
- Timeout automatique après le délai spécifié
|
|
|
|
```typescript
|
|
try {
|
|
const result = await createSyncSubscription({
|
|
pool,
|
|
filters,
|
|
timeout: 10000,
|
|
})
|
|
// Traiter les événements
|
|
} catch (error) {
|
|
console.error('Subscription failed:', error)
|
|
// Gérer l'erreur
|
|
}
|
|
```
|
|
|
|
## Bonnes pratiques
|
|
|
|
1. **Toujours utiliser createSyncSubscription** : Ne pas créer de code de subscription personnalisé
|
|
2. **Définir un timeout approprié** : Par défaut 10 secondes, ajuster selon le contexte
|
|
3. **Filtrer les événements** : Utiliser `eventFilter` pour éviter de traiter des événements non pertinents
|
|
4. **Gérer les callbacks** : Utiliser `onEvent` pour traitement immédiat, `onComplete` pour traitement final
|
|
5. **Mise à jour du progrès** : Utiliser `updateProgress` pour informer l'utilisateur
|
|
|
|
## Exemples complets
|
|
|
|
### Synchronisation de publications
|
|
|
|
```typescript
|
|
import { createSyncSubscription } from '@/lib/helpers/syncSubscriptionHelper'
|
|
import { buildTagFilter } from '@/lib/nostrTagSystemFilter'
|
|
import { PLATFORM_SERVICE } from '@/lib/platformConfig'
|
|
import { extractTagsFromEvent } from '@/lib/nostrTagSystem'
|
|
|
|
async function syncPublications(
|
|
pool: SimplePoolWithSub,
|
|
authorPubkey: string
|
|
): Promise<void> {
|
|
const { getLastSyncDate } = await import('./syncStorage')
|
|
const lastSyncDate = await getLastSyncDate()
|
|
|
|
const filters = [
|
|
{
|
|
...buildTagFilter({
|
|
type: 'publication',
|
|
authorPubkey,
|
|
service: PLATFORM_SERVICE,
|
|
}),
|
|
since: lastSyncDate,
|
|
limit: 1000,
|
|
},
|
|
]
|
|
|
|
const result = await createSyncSubscription({
|
|
pool,
|
|
filters,
|
|
eventFilter: (event: Event): boolean => {
|
|
const tags = extractTagsFromEvent(event)
|
|
return tags.type === 'publication' && !tags.hidden
|
|
},
|
|
timeout: 10000,
|
|
})
|
|
|
|
// Traiter les événements
|
|
for (const event of result.events) {
|
|
// ...
|
|
}
|
|
}
|
|
```
|