UNPKG

@actyx/sdk

Version:
126 lines 7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebsocketEventStore = exports.RequestTypes = void 0; /* * Actyx SDK: Functions for writing distributed apps * deployed on peer-to-peer networks, without any servers. * * Copyright (C) 2021 Actyx AG */ const t = require("io-ts"); const log_1 = require("../internal_common/log"); const types_1 = require("../internal_common/types"); const wire_1 = require("../types/wire"); const util_1 = require("../util"); const rxjs_1 = require("../../node_modules/rxjs"); const operators_1 = require("../../node_modules/rxjs/operators"); const semver_1 = require("semver"); var RequestTypes; (function (RequestTypes) { RequestTypes["Offsets"] = "offsets"; RequestTypes["Query"] = "query"; RequestTypes["Subscribe"] = "subscribe"; RequestTypes["SubscribeMonotonic"] = "subscribe_monotonic"; RequestTypes["Publish"] = "publish"; })(RequestTypes = exports.RequestTypes || (exports.RequestTypes = {})); const QueryRequest = t.readonly(t.type({ lowerBound: wire_1.OffsetMapIO, upperBound: wire_1.OffsetMapIO, query: t.string, order: types_1.EventsSortOrders, })); const SubscribeRequest = t.readonly(t.type({ lowerBound: wire_1.OffsetMapIO, query: t.string, })); const SubscribeMonotonicRequest = t.readonly(t.type({ session: t.string, query: t.string, lowerBound: wire_1.OffsetMapIO, })); const PersistEventsRequest = t.readonly(t.type({ data: types_1.UnstoredEvents })); const EventKeyWithTime = t.intersection([wire_1.EventKeyIO, t.type({ timestamp: t.number })]); const PublishEventsResponse = t.type({ data: t.readonlyArray(EventKeyWithTime) }); class WebsocketEventStore { constructor(multiplexer, appId, currentActyxVersion) { this.multiplexer = multiplexer; this.appId = appId; this.currentActyxVersion = currentActyxVersion; this.offsets = () => (0, rxjs_1.lastValueFrom)(this.multiplexer .request("offsets" /* Offsets */) .pipe((0, operators_1.map)((0, util_1.validateOrThrow)(types_1.OffsetsResponse)), (0, operators_1.first)())); this.queryUnchecked = (aqlQuery, sortOrder, lowerBound) => this.multiplexer .request("query" /* Query */, { lowerBound: lowerBound || {}, query: aqlQuery, order: sortOrder, }) .pipe((0, operators_1.tap)({ next: (item) => log_1.default.ws.debug(`got queryUnchecked response of type '${item.type}'`), error: (err) => log_1.default.ws.info('queryUnchecked response stream failed', err), complete: () => log_1.default.ws.debug('queryUnchecked reponse completed'), }), (0, operators_1.map)((x) => x)); this.query = (lowerBound, upperBound, whereObj, sortOrder, horizon) => this.multiplexer .request("query" /* Query */, QueryRequest.encode({ lowerBound, upperBound, query: `FEATURES(eventKeyRange) FROM (${whereObj}) ${(0, semver_1.gte)(this.currentActyxVersion(), '2.5.0') && horizon ? `& from(${horizon})` : ''}`, order: sortOrder, })) .pipe((0, operators_1.tap)({ next: (item) => log_1.default.ws.debug(`got query response of type '${item.type}'`), error: (err) => log_1.default.ws.info('query response stream failed', err), complete: () => log_1.default.ws.debug('query reponse completed'), }), (0, operators_1.filter)((x) => x.type === 'event'), (0, operators_1.map)((0, util_1.validateOrThrow)(types_1.EventIO))); this.subscribe = (lowerBound, whereObj, horizon) => this.multiplexer .request("subscribe" /* Subscribe */, SubscribeRequest.encode({ lowerBound, query: `FEATURES(eventKeyRange) FROM (${whereObj}) ${(0, semver_1.gte)(this.currentActyxVersion(), '2.5.0') && horizon ? `& from(${horizon})` : ''}`, })) .pipe((0, operators_1.tap)({ next: (item) => log_1.default.ws.debug(`got subscribe response of type '${item.type}'`), error: (err) => log_1.default.ws.info('subscribe response stream failed', err), complete: () => log_1.default.ws.debug('subscribe response completed'), }), (0, operators_1.filter)((x) => x.type === 'event'), (0, operators_1.map)((0, util_1.validateOrThrow)(types_1.EventIO))); this.subscribeMonotonic = (session, lowerBound, whereObj, horizon) => this.multiplexer .request("subscribe_monotonic" /* SubscribeMonotonic */, SubscribeMonotonicRequest.encode({ session, lowerBound, query: `FEATURES(eventKeyRange) FROM (${whereObj}) ${(0, semver_1.gte)(this.currentActyxVersion(), '2.5.0') && horizon ? `& from(${horizon})` : ''}`, })) .pipe((0, operators_1.tap)({ next: (item) => log_1.default.ws.debug(`got subscribe response of type '${item.type}'`), error: (err) => log_1.default.ws.info('subscribe response stream failed', err), complete: () => log_1.default.ws.debug('subscribe response completed'), }), (0, operators_1.filter)((x) => ['diagnostic', 'event', 'offsets', 'timeTravel'].includes(x.type)), (0, operators_1.map)((0, util_1.validateOrThrow)(types_1.SubscribeMonotonicResponseIO))); this.subscribeUnchecked = (aqlQuery, lowerBound) => this.multiplexer .request("subscribe" /* Subscribe */, { lowerBound: lowerBound === undefined ? {} : lowerBound, query: aqlQuery, }) .pipe((0, operators_1.tap)({ next: (item) => log_1.default.ws.debug(`got subscribeUnchecked response of type '${item.type}'`), error: (err) => log_1.default.ws.info('subscribeUnchecked response stream failed', err), complete: () => log_1.default.ws.debug('subscribeUnchecked reponse completed'), }), (0, operators_1.map)((x) => x)); this.persistEvents = (events) => { const publishEvents = events; return this.multiplexer .request("publish" /* Publish */, PersistEventsRequest.encode({ data: publishEvents })) .pipe((0, operators_1.map)((0, util_1.validateOrThrow)(PublishEventsResponse)), (0, operators_1.map)(({ data: persistedEvents }) => { if (publishEvents.length !== persistedEvents.length) { log_1.default.ws.error('PutEvents: Sent %d events, but only got %d PSNs back.', publishEvents.length, events.length); return []; } return publishEvents.map((ev, idx) => ({ ...persistedEvents[idx], appId: this.appId, tags: ev.tags, payload: ev.payload, })); }), (0, operators_1.defaultIfEmpty)([])); }; } } exports.WebsocketEventStore = WebsocketEventStore; //# sourceMappingURL=websocketEventStore.js.map