eventric
Version:
Build JavaScript applications with Behaviour-driven Domain Design. Based on DDD, BDD, CQRS and EventSourcing.
176 lines (164 loc) • 6.43 kB
JavaScript
var Aggregate, Repository, eventric,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
eventric = require('eventric');
Aggregate = require('eventric/src/context/aggregate');
Repository = (function() {
function Repository(params) {
this.save = __bind(this.save, this);
this.create = __bind(this.create, this);
this.findById = __bind(this.findById, this);
this._aggregateName = params.aggregateName;
this._AggregateRoot = params.AggregateRoot;
this._context = params.context;
this._command = {};
this._aggregateInstances = {};
this._store = this._context.getDomainEventsStore();
}
Repository.prototype.findById = function(aggregateId, callback) {
if (callback == null) {
callback = function() {};
}
return new Promise((function(_this) {
return function(resolve, reject) {
return _this._findDomainEventsForAggregate(aggregateId, function(err, domainEvents) {
var aggregate, commandId, _base, _ref;
if (err) {
callback(err, null);
reject(err);
return;
}
if (!domainEvents.length) {
err = "No domainEvents for " + _this._aggregateName + " Aggregate with " + aggregateId + " available";
eventric.log.error(err);
callback(err, null);
reject(err);
return;
}
aggregate = new Aggregate(_this._context, _this._aggregateName, _this._AggregateRoot);
aggregate.applyDomainEvents(domainEvents);
aggregate.id = aggregateId;
commandId = (_ref = _this._command.id) != null ? _ref : 'nocommand';
if ((_base = _this._aggregateInstances)[commandId] == null) {
_base[commandId] = {};
}
_this._aggregateInstances[commandId][aggregateId] = aggregate;
callback(null, aggregate.root);
return resolve(aggregate.root);
});
};
})(this));
};
Repository.prototype._findDomainEventsForAggregate = function(aggregateId, callback) {
return this._store.findDomainEventsByAggregateId(aggregateId, (function(_this) {
return function(err, domainEvents) {
if (err) {
return callback(err, null);
}
if (domainEvents.length === 0) {
return callback(null, []);
}
return callback(null, domainEvents);
};
})(this));
};
Repository.prototype.create = function() {
var callback, params;
params = arguments;
if (typeof params[params.length - 1] === 'function') {
callback = params.pop();
}
return new Promise((function(_this) {
return function(resolve, reject) {
var aggregate;
aggregate = new Aggregate(_this._context, _this._aggregateName, _this._AggregateRoot);
return aggregate.create.apply(aggregate, params).then(function(aggregate) {
var commandId, _base, _ref;
commandId = (_ref = _this._command.id) != null ? _ref : 'nocommand';
if ((_base = _this._aggregateInstances)[commandId] == null) {
_base[commandId] = {};
}
_this._aggregateInstances[commandId][aggregate.id] = aggregate;
if (typeof callback === "function") {
callback(null, aggregate.id);
}
return resolve(aggregate.id);
});
};
})(this));
};
Repository.prototype.save = function(aggregateId, callback) {
if (callback == null) {
callback = function() {};
}
return new Promise((function(_this) {
return function(resolve, reject) {
var aggregate, commandId, domainEvents, err, _ref;
commandId = (_ref = _this._command.id) != null ? _ref : 'nocommand';
aggregate = _this._aggregateInstances[commandId][aggregateId];
if (!aggregate) {
err = "Tried to save unknown aggregate " + _this._aggregateName;
eventric.log.error(err);
err = new Error(err);
if (typeof callback === "function") {
callback(err, null);
}
reject(err);
return;
}
domainEvents = aggregate.getDomainEvents();
if (domainEvents.length < 1) {
err = "Tried to save 0 DomainEvents from Aggregate " + _this._aggregateName;
eventric.log.debug(err, _this._command);
err = new Error(err);
if (typeof callback === "function") {
callback(err, null);
}
reject(err);
return;
}
eventric.log.debug("Going to Save and Publish " + domainEvents.length + " DomainEvents from Aggregate " + _this._aggregateName);
return eventric.eachSeries(domainEvents, function(domainEvent, next) {
domainEvent.command = _this._command;
return _this._store.saveDomainEvent(domainEvent, function() {
eventric.log.debug("Saved DomainEvent", domainEvent);
return next(null);
});
}, function(err) {
var domainEvent, _i, _len;
if (err) {
callback(err, null);
return reject(err);
} else {
if (!_this._context.isWaitingModeEnabled()) {
for (_i = 0, _len = domainEvents.length; _i < _len; _i++) {
domainEvent = domainEvents[_i];
eventric.log.debug("Publishing DomainEvent", domainEvent);
_this._context.getEventBus().publishDomainEvent(domainEvent, function() {});
}
resolve(aggregate.id);
return callback(null, aggregate.id);
} else {
return eventric.eachSeries(domainEvents, function(domainEvent, next) {
eventric.log.debug("Publishing DomainEvent in waiting mode", domainEvent);
return _this._context.getEventBus().publishDomainEventAndWait(domainEvent, next);
}, function(err) {
if (err) {
callback(err, null);
return reject(err);
} else {
resolve(aggregate.id);
return callback(null, aggregate.id);
}
});
}
}
});
};
})(this));
};
Repository.prototype.setCommand = function(command) {
return this._command = command;
};
return Repository;
})();
module.exports = Repository;