ysmood / yaku

A lightweight promise library
https://tonicdev.com/ysmood/yaku
MIT License
290 stars 28 forks source link

Request: Have a version which exposes only A+ and ES6 features #34

Closed JakeChampion closed 8 years ago

JakeChampion commented 8 years ago

This would enable the library to be used as a pure polyfill. What do you think to the idea?

ysmood commented 8 years ago

If you var Promise = require('yaku'), I think that will only expose A+ and ES6 features. Do you mean the npmCDN one?

If you mean Yaku.Symbol, Yaku.speciesConstructor(O, defaultConstructor), etc. These are only a part for the ES6 shim, because Yaku won't shim things like ES6 Symbol for the users, so that the users will have the chance to set their preference, such as use core-js Symbol polyfill. For most use cases, you won't like touch them.

JakeChampion commented 8 years ago

Yep, I mean Yaku.Symbol et al. I believe we have var Promise = require('yaku') via the npmCDN version by this file -- https://npmcdn.com/yaku@0.16.4/dist/yaku.browser.global.js

Is Yaku.Symbol in the specification? If it isn't, could we have a version which doesn't have it and instead assumes a global ES6 compliant Symbol (whether that be native or a polyfill)?

ysmood commented 8 years ago

If I do that, then the user will be unable to choose the right polyfill. For instance, IE8 doesn't support Symbol, the user want to polyfill it, the user can do it with Yaku.Symbol = require('core-js/library').Symbol. After then Yaku can take advantage of the polyfilled Symbol. If we don't expose an API, there's no way to control Yaku communication with the outside world. In that case you have to pollute the global environment with the Symbol polyfill before Yaku's initialization.

The reason why Yaku has these extra APIs is because the ES6 spec is somehow incomplete for some edge cases. For example, Promise depends on Symbol to work, in some circumstances we have Promise but we don't have Symbol. How to deal with that is still undocumented, and I hope we could find out a better solution.

ysmood commented 8 years ago

But I think I can find a way to get rid of these 2:

But these 4, I can't find a proper way to eliminate them:

JakeChampion commented 8 years ago

In that case you have to pollute the global environment with the Symbol polyfill before Yaku's initialization.

That is what I am asking for :-) I'm wanting to integrate Yaku into https://polyfill.io as our Promise polyfill. We support dependencies meaning that we would know to polyfill Symbol globally before initialising Yaku.

Here is the PR for switching to Yaku -- https://github.com/Financial-Times/polyfill-service/pull/780

ysmood commented 8 years ago

Suppose you are depending on two third libs, one depends on core-js to polyfill Symbol, another one depends on polyfill.io to do that. Which one will finally win the global pollution? If you don't have the full control of how the polyfill works on Yaku, that will really be a mess.

JakeChampion commented 8 years ago

If core-js ran before polyfill.io then polyfill.io would not polyfill Symbol. polyfill.io has a detection script which runs before polyfilling a feature, the Symbol detection script is 'Symbol' in this.

If polyfill.io ran before core-js I don't know what core-js does, hopefully it does feature detection much the same as polyfill.io does as to avoid needlessly overwriting functionality.

ysmood commented 8 years ago

And what if the user load the two libs by requirejs asynchronously? Nobody will know who wins.

JakeChampion commented 8 years ago

That is true, I wouldn't recommend loading two polyfill libraries which try and polyfill the same features.

ysmood commented 8 years ago

Besides, one thing I want to confirm is that all the extra APIs are class's static methods, and will be called only once through the entire project. Most times users won't know they are even exist.

JakeChampion commented 8 years ago

Perhaps Yaku could have a factory functions which accepts these configuration options and returns a Yaku Class with them applied? This way we won't require static methods added to the class and enable configuration for different Symbol polyfills etc. We could even have it have default configuration which uses global Symbol or something else.

ysmood commented 8 years ago

Well, if you insist, I will try my best to figure it out. To have a factory will increase a lot of dirty code. I would rather to make a separate version of the core.

JakeChampion commented 8 years ago

Thanks for taking the time to listen to my feature request :-)

I'd rather a separate version of core as well, factories are something I'm not particularly fond of.

ysmood commented 8 years ago

I added a new branch yaku.core, I'm not sure if it is ready to be published. So we should checkout it for some time.

For now only one thing is sure that src/yaku.core.js passed all the basic unit tests.

JakeChampion commented 8 years ago

All the tests pass according to my CI -- https://circleci.com/gh/JakeChampion/yaku/2

ysmood commented 8 years ago

v0.16.6 published

If everything goes well for a while, I will document it into the readme.

JakeChampion commented 8 years ago

looks good :-)

JakeChampion commented 8 years ago

https://polyfill.io has been using this since August 7th as our Promise polyfill, it is in the default set of polyfills given to users which is served million times a day, every day. We've had no bug reports about this polyfill, I think it is safe to close this issue and document this in the readme.

ysmood commented 8 years ago

Thanks for your report, the doc was added. If you are also interested in Promise based project, please try these: