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

uchain

v0.17.0

Published

A set of utilities for chaining asynchronous functions

Downloads

55

Readme

uchain

A tiny library for chaining functions asynchronously.

  let chain = InSeries(
    InParallel(
      (next, a, b) => next(null, a + b),
      (next, a, b) => next(null, a - b),
    ),
    (next, [ sum ], [ difference ]) => next(null, sum * difference),
    (next, result) => console.log('asynchronous math', result)
  );

  chain(null, 1, 2); // prints out -3, eventually

Links in the chain

There are two function signatures expected by uchain. Every 'task' in the chain takes in a next function, and then any number of arguments.

function (next, ...args) {...}

Every 'next' function is a callback, that takes in an error parameter, and then any number of results; These results are passed to the next link in the chain.

function (err, ...results) {...}

The utilities provided in the library generate next functions to bind your tasks together asynchronously.

API

Objects

Typedefs

uchain : object

Kind: global namespace


uchain.FromPromise ⇒ taskFunction

  let chain = InSeries(
    function(next, ...args) {...},
    FromPromise(
      (...args) => new Promise((resolve, reject) => resolve(...args))
    ),
    function(next, ...args) {},
    ...
  );

  chain(next, ...args);

Alias for PromiseWrapper Wraps around a promise generator function, to make it easier to integrate with task functions.

Kind: static constant of uchain
Returns: taskFunction - a task that wraps around the promise

| Param | Type | Description | | --- | --- | --- | | generator | function | a function that generates a promise from the args. |


uchain.ToPromise ⇒ function


  let chain = InSeries(
    function(next, ...args) {...},
    function(next, ...args) {...},
    ...
  );

 new Promise()
   .then(
     ToPromise(chain)
   );

Alias for Promisify

Wraps around a task function and greates a promise generator, to make it easier to integrate task functions and promises.

NOTE: uchain does not come bundled with a promise library, it expects Promise to already exists in the global namespace.

NOTE: because uchain can 'return' multiple values through the next callback, Promisify always resolves to an array of the results returned.

Kind: static constant of uchain
Returns: function - a function that generates a Promise when called

| Param | Type | Description | | --- | --- | --- | | task | function | a function that generates a promise from the args. |


uchain.Assert(validator, message) ⇒ taskFunction

Builds an async assertion task. When called, if the arguments do not match the validator functions, Assert passes an error to its callback.

Kind: static method of uchain
Returns: taskFunction - an assertion task

| Param | Type | Description | | --- | --- | --- | | validator | function | a function that checks the arguments. | | message | string | an optional error message to throw if the assertion fails, or a message builder function. |


uchain.CatchError(task) ⇒ taskFunction

Errors bypass the normal flow of execution. They're always returned to the last link in the chain, even if they occur inside nested InSeries or InParallel chains.

  let chain = InSeries(
    (next) => { console.log(1); next(); }
    InSeries(
      (next) => { console.log(2); next(); }
      (next) => { console.log(3); next('Error'); }
    ),
    InSeries(
      (next) => { console.log(4); next();}
      (next) => { console.log(5); next();}
    )
  )(console.log); // prints out 1 2 3 Error, eventually

If you need to catch an error explicitly at some point, wrap a chain in CatchError, which will return the error as the first argument to the next function.

  let chain = InSeries(
    (next) => { console.log(1); next();}
    CatchError(
      InSeries(
        (next) => { console.log(2); next();}
        (next) => { console.log(3); next('Error');}
      ),
    ),
    (next, error) => error != null ? console.log('Error Caught') : null,
    InSeries(
      (next) => { console.log(4); next();}
      (next) => { console.log(5); next();}
    )
  )(console.log); // prints out 1 2 3 Error Caught 4 5, eventually

Kind: static method of uchain
Returns: taskFunction - a wrapper function around the task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | a function that checks the arguments. |


uchain.If(conditionTask, thenTask, elseTask) ⇒ taskFunction

  let task = If(
    function(next, ...args) {},
    function(next, ...args) {},
    function(next, ...args) {}
  );

  chain(next, ...args);

If accepts up to three tasks and returns a task that conditionally executes some.

  let logIfEven = If(
    (next, num) => next(null, num % 2 === 0)
    (next, num) => { console.log('is even!'); next(null, num); },
    (next, num) => { console.log('is not even!'); next(null, num); },
  );

  let onDone = (err, ...results) => console.log(results);

  logIfEven(null, 1); // prints out 'is not even!' eventually
  logIfEven(null, 2); // prints out 'is even!' eventually

note: by default, the conditionTask, thenTask, and elseTask are all set to PassThrough note: the conditionTask can return multiple results, but only the first is checked for truthiness

Kind: static method of uchain

| Param | Type | Description | | --- | --- | --- | | conditionTask | taskFunction | a condition task. | | thenTask | taskFunction | a task to run if the condition returns a truthy value. | | elseTask | taskFunction | a task to run if the condition returns a falsy value. |


