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