import type { ActionObserver } from './ActionObserver'; import type { Actor, IAction, IActorOutput, IActorTest } from './Actor'; import type { TestResult } from './TestResult'; /** * A publish-subscribe bus for sending actions to actors * to test whether or not they can run an action. * * This bus does not run the action itself, * for that a {@link Mediator} can be used. * * @see Actor * @see Mediator * * @template A The actor type that can subscribe to the sub. * @template I The input type of an actor. * @template T The test type of an actor. * @template O The output type of an actor. * @template TS The test side data type. */ export declare class Bus, I extends IAction, T extends IActorTest, O extends IActorOutput, TS = undefined> implements IBusArgs { readonly name: string; protected readonly actors: A[]; protected readonly observers: ActionObserver[]; protected readonly dependencyLinks: Map; failMessage: string; /** * All enumerable properties from the `args` object are inherited to this bus. * * @param {IBusArgs} args Arguments object * @param {string} args.name The name for the bus * @throws When required arguments are missing. */ constructor(args: IBusArgs); /** * Subscribe the given actor to the bus. * After this, the given actor can be unsubscribed from the bus by calling {@link Bus#unsubscribe}. * * An actor that is subscribed multiple times will exist that amount of times in the bus. * * @param {A} actor The actor to subscribe. */ subscribe(actor: A): void; /** * Subscribe the given observer to the bus. * After this, the given observer can be unsubscribed from the bus by calling {@link Bus#unsubscribeObserver}. * * An observer that is subscribed multiple times will exist that amount of times in the bus. * * @param {ActionObserver} observer The observer to subscribe. */ subscribeObserver(observer: ActionObserver): void; /** * Unsubscribe the given actor from the bus. * * An actor that is subscribed multiple times will be unsubscribed only once. * * @param {A} actor The actor to unsubscribe * @return {boolean} If the given actor was successfully unsubscribed, * otherwise it was not subscribed before. */ unsubscribe(actor: A): boolean; /** * Unsubscribe the given observer from the bus. * * An observer that is subscribed multiple times will be unsubscribed only once. * * @param {ActionObserver} observer The observer to unsubscribe. * @return {boolean} If the given observer was successfully unsubscribed, * otherwise it was not subscribed before. */ unsubscribeObserver(observer: ActionObserver): boolean; /** * Publish an action to all actors in the bus to test if they can run the action. * * @param {I} action An action to publish * @return {IActorReply, I extends IAction, T extends IActorTest, * O extends IActorOutput>[]} * An array of reply objects. Each object contains a reference to the actor, * and a promise to its {@link Actor#test} result. */ publish(action: I): IActorReply[]; /** * Invoked when an action was run by an actor. * * @param actor The action on which the {@link Actor#run} method was invoked. * @param {I} action The original action input. * @param {Promise} output A promise resolving to the final action output. */ onRun(actor: Actor, action: I, output: Promise): void; /** * Indicate that the given actor has the given actor dependencies. * * This will ensure that the given actor will be present in the bus *before* the given dependencies. * * @param {A} dependent A dependent actor that will be placed before the given actors. * @param {A[]} dependencies Actor dependencies that will be placed after the given actor. */ addDependencies(dependent: A, dependencies: A[]): void; /** * Reorder the bus based on all present dependencies. */ reorderForDependencies(): void; } export interface IBusArgs { /** * The name for this bus. * @default {} */ name: string; } /** * Data interface for holding an actor and a promise to a reply from that actor. */ export interface IActorReply, I extends IAction, T extends IActorTest, O extends IActorOutput, TS = undefined> { actor: A; reply: Promise>; } export type IReply = IActorReply, I, T, O, TS>; export type IBus = Bus, I, T, O, TS>;