import { StrictEffect } from "@redux-saga/types";
import { Saga } from "redux-saga";
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Action } from "redux";
/* eslint-disable @typescript-eslint/no-explicit-any */
import { StrictEffect as StrictEffect$0 } from "redux-saga/effects";
/**
 * An event without payload
 */
interface Event<T extends string> extends Action<T> {
    type: T;
}
/**
 * An event with generic payload
 */
interface PayloadEvent<T extends string> extends Event<T> {
    payload: any;
}
/**
 * An error event (FSA compliant)
 */
interface ErrorEvent<T extends string> extends Event<T> {
    payload: Error;
    error: true;
}
/**
 * An activity that takes no input
 */
type VoidActivity = Saga<[]> | ((...args: []) => void);
/**
 * An activity that takes an event as input
 */
type Activity<K extends string> = Saga<[Event<K>]> | Saga<[PayloadEvent<K>]> | Saga<[ErrorEvent<K>]> | Saga<[]> | ((...args: [Event<K>]) => void) | ((...args: [PayloadEvent<K>]) => void) | ((...args: [ErrorEvent<K>]) => void);
declare const startStmActionType = "@@redux-sigma/start-stm";
declare const stmStartedActionType = "@@redux-sigma/stm-started";
declare const stopStmActionType = "@@redux-sigma/stop-stm";
declare const stmStoppedActionType = "@@redux-sigma/stm-stopped";
declare const storeStmStateActionType = "@@redux-sigma/store-state";
declare const storeStmContextActionType = "@@redux-sigma/store-context";
declare const REACTION_POLICY_FIRST = "REACTION_POLICY_FIRST";
declare const REACTION_POLICY_LAST = "REACTION_POLICY_LAST";
declare const REACTION_POLICY_ALL = "REACTION_POLICY_ALL";
/**
 * This type defines the action that can start the state machine.
 * It contains the state machine identifier (its name),
 * and the initial context for that state machine.
 *
 * This action has no actual effect on the store.
 * The state machine will propagate the context through `StateMachineStartedAction`
 * according to its actual state.
 */
interface StartStateMachineAction<N extends string, C> extends Action<typeof startStmActionType> {
    payload: {
        name: N;
        context: C;
    };
}
/**
 * This type defines the action that signals that a state machine
 * was successfully started. It initializes the store with the initial context
 * and the initial state of the state machine.
 */
interface StateMachineStartedAction<N extends string, C> extends Action<typeof stmStartedActionType> {
    payload: {
        name: N;
        context: C;
    };
}
/**
 * This type defines the action that can stop the state machine.
 * It contains the state machine identifier (its name).
 */
interface StopStateMachineAction<N extends string> extends Action<typeof stopStmActionType> {
    payload: {
        name: N;
    };
}
/**
 * This type defines the action that signals that a state machine
 * was successfully stopped. It has no practical use at the moment:
 * it is only triggered to flush the redux-saga event queue.
 * It contains the state machine identifier (its name).
 */
interface StateMachineStoppedAction<N extends string> extends Action<typeof stmStoppedActionType> {
    payload: {
        name: N;
    };
}
/**
 * This type defines the action that will update the state of the state machine
 * stored inside its `stateReducer`.
 * It contains the state machine identifier (its name),
 * and the new state that will be stored.
 */
interface StoreStateMachineState<N extends string, S extends string> extends Action<typeof storeStmStateActionType> {
    payload: {
        name: N;
        state: S;
    };
}
/**
 * This type defines the action that will update the context of the state machine
 * stored inside its `stateReducer`.
 * It contains the state machine identifier (its name),
 * and the new context that will be stored.
 */
interface StoreStateMachineContext<N extends string, C> extends Action<typeof storeStmContextActionType> {
    payload: {
        name: N;
        context: C;
    };
}
/**
 * This is the state and context of a state machine that is not running.
 */
interface StoppedStmStorage {
    state: null;
    context: undefined;
}
/**
 * This is the state and context of a state machine that IS running.
 */
interface StartedStmStorage<S extends string, C> {
    state: S;
    context: C;
}
/**
 * The actual state and context of a state machine.
 */
