notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

subscriptions.rs (2730B)


      1 //! Local nostrdb subscription management for nostrverse rooms.
      2 //!
      3 //! Subscribes to room events (kind 37555) and presence events (kind 10555)
      4 //! in the local nostrdb and polls for updates each frame.
      5 
      6 use nostrdb::{Filter, Ndb, Note, Subscription, Transaction};
      7 
      8 use crate::kinds;
      9 
     10 /// A local nostrdb subscription that polls for notes of a given kind.
     11 struct KindSubscription {
     12     sub: Subscription,
     13 }
     14 
     15 impl KindSubscription {
     16     fn new(ndb: &Ndb, kind: u16) -> Self {
     17         let filter = Filter::new().kinds([kind as u64]).build();
     18         let sub = ndb.subscribe(&[filter]).expect("kind subscription");
     19         Self { sub }
     20     }
     21 
     22     fn poll<'a>(&self, ndb: &'a Ndb, txn: &'a Transaction) -> Vec<Note<'a>> {
     23         ndb.poll_for_notes(self.sub, 50)
     24             .into_iter()
     25             .filter_map(|nk| ndb.get_note_by_key(txn, nk).ok())
     26             .collect()
     27     }
     28 }
     29 
     30 /// Manages a local nostrdb subscription for room events.
     31 pub struct RoomSubscription {
     32     inner: KindSubscription,
     33 }
     34 
     35 impl RoomSubscription {
     36     /// Subscribe to all room events (kind 37555) in the local nostrdb.
     37     pub fn new(ndb: &Ndb) -> Self {
     38         Self {
     39             inner: KindSubscription::new(ndb, kinds::ROOM),
     40         }
     41     }
     42 
     43     /// Subscribe to room events from a specific author.
     44     #[allow(dead_code)]
     45     pub fn for_author(ndb: &Ndb, author: &[u8; 32]) -> Self {
     46         let filter = Filter::new()
     47             .kinds([kinds::ROOM as u64])
     48             .authors([author])
     49             .build();
     50         let sub = ndb.subscribe(&[filter]).expect("room subscription");
     51         Self {
     52             inner: KindSubscription { sub },
     53         }
     54     }
     55 
     56     /// Poll for new room events. Returns parsed notes.
     57     pub fn poll<'a>(&self, ndb: &'a Ndb, txn: &'a Transaction) -> Vec<Note<'a>> {
     58         self.inner.poll(ndb, txn)
     59     }
     60 
     61     /// Query for existing room events (e.g. on startup).
     62     pub fn query_existing<'a>(ndb: &'a Ndb, txn: &'a Transaction) -> Vec<Note<'a>> {
     63         let filter = Filter::new().kinds([kinds::ROOM as u64]).limit(50).build();
     64         ndb.query(txn, &[filter], 50)
     65             .unwrap_or_default()
     66             .into_iter()
     67             .map(|qr| qr.note)
     68             .collect()
     69     }
     70 }
     71 
     72 /// Manages a local nostrdb subscription for presence events (kind 10555).
     73 pub struct PresenceSubscription {
     74     inner: KindSubscription,
     75 }
     76 
     77 impl PresenceSubscription {
     78     /// Subscribe to presence events in the local nostrdb.
     79     pub fn new(ndb: &Ndb) -> Self {
     80         Self {
     81             inner: KindSubscription::new(ndb, kinds::PRESENCE),
     82         }
     83     }
     84 
     85     /// Poll for new presence events.
     86     pub fn poll<'a>(&self, ndb: &'a Ndb, txn: &'a Transaction) -> Vec<Note<'a>> {
     87         self.inner.poll(ndb, txn)
     88     }
     89 }