@actyx/sdk
Version:
Actyx SDK
161 lines • 5.88 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeInfo = exports.SwarmState = exports.NodeStatusIo = exports.ConnectivityStatus = exports.ConnectivityStatusType = exports.EventsSortOrders = exports.UnstoredEvents = exports.UnstoredEvent = exports.Events = exports.Event = exports.SubscribeMonotonicResponseIO = exports.TimeTravelIO = exports.OffsetsIO = exports.DiagnosticIO = exports.MonotonicEventIO = exports._compareEvents = exports.EventIO = exports.OffsetsResponse = exports.createEnumType = exports.EnumType = void 0;
/*
* Actyx SDK: Functions for writing distributed apps
* deployed on peer-to-peer networks, without any servers.
*
* Copyright (C) 2021 Actyx AG
*/
const Either_1 = require("fp-ts/lib/Either");
const N = require("fp-ts/lib/number");
const S = require("fp-ts/lib/string");
const t = require("io-ts");
const types_1 = require("../types");
const wire_1 = require("../types/wire");
// EnumType Class
class EnumType extends t.Type {
constructor(e, name) {
super(name || 'enum', (u) => Object.values(this.enumObject).some((v) => v === u), (u, c) => (this.is(u) ? t.success(u) : t.failure(u, c)), t.identity);
this._tag = 'EnumType';
this.enumObject = e;
}
}
exports.EnumType = EnumType;
// simple helper function
const createEnumType = (e, name) => new EnumType(e, name);
exports.createEnumType = createEnumType;
exports.OffsetsResponse = t.readonly(t.type({
present: t.readonly(wire_1.OffsetMapIO),
toReplicate: t.record(wire_1.Codecs.StreamId, t.number),
}));
const stringRA = t.array(t.string);
const Tags = new t.Type('TagsSetFromArray', (x) => x instanceof Array && x.every(types_1.isString),
// Rust side for now expresses empty tag arrays as omitting the field
(x, c) => (x === undefined ? (0, Either_1.right)([]) : stringRA.validate(x, c)),
// Sending empty arrays is fine, though
(x) => x);
exports.EventIO = t.type({
offset: wire_1.Codecs.Offset,
stream: wire_1.Codecs.StreamId,
timestamp: wire_1.Codecs.Timestamp,
lamport: wire_1.Codecs.Lamport,
appId: wire_1.Codecs.AppId,
tags: Tags,
payload: t.unknown,
});
const _compareEvents = (a, b) => {
const lamportOrder = N.Ord.compare(a.lamport, b.lamport);
if (lamportOrder !== 0) {
return lamportOrder;
}
const sourceOrder = S.Ord.compare(a.stream, b.stream);
if (sourceOrder !== 0) {
return sourceOrder;
}
return N.Ord.compare(a.offset, b.offset);
};
exports._compareEvents = _compareEvents;
exports.MonotonicEventIO = t.intersection([
exports.EventIO,
t.type({
type: t.literal('event'),
caughtUp: t.boolean,
}),
]);
exports.DiagnosticIO = t.type({
type: t.literal('diagnostic'),
severity: t.keyof({ warning: 1, error: 1 }),
message: t.string,
});
exports.OffsetsIO = t.type({
type: t.literal('offsets'),
offsets: wire_1.OffsetMapIO,
});
exports.TimeTravelIO = t.type({
type: t.literal('timeTravel'),
newStart: wire_1.EventKeyIO,
});
exports.SubscribeMonotonicResponseIO = t.union([
exports.MonotonicEventIO,
exports.DiagnosticIO,
exports.OffsetsIO,
exports.TimeTravelIO,
]);
const eventsEqual = (a, b) =>
// compare numerical fields first since it should be faster
a.lamport === b.lamport && a.offset === b.offset && a.stream === b.stream;
/**
* Order for events
*
* Order is [lamport, sourceId]
* Events are considered equal when lamport, sourceId, psn are equal without considering
* the content of the payload. Having two events that have these fields equal yet a different
* payload would be a grave bug in our system.
*/
const ordEvent = {
equals: eventsEqual,
compare: exports._compareEvents,
};
exports.Event = {
ord: ordEvent,
};
/**
* A number of events, not necessarily from the same source
*/
exports.Events = t.array(exports.EventIO);
/**
* A number of generated events, that are going to be written to the store.
*/
exports.UnstoredEvent = t.readonly(t.type({
tags: Tags,
payload: t.unknown,
}));
exports.UnstoredEvents = t.readonlyArray(exports.UnstoredEvent);
exports.EventsSortOrders = (0, exports.createEnumType)(types_1.EventsSortOrder, 'PersistedEventsSortOrders');
/**
* Connectivity status type.
*/
var ConnectivityStatusType;
(function (ConnectivityStatusType) {
ConnectivityStatusType["FullyConnected"] = "FullyConnected";
ConnectivityStatusType["PartiallyConnected"] = "PartiallyConnected";
ConnectivityStatusType["NotConnected"] = "NotConnected";
})(ConnectivityStatusType = exports.ConnectivityStatusType || (exports.ConnectivityStatusType = {}));
const FullyConnected = t.readonly(t.type({
status: t.literal(ConnectivityStatusType.FullyConnected),
inCurrentStatusForMs: t.number,
}));
const PartiallyConnected = t.readonly(t.type({
status: t.literal(ConnectivityStatusType.PartiallyConnected),
inCurrentStatusForMs: t.number,
specialsDisconnected: t.readonlyArray(t.string),
swarmConnectivityLevel: t.number,
eventsToRead: t.number,
eventsToSend: t.number,
}));
const NotConnected = t.readonly(t.type({
status: t.literal(ConnectivityStatusType.NotConnected),
inCurrentStatusForMs: t.number,
eventsToRead: t.number,
eventsToSend: t.number,
}));
/**
* The IO-TS type parser for ConnectivityStatus.
* @public
*/
exports.ConnectivityStatus = t.union([FullyConnected, PartiallyConnected, NotConnected]);
exports.NodeStatusIo = (0, exports.createEnumType)(types_1.NodeStatus, 'NodeStatusIo');
exports.SwarmState = t.type({
peersStatus: t.record(wire_1.Codecs.NodeId, exports.NodeStatusIo),
});
exports.NodeInfo = t.type({
connectedNodes: t.number,
uptime: t.type({
secs: t.number,
nanos: t.number,
}),
version: t.string,
swarmState: t.union([t.undefined, exports.SwarmState]),
});
//# sourceMappingURL=types.js.map