{"id":18609673,"url":"https://github.com/unlight/nestjs-cqrx","last_synced_at":"2025-04-10T22:31:36.942Z","repository":{"id":138161032,"uuid":"407312287","full_name":"unlight/nestjs-cqrx","owner":"unlight","description":"EventStoreDB NestJS CQRS module","archived":false,"fork":false,"pushed_at":"2024-10-26T20:18:43.000Z","size":392,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T05:41:36.936Z","etag":null,"topics":["cqrs","eventstore","eventstoredb","nestjs","nestjs-cqrx"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unlight.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-09-16T20:55:27.000Z","updated_at":"2024-10-26T20:18:46.000Z","dependencies_parsed_at":"2024-03-31T16:23:42.070Z","dependency_job_id":"f971006a-99e7-4767-ab6a-256e5fe96c20","html_url":"https://github.com/unlight/nestjs-cqrx","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unlight%2Fnestjs-cqrx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unlight%2Fnestjs-cqrx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unlight%2Fnestjs-cqrx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unlight%2Fnestjs-cqrx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unlight","download_url":"https://codeload.github.com/unlight/nestjs-cqrx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247959798,"owners_count":21024842,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cqrs","eventstore","eventstoredb","nestjs","nestjs-cqrx"],"created_at":"2024-11-07T03:06:56.233Z","updated_at":"2025-04-10T22:31:36.373Z","avatar_url":"https://github.com/unlight.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nestjs-cqrx\n\nEventStoreDB NestJS CQRS module.\n\n## Based on\n\n- https://github.com/nordfjord/nestjs-cqrs-es\n- https://github.com/cqrx/cqrx\n\n## Features\n\n- Asynchronous commit/publish\n- Event handler decorator\n- Single event for read/write\n\n## Install\n\n```sh\nnpm install --save nestjs-cqrx\n```\n\n## Usage\n\n```ts\nimport { CqrxModule } from 'nestjs-cqrx';\n\n@Module({\n  imports: [\n    CqrxModule.forRoot({\n      eventstoreDbConnectionString: 'esdb://localhost:2113?tls=false',\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nYou can generate connection string on [Connection details](https://developers.eventstore.com/clients/grpc/#connection-details) page\n\n#### Example of User model\n\n```ts\nimport { ConflictException } from '@nestjs/common';\nimport { AggregateRoot, EventHandler } from 'nestjs-cqrx';\n\nimport { UserRegistered } from '../events';\n\nexport class User extends AggregateRoot {\n  protected static readonly streamName: string = 'user';\n  isRegistered = false;\n  email!: string;\n  password!: string;\n\n  @EventHandler(UserRegistered)\n  createUser(event: UserRegistered): void {\n    this.isRegistered = true;\n    this.email = event.data.email;\n    this.password = event.data.password;\n  }\n\n  register(email: string, password: string) {\n    if (this.isRegistered) {\n      throw new ConflictException();\n    }\n\n    this.apply(\n      new UserRegistered({\n        email,\n        password,\n      }),\n    );\n  }\n}\n```\n\n#### Example of usage\n\n```ts\nconst user = new User('123');\nuser.apply(new UserRegistered({ data }));\nawait userAggregateRepository.save(user);\n// Or you can create aggregate from repository\n// In this case you can use commit method\nconst user = userAggregateRepository.create('123');\nuser.apply(new UserRegistered({ data }));\nawait user.commit();\n```\n\n#### Example of events\n\n```ts\nimport { Event } from 'nestjs-cqrx';\n\ntype UserRegisteredDto = { email: string; password: string };\n\nexport class UserRegistered extends Event\u003cUserRegisteredDto\u003e {}\n```\n\n```ts\n@Module({\n  imports: [\n    CqrxModule.forFeature(\n      [User],\n      // Subscribe and transform events from eventstore\n      [['UserRegistered', event =\u003e new UserRegistered(event)]],\n    ),\n  ],\n})\nexport class UserModule {}\n```\n\n```ts\n// Signature of transformers\ntype Transformer = [\n  /* Recorded event type */ string,\n  /* Function which accept stream event (plain object) */ (\n    event: RecordedEvent,\n  ) =\u003e Event,\n];\n```\n\n`['UserRegistered', event =\u003e new UserRegistered(event)]` can be shorthanded to `UserRegistered`\n\nNote: If you have decorator `EventsHandler` (from `@nestjs/cqrs`) of some event,\nit will be automatically added to transform service.\n\n## Example apps pros/cons\n\n#### example / example-tick-tack-toe-cqrx\n\n[+] good option (save event to db, subscribe to event from db)  \n[–] synchronous (we must wait when event will be saved then reply to client)\n\n#### [nest-cqrs-example](https://github.com/kamilmysliwiec/nest-cqrs-example)\n\n[+] official nestjs/cqrs implementation, command handlers (fire new command via saga)  \n[+] faster, we reply processing to client, and do command on  \n[–] can emit only 1 event from saga\n\n## Similar Projects\n\n- https://github.com/cqrx/cqrx\n- https://github.com/nordfjord/nestjs-cqrs-es\n\n## Development\n\n- docker-compose up\n- http://localhost:2113/web/index.html#/dashboard\n\n## Resources\n\n- https://github.com/bradsheppard/nestjs-async-cqrs\n- https://github.com/valueadd-poland/nestjs-packages/tree/master/packages/typed-cqrs\n- https://github.com/ArkerLabs/event-sourcing-nestjs\n- https://github.com/amehat?tab=repositories\u0026q=cqrs\n- https://github.com/orhanveli/nestjs-saga-pattern-example\n- https://github.com/tuanitpro/nestjs-sagas-cqrs\n- https://github.com/ntxinh/nestjs-cqrs-es\n- https://github.com/ArkerLabs/event-sourcing-nestjs-graphql-example\n- https://github.com/oskardudycz/EventSourcing.JVM/tree/main/samples/event-sourcing-esdb-simple\n- https://github.com/PrestaShopCorp/nestjs-geteventstore\n\n## Todo\n\n- read from specific position\n- find lib for creating errors\n- better to split on read/write events\n- reducer (similar to evolve of emmet)\n\n## License\n\n[MIT License](https://opensource.org/licenses/MIT) (c) 2024\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funlight%2Fnestjs-cqrx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funlight%2Fnestjs-cqrx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funlight%2Fnestjs-cqrx/lists"}