Skip to content

Sandreu/eventric

 
 

Repository files navigation

Not production ready. API might change heavily. First public release will be 0.2.0

eventric logo

eventric.js Build Status

Behavior-first application development. Runs on NodeJS and modern Browsers.

Why?

Because MVC evolved.

MVC evolved

Philosophy

Getting started

Take a look at the eventric TodoMVC for a running example, or try it yourself:

We need to install eventric first.

npm install eventric

Setup Context

Having discussed the upcoming TodoApp Project with the Business-Experts and fellow Developers it got clear that we should start with a Context named Todo.

eventric = require('eventric');

todoContext = eventric.context('Todo');

Define the Event

Inside of our Todo Context things will happen which are called DomainEvents. A technique to come up with these is called EventStorming. Lets add two called TodoCreated and TodoDescriptionChanged.

todoContext.defineDomainEvents({
  TodoCreated: function(params) {},
  TodoDescriptionChanged: function(params) {
    this.description = params.description;
  }
});

Adding an Aggregate

Now we need an Aggregate which actually raises this DomainEvents.

todoContext.addAggregate('Todo', function() {
  this.create = function() {
    this.$emitDomainEvent('TodoCreated');
  }
  this.changeDescription = function(description) {
    this.$emitDomainEvent('TodoDescriptionChanged', {description: description});
  }
});

Hint: this.create is called by convention when you create an aggregate using this.$aggregate.create

Hint: this.$emitDomainEvent is dependency injected

Adding CommandHandlers

To actually work with the Context from the outside world we need CommandHandlers. Let's start by adding a simple one that will create an instance of our Todo Aggregate.

todoContext.addCommandHandler('CreateTodo', function(params) {
  this.$aggregate.create('Todo')
  .then(function (todo) {
    return todo.$save();
  });
});

Hint: this.$aggregate is dependency injected

It would be nice if we could change the description of the Todo, so let's add this CommandHandler too.

todoContext.addCommandHandler('ChangeTodoDescription', function(params) {
  this.$aggregate.load('Todo', params.id)
  .then(function (todo) {
    todo.changeDescription(params.description);
    return todo.$save();
  });
});

Subscribe to a DomainEvent

And last but not least we want to console.log when the description of the Todo changes.

todoContext.subscribeToDomainEvent('TodoDescriptionChanged', function(domainEvent) {
  console.log(domainEvent.payload.description);
});

Executing Commands

Initialize the Context, create a Todo and tell the Todo to change its description.

todoContext.initialize()
.then(function() {
  todoContext.command('CreateTodo');
})
.then(function(todoId) {
  todoContext.command('ChangeTodoDescription', {
    id: todoId,
    description: 'Do something'
  });
});

After executing the Commands the DomainEventHandler will print Do something. Your Todo Aggregate is now persisted using EventSourcing into the InMemory Store.

Running Tests

To execute all (client+server) tests, use:

gulp spec

You can watch for file-changes with

gulp watch

Release

gulp bump:patch
git add .
git commit -m"$VERSION"
git push
npm publish
git checkout -b release master
gulp dist
git add .
git commit -m"$VERSION"
git tag $VERSION
git push --tags
git checkout master
git branch -D release

License

MIT

Copyright (c) 2013-2014 SixSteps Team, eFa GmbH

About

Build JavaScript applications with Behaviour-Driven Domain Design. Based on DDD, BDD, CQRS and EventSourcing.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • CoffeeScript 99.8%
  • JavaScript 0.2%