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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
//! 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
//!
//! ## Define Events Using an Enum
//!
//! ```rust,ignore
//! // Define events using an enum - the macro generates individual structs
//! #[evento::aggregator]
//! pub enum Account {
//! AccountOpened {
//! owner: String,
//! initial_balance: i64,
//! },
//! MoneyDeposited {
//! amount: i64,
//! },
//! MoneyWithdrawn {
//! amount: i64,
//! },
//! }
//! ```
//!
//! ## Create and Store Events
//!
//! ```rust,ignore
//! use evento::metadata::Metadata;
//!
//! // Setup database and run migrations
//! let pool = sqlx::SqlitePool::connect("sqlite:events.db").await?;
//! let mut conn = pool.acquire().await?;
//! evento::sql_migrator::new()?
//! .run(&mut *conn, &evento::migrator::Plan::apply_all())
//! .await?;
//!
//! let executor: evento::Sqlite = pool.into();
//!
//! // Create a new aggregate with an event
//! let account_id = evento::create()
//! .event(&AccountOpened { owner: "Alice".into(), initial_balance: 1000 })
//! .metadata(&Metadata::default())
//! .routing_key("accounts")
//! .commit(&executor)
//! .await?;
//!
//! // Add more events to the aggregate
//! evento::aggregator(&account_id)
//! .original_version(1)
//! .event(&MoneyDeposited { amount: 100 })
//! .metadata(&Metadata::default())
//! .commit(&executor)
//! .await?;
//! ```
//!
//! ## Build Projections
//!
//! Projections are used to load aggregate state by replaying events:
//!
//! ```rust,ignore
//! use evento::{Executor, metadata::Event, projection::Projection};
//!
//! // Define projection state with cursor tracking
//! #[evento::projection]
//! #[derive(Debug)]
//! pub struct AccountView {
//! pub balance: i64,
//! pub owner: String,
//! }
//!
//! // Projection handlers update state from events
//! #[evento::handler]
//! async fn on_account_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_money_deposited(
//! event: Event<MoneyDeposited>,
//! view: &mut AccountView,
//! ) -> anyhow::Result<()> {
//! view.balance += event.data.amount;
//! Ok(())
//! }
//!
//! // Load aggregate state via projection
//! let result = Projection::<AccountView, _>::new::<Account>(&account_id)
//! .handler(on_account_opened())
//! .handler(on_money_deposited())
//! .execute(&executor)
//! .await?;
//! ```
//!
//! ## Run Continuous Subscriptions
//!
//! Subscriptions process events in real-time with side effects:
//!
//! ```rust,ignore
//! use std::time::Duration;
//! use evento::{Executor, metadata::Event, subscription::{Context, SubscriptionBuilder}};
//!
//! // Subscription handlers receive context and can perform side effects
//! #[evento::subscription]
//! async fn notify_on_deposit<E: Executor>(
//! context: &Context<'_, E>,
//! event: Event<MoneyDeposited>,
//! ) -> anyhow::Result<()> {
//! println!("Deposit of {} received", event.data.amount);
//! // Send notifications, update read models, etc.
//! Ok(())
//! }
//!
//! let subscription = SubscriptionBuilder::<evento::Sqlite>::new("deposit-notifier")
//! .handler(notify_on_deposit())
//! .routing_key("accounts")
//! .chunk_size(100)
//! .retry(5)
//! .delay(Duration::from_secs(10))
//! .start(&executor)
//! .await?;
//!
//! // On shutdown
//! subscription.shutdown().await?;
//! ```
//!
//! ## Handle All Events from an Aggregate
//!
//! Use `subscription_all` to process all events without deserializing:
//!
//! ```rust,ignore
//! use evento::{Executor, metadata::RawEvent, subscription::Context};
//!
//! #[evento::subscription_all]
//! async fn audit_all_events<E: Executor>(
//! context: &Context<'_, E>,
//! event: RawEvent<Account>,
//! ) -> anyhow::Result<()> {
//! println!("Event {} on account {}", event.name, event.aggregator_id);
//! 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
/// - [`ProjectionAggregator`] - 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;