UNPKG

@getanthill/datastore

Version:

Event-Sourced Datastore

145 lines 6.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.publish = publish; exports.publishEntityUpdates = publishEntityUpdates; exports.created = created; exports.updated = updated; exports.patched = patched; exports.applied = applied; exports.restored = restored; const omit_1 = __importDefault(require("lodash/omit")); const utils_1 = require("../../utils"); const LAST_FRAGMENT_REGEXP = /\/[^/]+$/; async function publish(services, topic, event) { if (services.config.features.mqtt.isEnabled === true) { await services.mqtt.publish(topic, event); // Required to listen on deterministic event names: services.mqtt.emit(topic.replace(LAST_FRAGMENT_REGEXP, ''), event); } if (services.config.features.amqp.isEnabled === true) { await services.amqp.publish(topic, event); // Required to listen on deterministic event names: services.amqp.emit(topic.replace(LAST_FRAGMENT_REGEXP, ''), event); } } async function publishEntityUpdates(services, modelName, eventName, entity) { const topic = `${modelName}/${eventName}/success/${entity.correlationId}`.toLowerCase(); await Promise.all([ publish(services, topic, entity.state), ...entity.latestHandledEvents.map((e) => publish(services, `${modelName}/${e.type}/events/${entity.correlationId}`.toLowerCase(), e)), ]); } async function created(services, req, event) { var _a; const entity = services.models.factory(req.params.model); const body = event; if ((_a = req.headers) === null || _a === void 0 ? void 0 : _a['created-at']) { body.created_at = (0, utils_1.getDate)(req.headers['created-at']); } await entity.create(body); services.telemetry.logger.debug('[events#created] Entity created', { entity: entity.state, }); await publishEntityUpdates(services, req.params.model, 'created', entity); return entity; } async function updated(services, req, event) { var _a, _b, _c, _d; const entity = services.models.factory(req.params.model, req.params.correlation_id); const upsert = ((_a = req.headers) === null || _a === void 0 ? void 0 : _a['upsert']) === 'true'; const imperativeVersion = ((_b = req.headers) === null || _b === void 0 ? void 0 : _b['version']) !== undefined ? Number.parseInt((_c = req.headers) === null || _c === void 0 ? void 0 : _c['version'], 10) : undefined; const body = event; if ((_d = req.headers) === null || _d === void 0 ? void 0 : _d['created-at']) { body.created_at = (0, utils_1.getDate)(req.headers['created-at']); } if (upsert === true) { await entity.upsert(body, { imperativeVersion }); } else { await entity.update(body, { imperativeVersion }); } services.telemetry.logger.debug('[api/models#update] Entity updated', { model: req.params.model, entity: entity.state, }); await publishEntityUpdates(services, req.params.model, 'updated', entity); return entity; } async function patched(services, req, event) { var _a, _b, _c; const entity = services.models.factory(req.params.model, req.params.correlation_id); const imperativeVersion = ((_a = req.headers) === null || _a === void 0 ? void 0 : _a['version']) ? Number.parseInt((_b = req.headers) === null || _b === void 0 ? void 0 : _b['version'], 10) : undefined; const body = event; if ((_c = req.headers) === null || _c === void 0 ? void 0 : _c['created-at']) { body.created_at = (0, utils_1.getDate)(req.headers['created-at']); } await entity.patch(body, { imperativeVersion }); services.telemetry.logger.debug('[api/models#update] Entity patched', { model: req.params.model, }); await publishEntityUpdates(services, req.params.model, 'patched', entity); return entity; } async function applied(services, req, event) { const entity = services.models.factory(req.params.model, req.params.correlation_id); const imperativeVersion = req.headers['version'] !== undefined ? Number.parseInt(req.headers['version'], 10) : undefined; const isReplay = req.headers['replay'] === 'true'; const retryDuration = req.headers['retry-duration'] !== undefined ? Number.parseInt(req.headers['retry-duration'], 10) : undefined; let body = event; if (req.headers['created-at']) { body.created_at = (0, utils_1.getDate)(req.headers['created-at']); } if (isReplay === true) { const Model = services.models.getModel(req.params.model); const modelConfig = Model.getModelConfig(); const correlationField = modelConfig.correlation_field; const foundEvent = await Model.getEventsCollection(Model.db(services.mongodb)).findOne({ [correlationField]: req.params.correlation_id, type: body.type, created_at: { $gte: body.created_at, $lte: body.created_at, }, }); if (!!foundEvent === true) { entity.state = await entity.getStateAtVersion(foundEvent.version); return entity; } const originalPayload = (0, omit_1.default)(body, 'type', 'v', '_id', 'version'); body = await Model.decrypt(originalPayload); } await entity.apply(req.params.event_type.toUpperCase(), body, { imperativeVersion, retryDuration, }, req.headers['event-version'] || req.params.event_version); if (isReplay === false) { await publishEntityUpdates(services, req.params.model, req.params.event_type, entity); } return entity; } async function restored(services, req, event) { const entity = services.models.factory(req.params.model, req.params.correlation_id); req.locals = req.locals || {}; req.locals.model = entity; const version = Number.parseInt(req.params.version, 10); await entity.getState(); if (entity.state === null) { throw new Error('Not Found'); } req.locals.currentVersion = entity.state.version; await entity.restore(version); await publishEntityUpdates(services, req.params.model, 'restored', entity); return entity; } //# sourceMappingURL=handlers.js.map