UNPKG

@nestjs-cqrs-eventsourcing/core

Version:

Event sourcing for nestjs CQRS

135 lines (134 loc) 5.38 kB
"use strict"; 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);