peermerge 0.0.3

Manage JSON-like documents with multiple writers, without a central authority, using a P2P protocol
Documentation
use automerge::Patch;

use crate::{DocumentId, FeedDiscoveryKey, PeerId};

use super::state::{ChildDocumentInfo, DocumentFeedInfo};

/// State event from a document
#[derive(Clone, Debug)]
pub struct StateEvent {
    /// ID of the document this event is about
    pub document_id: DocumentId,
    /// Content of the event
    pub content: StateEventContent,
}

impl StateEvent {
    /// Create a new StateEvent
    pub fn new(document_id: [u8; 32], content: StateEventContent) -> Self {
        Self {
            document_id,
            content,
        }
    }
}

/// Content of a [StateEvent]
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum StateEventContent {
    /// Remote peer's data was synced to local document
    #[non_exhaustive]
    PeerSynced {
        /// Id of the peer whose data was synced
        peer_id: PeerId,
        /// Discovery key of peer's feed
        discovery_key: FeedDiscoveryKey,
        /// Length that was synced
        contiguous_length: u64,
    },
    /// Remote peer got local data
    #[non_exhaustive]
    RemotePeerSynced {
        /// Id of the peer that was synced
        peer_id: PeerId,
        /// Discovery key of the feed
        discovery_key: FeedDiscoveryKey,
        /// Length that was synced
        contiguous_length: u64,
    },
    /// Peer's feed got replaced. NB: Listen to this for in-memory peers and
    /// if peer_id matches [local peer_id](crate::Peermerge::peer_id),
    /// store (and replace) value from [reattach_secret()](crate::Peermerge::reattach_secret)
    /// so that it can be given back when re-attaching the document.
    #[non_exhaustive]
    PeerChanged {
        /// Id of the peer that was changed
        peer_id: PeerId,
        /// New discovery key
        discovery_key: FeedDiscoveryKey,
        /// Discovery key that was replaced
        replaced_discovery_key: Option<FeedDiscoveryKey>,
    },
    /// Document was initialized and is now ready to transact with.
    #[non_exhaustive]
    DocumentInitialized {
        /// If true, this is a brand new document. If false, an existing one.
        new_document: bool,
        /// Whether this document is a child
        child: bool,
        /// All the document ids that are parents to this document. This can
        /// have multiple values if another parent of the document is being
        /// proxied in this peermerge.
        parent_document_ids: Vec<DocumentId>,
    },
    /// Document was changed
    #[non_exhaustive]
    DocumentChanged {
        /// Optional change id if given when creating a document or transacting
        /// with it. NB: This can only come with local changes.
        /// Remote peers' change ids are not transmitted over-the-wire.
        change_id: Option<Vec<u8>>,
        /// Full automerge patches of the change.
        patches: Vec<Patch>,
    },
}

#[derive(Clone, Debug)]
pub(crate) struct FeedEvent {
    pub(crate) doc_discovery_key: FeedDiscoveryKey,
    pub(crate) content: FeedEventContent,
}

impl FeedEvent {
    pub(crate) fn new(doc_discovery_key: FeedDiscoveryKey, content: FeedEventContent) -> Self {
        Self {
            doc_discovery_key,
            content,
        }
    }
}

#[derive(Clone, Debug)]
pub(crate) enum FeedEventContent {
    NewFeedsBroadcasted {
        new_feeds: Vec<DocumentFeedInfo>,
    },
    NewChildDocumentsBroadcasted {
        new_child_documents: Vec<ChildDocumentInfo>,
    },
    FeedSynced {
        peer_id: Option<PeerId>,
        discovery_key: FeedDiscoveryKey,
        contiguous_length: u64,
    },
    FeedVerified {
        peer_id: Option<PeerId>,
        discovery_key: FeedDiscoveryKey,
        verified: bool,
    },
    FeedDisconnected {
        channel: u64,
    },
    RemoteFeedSynced {
        peer_id: Option<PeerId>,
        discovery_key: FeedDiscoveryKey,
        contiguous_length: u64,
    },
    FeedMaxLengthReached {
        discovery_key: FeedDiscoveryKey,
    },
}