nodedb_lite/sync/array/mod.rs
1//! Array CRDT synchronization for NodeDB-Lite.
2//!
3//! This module implements the embedded side of the sparse N-dimensional array
4//! sync protocol. The design has three independent paths:
5//!
6//! 1. **Outbound** — local writes call [`ArrayOutbound`], which appends the op
7//! to a durable KV-backed [`KvOpLogStore`] and enqueues it on
8//! [`PendingQueue`] for the transport layer to drain. The send path is
9//! fire-and-forget from the engine's perspective.
10//!
11//! 2. **Inbound** — wire messages from Origin enter [`ArrayInbound`], which
12//! deduplicates by HLC against the local op-log, applies the op via
13//! [`LiteApplyEngine`], and persists the resulting state. The receive path
14//! deliberately does *not* re-trigger outbound hooks, preventing echo
15//! loops by construction.
16//!
17//! 3. **Catch-up** — [`CatchupTracker`] persists the highest applied HLC per
18//! array so that, on reconnect, the transport can request only the ops it
19//! missed.
20//!
21//! Cross-cutting state:
22//! - [`ReplicaState`] — stable replica identity + monotonic HLC generator.
23//! - [`SchemaRegistry`] — per-array [`SchemaDoc`] snapshots, persisted as
24//! Loro documents.
25//!
26//! Backpressure is enforced at the [`PendingQueue`] (100k-op cap); overflow
27//! surfaces as [`crate::error::LiteError::Backpressure`].
28//!
29//! Transport wiring (WebSocket dispatch into `ArrayInbound` and the push loop
30//! that drains `PendingQueue`) lives in `crate::sync::transport`. This module
31//! is transport-agnostic. [`reject_policy`] decides what happens to a local op
32//! Origin refuses.
33
34pub mod ack_sender;
35pub mod catchup;
36pub mod inbound;
37pub mod op_log_store;
38pub mod outbound;
39pub mod pending;
40pub mod reject_policy;
41pub mod replica_state;
42pub mod schema_registry;
43
44pub use ack_sender::spawn as spawn_ack_sender;
45pub use catchup::CatchupTracker;
46pub use inbound::{ArrayInbound, InboundOutcome, LiteApplyEngine};
47pub use op_log_store::KvOpLogStore;
48pub use outbound::ArrayOutbound;
49pub use pending::{PendingArrayOp, PendingQueue};
50pub use reject_policy::{RejectDisposition, reject_disposition};
51pub use replica_state::ReplicaState;
52pub use schema_registry::SchemaRegistry;