Home Intro Source Mebo GitHub
import Action from 'mebo/src/Action.js'
public class | source

Action

An action is used to perform an evaluation.

By implementing an evaluation through an action, the evaluation is wrapped by an agnostic interface which can be triggered through different domains (Handler).

The data used to perform an evaluation is held by inputs (Action.createInput). These inputs can be widely configured to enforce quality control via properties. The available properties can be found under the documentation for each input type.

class HelloWorld extends Mebo.Action{
  constructor(){
    super();
    this.createInput('repeat: numeric', {max: 100}); // <- input
  }

  async _perform(data){
    return 'HelloWorld '.repeat(data.repeat);
  }
}

const action = new HelloWorld();
action.input('repeat').setValue(3);
action.run().then(...) //  HelloWorld HelloWorld HelloWorld

An action is triggered through Action.run which internally calls Action._perform. Use _perform to implement the evaluation of your action. Also, you can implement Action._after to execute secondary routines.

Make sure actions are always created through the factory function create (Action.create). For that you need to register the action that can be done in two ways:

Decorator support:

@Mebo.register('helloWorld') // <- registering action
class HelloWorld extends Mebo.Action{
  constructor(){
    super();
    this.createInput('repeat: numeric', {max: 100});
  }

  async _perform(data){
    return 'HelloWorld '.repeat(data.repeat);
  }
}

const action = Mebo.Action.create('helloWorld');
action.input('repeat').setValue(3);
action.run().then(...) //  HelloWorld HelloWorld HelloWorld

Registration api (Action.register):

class HelloWorld extends Mebo.Action{
  constructor(){
    super();
    this.createInput('repeat: numeric', {max: 100});
  }

  async _perform(data){
    return 'HelloWorld '.repeat(data.repeat);
  }
}

Mebo.Action.register(HelloWorld, 'helloWorld'); // <- registering action

const action = Mebo.Action.create('helloWorld');
action.input('repeat').setValue(3);
action.run().then(...) //  HelloWorld HelloWorld HelloWorld

In case you have an action that may need to call another actions during _perform, it can be done through:

  • Action.createAction - allows actions to be created from inside of another action. By doing that it creates an action that shares the same Session.
class HelloWorld extends Mebo.Action{
  // ...
  async _perform(data){
    const fooAction = this.createAction('foo');
    const fooResult = await fooAction.run();
    // ...
  }
}
// ...
  • Action.create - factory an action with using a specific session when supplied otherwise, creates an action with a new session.
class HelloWorld extends Mebo.Action{
  // ...
  async _perform(data){
    // in case you are planning to share the same session please
    // use the "sugary" `this.createAction` instead.
    const fooAction = Mebo.Action.create('foo');
    const fooResult = await fooAction.run();
    // ...
  }
}
// ...

Also, actions can take advantage of the caching mechanism designed to improve the performance by avoiding re-evaluations in actions that might be executed multiple times. This can enabled through Action.isCacheable.

Static Method Summary

Static Public Methods
public static

create(actionName: string, session: Session): Action

Creates an action based on the registered action name, in case the action does not exist null is returned instead

public static

createFromJSON(serializedAction: string, autofill: boolean): Action

Creates an action based on the serialized input which is generated by Action.bakeToJSON

public static

register(actionClass: Action, name: string)

Registers an Action to the available actions

public static

Returns the action based on the registration name

public static

Returns the registered action name based on the action class

public static

Returns a list containing the names of the registered actions

Constructor Summary

Public Constructor
public

creates an action

Method Summary

Public Methods
public

addInput(inputInstance: Input)

Adds an Input instance to the action

public

async bakeToJSON(autofill: boolean, avoidHidden: boolean): Promise<string>

Serializes the current interface of the action into json format.

public

createAction(actionName: string): Action

Allows the creation of an action based on the current action.

public

createInput(inputInterface: string, args: ...*): Input

Creates a new input through Input.create then adds it to the action inputs Action.addInput

public

fromJSON(serializedAction: string, autofill: boolean)

Loads the interface of the action from json (serialized through Action.bakeToJSON).

public

async id(): Promise<string>

Returns an unique signature based on the action's current state. It's based on the input types, input values and meta data information about the action.

public

input(inputName: string, defaultValue: *): Input

Returns the input instance based on the given name

public

Returns the action input names

