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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@stroiman/async

v0.7.0

Published

Async support library for Reason/Bucklescript

Readme

Reason module for Async

Helper for async Reason/Bucklescript code without Promises.

Attention - The NPM package has moved to @stroiman/async. Remember to update both package.json AND bsconfig.json.

Build Status

I wrote this library because I needed to deal with async code, but I wanted to avoid using promises in order to keep the core of my application javascript agnostic.

Installation

Run npm install --save @stroiman/async and add @stroiman/async to the bs-dependencies in bsconfig.json.

Documentation

The heart of this module is the type:

Reason syntax:

module Async = {
  type t('a) = (('a => unit, exn => unit)) => unit;
}

OCaml syntax:

type 'a t = (('a -> unit) * (exn -> unit)) -> unit

So, it's a function that takes two callbacks, one that will be executed if an operation succeeds, and one that will be executed if an exception is thrown.

So if you have such a function, you can use this library to glue functions together that operate asynchronously.

If the last argument of your async function conforms to this signature, then you can use currying to compose functions together with this library.

Useful funcitons.

  • bind Takes a function that returns an async result and use it in an existing async context.
  • map Takes a function that returns a sync result, and use it in an async context.
  • return Takes a value, and returns an async context resolving that value. In a promise context, this would correspond to Promise.resolve
  • tryCatch Takes a function that might handle an exception. Return Some if the exception was handled, and None if it wasn't.
  • timeout Helps handling handling functions that take too long to execute
  • run(~fe=?,f) Takes a callback to be called with the final value, and an optional callback to be called with any exceptions caught during execution.
  • from_js Helps creating an Async.t from an async javascript function. See exmaple later
  • once Takes something that resolves asynchronously, and allow it to be called multiple times, each time yielding the same result. A database connection pool factory is a good candidate.

Be aware that this library does not evaluate any values in advance. Nothing is evaluated until you call the run function.

Look at the example tests for a hint as to their usage.

Only use the exception path for truly exceptional cases.

It is a common pattern to use a result type, like this (defined in Js.Result).

type result('a,'b) =
  | Ok('a)
  | Error('b)

This library does not attempt to replace this pattern, This type can still be used with the async module:

type asyncResult('a,'b) = Async.t(result('a,'b));

This is used a lot in my own code, and exceptions are only used to handle truly exceptional cases, that will result in HTTP 500 errors - e.g. broken database connections, etc. Any error that can be handled in the application layer is represented with the Error() constructor.

Using with async JavaScript modules

A common pattern in JavaScript is to have a function accept a callback that accepts two arguments, an error and a result. The error argument will receive null if the operation succeeded.

This library supports handling this case easily. This small adaption of the bcryptjs module shows how:

module Bcrypt = {
  type error = Js.Exn.t;
  [@bs.module "bcryptjs"]
  external hash : (string, int, (Js.null(error), string) => unit) => unit = "";
  [@bs.module "bcryptjs"]
  external compare : (string, string, (Js.null(error), Js.boolean) => unit) => unit = "";

  let hash = (password, gen) => hash(password,gen)
    |> Async.from_js;
  let compare = (password, hash) => compare(password, hash)
    |> Async.from_js |> Async.map(Js.to_bool);
}