Runs outside Fiber while using inside a Meteor package
Issue
The issue occurs when using @accounts/graphql-api inside of a meteor package. If we'd create the same logic but inside an app, it'd work.
const resolver = {
User: {
foo: () => FooCollection.findOne()
}
};
mutation login {
loginWithPassword( /*...*/ ) {
user {
username
foo {
id
}
}
}
}
Gives:
{
"data": {
"loginWithPassword": {
"user": {
"username": "foo",
"foo": null
}
}
},
"errors": [
{
"message": "Can't wait without a fiber",
"locations": [
{
"line": 5,
"column": 7
}
],
"path": [
"loginWithPassword",
"user",
"foo"
]
}
]
}
Reproduction
Run it and go to http://localhost:3000. It should display SUCCESS or FAILURE.
Failure:
Meteor@1.5.2 or less
https://github.com/kamilkisiela/js-accounts-meteor-fiber/tree/failure
Success:
Meteor@1.6-alpha.0 at least
https://github.com/kamilkisiela/js-accounts-meteor-fiber/tree/success
Differences
https://github.com/kamilkisiela/js-accounts-meteor-fiber/compare/failure...success
Idea
For me it's something to do with async/await and Promise. async/await is being compiled to something that uses asyncGeneratorFunction from babel-runtime's helpers and there's a Promise inside of it. For me, that Promise is not wrapped with a Fiber as it'd normally be in Meteor's environment.
babel-runtime/helpers/asyncToGenerator module uses a Promise from the core-js package.
Inside of core-js:
https://github.com/zloirock/core-js/blob/9bf000955a615307254cdb8861bfdc19c7184d77/library/modules/es6.promise.js#L26-L36
As you can see, USE_NATIVE value is boolean that tells if it should use native Promise or a polyfill.
I did some deep digging and it seems like at the time when an anonymous function executes to return a value for USE_NATIVE, there is a Promise available and it's wrapped with Fiber which is what we're looking for.
USE_NATIVE should be true but it's false. It happens because inside the try/catch an error occurs.
TypeError: es6PromiseThen.call is not a function
It points to this part of a code from meteor-promise package:
https://github.com/meteor/promise/blob/master/promise_server.js#L29-L33
Thanks for the research @kamilkisiela!
I've actually faced this issue myself in a recent project (not in a package) and have just used the rawCollection() function of the meteor collection in order to get the native mongo driver Collection object and then ran my queries as documented by mongo.
I guess there is not much we can do here but wait to 1.6 to release and it will just give us a free fix :)
Leaving this open for anyone else that faces this issue.