@yantrix/automata
Version:
Yantrix framework core: reference Typescript implementation of finite state machine
1,063 lines (1,058 loc) • 83.4 kB
TypeScript
type TStateDictionaryMapping<StateType extends TAutomataBaseStateType> = Record<string, StateType>;
type TActionDictionaryMapping<ActionType extends TAutomataBaseActionType> = Record<string, ActionType>;
type TEventDictionaryMapping<EventType extends TAutomataBaseEventType> = Record<string, EventType>;
type TStateKeysCollection<StateType extends TAutomataBaseStateType> = {
keys: string[];
namespace?: string;
states?: StateType[];
};
type TStateValuesCollection<StateType extends TAutomataBaseStateType> = {
states: StateType[];
namespace?: string;
};
type TStateLookupParams<StateType extends TAutomataBaseStateType> = TStateKeysCollection<StateType> & TStateValuesCollection<StateType>;
type TActionKeysCollection<ActionType extends TAutomataBaseActionType> = {
keys: Array<null | string>;
namespace?: string;
actions?: ActionType[];
};
type TActionValuesCollection<ActionType extends TAutomataBaseActionType> = {
actions: ActionType[];
namespace?: string;
};
type TActionLookupParams<ActionType extends TAutomataBaseActionType> = Partial<TActionKeysCollection<ActionType> & TActionValuesCollection<ActionType>>;
type TEventKeysCollection<EventType extends TAutomataBaseEventType> = {
keys: Array<null | string>;
namespace?: string;
events?: EventType[];
};
type TEventValuesCollection<EventType extends TAutomataBaseEventType> = {
events: EventType[];
namespace?: string;
};
type TEventLookupParams<EventType extends TAutomataBaseEventType> = Partial<TEventKeysCollection<EventType> & TEventValuesCollection<EventType>>;
/**
* Interface for an Automata event container.
* @template EventType - The type of the event.
*/
interface IAutomataEventContainer<EventType extends TAutomataBaseEventType> {
/**
* Validator function for the event.
*/
validateEvent: TValidator<EventType>;
/**
* Sets the event validator function.
* @param eventValidator - The validator function for the event.
* @returns The current instance.
*/
setEventValidator: (eventValidator?: TValidator<EventType>) => this;
}
/**
* Interface for an Automata state container.
* @template StateType - The type of the state.
*/
interface IAutomataStateContainer<StateType extends TAutomataBaseStateType> {
/**
* Validator function for the state.
*/
validateState: TValidator<StateType>;
/**
* Sets the state validator function.
* @param stateValidator - The validator function for the state.
* @returns The current instance.
*/
setStateValidator: (stateValidator?: TValidator<StateType>) => this;
}
/**
* Interface for an Automata action container.
* @template ActionType - The type of the action.
*/
interface IAutomataActionContainer<ActionType extends TAutomataBaseActionType> {
/**
* Validator function for the action.
*/
validateAction: TValidator<ActionType>;
/**
* Sets the action validator function.
* @param actionValidator - The validator function for the action.
* @returns The current instance.
*/
setActionValidator: (actionValidator?: TValidator<ActionType> | null) => this;
}
/**
* Interface for an Automata validator container.
* @template StateType - The type of the state.
* @template ActionType - The type of the action.
* @template EventType - The type of the event.
*/
interface IAutomataValidatorContainer<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, EventType extends TAutomataBaseEventType> extends IAutomataEventContainer<EventType>, IAutomataStateContainer<StateType>, IAutomataActionContainer<ActionType> {
}
/**
* Interface for an Automata extended action container.
* @template ActionType - The type of the action.
* @template PayloadType - The type of the payload.
*/
interface IAutomataExtendedActionContainer<ActionType extends TAutomataBaseActionType, PayloadType extends {
[K in ActionType]: any;
}> extends IAutomataActionContainer<ActionType> {
validateActionPayload: TValidator<TAutomataActionPayload<ActionType, PayloadType>>;
setActionPayloadValidator: (actionPayloadValidator?: TValidator<TAutomataActionPayload<ActionType, PayloadType>>) => this;
}
/**
* Interface for an Automata extended event container.
* @template EventType - The type of the event.
* @template EventMetaType - The type of the event metadata.
*/
interface IAutomataExtendedStateContainer<StateType extends TAutomataBaseStateType, ContextType extends {
[K in StateType]: any;
}> extends IAutomataStateContainer<StateType> {
validateContext: TValidator<TAutomataStateContext<StateType, ContextType>>;
setContextValidator: (contextValidator?: TValidator<TAutomataStateContext<StateType, ContextType>>) => this;
}
/**
* Interface for an Automata extended event container.
* @template EventType - The type of the event.
* @template EventMetaType - The type of the event metadata.
*/
interface IAutomataExtendedEventContainer<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
}> extends IAutomataEventContainer<EventType> {
validateEventMeta: TValidator<TAutomataEventMetaType<EventType, EventMetaType>>;
setEventMetaValidator: (eventMetaValidator?: TValidator<TAutomataEventMetaType<EventType, EventMetaType>>) => this;
}
/**
* Interface for an Automata extended validator container.
* @template StateType - The type of the state.
* @template ActionType - The type of the action.
* @template EventType - The type of the event.
* @template ContextType - The type of the context.
* @template PayloadType - The type of the payload.
* @template EventMetaType - The type of the event metadata.
*/
interface IAutomataExtendedValidatorContainer<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, EventType extends TAutomataBaseEventType, ContextType extends {
[K in StateType]: any;
}, PayloadType extends {
[K in ActionType]: any;
}, EventMetaType extends {
[K in EventType]: any;
}> extends IAutomataValidatorContainer<StateType, ActionType, EventType>, IAutomataExtendedActionContainer<ActionType, PayloadType>, IAutomataExtendedEventContainer<EventType, EventMetaType>, IAutomataExtendedStateContainer<StateType, ContextType> {
}
/**
* Interface for an Automata event adapter.
* @template StateType - The type of the state.
* @template ActionType - The type of the action.
* @template EventType - The type of the event.
* @template ContextType - The type of the context.
* @template PayloadType - The type of the payload.
* @template EventMetaType - The type of the event metadata.
*/
interface IAutomataEventAdapter<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, EventType extends TAutomataBaseEventType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> extends IAutomataValidatorContainer<StateType, ActionType, EventType> {
/**
* Adds an event listener for the specified event type.
* @param type - The type of the event.
* @param handler - The event handler function.
* @returns A cancel function to remove the event listener, or null if the event type is invalid.
*/
addEventListener: <T extends EventType>(type: T, handler: TAutomataEventHandler<T, ActionType, EventMetaType, PayloadType>) => null | TSubscriptionCancelFunction;
/**
* Adds an event emitter for the specified state type.
* @param on - The state type to listen for.
* @param emitter - The event emitter function.
* @returns A cancel function to remove the event emitter, or null if the state type is invalid.
*/
addEventEmitter: <T extends StateType>(on: T, emitter: TAutomataEventEmitter<EventType, T, EventMetaType, ContextType>) => null | TSubscriptionCancelFunction;
/**
* Handles the specified event and returns the results of the event handlers.
* @param event - The event to handle.
* @returns An array of the results of the event handlers.
*/
handleEvent: <T extends EventType>(event: TAutomataEventMetaType<T, EventMetaType>) => Array<ReturnType<TAutomataEventHandler<T, ActionType, EventMetaType, PayloadType>>>;
/**
* Handles the transition to the specified new state and returns the results of the event emitters.
* @param newState - The new state to transition to.
* @returns An array of the results of the event emitters.
*/
handleTransition: <T extends StateType>(newState: TAutomataStateContext<T, ContextType>) => Array<ReturnType<TAutomataEventEmitter<EventType, T, EventMetaType, ContextType>>>;
/**
* Removes all event listeners for the specified event type.
* @param type - The type of the event, or null to remove all event listeners.
* @returns The event adapter instance.
*/
removeAllListeners: <T extends EventType>(type: T | null) => this;
/**
* Removes all event emitters for the specified state type.
* @param type - The type of the state, or null to remove all event emitters.
* @returns The event adapter instance.
*/
removeAllEmitters: <T extends StateType>(type: T | null) => this;
/**
* Returns an array of the observed event types.
* @returns An array of the observed event types.
*/
getObservedEvents: () => EventType[];
/**
* Returns an array of the observed state types.
* @returns An array of the observed state types.
*/
getObservedStates: () => StateType[];
}
/**
* Interface for Automata, a state machine.
* @template StateType - The type of the state.
* @template ActionType - The type of the action.
* @template EventType - The type of the event.
* @template ContextType - The type of the context.
* @template PayloadType - The type of the payload.
* @template EventMetaType - The type of the event metadata.
*/
interface IAutomata<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, EventType extends TAutomataBaseEventType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> extends TAutomataStateContext<StateType, ContextType>, IAutomataValidatorContainer<StateType, ActionType, EventType> {
eventAdapter: IAutomataEventAdapter<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType> | null;
/**
* Reset the Instance and provide a Reducer, new State and optionally Validators
*/
init: (params: TAutomataParams<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType>) => this;
/**
* Return current Reducer function
*/
getReducer: () => TAutomataReducer<StateType, ActionType, ContextType, PayloadType> | null;
/**
* When the Instance is Disabled, Consuming Actions doesn't change the internal state
*/
enable: () => this;
disable: (clearQueue?: boolean) => this;
isEnabled: () => boolean;
/**
* When the Instance is Paused, dispatched Actions aren't Consumed, but put into the Queue instead
*/
isPaused: () => boolean;
/**
* Pause the automata.
* @returns The updated automata instance.
*/
pause: () => this;
/**
* Resuming will Collapse the Queue, unless the Instance is Disabled
*/
resume: () => this;
/**
* Returns internal State and Context of the Instance
*/
getContext: <K extends StateType = StateType>() => TAutomataStateContext<K, ContextType>;
/**
* Consume all Actions in the Queue and return the resulting State
* Works even when Paused
* When Disabled, consumed Actions don't change the internal State
* Returns the final result of all consumed Actions
*/
collapseActionQueue: () => {
actions: TAutomataQueue<ActionType, PayloadType> | null;
newState: TAutomataStateContext<StateType, ContextType>;
};
getActionQueue: () => TAutomataQueue<ActionType, PayloadType>;
clearActionQueue: () => this;
/**
* Pop at most [count] Actions from the Queue and Consume them
* Works even when Paused
* When Disabled, consumed Actions don't change the internal State
* Returns the final result of all consumed Actions
* @param count Number of Actions to consume, defaults to 1
*/
consumeAction: (count: number) => {
action: TAutomataActionPayload<ActionType, PayloadType> | null;
newState: TAutomataStateContext<StateType, ContextType>;
};
/**
* Consume Action and return the new State and its context.
* The Queue is Collapsed beforehand, if not Disabled
* When Paused, puts an Action into the Queue instead
* When Disabled, doesn't change the internal State
* Returns the final result of all Actions, including the Queue
*/
dispatch: TAutomataDispatch<StateType, ActionType, ContextType, PayloadType>;
}
/**
* Interface for a dictionary of states.
* @template StateType - The type of state.
* @template ContextType - The type of context.
*/
interface IStateDictionary<StateType extends TAutomataBaseStateType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>> extends IAutomataExtendedStateContainer<StateType, ContextType> {
/**
* Get Keys for selected States, possibly scoped to namespace
* @param {states:StateType[],namespace?:string} states
* @return {string[]}
*/
getStateKeys: (states: TStateValuesCollection<StateType>) => Array<string | null>;
/**
* Get all States for selected Keys, possibly scoped to namespace
* @param {keys:string[],namespace?:string} states
* @return {string[]}
*/
getStateValues: (states: TStateKeysCollection<StateType>) => Array<StateType | null>;
/**
* add new string States to the Dictionary, possibly within namespace
* @param {states:string[],namespace?:string} states
* @return new States' values
*/
addStates: (params: TStateKeysCollection<StateType>) => StateType[];
/**
* remove States from the Dictionary, possibly scoping them to namespace.
* @param {TStateLookupParams<StateType>} Search states: Namespace and States or Keys to remove
* @param {boolean} removeContextTransformers if true, also remove Context Transformers for removed States
* @return {this}
*/
removeStates: (params: TStateLookupParams<StateType>, removeContextTransformers?: boolean) => this;
/**
* remove all States from the Dictionary, possibly scoping them to namespace.
* @return {this}
*/
clearStates: (namespace?: string) => this;
/**
* Get all mapped State Types with their corresponding Keys, possibly filtered by Namespace
* @return {TStateDictionaryMapping<StateType>}
*/
getDictionary: (namespace?: string) => TStateDictionaryMapping<StateType>;
/**
* add a Context Transformer for a particular State, possibly scoped to namespace
* @param {TContextTransformer} transformer to add
* @param [string] namespace
* @returns {string} transformer ID
*/
addContextTransformer: <T extends StateType>(state: T, transformer: TContextTransformer<T, ContextType>, namespace?: string) => string;
/**
* remove a Context Transformer for a particular State, possibly scoped to namespace
* @param {T} state
* @param {TContextTransformer<T, ContextType>} transformer to remove
* @param {string} namespace
* @return {this}
*/
removeContextTransformer: <T extends StateType>(state: T, transformer: TContextTransformer<T, ContextType>, namespace?: string) => this;
/**
* remove a Context Transformer by ID
* @param {string} id
* @return {this}
*/
removeContextTransformerById: (id: string) => this;
/**
* Get all Context Transformers grouped by a particular State, possibly scoped to namespace
* @param {string} namespace
* @return {Partial<{[K in StateType]: Record<string, TContextTransformer<K, ContextType>>}>}
*/
getContextTransformers: (namespace?: string) => Partial<{
[K in StateType]: Record<string, TContextTransformer<K, ContextType>>;
}>;
/**
* Run all Context Transformers for a particular State, possibly scoped to namespace
* @param {string} Transformer ID
* @param {TAutomataStateContext<T, ContextType>} context
* @return {TAutomataStateContext<StateType, ContextType>}
*/
runContextTransformers: <T extends StateType>(id: string, context: TAutomataStateContext<T, ContextType>) => TAutomataStateContext<StateType, ContextType>;
}
/**
* Interface for a dictionary of actions.
* @template ActionType - The type of actions.
* @template PayloadType - The type of payloads for each action.
*/
interface IActionDictionary<ActionType extends TAutomataBaseActionType, PayloadType extends {
[K in ActionType]: any;
}> extends IAutomataExtendedActionContainer<ActionType, PayloadType> {
/**
* Add new Actions to the dictionary, possibly scope them to namespace
* @param {keys:string[],namespace?:string} actions
* @return {ActionType[]} a list of Keys for newly added Actions
*/
addActions: (actions: TActionKeysCollection<ActionType>) => ActionType[];
/**
* Get Keys of selected Actions, possibly scoped to namespace
* @param {actions:ActionType[],namespace?:string} actions
* @return {string[], null if not found}
*/
getActionKeys: (actions: TActionValuesCollection<ActionType>) => Array<string | null>;
/**
* Get all Actions for selected Keys, possibly scoped to namespace
* @param {keys:string[],namespace?:string} actions
* @return {Action[]}
*/
getActionValues: (actions: TActionKeysCollection<ActionType>) => Array<ActionType | null>;
/**
* remove Actions from the Dictionary, possibly scoping them to namespace.
* @param {TActionLookupParams<ActionType>} Search actions: Namespace and Actions or Keys to remove
* @return {this}
*/
removeActions: (actions: TActionLookupParams<ActionType>) => this;
/**
* remove all Actions from the Dictionary, possibly scoping them to namespace.
* @param {string} namespace
* @return {this}
*/
clearActions: (namespace?: string) => this;
/**
* Get all mapped Action Types with their corresponding Keys, possibly filtered by Namespace
* @param {string} namespace
* @return {[string]:Action}
*/
getDictionary: (namespace?: string) => TActionDictionaryMapping<ActionType>;
}
/**
* Interface for a dictionary of events.
* @template EventType - The type of events.
* @template EventMetaType - The type of event metadata.
*/
interface IEventDictionary<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
}> extends IAutomataExtendedEventContainer<EventType, EventMetaType> {
/**
* Add new Events to the dictionary, possibly scope them to namespace
* @param {keys:string[],namespace?:string} actions
* @return {EventType[]} a list of Keys for newly added Events
*/
addEvents: (Events: TEventKeysCollection<EventType>) => EventType[];
/**
* Get Keys of selected Events, possibly scoped to namespace
* @param {Events:EventType[],namespace?:string} Events
* @return {string[], null if not found}
*/
getEventKeys: (Events: TEventValuesCollection<EventType>) => Array<string | null>;
/**
* Get all Events for selected Keys, possibly scoped to namespace
* @param {keys:string[],namespace?:string} Events
* @return {Event[]}
*/
getEventValues: (Events: TEventKeysCollection<EventType>) => Array<EventType | null>;
/**
* remove Events from the Dictionary, possibly scoping them to namespace.
* @param {TEventLookupParams<EventType>} Search Events: Namespace and Events or Keys to remove
* @return {this}
*/
removeEvents: (Events: TEventLookupParams<EventType>) => this;
/**
* remove all Events from the Dictionary, possibly scoping them to namespace.
* @param {string} namespace
* @return {this}
*/
clearEvents: (namespace?: string) => this;
/**
* Get all mapped Event Types with their corresponding Keys, possibly filtered by Namespace
* @param {string} namespace
* @return {[string]:Event}
*/
getDictionary: (namespace?: string) => TEventDictionaryMapping<EventType>;
}
/**
* Interface representing a slice of an automata.
* @template EventType - The type of events.
* @template EventMetaType - The type of event metadata.
* @template ModelType - The type of the model.
*/
interface IAutomataSlice<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>, ModelType extends object = Record<string, any>> extends IAutomataEventContainer<EventType> {
/**
* A record of machines, where each machine is an instance of `IAutomata`.
*/
getMachines: Record<string, IAutomata<any, any, EventType>>;
/**
* Adds a machine to the automata slice.
* @param machineId - The ID of the machine.
* @param automata - The instance of `IAutomata` to add.
* @returns The current instance of `IAutomataSlice`.
*/
addMachine: <StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>>(machineId: string, automata: IAutomata<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType>) => this;
/**
* Removes a machine from the automata slice.
* @param machineId - The ID of the machine to remove.
* @returns The current instance of `IAutomataSlice`.
*/
removeMachine: (machineId: string) => this;
/**
* A record of composite states, where each composite state is an instance of `TAutomataStateContext`.
*/
getCompositeState: Record<string, TAutomataStateContext<any, any>>;
/**
* Restores a state for a specific machine.
* @param machineId - The ID of the machine.
* @param state - The state object to restore.
* @returns The current instance of `IAutomataSlice`.
*/
restoreState: <StateType extends TAutomataBaseStateType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>>(machineId: string, state: TAutomataStateContext<StateType, ContextType>) => this;
/**
* Restores composite states for all machines.
* @param compositeState - The record of composite states to restore.
* @returns The current instance of `IAutomataSlice`.
*/
restoreCompositeState: (compositeState: Record<string, TAutomataStateContext<any, any>>) => this;
/**
* Returns the event matrix, which is a record of events and their corresponding effects.
* @returns The event matrix.
*/
getEventMatrix: () => Record<EventType, Array<TAutomataEffect<ModelType, EventType>>>;
/**
* Dispatches an event and triggers its effects.
* @param event - The event object to dispatch.
* @returns The current instance of `IAutomataSlice`.
*/
dispatchEvent: (event: TAutomataEventMetaType<EventType, EventMetaType>) => this;
/**
* Starts the automata slice.
* @returns The current instance of `IAutomataSlice`.
*/
start: () => this;
/**
* Stops the automata slice.
* @param clearStack - Indicates whether to clear the event stack.
* @returns The current instance of `IAutomataSlice`.
*/
stop: (clearStack: boolean) => this;
/**
* Checks if the automata slice is running.
* @returns `true` if the automata slice is running, `false` otherwise.
*/
isRunning: () => boolean;
/**
* Returns the event stack.
* @returns The event stack.
*/
getEventStack: () => TAutomataEventStack<EventType, EventMetaType>;
/**
* Clears the event stack.
* @returns The current instance of `IAutomataSlice`.
*/
clearEventStack: () => this;
/**
* Consumes the event stack and returns the events and their effects.
* @returns An object containing the events and their effects.
*/
consumeEvent: () => {
events: TAutomataEventStack<EventType, EventMetaType>;
effects: Array<TAutomataEffect<ModelType, EventType>>;
};
/**
* Returns the effects associated with a specific event.
* @param event - The event for which to retrieve the effects.
* @returns The effects associated with the event.
*/
getEventEffects: (event: EventType) => Array<TAutomataEffect<ModelType, EventType>>;
}
/**
* Interface for an event bus that supports subscribing and dispatching events.
* @template EventType The type of events that can be dispatched.
* @template EventMetaType The type of metadata associated with each event.
*/
interface IAutomataEventBus<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> extends IAutomataExtendedEventContainer<EventType, EventMetaType> {
/**
* Subscribe n to an event.
* @param event The event to subscribe to.
* @param callback The callback function to call when the event is dispatched.
* @returns This event bus instance.
*/
subscribe: (event: EventType, callback: TEventBusHandler<EventType, EventMetaType>) => this;
/**
* Unsubscribe from an event.
* @param event The event to unsubscribe from.
* @param callback The callback function to unsubscribe.
* @returns This event bus instance.
*/
unsubscribe: (event: EventType, callback: null | TEventBusHandler<EventType, EventMetaType>) => this;
/**
* Dispatch one or more events.
* @param events The events to dispatch.
* @returns This event bus instance.
*/
dispatch: (...events: TAutomataEventStack<EventType, EventMetaType>) => this;
/**
* Get the current event stack.
* @returns The current event stack.
*/
getEventStack: () => TAutomataEventStack<EventType, EventMetaType>;
/**
* Clear the event stack.
* @returns This event bus instance.
*/
clearEventStack: () => this;
/**
* Pause the event bus.
* @returns This event bus instance.
*/
pause: () => this;
/**
* Resume the event bus.
* @returns This event bus instance.
*/
resume: () => this;
/**
* Check if the event bus is running.
* @returns True if the event bus is running, false otherwise.
*/
isRunning: () => boolean;
/**
* Process the events in the event stack.
* @returns The processed event stack.
*/
processEvents: () => TAutomataEventStack<EventType, EventMetaType>;
}
/**
* Interface for any data structure capable of storing and returning automata functions.
*/
interface IAutomataFunctionRegistry {
/**
* Register function under a specific name in the registry.
*
* @param f - function to register, either as just a name(string) or a name-function record
* @param callback - function to invoke, required if the first argument is a string
*
* @throws Will throw an error if:
*
* 1). Name is not valid (valid name starts with a letter, has length 1-255 and does not contain any special symbols).
*
* 2). Name is already taken. Function cannot be registered under an already existing name to prevent overwriting of the basic built-in functions.
*/
register: (f: string | Record<string, TAutomataFunction>, callback?: TAutomataFunction) => Record<string, TAutomataFunction>;
/**
* Get function from registry.
*
* @param functionKey - name of the function
* @returns function to invoke
*
* @throws Will throw an error if the function is not found by the specified key.
*/
get: (functionKey: string) => TAutomataFunction;
/**
* Check if a function exists in the registry.
*
* @param functionKey - name of the function to check
* @returns true if the function exists, false otherwise
*/
has: (functionKey: string) => boolean;
/**
* Retrieve function from the registry and immediately call it, returning the result to the consumer.
*
* Should return an error if the arguments for a specific function are incorrect.
*
* @param functionKey - name of the function to call
* @param args - arguments necessary for the function
* @returns result of calling the function
*
* @throws Will throw an error if:
*
* 1). Function is not found by the specified key.
*
* 2). Arguments for the function are incorrect(as specified in their implementation).
*/
call: (functionKey: string, ...args: any[]) => unknown;
}
/**
* Represents the base state type for the automata.
*/
type TAutomataBaseStateType = number;
/**
* Represents the base action type for the automata.
*/
type TAutomataBaseActionType = number;
/**
* Represents the base event type for the automata.
*/
type TAutomataBaseEventType = number;
interface IBaseClass {
next?: () => this;
correlationId: string;
}
type TAbstractConstructor<T = object> = new (...args: any[]) => T;
type TAbstractFunction<T = any> = (...args: any[]) => T;
type TMixin<T extends TAbstractFunction> = InstanceType<ReturnType<T>>;
type TMergeClassTrait<TTrait extends TAbstractConstructor, TTarget extends TAbstractConstructor> = (new (...a: ConstructorParameters<TTarget>) => InstanceType<TTrait> & InstanceType<TTarget>) & Pick<TTarget, keyof TTarget> & Pick<TTrait, keyof TTrait>;
/**
* Container for automata state.
*/
type TAutomataStateContainer<StateType extends TAutomataBaseStateType> = {
state: StateType | null;
};
/**
* Container for automata action.
*/
type TAutomataActionContainer<ActionType extends TAutomataBaseActionType> = {
action: ActionType | null;
};
/**
* Container for automata event.
*/
type TAutomataEventContainer<EventType extends TAutomataBaseEventType> = {
event: EventType | null;
};
/**
* Represents the current state & associated context of the automata.
*
* @template StateType - The type of the automata state.
* @template ContextType - The type of the context associated with each state.
*/
type TAutomataStateContext<StateType extends TAutomataBaseStateType, ContextType extends {
[K in StateType]: any;
}> = TAutomataStateContainer<StateType> & {
context: ContextType[StateType] | null;
};
/**
* Represents the action for an automata, together with its payload.
*
* @template ActionType - The type of the automata action.
* @template PayloadType - The type of the payload associated with each action.
*/
type TAutomataActionPayload<ActionType extends TAutomataBaseActionType, PayloadType extends {
[K in ActionType]: any;
}> = TAutomataActionContainer<ActionType> & {
payload: PayloadType[ActionType] | null;
};
/**
* Represents the event that can be emitted or received by an automata.
*
* @template EventType - The type of the automata event.
* @template EventMetaType - The type of the metadata associated with each event.
*/
type TAutomataEventMetaType<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> = TAutomataEventContainer<EventType> & {
meta: EventMetaType[EventType] | null;
};
/**
* Represents an event handler function for an automata.
*
* @template EventType - The type of the automata event.
* @template ActionType - The type of the automata action.
* @template EventMetaType - The type of the metadata associated with each event.
* @template PayloadType - The type of the payload associated with each action.
* @param event - The event metadata.
* @returns The action(and its payload) that needs to be dispatched to the automata upon processing the event.
*/
type TAutomataEventHandler<EventType extends TAutomataBaseEventType, ActionType extends TAutomataBaseActionType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>> = (event: TAutomataEventMetaType<EventType, EventMetaType>) => TAutomataActionPayload<ActionType, PayloadType>;
/**
* Represents an event emitter function for an automata.
*
* @template EventType - The type of the automata event.
* @template StateType - The type of the automata state.
* @template EventMetaType - The type of the metadata associated with each event.
* @template ContextType - The type of the context associated with each state.
* @param state - The current state of the automata.
* @returns The event that needs to be emitted by the automata after executing a certain `Action`.
*/
type TAutomataEventEmitter<EventType extends TAutomataBaseEventType, StateType extends TAutomataBaseStateType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>> = (state: TAutomataStateContext<StateType, ContextType>) => TAutomataEventMetaType<EventType, EventMetaType>;
type TAutomataEvent<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>> = TAutomataStateContext<StateType, ContextType> & TAutomataActionPayload<ActionType, PayloadType>;
/**
* Represents a reducer function for an automata,
* used for changing the state upon the dispatch of a certain `Action`.
*
* @template StateType - The type of the current automata state.
* @template ActionType - The type of the automata action.
* @template ContextType - The type of the context associated with each state.
* @template PayloadType - The type of the payload associated with each action.
* @template NewStateType - The type of the new state for the automata.
* @param params - The event parameters.
* @returns The new state that the automata should enter and its updated context.
*/
type TAutomataReducer<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>, NewStateType extends StateType = StateType> = (params: TAutomataEvent<StateType, ActionType, ContextType, PayloadType>) => TAutomataStateContext<NewStateType, ContextType>;
/**
* Represents a dispatch function for an automata,
* used for dispatching certain `Actions` to the automata to change its state.
*
* @template StateType - The type of the automata state.
* @template ActionType - The type of the automata action.
* @template ContextType - The type of the context associated with each state.
* @template PayloadType - The type of the payload associated with each action.
* @template NewStateType - The type of the new state after the dispatch.
* @param action - The action payload.
* @returns The new state of the automata and the updated context.
*/
type TAutomataDispatch<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>, NewStateType extends StateType = StateType> = (action: TAutomataActionPayload<ActionType, PayloadType>) => ReturnType<TAutomataReducer<StateType, ActionType, ContextType, PayloadType, NewStateType>>;
type TSubscriptionCancelFunction = () => void;
/**
* Represents a type with all properties defined and non-nullable.
*
* @template T - The type to transform.
*/
type TDefinedValues<T> = T extends object ? {
[P in keyof T]: NonNullable<T[P]>;
} : NonNullable<T>;
/**
* Represents a validator function of the automata.
* Used as a template for validating the automata state, action, event, or event metadata.
*
* @example
* ```typescript
* // Create an action validator for the automata:
* const testValidator = ((a: number) => a % 15 === 0) as TValidator<TTestAction>;
* sampleAutomataInstance.setActionValidator(testValidator);
* ```
*
* @template T - The type of the validator.
* @param x - The value to validate.
*/
type TValidator<T> = (x: any) => x is TDefinedValues<T>;
/**
* Parameters for automata configuration.
*/
type TAutomataParams<StateType extends TAutomataBaseStateType, ActionType extends TAutomataBaseActionType, EventType extends TAutomataBaseEventType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> = TAutomataStateContext<StateType, ContextType> & {
rootReducer: TAutomataReducer<StateType, ActionType, ContextType, PayloadType> | null;
stateValidator?: TValidator<StateType>;
actionValidator?: TValidator<ActionType>;
eventValidator?: TValidator<EventType>;
eventMetaValidator?: TValidator<EventMetaType>;
functionRegistry?: IAutomataFunctionRegistry;
enabled?: boolean;
paused?: boolean;
};
/**
* Queue for automata actions.
*/
type TAutomataQueue<ActionType extends TAutomataBaseActionType, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>> = Array<TAutomataActionPayload<ActionType, PayloadType>>;
/**
* Stack for automata events.
*/
type TAutomataEventStack<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> = Array<TAutomataEventMetaType<EventType, EventMetaType>>;
/**
* Effect function for automata model.
*/
type TAutomataEffect<ModelType extends object, EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> = (event: EventMetaType, model: ModelType) => ModelType;
type TGenericTransformer<DataType> = (data: DataType) => DataType;
/**
* Represents a transformer function for the context of an automata state.
* This transformer can be added to the `State Dictionary` of the automata.
*
* @template StateType - The type of the automata state.
* @template ContextType - The type of the context associated with each state.
* @param context - The current state (and context) of the automata.
* @returns The transformed state (and context) of the automata.
*/
type TContextTransformer<StateType extends TAutomataBaseStateType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>> = (context: TAutomataStateContext<StateType, ContextType>) => TAutomataStateContext<StateType, ContextType>;
type TContextPredicate<StateType extends TAutomataBaseStateType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>> = (context: TAutomataStateContext<StateType, ContextType>) => THighOrderPredicate;
type TModelPredicate<ModelType extends object = Record<string, any>> = (model: ModelType) => THighOrderPredicate;
type THighOrderPredicate = (...predicates: Array<(...args: any[]) => boolean>) => boolean;
/**
* Represents a task that will be processed by the event bus after emitting a certain `Event`.
* Contains the ID of this task, as well as next events to be emitted once this task is completed.
*
* @template EventType - The type of the automata event.
* @template EventMetaType - The type of the metadata associated with each event.
*/
type TEventBusTask<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> = TAutomataEventMetaType<EventType, EventMetaType> & {
task_id: string;
result: Promise<TAutomataEventStack<EventType, EventMetaType>>;
};
/**
* Handler function for the event bus that transforms emitted events to event bus tasks.
*
* @template EventType - The type of the automata event.
* @template EventMetaType - The type of the metadata associated with each event.
* @param event - The event metadata.
* @returns The event bus task.
*/
type TEventBusHandler<EventType extends TAutomataBaseEventType, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>> = (event: TAutomataEventMetaType<EventType, EventMetaType>) => TEventBusTask<EventType, EventMetaType>;
/**
* Represents a function that can be used in the automata.
*/
type TAutomataFunction = ((...args: any) => any) | null;
declare class AbstractBaseClass implements IBaseClass {
correlationId: string;
constructor(...args: any[]);
next(): this;
}
declare function createActionDictionary<ActionType extends TAutomataBaseActionType, PayloadType extends {
[K in ActionType]: any;
}>(): <BaseType extends TAbstractConstructor = TAbstractConstructor>(Base: BaseType) => {
new (...args: any[]): {
getActionKeys({ actions, namespace, }: TActionValuesCollection<ActionType>): Array<string | null>;
clearActions(namespace?: string): /*elided*/ any;
removeActions({ namespace, actions, keys }: Partial<TActionKeysCollection<ActionType> & TActionValuesCollection<ActionType>>): /*elided*/ any;
getActionValues({ namespace, keys, }: TActionKeysCollection<ActionType>): Array<ActionType | null>;
addActions({ namespace, keys }: TActionKeysCollection<ActionType>): ActionType[];
_dictionary: Record<string, ActionType>;
_dictionaryIndex: Map<ActionType, {
key: string;
namespace: string | undefined;
}>;
_namespaceIndex: Record<string, string[]>;
getDictionary(namespace?: string): Record<string, ActionType>;
_stringHash(str: string): number;
_findItem(itemKey: string, namespace?: string): ActionType | null;
_getItemKey(itemKey: string, namespace?: string): string;
_getItemValue(itemKey: string, namespace?: string): ActionType;
_deleteItemKey(itemKey: string): /*elided*/ any;
_getValueData(value: ActionType): {
key: string;
namespace: string | undefined;
} | null;
_addItemKey(itemKey: string, namespace?: string): ActionType;
_clearItems(namespace?: string): /*elided*/ any;
_payloadValidator: TValidator<TAutomataActionPayload<ActionType, PayloadType>> | undefined;
readonly validateActionPayload: TValidator<TAutomataActionPayload<ActionType, PayloadType>>;
setActionPayloadValidator(payloadValidator?: TValidator<TAutomataActionPayload<ActionType, PayloadType>> | undefined): /*elided*/ any;
_defaultPayloadValidator: (p: any) => p is {
action: ActionType;
payload: PayloadType[ActionType] & {};
};
"__#1@#_defaultActionValidator": TValidator<ActionType_1>;
"__#1@#_actionValidator": TValidator<ActionType> | undefined;
readonly validateAction: TValidator<ActionType>;
setActionValidator(actionValidator?: TValidator<ActionType> | null): /*elided*/ any;
};
} & BaseType;
declare const BasicActionDictionary_base: {
new (...args: any[]): {
getActionKeys({ actions, namespace, }: TActionValuesCollection<number>): Array<string | null>;
clearActions(namespace?: string): /*elided*/ any;
removeActions({ namespace, actions, keys }: Partial<TActionKeysCollection<number> & TActionValuesCollection<number>>): /*elided*/ any;
getActionValues({ namespace, keys, }: TActionKeysCollection<number>): (number | null)[];
addActions({ namespace, keys }: TActionKeysCollection<number>): number[];
_dictionary: Record<string, number>;
_dictionaryIndex: Map<number, {
key: string;
namespace: string | undefined;
}>;
_namespaceIndex: Record<string, string[]>;
getDictionary(namespace?: string): Record<string, number>;
_stringHash(str: string): number;
_findItem(itemKey: string, namespace?: string): number | null;
_getItemKey(itemKey: string, namespace?: string): string;
_getItemValue(itemKey: string, namespace?: string): number;
_deleteItemKey(itemKey: string): /*elided*/ any;
_getValueData(value: number): {
key: string;
namespace: string | undefined;
} | null;
_addItemKey(itemKey: string, namespace?: string): number;
_clearItems(namespace?: string): /*elided*/ any;
_payloadValidator: TValidator<TAutomataActionPayload<number, Record<number, any>>> | undefined;
readonly validateActionPayload: TValidator<TAutomataActionPayload<number, Record<number, any>>>;
setActionPayloadValidator(payloadValidator?: TValidator<TAutomataActionPayload<number, Record<number, any>>> | undefined): /*elided*/ any;
_defaultPayloadValidator: (p: any) => p is {
action: number;
payload: any;
};
"__#1@#_defaultActionValidator": TValidator<ActionType>;
"__#1@#_actionValidator": TValidator<number> | undefined;
readonly validateAction: TValidator<number>;
setActionValidator(actionValidator?: TValidator<number> | null): /*elided*/ any;
};
} & typeof AbstractBaseClass;
/**
* Basic action dictionary class that is used in Yantrix automatas.
*/
declare class BasicActionDictionary extends BasicActionDictionary_base implements IActionDictionary<TAutomataBaseActionType, Record<TAutomataBaseActionType, any>> {
constructor();
}
declare function createAutomata<StateType extends TAutomataBaseStateType = TAutomataBaseStateType, ActionType extends TAutomataBaseActionType = TAutomataBaseActionType, EventType extends TAutomataBaseEventType = TAutomataBaseEventType, ContextType extends {
[K in StateType]: any;
} = Record<StateType, any>, PayloadType extends {
[K in ActionType]: any;
} = Record<ActionType, any>, EventMetaType extends {
[K in EventType]: any;
} = Record<EventType, any>>(): <BaseType extends TAbstractConstructor = TAbstractConstructor>(Base: BaseType) => {
new (eventAdapter?: IAutomataEventAdapter<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType> | null, ...args: any[]): {
eventAdapter: IAutomataEventAdapter<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType> | null;
"__#4@#state": StateType | null;
"__#4@#context": ContextType[StateType] | null;
"__#4@#lastAction": ActionType | null;
"__#4@#actionQueue": TAutomataQueue<ActionType, PayloadType>;
"__#4@#enabled": boolean;
"__#4@#paused": boolean;
"__#4@#rootReducer": TAutomataReducer<StateType, ActionType, ContextType, PayloadType> | null;
"__#4@#functionRegistry": IAutomataFunctionRegistry | null;
"__#4@#currentCycle": number;
readonly state: StateType | null;
readonly context: ContextType[StateType] | null;
lastAction: ActionType | null;
readonly currentCycle: number;
incrementCycle(): /*elided*/ any;
clearActionQueue(): /*elided*/ any;
collapseActionQueue(): {
actions: TAutomataQueue<ActionType, PayloadType> | null;
newState: TAutomataStateContext<StateType, ContextType>;
};
enable(): /*elided*/ any;
disable(clearQueue?: boolean): /*elided*/ any;
isEnabled(): boolean;
isPaused(): boolean;
pause(): /*elided*/ any;
resume(): /*elided*/ any;
init(params: TAutomataParams<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType>): /*elided*/ any;
dispatch(action: TAutomataActionPayload<ActionType, PayloadType>): TAutomataStateContext<StateType, ContextType>;
getContext<K extends StateType = StateType>(): TAutomataStateContext<K, ContextType>;
getActionQueue(): TAutomataActionPayload<ActionType, PayloadType>[];
getReducer(): TAutomataReducer<StateType, ActionType, ContextType, PayloadType> | null;
consumeAction(count?: number): {
action: TAutomataActionPayload<ActionType, PayloadType> | null;
newState: TAutomataStateContext<StateType, ContextType>;
};
reduceQueueItem(queue?: TAutomataActionPayload<ActionType, PayloadType>[], newState?: TAutomataStateContext<StateType, ContextType>): {
action: TAutomataActionPayload<ActionType, PayloadType> | null;
newState: TAutomataStateContext<StateType, ContextType>;
};
reduceQueue: () => TAutomataStateContext<StateType, ContextType>;
setContext: (context?: TAutomataStateContext<StateType, ContextType> | null) => /*elided*/ any;
setActionQueue: (queue?: TAutomataQueue<ActionType, PayloadType> | null) => /*elided*/ any;
getFunctionRegistry(): IAutomataFunctionRegistry | null;
setFunctionRegistry: (registry: IAutomataFunctionRegistry | null) => /*elided*/ any;
getEventAdapter(): IAutomataEventAdapter<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType> | null;
setEventAdapter: (adapter: IAutomataEventAdapter<StateType, ActionType, EventType, ContextType, PayloadType, EventMetaType> | null) => /*elided*/ any;
"__#3@#_defaultStateValidator": TValidator<StateType_1>;
"__#3@#_stateValidator": TValidator<StateType> | undefined;
readonly validateState: TValidator<StateType>;
setStateValidator(stateValidator?: TValidator<StateType> | null): /*elided*/ any