public

Returns a boolean telling if the action is cacheable (false by default).

public

meta(path: string, defaultValue: *): *

Returns a value under the action's metadata.

public

async run(useCache: boolean): Promise<*>

Executes the action and returns the result through a promise

public

Returns the session object

public

setMeta(path: string, value: *, merge: boolean)

Sets a value to the action's metadata.

Detailed information about the metadata support can be found at Metadata.

public

setSession(session: Session)

Associates a Session with the action.

public

Runs the validations of all inputs

Protected Methods
protected

async _after(err: Error | null, value: *): Promise

This method is called after the execution of the action.

protected

async _before(data: Object): Promise

This method is called before the execution of the action.

protected abstract

async _perform(data: Object): Promise<*>

This method should be used to implement the evaluation for the action.

Static Public Methods

public static create(actionName: string, session: Session): Action source

Creates an action based on the registered action name, in case the action does not exist null is returned instead

Params:

NameTypeAttributeDescription
actionName string

registered action name (case-insensitive)

session Session
  • optional

optional custom session object

Return:

Action

public static createFromJSON(serializedAction: string, autofill: boolean): Action source

Creates an action based on the serialized input which is generated by Action.bakeToJSON

Params:

NameTypeAttributeDescription
serializedAction string

json encoded action

autofill boolean
  • optional
  • default: true

tells if the autofill information should be loaded

Return:

Action

public static register(actionClass: Action, name: string) source

Registers an Action to the available actions

In case you want to use a compound name with a prefix common across some group of actions, you can use '.' as separator.

Params:

NameTypeAttributeDescription
actionClass Action

action implementation that will be registered

name string

string containing the registration name for the action, this name is used later to create the action (Action.create). In case of an empty string, the registration is done by using the name of the type.

public static registeredAction(name: string): Action source

Returns the action based on the registration name

Params:

NameTypeAttributeDescription
name string

name of the registered action

Return:

Action

public static registeredActionName(actionClass: Action): string source

Returns the registered action name based on the action class

Params:

NameTypeAttributeDescription
actionClass Action

action that should be used to query the registered name

Return:

string

public static registeredActionNames(): Array<string> source

Returns a list containing the names of the registered actions

Return:

Array<string>

Public Constructors

public constructor() source

creates an action

Public Methods

public addInput(inputInstance: Input) source

Adds an Input instance to the action

Params:

NameTypeAttributeDescription
inputInstance Input

input that should be added to the action

public async bakeToJSON(autofill: boolean, avoidHidden: boolean): Promise<string> source

Serializes the current interface of the action into json format. Serialized actions can be recreated later through Action.createFromJSON or in case of non-registered actions the baked information can be loaded directly to an instance through Action.fromJSON.

Params:

NameTypeAttributeDescription
autofill boolean
  • optional
  • default: true

tells if the Session.autofill will be included in the serialization

avoidHidden boolean
  • optional
  • default: true

tells if inputs with the 'hidden' property should be ignored

Return:

Promise<string>

serialized json version of the action

public createAction(actionName: string): Action source

Allows the creation of an action based on the current action. By doing this it passes the current Action.session to the static create method (Action.create). Therefore creating an action that shares the same session.

Params:

NameTypeAttributeDescription
actionName string

registered action name (case-insensitive)

Return:

Action

public createInput(inputInterface: string, args: ...*): Input source

Creates a new input through Input.create then adds it to the action inputs Action.addInput

Params:

NameTypeAttributeDescription
inputInterface string

string followed by either the pattern name: type or name?: type in case of optional Input

args ...*

arguments passed to the input's constructor

Return:

Input

Returns the created input instance

public fromJSON(serializedAction: string, autofill: boolean) source

Loads the interface of the action from json (serialized through Action.bakeToJSON).

Params:

NameTypeAttributeDescription
serializedAction string

serialized json information generated by Action.bakeToJSON

autofill boolean
  • optional
  • default: true

tells if the Session.autofill should be loaded

public async id(): Promise<string> source

Returns an unique signature based on the action's current state. It's based on the input types, input values and meta data information about the action.

For a more reliable signature make sure that the action has been created through the factory method (Action.create).

Return:

Promise<string>

public input(inputName: string, defaultValue: *): Input source

Returns the input instance based on the given name

Params:

NameTypeAttributeDescription
inputName string

