| Crates.io | eventuali-core |
| lib.rs | eventuali-core |
| version | 0.1.1 |
| created_at | 2025-09-17 15:26:38.347261+00 |
| updated_at | 2025-09-17 15:26:38.347261+00 |
| description | High-performance event sourcing core library in Rust |
| homepage | |
| repository | https://github.com/primevalai/eventuali |
| max_upload_size | |
| id | 1843478 |
| size | 860,294 |
A high-performance event sourcing library written in Rust, providing the core foundation for the Eventuali event sourcing ecosystem.
Add to your Cargo.toml:
[dependencies]
eventuali-core = "0.1"
use eventuali_core::{
EventStoreConfig, create_event_store, Event, EventData, EventMetadata
};
use chrono::Utc;
use serde_json::json;
use uuid::Uuid;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create an in-memory SQLite event store
let config = EventStoreConfig::sqlite(":memory:").await?;
let store = create_event_store(config).await?;
// Create an event
let event = Event {
id: Uuid::new_v4(),
aggregate_id: "user-123".to_string(),
aggregate_type: "User".to_string(),
event_type: "UserRegistered".to_string(),
event_version: 1,
aggregate_version: 1,
data: EventData::from_json(&json!({
"name": "Alice",
"email": "alice@example.com"
}))?,
metadata: EventMetadata::default(),
timestamp: Utc::now(),
};
// Store the event
store.append_events(vec![event]).await?;
// Load events for an aggregate
let events = store.load_events("user-123", None).await?;
println!("Loaded {} events", events.len());
Ok(())
}
use eventuali_core::{
InMemoryEventStreamer, SubscriptionBuilder, Projection
};
use async_trait::async_trait;
// Define a projection
struct UserCountProjection {
count: i32,
}
#[async_trait]
impl Projection for UserCountProjection {
async fn handle_event(&mut self, event: &Event) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
if event.event_type == "UserRegistered" {
self.count += 1;
println!("User count: {}", self.count);
}
Ok(())
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let streamer = InMemoryEventStreamer::new();
let projection = UserCountProjection { count: 0 };
// Subscribe to events
let subscription = SubscriptionBuilder::new()
.event_type("UserRegistered".to_string())
.build();
let mut receiver = streamer.subscribe(subscription).await?;
// Process events as they arrive
while let Ok(stream_event) = receiver.recv().await {
projection.handle_event(&stream_event.event).await?;
}
Ok(())
}
Control which features are compiled:
[dependencies]
eventuali-core = { version = "0.1", features = ["postgres", "sqlite", "observability"] }
Available features:
postgres - PostgreSQL backend supportsqlite - SQLite backend support (included by default)observability - OpenTelemetry tracing and metrics (included by default)Eventuali Core achieves exceptional performance through Rust's zero-cost abstractions:
The library is organized into several key modules:
event - Core event types and serializationstore - Event storage abstraction and implementationsstreaming - Real-time event streaming and projectionsaggregate - Aggregate root patterns and versioningsnapshot - Snapshot storage and compressionsecurity - Event encryption and key managementtenancy - Multi-tenant isolation and resource managementobservability - Metrics, tracing, and logginglet config = EventStoreConfig::sqlite("events.db").await?;
let store = create_event_store(config).await?;
let config = EventStoreConfig::postgres("postgresql://user:password@localhost/eventstore").await?;
let store = create_event_store(config).await?;
use eventuali_core::{EventEncryption, KeyManager, EncryptionAlgorithm};
let key_manager = KeyManager::new();
let encryption = EventEncryption::new(key_manager, EncryptionAlgorithm::AesGcm);
// Events are automatically encrypted/decrypted
use eventuali_core::{TenantId, IsolatedEventStore};
let tenant_id = TenantId::new("tenant-1");
let isolated_store = IsolatedEventStore::new(store, tenant_id);
// All operations are automatically scoped to the tenant
use eventuali_core::{SnapshotStore, SnapshotConfig, SnapshotCompression};
let snapshot_config = SnapshotConfig {
compression: SnapshotCompression::Gzip,
retention_count: 10,
};
let snapshot_store = SqliteSnapshotStore::new(snapshot_config).await?;
The examples/ directory contains comprehensive examples:
basic_event_store.rs - Basic event storage and retrievalstreaming_projections.rs - Real-time event streaming and projectionsmulti_tenant.rs - Multi-tenant event isolationrust_streaming_demo.rs - Complete streaming demonstrationRun examples with:
cargo run --example basic_event_store
Eventuali Core is designed to integrate seamlessly with:
Contributions are welcome! Please see our contributing guidelines.
Licensed under either of:
at your option.