jdonaldson / promhx

A promise and functional reactive programming library for Haxe
MIT License
146 stars 24 forks source link

Added automatic promisification of NodeJS style functions #36

Open hexonaut opened 10 years ago

hexonaut commented 10 years ago

This addition is a starting point for automatically "promisifying" NodeJS style functions using macros. This is similar to the way it is done in the popular bluebird promise library for JS: https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

Without getting into details this will convert a function with signature of the form:

function (a1:Type1, a2:Type2, ..., callbackFunc:String -> SomeType):Void;

into:

function (a1:Type1, a2:Type2, ...):Promise<SomeType>;

Here is an example with node fs using the https://github.com/dionjwa/nodejs-std externs library:

var readFile = promhx.js.NodeTools.promisify(cast(Node.require("fs"), js.Node.NodeFS).readFile);
readFile("someFile.txt", { encoding:'utf8' } ).then(function (data) {
    trace(data);
});

I also included a build function which will scan through a definition file (such as the ones included in the above library) and build all the fields that can be promisified.

@:build(promhx.js.NodeTools.autoPromisify("js.Node.NodeFS", "fs"))
class NodeFSProm {
}

// Somewhere else in the code
NodeFSProm.readFile("someFile.txt", { encoding:'utf8' } ).then(function (data) {
    trace(data);
});

Some notes:

jdonaldson commented 10 years ago

I only see a few issues, it would be nice to keep the argument types in multi-argument callbacks. I'll have to see if it's possible to coerce those into a an anonymous object.

Also, I see what you mean by the namespace issue. I'll check that out as well. If I have to break the api, I'd want to change the version. I'm not quite ready to do that yet though... so I hope to avoid it.

I won't have a ton of time this weekend (family wedding!), but I'll check this out in more detail when I get back.

hexonaut commented 10 years ago

Yeah I was thinking of the function overloading. There seems to be a lot of it in node, and I couldn't really come up with a solution off the top of my head.

If you are worried about breaking the API you could temporarily typedef the classes in the js.promhx package.

hexonaut commented 10 years ago

I've been thinking about the macro build feature some more, and I think it might be worthwhile to have a Node package pre-built with all callback-style functions converted to promise-style using the build macro. Perhaps this could be a separate library, or if you are open to it I could merge this into promhx.

Just thinking it would be nice to be able to start using Haxe/Node with promhx and have promises working right out of the box under some package for example "promhx.node.Fs", etc.

What do you think?

EDIT

Now that there is a standard NodeJS library (https://github.com/HaxeFoundation/hxnodejs) I could automatically generate promise based externs for all js.node.* externs. Not entirely decided on the naming scheme though. Maybe a js.node.promhx.* subpackage or put them side by side with "Prom" appended? Thoughts?

hexonaut commented 10 years ago

Will be adding overload support pending this issue getting implemented https://github.com/HaxeFoundation/haxe/issues/3460

hexonaut commented 10 years ago

I've switched the implementation to automatically promisify the entire NodeJS package with the command line macro --macro promhx.js.NodeTools.promisifyPackage('js.node', 'js.pnode'). Still waiting on the Haxe commit before overloads are implemented.

jdonaldson commented 10 years ago

Thanks for the updates, was there an ETA on the haxe commit?

hexonaut commented 10 years ago

Not that I know of. I wouldn't mind implementing it myself, but I am very unfamiliar with the compiler.

dionjwa commented 9 years ago

Big +1 here. Can I help with this? This would save so much boilerplate code.

hexonaut commented 9 years ago

The big thing missing from this is operator overloading support which was missing from Haxe macros at the time. It has since been added, but I haven't got around to adding support. If you wanted you could add that support.

Other than that the promisification works fine. I use it in my own projects.

jdonaldson commented 9 years ago

I agree... I really want to add this into a v2, but it will take some thought and I'm working on something else that is taking all of my bandwidth. How much of an impact will this have for you?

hexonaut commented 9 years ago

I haven't had a chance to look at this again since the introduction of overload access in macros. No guarantees, but I'll try to get to this when I get some time. Do you have an estimate for when you want to release v2?

jdonaldson commented 8 years ago

FWIW, I'm in the midst of rewriting promhx to take advantage of the new haxe macro/syntax idioms....