name of the input

defaultValue *
  • optional

default value that is returned in case the input does not exist

Return:

Input

public inputNames(): Array<string> source

Returns the action input names

Return:

Array<string>

public isCacheable(): boolean source

Returns a boolean telling if the action is cacheable (false by default).

This method should be overridden by derived classes to tell if the action is cacheable. This information is used by Action.run.

The configuration about the LRU cache can be found under the Session.

Return:

boolean

public meta(path: string, defaultValue: *): * source

Returns a value under the action's metadata.

Params:

NameTypeAttributeDescription
path string

path about where the value is localized (the levels must be separated by '.'). In case of an empty string it returns the entire metadata. The path can be defined using option vars (Metadata.optionVar).

defaultValue *
  • optional

default value returned in case a value was not found for the path

Return:

*

public async run(useCache: boolean): Promise<*> source

Executes the action and returns the result through a promise

Params:

NameTypeAttributeDescription
useCache boolean
  • optional
  • default: true

tells if the action should try to use the LRU cache to avoid the execution. This option is only used when the action is Action.isCacheable

Return:

Promise<*>

public session(): Session source

Returns the session object

Return:

Session

public setMeta(path: string, value: *, merge: boolean) source

Sets a value to the action's metadata.

Detailed information about the metadata support can be found at Metadata.

Params:

NameTypeAttributeDescription
path string

path about where the value should be stored under the metadata (the levels must be separated by '.'). The path can be defined using option vars (Metadata.optionVar).

value *

value that is going to be stored under the collection

merge boolean
  • optional
  • default: true

this option is used to decide in case of the last level is already existing under the collection, if the value should be either merged (default) or overridden.

public setSession(session: Session) source

Associates a Session with the action. By doing this all inputs that are flagged with 'autofill' property will be initialized with the session value. The session assigned to the action is cloned during the assignment (Session.clone). A session is always assigned to an action, during the factoring (Action.create).

Params:

NameTypeAttributeDescription
session Session

session object

public validate(): Promise source

Runs the validations of all inputs

Return:

Promise

Protected Methods

protected async _after(err: Error | null, value: *): Promise source

This method is called after the execution of the action.

You could re-implement this method to:

  • Add custom metadata information that can be used by a Writer
  • Add arbitrary information to a log
  • In case of errors to purge temporary files

Params:

NameTypeAttributeDescription
err Error | null

Error exception or null in case the action has been successfully executed

value *

value returned by the action

Return:

Promise

resolved promise (any result passed to the promise is ignored)

protected async _before(data: Object): Promise source

This method is called before the execution of the action.

In case you need to check data against multiple inputs a recommended strategy to tackle this scenario is to implement a special input type where compound data can be represented (like json input type). However, for cases where the data cannot be coupled you can use this method to provide a way to check them before the execution of the action by raising an error in case the check fails. Therefore, avoiding to have any special verification inside of _perform.

class MyAction extends Mebo.Action{
   // ...
   async _before(data){
       // if (...){
           throw new Mebo.Error.NotFound('my error message');
       // }
   }
   // ...
}

Params:

NameTypeAttributeDescription
data Object

plain object containing the value of the inputs, this is just to provide a more convenient way to query the value of the inputs data.myInput instead of this.input('myInput').value().

Return:

Promise

resolved promise (any result passed to the promise is ignored)

protected abstract async _perform(data: Object): Promise<*> source

This method should be used to implement the evaluation for the action. It's called by Action.run after all inputs have been validated (Action.validate and Action._before). It's expected to return a Promise containing the result for the evaluation.

During the execution of the action all inputs are assigned as read-only (Input.readOnly), this is done to prevent any modification in the input while the execution is happening, by the end of the execution the inputs are assigned back with the read-only state that was assigned before of the execution.

Result through a Handler:

The Handler.output is used for the serialization of a result. Therefore, actions should not serialize the result by themselves; instead it should be done by a handler. The handlers shipped with Mebo have support for streams where in case of any readable stream or buffer value they are piped to the output, otherwise the result is serialized using JSON.

Params:

NameTypeAttributeDescription
data Object

plain object containing the value of the inputs, this is just to provide a more convenient way to query the value of the inputs inside of the execution for instance: data.myInput instead of this.input('myInput').value().

Return:

Promise<*>

value that should be returned by the action