1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//! Event sourcing and CQRS toolkit with SQL persistence, projections, and subscriptions.
//!
//! Evento provides a complete toolkit for implementing event sourcing patterns in Rust,
//! with support for SQLite, PostgreSQL, MySQL databases, and embedded storage via Fjall.
//!
//! # Features
//!
//! - **Event Sourcing** - Store state changes as immutable events with complete audit trail
//! - **CQRS Pattern** - Separate read and write models for scalable architectures
//! - **SQL Database Support** - Built-in support for SQLite, PostgreSQL, and MySQL
//! - **Embedded Storage** - Fjall key-value store for embedded applications
//! - **Projections** - Build read models by replaying events
//! - **Subscriptions** - Continuous event stream processing with cursor tracking
//! - **Database Migrations** - Automated schema management
//! - **Compact Serialization** - Fast binary serialization with bitcode
//!
//! # Feature Flags
//!
//! - `macro` (default) - Procedural macros for cleaner code
//! - `group` - Multi-executor support via `EventoGroup`
//! - `rw` - Read-write split executor pattern
//! - `sql` - Enable all SQL database backends
//! - `sqlite` - SQLite support via sqlx
//! - `mysql` - MySQL support via sqlx
//! - `postgres` - PostgreSQL support via sqlx
//! - `fjall` - Embedded key-value storage with Fjall
//!
//! # Quick Start
//!
//! The example below is generic over any [`Executor`], so it type-checks the whole
//! surface — macros, write path, projection, and subscriptions — without a database.
//! See `examples/bank` for a runnable backend setup (SQLite/Fjall + migrations).
//!
//! ```rust,no_run
//! use evento::{
//! metadata::{Event, RawEvent},
//! projection::Projection,
//! subscription::{Context, SubscriptionBuilder},
//! Executor,
//! };
//!
//! // Define events with an enum; each variant becomes an event struct.
//! #[evento::aggregate]
//! pub enum Account {
//! AccountOpened { owner: String, initial_balance: i64 },
//! MoneyDeposited { amount: i64 },
//! }
//!
//! // A read model. Add bitcode derives so it can be snapshotted.
//! #[evento::projection(bitcode::Encode, bitcode::Decode)]
//! pub struct AccountView {
//! pub owner: String,
//! pub balance: i64,
//! }
//!
//! // Projection handlers are pure: (event, &mut view).
//! #[evento::handler]
//! async fn on_opened(event: Event<AccountOpened>, view: &mut AccountView) -> anyhow::Result<()> {
//! view.owner = event.data.owner.clone();
//! view.balance = event.data.initial_balance;
//! Ok(())
//! }
//! #[evento::handler]
//! async fn on_deposited(event: Event<MoneyDeposited>, view: &mut AccountView) -> anyhow::Result<()> {
//! view.balance += event.data.amount;
//! Ok(())
//! }
//!
//! // Subscription handlers take the context first and may do side effects.
//! #[evento::subscription]
//! async fn notify<E: Executor>(_ctx: &Context<'_, E>, event: Event<MoneyDeposited>) -> anyhow::Result<()> {
//! println!("deposited {}", event.data.amount);
//! Ok(())
//! }
//!
//! // `subscription_all` sees every event without deserializing the payload.
//! #[evento::subscription_all]
//! async fn audit<E: Executor>(_ctx: &Context<'_, E>, event: RawEvent<Account>) -> anyhow::Result<()> {
//! println!("event {} on {}", event.name, event.aggregate_id);
//! Ok(())
//! }
//!
//! async fn run<E: Executor + Clone>(executor: &E) -> anyhow::Result<()> {
//! // Start a new aggregate, then append to it (with optimistic concurrency).
//! let id = evento::create()
//! .event(&AccountOpened { owner: "Alice".into(), initial_balance: 1000 })
//! .routing_key("accounts")
//! .commit(executor)
//! .await?;
//! evento::append(&id)
//! .original_version(1)
//! .event(&MoneyDeposited { amount: 100 })
//! .commit(executor)
//! .await?;
//!
//! // Load the read model by replaying events.
//! let _view: Option<AccountView> = Projection::<_, AccountView>::new::<Account>()
//! .handler(on_opened())
//! .handler(on_deposited())
//! .load(&id)
//! .execute(executor)
//! .await?;
//!
//! // Run a background subscription, then shut it down.
//! let subscription = SubscriptionBuilder::new("deposit-notifier")
//! .handler(notify())
//! .routing_key("accounts")
//! .start(executor)
//! .await?;
//! subscription.shutdown().await?;
//! Ok(())
//! }
//! ```
//!
//! # Re-exports
//!
//! This crate re-exports types from [`evento_core`] and conditionally from
//! `evento_sql` and `evento_sql_migrator` when database features are enabled.
// Re-export everything from evento-core
pub use *;
/// Projection types re-exported at root level for convenience.
///
/// These are the most commonly used types for building read models:
/// - [`Handler`] - Trait for projection event handlers
/// - [`Projection`] - Builder for loading aggregate state
/// - [`ProjectionAggregate`] - Trait for projections that emit events
/// - [`ProjectionCursor`] - Trait for cursor position tracking
/// - [`Snapshot`] - Trait for snapshot restoration
pub use ;
// Re-export SQL types when SQL features are enabled
/// SQL executor and types (requires `sqlite`, `mysql`, or `postgres` feature).
pub use evento_sql as sql;
/// SQL type wrappers for bitcode serialization.
pub use sql_types;
/// Database migration utilities for evento schema.
pub use evento_sql_migrator as sql_migrator;
/// Database migration plan and execution utilities.
/// MySQL executor type alias.
pub use MySql;
/// PostgreSQL executor type alias.
pub use Postgres;
/// SQLite executor type alias.
pub use Sqlite;
/// Fjall executor and types (requires `fjall` feature).
pub use evento_fjall as fjall;
/// Fjall executor type alias.
pub use Fjall;