import { AbilityType, Actor, isAbilityFactory } from './actor'; /** * Type definition for task interactions. */ export interface TaskInteraction

{ invoke(param: P): void | Promise; } /** * Type definition for tasks. * * An task is a list of interactions that accept a parameter of type P and don't * yield a result, but modify the state as a side effect. */ type TaskType

= { new (actor: Actor): TaskInteraction

}; export type Task

= TaskType

| TaskType

[]; export type TaskProcedure = ( ability: AbilityType, param: P, ) => void | Promise; /** * Shorthand for creating tasks using a specific ability. * * @param ability * A constructor for an ability service. * @param procedure * The procedure to fulfill this task. */ export function createTask( ability: { new (): A }, procedure: TaskProcedure, ) { return class implements TaskInteraction

{ /** * A ability service object to invoke commands on. */ public ability?: A; /** * An actor to perform sub-tasks. */ public actor?: Actor; constructor(actor: Actor) { this.actor = actor; this.ability = actor.ability(ability); } invoke(param: P): void | Promise { return procedure( isAbilityFactory(this.ability) ? this.ability.create() : this.ability, param, ); } }; }