npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

atween

v0.0.5

Published

Hooking into business-logic

Downloads

3

Readme

Atween

Hooking into Business Logic

Build Status Current Version

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 the case 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 the case 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 each handler.
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 on result-object.
    • handler(input, results) - Hook-handler which will be executed on run. Will have context as this if context is given in runHooks-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 on result-object.
    • handler(input, results) - Hook-handler which will be executed on run. Will have context as this if context is given in runHooks-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.