data-workflow-engine v1.0.0
Data Workflow Engine
A configurable data workflow engine. Configure an engine with:
- a workflow configuration JSON
- a
computation_context
Demo
View an online demo here: https://lukepur.github.io/data-workflow-engine.
Workflow configuration
The workflow configuration object has the following properties:
sections: an array of items with atypeof 'section' - nodes which make up the input components of the workflowdecisions: nodes which allow conditional paths through the workflowedges: an array ofedgeitems which describe the paths connecting the nodes of the workflowderived_data: an array of derived data items which compute the output of running custom functions on a data instance
These entities have the following properties:
section
id: a unique string reference to thissectionchildren: an array of thesection's items (eithergroup,array_group, orvalue)
An section of a data instance can be in one of the following states:
invalid: there are validation errors in thesectionvalid: there are no validation errors in thesection
decision
id: a unique string reference to thisdecisionoutput: thefunc_refthat will be evaluated on the data instance to return either true or false as the input for a connected outgoingedge
edge
from: the id of the node this edge directs fromto: the id of the node this edge direct towhen_input_is: optional activate this edge when the input node istrueorfalse. This property is only appropriate when thefromid refers to adecisionnode
derived_data
id: a unique string reference for thisderived_datafn: thefunc_refthat will be evaluated on the current data instance to determine the value assigned toidin the output data
func_ref
A func_ref is a descriptor for run-time computations against a data instance. A func_ref has the following properties:
fn: the name of the function to invoke. This must be a pre-configured method available on thecomputation_contextused to configure the engine instanceargs: an array of arguments to pass into the function. The following special tokens can be used as items:$.<path>: de-reference the value atpathof the data instance. See path resolving for more details$value: de-reference the value of the current node. Undefined if nodetypeis notvalue
Path resolving
The following special characters can be used in paths:
*: selects all array items at this level in the path. Note, can be used more than once in a path, and items from other path branches will be included^: selects the array index that matches the instance index of this node. Useful, for example, to select sibling values
Data mapping
If a different structure of the data returned by the getWorkflowState method is
required, the data_mapping property can be used to specify what a value, array_value
or array_group node's value is bound to in the mapped_data object. The mapped_data object
is included in addition to the data property which maintains the hierarchy defined in the
configuration.
For example, consider the following configuration snippet:
{
id: name,
type: group
children: [
{
id: title,
type: value
data_mapping: title
}
]
}By default, the data property returned in the response of getWorkflowState
would assign a title value as follows:
{
name: {
title: 'miss'
}
}But with the above data_mapping: title configuration, the value of title would
be assigned directly to the root (or relative to any array ancestor paths) property
of 'title' in the mapped_data object:
{
title: 'miss'
}Note that data_mapping only applies to the output data - all refs in func_refs
must use the full (unmapped) data path.
Data Engine API
To get started, create a Data Engine instance:
- Import data-engine:
const DataEngine = require('data-workflow-engine');- Create a data engine instance:
const configuration = require('./path/to/configuration');
// optional - use a custom computation_context which is merged with the default context
const ctx = require('./path/to/computation-context');
const engine = DataEngine.create(configuration, ctx);Instance methods
getWorkflowState(dataInstanceObject)
Usage: engine.getWorkflowState(dataInstanceObject)
Returns an object with the following shape:
{
data: Object, // a 'pruned' representation of `dataInstanceObject` - unmet preconditions and unspecified data items are removed
derived: Object, // object containing the results of the derived calculations (derived id's are object keys, with results the values)
section_states: Object, // object containing the state of the workflow nodes for `dataInstanceObject`. Each section's ID is a key in the object, and the value has the properties: `status` (either 'valid' or 'invalid') and `validationMessages` which contains an array of `validationMessage` objects
edge_states: Array // an array of the edge states of the configuration, enhanced with a `status` property - 'active' or 'inactive' depending on whether the `dataInstanceObject` activates this edge
}nextSection(currentSectionId, dataInstanceObject)
Usage: engine.nextSection(currentSectionId, dataInstanceObject)
Returns an object representing the next section node that should be visited in
the workflow:
{
sectionId: id_of_next_section,
validationMessages: [{path: path.to.target, message: message}]
}The next section will be determined according to the following rules:
- If the current section is reachable by active edges and is valid, the next section will be determined by the next active edge(s) which point to that section
- If the current section is reachable by active edges and is invalid, the same
section's id will be returned, indicating the section needs to be made valid before
the next section can be reached. In this case, the return object will also have a
validationMessagesproperty - If the current section is unreachable by active edges, then the last reachable section's
id will be returned, and any applicable
validationMessages
previousSection(currentSectionId, dataInstanceObject)
Usage: engine.previousSection(currentSectionId, dataInstanceObject)
Returns an object representing the previous section in the workflow tree:
{
sectionId: id_of_previous_section
}The previous section will be determined according to the following rules:
- If the current section is reachable by active edges, the previous section will be determined by the previous active edge(s) which point from that section
- If the current section is unreachable by active edges, then the last reachable section's id will be returned
isSectionReachable(requestedSectionId, dataInstanceObject)
Usage: engine.isSectionReachable(requestedSectionId, dataInstanceObject)
Return a boolean determining whether requestedSectionId is reachable for the
given dataInstanceObject
Example configuration
See the file test/test-configuration.yaml for an up-to-date example of how to configure a workflow.
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago