creationix / js-git

A JavaScript implementation of Git.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support promises and continuables in public APIs

creationix opened this issue · comments

The plan is to make the returned continuables also act like promises somehow, but not depending on a promise library. This will assume window.Promise exists and implements ES6 promises.

It'd still be nice imo to fall back to a shim.

@ljharb what do you mean?

If you rely on the existence of window.Promise, then only ES6 environments, or user-shimmed environments, will be able to benefit from the Promise API.

If instead you provide a Promise shim when a global implementation is unavailable, more environments (more people) will be able to benefit from the Promise API, which will then make them forwards-compatible as well :-)

I see. I really feel this is backwards though. If you want to consume js-git using ES6 promises, you have promises and already have the polyfill. If you want to consume js-git using node callbacks or continuables, then you don't want the bloat of a 2k minified polyfill included.

In other words. I'm willing to make js-git play nice in a promise environment, but it's outside the scope of js-git to provide such an environment if it doesn't exist already.

If I may pitch in:

Some libraries allow users to pass their own promise constructor, or else fall back to a global defined Promise (or else bail with an error). So they don't ship any implementation at all.

This means user can pick either a light shim or a heavy implementation like bluebird, but without Promise.cast() etc.

@Bartvds that's essentially what I'm doing. I'm just using window.Promise as the entry point to pass in the promise implementation. I don't see this as an issue since I'm only planning to support ES6's Promise API. Is there ever a case where a user would have window.Promise but want to use a different Promise constructor in js-git?

@creationix Using window.Promise is similar, but not quite the same as passing it in a call: global vars have a way of becoming problematic.

Simplest example: if you have an application with one module overwriting the global Promise with bluebird and another module who sets it to Q and then rely on their respective methods.

It is probably a bad idea to assume non-spec features about promises returned from a external module unless you can explicitly pass a constructor; any module might return an internal shim even with a global override set.

@creationix a spec-compliant polyfill is tiny. See https://github.com/paulmillr/es6-shim/blob/master/es6-shim.js#L1065-L1410 - 350 lines is not going to be that large.

I'd hope that js-git would have a build process anyways, so I can always choose which parts I want to include and which not, so a Promise shim could just be omitted if I didn't want it.

What is the status on this? It would be nice to use with async/await now that it is getting supported, instead of using gen-run. I haven't looked into it, but couldn't there be a mixin that promisifies the api? Then nothing would be needed to be done to the core of js-git.

It probably wouldn't be hard to have a mixin that went through a set of known API signatures and turned them into promise based APIs. The harder task would be to automatically convery any api already mixed in.

for the record: now, 3 years later, the best practice has indeed unequivocally become to just assume Promise is globally available and expect the user to shim it.

@creationix, I'm not familiar with the full scope of the api possible to create with mixins, but as long as they are enumerable methods on the repo object, then it shouldn't be too hard to loop through and promisify them. There are several npm packages that do this. I can try to have a look at this.

Go for it and let me know how it works.