ocoda/event-sourcing
55.4
Adequate · 4 August 2026
8.1k
lines of production code
TypeScript
primary language
3
measurements over time
What this system is
This is a modular event sourcing framework for NestJS that provides a complete foundation for implementing CQRS and event-driven architectures. It offers a core library with command, query, and event buses, along with domain models and decorators, while supporting multiple storage backends including in-memory, PostgreSQL, MariaDB, MongoDB, and DynamoDB. The system enables developers to build applications that persist state through event streams and snapshots, with comprehensive testing utilities and benchmarking infrastructure to validate performance across different integrations.
Features
Add ExplorerService for introspecting event sourcing providers
A new ExplorerService has been introduced to inspect and collect registered handlers, publishers, subscribers, and serializers within the event sourcing module. This service scans NestJS modules to gather metadata about commands, queries, events, and related components, enabling the framework to introspect the current state of registered providers.
packages/core/lib/services · high confidence
Add MariaDB event and snapshot store integrations
Introduced new MariaDB integrations for both event sourcing and snapshot storage. The changes add \MariaDBEventStore\ and \MariaDBSnapshotStore\ classes that manage database connections, create required tables, and implement methods for reading, writing, and listing collections. The implementation includes optimistic version locking to prevent concurrent write conflicts, supports batched reading of events and snapshots, and exposes configuration interfaces for connecting to a MariaDB database.
packages/integration/mariadb/lib · high confidence
Add Postgres integration for event and snapshot stores
Introduced a new Postgres-based implementation for both the event store and snapshot store. The event store now persists events in a table with columns for stream\_id, version, event, payload, and various metadata fields (occurred\_on as TIMESTAMPTZ, etc.), with appropriate indexes. The snapshot store similarly persists snapshots with columns for stream\_id, version, payload, and aggregate metadata. Both stores implement connection pooling, collection management, and query methods for reading and writing events and snapshots, effectively providing a new database-backed storage backend for the event-sourcing framework.
packages/integration/dynamodb/lib, packages/integration/postgres/lib, packages/integration/postgres/lib/interfaces · high confidence
Add benchmarking scripts for multiple event-sourcing backends
The benchmarks/lib directory now includes new files that set up benchmarking scripts for various event-sourcing backends, including DynamoDB, in-memory, MariaDB, MongoDB, and Postgres. Each backend-specific file configures the corresponding event and snapshot stores and invokes a shared bootstrap function to start the server, enabling users to run performance tests against different storage implementations.
benchmarks/lib · high confidence
Add demo application showcasing event sourcing with MongoDB
Introduces a demo application in the \example/src\ directory that demonstrates the new modular event sourcing architecture. The example includes a \CatalogueModule\ for managing books (with commands to add, remove, and query books) and a \LoaningModule\ for managing book loans (with commands to create, extend, and return loans). Each module registers its own event handlers, query handlers, and snapshot repositories, wired via a shared \EventSourcingModule\ configured with MongoDB event and snapshot stores.
example/src · high confidence
Add in-memory snapshot store implementation
An in-memory implementation of the snapshot store is now available for development and testing purposes. This new component provides an in-memory data store for snapshots, supporting operations like retrieving, appending, and listing snapshots in memory, which allows for faster, non-persistent snapshot storage during testing or local development.
packages/core/lib/integration/snapshot-store · high confidence
Added command and query interface definitions
The core library now exposes a set of TypeScript interfaces for commands and queries, including buses, handlers, metadata, and publishers. This provides a standardized contract for executing commands and queries within the application, enabling consistent integration with the CQRS (Command Query Responsibility Segregation) pattern.
packages/core/lib/interfaces/commands, packages/core/lib/interfaces/queries · high confidence
Added initial benchmarking infrastructure and reporting
Introduced a new benchmarking suite in the \benchmarks\ directory to evaluate performance across different storage integrations (in-memory, DynamoDB, MariaDB, MongoDB, and Postgres). The change adds an Artillery load-test configuration (\artillery.yml\) that simulates user traffic against the application, a Node.js runner (\benchmark.js\) to orchestrate the tests, and a reporting script (\report-benchmark.js\) that generates a Markdown table comparing request rates and response times against the in-memory baseline. The setup includes necessary build configuration (\tsup.config.ts\, \tsconfig.json\) and Turborepo task definitions (\turbo.json\) to automate the benchmarking and reporting workflow.
benchmarks · high confidence
DynamoDB and MongoDB integrations are now standalone packages
The DynamoDB and MongoDB integration modules have been moved into their own separate packages (\@ocoda/event-sourcing-dynamodb\ and \@ocoda/event-sourcing-mongodb\). This change includes adding independent build configurations, test setups, and publishing metadata for each integration, allowing them to be versioned and released independently from the core library.
packages/integration/dynamodb, packages/integration/mongodb · high confidence
Introduce application-level exception classes for command, query, and event handling
The core library now provides a comprehensive set of application exceptions in the \packages/core/lib/exceptions/application\ directory. These include specific error types for missing or invalid command and query handlers, missing metadata for aggregates, commands, queries, events, and snapshots, as well as exceptions for unregistered events and serializers. This change improves error handling by providing distinct exception classes that help developers identify and resolve issues related to command/query handler registration, event handling, and metadata configuration.
packages/core/lib/exceptions/application · high confidence
Introduce event sourcing module configuration interfaces
Added new TypeScript interfaces for configuring the event sourcing module, including \EventSourcingModuleOptions\ which allows optional global event registration, and async/dynamic module options for flexible configuration.
packages/core/lib/interfaces/module · high confidence
Introduce modular event sourcing core with command, query, and event buses
The core library now provides a complete event sourcing foundation, introducing \CommandBus\, \QueryBus\, and \EventBus\ to handle command and query dispatching alongside event publishing. The \EventSourcingModule\ and \EventSourcingCoreModule\ manage the lifecycle of \EventStore\ and \SnapshotStore\ implementations, automatically registering handlers, subscribers, and serializers. This change enables developers to integrate event sourcing into their applications by configuring the core module and defining event and snapshot stores.
packages/core/lib · high confidence
MongoDB integration for event and snapshot stores
Added MongoDB implementations for the event store and snapshot store, including the necessary interfaces, configuration types, and store classes. The event store supports appending and retrieving events with optimistic version locking, while the snapshot store manages aggregate snapshots with similar concurrency controls. Both stores handle collection creation, indexing, and error handling for MongoDB operations.
packages/integration/mongodb/lib · high confidence
New MariaDB integration package for event sourcing
A new \@ocoda/event-sourcing-mariadb\ package has been added to the repository, providing a MariaDB driver for the event-sourcing library. This release includes the initial boilerplate code, configuration files (such as \tsconfig.json\, \jest.config.js\, and \turbo.json\), and supporting assets like \README.md\ and \biome.json\. The package is structured to export from a \dist\ folder and relies on the core \@ocoda/event-sourcing\ module.
packages/integration/mariadb · high confidence
New PostgreSQL integration package for event sourcing
A new \@ocoda/event-sourcing-postgres\ package has been added to provide a PostgreSQL-based event store implementation. This release includes the core library files, configuration files (TypeScript, Jest, Biome, Turbo), and supporting documentation (README, CHANGELOG). The package is structured to integrate with the existing \@ocoda/event-sourcing\ core, enabling users to persist events to a PostgreSQL database.
packages/integration/postgres · high confidence
New aggregate and snapshot interfaces for improved type safety
The core library now exposes a comprehensive set of TypeScript interfaces and types for aggregate metadata, snapshot repositories, and snapshot stores. This includes the \AggregateMetadata\ interface for decorator metadata, \ISnapshotRepository\ for serializing and deserializing aggregate states, and \SnapshotStoreDriver\ for managing snapshot collections. These changes provide a more robust and type-safe foundation for working with aggregate roots and their snapshots.
packages/core/lib/interfaces/aggregate · high confidence
New default implementations for command, event, and query publishing and serialization
The core library now provides default, out-of-the-box implementations for publishing commands, events, and queries using RxJS Observables, alongside a default event serializer. Specifically, \DefaultCommandPubSub\, \DefaultEventPubSub\, and \DefaultQueryPubSub\ classes are introduced to handle message routing via RxJS subjects. Additionally, \DefaultEventSerializer\ is added to handle event serialization using \class-transformer\. These helpers are exported from the \packages/core/lib/helpers\ module, enabling users to quickly integrate basic messaging and serialization without writing custom infrastructure code.
packages/core/lib/helpers · high confidence
New domain models for event sourcing and identity management
The models package now introduces core domain primitives for event sourcing and identity management. A new \AggregateRoot\ base class manages event application and versioning, while \EventEnvelope\ and \SnapshotEnvelope\ provide structured containers for event and snapshot data. Identity handling is expanded with new \Id\, \ULID\, and \UUID\ value objects, alongside \EventStream\ and \SnapshotStream\ classes that define stream routing for aggregates. These additions establish the foundational building blocks for the system's event-driven architecture.
packages/core/lib/models · high confidence
New event system interfaces and types
The \packages/core/lib/interfaces/events\ directory now contains a comprehensive set of new interfaces and types for the event system, including \IEventBus\, \IEventPublisher\, \IEventSubscriber\, \IEventSerializer\, and \EventStoreDriver\. It also introduces filtering capabilities via \IEventFilter\ and \IAllEventsFilter\, along with metadata interfaces for handlers, subscribers, and serializers. These changes establish the core contracts for event publishing, subscription, serialization, and storage within the core library.
packages/core/lib/interfaces/events · high confidence
New integration exception classes for event and snapshot stores
Six new exception classes have been added to the core library's integration layer to provide specific error handling for event and snapshot store operations. These include exceptions for collection creation and persistence failures, as well as version conflicts for both event and snapshot streams. This allows developers to catch and handle these specific integration errors more precisely.
packages/core/lib/exceptions/integration · high confidence
Behavioural changes
Add in-memory event store implementation with optimistic locking
The in-memory event store implementation now supports listCollections for enumerating event collections and enforces optimistic locking on the appendEvents method to prevent version conflicts. Additionally, the implementation catches and rethrows persistence errors to ensure consistent error handling.
packages/core/lib/integration/event-store · high confidence
Centralized exception exports in core library
The core library now exports all exception classes from a single index file, consolidating the public API for application, domain, and integration errors. This makes it easier for consumers to import all available exceptions from one location.
packages/core/lib/exceptions · high confidence
Centralized type exports for core interfaces
The core library now exposes all interface types through a single entry point at packages/core/lib/interfaces/index.ts. This change consolidates the public API for aggregates, commands, events, modules, and queries, allowing consumers to import these types from one location rather than navigating the internal directory structure.
packages/core/lib/interfaces · high confidence
Configure example project with build and tooling setup
The example project is now fully configured for development and building. A new tsup build configuration is added to compile the main entry point to CommonJS, and a tsconfig.json is introduced that extends the shared @ocoda/event-sourcing-config/typescript/example.json. Additionally, biome.json is added to extend the root biome configuration for linting and formatting, and a turbo.json is added to define task dependencies, specifically ensuring the event-sourcing package is built before the example's dev task runs.
example · medium confidence
Refactored and validated core decorators with new constraints
The core library's decorator system has been reorganized and enhanced. All decorators now include JSDoc documentation for better developer experience. A maximum length of 50 characters is now enforced for aggregate stream names, and a maximum length of 80 characters is enforced for event stream names, throwing specific exceptions if these limits are exceeded. Additionally, the \EventHandler\ decorator has been renamed to \EventSubscriber\ to better reflect its role in the system.
packages/core/lib/decorators · high confidence
Refactored domain exception hierarchy and added specific exception classes
The domain error handling has been refactored to use a new abstract base class, DomainException, which all domain-specific exceptions now extend. New concrete exception classes have been introduced: IdAlreadyRegisteredException, IdNotFoundException, and InvalidIdException, each providing static factory methods for common error scenarios. This change improves type safety and provides more descriptive error messages for ID-related validation failures.
packages/core/lib/exceptions/domain · medium confidence
Removal of empty EventSourcingModule and its barrel export
The empty NestJS module class EventSourcingModule and its corresponding barrel export in lib/index.ts have been removed. This cleanup eliminates unused infrastructure code, ensuring that the library no longer exposes an empty module wrapper, which simplifies the public API and reduces bundle size.
lib · high confidence
Standardized TypeScript and Jest configuration across the monorepo
Developers will now use shared base configurations for TypeScript and Jest, ensuring consistent compiler settings and test coverage thresholds. The new base TypeScript config enables strictNullChecks and preserves comments, while the Jest base config enforces 80-90% coverage thresholds and uses @swc/jest for transformation. Specific profiles for docs and examples extend these bases with appropriate path mappings and compiler options.
packages/config · medium confidence
Standardized core package configuration and metadata
The core package now includes a .npmignore file to control published contents, a CHANGELOG.md for version history, a README.md with usage and contact information, and build configuration files (biome.json, tsconfig.json, turbo.json, jest.config.js) that standardize linting, TypeScript compilation, and testing workflows for the @ocoda/event-sourcing core module.
packages/core · high confidence
Test coverage
Added e2e application layer for account domain; Added e2e domain models and event subscribers for testing; Added e2e tests for DynamoDB, MariaDB, and MongoDB integrations; Added e2e tests for the EventSourcingModule; Added end-to-end tests for the Postgres event and snapshot stores; Added integration tests for InMemorySnapshotStore; Added integration tests for the in-memory event store; Added unit test helpers and test data for account aggregates; Added unit tests for Postgres event and snapshot stores; Added unit tests for core decorator metadata; Added unit tests for core event-sourcing components; Added unit tests for core models and ID types; Added unit tests for metadata exception formatting and e2e test fixtures for banking domain events; New e2e testing utilities for account lifecycle.
Dependencies
Upgrade to NestJS v11 and modernize tooling and dependencies
The project has been upgraded to NestJS v11 (specifically 11.1.6) and requires Node.js 20 or higher. This update includes a migration from Prettier/ESLint to Biome for formatting and linting, and updates core dependencies such as reflect-metadata to v0.2.0 and rxjs to v7.8.2. The lockfile has been regenerated for pnpm v9, and development tooling has been modernized with the addition of Turbo, Changesets, and SWC for faster builds and testing.
(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
Score
- CAI 28 → 55 (+27.2)
- Rubric changed (rubric-2026.08.18 → rubric-2026.08.19) — scores are not directly comparable.
Lenses
- Code Health 89 (new)
- Architecture 70 (new)
- Maturity 13 → 52 (+38.7)
- Readiness 15 → 53 (+38.0)
- Security 100 → 50 (-50.0)
- Domain Modelling 100 (new)
Resolved (6)
- Dependency hygiene not measured — no supported dependency manifest was read
- No automated tests
- No tests found
- bus factor not measured — no commits were sampled
- early-stage repository — too little history to judge knowledge freshness
- single-commit history — no usable git history window to measure hotspots
New (106)
- Change coupling: dynamodb.event-store.ts ↔ mariadb.event-store.ts (packages/integration/dynamodb/lib/dynamodb.event-store.ts)
- Change coupling: dynamodb.event-store.ts ↔ mongodb.event-store.ts (packages/integration/dynamodb/lib/dynamodb.event-store.ts)
- Change coupling: dynamodb.snapshot-store.ts ↔ mariadb.snapshot-store.ts (packages/integration/dynamodb/lib/dynamodb.snapshot-store.ts)
- Change coupling: dynamodb.snapshot-store.ts ↔ mongodb.snapshot-store.ts (packages/integration/dynamodb/lib/dynamodb.snapshot-store.ts)
- Change coupling: dynamodb.snapshot-store.ts ↔ postgres.snapshot-store.ts (packages/integration/dynamodb/lib/dynamodb.snapshot-store.ts)
- Change coupling: mariadb.event-store.ts ↔ mongodb.event-store.ts (packages/integration/mariadb/lib/mariadb.event-store.ts)
- Change coupling: mariadb.event-store.ts ↔ postgres.event-store.ts (packages/integration/mariadb/lib/mariadb.event-store.ts)
- Change coupling: mariadb.snapshot-store.ts ↔ mongodb.snapshot-store.ts (packages/integration/mariadb/lib/mariadb.snapshot-store.ts)
- Change coupling: mariadb.snapshot-store.ts ↔ postgres.snapshot-store.ts (packages/integration/mariadb/lib/mariadb.snapshot-store.ts)
- Change coupling: mongodb.snapshot-store.ts ↔ postgres.snapshot-store.ts (packages/integration/mongodb/lib/mongodb.snapshot-store.ts)
- Coverage not included — suite not readable by the collector
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical CVE: [GHSA redacted] (pnpm-lock.yaml)
- Critical vulnerability: [GHSA redacted] (pnpm-lock.yaml)
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- …and 86 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
ocoda/event-sourcing 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 4 August 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit ce84544b206c6f37ce3fe6bc030328c3758fabe3 — the exact code this score is about.
- Scored under rubric-2026.08.19 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer latest.