Skip to main content

Crate mire

Crate mire 

Source
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-level Subscription poll cursor it’s built on is internal.)

See the examples/ directory for runnable end-to-end usage.

Structs§

AggregateRoot
CommittedEvents
Event
EventMetadata
EventStore
HandledEvent
Envelope handed to an EventHandler: a typed, already-decoded event plus the full RecordedEvent it came from.
LeaseStatus
Snapshot of a lease row as seen in Postgres. Returned by [status] for the public ProjectionRunner::lease_status API.
ProjectionRunner
Long-running supervisor for projections. Drive with run from any host supervisor; for notmad-based apps, see the module-level wrapper example.
ProjectionRunnerBuilder
Builds a ProjectionRunner.
RecordedEvent
ResponseValue
What IntoResponse::into_response returns. The saga runner uses the fields to deliver the response back to the awaiting step (or fail it when is_error is true).
StreamQuery
TransactionScope
Read-before-write escape hatch. In a strict event-sourced design, commands read from projections (CQRS) and write to aggregates. The TransactionScope exists 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-lived TransactionScope on a hot stream blocks other writers and couples your read path to the event store’s transaction lifecycle.

Enums§

DbErrorKind
Coarse classification of EventStoreError::Database for callers that want to react differently to common failure modes without depending on sqlx types. Use EventStoreError::db_kind to inspect.
EventStoreError
ExpectedVersion
ReadDirection

Traits§

Aggregate
The domain model whose state is rebuilt by folding events.
EventData
The serializable shape of a domain event. Every variant must report a stable event_type string — this is what mire stores in the event_type column and uses as the schema discriminator for the event log.
EventHandler
Handles a single event for an aggregate’s stream, updating a read model. The runner decodes recorded.data into the aggregate’s event type before invoking handle, so handlers see typed events directly. Returning Err triggers a retry; persistent failure (past max_attempts) stops the runner.
EventTypeStatic
An EventData type whose event_type discriminator string is known at compile time. Enables references like await_event::<E>() that don’t have an instance to call event_type(&self) on.
IntoResponse
A value that can be turned into a response event.
Snapshot
Opt-in capability: an Aggregate whose state can be snapshotted. Requires the state to be (de)serializable. Use EventStore::load_snapshotted and save_snapshotting for these.
TransactionalEventHandler
A read-model handler that writes inside the runner’s checkpoint transaction (review C2/LEASE-1).

Derive Macros§

EventData
#[derive(EventData)] — see the crate-level docs and EventData for the runtime contract. Enabled by default via the derive feature; turn it off with mire = { ..., default-features = false } if you don’t want the proc-macro dep.
IntoResponse
#[derive(EventData)] — see the crate-level docs and EventData for the runtime contract. Enabled by default via the derive feature; turn it off with mire = { ..., 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 delegating IntoResponse impl that calls inner.into_response() per variant.