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 |
Creates an action based on the registered action name, in case the action does
not exist |
|
public static |
createFromJSON(serializedAction: string, autofill: boolean): Action Creates an action based on the serialized input which is generated by Action.bakeToJSON |
|
public static |
Registers an Action to the available actions |
|
public static |
registeredAction(name: string): Action Returns the action based on the registration name |
|
public static |
registeredActionName(actionClass: Action): string 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 |
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 |
Loads the interface of the action from json (serialized through Action.bakeToJSON). |
|
public |
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 |
Returns the input instance based on the given name |
|
public |
inputNames(): Array<string> Returns the action input names |
|
public |
Returns a boolean telling if the action is cacheable ( |
|
public |
Returns a value under the action's metadata. |
|
public |
Executes the action and returns the result through a promise |
|
public |
Returns the session object |
|
public |
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 |
This method is called after the execution of the action. |
|
protected |
This method is called before the execution of the action. |
|
protected abstract |
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
public static createFromJSON(serializedAction: string, autofill: boolean): Action source
Creates an action based on the serialized input which is generated by Action.bakeToJSON
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:
Name | Type | Attribute | Description |
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:
Name | Type | Attribute | Description |
name | string | name of the registered action |
Public Constructors
Public Methods
public addInput(inputInstance: Input) source
Adds an Input instance to the action
Params:
Name | Type | Attribute | Description |
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:
Name | Type | Attribute | Description |
autofill | boolean |
|
tells if the Session.autofill will be included in the serialization |
avoidHidden | boolean |
|
tells if inputs with the 'hidden' property should be ignored |
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:
Name | Type | Attribute | Description |
actionName | string | registered action name (case-insensitive) |
public createInput(inputInterface: string, args: ...*): Input source
Creates a new input through Input.create then adds it to the action inputs Action.addInput
public fromJSON(serializedAction: string, autofill: boolean) source
Loads the interface of the action from json (serialized through Action.bakeToJSON).
Params:
Name | Type | Attribute | Description |
serializedAction | string | serialized json information generated by Action.bakeToJSON |
|
autofill | boolean |
|
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).
public input(inputName: string, defaultValue: *): Input source
Returns the input instance based on the given name
Params:
Name | Type | Attribute | Description |
inputName | string | name of the input |
|
defaultValue | * |
|
default value that is returned in case the input does not exist |
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.
public meta(path: string, defaultValue: *): * source
Returns a value under the action's metadata.
Params:
Name | Type | Attribute | Description |
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 |
|
defaultValue | * |
|
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:
Name | Type | Attribute | Description |
useCache | boolean |
|
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 |
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:
Name | Type | Attribute | Description |
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 |
|
value | * | value that is going to be stored under the collection |
|
merge | boolean |
|
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:
Name | Type | Attribute | Description |
session | Session | session object |
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
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:
Name | Type | Attribute | Description |
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
|
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:
Name | Type | Attribute | Description |
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: |