How are the return promises from Rollup plugin hooks used? - rollup

I'm attempting my first plugin for Rollup. Reading over the plugin docs in the hooks section I can see that most of the hooks can return a promise. However I don't see how that promise can be used. Is it passed to the next hook? What am I missing here?

The rollup hook system calls into registered plugins in its many processing stages. Each stage consists of many rollup internal and plugin supplied promises. It chains promises together to process through all steps. That's the typical way an async Javascript system works. For example, your plugin can have a load hook, the hook can immediately return the contents of a file, or it can return a Promise that, at a later time, resolves to the contents; rollup will chain the Promise with more processing Promises, which will execute when the first Promise resolved. Tip: Read about async functions.

Related

Is possible get which component call some action Vuex?

Is possible to get which component call some action Vuex ?
I return a promise from vuex actions and take some decisions in component as set errors messages on respective fields but I would like to set on component.$validator.errors asap I receive http response (in action method)
Is that possible and a good approach ?
In Vuex when you make a call to a mutation or action you can send an object alongside your dispatch call, if you wanted to track the component which called an action you could also send that as part of the object. Better yet you could have all objects sent via Vuex extend a specific class if your using typescript. Though note that finding which component called an action or mutation is not native behavior for Vuex.
Consider the following:
try{
let out = await this.$store.dispatch('someActionHandler', {referingComponent: this.$options.name, someParam:[1,2,3]})
} catch (e){
// Lets deal with the problem
}
In here we are sending the name of the component as a parameter, so it can be checked inside our action handler or alternatively you could just pass this straight to a mutation, though I think the former is a more likely case if you plan to build logic into this.
As for if this is a good approach, the answer to that is fairly subjective, I personally don't see any problems with the above approach. Though I would think it was an anti pattern if the majority of components are never checked or the added data ends up becoming meaningless fluff passed alongside every call.

Apollo - update() method getting called twice, both times with optimistic/fake data

