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

agency

v1.0.2

Published

Dependency based asynchronous flow control utility

Downloads

4

Readme

Agency Logo

Dependency based asynchronous flow control utility for Node.js.

NPM Version NPM Downloads

Philosophy

" never wait, never block, finish fast "

Respecting the nature of Node.js, agency encourages the use of independent, non blocking, fast running units of execution called agents. agency controls the execution flow of agents by looking at their dependency list defined by a logical expression. Inter agent communication allows greater arquitecture flexibility and additional conditional execution.

Installation

$ npm install agency

Usage case #1

agency set up and single agent creation and execution

var ag = require('agency');

// creates new agency and sets logging to verbose mode (output to console)
var agency = ag('v');

// creates new agent 'id1'
var agent = agency.createAgent('id1');

// defines agent code
agent.setFunction(function() {console.log('agent id1 executed!');}); 

// run agents
agency.runAgents();

Usage case #2

agency with dependency execution

var ag = require('agency');

var agency = ag('v');

// agent 'id3' will be executed after 'id1' and 'id2'
var agent3 = agency.createAgent('id3', 'id1&&id2');
agent3.setFunction(function () { console.log('agent id3 executed!'); });

// defines agent 'id1'
var agent = agency.createAgent('id1');
agent.setFunction(function () { console.log('agent id1 executed!'); });

// defines agent 'id2'
var agent2 = agency.createAgent('id2');
agent2.setFunction(function () { console.log('agent id2 executed!'); });

// run agents
agency.runAgents();

Usage case #3

cascading agency with execution interruption

var ag = require('agency');

var agency = ag('l');

// log will be written to specified file;
// on error log will be written on default file [timestamp].log
agency.setLogFile('UsageCase#3.log');

// defines agent 'id1'
var agent = agency.createAgent('id1');
agent.setFunction(function () { console.log('agent id1 executed!'); });

// agent 'id2' will be executed after 'id1'
var agent2 = agency.createAgent('id2', 'id1');
agent2.setFunction(function () { console.log('agent id2 executed!'); });

// agent 'id3' will be executed after 'id2'
var agent3 = agency.createAgent('id3', 'id2');
agent3.setFunction(function () {
    var err = new Error('agent 3 error');
    console.log('agent id3 executed!');
    throw err;
});
agent3.setHaltExecution(true);

// agent 'id4' will not run because 'id3' error stopped the agency execution
var agent4 = agency.createAgent('id4', 'id3');
agent4.setFunction(function () { console.log('agent id4 executed!'); });

// run agents
agency.runAgents();

Usage case #4

inter agent communication

var ag = require('agency');

var agency = ag('v');

// defines agent 'id1'
var agent = agency.createAgent('id1');

agent.setFunction(function () {
    console.log('agent id1 executed!');
    return 10;
});

// agent 'id2' will be executed after 'id1'
var agent2 = agency.createAgent('id2', 'id1');

// agent 'id2' executes conditionally according to 'id1' result 
agent2.setFunction(function (inter) {
    var depResult = inter.getValueOfAgent('id1');
    var res;
    
    if (depResult instanceof Error) {
        return depResult;
    } else {
        res = 10 + depResult;
        console.log(res);
        return res;
    }
 
});

// defines a callback for agent 'id2' using the standard contract
agent2.setCallback(function (err, data) { 
    if (err) {
        console.log(err.message);
    } else {
        console.log('id2 callback executed: ' + data); 
    }
});

// run agents
agency.runAgents();

Usage case #5

deferred dependency checking

var ag = require('agency');

var agency = ag('q');

var agent1 = agency.createAgent('id1');
agent1.setFunction(function () { console.log('agent id1 executed'); });
agent1.setCallback(function () { console.log('agent id1 callback has executed!'); });

// runs only if agent id1 has not executed yet
var agent2 = agency.createAgent('id2', '!id1');
agent2.setFunction(function () { console.log('agent id2 executed!'); });
agent2.setCallback(function () { console.log('agent id2 callback has executed!'); });

// test with true or false values to observe different agency execution
// see API setDeffDepCheck section for explanation of flag
agent2.setDifDepCheck(true);

// run agents
agency.runAgents();

API

agency (mode)

object constructor, receives the log mode as optional parameter; 'q' represents quiet mode and doesn't report any activity; 'v' means verbose and outputs the creation and execution events to the console; 'l' stands for log mode and writes the events into the defined directory/file in JSON format; if the log directory/file is not defined, or cannot be written, a default log file with format timestamp.log will be created in the project directory

  • createAgent (id, expr)

    method used to create a new execution unit; the first parameter id is required and can contain alphanumeric charaters and the underscore; the second parameter is an optional logical expression defining the execution dependencies of the agent; all logical expressions containing the symbols '&&', '||', '!', '(', ')' are accepted; if no dependecies are defined, agents are executed by creation order

  • runAgents ()

    method that controls the execution of the agents, based on their current status and dependencies list; when all agents are executed reports the results; should be the last method called

  • setLogFile (fileName)

    sets the directory/file name of the log file

agent

created at agency level by the method createAgent(id, expr)

  • setFunction (function (o) { var agRes = o.getValueOfAgent('id'); })

    sets the code to be executed by the agent wrapped in a function; by default, the first parameter of the defined function receives an object o that allows the agent to get the result of any of its dependency agents (see usage case #4)

  • setFunction (function () { // your code here })

    optional call if there is no need for inter agent communication; code to execute is simply wrapped in a function

  • setCallback (function (err, data) {})

    defines an optional callback function; if the agent defines a callback function it will receive an error object if the agent function execution fails or the value returned by the agent function - only one of the parameters will be sent; executed after the agent function has completed (see usage case #4)

  • setCallback (function () { // your code here })

    optional definition of callback if the execution result of the function is not needed

  • setHaltExecution (flag)

    setting this flag to true (false by default) will cause the interruption of the agency execution if the agent execution fails (see usage case #3)

  • setDeffDepCheck (flag)

    setting this flag to true (false by default) will cause the agency to look not only for the executed state of each agent but also its waiting for execution state; executed state is set to true only when the agent has actually executed whereas the waiting for execution is set at creation time; decomposing usage case #5 steps:

    • flag is set to false
      • the agency will create agent 'id1' [call stack]
      • the agency will create agent 'id2' [call stack]
      • agency.runAgents() is called
      • agent 'id1' has not executed yet so it is queued for execution [placed on task queue]
      • agent 'id2' is dependent on 'id1' but since 'id1' has not executed yet it is also queued [task queue]
      • agent 'id1' is moved from the task queue to the call stack and executes
      • agent 'id2' is moved from the task queue to the call stack and executes
    • flag is set to true
      • the agency will create agent 'id1' [call stack]

      • the agency will create agent 'id2' [call stack]

      • agency.runAgents() is called

      • agent 'id1' has not executed yet so it is queued for execution [placed on task queue]

      • agent 'id2' is dependent on 'id1' and checks for its execution state (false), but also for its waiting for execution state; since it is true it will not queue it for execution

      • agent 'id1' is moved from the task queue to the call stack and executes

License

MIT