mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
3.7 KiB
3.7 KiB
NostrClient Overview
The NostrClient class in js/nostr/client.js is the central controller for all Nostr protocol interactions in the application. It handles connection management, event publishing, state synchronization, and caching.
Key Responsibilities
- Connection Management: Maintains a pool of connections to Nostr relays (
SimplePool). - State Management:
allEvents: A raw map of all fetched events, useful for history.activeMap: A "materialized view" containing only the latest version of each video (deduplicated byvideoRootIdordtag).tombstones: Tracks deleted events to prevent them from reappearing if an old relay broadcasts them.
- Event Publishing: Handles signing and broadcasting events (Kind 30078 video posts, Kind 1 metadata, etc.).
- Buffering: Implements a buffering strategy for incoming events to optimize UI rendering performance.
- Caching: Uses
EventsCacheStore(IndexedDB + localStorage) to persist state across sessions for instant load times. - Signer Abstraction: Manages different signing methods (NIP-07 extension, NIP-46 remote signer, local keys).
Core Concepts
Eventual Consistency & activeMap
Nostr is a decentralized protocol where events can arrive out of order or be duplicated across relays. The activeMap is critical for presenting a consistent view to the user.
- Logic: When a new event arrives,
activeMaponly updates if the new event has a newercreated_attimestamp than the existing entry for thatvideoRootId(ordtag). - Deletions: If an event is deleted (Kind 5 or explicit
deleted: trueflag), a "tombstone" is recorded. Future events with a timestamp older than the tombstone are ignored.
Buffering Strategy (subscribeVideos)
To prevent the UI from freezing when thousands of events arrive during the initial connection:
- Incoming events are pushed into an
eventBuffer. - A debounced flush function processes the buffer every ~75ms.
- Events are processed in batches: validation, deduplication, and state updates happen in bulk.
- The UI is notified only once per batch.
Caching (EventsCacheStore)
The client attempts to restore state immediately on load ("Stale-While-Revalidate"):
- Restore:
restoreLocalDatareads from IndexedDB (or localStorage fallback). - Display: The UI renders cached content immediately.
- Fetch: The client connects to relays and fetches new events, updating the UI as they arrive.
- Persist: The
EventsCacheStoreperiodically saves the current state to disk, using fingerprints to avoid unnecessary writes.
Common Workflows
1. Publishing a Video
publishVideo(videoPayload, pubkey)
- Constructs the video metadata (Kind 30078).
- Signs the event using the active signer.
- Publishes to configured relays.
- Side Effects:
- If a hosted URL is present, publishes a NIP-94 mirror event (Kind 1063).
- If NIP-71 categorization tags are present, publishes a wrapper event (Kind 22).
2. Loading the Feed
subscribeVideos(onVideo, options)
- Checks cache for the latest timestamp.
- Subscribes to relays with
sincefilter (if cached) or full history. - Buffers incoming events.
- Updates
activeMapand callsonVideofor valid updates.
When to Modify
- New Event Kinds: If adding support for a new NIP or event type, add handlers here.
- Performance Tuning: Adjust buffering timeouts or cache policies in
EventsCacheStoreif UI responsiveness issues arise. - Signer Logic: If modifying how keys are handled (e.g., adding a new wallet adapter), update
signerHelpers.jsornip46Client.js, but ensureNostrClientintegrates it correctly.