type StmStorage<S extends string, C> = StartedStmStorage<S, C> | StoppedStmStorage;
/**
 * This is the public interface for a state machine.
 * It removes private and protected fields, and can be used by other libraries.
 */
interface StateMachineInterface<S extends string, SM extends string, C> {
    name: SM;
    starterSaga: () => Generator<StrictEffect$0, void>;
    stateReducer: (state: StmStorage<S, C> | undefined, action: any) => StmStorage<S, C>;
    start: (ctx: C) => StartStateMachineAction<SM, C>;
    stop: () => StopStateMachineAction<SM>;
}
/**
 * This is a state machine that can be used as a sub state machine
 * without providing an initial context, since an empty object
 * can be assigned to its context.
 */
interface SubStateMachineWithoutContext<SM extends string> extends StateMachineInterface<any, SM, {}> {
}
/**
 * This is a state machine that can only be used as a sub state machine
 * by providing an initial context, since an empty object may not be
 * assignable to its context.
 *
 * The `contextBuilder` field is a function or generator that will return
 * the initial context for this state machine.
 */
interface SubStateMachineWithContext<SM extends string, SC = any> {
    stm: StateMachineInterface<any, SM, SC>;
    contextBuilder: (() => SC) | (() => Generator<StrictEffect$0, SC>);
}
/**
 * This is any state machine that can be used as a sub state machine.
 */
type SubStateMachine<SM extends string> = SubStateMachineWithContext<SM> | SubStateMachineWithoutContext<SM>;
/**
 * A guard is a boolean function that takes in input an event and the
 * current context of the STM.
 */
type Guard<K extends string, C> = ((...args: [Event<K>, C]) => boolean) | ((...args: [PayloadEvent<K>, C]) => boolean) | ((...args: [ErrorEvent<K>, C]) => boolean);
/**
 * A transition can be defined as a target state and a command (or commands)
 * to execute before reaching the target state.
 */
interface Transition<S extends string, E extends string> {
    target: S;
    command: Activity<E> | Activity<E>[];
}
/**
 * A guarded transition is defined by a target state, and a guard that
 * returns true if the transition should happen. It can optionally have a
 * command (or commands).
 */
interface GuardedTransition<S extends string, E extends string, C> {
    target: S;
    guard: Guard<E, C>;
    command?: Activity<E> | Activity<E>[];
}
/**
 * A transition can be one of the following:
 * - just a state
 * - a target state and a command to execute
 * - a state and a guard, and an optional command
 * - more than one state and guard, with optional commands
 */
type TransitionSpec<S extends string, K extends string, C = unknown> = S | Transition<S, K> | GuardedTransition<S, K, C> | GuardedTransition<S, K, C>[];
/**
 * The transition map is a partial mapping between events and target states.
 * Transitions may have a command, and a guard.
 */
type TransitionMap<E extends string, S extends string, C> = Partial<{
    [key in E]: TransitionSpec<S, key, C>;
}>;
/**
 * A reaction policy determines what the state machine will do when a reaction
 * is triggered several times during a short period of time.
 */
type ReactionPolicy = typeof REACTION_POLICY_FIRST | typeof REACTION_POLICY_LAST | typeof REACTION_POLICY_ALL;
/**
 * This type defines what a reaction looks like when a reaction policy
 * is specified explicitly.
 */
interface ReactionSpec<E extends string> {
    activity: Activity<E>;
    policy: ReactionPolicy;
}
/**
 * The reaction map is a partial mapping between possible events and
 * the commands to run when the event happens.
 */
type ReactionMap<E extends string> = Partial<{
    [key in E]: Activity<key> | ReactionSpec<key>;
}>;
/**
 * Each state definition can contain the following fields:
 *
 * - what to do onEntry and onExit
 * - which subMachines to run when inside the state
 * - the possible transitions for the state
 * - the reactions for the state
 */
