@dolittle/sdk.aggregates
Version:
Dolittle is a decentralized, distributed, event-driven microservice platform built to harness the power of events.
154 lines • 10.8 kB
JavaScript
"use strict";
// Copyright (c) Dolittle. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.AggregateRoot = void 0;
const rudiments_1 = require("@dolittle/rudiments");
const sdk_events_1 = require("@dolittle/sdk.events");
const AggregateRootIdentifierNotSet_1 = require("./AggregateRootIdentifierNotSet");
const AppliedEvent_1 = require("./AppliedEvent");
const EventTypesNotSet_1 = require("./EventTypesNotSet");
const onDecorator_1 = require("./onDecorator");
/**
* Represents the aggregate root.
*/
class AggregateRoot {
/**
* Initialises a new instance of the {@link AggregateRoot} class.
* @param {EventSourceId} eventSourceId - The event source id of the aggregate root.
*/
constructor(eventSourceId) {
this.eventSourceId = eventSourceId;
this._appliedEvents = [];
this._version = sdk_events_1.AggregateRootVersion.initial;
this._aggregateRootType = Object.getPrototypeOf(this).constructor;
}
/**
* Gets aggregate root id.
*/
get aggregateRootId() {
if (!this._aggregateRootId) {
throw new AggregateRootIdentifierNotSet_1.AggregateRootIdentifierNotSet();
}
return this._aggregateRootId;
}
/**
* Sets the aggregate root id - internal use.
*/
set aggregateRootId(value) {
this._aggregateRootId = value;
}
/**
* Sets the event types - internal use.
*/
set eventTypes(value) {
this._eventTypes = value;
}
/**
* Gets the version of the aggregate root.
*/
get version() {
return this._version;
}
/**
* Gets all applied events.
*/
get appliedEvents() {
return this._appliedEvents;
}
/**
* Apply an event to the aggregate root that will be committed to the event store.
* @param {any} event - Event type apply.
* @param {EventType} [eventType] - Optional type of event to apply.
*/
apply(event, eventType) {
this.applyImplementation(event, eventType, false);
}
/**
* Apply a public event to the aggregate root that will be committed to the event store.
* @param {any} event - Event type apply.
* @param {EventType} [eventType] - Optional type of event to apply.
*/
applyPublic(event, eventType) {
this.applyImplementation(event, eventType, true);
}
/**
* Re-applies the committed aggregate events to rehydrate the state of the aggregate root by calling on()-methods and incrementing the in-memory version.
* @param {CommittedAggregateEvents} committedEvents - The events to re-apply.
*/
reApply(committedEvents) {
this.throwIfEventWasAppliedToOtherEventSource(committedEvents);
this.throwIfEventWasAppliedByOtherAggreateRoot(committedEvents);
const hasState = (0, onDecorator_1.getOnDecoratedMethods)(this._aggregateRootType).length > 0;
for (const event of committedEvents) {
this.throwIfAggregateRootVersionIsOutOfOrder(event);
this.nextVersion();
if (hasState) {
const onMethod = this.getOnMethodFor(event, event.type);
if (onMethod) {
onMethod.method.call(this, event.content);
}
}
}
}
/**
* Move to next version.
*/
nextVersion() {
this._version = this._version.next();
}
applyImplementation(event, eventType, isPublic) {
this.throwIfEventContentIsNullOrUndefined(event);
this._appliedEvents.push(new AppliedEvent_1.AppliedEvent(event, eventType, isPublic));
this.nextVersion();
this.invokeOnMethod(event, eventType);
}
invokeOnMethod(event, eventType) {
if (this._eventTypes === undefined) {
throw new EventTypesNotSet_1.EventTypesNotSet();
}
const hasState = (0, onDecorator_1.getOnDecoratedMethods)(this._aggregateRootType).length > 0;
if (!hasState) {
return;
}
const onMethod = this.getOnMethodFor(event, eventType);
if (onMethod) {
onMethod.method.call(this, event);
}
}
throwIfEventContentIsNullOrUndefined(event) {
if (!event) {
throw new sdk_events_1.EventContentNeedsToBeDefined();
}
}
getOnMethodFor(event, eventType) {
return (0, onDecorator_1.getOnDecoratedMethods)(this._aggregateRootType).find(_ => {
let decoratorEventTypeId = sdk_events_1.EventTypeId.from(rudiments_1.Guid.empty);
if (_.eventTypeOrId instanceof Function) {
decoratorEventTypeId = this._eventTypes.getFor(_.eventTypeOrId).id;
}
else {
decoratorEventTypeId = sdk_events_1.EventTypeId.from(_.eventTypeOrId);
}
const appliedEventType = this._eventTypes.resolveFrom(event, eventType);
return appliedEventType.id.equals(decoratorEventTypeId);
});
}
throwIfAggregateRootVersionIsOutOfOrder(event) {
if (event.aggregateRootVersion.value !== this.version.value) {
throw new sdk_events_1.AggregateRootVersionIsOutOfOrder(event.aggregateRootVersion, this.version);
}
}
throwIfEventWasAppliedByOtherAggreateRoot(event) {
if (!event.aggregateRootId.equals(this.aggregateRootId)) {
throw new sdk_events_1.EventWasAppliedByOtherAggregateRoot(event.aggregateRootId, this.aggregateRootId);
}
}
throwIfEventWasAppliedToOtherEventSource(event) {
if (!event.eventSourceId.equals(this.eventSourceId)) {
throw new sdk_events_1.EventWasAppliedToOtherEventSource(event.eventSourceId, this.eventSourceId);
}
}
}
exports.AggregateRoot = AggregateRoot;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdncmVnYXRlUm9vdC5qcyIsInNvdXJjZVJvb3QiOiIuLi8iLCJzb3VyY2VzIjpbIkFnZ3JlZ2F0ZVJvb3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxxR0FBcUc7OztBQUVyRyxtREFBMkM7QUFHM0MscURBQTRUO0FBRTVULG1GQUFnRjtBQUNoRixpREFBOEM7QUFFOUMseURBQXNEO0FBQ3RELCtDQUFzRDtBQUV0RDs7R0FFRztBQUNILE1BQWEsYUFBYTtJQU90Qjs7O09BR0c7SUFDSCxZQUFxQixhQUE0QjtRQUE1QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtRQVJ6QyxtQkFBYyxHQUFtQixFQUFFLENBQUM7UUFDcEMsYUFBUSxHQUF5QixpQ0FBb0IsQ0FBQyxPQUFPLENBQUM7UUFRbEUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsV0FBVyxDQUFDO0lBQ3RFLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksZUFBZTtRQUNmLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDeEIsTUFBTSxJQUFJLDZEQUE2QixFQUFFLENBQUM7U0FDN0M7UUFDRCxPQUFPLElBQUksQ0FBQyxnQkFBaUIsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLGVBQWUsQ0FBQyxLQUFzQjtRQUN0QyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO0lBQ2xDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksVUFBVSxDQUFDLEtBQWtCO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN6QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLGFBQWE7UUFDYixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDL0IsQ0FB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