eventric
Version:
Build JavaScript applications with Behaviour-driven Domain Design. Based on DDD, BDD, CQRS and EventSourcing.
91 lines (64 loc) • 2.42 kB
text/coffeescript
eventric = require 'eventric'
# TODO: replace with eventric api call getDomainEventClass() or property access?
DomainEvent = require 'eventric/src/context/domain_event'
class Aggregate
constructor: (@_context, @_name, Root) ->
@_domainEvents = []
if !Root
@root = {}
else
@root = new Root
@root.$emitDomainEvent = @emitDomainEvent
emitDomainEvent: (domainEventName, domainEventPayload) =>
DomainEventClass = @_context.getDomainEvent domainEventName
if !DomainEventClass
err = "Tried to emitDomainEvent '#{domainEventName}' which is not defined"
eventric.log.error err
throw new Error err
domainEvent = @_createDomainEvent domainEventName, DomainEventClass, domainEventPayload
@_domainEvents.push domainEvent
@_handleDomainEvent domainEventName, domainEvent
eventric.log.debug "Created and Handled DomainEvent in Aggregate", domainEvent
# TODO: do a rollback if something goes wrong inside the handle function
_createDomainEvent: (domainEventName, DomainEventClass, domainEventPayload) ->
new DomainEvent
id: eventric.generateUid()
name: domainEventName
aggregate:
id: @id
name: @_name
context: @_context.name
payload: new DomainEventClass domainEventPayload
_handleDomainEvent: (domainEventName, domainEvent) ->
if @root["handle#{domainEventName}"]
@root["handle#{domainEventName}"] domainEvent, ->
else
eventric.log.debug "Tried to handle the DomainEvent '#{domainEventName}' without a matching handle method"
getDomainEvents: =>
@_domainEvents
applyDomainEvents: (domainEvents) ->
@_applyDomainEvent domainEvent for domainEvent in domainEvents
_applyDomainEvent: (domainEvent) ->
@_handleDomainEvent domainEvent.name, domainEvent
create: =>
params = arguments
new Promise (resolve, reject) =>
@id = eventric.generateUid()
if typeof @root.create isnt 'function'
err = "No create function on aggregate"
eventric.log.error err
throw new Error err
try
check = @root.create params..., (err) =>
if err
reject err
else
resolve @
if check instanceof Promise
check.then =>
resolve @
check.catch (err) =>
reject err
catch e
reject e
module.exports = Aggregate