UNPKG

@yantrix/automata

Version:

Yantrix framework core: reference Typescript implementation of finite state machine

1,063 lines (1,058 loc) 83.4 kB
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