@nestjs-cqrs-eventsourcing/core
Version:
Event sourcing for nestjs CQRS
135 lines (134 loc) • 5.38 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.EventstoreProvider = void 0;
const debug_1 = __importDefault(require("debug"));
const src_1 = require("@nestjs-cqrs-eventsourcing/core/src");
const common_1 = require("@nestjs/common");
const debug = (0, debug_1.default)('eventstore:provider');
let EventstoreProvider = class EventstoreProvider {
constructor(options) {
this.eventStoreLaunched = false;
this.eventStreamCache = new Map();
if (!options.store) {
throw new Error('No event store provided');
}
this.eventstore = new src_1.Eventstore(options);
void this.eventstore.init().then(() => {
this.eventStoreLaunched = true;
});
}
isInitiated() {
return this.eventStoreLaunched;
}
async getAggregateEvents(aggregate, id, take, back) {
const res = await this.eventstore.getFromSnapshot(this.getAggregateId(aggregate, String(id)));
if (!res) {
return [];
}
const [, stream] = res;
const { events } = stream;
if (take) {
const slice = events.slice(0, take);
return slice.map(event => this.getStorableEventFromPayload(event));
}
if (back) {
const slice = events.slice(0, events.length - back);
return slice.map(event => this.getStorableEventFromPayload(event));
}
return stream.events.map((event) => this.getStorableEventFromPayload(event));
}
async getEvents(query, skip = 0, limit = -1) {
const events = await this.eventstore.getEvents(query, skip, limit);
return events.map(e => this.getStorableEventFromPayload(e));
}
async countEvents(query) {
return this.eventstore.countEvents(query);
}
async getEvent(index) {
const event = await this.eventstore.getEvent(index);
if (event) {
return this.getStorableEventFromPayload(event);
}
return null;
}
async storeEvent(event) {
const stream = await this.getStream(event);
if (stream) {
stream.addEvent(event);
}
else {
throw new Error('No stream');
}
}
async commit(aggregateId) {
let i = 0;
for (const [aggregate, stream] of this.eventStreamCache.entries()) {
if (aggregate === aggregateId) {
debug('Request commit stream', stream.nonce, aggregate, 'loop index', i);
await stream.commit();
this.eventStreamCache.delete(aggregate);
debug('After stream committed and removed from the cache', stream.nonce, aggregate, 'loop index', i);
i += 1;
}
}
}
logUncommitted() {
debug('>>>>>>>>>>> Uncommitted');
for (const [aggregate, stream] of this.eventStreamCache.entries()) {
debug('!UNCOMMITTED!', aggregate);
}
debug('<<<<<<<<<<< Uncommitted');
}
createSequence(name, startValue = 0) {
return this.eventstore.createSequence(name, startValue);
}
async getStream(event) {
const aggregate = event.eventAggregate;
const aggregateId = this.getAggregateId(aggregate, event.id);
let stream;
try {
const hasStream = this.eventStreamCache.has(aggregateId);
if (!hasStream) {
stream = await this.eventstore.getEventStream({
aggregateId,
aggregate,
});
this.eventStreamCache.set(aggregateId, stream);
}
stream = this.eventStreamCache.get(aggregateId);
}
catch (e) {
console.error(e);
}
return stream;
}
getStorableEventFromPayload(event) {
const { payload } = event;
const eventPlain = payload;
eventPlain.constructor = { name: payload.eventName };
eventPlain.timestamp = event.timestamp
? new Date(event.timestamp).toISOString()
: (0, src_1.nowIso)();
return Object.assign(Object.create(eventPlain), eventPlain);
}
getAggregateId(aggregate, id) {
return `${aggregate}-${id}`;
}
};
exports.EventstoreProvider = EventstoreProvider;
exports.EventstoreProvider = EventstoreProvider = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [Object])
], EventstoreProvider);