GithubHelp home page GithubHelp logo

vow's Introduction

Vow

Vow is a tiny library which allows you to handle promises more safely in your Bucklescript application.

A Vow can be either handled and unhandled. All promises of type vow 'a handled make sure that you handled Promise rejections. Thanks to that you will avoid the Uncaught promise error.

Installation

npm install --save @wokalski/vow

Then add vow to bs-dependencies in your bsconfig.json:

{
  ...
  "bs-dependencies": ["@wokalski/vow"]
}

Side effects

After series of operations you usually want to "consume" a promise. Vow.sideEffect should be used for that.

It only accepts promises which are properly handled.

Unwrapping

You can unwrap a handled promise using Vow.unwrap.

Nesting vows

Js.Promise.t is unsafe when you nest promises. i.e. Js.Promise.t (Js.Promise.t 'a) is unsound. In the runtime it's Js.Promise.t.

This is resolved with vows. If you nest vows they behave as expected.

However if you put a Js.Promise.t inside a vow (which are boxed Js.Promise.t under the scenes) you're gonna get a vow of the following type:

/* in Reason syntax */

vow (Js.Promise.t 'a) 'status

However, under the scenes it'll really be

vow 'a 'status

Therefore vow is not sound.

Binding

In order to use vows you have to bind to your existing APIs using Vow.wrap/Vow.unsafeWrap.

If you unsafeWrap a promise which does throw your code will be unsound.

Example

Let's see a real world example of vows with some comments:

let login _: Vow.Result.t authenticationState error Vow.handled =>
  /* Returns a handled Vow.Result.t */
  Login.logIn () |>
  /* Validates the returned value. Since the vow is handled we don't need to catch*/
  Vow.Result.flatMap (
    fun x =>
      if x##isCancelled {
        Vow.Result.fail LoginRequestCancelled
      } else {
        Vow.Result.return ()
      }
  ) |>
  /* Another handled Vow.Result.t */
  Vow.Result.flatMap Login.getCurrentAccessToken () |>
  Vow.Result.map (
    fun x => {
      let token = x##accessToken;
      /* This returns an unhandled Vow.Result.t.
       * Note that the 'error types have to match
       * Because after one error the subsequent operations
       * Are not performed.
       */
      Queries.login ::token
    }
  ) |>
  /* Ooops, the `Queries.login` might reject.
   * We are forced to handle it in the compile time.
   */
  Vow.Result.onError (fun _ => Vow.Result.fail GraphQlSignInError) |>
  Vow.Result.flatMap (
    fun x =>
      switch x {
      | Authenticated {token, userId} =>
        /* The promise we wrap is never rejected */
        Vow.unsafeWrap
          KeyChain.(
            Js.Promise.all2 (
              setGenericPassword username::"userId" password::userId service::"userId",
              setGenericPassword username::"token" password::token service::"token"
            )
          ) |>
        Vow.map (fun _ => Vow.Result.return x)
      | _ => Vow.Result.return x
      }
  );

Author

@wokalski

vow's People

Contributors

astrada avatar glennsl avatar johnhaley81 avatar lilactown avatar ncthbrt avatar wokalski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

vow's Issues

Example wrong?

In the example it shows using map and not flatMap which referencing the following code from the example:

Login.logIn () |>
  /* Validates the returned value. Since the vow is handled we don't need to catch*/
  Vow.Result.map (
    fun x =>
      if x##isCancelled {
        Vow.Result.fail LoginRequestCancelled
      } else {
        Vow.Result.return ()
      }
  )

returns a result of Vow.Result.t(Vow.Result.t('value, 'error, handled), 'error, handled).

Should this be flatMap to get Vow.Result.t('value, 'error', handled)?

Add `all` like functionality

Say you have multiple vows going in parallel. How would one bring them all back together into a single vow?

In promises you would do something like Js.Promise.all2((promise1, promise2)) |> then_((promise1Resolve, promise2Resolve) => /* do something with both promises */ resolve())

With vows I'm unwrapping all the way down to promises and then wrapping back up. Is there a better way or does this need all like functionality?

Thanks for everything :)

Compatibility with bs-platform 3.0.0

I ran into this error after upgrading bs-platform to 3.0.0

Warning: refmt version missing. Please set it explicitly, since we may change the default in the future.
[1/4] Building src/vow.mliast
FAILED: src/vow.mliast
/Users/kyle/git-projects/hashback/model-trainer/node_modules/bs-platform/lib/bsc.exe -pp "/Users/kyle/git-projects/hashback/model-trainer/node_modules/bs-platform/lib/refmt.exe --print binary"   -w -30-40+6+7+27+32..39+44+45+101 -nostdlib -I '/Users/kyle/git-projects/hashback/model-trainer/node_modules/bs-platform/lib/ocaml' -bs-super-errors -no-alias-deps -color always  -c -o src/vow.mliast -bs-syntax-only -bs-binary-ast -intf '/Users/kyle/git-projects/hashback/model-trainer/node_modules/@wokalski/vow/src/vow.rei'
File "/Users/kyle/git-projects/hashback/model-trainer/node_modules/@wokalski/vow/src/vow.rei", line 5, characters 7-8:
Error: 1150: syntax error, consider adding a `;' before

  We've found a bug for you!
  /Users/kyle/git-projects/hashback/model-trainer/node_modules/@wokalski/vow/src/vow.rei

  There's been an error running Reason's refmt parser on a file.
  This was the command:

  /Users/kyle/git-projects/hashback/model-trainer/node_modules/bs-platform/lib/refmt.exe --print binary '/Users/kyle/git-projects/hashback/model-trainer/node_modules/@wokalski/vow/src/vow.rei' > /var/folders/zv/b87pssd55kbfnnhzjxz7zn0w0000gn/T/ocamlpp01eeb5

  Please file an issue on github.com/facebook/reason. Thanks!

I'm not sure if this is a problem with vow or with reason but I figured I'd let you know

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.