Skip to main content

crdt_kit/
events.rs

1//! Operation-based CRDT trait for event sourcing.
2//!
3//! Op-based CRDTs produce **operations** (events) that can be:
4//! - Persisted as an append-only event log
5//! - Broadcast to other replicas for synchronization
6//! - Replayed to reconstruct state
7//!
8//! This trait bridges the gap between CRDTs and event sourcing:
9//! each CRDT operation IS a domain event.
10
11use crate::Crdt;
12
13/// A CRDT that can express its mutations as discrete operations.
14///
15/// Unlike state-based CRDTs (which merge full state), op-based CRDTs
16/// exchange individual operations. Each operation is an event that
17/// can be persisted, broadcast, and replayed.
18///
19/// # Relationship to Event Sourcing
20///
21/// ```text
22/// Traditional Event Sourcing:
23///   Command → Validate → Event → Persist → Apply → State
24///
25/// CRDT Event Sourcing (this trait):
26///   Operation → apply_op() → State
27///   (No validation needed — CRDTs guarantee convergence)
28/// ```
29///
30/// # Example
31///
32/// ```
33/// use crdt_kit::events::OpCrdt;
34/// use crdt_kit::prelude::*;
35/// // OpCrdt implementors produce typed operations
36/// // that can be serialized and stored as events.
37/// ```
38pub trait OpCrdt: Crdt {
39    /// The operation type this CRDT produces.
40    ///
41    /// Operations must be serializable (for persistence and network transfer)
42    /// and deterministically applicable (for convergence).
43    type Op;
44
45    /// Apply an operation to the current state.
46    ///
47    /// This is the core function: it takes an operation (from local or remote)
48    /// and updates the CRDT state. For convergence, `apply_op` must be:
49    /// - **Commutative**: order of operations doesn't matter
50    /// - **Idempotent**: applying the same op twice has no additional effect
51    fn apply_op(&mut self, op: &Self::Op);
52}