interface StateAttributes<E extends string, S extends string, SM extends string, C> {
    onEntry?: VoidActivity | VoidActivity[];
    onExit?: VoidActivity | VoidActivity[];
    subMachines?: SubStateMachine<SM> | SubStateMachine<SM>[];
    transitions?: TransitionMap<E, S, C>;
    reactions?: ReactionMap<E>;
}
/**
 * This is the root type of the `spec` field of each state machine.
 * It's a mapping of each possible state to the specification of that
 * state.
 */
type StateMachineSpec<E extends string, S extends string, SM extends string, C> = {
    [key in S]: StateAttributes<E, S, SM, C>;
};
declare abstract class StateMachine<E extends string = string, S extends string = string, SM extends string = string, C = {}, IS extends S = S, N extends SM = SM> implements StateMachineInterface<S, SM, C> {
    abstract readonly name: N;
    private _context;
    protected abstract readonly spec: StateMachineSpec<E, S, SM, C>;
    protected abstract readonly initialState: IS;
    private runningTasks;
    private currentState;
    private transitionChannel;
    /**
     * Returns a redux action that will start this state machine when dispatched,
     * with the initial context provided in input.
     *
     * @param context The initial context of the state machine.
     */
    start: (context: C) => StartStateMachineAction<N, C>;
    /**
     * Returns a redux action that will stop this state machine when dispatched.
     */
    stop: () => StopStateMachineAction<N>;
    /**
     * Returns a redux action that signals that the state machine
     * was successfully started.
     */
    private started;
    /**
     * Returns a redux action that signals that the state machine
     * was successfully stopped.
     */
    private stopped;
    /**
     * Returns an action that will update the state of this state machine stored
     * by the `stateReducer`.
     *
     * @param state The new state.
     */
    private storeState;
    /**
     * Returns an action that will update the context of this state machine stored
     * by the `stateReducer`.
     *
     * @param context The new context.
     */
    private storeContext;
    /**
     * Computes the new context and stores it using `storeContext`.
     *
     * @param newContext The new context, or an immer-style function that mutates
     * the current context.
     */
    setContext(newContext: C | ((ctx: C) => void)): Generator<import("redux-saga/effects").PutEffect<StoreStateMachineContext<N, C>>, void, unknown>;
    /**
     * Returns the current context.
     */
    get context(): C;
    /**
     * This saga is responsible for starting and stopping this state machine.
     * It listens to the `start` actions returned by the methods of
     * this state machine, and relies on the `run` method to catch `stop` actions.
     *
     * This saga shouldn't be used directly: rely on `stateMachineStarterSaga`
     * instead.
     */
    starterSaga(): Generator<StrictEffect, void>;
    /**
     * Runs the state machine described by this state machines' spec.
     */
    private run;
    /**
     * A generator that runs the "loop" for the current state.
     * It listens to transition events while running `onEntry` activities and
     * `reactions`, and starts sub state machines. As soon as a transition event
     * is returned, the state loop is stopped, and the transition trigger is
     * returned to the calling function.
     *
     * The loop listens for both transition events and the stop event.
     * The first event that is received exits the loop: a transition event
     * returns a TransitionTrigger, while a stop event returns nothing.
     */
    private stateLoop;
    /**
     * Waits for the first event matching a regular transition or a guarded
     * transition, and returns it together with the next state and the
     * optional command (or commands) that must be executed before transitioning.
     */
    private getNextState;
    /**
     * This reducer stores the current state of the State Machine. It can be
     * added to your application reducers if you need to access the state of a
     * State Machine somewhere in your application.
     *
     * @param state  The current state and context.
     * @param action The action taken by the reducer.
     */
    stateReducer: (state: StoppedStmStorage | StartedStmStorage<S, C> | undefined, action: StoreStateMachineState<N, S> | StartStateMachineAction<N, C> | StopStateMachineAction<N> | StateMachineStoppedAction<N> | StateMachineStartedAction<N, C> | StoreStateMachineContext<N, C>) => StmStorage<S, C>;
    /**
     * Starts all onEntry activities. Does not wait for them to complete.
     */
    private startOnEntryActivities;
    /**
     * Starts and adds the background tasks listening to reactions
     * in the background task list.
     */
    private registerToReactions;
    /**
     * Implements the `first` reaction policy: once an event triggering a reaction
     * is received, no other event are processed until the first event has
     * complete its processing.
     *
     * @param eventType The event triggering the reaction
     * @param activity The reaction activity
     */
    private takeFirst;
    /**
     * Implements the `last` reaction policy: events are processed as they come.
     * If a new event is received while a reaction is running, the old reaction
     * is stopped, and a new reaction starts running.
     *
     * @param eventType The event triggering the reaction
     * @param activity The reaction activity
     */
    private takeLast;
    /**
     * Implements the `all` reaction policy: events that can trigger a reaction
     * are stored in a queue, and processed sequentially.
     *
     * @param eventType The event triggering the reaction
     * @param activity The reaction activity
     */
    private takeAll;
    /**
     * Stops all running tasks. Used when exiting from a state
     * or when the state machine is stopped.
     */
    private cancelRunningTasks;
    /**
     * Starts all sub state machines for the current state..
     */
    private startSubMachines;
    /**
     * Stops all state machines for the current state.
     */
    private stopSubMachines;
    /**
     * Runs all onExit activities, and waits for them to return before continuing.
     */
    private runOnExitActivities;
}
/**
 * Returns the negation of the input function.
 *
 * @param f A function.
 */
