@actyx/sdk
Version:
Actyx SDK
1,225 lines (1,130 loc) • 46.7 kB
TypeScript
import { Ord } from 'fp-ts/lib/Ord';
import * as t from 'io-ts';
declare type ActiveRequest = {
serviceId: string;
payload?: unknown;
time: Date;
};
declare type ActiveRequestGlobals = {
all: () => ActiveRequest[];
[GlobalInternalSymbol]: {
register: (sym: symbol, activeRequest: ActiveRequest) => unknown;
unregister: (sym: symbol) => unknown;
};
};
/**
* Global object for accessing currently active requests
* @public
*/
declare const activeRequests: ActiveRequestGlobals;
/** Access all sorts of functionality related to the Actyx system!
* @public */
export declare type Actyx = EventFns & {
/** Id of the Actyx node this interface is connected to. */
readonly nodeId: NodeId;
/** Fish snapshot store for the Pond
* @beta */
readonly snapshotStore: SnapshotStore;
/** Dispose of this Actyx connector, cancelling all ongoing subscriptions and freeing all underlying ressources.
* @public */
dispose: () => void;
/** Wait for the connected node to be in sync with the swarm. This is on a
* best-effort basis and waits at most 30 seconds after the point in time the
* node has been started. This can be used in order to reduce stale state
* inside the application when started together with an Actyx node.
* @public */
waitForSync: () => Promise<void>;
/**
* Obtain information on the Actyx node. In order to save some cycles, and because the information
* doesn’t change all that quickly, please provide a time parameter that matches your app’s
* freshness requirements — for human consumption a couple hundred milliseconds is good enough.
*
* The underlying API endpoint has been added in Actyx 2.5.0, earlier versions report dummy data.
*
* Starting with Actyx 2.15.0 the returned data also contains the swarm status as seen by this node.
*
* @public
*/
nodeInfo: (maxAgeMillis: number) => Promise<NodeInfo>;
};
/** Function for creating `Actyx` instances.
* @public */
export declare const Actyx: {
/** Create an `Actyx` instance that talks to a running `Actyx` system.
* @public */
of: (manifest: AppManifest, opts?: ActyxOpts) => Promise<Actyx>;
/**
* Create an `Actyx` instance that mocks all APIs within TypeScript. Useful for unit-tests.
* Will not talk to other nodes, but rather that can be simulated via `directlyPushEvents`.
* @public
*/
test: (opts?: ActyxTestOpts) => TestActyx;
};
/** An event with its metadata.
* @public */
export declare type ActyxEvent<E = unknown> = {
meta: Metadata;
payload: E;
};
/** Things related to ActyxEvent.
* @public */
export declare const ActyxEvent: {
ord: Ord<ActyxEvent<unknown>>;
};
/** Options used when creating a new `Actyx` instance.
* @public */
export declare type ActyxOpts = {
/** Host of the Actxy service. This defaults to localhost and should stay localhost in almost all cases. */
actyxHost?: string;
/** API port of the Actyx service. Defaults to 4454. */
actyxPort?: number;
/** Hook, when the connection to the store is closed */
onConnectionLost?: () => void;
/**
* Hook, when the connection to the store has been established.
*/
onConnectionEstablished?: () => void;
};
/** Options used when creating a new TEST `Actyx` instance.
* @public */
export declare type ActyxTestOpts = {
/** Local node id to use
* @public */
nodeId?: NodeId;
/** Install the given time source for test purposes
* @beta */
timeInjector?: TimeInjector;
};
/**
* A `Where` expression that selects all events.
* @public
*/
export declare const allEvents: Tags<unknown>;
/**
* An Actyx app id.
* @public
*/
export declare type AppId = string;
/**
* `AppId` associated functions.
* @public
*/
export declare const AppId: {
/**
* Creates a AppId from a string
*/
of: (text: string) => AppId;
};
/** Manifest describing an Actyx application. Used for authorizing API access.
* @public */
export declare type AppManifest = {
/**
* Structured application id.
* For testing and development purposes, you can always pass 'com.example.somestring'
* For production, you will buy a license from Actyx for your specific app id like com.my-company.my-app.
*/
appId: string;
/** Arbitrary string describing the app. */
displayName: string;
/** Arbitrary version string */
version: string;
/** Manifest signature, if it’s not an example app. */
signature?: string;
};
/** AQL diagnostic output describing an error that occured during query evaluation.
* @beta */
export declare type AqlDiagnosticMessage = {
/** A problem occured */
type: 'diagnostic';
severity: string;
message: string;
};
/** AQL message conveying a raw event or a record created by mapping an event via SELECT.
* @beta */
export declare type AqlEventMessage = {
/** A simply-mapped event */
type: 'event';
/** Payload data generated by the AQL query via SELECT statements. */
payload: unknown;
/** Metadata of the event that yielded this record. */
meta: Metadata;
};
/** Future versions of AQL will know additional response message types.
* @beta */
export declare type AqlFutureCompat = {
/** Consult AQL documentation to find out about future available types. */
type: Exclude<'event' | 'offsets' | 'diagnostic', string>;
payload: unknown;
/** Consult AQL documentation to find out about future metadata contents. */
meta: Record<string, unknown>;
};
/** AQL message describing the offsets at the current state of the response stream.
* @beta */
export declare type AqlOffsetsMsg = {
type: 'offsets';
offsets: OffsetMap;
};
/** An aql query is either a plain string, or an object containing the string and the desired order.
* @beta */
export declare type AqlQuery = string | {
/** Query as AQL string */
query: string;
/** Desired order of delivery (relative to events). Defaults to 'Asc' */
order?: EventsSortOrder;
};
/** Response message returned by running AQL query.
* @beta */
export declare type AqlResponse = AqlEventMessage | AqlOffsetsMsg | AqlDiagnosticMessage | AqlFutureCompat;
/** Query for a set of events which is automatically capped at the latest available upperBound.
* @public */
export declare type AutoCappedQuery = {
/**
* Starting point for the query. Everything up-to-and-including `lowerBound` will be omitted from the result.
* Defaults to empty map, which means no lower bound at all.
* Sources not listed in the `lowerBound` will be delivered in full.
*/
lowerBound?: OffsetMap;
/** Statement to select specific events. Defaults to `allEvents`. */
query?: Where<unknown>;
/** Desired order of delivery. Defaults to 'Asc' */
order?: EventsSortOrder;
/** Earliest event ID to consider in the result */
horizon?: string;
};
/**
* Cancel an ongoing aggregation (the provided callback will stop being called).
* @public
*/
export declare type CancelSubscription = () => void;
/** Query for observeEarliest.
* @beta */
export declare type EarliestQuery<E> = {
/** Statement to select specific events. */
query: Where<E>;
/**
* Starting point for the query. Everything up-to-and-including `lowerBound` will be omitted from the result.
* Defaults to empty map, which means no lower bound at all.
* Sources not listed in the `lowerBound` will be delivered in full.
*/
lowerBound?: OffsetMap;
/** The order to find min/max for. Defaults to `Lamport`. */
eventOrder?: EventOrder;
};
declare class EnumType<A> extends t.Type<A> {
readonly _tag: 'EnumType';
enumObject: object;
constructor(e: object, name?: string);
}
/**
* A chunk of events, with lower and upper bound.
* A call to `queryKnownRange` with the included bounds is guaranteed to return exactly the contained set of events.
* A call to `subscribe` with the included `lowerBound`, however, may find new events from sources not included in the bounds.
*
* @public
*/
export declare type EventChunk = {
/** The event data. Sorting depends on the request which produced this chunk. */
events: ActyxEvent[];
/** The lower bound of the event chunk, independent of its sorting in memory. */
lowerBound: OffsetMap;
/** The upper bound of the event chunk, independent of its sorting in memory. */
upperBound: OffsetMap;
};
/** Functions that operate directly on Events.
* @public */
export declare interface EventFns {
/** Get the current local 'present' i.e. offsets up to which we can provide events without any gaps. */
present: () => Promise<OffsetMap>;
/** Get the present alongside information on how many events are known to be pending replication from peers to us. */
offsets: () => Promise<OffsetsResponse>;
/**
* Get all known events between the given offsets, in one array.
*
* @param query - `RangeQuery` object specifying the desired set of events.
*
* @returns A Promise that resolves to the complete set of queries events.
*/
queryKnownRange: (query: RangeQuery) => Promise<ActyxEvent[]>;
/**
* Get all known events between the given offsets, in chunks.
* This is helpful if the result set is too large to fit into memory all at once.
* The returned `Promise` resolves after all chunks have been delivered.
*
* @param query - `RangeQuery` object specifying the desired set of events.
* @param chunkSize - Maximum size of chunks. Chunks may be smaller than this.
* @param onChunk - Callback that will be invoked with every chunk, in sequence.
*
* @returns A function that can be called in order to cancel the delivery of further chunks.
*/
queryKnownRangeChunked: (query: RangeQuery, chunkSize: number, onChunk: (chunk: EventChunk) => Promise<void> | void, onComplete?: OnCompleteOrErr) => CancelSubscription;
/**
* Query all known events that occured after the given `lowerBound`.
*
* @param query - `OpenEndedQuery` object specifying the desired set of events.
*
* @returns An `EventChunk` with the result and its bounds.
* The contained `upperBound` can be passed as `lowerBound` to a subsequent call of this function to achieve exactly-once delivery of all events.
*/
queryAllKnown: (query: AutoCappedQuery) => Promise<EventChunk>;
/**
* Query all known events that occured after the given `lowerBound`, in chunks.
* This is useful if the complete result set is potentially too large to fit into memory at once.
*
* @param query - `OpenEndedQuery` object specifying the desired set of events.
* @param chunkSize - Maximum size of chunks. Chunks may be smaller than this.
* @param onChunk - Callback that will be invoked for each chunk, in sequence. Second argument is an offset map covering all events passed as first arg.
*
* @returns A function that can be called in order to cancel the delivery of further chunks.
*/
queryAllKnownChunked: (query: AutoCappedQuery, chunkSize: number, onChunk: (chunk: EventChunk) => Promise<void> | void, onComplete?: OnCompleteOrErr) => CancelSubscription;
/**
* Run a custom AQL query and get back the raw responses collected.
*
* @param query - A plain AQL query string.
*
* @returns List of all response messages generated by the query.
*
* @beta
*/
queryAql: (query: AqlQuery) => Promise<AqlResponse[]>;
/**
* Run a custom AQL subscription and get back the raw responses collected via a callback.
*
* @param query - A plain AQL query string.
* @param onResponse - Callback that will be invoked for each raw response, in sequence. Even if this is an async function (returning `Promise<void>`), there will be no concurrent invocations of it.
* @param onError - Callback that will be invoked in case on a error.
* @param lowerBound - Starting point (exclusive) for the query. Everything up-to-and-including `lowerBound` will be omitted from the result. Defaults empty record.
*
* @returns A `Promise` that resolves to updated offset-map after all chunks have been delivered.
*
* @beta
*/
subscribeAql: (query: AqlQuery, onResponse: (r: AqlResponse) => Promise<void> | void, onError?: (err: unknown) => void, lowerBound?: OffsetMap) => CancelSubscription;
/**
* Run a custom AQL query and get the response messages in chunks.
*
* @param query - AQL query
* @param chunkSize - Desired chunk size
* @param onChunk - Callback that will be invoked for each chunk, in sequence. Even if this is an async function (returning `Promise<void>`), there will be no concurrent invocations of it.
*
* @returns A function that can be called in order to cancel the delivery of further chunks.
*
* @beta
*/
queryAqlChunked: (query: AqlQuery, chunkSize: number, onChunk: (chunk: AqlResponse[]) => Promise<void> | void, onCompleteOrError: OnCompleteOrErr) => CancelSubscription;
/**
* Subscribe to all events fitting the `query` after `lowerBound`.
*
* The subscription goes on forever, until manually cancelled.
*
* @param query - `EventSubscription` object specifying the desired set of events.
* @param onEvent - Callback that will be invoked for each event, in sequence.
*
* @returns A function that can be called in order to cancel the subscription.
*/
subscribe: (query: EventSubscription, onEvent: (e: ActyxEvent) => Promise<void> | void, onError?: (err: unknown) => void) => CancelSubscription;
/**
* Subscribe to all events fitting the `query` after `lowerBound`.
* They will be delivered in chunks of configurable size.
* Each chunk is internally sorted in ascending `eventId` order.
* The subscription goes on forever, until manually cancelled.
*
* @param query - `EventSubscription` object specifying the desired set of events.
* @param chunkConfig - How event chunks should be built.
* @param onChunk - Callback that will be invoked for each chunk, in sequence. Second argument is the updated offset map.
*
* @returns A function that can be called in order to cancel the subscription.
*/
subscribeChunked: (query: EventSubscription, chunkConfig: {
/** Maximum chunk size. Defaults to 1000. */
maxChunkSize?: number;
/**
* Maximum duration (in ms) a chunk of events is allowed to grow, before being passed to the callback.
* Defaults to 5.
*/
maxChunkTimeMs?: number;
}, onChunk: (chunk: EventChunk) => Promise<void> | void, onError?: (err: unknown) => void) => CancelSubscription;
/**
* Subscribe to a stream of events until this would go back in time.
* Instead of going back in time, receive a TimeTravelMsg and terminate the stream.
*
* @alpha
*/
subscribeMonotonic: <E>(query: MonotonicSubscription<E>, callback: (data: EventsOrTimetravel<E>) => Promise<void> | void, onCompleteOrErr?: OnCompleteOrErr) => CancelSubscription;
/**
* Observe always the **earliest** event matching the given query.
* If there is an existing event fitting the query, `onNewEarliest` will be called with that event.
* Afterwards, `onNewEarliest` will be called whenever a new event becomes known that is older than the previously passed one.
* Note that the 'earliest' event may keep updating as new events become known.
*
* @param query - Query to select the set of events.
* @param onNewEarliest - Callback that will be invoked whenever there is a 'new' earliest event.
*
* @returns A function that can be called in order to cancel the subscription.
*
* @beta
*/
observeEarliest: <E>(query: EarliestQuery<E>, onNewEarliest: (event: E, metadata: Metadata) => void, onError?: (err: unknown) => void) => CancelSubscription;
/**
* Observe always the **latest** event matching the given query.
* If there is an existing event fitting the query, `onNewLatest` will be called with that event.
* Afterwards, `onNewLatest` will be called whenever a new event becomes known that is younger than the previously passed one.
*
* @param query - Query to select the set of events.
* @param onNewLatest - Callback that will be invoked for each new latest event.
*
* @returns A function that can be called in order to cancel the subscription.
*
* @beta
*/
observeLatest: <E>(query: EarliestQuery<E>, onNewLatest: (event: E, metadata: Metadata) => void, onError?: (err: unknown) => void) => CancelSubscription;
/**
* Among all events matching the query, find one that best matches some property.
* This is useful for finding the event that has `min` or `max` of something.
* E.g. `shouldReplace = (candidate: ActyxEventy<number>, cur: ActyxEventy<number>) => candidate.payload > cur.payload` keeps finding the event with the highest payload value.
* Note that there is no guarantee regarding the order in which candidates are passed to the callback!
* If `shouldReplace(a, b)` returns true, the reversed call `shouldReplace(b, a)` should return false. Otherwise results may be wild.
*
* @param query - Query to select the set of `candidate` events.
* @param shouldReplace - Should `candidate` replace `cur`?
* @param onReplaced - Callback that is evoked whenever replacement happens, i.e. we found a new best match.
*
* @returns A function that can be called in order to cancel the subscription.
*/
observeBestMatch: <E>(query: Where<E>, shouldReplace: (candidate: ActyxEvent<E>, cur: ActyxEvent<E>) => boolean, onReplaced: (event: E, metadata: Metadata) => void, onError?: (err: unknown) => void) => CancelSubscription;
/**
* Apply a `reduce` operation to all events matching `query`, in no specific order.
* This is useful for operations that are **commutative**, e.g. `sum` or `product`.
*
* @param query - Query to select the set of events to pass to the reducer.
* @param reduce - Compute a new state `R` by integrating the next event.
* @param initial - Initial, neutral state, e.g. `0` for a `sum` operation.
* @param onUpdate - Callback that is evoked with updated results.
* If a batch of events was applied, `onUpdate` will only be called once, with the final new state.
*
* @returns A function that can be called in order to cancel the subscription.
*/
observeUnorderedReduce: <R, E>(query: Where<E>, reduce: (acc: R, event: E, metadata: Metadata) => R, initial: R, onUpdate: (result: R) => void, onError?: (err: unknown) => void) => CancelSubscription;
/**
* Emit a number of events with tags attached.
*
* @param events - Events to emit.
*
* @returns A `PendingEmission` object that can be used to register callbacks with the emission’s completion.
*
* @deprecated Use `publish` instead, and always await the Promise.
*/
emit: (events: TaggedEvent[]) => PendingEmission;
/**
* Publish a number of events with tags attached.
* This function is the same as `emit`, only it directly returns the Promise.
*
* @param events - Events to publish.
*
* @returns A Promise that resolves to the persisted event’s metadata, in the same order they were passed into the function.
*/
publish(event: TaggedEvent): Promise<Metadata>;
publish(events: TaggedEvent[]): Promise<Metadata[]>;
}
/**
* Triple that Actyx events are sorted and identified by.
*
* @public
*/
export declare type EventKey = {
lamport: Lamport;
offset: Offset;
stream: StreamId;
};
/** Functions related to EventKey.
* @public */
export declare const EventKey: {
zero: EventKey;
ord: Ord<EventKey>;
format: (key: EventKey) => string;
};
/** Which clock to compare events by. Defaults to `Lamport`.
* @beta */
export declare enum EventOrder {
/**
* Comparison according to Lamport clock, which is a logical clock,
* meaning it preserves causal order even when wall clocks on devices are off.
*
* On the flip-side, for any two events where neither is a cause of the other,
* lamport-order may be different from timestamp-order, if the devices creating the events
* where disconnected from each other at the time.
*/
Lamport = "lamport",
/**
* Comparison according to wall clock time logged at event creation.
* If the system clock on a device is wrong, the event's timestamp will also be wrong. */
Timestamp = "timestamp"
}
/** Implies consumer should apply the given events to its latest local state.
* @alpha */
export declare type EventsMsg<E> = {
type: MsgType.events;
events: ActyxEvent<E>[];
caughtUp: boolean;
};
/** Possible subscribe_monotonic message types.
* @alpha */
export declare type EventsOrTimetravel<E> = StateMsg | EventsMsg<E> | TimeTravelMsg<E>;
/**
* Sort order for persisted events.
* @public
*/
export declare enum EventsSortOrder {
/** Strictly ascending, meaning events are strictly ordered by eventId. */
Ascending = "asc",
/** Strictly descending, meaning events are strictly ordered by eventId, reverse. */
Descending = "desc",
/** Ascending per stream, meaning between different streams there is no specific order guaranteed. */
StreamAscending = "stream-asc"
}
/** Subscription to a set of events that may still grow.
* @public */
export declare type EventSubscription = {
/**
* Starting point for the query. Everything up-to-and-including `lowerBound` will be omitted from the result.
* Defaults to empty map, which means no lower bound at all.
* Sources not listed in the `lowerBound` will be delivered in full.
*/
lowerBound?: OffsetMap;
/** Statement to select specific events. Defaults to `allEvents`. */
query?: Where<unknown>;
};
/**
* Sent by the client to indicate it wants event delivery to start from this point.
* Implies that a state was cached in-process by the client and so it does not want to start from a snapshot known to Actyx.
* @alpha
*/
export declare type FixedStart = {
from: OffsetMap;
latestEventKey: EventKey;
horizon?: EventKey;
};
declare const GlobalInternalSymbol: unique symbol;
declare type GlobalInternalSymbol = typeof GlobalInternalSymbol;
declare namespace globals {
export {
activeRequests
}
}
export { globals }
/** Anything with offset on a stream.
* @public */
export declare type HasOffsetAndStream = {
offset: number;
stream: string;
};
/** Anything that has tags. @alpha */
export declare type HasTags = {
tags: string[];
};
/** The signature of the function to invalidate all stored snapshots.
* @beta */
export declare type InvalidateAllSnapshots = () => Promise<void>;
/** The signature of the function to invalidate snapshots for a given fish.
* @beta */
export declare type InvalidateSnapshots = (semantics: string, name: string, key: EventKey) => Promise<void>;
/**
* Refinement that checks whether typeof x === 'number'
* @public
*/
export declare const isBoolean: (x: any) => x is boolean;
/**
* Refinement that checks whether typeof x === 'number'
* @public
*/
export declare const isNumber: (x: any) => x is number;
/**
* Refinement that checks whether typeof x === 'string'
* @public
*/
export declare const isString: (x: any) => x is string;
/**
* Lamport timestamp, cf. https://en.wikipedia.org/wiki/Lamport_timestamp
* @public
*/
export declare type Lamport = number;
/** @public */
export declare const Lamport: {
of: (value: number) => Lamport;
zero: number;
};
/** Query for observeLatest.
* @beta */
export declare type LatestQuery<E> = EarliestQuery<E>;
/** A local snapshot of state.
* @beta */
export declare type LocalSnapshot<S> = StateWithProvenance<S> & {
/**
* eventKey of the last event according to event order that went into the state.
* This can be used to detect shattering of the state due to time travel.
*/
eventKey: EventKey;
/**
* Oldest event key we are interested in. This is defined for a local snapshot
* that is based on a semantic snapshot. All events before the semantic snapshot
* that the local snapshot is based on are not relevant and can be discarded.
*
* Not discarding these events will lead to unnecessary shattering.
*/
horizon: EventKey | undefined;
/**
* Number of events since the beginning of time or the last semantic snapshot (which is
* kind of the same thing as far as the fish is concerned). This can be used as a measure
* how useful the snapshot is, and also for count-based snapshot scheduling
*/
cycle: number;
};
/** The format of snapshots coming back from the store.
* @beta */
export declare type LocalSnapshotFromIndex = LocalSnapshot<string>;
/** Generic Metadata attached to every event.
* @public */
export declare type Metadata = {
isLocalEvent: boolean;
tags: string[];
timestampMicros: Timestamp;
timestampAsDate: () => Date;
lamport: Lamport;
eventId: string;
appId: AppId;
stream: StreamId;
offset: Offset;
};
/** Some number of milliseconds.
* @public */
export declare type Milliseconds = number;
/** Helper functions for making sense of and converting Milliseconds.
* @public */
export declare const Milliseconds: {
of: (time: number) => Milliseconds;
fromDate: (date: Date) => Milliseconds;
zero: number;
now: (now?: number | undefined) => Milliseconds;
toSeconds: (value: Milliseconds) => number;
toTimestamp: (value: Milliseconds) => Timestamp;
fromSeconds: (value: number) => number;
fromMinutes: (value: number) => number;
fromAny: (value: number) => Milliseconds;
};
/**
* Subscribe to a stream of events that will never go backwards in time, but rather terminate with a timetravel-message.
*
* @alpha
*/
export declare type MonotonicSubscription<E> = {
/** User-chosen session id, used to find cached intermediate states aka local snapshots. */
sessionId: string;
/** Statement to select specific events. */
query: Where<E>;
/** Sending 'attemptStartFrom' means we DONT want a snapshot sent as initial message. */
attemptStartFrom: FixedStart;
};
/** Possible subscribe_monotonic message types.
* @alpha */
export declare enum MsgType {
state = "state",
events = "events",
timetravel = "timetravel"
}
/**
* An Actyx source id.
* @public
*/
export declare type NodeId = string;
/**
* `SourceId` associated functions.
* @public
*/
export declare const NodeId: {
/**
* Creates a NodeId from a string
*/
of: (text: string) => NodeId;
/**
* Creates a random SourceId with the given number of digits
*/
random: (digits?: number | undefined) => string;
streamNo: (nodeId: NodeId, num: number) => string;
};
/**
* Information about the Actyx node this SDK is connected to.
*
* Instances are returned by `Pond.nodeInfo()`.
* @public
*/
export declare class NodeInfo {
private io;
private semver;
constructor(io: NodeInfo_2);
/**
*
* @returns the full version string including git hash and CPU architecture
*/
longVersion(): string;
/**
*
* @returns the semantic version part of the full version string, e.g. `2.6.1`
*/
semVer(): string;
/**
*
* @param version - The version to compare with, in semantic version format `<major>.<minor>.<patch>`
* @returns `true` if the reported Actyx version is greater than or equal to the supplied version
*/
isAtLeastVersion(version: string): boolean;
/**
*
* @returns the uptime of the Actyx node in milliseconds
*/
uptimeMillis(): number;
/**
*
* @returns the number of other nodes the Actyx node is currently connected to
*/
connectedNodes(): number;
/**
*
* @returns information about the perceived connectivity of other nodes
*/
peersStatus(): Record<string, NodeStatus> | undefined;
}
declare const NodeInfo_2: t.TypeC<{
connectedNodes: t.NumberC;
uptime: t.TypeC<{
secs: t.NumberC;
nanos: t.NumberC;
}>;
version: t.StringC;
swarmState: t.UnionC<[t.UndefinedC, t.TypeC<{
peersStatus: t.RecordC<t.Type<string, string, unknown>, EnumType<NodeStatus>>;
}>]>;
}>;
declare type NodeInfo_2 = t.TypeOf<typeof NodeInfo_2>;
/**
* Status of another node as observed by the local node
* @public
*/
export declare enum NodeStatus {
/**
* Replicates all streams within at most two gossip cycles
*/
LowLatency = "LowLatency",
/**
* Replicates all streams within at most five gossip cycles
*/
HighLatency = "HighLatency",
/**
* Replicates at least half of all streams within five gossip cycles
*/
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.
*/
NotWorking = "NotWorking"
}
/** Offset within an Actyx event stream.
* @public */
export declare type Offset = number;
/** Functions related to Offsets.
* @public */
export declare const Offset: {
of: (n: number) => Offset;
zero: number;
/**
* A value that is below any valid Offset
*/
min: number;
/**
* A value that is above any valid Offset
*/
max: number;
};
/**
* A offset map stores the high water mark for each source.
*
* The value in the psn map is the highest psn seen for this source. Since sequence
* numbers start with 0, the default value for sources that are not present is -1
*
* @public
*/
export declare type OffsetMap = Record<StreamId, Offset>;
/** OffsetMap companion functions.
* @public */
export declare const OffsetMap: OffsetMapCompanion;
/**
* Relatively pointless attempt to distinguish between mutable and immutable psnmap
* See https://github.com/Microsoft/TypeScript/issues/13347 for why this does not help much.
* @public
*/
export declare type OffsetMapBuilder = Record<string, Offset>;
/** OffsetMap companion functions.
* @public */
export declare type OffsetMapCompanion = {
empty: OffsetMap;
isEmpty: (m: OffsetMap) => boolean;
lookup: (m: OffsetMap, s: string) => Offset;
lookupOrUndefined: (m: OffsetMap, s: string) => Offset | undefined;
update: (m: OffsetMapBuilder, ev: HasOffsetAndStream) => OffsetMapBuilder;
};
/**
* Response to an offsets() call
* @public
*/
export declare type OffsetsResponse = {
/** The current local present, i.e. offsets up to which we can provide events without any gaps. */
present: OffsetMap;
/** For each stream we still need to download events from, the number of pending events. */
toReplicate: Record<StreamId, number>;
};
/**
* Handler for a streaming operation ending, either normally or with an error.
* If the `err` argument is defined, the operation completed due to an error.
* Otherwise, it completed normally.
* @public
**/
export declare type OnCompleteOrErr = (err?: unknown) => void;
/**
* Allows you to register actions for when event emission has completed.
* @public
*/
export declare type PendingEmission = {
subscribe: (whenEmitted: (meta: Metadata[]) => void) => void;
toPromise: () => Promise<Metadata[]>;
};
/** Query for a fixed set of known events.
* @public */
export declare type RangeQuery = {
/** Statement to select specific events. Defaults to `allEvents`. */
query?: Where<unknown>;
/**
* Starting point (exclusive) for the query. Everything up-to-and-including `lowerBound` will be omitted from the result. Defaults empty record.
*
* Events from sources not included in the `lowerBound` will be delivered from start, IF they are included in `upperBound`.
* Events from sources missing from both `lowerBound` and `upperBound` will not be delivered at all.
*/
lowerBound?: OffsetMap;
/**
* Ending point (inclusive) for the query. Everything covered by `upperBound` (inclusive) will be part of the result.
*
* If a source is not included in `upperBound`, its events will not be included in the result.
**/
upperBound: OffsetMap;
/** Desired order of delivery. Defaults to 'Asc' */
order?: EventsSortOrder;
/** Earliest event ID to consider in the result */
horizon?: string;
};
/** The signature of the function to retrieve a snapshot.
* @beta */
export declare type RetrieveSnapshot = (semantics: string, name: string, version: number) => Promise<LocalSnapshotFromIndex | undefined>;
/** A local snapshot where the state has already been serialised.
* @beta */
export declare type SerializedStateSnap = LocalSnapshot<string>;
/**
* Interface to the snapshot store.
* @beta
*/
export declare interface SnapshotStore {
/**
* Store local snapshot (best effort)
*
* @param version - For each semantics, the store is partitioned into versions corresponding to the snapshot format.
* Only the newest known version should be kept.
*
* @param key - is the EventKey of the event from which the snapshot state was computed.
*
* @param tag - is a unique identifier for a given semantics, name, and version; it is used to ensure that only
* one snapshot is kept for the a given interval (hour, day, month, year)
*
* @param psnMap - is needed to recognize whether the given snapshot has already been invalidated by the
* root updates that have been performed between the one that triggered the snapshot computation and now
*
* @returns success if the snapshot was accepted, false if it was rejected due to using an old format
*
* A snapshot is out of date if between the event state it represents (as demonstrated by the given psnMap)
* and the current index store state there have been root updates that would have invalidated the snapshot.
*
* Snapshots will not be validated against events on storage. The only validation that might happen is that
* the format version is the latest.
*/
storeSnapshot: StoreSnapshot;
/**
* Retrieve local snapshot and its EventKey if it exists; undefined otherwise.
* The method also returns the PsnMap from which the snapshot was calculated.
*
* Most of the time, snapshots returned by this method will be valid, meaning that all stored events with
* larger psns than the snapshot also have larger event keys that the snapshot.
*
* However, this is not guaranteed. In very rare circumstances it is possible that there are stored events with
* a psn above the snapshot psnMap, but an eventKey below the snapshot eventKey. In these cases, the snapshot
* needs to be discarded, exactly as if there was a realtime event coming in with a smaller eventKey than
* the snapshot.
*
* To be precise, invalid snapshots will happen only if the application crashes between the time events are added
* at the store level (e.g. to the recvlog) and the time the events appear in the fishjar, triggering explicit
* invalidation. This should be very rare, but still needs to be handled properly.
*/
retrieveSnapshot: RetrieveSnapshot;
/**
* Invalidate all snapshots for the fish identified by semantics and name that are at or above the given event key.
*
* @param semantics - semantics of the fish to invalidate snapshots for
* @param name - name of the fish to invalidate snapshots for
* @param eventKey - eventKey at or above which to purge snapshots
* @returns a void promise that will complete once the snapshot invalidation is done in the persistence layer.
*/
invalidateSnapshots: InvalidateSnapshots;
/**
* Invalidate all snapshots
*
* @returns a void promise that will complete once the snapshot invalidation is done in the persistence layer.
*/
invalidateAllSnapshots: InvalidateAllSnapshots;
}
/** Interface to the snapshot store.
* @beta */
export declare const SnapshotStore: {
noop: SnapshotStore;
inMem: () => SnapshotStore;
};
/** Implies consumer should apply the given state.
* @alpha */
export declare type StateMsg = {
type: MsgType.state;
snapshot: SerializedStateSnap;
};
/**
* A state and its corresponding psn map.
* @beta
*/
export declare type StateWithProvenance<S> = {
readonly state: S;
/**
* Minimum psn map that allow to reconstruct the state.
* Only contains sources that contain events matching the filter.
*/
readonly offsets: OffsetMap;
};
/** The signature of the function to store a snapshot.
* @beta */
export declare type StoreSnapshot = (semantics: string, name: string, key: EventKey, offsets: OffsetMap, horizon: EventKey | undefined, cycle: number, version: number, tag: string, serializedBlob: string) => Promise<boolean>;
/**
* An Actyx stream id.
* @public
*/
export declare type StreamId = string;
/**
* `SourceId` associated functions.
* @public
*/
export declare const StreamId: {
/**
* Creates a StreamId from a string
*/
of: (text: string) => StreamId;
/**
* Creates a random StreamId off a random NodeId.
*/
random: () => string;
};
/**
* Representation of a single tag.
* @public
*/
export declare interface Tag<E = unknown> extends Tags<E> {
/**
* Returns two tags:
*
* - this tag
* - this tag suffixed with the given `name`, e.g. `Tag<RobotEvent>('robot').withId('robot500')`
* expresses robot events belonging to a *specific* robot. The suffix will be separated
* from the base name by a colon `:` like `robot:robot500`.
*
* The reason for preserving the base tag is to keep a notion of the whole event group,
* and enable selection of it all without knowing every individual specific ID.
*/
withId(name: string): Tags<E>;
/**
* Returns the ID-specific variant of this particular tag, see also `withId`.
*
* Use this if you want to tag an event belonging to entity A with a specific identity of entity B.
* For example an activity has been started by some user, so you may add
* `activityTag.withId(activityId).and(userTag.id(userId))`; this would result in three tags.
*
* This returns a tag for arbitrary events (type `unknown`) because the base tag is omitted.
*/
id(name: string): Tags<unknown>;
}
/**
* Create a new tag from the given string.
* (Tag factory function. Call WITHOUT new, e.g. `const myTag = Tag<MyType>('my-tag')`)
*
* @param rawTagString - The raw tag string
* @param extractId - If supplied, this function will be used to automatically call `withId` for events this tag is being attached to.
* The automatism is disabled if there is a manual `withId` call.
* @public
*/
export declare const Tag: <E = unknown>(rawTagString: string, extractId?: ((e: E) => string) | undefined) => Tag<E>;
/** An event with tags attached.
* @public */
export declare type TaggedEvent = {
tags: string[];
event: unknown;
};
/** A typed event with tags attached.
* @public */
export declare interface TaggedTypedEvent<E = unknown> extends TaggedEvent {
readonly tags: string[];
readonly event: E;
withTags<E1>(tags: Tags<E1> & (E extends E1 ? unknown : never)): TaggedTypedEvent<E>;
}
/**
* Selection of events based on required tags. `Tags('a', 'b')` will select all events that have tag 'a' *as well as* tag 'b'.
* @public
*/
export declare interface Tags<E = unknown> extends Where<E> {
/**
* Add more tags to this requirement. E.g `Tag<FooEvent>('foo').and(Tag<BarEvent>('bar'))` will require both 'foo' and 'bar'.
*/
and<E1 = unknown>(tag: Tags<E1>): Tags<E1 & E>;
/**
* Add an additional untyped tag to this requirement.
* Since there is no associated type, the overall type cannot be constrained further.
*/
and(tag: string): Tags<E>;
/**
* The same requirement, but matching only Events emitted by the very node the code is run on.
* E.g. `Tags('my-tag').local()` selects all locally emitted events tagged with 'my-tag'.
*/
local(): Tags<E>;
/**
* Apply these tags to an event that they may legally be attached to (according to the tag's type `E`).
*/
apply(event: E): TaggedEvent;
/**
* Apply these tags to a list of events that they may legally be attached to.
*/
apply(...events: E[]): TaggedEvent[];
/**
* Apply these tags to a list of events that match their type, and allow further tags to be added.
*/
applyTyped<E1 extends E>(event: E1): TaggedTypedEvent<E1>;
}
/**
* Declare a set of tags.
* This is a generator function to be called WITHOUT new, e.g. `const required = Tags('a', 'b', 'c')`
* @public
*/
export declare const Tags: <E = unknown>(...requiredTags: string[]) => Tags<E>;
/**
* An instance of `Actyx` that is not talking to any Actyx instance, but mocks all functionality within TypeScript.
* Very useful for unit-testing.
*
* @public
*/
export declare type TestActyx = TestEventFns & {
/** Prented id of the underlying Actyx instance that actually is just simulated. */
readonly nodeId: NodeId;
/** Fish snapshot store for the Pond
* @beta */
readonly snapshotStore: SnapshotStore;
/** For `TestActyx` instances, this method does nothing; it’s just there so all normal `Actyx` functions are provided.
* @public */
dispose: () => void;
waitForSync: () => Promise<void>;
};
/**
* A raw Actyx event to be emitted by the TestEventStore, as if it really arrived from the outside.
* @public
*/
export declare type TestEvent = {
offset: number;
stream: string;
timestamp: Timestamp;
lamport: Lamport;
tags: string[];
payload: unknown;
};
/** EventFns for unit-tests.
* @public */
export declare type TestEventFns = EventFns & {
/** Inject an event as if it arrived from anywhere.
* @public */
directlyPushEvents: (events: TestEvent[]) => void;
};
/**
* Test tool.
* @beta
*/
export declare type TimeInjector = (tags: string[], events: unknown) => Timestamp;
/** Timestamp (UNIX epoch), MICROseconds resolution.
* @public */
export declare type Timestamp = number;
/** Helper functions for making sense of and converting Timestamps.
* @public */
export declare const Timestamp: {
of: (time: number) => Timestamp;
zero: number;
maxSafe: number;
now: (now?: number | undefined) => number;
format: (timestamp: Timestamp) => string;
toSeconds: (value: Timestamp) => number;
toMilliseconds: (value: Timestamp) => Milliseconds;
toDate: (value: Timestamp) => Date;
fromDate: (date: Date) => Timestamp;
fromDays: (value: number) => number;
fromSeconds: (value: number) => number;
fromMilliseconds: (value: number) => number;
min: (...values: Timestamp[]) => number;
max: (values: Timestamp[]) => number;
};
/** Implies consumer should re-subscribe starting from `trigger` or earlier.
* @alpha */
export declare type TimeTravelMsg<E> = {
type: MsgType.timetravel;
trigger: EventKey;
};
/**
* Turn a `Where` into a function that can decide whether a locally emitted event matches the clause.
*
* We can ignore the 'local' flag since it will never exclude our local events,
* and this method is used solely to decide whether locally emitted events are relevant.
*
* TODO: This will be removed once we support other means of 'I got events up to X' feedback
*
* @alpha
*/
export declare const toEventPredicate: (where: Where<unknown>) => (event: HasTags) => boolean;
/**
* Representation of a union of tag sets. I.e. this is an event selection that combines multiple `Tags` selections.
* @public
*/
export declare interface Where<E> {
/**
* Add an alternative set we may also match. E.g. tag0.or(tag1.and(tag2)).or(tag1.and(tag3)) will match:
* Events with tag0; Events with both tag1 and tag2; Events with both tag1 and tag3.
*/
or<E1>(tag: Where<E1>): Where<E1 | E>;
/**
* Type of the Events which may be returned by the contained tags.
* Note that this does reflect only locally declared type knowledge;
* historic events delivered by the Actyx system may not match these types, and this is not automatically detected.
* It is therefore good practice to carefully review changes to the declared type so that they remain
* backwards compatible.
*/
readonly _dataType?: E;
/**
* Convert to an Actyx Event Service query string.
*/
toString(): string;
}
export { }