uchain.InOrder(...tasks) ⇒ taskFunction

  let chain = InOrder(
    function(next, ...args) {},
    function(next, ...args) {},
    ...
  );

  chain(next, ...args);

Runs several asynchronous tasks one after another. Each task gets the arguments that were originally passed into the wrapper. This is different from InSeries, where the output of each is task is passed as the input to the next.

  let chain = InOrder(
    (next, a) => { a.val = 1; console.log(a.val); next();}
    (next) => { a.val = 2; console.log(a.val); next();}
    (next) => { a.val = 3; console.log(a.val); next();}
  )(null, {}); // prints out 1 2 3, eventually

Kind: static method of uchain
Returns: taskFunction - a wrapper function that runs the tasks in order

| Param | Type | Description | | --- | --- | --- | | ...tasks | taskFunction | any number of tasks to run in order. |


uchain.InParallel(...tasks) ⇒ taskFunction

  let chain = InParallel(
    function(next, ...args) {},
    function(next, ...args) {},
    ...
  );

  chain(next, ...args);

InParallel accepts a number of functions, and returns a task function that executes all of its child tasks in parallel.

  let chain = InParallel(
    (next) => next(null, 1),
    (next) => next(null, 2),
    (next) => next(null, 3, 4),
  );

  let onDone = (err, ...results) => console.log(results);

  chain(onDone); // prints out [ 1 ] [ 2 ] [ 3, 4 ], eventually

note: because the callbacks can return any number of results, the results from each task are autoboxed into an array. This includes an empty array for tasks that don't return results.

Kind: static method of uchain
Returns: taskFunction - a wrapper function that runs the tasks in parallel

| Param | Type | Description | | --- | --- | --- | | ...tasks | taskFunction | any number of tasks to run in parallel. |


uchain.InSeries(...tasks) ⇒ taskFunction

  let chain = InSeries(
    function(next, ...args) {},
    function(next, ...args) {},
    ...
  );

  chain(next, ...args);

Runs several tasks in series, and passes the results from one down to the next. This works similarly to the 'waterfall' method in caolan's async.

  let chain = InSeries(
    (next) => { console.log(1); next();}
    InSeries(
      (next) => { console.log(2); next();}
      (next) => { console.log(3); next();}
    ),
    InSeries(
      (next) => { console.log(4); next();}
      (next) => { console.log(5); next();}
    )
  )(); // prints out 1 2 3 4 5, eventually

Kind: static method of uchain
Returns: taskFunction - a wrapper function that runs the tasks in series

| Param | Type | Description | | --- | --- | --- | | ...tasks | taskFunction | any number of tasks to run in series. |


uchain.Logging(...statements) ⇒ taskFunction

A logging utility. It passes the arguments received into all the statements, collects the results, and joins them together with newlines to build the final log statement

Kind: static method of uchain
Returns: taskFunction - a logging task

| Param | Type | Description | | --- | --- | --- | | ...statements | string | stringBuilder | any number of strings, or string builder functions |


uchain.ParallelFilter(filter) ⇒ taskFunction

Builds a task that filters all of its arguments in parallel, and returns the results

Kind: static method of uchain
Returns: taskFunction - a filtering task

| Param | Type | Description | | --- | --- | --- | | filter | taskFunction | an asynchronous filter function that returns true or false through its callback. |


uchain.ParallelForEach(task) ⇒ taskFunction

Builds a task wrapper that calls a task once on each of its arguments in parallel

Kind: static method of uchain
Returns: taskFunction - a parallel foreach task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | an asynchronous function that gets called once on each argument. |


uchain.ParallelMap(task) ⇒ taskFunction

Builds a task wrapper that asynchronously maps each of its arguments to a result. Note: even though the mapping function can return any number of results, ParallelMap only uses the first result

Kind: static method of uchain
Returns: taskFunction - a parallel map task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | an asynchronous mapping function. |


uchain.ParallelObjectFilter(task) ⇒ taskFunction

Similar to ParallelFilter, but instead of running on an array of arguments, it runs a filter on every key-value pair in an object.

Kind: static method of uchain
Returns: taskFunction - a parallel filter task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | an asynchronous filter function. |


uchain.ParallelObjectMap(task) ⇒ taskFunction

Similar to ParallelMap, but instead of running on an array of arguments, it runs a filter on every key-value pair in an object.

Kind: static method of uchain
Returns: taskFunction - a parallel map task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | an asynchronous map function. |


uchain.PassThrough()

Sometimes, you need to pass previous arguments along with a new result. The easiest way to do this is to use PassThrough, which is a convenience method for:

 (next, ...args) => next(null, ...args),

Kind: static method of uchain


uchain.PromiseWrapper(generator) ⇒ taskFunction

  let chain = InSeries(
    function(next, ...args) {...},
    PromiseWrapper(
      (...args) => new Promise((resolve, reject) => resolve(...args))
    ),
    function(next, ...args) {},
    ...
  );

  chain(next, ...args);

