atween
v0.0.5
Published
Hooking into business-logic
Downloads
3
Readme
Atween
Hooking into Business Logic
Lead Maintainer: Christian Blaschke / @platdesign
Install
npm install --save atween
Usage
const Atween = require('atween');
const atween = new Atween();
Concepts
Interceptors
Basically an interceptor transforms a given input an returns it. If there are multiple interceptors registered on the same case they will get the result of its antecessor as input. Additionally they will get the original
-input as second parameter. If an error occurs inside of an interceptor the error object will be decorated with $prevResult
and $input
. Interceptors run sequentially based on their priority
and can return a Promise
if transformation needs async operations. If an interceptor does not return a value (or s.th. like null
or undefined
) it will pipe through its input value.
Interceptor methods can have an execution context (this
).
Methods
registerInterceptor(case, config)
case
- (String) Name of thecase
as a string.config
- (Object|Function)If given config is a function it will be used as handler.
priority
- (Number) Give a priority to influence execution order. (Default: 1000)handler(prevResult, originalInput)
The "transform"-logic function.
atween.registerInterceptor('myUseCase', {
priority: 500,
handler: function(prevResult, originalInput) {
return prevResult + 1;
}
});
or without specific priority:
atween.registerInterceptor('myUseCase', function(prevResult, originalInput) {
return prevResult + 1;
});
runInterceptors(case, input, [context])
Returns a Promise
which resolves with the result of the last executed interceptor-handler. In case of an error it rejects with an error having two additional attribtues: $prevResult
and $input
.
case
- (String) Name of thecase
as a string.input
- Every input which should run through the chain of registered interceptors.context
- (Object) Give a specific object which will be used as execution context of eachhandler
.
atween.registerInterceptor('myUseCase', {
priority: 500, // Default is 1000
handler: function(prevResult, originalInput) {
return prevResult + 1;
}
});
// result: 5 + 1 = 6
atween.registerInterceptor('myUseCase', {
// Will run with default priority of 1000
handler: function(prevResult, originalInput) {
return prevResult + originalInput;
}
});
// result: 6 + 5 = 11
atween.registerInterceptor('myUseCase', {
priority: 1500,
handler: function(prevResult, originalInput) {
return prevResult * this.factor;
}
});
// result: 11 * 2 = 22
atween.runInterceptors('myUseCase', 5, { factor: 2 })
.then((res) => expect(res).to.equal(22));
Hooks
Hooks can be registered on a specific case
with a unique name
. Running a case
with multiple hooks registered on it will execute all hook-handlers sequentially by priority
. The first parameter passed into each hook-handler is the input
given by the executor. Its result will be stored on a result
-object with given name
as key. The result
-object is passed into each hook-handler as second paramter. If all hook-handlers of a case
run successfully the result
-object will be returned. Hook-handlers can return a Promise
to do async stuff. A hook without a name will ignore the return value except its a Promise
which would be used to defer the sequential-run. Thats very important and differs from an Event!
Methods
registerHook(case, config)
case
- Name of the case given as a string.config
priority
- Number to define execution order point (Default: 1000)name
- Name of the hook. Will be used as key onresult
-object.handler(input, results)
- Hook-handler which will be executed on run. Will havecontext
asthis
ifcontext
is given inrunHooks
-method.
runHooks(case, input, [context])
case
- Name of the case which should be executed.input
- Any type which should be injected into hook-handlers as input value.context
- Optional execution context for handlers.
Example
atween.registerHook('test', {
name: 'A',
handler: (i) => i
});
// Will not have any effect on result-object cause missing name attribute.
atween.registerHook('test', (i) => console.log(i));
atween.registerHook('test', {
name: 'B',
handler: (i) => Promise.resolve(i * 2)
});
atween.registerHook('test', {
name: 'C',
priority: 500,
handler: (i) => i * 3
});
atween.runHooks('test', 2)
.then((res) => expect(res).to.equal({
C: 6, // First assignment caused by priority of 500
A: 2,
B: 4
}));
Events
Events work by the concept of "Fire and Forget". They will not wait for async operations of previous event-handlers. Its return value can be true
or false
but for logging purpose only.
Methods
registerEvent(case, config)
case
- Name of the case given as a string.config
priority
- Number to define execution order point (Default: 1000)name
- Name of the hook. Will be used as key onresult
-object.handler(input, results)
- Hook-handler which will be executed on run. Will havecontext
asthis
ifcontext
is given inrunHooks
-method.
runEvents(case, input, [context])
case
- Name of the case which should be executed.input
- Any type which should be injected into event-handlers as input value.context
- Optional execution context for handlers.