declare function not<A extends unknown[]>(f: (...args: A) => boolean): (...args: A) => boolean;
/**
 * Returns a boolean function returning true if all input functions
 * return true.
 *
 * @param fs An array of functions.
 */
declare function and<A extends unknown[]>(...fs: Array<(...args: A) => boolean>): (...args: A) => boolean;
/**
 * Returns a boolean function returning true if at least one input functions
 * returns true.
 *
 * @param fs An array of functions.
 */
declare function or<A extends unknown[]>(...fs: Array<(...args: A) => boolean>): (...args: A) => boolean;
/**
 * Instructs redux-sigma to use the `all` reaction policy for the input activity.
 *
 * @param activity An activity.
 */
declare function all<K extends string>(activity: Activity<K>): ReactionSpec<K>;
/**
 * Instructs redux-sigma to use the `last` reaction policy for the input activity.
 *
 * @param activity An activity.
 */
declare function last<K extends string>(activity: Activity<K>): ReactionSpec<K>;
/**
 * Instructs redux-sigma to use the `first` reaction policy for the input activity.
 *
 * @param activity An activity.
 */
declare function first<K extends string>(activity: Activity<K>): ReactionSpec<K>;
/**
 * Helper function to bind a sub STM to a context builder function.
 * The context builder function is responsible for creating the initial context
 * for the sub STM.
 *
 * This is just some TypeScript magic (aka inference) to make sure that
 * the sub state machine context contract is respected.
 *
 * @param stm the sub state machine to start
 * @param contextBuilder a function or saga that returns
 * the initial context for `stm`
 *
 * @returns a sub state machine with context descriptor,
 * used inside another STM spec
 */
declare function bindStm<SM extends string = string, SC = unknown>(stm: StateMachineInterface<any, SM, SC>, contextBuilder: (() => SC) | (() => Generator<StrictEffect$0, SC>)): SubStateMachineWithContext<SM, SC>;
/**
 * Creates a saga that runs the `starterSaga` for the state machines
 * given in input.
 *
 * It does some additional checks for you:
 *
 * - if two or more state machines have the same identifier (their name),
 *   this saga throws an error, since running more than one instance of
 *   the same state machine _will_ result in undefined behaviour
 * - if you try to start or stop a state machine that was not passed
 *   to this saga, it will log an error in console (in development only)
 *
 * @param stms An array of StateMachine instances.
 */
declare function stateMachineStarterSaga(...stms: StateMachineInterface<any, any, any>[]): Generator<import("redux-saga/effects").ForkEffect<void>, void, unknown>;
export { StateMachine, StateMachineInterface, StateMachineSpec, StmStorage, StartedStmStorage, StoppedStmStorage, stateMachineStarterSaga, and, not, or, all, first, last, bindStm };
