ac-chain
v1.0.2
Published
Similar to a reducer pattern, that package is made to create some chain of actions
Downloads
5
Readme
Introduction :
That package have been originally build to handle some middlewares. It's probably still it's only use case, but maybe it will match your expectations in another context. For that introduction however, I will explain in which case of middlewares management I created it.
The purpose was to create a process with several middlewares activated during it, triggered at specific lifecycles. So, let's consider a process in 3 parts, respectively named "P1", "P2" and "P3". At the end of each of those parts, an optional middleware was triggered. At that point we are on a really classical middleware scenario, and it looks like that :
-- P1 -- (middleware 1) -- P2 -- (middleware 2) -- P3 -- (middleware 3)
Now we will add a point that make things tricky : Some of those 3 parts can be skipped. When it's the case, middlewares of previous parts should however still be run. So, if P1 and P2 are skipped, we will directly run P3, but then we want to run all 3 middlewares. Or not... Maybe when we directly reach an advanced part of the process, some previous middlewares should be skipped.
For now, let's summarize what that package will do : It creates Chains of ordered Actions. You can run a specific portion of those Chains by specifying the range of lifecycles. Actions of a Chain are instances of class Action and are mostly just functions connected to lifecycles. Those Actions can have a Role that will define what that Action is supposed to do and prevent 2 Actions with the same role to be executed. Those Actions can also have Rules (beta feature) that will define in which case the Action should be run.
Get started :
You must start by creating a list of Actions.
const myActions: Action[] = [...]
The order of that list doesn't matter (the order of Actions is defined by Lifecycle) :
const myActions: Action[] = [
new Action(() => {
do_something;
}, 2),
new Action(() => {
do_something_before;
}, 1),
];
Lifecycles are just integers. Notice however that you can use Enums instead of numbers (which is great to make you code more readable) :
enum Lifecycle {
START,
HALF,
END,
}
const myActions: Action[] = [
new Action(() => {
do_something;
}, Lifecycle.HALF),
new Action(() => {
do_something_before;
}, Lifecycle.START),
];
Then, you can create a Chain from those Actions and resolve some parts of it :
const chain = new AcChain(actions);
chain.resolveUntil(Lifecycle.END, {});
In that case, we do not pass any data for Actions, represented by the empty object as second argument.
And, that's it for the basics. It's a small package for a specific purpose, nothing more.
Now, let's focus on some details :
Actions :
Actions are created with the class Action.
Action first parameter :
The only mandatory attribute for an Action is the function to run. That function takes 2 parameters :
- An arbitrary data that you can provide when you call one of the resolution method of the Chain and that will be shared by all Actions of the portion that is resolving.
- A ProcessReport that will provide some information about what already been done by the Chain.
Action optional options :
You can provide several options with an object as second parameter :
A Lifecycle :
It will define the order of resolution of the Chain. The default is -1. While you must never provide any negative number as Lifecycle, actions with the default value will be resolved before the others.
As explained before, usage of Enums can be a good alternative to numbers.
A Role :
If a Chain contains 2 Actions with the same Role, only 1 of those Actions will be run. In case where you resolve a portion of the Chain and in that portion there are several Actions with the same Role, the Action with the higher value of Lifecycle will be the one that is run. However, if an Action of the Chain has already been run and, later, another one with the same Role should be executed as element of a portion of the Chain, that second Action will not be run. Indeed, another one have been called before, and only 1 Action can be called per Role.
Rules (beta feature) :
An Action can have some Rules that will define in which context the Action should be run. Currently, Rules are in a beta version (mainly because you can just use some if statement in the function of the Action). I might so remove Rules if it doesn't appear to be relevant. If you want to use some, you should create new implementations of ABS_Rule.