ts-cqs
TypeScript icon, indicating that this package has built-in type declarations

0.1.0 • Public • Published

CircleCI Test Coverage Maintainability npm version Known Vulnerabilities

ts-cqs

Light Command and Query Separation framework for typescript that uses inversify for dependency injection.

⚠️ Note, this is not a CQRS library

Motivation

Following the single responsibility principle, the command and query separation pattern works well. This library sets out to provide a framework in to replicate the CQS pattern in typescript that uses the dependency injection framework InversifyJs.

There are CQRS libraries such as NestJS/CQRS that provides a framework for this pattern. However, it adheres more to the CQRS pattern with event sourcing and uses the bus (command/query processor) as a way to wire up the dependency injection. This library allows you to wire up the dependencies outside of the processors.

Installation

npm install ts-cqs inversify reflect-metadata --save

The InversifyJS type definitions are included in the inversify npm package.

⚠️ Important! ts-cqs requires has a peer dependency on InversifyJs, please view their readme for their requirements.

Usage

Commands

// TestCommand.ts
 
import 'reflect-metadata'
import { injectable } from 'inversify'
import { ICommand, ICommandHandler, CommandHandler } from 'ts-cqs'
 
export class TestCommand implements ICommand<string> {
  constructor(public readonly val: string) {}
}
 
@injectable()
@CommandHandler(TestCommand)
export class TestCommandHandler implements ICommandHandler<TestCommand> {
  async handle(command: TestCommand): Promise<string> {
    return command.val
  }
}

ICommandHandler.execute is set to return any. In this case, command handlers can chose to return something or not.

// CompositeRoot.ts
 
import { Container } from 'inversify'
import { TestCommandHandler } from './TestCommand'
 
const container = new Container()
container.bind(TestCommandHandler).toSelf()

The inversify binding here uses the handler class as the id. See docs

// SomeConsumerClass.ts
 
import { CommandProcessor } from 'ts-cqs'
import { TestCommand } from './TestCommand'
 
export class SomeConsumerClass {
  constructor(private commandProcessor: CommandProcessor) {}
 
  async use(): Promise<string> {
    const testCommand = new TestCommand('some value')
    const commandResult = await this.commandProcessor.execute(testCommand)
 
    console.log(commandResult) // logs 'some value'
  }
}

Contributing

Tests

npm run test

Package Sidebar

Install

npm i ts-cqs

Weekly Downloads

3

Version

0.1.0

License

ISC

Unpacked Size

12.9 MB

Total Files

49

Last publish

Collaborators

  • shawnmclean