UNPKG

@actyx/sdk

Version:
219 lines 7.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeStatus = exports.EventsSortOrder = exports.ActyxEvent = exports.toMetadata = exports.maxLamportLength = exports.EventKey = exports.Milliseconds = exports.Timestamp = exports.Offset = exports.Lamport = exports.AppId = exports.StreamId = exports.NodeId = void 0; /* * Actyx SDK: Functions for writing distributed apps * deployed on peer-to-peer networks, without any servers. * * Copyright (C) 2021 Actyx AG */ const Ord_1 = require("fp-ts/lib/Ord"); const string_1 = require("fp-ts/lib/string"); const number_1 = require("fp-ts/lib/number"); const mkNodeId = (text) => text; const randomBase58 = (digits) => { const base58 = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'.split(''); let result = ''; let char; while (result.length < digits) { char = base58[(Math.random() * 57) >> 0]; result += char; } return result; }; /** * `SourceId` associated functions. * @public */ exports.NodeId = { /** * Creates a NodeId from a string */ of: mkNodeId, /** * Creates a random SourceId with the given number of digits */ random: (digits) => mkNodeId(randomBase58(digits || 11)), streamNo: (nodeId, num) => nodeId + '-' + num, }; const mkStreamId = (text) => text; /** * `SourceId` associated functions. * @public */ exports.StreamId = { /** * Creates a StreamId from a string */ of: mkStreamId, /** * Creates a random StreamId off a random NodeId. */ random: () => exports.NodeId.streamNo(mkNodeId(randomBase58(11)), Math.floor(Math.random() * 100)), }; const mkAppId = (text) => text; /** * `AppId` associated functions. * @public */ exports.AppId = { /** * Creates a AppId from a string */ of: mkAppId, }; const mkLamport = (value) => value; /** @public */ exports.Lamport = { of: mkLamport, zero: mkLamport(0), }; const mkOffset = (n) => n; /** Functions related to Offsets. * @public */ exports.Offset = { of: mkOffset, zero: mkOffset(0), /** * A value that is below any valid Offset */ min: mkOffset(-1), /** * A value that is above any valid Offset */ max: mkOffset(Number.MAX_SAFE_INTEGER), }; const mkTimestamp = (time) => time; const formatTimestamp = (timestamp) => new Date(timestamp / 1000).toISOString(); const secondsPerDay = 24 * 60 * 60; /** Helper functions for making sense of and converting Timestamps. * @public */ exports.Timestamp = { of: mkTimestamp, zero: mkTimestamp(0), maxSafe: mkTimestamp(Number.MAX_SAFE_INTEGER), now: (now) => mkTimestamp((now || Date.now()) * 1e3), format: formatTimestamp, toSeconds: (value) => value / 1e6, toMilliseconds: (value) => exports.Milliseconds.of(value / 1e3), toDate: (value) => new Date(value / 1e3), fromDate: (date) => mkTimestamp(date.valueOf() * 1e3), fromDays: (value) => exports.Timestamp.fromSeconds(secondsPerDay * value), fromSeconds: (value) => mkTimestamp(value * 1e6), fromMilliseconds: (value) => mkTimestamp(value * 1e3), min: (...values) => mkTimestamp(Math.min(...values)), max: (values) => mkTimestamp(Math.max(...values)), }; const mkMilliseconds = (time) => time; /** Helper functions for making sense of and converting Milliseconds. * @public */ exports.Milliseconds = { of: mkMilliseconds, fromDate: (date) => mkMilliseconds(date.valueOf()), zero: mkMilliseconds(0), now: (now) => mkMilliseconds(now || Date.now()), toSeconds: (value) => value / 1e3, toTimestamp: (value) => exports.Timestamp.of(value * 1e3), fromSeconds: (value) => mkMilliseconds(value * 1e3), fromMinutes: (value) => mkMilliseconds(value * 1e3 * 60), // Converts millis or micros to millis // Note: This is a stopgap until we fixed once and for all this mess. fromAny: (value) => { const digits = Math.floor(Math.abs(value)).toString().length; return exports.Milliseconds.of(digits <= 13 ? value : value / 1e3); }, }; const zeroKey = { lamport: exports.Lamport.zero, // Cannot use empty source id, store rejects. stream: exports.NodeId.of('!'), offset: exports.Offset.of(0), }; const keysEqual = (a, b) => a.lamport === b.lamport && a.stream === b.stream; const keysCompare = (a, b) => { const lamportOrder = number_1.Ord.compare(a.lamport, b.lamport); if (lamportOrder !== 0) { return lamportOrder; } return string_1.Ord.compare(a.stream, b.stream); }; /** * Order for event keys * * Order is [lamport, streamId, psn]. Event keys are considered equal when `lamport`, * `streamId` and `psn` are equal. */ const ordEventKey = { equals: keysEqual, compare: keysCompare, }; const formatEventKey = (key) => `${key.lamport}/${key.stream}`; /** Functions related to EventKey. * @public */ exports.EventKey = { zero: zeroKey, ord: ordEventKey, format: formatEventKey, }; /** Max length of a lamport timestamp as string. @internal */ exports.maxLamportLength = String(Number.MAX_SAFE_INTEGER).length; /** Make a function that makes metadata from an Event as received over the wire. @internal */ const toMetadata = (sourceId) => (ev) => ({ isLocalEvent: ev.stream === sourceId, tags: ev.tags, timestampMicros: ev.timestamp, timestampAsDate: exports.Timestamp.toDate.bind(null, ev.timestamp), lamport: ev.lamport, appId: ev.appId, eventId: String(ev.lamport).padStart(exports.maxLamportLength, '0') + '/' + ev.stream, stream: ev.stream, offset: ev.offset, }); exports.toMetadata = toMetadata; /** Things related to ActyxEvent. * @public */ exports.ActyxEvent = { // TODO: Maybe improve this by just comparing the lamport -> stream combo ord: (0, Ord_1.contramap)((e) => e.meta.eventId)(string_1.Ord), }; /** * Sort order for persisted events. * @public */ var EventsSortOrder; (function (EventsSortOrder) { /** Strictly ascending, meaning events are strictly ordered by eventId. */ EventsSortOrder["Ascending"] = "asc"; /** Strictly descending, meaning events are strictly ordered by eventId, reverse. */ EventsSortOrder["Descending"] = "desc"; /** Ascending per stream, meaning between different streams there is no specific order guaranteed. */ EventsSortOrder["StreamAscending"] = "stream-asc"; })(EventsSortOrder = exports.EventsSortOrder || (exports.EventsSortOrder = {})); /** * Status of another node as observed by the local node * @public */ var NodeStatus; (function (NodeStatus) { /** * Replicates all streams within at most two gossip cycles */ NodeStatus["LowLatency"] = "LowLatency"; /** * Replicates all streams within at most five gossip cycles */ NodeStatus["HighLatency"] = "HighLatency"; /** * Replicates at least half of all streams within five gossip cycles */ NodeStatus["PartiallyWorking"] = "PartiallyWorking"; /** * Replicates less than half of all streams within five gossip cycles * * This state either means that the node is disconnected from our part of * the network or that it has been shut down or decommissioned. Old streams * will stay in the swarm in this state. */ NodeStatus["NotWorking"] = "NotWorking"; })(NodeStatus = exports.NodeStatus || (exports.NodeStatus = {})); //# sourceMappingURL=various.js.map