I'm completely stuck on an Apollo problem, for which I've opened a GitHub issue and had zero response on.
I'm calling an Apollo mutation, using optimisticResponse. The way it's supposed to work, as I understand it, is that update() gets called twice: first with the optimistic data, then again with the actual data coming in from the network.
But for some reason, my code is not working like this. I'm getting two update() calls, both with the optimistic data.
Here's a repo that demonstrates this behavior: https://github.com/ffxsam/apollo-update-bug
yarn && yarn dev
Open in browser, open console
Enter some text and hit enter
Repeat above
Notice the error in the console about duplicate keys. This is happening because the temporary ID "??" is not being replaced with the real UUID
(optional) You can open Vue DevTools if available and inspect the data to see it's incorrect
I was doing some digging and I think I found the source of the problem.
Unfortunately, I don't have a solution.
In short, the problem might be with a network link called OfflineLink that is used by aws-appsync.
Explanation
aws-appsync has an ApolloLink called OfflineLink that intervenes with the request function.
What happens is something like this:
you call $apollo.mutate(...)
ApolloClient.QueryManager initializes the mutation that triggers your update the first time with the optimistic response. That is happening inside ApolloClient data store, markMutationInit calls markMutationResult that calls your update.
The graphql operation executes and reaches the OfflineLink in the network chain.
OfflineLink creates a new observer and dispatches the mutation info as an action.
The next line of OfflineLink calls the observer's next function with the optimisticResponse as if it was the execution result!
This triggers your update the second time with the result which is actually the optimisticResponse.
OfflineLink calls the observer's complete which resolves your promise.
console.log('done!'...
Meanwhile, OfflineLink prevents the original mutation from even sending the request, and a new mutation is generated and sent with the options you've given it.

Ember -- component integration async tests aren't waiting until async calls are returned

I'm having a hard time testing async functionality in component integration tests. Input kicks off an async call to an endpoint, and when it returns, I send an action. I'm trying to test that the action sends the correct data.
I've tried putting my assertion in the wait() helper, but the assertion gets hit before the (dependent upon async) action is called.
Here's a twiddle showing that problem: https://ember-twiddle.com/79f9a80c639b642e538803ac64a1cf9d?openFiles=tests.integration.components.test-comp-test.js%2Ctemplates.components.test-comp.hbs
How can I correctly code my async component integration tests?
There are two things that fails your test:
Firstly, never make use of setTimeout (window.setTimeout) to schedule some future work with Ember. Make use the Ember way of doing it; I mean Ember.run.later. For the same thing that happened to me with acceptance tests; please see the following question and look through comments on the answer. The reason is that; Ember's test helpers really cannot handle setTimeout as we expect it.
You have a problem within the test itself; in the action handler you have written in test you need to change the name attribute instead of returning a promise.
Anyway please see the following twiddle I have updated. Testing in general with Ember is kind of a pain; since I believe there is not a proper comprehensive documentation. Good luck!

Convenient logging with protractor

I'm trying to make logging easier for devs writing selenium tests with protractor.
I'm looking at selenium-webdriver/lib/logging and am trying to figure out how to make a convenient logging system.
Here is an example spec:
it('should NOT show welcome before login', () => {
// convenient log here
expect(homepage.logo.isPresent()).toBe(true);
// log message that would occur after expect
expect(homepage.welcomeText.isPresent()).toBe(false);
// final log message
});
I'm not quite sure how to go about this.
I'm trying to avoid having to do (below) for every log message.
homepage.welcomeText.isPresent().then(() => console.log('foo bar'));
There is a npm package - log4js-protractor-appender which will solve your problem.It is built specially for Protractor based environments and it places all logger command in Protractor Control flow and resolves Protractor promises before logging.
Since Protractor executes all commands in a Control Flow , and all non protractor commands dont get executed in the order we like. So regular logging will need an extra effort from us to chain a non-protractor command to a protractor command
Example:
browser.getCurrentUrl().then(function _logValue(url){
logger.info("The url is" + url);
});
But log4js-protractor-appender enabled to write something like this directly - browser.logger.info('Displayed text is:', browser.getCurrentUrl());
For more details on how to implement this- Please check my blog post - How to implements logs for Protractor/JavaScript based Test Automation Frameworks
For expects you can use toBeTruthy or Falsy and include message there. It would log if something goes wrong. Page Object pattern says you must not have weddriver methods in spec files meaning you may cretae method which would verify something present or not and then() log there like in your example. Also you can implement asyncLog function. console.log() method goes to Stack and executes before protractor methods since protractor's Control Flow or Managed Promise. It wraps every protractor method in deffered promise which puts it in callback queue which executes only after stack is empty. Take a look at next code. I didn't try it out for Protractor though but you can get the idea.
var promise = Promise.resolve();
function asyncLog(message) {
Promise.resolve().then(() => console.log(message));
}
console.log('Start');
promise
.then(() => console.log('This is then'))
asyncLog('This is Callback Queue log');
console.log('This is Call Stack log');
promise
.then(() => console.log('This is another then'))

How can I make browserify onComplete handlers wait for my plugin to finish?

I'm writing a browserify plugin which adds a transform but also needs to do things at the very end, once browserify has finished going through the require tree. Achieving this is simple since my plugin receives a browserify instance (which I call brow), so I can just brow.transform(...) to add my transform and use the following to do more at the end:
brow.on('bundle', function (bundler) {
bundler.on('end', doMoreAtTheEnd)
})
This works fine except for one pretty important detail. Any other handlers expected to run when browserify is done (via the onComplete handler brow.bundle(onComplete)) execute too soon (before my plugin is done doing it's work). This makes testing my plugin rather difficult, for example, since the assertions I wrote in the onComplete handler execute before my plugin is done doing its work.
I understand why this happens: my plugin and my assertions are both using the same onComplete event, so they will run one immediately before the other, and since my plugin is doing async work, the assertions run too soon). but I'm not sure how to achieve what I want without extreme hackery... I could use setTimeout, of course, but I'm trying to avoid that, for reasons that should be obvious...
Any ideas?
update
I've reduced my problem to a short gist, if that helps
I found a solution using the browserify pipeline. The trick is to use the flush callback of the last phase in the pipeline (wrap).
var through = require('through2')
var wrap = brow.pipeline.get('wrap')
wrap.push(through(function (buf, enc, next) {
// This leaves the chunks unchanged
this.push(buf)
next()
}, function (next) {
// Here I can do some async work
setTimeout(function () {
// and call `next` when I'm done
next()
}, 1000)
})
I made a new gist which applies this fix to the original gist illustrating the problem in the question.