eventsdb_core/lib.rs
1//! An embedded, append-only event log.
2//!
3//! `eventsdb` is an event store that lives in the process rather than behind
4//! a socket. It keeps the guarantees an event store exists for — immutable
5//! facts, per-stream ordering, decisions taken inside the write, schema
6//! evolution without rewriting stored bytes — and drops the ones that require
7//! a cluster.
8//!
9//! # The layers
10//!
11//! | Layer | What it answers |
12//! |-------|-----------------|
13//! | [`event`] | what a valid event is, and which fields the store owns |
14//! | [`upcast`] | how a reader sees an old event's current shape |
15//! | [`store`] | one stream: append, decide-and-append, read, head |
16//! | [`log`] | the database: read across streams, subscribe, checkpoint |
17//!
18//! This crate is the contract and the in-memory backend. A durable backend is
19//! a separate crate implementing the same two traits.
20//!
21//! # What single-writer buys
22//!
23//! Two properties this design has are not available to a store that runs as a
24//! separate service, and both come from the same place — one writer, one
25//! transaction:
26//!
27//! - **Positions have no holes.** The backend allocates a
28//! [`position::Position`] inside the transaction that commits it, so a
29//! reader never sees `n + 1` while `n` is still uncommitted. Following the
30//! log is a range read, with no gap detection and no grace window.
31//! - **A projection can be exactly-once.** When the read model lives in the
32//! same database as the log, applying an event and advancing the consumer's
33//! checkpoint are one transaction. There is no dedupe table and no
34//! idempotence requirement on the projection author.
35//!
36//! Distributing the store forfeits both.
37
38pub mod error;
39pub mod event;
40pub mod log;
41pub mod mem;
42pub mod params;
43pub mod position;
44pub mod store;
45pub mod transfer;
46pub mod upcast;
47
48pub use error::{Error, Result};
49pub use event::{validate, CURRENT_SCHEMA_VERSION};
50pub use log::{EventLog, Filter};
51pub use mem::MemEventStore;
52pub use params::Params;
53pub use position::{Committed, Position, Recorded};
54pub use store::{Decision, EventStore, Expected};
55pub use transfer::{ExportedEvent, ImportReport};
56pub use upcast::{Current, UpcastChain, Upcaster};