UNPKG

eventric

Version:

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

127 lines (100 loc) 4.08 kB
eventric = require 'eventric' Aggregate = require 'eventric/src/context/aggregate' class Repository constructor: (params) -> @_aggregateName = params.aggregateName @_AggregateRoot = params.AggregateRoot @_context = params.context @_command = {} @_aggregateInstances = {} @_store = @_context.getDomainEventsStore() findById: (aggregateId, callback = ->) => new Promise (resolve, reject) => @_findDomainEventsForAggregate aggregateId, (err, domainEvents) => if err callback err, null reject err return if not domainEvents.length err = "No domainEvents for #{@_aggregateName} Aggregate with #{aggregateId} available" eventric.log.error err callback err, null reject err return aggregate = new Aggregate @_context, @_aggregateName, @_AggregateRoot aggregate.applyDomainEvents domainEvents aggregate.id = aggregateId commandId = @_command.id ? 'nocommand' @_aggregateInstances[commandId] ?= {} @_aggregateInstances[commandId][aggregateId] = aggregate callback null, aggregate.root resolve aggregate.root _findDomainEventsForAggregate: (aggregateId, callback) -> @_store.findDomainEventsByAggregateId aggregateId, (err, domainEvents) => return callback err, null if err return callback null, [] if domainEvents.length == 0 callback null, domainEvents create: => params = arguments if typeof params[params.length-1] is 'function' callback = params.pop() new Promise (resolve, reject) => aggregate = new Aggregate @_context, @_aggregateName, @_AggregateRoot aggregate.create params... .then (aggregate) => commandId = @_command.id ? 'nocommand' @_aggregateInstances[commandId] ?= {} @_aggregateInstances[commandId][aggregate.id] = aggregate callback? null, aggregate.id resolve aggregate.id save: (aggregateId, callback=->) => new Promise (resolve, reject) => commandId = @_command.id ? 'nocommand' aggregate = @_aggregateInstances[commandId][aggregateId] if not aggregate err = "Tried to save unknown aggregate #{@_aggregateName}" eventric.log.error err err = new Error err callback? err, null reject err return domainEvents = aggregate.getDomainEvents() if domainEvents.length < 1 err = "Tried to save 0 DomainEvents from Aggregate #{@_aggregateName}" eventric.log.debug err, @_command err = new Error err callback? err, null reject err return eventric.log.debug "Going to Save and Publish #{domainEvents.length} DomainEvents from Aggregate #{@_aggregateName}" # TODO: this should be an transaction to guarantee consistency eventric.eachSeries domainEvents, (domainEvent, next) => domainEvent.command = @_command @_store.saveDomainEvent domainEvent, => eventric.log.debug "Saved DomainEvent", domainEvent next null , (err) => if err callback err, null reject err else if not @_context.isWaitingModeEnabled() for domainEvent in domainEvents eventric.log.debug "Publishing DomainEvent", domainEvent @_context.getEventBus().publishDomainEvent domainEvent, -> resolve aggregate.id callback null, aggregate.id else eventric.eachSeries domainEvents, (domainEvent, next) => eventric.log.debug "Publishing DomainEvent in waiting mode", domainEvent @_context.getEventBus().publishDomainEventAndWait domainEvent, next , (err) => if err callback err, null reject err else resolve aggregate.id callback null, aggregate.id setCommand: (command) -> @_command = command module.exports = Repository