UNPKG

@othree.io/chisel

Version:

Event sourcing made easy

105 lines 5.1 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateNewState = exports.loadState = void 0; const optional_1 = require("@othree.io/optional"); const cerillo_1 = require("@othree.io/cerillo"); const loadState = (configuration) => (getEvents) => (getInitialState) => (reduce) => (contextId) => __awaiter(void 0, void 0, void 0, function* () { return (0, optional_1.TryAsync)(() => __awaiter(void 0, void 0, void 0, function* () { if (contextId.isEmpty) { return (yield getInitialState(contextId)) .map(state => ({ state: state, events: [], })); } return (yield getEvents(contextId.get())) .mapAsync((events) => __awaiter(void 0, void 0, void 0, function* () { if (events.length === 0) { return (yield getInitialState(contextId)) .map(state => ({ state: state, events: [], })); } const snapshotIdx = events.findIndex(event => event.type === configuration.SnapshotEventType); const maybeInitialState = yield (0, cerillo_1.match)(snapshotIdx) .when(_ => _ < 0).then((_) => __awaiter(void 0, void 0, void 0, function* () { return getInitialState(contextId); })) .default((_) => __awaiter(void 0, void 0, void 0, function* () { return (0, optional_1.Optional)(configuration.SnapshotSerializer.deserialize(events[_].snapshot)); })) .get(); return maybeInitialState.map(initialState => { const eventsReplayRange = snapshotIdx < 0 ? events.length : snapshotIdx; const eventsToReplay = Array.from(Array(eventsReplayRange).keys()) .map(key => events[key]) .reverse(); const currentState = eventsToReplay.reduce(reduce, initialState); return { state: currentState, events: eventsToReplay, }; }); })); })); }); exports.loadState = loadState; const calculateNewState = (configuration) => (newId) => (now) => (persistEvent) => (reduce) => (command, state, newEvents) => __awaiter(void 0, void 0, void 0, function* () { return (0, optional_1.TryAsync)(() => __awaiter(void 0, void 0, void 0, function* () { return newEvents.reduce((acumPromise, newEvent) => __awaiter(void 0, void 0, void 0, function* () { const currentState = yield acumPromise; const event = (yield persistEvent({ type: newEvent.type, body: newEvent.body, contextId: newEvent.contextId, eventId: newId(), eventDate: now(), metadata: command.metadata, emitter: command.emitter })).get(); if ((currentState.events.length + 1) === (configuration.SnapshotFrequency - 1)) { const snapshot = [event].reduce(reduce, currentState.state); (yield persistEvent({ snapshot: configuration.SnapshotSerializer.serialize(snapshot), contextId: event.contextId, eventId: newId(), eventDate: now(), type: configuration.SnapshotEventType, body: {}, })).get(); return { state: snapshot, events: [], newEvents: [ ...currentState.newEvents, event, ], }; } else { const updatedState = [event].reduce(reduce, currentState.state); return { state: updatedState, events: [ ...currentState.events, event, ], newEvents: [ ...currentState.newEvents, event, ], }; } }), Promise.resolve(Object.assign(Object.assign({}, state), { newEvents: [] }))); })); }); exports.calculateNewState = calculateNewState; //# sourceMappingURL=event-source.js.map