UNPKG

@actyx/sdk

Version:
161 lines 5.88 kB
"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