Reflow
Reflow is a very basic workflow helper, it takes a state getter/setter function and a workflow definition,
and returns a transition function which will transition an object between states, following the rules of the
workflow and calling any workflow state transition logic provided.
Contrived Example:
var reflow = require("reflow");
function getState(o, callback) {
callback(null, o.state);
};
function setState(o, state, callback) {
o.state = state;
callback(null, o);
};
var workflow = {
start : {
middle : {}
},
middle : {
end : {}
},
end : {
start : {}
}
};
var transition = reflow(getState, setState, workflow);
var obj = { state : 'start' };
transition(obj, 'middle', function(err, obj) {
if(err) console.log(err);
console.log("New state is:", obj.state);
});
Defining workflows
Workflows are simply a double-nested javascript object with the first
tier defining states, and the second defining transitions.
Each state defines allowed target states (transitions), which
can have conditions and triggers. Conditions and triggers are functions
which are invoked before the transition to check it is allowed, or after
to perform some activity on transition.
Condition functions
Condition functions take the object, target state and a callback which should
be invoked with an error, and a boolean value, to allow or block transition.
function myCondition(obj, newState, callback) {
if(obj.someCondition) {
return callback(null, true);
} else {
return callback(null, false);
}
});
Trigger functions
Trigger functions take the object and a callback, and perform any side-effect
of the transition.
function myCondition(obj, callback) {
return callback(null);
}
});
A more involved workflow with triggers and conditions
var orderWorkflow = {
received : {
assembly : {
conditions : [ checkStock, checkBacklog ],
triggers : [ sendAssemblyTicket ]
}
},
assembly : {
received : {
triggers : [ notifyAccountsRejected ]
},
shipping : {
conditions : [ checkBuild ],
triggers : [ notifyAccountsBuildComplete ]
}
},
shipping : {
received : {
trigger : [ notifyAccountsReceived ]
}
},
received : {}
};
Passing contexts to triggers and conditions
any arguments passed to the transition function after the callback will be
passed as extra positional arguments to both condition and trigger functions,
this is handy when you need to pass context information to triggers and
conditions.