peermerge 0.0.3

Manage JSON-like documents with multiple writers, without a central authority, using a P2P protocol
Documentation
//! ## Introduction
//!
//! Peermerge is a Rust crate for managing JSON-like documents with multiple writers without a
//! central authority. Concurrent writing is made possible with the CRDT implementation of
//! [automerge][automerge], and communication between peers with
//! [hypercore-protocol][hypercore-protocol]. Optional support for
//! [p2panda][p2panda] and other peer protocols, instead of hypercore, is planned in the
//! future.
//!
//! Peermerge can be built with WASM for browser support and uses either the `tokio` or
//! `async-std` runtimes.
//!
//! This crate exposes a low-level API that the following crates from the same family utilize:
//!
//! * [peermerge-tcp][peermerge-tcp]: TCP/IP bindings to an existing peermerge
//! * [peermerge-hub][peermerge-hub]: configurable (tokio) runner that utilizes peermerge-tcp
//!   to host a proxy peermerge and adds back-up and logging
//! * [peermerge-server][peermerge-server]: configurable [axum][axum] web server built on
//!   top of peermerge-hub, which adds websocket bindings and static HTML file serving.
//!
//! ## Design
//!
//! The main abstraction is [Peermerge], which is a repository that stores
//! documents. For a single peer (device or server) there usually isn't a
//! need to create and/or open more than one Peermerge instance.
//!
//! Peermerge is designed to be cheap to clone and sent to spawned threads, and data within
//! it can be either stored in memory or on disk. Disk storage is naturally more common,
//! but in-memory storage can also be useful for example for WASM builds where a peer (i.e.
//! browser) doesn't have a file system. (To prevent a new peer from being created on every
//! browser refresh, see `reattach_secrets`.)
//!
//! Peermerge exposes the full interface of automerge's
//! [AutoCommit][automerge-autocommit] via the methods [transact](crate::Peermerge::transact) and
//! [transact_mut](crate::Peermerge::transact_mut), for reading and writing, respectively.
//!
//! Connecting to a peer is done via [AsyncRead]/[AsyncWrite] supported [FeedProtocol] passed
//! onto either [connect_protocol_disk](crate::Peermerge::connect_protocol_disk) or
//! [connect_protocol_memory](crate::Peermerge::connect_protocol_memory).
//!
//! ## Features
//!
//! ### `hypercore-feed` (default, mandatory)
//!
//! Future-compatible, currently mandatory, feature to use the hypercore feed.
//!
//! ### `tokio-runtime` (default)
//!
//! Use the tokio runtime, on by default. Either this or `async-std-runtime` is mandatory.
//!
//! ### `async-std-runtime`
//!
//! Use the async-std runtime. Either this or `tokio-runtime` is mandatory.
//!
//! ### `wasm-bindgen` (default)
//!
//! Enable support for WASM compilation and runtime.
//!
//! ### `log`
//!
//! Enable support for [log][log] from [tracing].
//!
//! ### `channel-writer`
//!
//! Export a convenient `ChannelWriter` wrapper and the [bytes][bytes] crate and .
//!
//! ## Example
//!
//! TODO
//!
//! ## See also
//!
//! Peermerge is heavily inspired by the original Javascript [hypermerge][hypermerge] package,
//! which targeted now obsolete versions of both hypercore and automerge.
//!
//! [automerge]: https://crates.io/crates/automerge
//! [hypercore-protocol]: https://crates.io/crates/hypercore-protocol
//! [p2panda]: https://crates.io/crates/p2panda-rs
//! [peermerge-tcp]: https://crates.io/crates/peermerge-tcp
//! [peermerge-hub]: https://crates.io/crates/peermerge-hub
//! [peermerge-server]: https://crates.io/crates/peermerge-server
//! [axum]: https://crates.io/crates/axum
//! [automerge-autocommit]: automerge::AutoCommit
//! [log]: https://crates.io/crates/log
//! [bytes]: https://crates.io/crates/bytes
//! [hypermerge]: https://github.com/automerge/hypermerge

#![forbid(unsafe_code, nonstandard_style, future_incompatible)]
#![forbid(missing_debug_implementations)]
#![forbid(unreachable_pub, missing_docs)]

/// Module to host convenient ChannelWriter wrapper
#[cfg(feature = "channel-writer")]
pub mod channel_writer;
mod common;
mod core;
mod crdt;
mod document;
mod feeds;
mod options;

#[macro_use]
extern crate derive_builder;

// Custom types and traits
/// Public key of the feed.
pub type FeedPublicKey = [u8; 32];
/// Discovery key of the feed. Derived by hashing from FeedPublicKey.
pub type FeedDiscoveryKey = [u8; 32];
/// Id of a document. Derived by hashing from FeedDiscoveryKey.
pub type DocumentId = [u8; 32];
/// Id of a peer
pub type PeerId = [u8; 16];
use futures::{AsyncRead, AsyncWrite};
/// Input/Output trait using AsyncRead/AsyncWrite
pub trait IO: AsyncWrite + AsyncRead + Send + Unpin + 'static {}
impl<T> IO for T where T: AsyncWrite + AsyncRead + Send + Unpin + 'static {}

// Crate exports
pub use crate::common::constants::{
    DEFAULT_MAX_ENTRY_DATA_SIZE_BYTES, DEFAULT_MAX_WRITE_FEED_LENGTH, MAX_ENTRY_DATA_SIZE_BYTES,
};
pub use crate::common::{
    decode_base64_nopad, encode_base64_nopad, get_document_info, new_uuid_v4, AccessType,
    DocumentInfo, DocumentSharingInfo, DynamicDocumentInfo, FeedType, NameDescription,
    PeermergeError, StateEvent, StateEventContent, StaticDocumentInfo, UrlDocumentInfo,
};
pub use crate::core::Peermerge;
pub use crate::crdt::AutomergeDoc;
#[cfg(not(target_arch = "wasm32"))]
pub use feeds::FeedDiskPersistence;
pub use feeds::{FeedMemoryPersistence, FeedPersistence};
pub use feeds::{FeedProtocol, ProtocolBuilder};
pub use options::*;

// Related crates' re-exports
pub use automerge;
#[cfg(feature = "channel-writer")]
pub use bytes;
#[cfg(not(target_arch = "wasm32"))]
pub use random_access_disk::RandomAccessDisk;
pub use random_access_memory::RandomAccessMemory;
pub use random_access_storage::RandomAccess;
pub use uuid;