Wraps around a promise generator function, to make it easier to integrate with task functions.

Kind: static method of uchain
Returns: taskFunction - a task that wraps around the promise

| Param | Type | Description | | --- | --- | --- | | generator | function | a function that generates a promise from the args. |


uchain.Promisify(task) ⇒ function


  let chain = InSeries(
    function(next, ...args) {...},
    function(next, ...args) {...},
    ...
  );

 new Promise()
   .then(
     Promisify(chain)
   );

Wraps around a task function and greates a promise generator, to make it easier to integrate task functions and promises.

NOTE: uchain does not come bundled with a promise library, it expects Promise to already exists in the global namespace.

NOTE: because uchain can 'return' multiple values through the next callback, Promisify always resolves to an array of the results returned.

Kind: static method of uchain
Returns: function - a function that generates a Promise when called

| Param | Type | Description | | --- | --- | --- | | task | function | a function that generates a promise from the args. |


uchain.Race(...tasks) ⇒ taskFunction

  let chain = Race(
    function(next, ...args) {},
    function(next, ...args) {},
    ...
  );

  chain(next, ...args);

Race accepts a number of functions, and returns a task function that executes all of its child tasks simultaneously. The first result (or error) is returned, and the remaining results (or errors) are ignored.

  let chain = Race(
    (next) => next(null, 1),
    (next) => setTimeout(next, 100, null, 2),
    (next) => { throw new Error(); } ,
  );

  let onDone = (err, ...results) => console.log(results);

  chain(onDone); // prints out [ 1 ], eventually

Kind: static method of uchain
Returns: taskFunction - a task

| Param | Type | Description | | --- | --- | --- | | ...tasks | taskFunction | any number of tasks to run in parallel. |


uchain.Retry(task, options) ⇒ taskFunction

Wraps a task and attempts to retry if it throws an error, with an exponential backoff.

Kind: static method of uchain
Returns: taskFunction - a task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | the task to wrap. | | options | object | an optional set of retry options. | | options.timeout | object | maximum time to attempt retries. | | options.retries | object | maximum number of retries to attempt. |


uchain.Throttle(task, limit) ⇒ taskFunction

Wraps a task and ensures that only X number of instances of the task can be run in parallel. Requests are queued up in an unbounded FIFO queue until they can be run.

Kind: static method of uchain
Returns: taskFunction - a task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | the task to throttle | | limit | number | the number of instances that can run in parallel. default 1. |


uchain.TimeIn(task, ms) ⇒ taskFunction

  let chain = TimeIn(
    function(next, ...args) {},
			1000
  );

  chain(next, ...args);

TimeIn wraps a single task function, and returns a function that only returns after X ms.

Kind: static method of uchain
Returns: taskFunction - a task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | the task to wrap in a timeout. | | ms | number | the timein in ms. |


uchain.TimeOut(task, ms) ⇒ taskFunction

  let chain = TimeOut(
    function(next, ...args) {},
			1000
  );

  chain(next, ...args);

TimeOut wraps a single task function, and returns a function that returns early if the task fails to complete before the timeout triggers.

NOTE: no error is thrown on a timeout, the result is merely undefined.

NOTE: the timeout being triggered will not cancel the original task.

Kind: static method of uchain
Returns: taskFunction - a task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | the task to wrap in a timeout. | | ms | number | the timeout in ms. |


uchain.Timer(task, label) ⇒ taskFunction

Wraps a task and logs how long it takes to finish, or fail.

Kind: static method of uchain
Returns: taskFunction - a task

| Param | Type | Description | | --- | --- | --- | | task | taskFunction | the task to wrap. | | label | string | an optional label to log. |


uchain.While(conditionTask, loopTask) ⇒ taskFunction

  let task = While(
    function(next, ...args) {},
    function(next, ...args) {},
  );

  chain(next, ...args);

While accepts two tasks and returns a task that conditionally executes some.

  let incUntil10 = While(
    (next, num) => next(null, num < 10),
    (next, num) => { console.log('num', nul); next(null, num + 1); },
  );

  let onDone = (err, ...results) => console.log(results);

  incUntil10(null, 1); // prints 1, 2, ... 9

note: the results of the loop task are saved to pass into the conditionTask, and the loopTask note: when the condition task returns false, those results are passed down the chain

Kind: static method of uchain

| Param | Type | Description | | --- | --- | --- | | conditionTask | taskFunction | a condition task. | | loopTask | taskFunction | a task to run if the condition returns a truthy value. |


nextFunction : function

An async callback function.

Kind: global typedef

| Param | Type | | --- | --- | | err | error | | ...results | * |


taskFunction : function

An async task function.

Kind: global typedef

| Param | Type | | --- | --- | | next | nextFunction | | ...args | * |


stringBuilder ⇒ string

A string building function.

Kind: global typedef
Returns: string - the string

| Param | Type | | --- | --- | | ...args | * |