story-research-zapwall/docs/patterns/subscription-patterns.md
2026-01-07 11:00:13 +01:00

3.8 KiB

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

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

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

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

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é
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

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) {
    // ...
  }
}