Introducing `purescript-node-execa`

I ported the execa Node.js library to PureScript: GitHub - JordanMartinez/purescript-node-execa

It’s not fully tested yet, so feel free to open bugs. However, it does provide better and easier-to-use bindings than node-child-process.

11 Likes

Hey there! Great job on translating the execa library from Node.js to PureScript. I noticed that you didn’t include the asynchronous module, is there a reason for that? Just curious!

I’m not sure what you mean by “the asynchronous module”. Could you clarify?

sorry, I see, execa provides the asynchronous behavior you need to run shell commands without blocking the rest of your code, so you do not need an additional “Asynch” module.

I wonder why not build the thing on top of existing node api binding (node-child-process, buffer, stream), without relying on FFI? Considering that you may introduce the updates needed for those bindings without much hassle.

There’s a few reasons:

First, the child_process module is difficult to write bindings for. Its main APIs have “syntax sugar” in a number of places that make bindings difficult. Its current bindings in node-child-process are also incomplete/incorrect in a few areas. I attempted to exhaustively implement all of its bindings here: Exhaustively cover the `child_process` module by JordanMartinez · Pull Request #39 · purescript-node/purescript-node-child-process · GitHub

Second, when writing these bindings, should one write bindings for this module that use phantom types (my PR above) to ensure type safety or should no such types be used, allowing that to be done by some higher-level library? Is the higher complexity of phantom types worth the additional type safety? Some would say no while others would say yes. Alternatively, I could forego some of the “syntax sugar” allowed by the API, write bindings to a subset of the API, and implement “syntax sugar” on top of that subset. This alternative approach is what I did in the node-execa library.

But whatever approach taken for the bindings, getting the resulting PR merged into node-child-process requires an approval. Who’s going to spend the needed amount of time to first understand this complex module’s docs and then verify that what I’ve done is correct? By publishing this as a separate library I control, I don’t have to wait on anyone.

As for usage, using just the bindings (whatever they may be) doesn’t fix the numerous issues that can occur. Lots of things can go wrong on Windows, and some of these are not very obvious as well. See the execa, cross-spawn, and signal-exit closed issues. I imagine most people just want to run a child process, ensure it works, and not care about the details.

Other than that, I did build on top of bindings provided via node-process, node-buffer, and node-stream unless execa or one of its dependencies used code for which such libraries do not provide bindings. In that instance, I wrote the FFI I needed to get the code to work.

1 Like

I understand, but eventually it is still a good motivation to make better and more complete node bindings.

What would be “better and more complete node bindings” be? More complete is obvious, but what would “better” be?

The more complete and actual is better :slightly_smiling_face:

I don’t understand your response.

I mean, it is still better (for the future) to extend the node bindings so execa pkg could be written without FFI.