FollowListRepositoryImpl.ts raw

   1  import { FollowListRepository, FollowList, Pubkey, tryToFollowList } from '@/domain'
   2  import client from '@/services/client.service'
   3  import indexedDb from '@/services/indexed-db.service'
   4  import { Event as NostrEvent, kinds } from 'nostr-tools'
   5  import { RepositoryDependencies } from './types'
   6  
   7  /**
   8   * IndexedDB + Relay implementation of FollowListRepository
   9   *
  10   * Uses IndexedDB for local caching and the client service for relay fetching.
  11   * Save operations publish to relays and update the local cache.
  12   */
  13  export class FollowListRepositoryImpl implements FollowListRepository {
  14    constructor(private readonly deps: RepositoryDependencies) {}
  15  
  16    async findByOwner(pubkey: Pubkey): Promise<FollowList | null> {
  17      // Try cache first
  18      const cachedEvent = await indexedDb.getReplaceableEvent(pubkey.hex, kinds.Contacts)
  19      if (cachedEvent) {
  20        const followList = tryToFollowList(cachedEvent)
  21        if (followList) return followList
  22      }
  23  
  24      // Fetch from relays
  25      const event = await client.fetchFollowListEvent(pubkey.hex, true)
  26      if (!event) return null
  27  
  28      return tryToFollowList(event)
  29    }
  30  
  31    async save(followList: FollowList): Promise<void> {
  32      const draftEvent = followList.toDraftEvent()
  33      const publishedEvent = await this.deps.publish(draftEvent)
  34  
  35      // Update cache
  36      await indexedDb.putReplaceableEvent(publishedEvent)
  37  
  38      // Update client's follow list cache for filtering
  39      await client.updateFollowListCache(publishedEvent)
  40    }
  41  
  42    /**
  43     * Save and return the published event
  44     */
  45    async saveAndGetEvent(followList: FollowList): Promise<NostrEvent> {
  46      const draftEvent = followList.toDraftEvent()
  47      const publishedEvent = await this.deps.publish(draftEvent)
  48  
  49      await indexedDb.putReplaceableEvent(publishedEvent)
  50      await client.updateFollowListCache(publishedEvent)
  51  
  52      return publishedEvent
  53    }
  54  }
  55