Eventuous/eventuous
67.4
Adequate · 21 September 2026
22.4k
lines of production code
C#
primary language
3
measurements over time
What this system is
Eventuous is an open-source event sourcing framework for .NET that provides the core abstractions for building event-driven applications, including aggregates, command handling, and stream persistence. It offers a comprehensive ecosystem of integrations for various event stores (such as PostgreSQL, SQL Server, MongoDB, Redis, and KurrentDB) and message brokers (including RabbitMQ, Kafka, Azure Service Bus, and Google Pub/Sub). The system also includes built-in support for read-model projections, distributed tracing, metrics, and real-time streaming via SignalR, along with sample applications demonstrating these capabilities.
How it got here
2021 — Subscription engine overhaul and integration expansion
39 changes.
This period focused on a comprehensive refactoring of the subscription engine, introducing a supervisor-based lifecycle, explicit checkpointing, and a composable filter pipeline with partitioning support. Simultaneously, the project expanded its integration ecosystem by adding initial producers and subscriptions for Google Pub/Sub and RabbitMQ, alongside new MongoDB projection utilities. The work was underpinned by significant improvements in observability through OpenTelemetry integration and extensive test coverage for the new core and integration components.
2022–2023 — multi-store expansion and core refactoring
61 changes.
This period focused on significantly expanding persistence support by introducing initial implementations for Elasticsearch, Kafka, SQL Server, and Redis, alongside major enhancements to PostgreSQL and MongoDB. The core framework underwent substantial refactoring to improve observability through OpenTelemetry integration, modernize command handling with fluent builders, and establish robust type mapping and streaming infrastructure.
2024–2025 — SQL provider expansion and HTTP command mapping
42 changes.
This period focused on adding native support for SQL Server and KurrentDB event stores, including schema definitions, projections, and comprehensive integration tests. It also introduced a new declarative HTTP command mapping system for ASP.NET Core, supported by source generators and analyzers to ensure type safety and correct route registration.
2026 — Real-time streaming and storage expansion
14 changes.
This period focused on enabling real-time event streaming through a new SignalR integration layer, including server hubs, client subscriptions, and distributed tracing. It also expanded storage capabilities by introducing SQLite as a lightweight event store and adding Azure Blob Storage projections for maintaining read-model state.
Features
Add Bookings sample application with PostgreSQL, MongoDB, and RabbitMQ integration
Introduces a new sample application for the Bookings domain, providing a complete reference implementation for running an event-sourced service. The sample includes a Dockerfile and .dockerignore for containerized deployment, along with configuration files (appsettings.json) defining connections to PostgreSQL, MongoDB, and RabbitMQ. It demonstrates the integration of these technologies through Program.cs and Registrations.cs, which set up the Eventuous framework, command services, and subscriptions for both database projections (via PostgresAllStreamSubscription) and external events (via RabbitMqSubscription). Additionally, it includes an integration handler (Payments.cs) to process payment events, showcasing how to bridge external systems with the internal booking state.
samples/postgres/Bookings · high confidence
Add Bookings.Payments sample application
Introduces a new sample application for the Bookings domain's payment functionality. The app is built on .NET and uses Eventuous for event sourcing, with PostgreSQL as the event store and MongoDB for checkpoint storage. It integrates with RabbitMQ for message publishing and exposes an HTTP API on port 5052 with Swagger UI and OpenTelemetry Prometheus scraping enabled.
samples/postgres/Bookings.Payments · high confidence
Add KurrentDB event store and producer support
This change introduces a new integration for KurrentDB, adding the \KurrentDBEventStore\ implementation of the \IEventStore\ interface and a \KurrentDBProducer\ for message production. The event store now supports native multi-stream appends, allowing events to be written to multiple streams in a single operation, and includes a \Created\ timestamp on stream events. The producer handles batching and acknowledgment of messages, configurable via \KurrentDBProduceOptions\.
src/KurrentDB/src/Eventuous.KurrentDB · high confidence
Add configurable logging event listener for internal diagnostics
Users can now expose Eventuous internal diagnostic events to the standard .NET logging system via the new LoggingEventListener. This component allows customization of the log level and keywords, enabling better visibility into internal event source activity.
src/Diagnostics/src/Eventuous.Diagnostics.Logging · high confidence
Add middleware to capture Eventuous internal logs
A new extension method, UseEventuousLogs, is now available for the ASP.NET Core application builder. This allows users to easily integrate internal Eventuous event sources into the application's standard logging pipeline, with configurable verbosity levels and keywords to balance detail against performance.
src/Extensions/src/Eventuous.Extensions.AspNetCore/Logging · high confidence
Add retry policies to event subscriptions via Polly
The Eventuous Subscriptions library now includes a Polly integration that allows users to wrap event handlers with configurable retry policies. A new \PollyEventHandler\ decorator intercepts event handling to apply the specified \IAsyncPolicy\, tracking retry attempts and logging failures when retries are exhausted. Users can register these wrapped handlers using the new \AddEventHandlerWithRetries\ extension methods on \SubscriptionBuilder\, which support both direct handler types and factory-based construction, ensuring transient failures in event processing are automatically retried according to the defined policy.
src/Extensions/src/Eventuous.Subscriptions.Polly · high confidence
Add tracing constants for components and operations
A new Constants class has been introduced in the Eventuous.Diagnostics.Tracing namespace to define standardized string identifiers for tracing. This includes component types such as service, eventstore, sub, consumer, and handler, as well as specific operations like exists, append, read, truncate, and delete. These constants provide a centralized source of truth for naming conventions used in distributed tracing and telemetry.
src/Core/src/Eventuous.Diagnostics/Tracing · high confidence
Added MongoDB read-model projections for booking queries
The sample application now includes MongoDB-based projections to support efficient read queries for booking data. New files define the \BookingDocument\ and \MyBookings\ read models, along with \BookingStateProjection\ and \MyBookingsProjection\ classes that map domain events (\RoomBooked\, \PaymentRecorded\, \BookingFullyPaid\, \BookingCancelled\) to these documents. This enables the application to query booking details and a user's booking list directly from MongoDB, decoupling read operations from the event store.
samples/postgres/Bookings/Application/Queries · high confidence
Added MurmurHash3-based partitioning logic
The partitioning subsystem now includes a new MurmurHash3 implementation to calculate partition hashes from string keys, replacing or supplementing previous hashing mechanisms. This change introduces the \MurmurHash3\ class for efficient hash computation and defines the \Partitioner\ class with delegates for getting partition hashes and keys, enabling more consistent and performant event distribution across partitions.
src/Core/src/Eventuous.Subscriptions/Filters/Partitioning · high confidence
Added configuration and setup logic for Elasticsearch data streams
This change introduces new configuration records (IndexConfig, DataStreamTemplateConfig, LifecycleConfig, etc.) and a setup utility (SetupIndex) for managing Elasticsearch data streams. Users can now define index names, lifecycle policies with tiered retention (hot, warm, cold, frozen, delete), and template settings (shards, replicas). The SetupIndex class provides a method to automatically create the necessary lifecycle policies and data stream templates in Elasticsearch if they do not already exist, including retry logic for transient connection issues.
src/Experimental/src/Eventuous.ElasticSearch/Index · high confidence
Added distributed tracing and event source diagnostics for message producers
The producer module now includes built-in observability via OpenTelemetry-style activity tracing and .NET EventSource logging. A new \ProducerActivity\ class automatically creates and manages distributed traces when messages are produced, enriching them with standard messaging tags (message ID, conversation ID, causation ID, correlation ID) and propagating parent context. \ProducerEventSource\ emits verbose events for message production acknowledgments and failures, enabling low-overhead runtime diagnostics. Configuration is handled through \ProducerTracingOptions\, allowing users to specify the messaging system, destination kind, and operation name to contextualize the telemetry data.
src/Core/src/Eventuous.Producers/Diagnostics · high confidence
Added infrastructure for logging, MongoDB, and telemetry in the Bookings sample
The Bookings sample now includes dedicated infrastructure components for observability and data access. Logging is configured via Serilog with specific level overrides for Microsoft, ASP.NET Core, gRPC, EventStore, and Npgsql, outputting to the console. MongoDB support is added with a configuration helper that handles connection strings, optional authentication, and diagnostic event subscription. Telemetry is set up using OpenTelemetry, enabling metrics (ASP.NET Core, Eventuous, Prometheus) and tracing (ASP.NET Core, Eventuous, Npgsql) with conditional exporters for OTLP or Zipkin based on environment variables.
samples/postgres/Bookings/Infrastructure · high confidence
Added local Kafka development environment
A new local development environment for Kafka has been added, consisting of a docker-compose configuration and a startup script. The configuration provisions Zookeeper, Kafka, Schema Registry, and the Kafka UI, allowing developers to run and inspect the message broker locally.
src/Kafka · high confidence
Added payment integration gateway for RabbitMQ
A new PaymentsGateway class has been introduced in the Bookings.Payments integration layer to handle event transformation. It listens for PaymentRecorded domain events and converts them into BookingPaymentRecorded messages, which are then published to RabbitMQ via the Eventuous gateway pattern.
samples/postgres/Bookings.Payments/Integration · high confidence
Added persistence diagnostics and metrics
The persistence layer now includes built-in diagnostics and metrics collection. A new \PersistenceEventSource\ emits structured events for critical failures, such as inability to load or store aggregates and append events. Additionally, a \PersistenceMetrics\ class exposes OpenTelemetry-compatible metrics, specifically tracking the duration of event store operations and counting the number of errors, allowing users to monitor persistence performance and reliability.
src/Core/src/Eventuous.Persistence/Diagnostics · high confidence
Added shared PubSub utility methods for topic and subscription management
A new shared utility class has been introduced to provide helper methods for managing Google Cloud Pub/Sub resources. This includes functionality to detect emulator settings for subscriber and publisher clients, as well as asynchronous methods to check for the existence of topics and subscriptions, creating them automatically if they are missing. This simplifies the initialization process for applications using Google PubSub by handling common setup tasks like topic and subscription creation with configurable logging and emulator detection.
src/GooglePubSub/src/Eventuous.GooglePubSub/Shared · high confidence
Azure Blob Storage projections for event-sourced state
The \Eventuous.Azure.Storage.Blobs\ package now includes a \BlobStorageProjector\<T\>\ that maintains per-stream state objects in Azure Blob Storage. It automatically retrieves, updates, and uploads JSON state blobs using optimistic concurrency (ETags) and supports configurable retry logic for race conditions. Users can enable idempotency to prevent duplicate processing via \ByGlobalPosition\ or \ByMessageId\ modes, customize blob naming conventions, and register handlers for specific event types with optional custom blob ID generation.
src/Azure/src/Eventuous.Azure.Storage.Blobs · high confidence
Built-in distributed tracing and metrics for command services
The command service layer now includes native observability support. A new \TracedCommandService\ wrapper automatically instruments command handling with OpenTelemetry-compatible distributed tracing activities and Prometheus-style metrics (processing duration and error counts). Additionally, an \ApplicationEventSource\ provides low-level ETW events for command handler registration, execution, and errors, enabling developers to monitor and debug command processing without external dependencies.
src/Core/src/Eventuous.Application/Diagnostics · high confidence
Elasticsearch-based checkpoint store for projections
Added a new \ElasticCheckpointStore\ implementation that persists projection checkpoints to an Elasticsearch index. This allows users to store and retrieve projection state using Elasticsearch, supporting configurable index names and batched writes to optimize performance.
src/Experimental/src/Eventuous.ElasticSearch/Projections · high confidence
Initial Azure Service Bus subscription support with session and metadata handling
This change introduces the core subscription infrastructure for Azure Service Bus, allowing users to subscribe to queues and topics via the new \ServiceBusSubscription\ class. It adds support for message sessions through \SessionProcessorOptions\, enables configurable message attribute mapping via \ServiceBusMessageAttributeNames\, and ensures that message metadata (such as correlation ID and subject) is correctly exposed in the consume context.
src/Azure/src/Eventuous.Azure.ServiceBus/Subscriptions · high confidence
Initial Kafka integration support added
This change introduces the foundational components for Apache Kafka support within the Eventuous library. It adds a new \KafkaHeaderKeys\ class to define standard message headers (message-type, content-type), implements \MetadataExtensions\ to handle the conversion between Eventuous metadata and Kafka headers, and includes a README outlining the basic producer capabilities. This enables users to produce messages to Kafka using a serialization-agnostic approach.
src/Kafka/src/Eventuous.Kafka · high confidence
Initial PostgreSQL event store schema and stored procedures
Adds the foundational SQL scripts for the PostgreSQL event store, including the \\_\schema\\_\ namespace with tables for streams, messages, and checkpoints, alongside stored procedures for appending events, reading streams forwards/backwards, global reads, subscriptions, stream truncation, and gap handling via tombstones.
src/Postgres/src/Eventuous.Postgresql/Scripts · high confidence
Initial RabbitMQ producer implementation with exchange management and telemetry
This change introduces the core RabbitMQ producer component, including the \RabbitMqProducer\ class that handles message publishing, exchange declaration, and connection lifecycle management. It adds support for configuring exchange properties (type, durability, auto-delete) via \RabbitMqExchangeOptions\ and message-specific options (routing key, persistence, priority, expiration) via \RabbitMqProduceOptions\. The implementation includes an \ExchangeCache\ to manage exchange declarations and integrates telemetry tags for routing keys, enabling users to produce messages to RabbitMQ with configurable exchange behavior and observability.
src/RabbitMq/src/Eventuous.RabbitMq/Producers · high confidence
Initial Redis event store implementation with Lua-based append logic
Introduces the Eventuous Redis persistence provider, enabling users to store and read events using Redis Streams. The implementation uses a Lua script (append\_events) to atomically append events to both the specific stream and a global '\_all' stream, ensuring consistent versioning and global positioning. It includes a custom Module to load these Lua functions into Redis and handles position encoding specifically for Redis stream IDs, restricting resumed reads to entries with sequence numbers 0-9 to ensure unambiguous position round-tripping.
src/Redis/src/Eventuous.Redis · high confidence
Initial SQL Server event store implementation
Eventuous now supports Microsoft SQL Server as a persistence backend. This release introduces the core components for the SQL Server store, including a connection factory, a schema initializer that automatically creates database objects (stored procedures, tables) from embedded SQL scripts, and the main \SqlServerStore\ class that implements the event store interface using SQL Server-specific commands for appending, reading, and truncating streams.
src/SqlServer/src/Eventuous.SqlServer · high confidence
Initial SQL Server event store schema and stored procedures
This change introduces the foundational database schema and stored procedures for the SQL Server event store implementation. It adds the \\_\schema\\_\ namespace containing tables for \Streams\, \Messages\, and \Checkpoints\, along with a \StreamMessage\ table type. The included scripts provide core event store operations: \append\_events\ for writing events with optimistic concurrency control (throwing \WrongExpectedVersion\ on conflicts), \check\_stream\ for stream existence and version validation, \read\_all\_forwards\ for global event reading, \read\_stream\_forwards\ and \read\_stream\_backwards\ for stream-specific reads with position validation, \read\_stream\_sub\ for subscription-style reads, and \truncate\_stream\ for removing historical events up to a specific position.
src/SqlServer/src/Eventuous.SqlServer/Scripts · high confidence
Initial SQL Server subscription and checkpoint infrastructure
This change introduces the core SQL Server subscription components, including \SqlServerAllStreamSubscription\ for subscribing to all events, \SqlServerStreamSubscription\ for single-stream subscriptions, and \SqlServerCheckpointStore\ for persisting read positions. It also adds the necessary base classes and options records (\SqlServerSubscriptionBase\, \SqlServerStreamSubscriptionOptions\, \SqlServerCheckpointStoreOptions\) to enable these subscriptions to function with SQL Server, handling connection management, schema configuration, and transient error detection.
src/SqlServer/src/Eventuous.SqlServer/Subscriptions · high confidence
Initial implementation of Google PubSub producer
This change introduces the Google PubSub producer component, enabling the application to publish events to Google Cloud PubSub topics. The implementation includes the \GooglePubSubProducer\ class which handles message serialization and publishing, a \ClientCache\ for managing and reusing \PublisherClient\ instances per topic, and configuration options (\PubSubProducerOptions\, \PubSubProduceOptions\) for setting the project ID, configuring the client builder, managing topic creation, and specifying ordering keys or custom attributes. It also implements lifecycle management via \IHostedProducer\ to start and stop clients gracefully.
src/GooglePubSub/src/Eventuous.GooglePubSub/Producers · high confidence
Initial release of Eventuous.Domain core abstractions
This change introduces the foundational domain modeling components for the Eventuous framework. It adds the \Aggregate\<T\>\ base class, which manages event streams, versioning, and state transitions, along with the \State\<T\>\ record that provides a handler-based mechanism for applying events to state. The package also includes the \Id\ record for entity identification (replacing the deprecated \AggregateId\), a \DomainException\ type, and supporting infrastructure for exception messaging and validation.
src/Core/src/Eventuous.Domain · high confidence
Initial release of Google PubSub subscription support
This change introduces the \Eventuous.GooglePubSub\ package, providing a new subscription implementation for Google Cloud Pub/Sub. It adds \GooglePubSubSubscription\ and \PubSubSubscriptionOptions\ to allow users to consume events from Google Pub/Sub topics, supporting features like automatic subscription creation, custom client configuration, and configurable failure handling.
src/GooglePubSub/src/Eventuous.GooglePubSub/Subscriptions · high confidence
Introduce ElasticSearch event store implementation
This change adds a new ElasticSearch-backed event store to the library, introducing the \ElasticEventStore\ class that implements the \IEventStore\ interface for persisting and reading events. The implementation supports configurable index names via \ElasticEventStoreOptions\, stores events as JSON documents with a \Created\ timestamp mapped to \@timestamp\, and provides methods for appending events, reading forwards/backwards, and checking stream existence. A dedicated \ElasticSerializer\ handles type-aware serialization and deserialization using System.Text.Json, while the \PersistedEvent\ record defines the schema for stored events including message ID, type, stream position, and metadata.
src/Experimental/src/Eventuous.ElasticSearch/Store · high confidence
Introduce Redis-based event subscriptions with checkpointing
This change adds the core infrastructure for subscribing to events stored in Redis Streams. It introduces a base subscription class that handles polling, checkpoint management via a new Redis checkpoint store, and event deserialization. Two concrete implementations are provided: one for subscribing to a specific named stream and another for subscribing to the global all-stream, allowing users to consume events from Redis as part of their event sourcing architecture.
src/Redis/src/Eventuous.Redis/Subscriptions · high confidence
Introduce SQLite as a new event store and projection backend
Users can now persist events and manage read-model checkpoints using SQLite. This change adds the \Eventuous.Sqlite\ library, providing a \SqliteStore\ for event sourcing with automatic schema initialization (streams, messages, and checkpoints tables) via a hosted service. It includes DI registration extensions (\AddEventuousSqlite\) for easy setup, a \SqliteProjector\ base class for building read models, and subscription implementations (\SqliteAllStreamSubscription\, \SqliteStreamSubscription\) that track progress in the SQLite checkpoint store.
src/Sqlite/src · high confidence
Introduce SignalR subscription gateway for real-time event streaming
This update adds a new SignalR integration layer that allows clients to subscribe to event streams in real-time. It introduces a \SignalRSubscriptionHub\ for handling client connect/disconnect and subscription requests, backed by a \SubscriptionGateway\ that manages per-connection, per-stream event store subscriptions. The system includes DI registration extensions (\AddSignalRSubscriptionGateway\) to simplify setup, a \SignalRProducer\ to route serialized events to specific client connections, and a \SignalRTransform\ factory to convert internal event contexts into SignalR-compatible envelopes. Users can now expose their event store subscriptions over SignalR with minimal configuration.
src/SignalR/src/Eventuous.SignalR.Server · high confidence
Introduce Spyglass diagnostic API for inspecting aggregates and events
The Eventuous.Spyglass package now provides a built-in diagnostic API to inspect registered aggregates and load event data. Developers can enable this via the new \MapEventuousSpyglass\ extension, which registers endpoints for pinging the service, listing registered aggregate types, viewing the type mapping, and loading specific aggregate states and events by ID. The API supports optional access key authentication via the \X-Eventuous\ header, with automatic key generation in development environments and warnings if no key is provided in production. The underlying registry is now populated automatically via source-generated module initializers, making the previous \AddEventuousSpyglass\ DI registration obsolete.
src/Experimental/src/Eventuous.Spyglass · high confidence
Introduce type mapping system with source generation and reflection-free lookups
The Eventuous core now includes a dedicated TypeMap subsystem that decouples event/message type names from CLR type names, allowing safe renaming of event classes without breaking deserialization. This change introduces a new \ITypeMapper\ interface and a \TypeMapper\ implementation that supports both manual registration and automatic scanning of assemblies for types decorated with \EventTypeAttribute\. To improve performance and reduce runtime reflection overhead, a source generator has been added to handle context conversion, while the underlying \TypeMap\<TV\>\ structure uses index-based slot allocation for efficient lookups. The system also includes comprehensive exception handling via \DuplicateTypeException\ and \UnregisteredTypeException\, along with diagnostic event logging for registration and mapping failures.
src/Core/src/Eventuous.Shared/TypeMap · high confidence
Introduces SignalR wire-format contracts for stream subscriptions
New contract types have been added to define the communication protocol between SignalR clients and the server. This includes \SignalRSubscriptionMethods\ to standardize hub method names for subscribing, unsubscribing, and receiving events or errors, \StreamEventEnvelope\ to structure event data (including payload, position, and metadata) transmitted over the wire, and \StreamSubscriptionError\ to handle subscription failure notifications.
src/SignalR/src/Eventuous.SignalR.Server/Contracts · high confidence
Introduces structured producer API with acknowledgment callbacks and parallel multi-stream support
The Eventuous producers library now provides a new, structured API for publishing messages. Users can produce messages using extension methods that wrap payloads in a ProducedMessage struct, which supports OnAck and OnNack callbacks to handle success or failure outcomes explicitly. The IProducer interface and BaseProducer implementation now support producing to multiple streams in parallel via a ProduceRequest collection, allowing efficient batch operations across different destinations. Additionally, the library includes new registration extensions for dependency injection, simplifying producer setup in hosted services.
src/Core/src/Eventuous.Producers · high confidence
Introduction of Google PubSub support package
The Eventuous.GooglePubSub package has been added, providing integration with Google PubSub for event-driven applications. This includes a GooglePubSubSubscription for consuming events and a GooglePubSubProducer for publishing them, both of which support ordering keys. The package also introduces PubSubAttributes to configure message metadata mapping for event types, content types, and message IDs. Note that PubSub Lite is currently not supported due to the lack of a C\# SDK.
src/GooglePubSub/src/Eventuous.GooglePubSub · high confidence
Introduction of Kafka subscription configuration and base class
The Kafka integration now includes a dedicated options record, KafkaSubscriptionOptions, which exposes the underlying Confluent Kafka ConsumerConfig, and a base subscription class, KafkaBasicSubscription, that initializes the subscription with options, a consume pipe, and optional logging/serialization services. This establishes the foundational structure for Kafka-based event subscriptions within the library.
src/Kafka/src/Eventuous.Kafka/Subscriptions · high confidence
Introduction of SQL base event store and core data structures
This change introduces the foundational components for SQL-based event sourcing within the Eventuous library. It adds the \PersistedEvent\ record struct to represent events as stored in a relational database, including a new \Created\ timestamp field. A new \SqlEventStoreBase\ abstract class is provided as the base implementation for SQL event stores, handling connection management, transaction handling, and event serialization/deserialization. Additionally, a \UniversalProducer\ is added to allow appending events to streams via the event store, and \ReaderExtensions\ are introduced to facilitate reading events from ADO.NET \DbDataReader\ objects into the new \PersistedEvent\ format.
src/Relational/src/Eventuous.Sql.Base · high confidence
Introduction of a structured StreamName record type
A new \StreamName\ record struct has been added to the core store module to provide a strongly-typed, validated representation of stream identifiers. This type automatically generates stream names based on entity IDs and state types (e.g., stripping 'State' suffixes), parses stream values into categories and IDs, and enforces non-empty validation upon creation, replacing ad-hoc string handling with a dedicated, reusable type.
src/Core/src/Eventuous.Shared/Store · high confidence
KurrentDB subscription implementations for $all and specific streams
The subscription layer now includes concrete implementations for KurrentDB, providing catch-up subscriptions for both the global $all stream and specific named streams, as well as persistent subscriptions for both scopes. These components handle event consumption, checkpoint management, and server-side filtering, and include diagnostic measures to track subscription lag.
src/KurrentDB/src/Eventuous.KurrentDB/Subscriptions · high confidence
New Cloud Run Pub/Sub subscription endpoint
A new \CloudRunPubSubSubscription\ class and associated options have been added to the \Eventuous.GooglePubSub.CloudRun\ package, enabling the application to receive events via Google Cloud Pub/Sub push triggers on Cloud Run. This includes an extension method \MapCloudRunPubSubSubscription\ to register the HTTP POST endpoint, which deserializes incoming Pub/Sub messages, maps them to the Eventuous consume pipeline, and handles message attributes for content type and event identification.
src/GooglePubSub/src/Eventuous.GooglePubSub.CloudRun · high confidence
New DI registration extensions for event stores, aggregates, and logging
The Eventuous.Extensions.DependencyInjection package now provides a comprehensive set of extension methods for configuring services in the dependency injection container. Users can register event readers, writers, and stores (including tiered hot/archive configurations) via new AddEventReader, AddEventWriter, and AddEventStore methods, which also support diagnostic tracing. Aggregate registration is simplified with AddAggregate to handle dependencies, while AddCommandService registers application services. Additionally, a new AddEventuousLogs extension allows internal Eventuous event sources to be captured by the application's logging factory.
src/Extensions/src/Eventuous.Extensions.DependencyInjection · high confidence
New ElasticPlayground sample with tiered event storage
A new experimental playground project demonstrates integrating Eventuous with Elasticsearch and KurrentDB (EventStore). It provides sample implementations for using Elasticsearch as a standalone event store, as an archive tier, and in a combined tiered setup where KurrentDB serves as the hot store and Elasticsearch handles warm/cold/frozen tiers. The sample includes Docker Compose configuration to spin up a 4-node Elasticsearch cluster, Kibana, and KurrentDB, along with code for configuring the Elasticsearch index lifecycle management (ILM) policy and executing booking domain commands against these stores.
src/Experimental/src/ElasticPlayground · high confidence
New ElasticSearch producer for event streaming
Introduces the ElasticProducer class, enabling Eventuous to publish events directly to ElasticSearch data streams. This new component supports both 'Create' and 'Index' production modes, handles bulk operations via the ElasticClient, and implements specific error handling for version conflicts and message acknowledgments (Ack/Nack) to ensure reliable event delivery.
src/Experimental/src/Eventuous.ElasticSearch/Producers · high confidence
New Gateway message routing and transformation pipeline
The Eventuous Gateway now includes a new message routing and transformation system that allows incoming events to be transformed into zero or more outgoing messages before being produced to target streams. This change introduces a \RouteAndTransform\ delegate and \IGatewayTransform\ interface for defining custom transformation logic, a \GatewayHandler\ to orchestrate the processing, and a \GatewayProducer\ wrapper that ensures the underlying producer is ready before sending messages. Additionally, the original message context (including stream, position, and metadata) is preserved and attached to the produced messages via new helper classes and extension methods, enabling better traceability and context propagation in downstream consumers.
src/Gateway/src/Eventuous.Gateway · high confidence
New HTTP API endpoints for booking commands and queries
The sample application now exposes dedicated HTTP endpoints for managing bookings. A new CommandApi provides POST endpoints at /booking/book for creating bookings and /booking/recordPayment for registering payments, while a QueryApi exposes a GET endpoint at /bookings/{id} to retrieve booking state. These endpoints replace previous implementation patterns by directly handling commands and loading state via the event reader.
samples/postgres/Bookings/HttpApi · high confidence
New HTTP command mapping and result handling in AspNetCore
This change introduces a new set of components in the \Eventuous.Extensions.AspNetCore.Http\ namespace to simplify exposing domain commands as HTTP endpoints. It adds \CommandHttpApiBase\ for controller-based command handling, \CommandServiceRouteBuilder\ for fluent endpoint configuration, and extension methods on \IEndpointRouteBuilder\ (such as \MapCommand\ and \MapDiscoveredCommands\) to map commands to HTTP POST routes. The update includes \HttpCommandAttribute\ and \HttpCommandsAttribute\ for declarative command-to-route mapping, a \CommandMappingRegistry\ to support source-generated command discovery, and \ResultExtensions\ to automatically convert domain command results into appropriate HTTP responses (including ProblemDetails for errors). Additionally, a new \ExtensionsEventSource\ is added to log HTTP endpoint registration events for diagnostics.
src/Extensions/src/Eventuous.Extensions.AspNetCore/Http · high confidence
New KurrentDB Bookings sample with Aspire orchestration and blob storage projections
The \samples/kurrentdb\ area now includes a complete hotel booking sample consisting of a \Bookings.AppHost\ project that orchestrates the \Bookings\ and \Bookings.Payments\ services using .NET Aspire. The AppHost provisions a KurrentDB container, a MongoDB instance, and an Azure Blob Storage emulator, wiring them to the services. The \Bookings\ service demonstrates projecting event state to both MongoDB and Azure Blob Storage (using \BookingStateBlobProjection\), while the \Bookings.Payments\ service records payments and publishes integration events back to KurrentDB via an Eventuous gateway. The sample also includes Scalar API references for browsing the services' OpenAPI documentation and supports running with .NET Aspire or standalone via Docker Compose.
samples/kurrentdb · high confidence
New MongoDB document storage and query utilities
The MongoDB projection tools now include a set of new helper classes to simplify document persistence and retrieval. A base \Document\ record and a \ProjectedDocument\ record provide a standard structure for stored entities, including stream position tracking. \MongoCollectionName\ offers automatic, convention-based collection naming by stripping common suffixes like 'Document' or 'Projection'. \MongoDefaults\ registers BSON serialization conventions (camelCase, ignore nulls/extra elements) and sets default options for upserts and bulk writes. Finally, \MongoDatabaseExtensions\ and \MongoCollectionExtensions\ expose a fluent API for common operations, including loading documents by ID or bulk IDs, storing/replacing/updating documents, deleting documents, and performing bulk updates or writes.
src/Mongo/src/Eventuous.Projections.MongoDB/Tools · high confidence
New MongoDB projection and checkpoint infrastructure
The MongoDB projections package now provides a new \MongoProjector\ base class and a \MongoCheckpointStore\ for persisting subscription checkpoints. Users can register the checkpoint store to automatically manage subscription positions in a MongoDB collection, with configurable batch sizes and intervals for performance. The new projector API allows defining event handlers using a fluent builder (\MongoOperationBuilder\) that supports update, insert, delete, and bulk operations, with the ability to extract document IDs from events, streams, or context. This replaces the previous \MongoProjection\ class (now obsolete) and introduces functional delegates for building filters and updates, enabling more flexible and type-safe read model projections.
src/Mongo/src/Eventuous.Projections.MongoDB · high confidence
New OpenTelemetry integration for metrics and tracing
The Eventuous diagnostics package now provides explicit OpenTelemetry integration via new extension methods. Users can call \AddEventuousTracing\ on the \TracerProviderBuilder\ to register the Eventuous activity source, with sampling behavior left to the application's existing configuration. Additionally, \MeterProviderBuilder\ extensions allow users to enable metrics: \AddEventuousSubscriptions\ exposes subscription-specific metrics, while \AddEventuous\ adds metrics for core components like the command service and persistence layer. These changes introduce a new \DiagnosticName\ constant and internal visibility settings to support the instrumentation.
src/Diagnostics/src/Eventuous.Diagnostics.OpenTelemetry · high confidence
New PostgreSQL event store implementation with configurable schema and auto-initialization
The Eventuous PostgreSQL provider now includes a new \PostgresStore\ implementation that allows users to specify a custom database schema (defaulting to 'eventuous') via \PostgresStoreOptions\. This change introduces a \SchemaInitializer\ hosted service that automatically creates the necessary database objects on startup when the \InitializeDatabase\ option is enabled, simplifying setup for new environments.
src/Postgres/src/Eventuous.Postgresql · high confidence
New PostgreSQL subscription and checkpoint infrastructure
This change introduces the core PostgreSQL subscription components, including \PostgresAllStreamSubscription\ for subscribing to all events, \PostgresStreamSubscription\ for single-stream subscriptions, and \PostgresCheckpointStore\ for persisting subscription positions. It also adds \PostgresSubscriptionBase\ to handle connection management, transient error detection, and global subscription gap handling via tombstones. These classes provide the foundational mechanism for reading events from PostgreSQL using Npgsql, replacing previous implementations or adding initial support for this store type.
src/Postgres/src/Eventuous.Postgresql/Subscriptions · high confidence
New PostgresProjector base class for PostgreSQL read models
A new abstract PostgresProjector class has been introduced in the Eventuous.Postgresql library to serve as a base for projectors that store read models in PostgreSQL. This class extends the standard EventHandler and provides specialized methods (On) to register event handlers that project events into PostgreSQL commands, along with helper methods to create NpgsqlCommand instances from connection and parameter data.
src/Postgres/src/Eventuous.Postgresql/Projections · high confidence
New SQL Server projector for read models
A new SqlServerProjector base class and SqlServerConnectionOptions record have been added to the SQL Server projections module. This allows users to define read models that are updated via SQL commands, supporting both synchronous and asynchronous event handlers with proper connection management.
src/SqlServer/src/Eventuous.SqlServer/Projections · high confidence
New SQL subscription base with configurable gap handling and polling
Introduces SqlSubscriptionBase and SqlSubscriptionOptionsBase for relational database subscriptions, adding configurable polling intervals, retry delays, and concurrency limits. It implements global position gap detection for 'All' subscriptions, allowing users to configure a gap age threshold to ignore stale gaps and a gap handling timeout to trigger provider-specific remediation (such as tombstone insertion) or a gap skip timeout to abandon missing positions after a set duration.
src/Relational/src/Eventuous.Sql.Base/Subscriptions · high confidence
New SignalR subscription client with typed event handling and distributed tracing
The Eventuous SignalR client now includes a new \SignalRSubscriptionClient\ that allows subscribing to event streams over SignalR and consuming events as an async enumerable, with automatic reconnection handling when the connection drops. A companion \TypedStreamSubscription\ class enables registering type-specific handlers via \On\<T\>\ for automatic deserialization and dispatch, while an optional tracing feature (\EnableTracing\) links incoming events to their original producer context using distributed tracing links rather than parenting, ensuring trace continuity without creating unbounded trace trees.
src/SignalR/src/Eventuous.SignalR.Client · high confidence
New checkpointing infrastructure for subscriptions
The subscription subsystem now includes a dedicated checkpointing layer to track and persist processing progress. This introduces a new \ICheckpointStore\ interface and a \CheckpointCommitHandler\ that manages commit positions with gap detection and backpressure via a bounded channel worker, ensuring that checkpoint progression is not stalled by lost sequence numbers. The implementation includes a \MeasuredCheckpointStore\ for distributed tracing diagnostics and a \NoOpCheckpointStore\ for testing, allowing users to reliably resume subscriptions from the last committed position.
src/Core/src/Eventuous.Subscriptions/Checkpoints · high confidence
New distributed tracing and telemetry infrastructure
The Eventuous.Diagnostics module now provides a complete, OpenTelemetry-compatible foundation for distributed tracing and metrics. This includes a new ActivitySource and ActivityListener setup that automatically captures and propagates trace context (TraceId and SpanId) across service boundaries, ensuring that existing tracing data is not overridden during restoration. The update introduces standardized semantic conventions for tags (covering messaging, database, and exception details) and adds helper extensions to easily attach tracing metadata to events and manage activity status, enabling out-of-the-box observability for subscriptions and event handling.
src/Core/src/Eventuous.Diagnostics · high confidence
New fluent API for MongoDB projection operations
The MongoDB projection builder now exposes a new fluent API for constructing insert, update, delete, and bulk write operations. Users can now explicitly configure document insertion (single or multiple), filtering and updating documents (one or many), and deleting documents using a builder pattern that supports options like upserts, collation, and hints. This new API also introduces bulk operation support, allowing multiple write models to be combined and executed in a single bulk write call to MongoDB, improving performance for complex projection scenarios.
src/Mongo/src/Eventuous.Projections.MongoDB/Operations · high confidence
New gateway subscription registration extensions
The gateway now provides new \AddGateway\ extension methods in \GatewayRegistrations.cs\ that simplify registering event subscriptions with a producer. These methods allow developers to configure subscriptions with optional routing and transformation logic, either by passing a function directly, expecting it to be registered in the service collection, or providing a custom transform type. The extensions handle producer registration, hosted service setup, and event handler wiring automatically.
src/Gateway/src/Eventuous.Gateway/Registrations · high confidence
New metadata model and extension methods for correlation and causation tracking
The Eventuous core now introduces a dedicated Metadata class that wraps a dictionary of string keys and object values, providing type-safe accessors like Get\<T\> and GetString. This change adds a MetaTags class to define standard metadata keys (message-id, correlation-id, causation-id) and provides extension methods on Metadata to easily attach and retrieve correlation and causation IDs, simplifying the tracking of request context across distributed operations.
src/Core/src/Eventuous.Shared/Meta · high confidence
New metrics infrastructure for tracking operation duration and errors
The metrics subsystem now includes a new \Measure\ class that records the duration and error state of operations via \DiagnosticSource\, a \MetricsListener\ that consumes these events to populate Histogram and Counter metrics with context-specific tags, and a \GenericObserver\ helper to simplify reactive stream handling. This change provides a standardized way to instrument code paths for performance monitoring and error tracking without requiring manual metric recording at every call site.
src/Core/src/Eventuous.Diagnostics/Metrics · high confidence
New persistence primitives and stream naming infrastructure
The Eventuous.Persistence module introduces foundational types for event sourcing, including the \StreamEvent\ record (now containing a \Created\ timestamp), \NewStreamEvent\, and \NewStreamAppend\ structs to represent events and multi-stream appends. It adds \AggregateFactoryRegistry\ to allow customizing how aggregate instances are created, \StreamNameMap\ and \StreamNameFactory\ to provide flexible, type-aware stream name generation strategies, and supporting records like \ExpectedStreamVersion\, \StreamReadPosition\, \AppendEventsResult\, and \AmendEvent\ delegates to manage versioning, results, and event modification before storage.
src/Core/src/Eventuous.Persistence · high confidence
New shared utility extensions for validation, async context, and type inspection
This change introduces a new set of helper classes in the Eventuous.Shared.Tools namespace to standardize common operations across the library. The Ensure class provides static methods for null and empty-string validation with improved exception messaging via CallerArgumentExpression. TaskExtensions adds NoContext wrappers that automatically apply ConfigureAwait(false) to tasks, value tasks, async enumerables, and async disposables, helping to prevent deadlocks and reduce boilerplate in library code. It also includes optimized WhenAll implementations for collections of ValueTasks and a NoThrow extension for suppressing exception propagation. Finally, TypeExtensions offers a generic GetAttribute method to simplify retrieving custom attributes from types.
src/Core/src/Eventuous.Shared/Tools · high confidence
New source generator for IMessageConsumeContext conversions
A new source generator, ConsumeContextConverterGenerator, has been added to the Eventuous.Subscriptions.Generators package. It automatically creates static conversion logic from IMessageConsumeContext to IMessageConsumeContext\<T\> for all event types T detected in consumer code, handling both explicit generic usages and implicit lambda parameter inference. The generator ensures type safety by emitting switch arms ordered by type specificity and uses fully qualified names to avoid namespace conflicts.
src/Core/gen/Eventuous.Subscriptions.Generators · high confidence
New static analysis and code generation for HTTP command mappings
The generator extension now includes an incremental source generator and Roslyn analyzer for HTTP commands. The analyzer introduces four new diagnostics (EVTA001–EVTA004) that warn or error on state generic type mismatches, route override mismatches, duplicate routes, and parent state type mismatches. The generator automatically produces registration code for HttpCommand-decorated types, ensuring commands are correctly mapped to their state types and routes at compile time.
src/Extensions/gen · high confidence
New subscription diagnostics: metrics, health checks, and tracing
The subscription subsystem now includes built-in observability. SubscriptionMetrics exposes OpenTelemetry gauges and histograms for processing duration, error counts, checkpoint queue length, and the gap (lag) between the last processed event and the stream tail. SubscriptionHealthCheck integrates with Microsoft.Extensions.Diagnostics.HealthChecks to report whether subscriptions are healthy or have dropped, including the last exception. SubscriptionActivity standardizes distributed tracing for message consumption, correctly linking to remote trace contexts from message metadata rather than incorrectly parenting to unrelated ambient spans, and enriches spans with message and stream tags. CheckpointCommitMetrics tracks checkpoint commit positions to support the gap and queue-length metrics, while SubscriptionsEventSource emits verbose/warning events for checkpoint anomalies (gaps, duplicates, invalid heads) and metric collection failures.
src/Core/src/Eventuous.Subscriptions/Diagnostics · high confidence
New tiered event store and refined stream operations
The Event Store now supports a TieredEventStore that reads from both a hot store (recent events) and an archive store (older events), allowing applications to query across both tiers while appending only to the hot store. The IEventReader interface has been updated to return IAsyncEnumerable instead of materialized arrays, enabling true streaming reads with better memory efficiency. New exception types (StreamNotFound, AppendToStreamException, etc.) provide more specific error handling for stream operations. The StoreFunctions class offers helper methods for storing events with optional amendment functions and reading streams with configurable failure behavior.
src/Core/src/Eventuous.Persistence/EventStore · high confidence
Repository initialization with core structure and documentation
The repository has been initialized with the Eventuous Event Sourcing library for .NET, including the new .slnx solution file that organizes core packages (Domain, Persistence, Application, Subscriptions, Producers, Serialization), integrations (EventStoreDB, PostgreSQL, SQL Server, MongoDB, RabbitMQ, Kafka, Google Pub/Sub, Azure Service Bus), and experimental features (Spyglass, Redis). The project targets .NET 8, 9, and 10, uses the TUnit test framework with Microsoft.Testing.Platform, and includes source generators for context conversion and type mapping. Standard development infrastructure is added, including .editorconfig for consistent code formatting, .dockerignore, .gitattributes, and a docker-compose.yml for local development services (EventStoreDB, PostgreSQL, MongoDB, RabbitMQ, Kafka). Documentation and community guidelines are established via README.md, CONTRIBUTING.md, CODE\_OF\_CONDUCT.md, and CLAUDE.md for AI agent guidance.
(repo-wide) · high confidence
Simplified SQL Server integration via new registration extensions
The SQL Server provider now offers streamlined dependency injection setup through new extension methods in the \Extensions\ folder. \RegistrationExtensions.cs\ introduces \AddEventuousSqlServer\ for registering the event store and schema initializer via connection string or configuration, along with \AddSqlServerCheckpointStore\ for checkpointing. \SqlExtensions.cs\ provides internal helpers for building SQL commands, including support for table-valued parameters to persist events efficiently.
src/SqlServer/src/Eventuous.SqlServer/Extensions · high confidence
Structured tracing and metrics for event store operations
The persistence layer now automatically instruments event store interactions with distributed tracing and metrics. New wrapper classes (TracedEventReader, TracedEventWriter, TracedEventStore) intercept reads, writes, and stream management, emitting OpenTelemetry activities and performance metrics for each operation. This allows users to observe the health and latency of their event sourcing infrastructure without manual instrumentation.
src/Core/src/Eventuous.Persistence/Diagnostics/Tracing · high confidence
Removals
Removal of CoreLib event-sourcing infrastructure
The core event-sourcing abstractions and their implementations have been removed from the codebase. This includes the deletion of the \CoreLib\ base classes for aggregates, aggregate states, and IDs, as well as the \AggregateStore\ and \ApplicationService\ logic that managed persistence and command handling. The specific storage implementations for EventStoreDB (\EventStore.cs\) and MongoDB (\MongoCheckpointStore.cs\, \MongoProjection.cs\) have also been deleted, along with supporting types like \IEventStore\, \IEventSerializer\, \StreamEvent\, and \TypeMap\. This change eliminates the existing event-sourcing framework and its database-specific backends.
src/CoreLib, src/CoreLib.EventStoreDB, src/CoreLib.MongoDB · high confidence
Behavioural changes
AggregateStore is deprecated in favor of IEventReader/IEventWriter extensions
The AggregateStore API is now obsolete and marked for removal. Users should migrate to the new extension methods on IEventReader and IEventWriter, specifically LoadAggregate and StoreAggregate, which provide the same functionality for loading and persisting aggregates. The old AggregateStore class and its interface IAggregateStore are now deprecated, with all their methods pointing to the new extension-based approach.
src/Core/src/Eventuous.Persistence/AggregateStore · high confidence
Command service handler registration refactored to a fluent builder API
The CommandService now uses a fluent builder pattern (On\<TCommand\>().InState(...).GetId(...).Act(...)) for registering command handlers, replacing the previous OnNew/OnExisting/OnAny methods which are now obsolete. This change allows developers to explicitly define the expected aggregate state (New, Existing, Any), customize how the aggregate ID is extracted, and optionally resolve specific event readers/writers or amend events per command, providing finer control over command execution and store resolution.
src/Core/src/Eventuous.Application/AggregateService · high confidence
Deprecation of IStateStore in favor of IEventReader extension functions
The IStateStore interface and its implementation are now obsolete; users should use the new IEventReader extension functions (LoadState) to load aggregate state. The new approach returns a FoldedEventStream containing both the events and the computed state, providing a more direct way to read and reconstruct state from event streams without initializing the aggregate itself.
src/Core/src/Eventuous.Persistence/StateStore · high confidence
Introduce RabbitMQ subscription service with configurable exchange, queue, and binding options
The RabbitMQ subscription implementation has been refactored to use a dedicated \RabbitMqSubscriptionOptions\ record, allowing users to explicitly configure the exchange name, exchange settings (type, durability, auto-delete), queue settings (name, durability, exclusive, auto-delete), and binding options (routing key, arguments). The subscription service now manages the lifecycle of the RabbitMQ connection and channel, ensuring proper declaration and binding of exchanges and queues, and supports configurable concurrency limits and prefetch counts to control message consumption rates. A custom failure handler can be provided to manage event processing errors, and the subscription respects the \ThrowOnError\ option to determine whether to fail the run or continue processing on errors.
src/RabbitMq/src/Eventuous.RabbitMq/Subscriptions · high confidence
Introduce compile-time Spyglass source generator for automatic API registration
The Eventuous Spyglass API now uses a Roslyn incremental source generator to discover aggregates and standalone state types at compile time, replacing the previous reflection-based runtime discovery. This change eliminates the need for manual dependency injection registrations, as the generator emits a ModuleInitializer that automatically registers all discovered types into the SpyglassRegistry at application startup, supporting both traditional aggregate classes and functional aggregate-less state patterns.
src/Experimental/gen · high confidence
Introduces Result-based command handling and AOT-compatible serialization
The application layer now returns a \Result\<TState\>\ from command handling instead of throwing exceptions directly, allowing callers to inspect success or error states explicitly via \TryGet\ or \Match\. A \ThrowingCommandService\ wrapper is provided for users who prefer the previous exception-throwing behavior. Additionally, the serialization layer now supports Ahead-Of-Time (AOT) and trimming scenarios through \DefaultStaticEventSerializer\ (using \JsonSerializerContext\), while the existing \DefaultEventSerializer\ remains for reflection-based usage.
src/Core/src/Eventuous.Application · high confidence
Introduction of Kafka Basic Producer with explicit type mapping
The Kafka producer implementation has been updated to use a basic producer that sends messages with byte\[\] payloads without relying on a schema registry. Instead, the message type is specified in the headers, requiring explicit type mapping for serialization. This change introduces new configuration options for partition keys and producer settings, and ensures proper handling of message acknowledgments and nacknowledgments through the Kafka producer's reporting mechanism.
src/Kafka/src/Eventuous.Kafka/Producers · high confidence
New Azure Service Bus producer implementation with batch support and message options
The Azure Service Bus producer has been replaced with a new implementation that supports sending messages in batches for improved performance, configurable message properties (such as SessionId, ScheduledEnqueueTime, and TimeToLive) via ServiceBusProduceOptions, and custom application properties derived from message metadata while filtering out non-serializable values.
src/Azure/src/Eventuous.Azure.ServiceBus/Producers · high confidence
New ProposedAppend model and WriterExtensions for stream persistence
The persistence layer now uses a new \ProposedAppend\ record struct (along with \ProposedEvent\) to represent pending stream writes, replacing or preceding the previous internal representation. A new \WriterExtensions\ class provides \Store\ methods that accept these \ProposedAppend\ objects, handling the conversion to \NewStreamEvent\ instances, applying optional event amendments, and wrapping optimistic concurrency failures (\WrongExpectedVersion\) into \OptimisticConcurrencyException\. This change introduces a specific data structure for proposed appends and the extension logic to persist them, including multi-stream support via the collection-based \Store\ overload.
src/Core/src/Eventuous.Application/Persistence · high confidence
New analyzer warns when domain events lack the \[EventType\] attribute
The Eventuous source generator now includes the EVTC001 analyzer, which flags any type used as a domain event (e.g., passed to \Aggregate.Apply\, \State.When\, or handler registrations) that is not decorated with the \\[EventType\]\ attribute. This ensures the type mapper can resolve the event correctly. The analyzer is smart enough to suppress this warning if the event type has been explicitly registered via \TypeMapper.AddType\, preventing false positives for manually configured mappings.
src/Core/gen/Eventuous.Shared.Generators · high confidence
New channel-based subscription workers with hardened shutdown
The subscription system now uses a new channel-based architecture in the Channels module, introducing \ChannelWorkerBase\ and specific implementations (\ConcurrentChannelWorker\, \BatchedChannelWorker\) to manage background processing. This change adds extension methods for reading single elements or batches from channels and implements a robust, idempotent disposal mechanism that prevents double-dispose crashes and ensures graceful worker termination with timeout handling.
src/Core/src/Eventuous.Subscriptions/Channels · high confidence
New functional command service with fluent handler configuration
The functional command service has been refactored to use a fluent builder pattern for defining command handlers. Users now configure handlers via \On\<TCommand\>().InState(...).GetStream(...).Act(...)\, which replaces the previous \OnNew\, \OnExisting\, and \OnAny\ methods that are now obsolete. This change introduces \CommandHandlerBuilder\ and \CommandService\ classes that support resolving specific event readers and writers per command, amending events before storage, and handling expected stream states (New, Existing, Any) with explicit validation.
src/Core/src/Eventuous.Application/FunctionalService · high confidence
New subscription consumer infrastructure with optimized context conversion
The subscription consumption pipeline has been refactored to use a new \DefaultConsumer\ and \IMessageConsumer\ interface, replacing previous implementations. This change introduces a structured logging scope for every consumed message and implements explicit acknowledgment, ignoring, or negative-acknowledgment (Nack) logic based on the result of event handlers. To improve performance, a new \MessageConsumeContextConverter\ is included, which supports registering fast-path converters (intended for source generators) before falling back to a cached, compiled expression-based constructor invocation, thereby reducing reflection overhead during message processing.
src/Core/src/Eventuous.Subscriptions/Consumers · high confidence
New subscription filter pipeline with async handling and partitioning
The subscription processing model has been refactored to use a new \ConsumePipe\-based filter chain. This introduces an \AsyncHandlingFilter\ that manages concurrent message processing with configurable limits and buffer sizes, ensuring proper cancellation token linking and error handling. A \PartitioningFilter\ is now available to distribute messages across multiple partitions based on a configurable key and hash function, each with its own async handler. The pipeline includes built-in \TracingFilter\ support for distributed tracing via \System.Diagnostics.Activity\, and a \MessageFilter\ for conditional message routing. This change replaces the previous synchronous or less structured handling mechanism with a composable, type-safe filter architecture.
src/Core/src/Eventuous.Subscriptions/Filters · high confidence
Refactored message consumption context with explicit handling results and baggage
The subscription context model has been restructured to decouple message acknowledgment from processing logic and provide granular control over handler outcomes. Consumers now receive a context that explicitly tracks per-handler results (success, failure, or ignore) via the new \HandlingResults\ collection, allowing the system to determine final message status based on individual handler reports rather than a single global outcome. The context also introduces a \ContextItems\ baggage for passing arbitrary data through the processing pipeline and supports delayed acknowledgment via \AsyncConsumeContext\, enabling asynchronous transport interactions. Additionally, helper extensions simplify accessing nested context types and managing diagnostic activity status.
src/Core/src/Eventuous.Subscriptions/Context · high confidence
Simplified PostgreSQL event store registration with configurable data source builder
The library now provides a streamlined way to register the PostgreSQL event store and checkpoint store via the new \AddEventuousPostgres\ and \AddPostgresCheckpointStore\ extension methods. Users can register the store using either a connection string or an \IConfiguration\ section, with optional support for initializing the database schema on startup. A key addition is the \configureBuilder\ callback, which allows users to customize the underlying \NpgsqlDataSourceBuilder\ (e.g., for logging or custom type mapping) during registration. The registration also handles the lifetime of connections and data sources, defaulting to transient connections and singleton data sources.
src/Postgres/src/Eventuous.Postgresql/Extensions · high confidence
Simplified command service implementation for bookings
The BookingsCommandService has been refactored to use a simplified, fluent API for defining command handlers. The service now explicitly registers handlers for 'BookRoom' and 'RecordPayment' commands using a chainable syntax that specifies expected states and ID extraction, replacing the previous aggregate store approach. This change streamlines how booking commands are processed within the application layer.
samples/postgres/Bookings/Application · high confidence
Structured logging for subscriptions and checkpoints
Subscription and checkpoint operations now emit structured logs via a new logging subsystem. Users will see detailed trace, debug, and info messages for subscription lifecycle events (start, stop, resubscribe, drop) and message processing (received, handled, ignored, failed), along with checkpoint store interactions (loaded, stored, committed). Each log entry is scoped to the specific subscription ID, and errors include exception details to aid in diagnosing deserialization failures, handler issues, and connection problems.
src/Core/src/Eventuous.Subscriptions/Logging · high confidence
Subscription event handlers now return explicit handling status
The subscription handler pipeline has been refactored so that event handlers return an EventHandlingStatus (Success, Failure, Ignored, or Pending) instead of void. This allows the subscription system to distinguish between successfully processed events, ignored events, and failures, enabling proper acknowledgment and error handling. The new architecture includes a TracedEventHandler that wraps handlers to emit metrics and distributed tracing activities, and a base EventHandler class that supports registering typed handlers for specific event types.
src/Core/src/Eventuous.Subscriptions/Handlers · high confidence
Subscription handlers and services are now isolated using keyed dependency injection
The subscription registration system has been refactored to use keyed service registrations, allowing multiple subscriptions to coexist without handler conflicts. Event handlers, checkpoint stores, serializers, and type mappers are now registered with a unique subscription ID key, ensuring that each subscription resolves its own isolated set of components. This change enables factory-registered handlers to be kept separate per subscription and allows users to configure different checkpoint stores, serializers, and type mappers for individual subscriptions via the builder extensions.
src/Core/src/Eventuous.Subscriptions/Registrations · high confidence
Subscription lifecycle and checkpointing restructured
The subscription engine has been refactored to use a new supervisor-based lifecycle model. Subscriptions now manage their own runs via \EventSubscription\, which handles automatic resubscription on drops (distinguishing between server and subscription errors) and ensures graceful teardown with ordered resource release. Checkpointing is now tightly coupled to individual runs in \EventSubscriptionWithCheckpoint\, ensuring that acknowledgments are committed by the specific run that processed the event, preventing race conditions during resubscription. A new \DropReason\ enum and \OnDropped\ callback provide explicit visibility into why a subscription stopped, while \SubscriptionHostedService\ integrates these subscriptions into the .NET \IHostedService\ lifecycle.
src/Core/src/Eventuous.Subscriptions · high confidence
Test coverage
Added AspNetCore test scaffolding for booking domain; Added Booking aggregate domain model for testing; Added KurrentDB integration tests; Added KurrentDB test fixtures and infrastructure; Added Postgres test fixture for integration tests; Added Redis test fixtures for integration and subscription testing; Added SQL Server subscription test coverage; Added SQL Server test fixture; Added TUnit logging helpers for test output; Added base fixture for OpenTelemetry subscription metrics testing; Added base test fixtures for persistence integration testing; Added base test suite for subscription reliability and diagnostics; Added comprehensive test coverage for subscription lifecycle and checkpointing; Added end-to-end integration tests for SignalR subscriptions; Added integration tests for Azure Blob Storage projector; Added integration tests for Azure Service Bus producers and subscriptions; Added integration tests for Google Pub/Sub producer and subscription; Added integration tests for Kafka producer functionality; Added integration tests for RabbitMQ subscription and error handling; Added integration tests for Redis event store append and read operations; Added integration tests for SQL Server projections; Added metrics tests for KurrentDB subscriptions; Added parallel execution limiter for Postgres integration tests; Added subscription performance benchmarks; Added subscription test fixtures for handler failure recovery and tracing; Added test application for command service validation; Added test coverage for KurrentDB store operations; Added test coverage for the SQLite event store and subscriptions; Added test fakes for OpenTelemetry metrics and event handling; Added test fixture for AspNetCore HTTP command integration; Added test fixtures for ID generation and command creation; Added test fixtures for MongoDB projection tests; Added test fixtures for dependency injection scenarios; Added test helper utilities for TUnit; Added test helper utilities for tracing, reflection, and JSON serialization; Added tests for ASP.NET Core command mapping and analyzer diagnostics; Added tests for KurrentDB subscription checkpointing and failure handling; Added tests for MongoDB projection context conversion and bulk operations; Added tests for OpenTelemetry subscription gap metrics; Added tests for PostgreSQL subscription gap handling and resubscription; Added tests for Postgres event store and tiered store; Added tests for Postgres event store registration; Added tests for Postgres projector integration; Added tests for Postgres stream subscription metrics; Added tests for Redis subscription polling failures and event consumption; Added tests for SignalR tracing, subscription gateway, and typed subscriptions; Added tests for aggregate factory registration; Added tests for booking payment and state validation; Added tests for command service state handling and event amendments; Added tests for diagnostics initialization order and metrics registration; Added tests for the EventUsageAnalyzer (EV001); Added tests for the Spyglass API and source generator; Added unit tests for Gateway metadata extraction, multi-stream production, and DI registration; Added unit tests for SQL Server event store registration; Added unit tests for core Eventuous components; Expanded base test coverage for event store append, read, and tiered operations; Expose internal members to test assemblies; New testing utilities for aggregate and command service verification.
Dependencies
Adopts centralized package versioning and upgrades to .NET 10
The project now uses a centralized package versioning file (Directory.Packages.props) to manage dependency versions across all projects. This change includes upgrading the target framework to .NET 10, updating the KurrentDB client to version 1.4.1, and upgrading the Npgsql driver to version 10.0.3. Additionally, the Testcontainers library has been updated to version 4.13.0, and the TUnit test framework is now at version 1.63.0.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 67.
Lenses
- Code Health 78
- Architecture 83
- Maturity 74
- Readiness 57
- Security 73
- Domain Modelling 100
- Performance 85
Changes since last survey
- 300 commits — 240 feature/other, 60 fixes
By area
- src/Core — 65 commits
- .github/workflows — 46 commits
- docs/src — 27 commits
- (repo) — 23 commits
- src/Azure — 18 commits
- (root) — 15 commits
- docs/superpowers — 11 commits
- src/SignalR — 11 commits
- docs/astro.config.mjs — 8 commits
- samples/kurrentdb — 7 commits
- src/Postgres — 7 commits
- docs/versioned_docs — 6 commits
- src/KurrentDB — 6 commits
- docs/docs — 5 commits
- docs/pnpm-lock.yaml — 5 commits
- samples/postgres — 5 commits
- src/EventStore — 4 commits
- src/Gateway — 4 commits
- src/Sqlite — 4 commits
- src/Extensions — 3 commits
Notable commits
- fix: Bug in Functional command service, Proposed event was being passed to state.When(), which expects the raw event data. Would be nice to support both the raw event and event with metadata (ProposedEvent) (#411)
- fix: Cleanup and docs fix
- fix: Fix #406 System.ArgumentException: A PostgreSQL type with the name 'bookings.stream_message' was not found in the current database info at Npgsql.Internal.NpgsqlDatabaseInfo.GetPostgresType(DataTypeName dataTypeName) This is caused by the Npgsql internal info cache not getting updated after initial database creation. Previously, restarting the app a second time would work successfully because the info cache could see the user defined type for the booking.stream_message on the second run. Simple fix is to force the info cache to reload after database initialization
- fix: Fix AddCompositionEventHandler DI registration with factory functions (#462)
- fix: Fix Dependabot security alerts by updating docs dependencies
- fix: Fix PostgreSQL read_stream_backwards guard clause and add backwards read tests (#464)
- fix: Fix RabbitMQ queue binding and Gateway GetOriginalStream (#498)
- fix: Fix TraceEnumerable to record errors on failed enumeration
- fix: Fix archive order (#382)
- fix: Fix issue 427 (#433)
- fix: Fix more samples
- fix: Fix persistent subscription failure handler never being invoked (#546)
- fix: Fix plan: use GatewayHandlerFactory.Create (internal class), fix pipe assembly
- fix: Fix pre-existing bugs in TieredEventReader and ElasticEventStore
- fix: Fix resubscribe race (#571)
- fix: Fix sample
- fix: Fix samples
- fix: Fix source generator emitting global::T for generic type parameters
- fix: Fix source generator event type detection (#538) (#542)
- fix: Fix source generators not included in NuGet packages
- …and 280 more
API surface
- 11 HTTP endpoints (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Eventuous/eventuous was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 21 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 91798851431bbd06b4fb46793c5cc0c7e18cf310 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-28e75b8e3254.