1.4.1 • Published 6 years ago

bs-callback v1.4.1

Weekly downloads
2
License
BSD-2-Clause
Repository
github
Last release
6 years ago

bs-callback

This module provides a Monadic API for callback computations in BuckleScript applications, as described in this article.

Installation

npm install [--save] bs-callback

Then add it to your bsconfig.json:

  ...
  "bs-dependencies" : [
    "bs-callback",
    ...
    ],
  ...

Rationale

Monadic computations are handy to write code that handles asynchronous errors and results in a composable fashion without having to repeat the same patterns again. For instance, from the examples/ section:

module Fs : sig
  type fd
  val fopen  : string -> fd BsCallback.t
  val unlink : string -> unit BsCallback.t
end

(* Pipe two asynchronous computations: *)
let unlink_if_fopen path =
  (Fs.fopen path) >> fun _ ->
    Fs.unlink path

Here, errors raised during the first call are immediately passed to the final callback without having to repeatedly write that pattern over and over.

This is similar to the Promise API but with less overhead and a focus on composability.

The API is as follows:

(* BsCallback type. Strict arity is enforced here. *)
type error  = exn Js.Nullable.t
type 'a callback = error -> 'a -> unit [@bs]

(* A asynchronous computation takes a callback and executes it when it
   has finished, either with an error or with a result of type 'a. *)
type 'a t = 'a callback -> unit

(* A computation that returns a result of type 'a. *)
val return : 'a -> 'a t

(* A computation that returns an error. *)
val fail : exn -> 'a t

(* Combine two computations.
 * Operates on a constant call stack if [noStack] is true
 * with the drawback that no call trace will be returned
 * in case of error. Default: [false] *)
val compose : ?noStack:bool -> 'a t -> ('a -> 'b t) -> 'b t
val (>>)    : 'a t -> ('a -> 'b t) -> 'b t

(* Catch errors raised during a computation. *)
val catch  : ?noStack:bool -> 'a t -> (exn -> 'a t) -> 'a t
val (||>)  : 'a t -> (exn -> 'a t) -> 'a t

(* Pipe a result through a function. Equivalent to:
 * [computation >> fun v -> return (fn v)] *)
val pipe : ?noStack:bool -> 'a t -> ('a -> 'b) -> 'b t
val (>|) : 'a t -> ('a -> 'b) -> 'b t

(* Execute a callback regardless of success or failure.
 * Errors raised by the [unit t] computation are discared. *)
val ensure : ?noStack:bool -> 'a t -> (unit -> unit t) -> 'a t
val (&>)   : 'a t -> (unit -> unit t) -> 'a t

(* Discard a computation's result. *)
val discard : 'a t -> unit t

(* Repeat a computation. Tail-recursive. *)
val repeat : (unit -> bool t) -> (unit -> unit t) -> unit t

(* In the following [concurrency] refers to the number
 * of concurrent executions. It is meant as in the node
 * model of concurrency, i.e. JS code is always non-concurrent
 * but e.g. HTTP Get calls can be queued via the event loop. *)

(* Fold over a list or array of elements. Tail-recursive.
 * Result order will be shuffled when using concurrency > 1. *)
val fold_lefta : ?concurrency:int -> ('a -> 'b -> 'a t) -> 'a t -> 'b array -> 'a t
val fold_left  : ?concurrency:int -> ('a -> 'b -> 'a t) -> 'a t -> 'b list -> 'a t
val fold_lefti : ?concurrency:int -> ('a -> int -> 'b -> 'a t) -> 'a t -> 'b list -> 'a t

(* Iter over a list or array of computations. Tail-recursive.
 * Execution order will be shuffled when using concurrency > 1. *)
val itera  : ?concurrency:int -> ('a -> unit t) -> 'a array -> unit t
val iter   : ?concurrency:int -> ('a -> unit t) -> 'a list -> unit t
val iteri  : ?concurrency:int -> (int -> 'a -> unit t) -> 'a list -> unit t

(* Map results. Tail-recursive.
 * Result order will be shuffled when using concurrency > 1. *)
val mapa : ?concurrency:int -> ('a -> 'b t) -> 'a array -> 'b array t
val map  : ?concurrency:int -> ('a -> 'b t) -> 'a list -> 'b list t
val mapi : ?concurrency:int -> (int -> 'a -> 'b t) -> 'a list -> 'b list t

(* Execute a sequence of computations.
 * Execution order will be shuffled when using concurrency > 1. *)
val seqa : ?concurrency:int -> unit t array -> unit t
val seq  : ?concurrency:int -> unit t list -> unit t

(* Execute a computation and pass its result to a callback.
 * Default [exceptionHandler] raises any received exception. *)
val execute : ?exceptionHandler:(exn->unit) -> 'a t -> ('a -> unit) -> unit
val finish  : ?exceptionHandler:(exn->unit) -> unit t -> unit

(* Interface with Promise API. *)
val from_promise : 'a Js.Promise.t -> 'a t
val to_promise   : 'a t -> 'a Js.Promise.t
1.4.1

6 years ago

1.4.0

6 years ago

1.3.6

6 years ago

1.3.5

6 years ago

1.3.4

6 years ago

1.3.3

6 years ago

1.3.2

6 years ago

1.3.1

6 years ago

1.3.0

6 years ago

1.2.9

6 years ago

1.2.8

6 years ago

1.2.7

6 years ago

1.2.6

6 years ago

1.2.5

6 years ago

1.2.4

6 years ago

1.2.3

6 years ago

1.2.2

6 years ago

1.2.1

6 years ago

1.2.0

6 years ago

1.1.0

6 years ago

1.0.16

6 years ago

1.0.15

6 years ago

1.0.14

6 years ago

1.0.13

6 years ago

1.0.12

6 years ago

1.0.11

6 years ago

1.0.10

6 years ago

1.0.9

6 years ago

1.0.8

6 years ago

1.0.7

6 years ago

1.0.6

6 years ago

1.0.5

6 years ago

1.0.4

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago