@actyx/sdk
Version:
Actyx SDK
126 lines • 7 kB
JavaScript
;
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