Expand description
mire — a small, generic PostgreSQL event-sourcing library.
Events are appended to per-aggregate streams in an append-only log, ordered
both within a stream (stream_version) and globally (global_position).
Aggregates are rebuilt by replaying their events; read models are built by
a ProjectionRunner, which polls the log and checkpoints under a
replica-safe fenced lease.
The core building blocks are:
Aggregate/AggregateRoot— your domain state + the events it records.EventStore— load, save, append and read events (Postgres-backed).ProjectionRunner— drive projections / read models across replicas, one leader per subscription via fenced leases. (The lower-levelSubscriptionpoll cursor it’s built on is internal.)
See the examples/ directory for runnable end-to-end usage.
Structs§
- Aggregate
Root - Committed
Events - Event
- Event
Metadata - Event
Store - Handled
Event - Envelope handed to an
EventHandler: a typed, already-decoded event plus the fullRecordedEventit came from. - Lease
Status - Snapshot of a lease row as seen in Postgres. Returned by
[
status] for the publicProjectionRunner::lease_statusAPI. - Projection
Runner - Long-running supervisor for projections. Drive with
runfrom any host supervisor; fornotmad-based apps, see the module-level wrapper example. - Projection
Runner Builder - Builds a
ProjectionRunner. - Recorded
Event - Response
Value - What
IntoResponse::into_responsereturns. The saga runner uses the fields to deliver the response back to the awaiting step (or fail it whenis_erroris true). - Stream
Query - Transaction
Scope - Read-before-write escape hatch. In a strict event-sourced design,
commands read from projections (CQRS) and write to aggregates. The
TransactionScopeexists for edge cases where that separation is impractical: cross-aggregate invariants enforced in a single deployment, recovery tooling, one-shot migrations. Prefer a projection-driven design wherever you can — a long-livedTransactionScopeon a hot stream blocks other writers and couples your read path to the event store’s transaction lifecycle.
Enums§
- DbError
Kind - Coarse classification of
EventStoreError::Databasefor callers that want to react differently to common failure modes without depending onsqlxtypes. UseEventStoreError::db_kindto inspect. - Event
Store Error - Expected
Version - Read
Direction
Traits§
- Aggregate
- The domain model whose state is rebuilt by folding events.
- Event
Data - The serializable shape of a domain event. Every variant must report
a stable
event_typestring — this is what mire stores in theevent_typecolumn and uses as the schema discriminator for the event log. - Event
Handler - Handles a single event for an aggregate’s stream, updating a read model.
The runner decodes
recorded.datainto the aggregate’s event type before invokinghandle, so handlers see typed events directly. ReturningErrtriggers a retry; persistent failure (pastmax_attempts) stops the runner. - Event
Type Static - An
EventDatatype whoseevent_typediscriminator string is known at compile time. Enables references likeawait_event::<E>()that don’t have an instance to callevent_type(&self)on. - Into
Response - A value that can be turned into a response event.
- Snapshot
- Opt-in capability: an
Aggregatewhose state can be snapshotted. Requires the state to be (de)serializable. UseEventStore::load_snapshottedandsave_snapshottingfor these. - Transactional
Event Handler - A read-model handler that writes inside the runner’s checkpoint transaction (review C2/LEASE-1).
Derive Macros§
- Event
Data #[derive(EventData)]— see the crate-level docs andEventDatafor the runtime contract. Enabled by default via thederivefeature; turn it off withmire = { ..., default-features = false }if you don’t want the proc-macro dep.- Into
Response #[derive(EventData)]— see the crate-level docs andEventDatafor the runtime contract. Enabled by default via thederivefeature; turn it off withmire = { ..., default-features = false }if you don’t want the proc-macro dep.#[derive(IntoResponse)]on an enum whose every variant is a single unnamed field wrapping an event type. Generates a delegatingIntoResponseimpl that callsinner.into_response()per variant.