Hello everyone!
For the past few weeks, we have been working hard on a proposal for replacing the original Js.Promise
bindings that are currently shipped within the ReScript compiler, and we think we finally settled on a design we are happy with to share with the broader community.
Installation
We ship our new bindings as a third party npm package to be able to collect more feedback from our production users to see if the binding is practical enough to be considered as a Js.Promise
replacement.
The bindings can be installed alongside your existing Js.Promise
code.
npm install @ryyppy/rescript-promise --save
Don’t forget to update your bsconfig.json
as well:
{
"bs-dependencies": ["@ryyppy/rescript-promise"]
}
The new bindings are globally accessible via the Promise
module.
The source code and issue tracker can be found here: github.com/ryyppy/rescript-promise.
Proposal Document & Examples
The rationale and decision making for the new APIs can be found in our PROPOSAL.md document.
Here is a quick usage example (more examples can be found in the README as well):
type user = {"name": string}
type comment = string
@val external queryComments: string => Js.Promise.t<array<comment>> = "API.queryComments"
@val external queryUser: string => Js.Promise.t<user> = "API.queryUser"
open Promise
queryUser("patrick")
->then(user => {
// We use `then` instead of `map` to automatically
// unnest our queryComments promise
queryComments(user["name"])
})
->map(comments => {
// comments is now an array<comment>
Belt.Array.forEach(comments, comment => Js.log(comment))
})
->ignore
The repository also comes with an examples
directory for more thorough “real world scenarios”, such as using and chaining some fetch promises.
The Proposal Process
We are convinced that our solution is hitting the right spot of being practical enough, while yielding efficient and idiomatic JS code without introducing too much complexity on the type level.
I’d ask everyone in the community to install / vendor our new Promise bindings, use all the proposed features and give us feedback in the rescript-promise issue tracker.
We’ve set a first review deadline of 2 months (until 2021-03-30T22:00:00Z), where we’ll assess if the bindings are acceptable to be shipped as a core binding. If there’s any deal-breaking issues, we will postpone the deadline and repeat the feedback loop if necessary.
Feedback Format
Please make sure to provide real-world use-cases from your actual app code to give proper context on potential problems. Our main goal is to stay JS runtime free, and also to stay close to JS API semantics.
Even though the final library looks pretty minimalistic, it took as several iterations to consider different solutions (some with runtime overhead, some without, etc). The simplest solution turned out to be the most practical for us, so we are happy that we don’t need to introduce a bunch of extra JS runtime code, just to be able to interact with promises efficiently.
We hope you like it!