Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added automatic promisification of NodeJS style functions #36

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

hexonaut
Copy link

@hexonaut hexonaut commented Oct 2, 2014

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:

  • I tried to put the NodeTools in the js.promhx package, but I get js package unavailable errors from the macro context. You may want to consider renaming this directory for consistancy.
  • If a function signature has more than one return type in the callback then the promise will return an array of values typed as Array.
  • Untyped functions work as well. They will just require using reflection and the JS arguments parameter.

@jdonaldson
Copy link
Owner

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
Copy link
Author

hexonaut commented Oct 4, 2014

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
Copy link
Author

hexonaut commented Oct 4, 2014

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
Copy link
Author

hexonaut commented Oct 9, 2014

Will be adding overload support pending this issue getting implemented HaxeFoundation/haxe#3460

@hexonaut
Copy link
Author

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
Copy link
Owner

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

@hexonaut
Copy link
Author

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

@dionjwa
Copy link
Contributor

dionjwa commented Oct 6, 2015

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

@hexonaut
Copy link
Author

hexonaut commented Oct 6, 2015

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
Copy link
Owner

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
Copy link
Author

hexonaut commented Nov 3, 2015

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
Copy link
Owner

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants