UNPKG

curli-bus

Version:

Simple Command Bus Implementation (CQRS) for NodeJS/Typescript.

309 lines (188 loc) 6.9 kB
# Curli-Bus [![Build Status](https://travis-ci.org/CarlosCraviotto/curli-bus.svg?branch=master)](https://travis-ci.com/github/CarlosCraviotto/curli-bus) [![Coverage Status](https://coveralls.io/repos/github/CarlosCraviotto/curli-bus/badge.svg?branch=master&cach=ff)](https://coveralls.io/github/CarlosCraviotto/curli-bus?branch=master) Simple Command/Query/Event Bus Implementation to use with CQRS or DDD for NodeJS/Typescript. ### Motivation There are a lot of bus CQRS libraries for JavaScript/Typescript out there, this is not new. The one thing we're trying to achieve here is the ability to take advantage of such a library but without coupling it into the application's domain. The main goal here is to create a library that you can use without using third part code into your domains. ### Installation Install by `npm` ```sh npm install --save curli-bus ``` #### Basic Usage #### Command Bus: ```typescript import {CommandBusSync, CommandInstanceType} from "curli-bus"; class CommandTest { public constructor (private name: string){ } } const commandBus = new CommandBusSync(); bus.registerHandler(CommandTest, function (command: CommandInstanceType): any { container.get('useCase').execute(command); }); const commandTest = new CommandTest('test'); bus.dispatch(commandTest); ``` #### Registering command using string name ```typescript bus.registerHandler('CommandTest', function (command: CommandInstanceType): any { container.get('useCase').execute(command); }); const commandTest = new CommandTest('test'); bus.dispatch(commandTest); ``` #### Using options We can send options to the handler through all the middleware. ```typescript bus.registerHandler('CommandTest', function (command: CommandInstanceType, options?: any): any { container.get('useCase').execute(command, options); }); bus.dispatch(commandTest, {"dev": true}); ``` #### Using middleware ```typescript import {BusSync, CommandInstanceType, Middleware} from "curli-bus"; class CommandTest { public constructor (private name: string){ } public addToName (toAdd: string) { this.name = this.name + ' - ' + toAdd + ' -'; } } class MiddlewareTest extends Middleware { execute (command: CommandInstanceType, next: (a: any) => any): any { command.addToName('preHandler'); command = next(command); command.addToName('postHandler'); return command; } } const bus = new BusSync(); const commandTest = new CommandTest('test'); bus.addMiddleware(new MiddlewareTest()); bus.registerHandler(CommandTest, function (command: CommandInstanceType): any { command.addToName('hendler'); container.get('useCase').execute(command); }); commandTest = bus.dispatch(commandTest); console.log(commandTest.name); //test - preHandler - hendler - postHandler - ``` #### Query Bus: ```typescript import {QueryBusSync, QueryInstanceType} from "curli-bus"; class QueryTest { public constructor (private query: object){ } } const queryBus = new QueryBusSync(); bus.registerHandler(QueryTest, function (query: QueryInstanceType): any { container.get('useCase').execute(query); }); const queryTest = new QueryTest({'name': 'test'}); const result = bus.ask(queryTest); ``` #### Registering query using string name ```typescript bus.registerHandler('QueryTest', function (query: QueryInstanceType): any { container.get('useCase').execute(query); }); const queryTest = new QueryTest({'name': 'test'}); const result = bus.ask(queryTest); ``` #### Using options We can send options to the handler through all the middleware. ```typescript bus.registerHandler('QueryTest', function (query: QueryInstanceType, options?: any): any { container.get('useCase').execute(query, options); }); const result = bus.ask(queryTest, {"dev": true}); ``` #### Using middleware ```typescript import {BusSync, QueryInstanceType, Middleware} from "curli-bus"; class QueryTest { public constructor (private name: string){ } public addToName (toAdd: string) { this.name = this.name + ' - ' + toAdd + ' -'; } } class MiddlewareTest extends Middleware { execute (query: QueryInstanceType, next: (a: any) => any): any { query.addToName('preHandler'); query = next(query); query.addToName('postHandler'); return query; } } const bus = new BusSync(); const queryTest = new QueryTest('test'); bus.addMiddleware(new MiddlewareTest()); bus.registerHandler(QueryTest, function (query: QueryInstanceType): any { query.addToName('hendler'); container.get('useCase').execute(query); }); const result = bus.ask(queryTest); console.log(result.name); //test - preHandler - hendler - postHandler - ``` #### Event Bus We can create an event bus and send events throw it. ```typescript import {EventBus} from "curli-bus"; class UserCreatedEvent { public eventName = 'user_created'; public dateTimeOccurred?: Date; public constructor(public data: {[key:string]: any}) { } } class OnUserCreatedEventSubscriber { public getEventName(): string { return 'user_created'; } public handle (event: Event): any{ //... Do stuff with the event } } const eventBus = new EventBus(); eventBus.register(new OnUserCreatedEventSubscriber()); const event = new UserCreatedEvent( {userName: 'Josh', email:'josh@notexist.com'} ); eventBus.publish(event); ``` #### Commands - `npm run build`: Build the project (Bus). - `npm run build:clean`: Delete first the dist folder and build it. - `npm run clean`: Delete the dist folder. - `npm run test`: Execute the tests. - `npm run test:coverage`: Execute the tests and calculate the coverage. - `npm run lint`: Check the code using the rules in .eslintre.js - `npm run lint:fix`: Check the code and try to fix it. #### Contributing When submitting your pull-request try to follow those guides: - https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github - https://medium.com/@vadimdemedes/making-your-first-contribution-de6576ddb190 ### Changelog All notable changes to this project will be documented in this section. ### 0.2.1 #### Changed - Expose Event interface and EventSubscriber type ### 0.2.0 #### Added - Support publish multiple events (array) in event bus. ### 0.1.0 #### Added - Event bus support ### 0.0.2 #### Added - QueryBusSync support #### Changed - BusSync interface will be CommandBusSync ### 0.0.1 #### Added - CommandBusSync support #### License MIT