Following OS.file example it uses TextEncoder however from bootstrap scope this is not available.
https://developer.mozilla.org/en-US/docs/JavaScript_OS.File/OS.File_for_the_main_thread#Example.3A_Read_the_contents_of_a_file_as_text
Only way I could access it is by going decoder = new Services.appShell.hiddenDOMWindow.TextDecoder(); but is thi the only way?
You can use TextEncoder and friends inside a javascript module. But doing so might be an overkill, if all you want is a couple of missing globals (putting aside the fact that jsm are cached and this might not work well with a restartless addon).
Conveniently Addon SDK's loader delivers what you need.
const { TextDecoder, TextEncoder } = Cu.import('resource://gre/modules/commonjs/toolkit/loader.js', {});
Related
First, I'd like to explain that I have a Vue component repository that is responsible for displaying data retrieved from an http service. Rather than the component itself managing the same data retrieval per instance and spamming the client with network requests, I've managed to find a solution which allows another component to be mounted to the root directly (which I've dubbed as a "Service" due to its similarity to Angular) to manage the data those components need instead. This works great and other components can access it via Vue.prototype (via this.$TestService.value). It has some caveats but for the most part it accomplishes exactly what I needed. This may be uncommon, but those that use Vuex are using a similar methodology and I don't want to use the store paradigm.
I've made a very simple Vue JsFiddle to show this in action...
https://jsfiddle.net/spronkets/8v31tcfd/18
Now, to the point... I'm using #testing-library/vue, #vue/test-utils, and Jest to test the components and get test coverage and now I get errors anytime I run the tests due to the service not existing on the Vue.prototype during the test execution. I don't want to mock out the functionality of the "Service" layer, so does anyone have a solution to test these root-mounted components? I've tried manually exporting the services (unmounted and mounted) and including them in the mock section as well as importing the files directly into the test files but the "Service" is always undefined when the component is trying to retrieve the value and ONLY during test execution...
I've also created a simple repository modelled after the Vue component repository I am working with below...
https://github.com/kcrossman/VueServiceExample
To get started, clone the repo and follow the README.md included in the repo. Thanks!
I would go against using the real service if it is asyncronous, but if you just want to register it to be available you can follow the mock instructions but instead of mocking with an object just import the real service. Although after seeing your TestService implementation you will need to separate the real service from the service registration and export it to be able to register it in local vue.
You need to create and prepare your custom Vue instance in your tests in order to use any custom functionalities in your unit tests (like stores, routers, and anything else). (You can use your real modules with the custom instance, don't have to mock anything.)
In your case you should create a new Vue instance with "createLocalVue" function from '#vue/test-utils' and apply your custom prototype functionalities on that. After that you can write proper test cases accessing that custom features as well.
Update:
For those that might be referring to this in the future, Vue Plugins might be a better solution for this kind of functionality.
I stumbled along this issue in GitHub and that led me to the fix I made below:
https://github.com/testing-library/vue-testing-library/issues/113
Specifically, this comment by user nikravi:
ok, I found the fix. The trick was to add
import Vue from "vue";
import Vuetify from "vuetify";
Vue.use(Vuetify);
and then the render() works without warnings.
After I manually imported Vue and set Vue.prototype.$TestService = TestService directly in the unit test, it got passed that error. Personally, I think this is pretty silly, but it worked.
After this worked, I also found that you can access the Vue instance directly within the render callback (from #testing-library/vue), so I finished on this code instead of importing Vue:
render(TestComponent, {}, vue => {
vue.prototype.$TestService = TestService;
});
I've included all the commits to solve my issue in the repo I posted previously:
https://github.com/kcrossman/VueServiceExample
Some of the tests were malformed but once I made those changes, the tests started to work and I updated some other files to be a bit nicer for people to refer to.
Background:
I'm building an SPA (Single Page Application) PWA (Progressive Web App) using Vue.js. I've a remote PostgreSQL database, serving the tables over HTTP with PostgREST. I've a working Workbox Service Worker and IndexedDB, which hold a local copy of the database tables. I've also registered some routes in my service-worker.js; everything is fine this far....
I'm letting Workbox cache GET calls that return tables from the REST service. For example:
https://www.example.com/api/customers will return a json object of the customers.
workbox.routing.registerRoute('https://www.example.com/api/customers', workbox.strategies.staleWhileRevalidate())
At this point, I need Workbox to do the stale-while-revalidate pattern, but to:
Not use a cache, but instead return the local version of this table, which I have stored in IndexedDB. (the cache part)
Make the REST call, and update the local version, if it has changed. (the network part)
I'm almost certain that there is no configurable option for this in this workbox strategy. So I would write the code for this, which should be fairly simple. The retrieval of the cache is simply to return the contents of the requested table from IndexedDB. For the update part, I'm thinking to add a data revision number to compare against. And thus decide if I need to update the local database.
Anyway, we're now zooming in on the actual question:
Question:
Is this actually a good way to use Workbox Routes/Caching, or am I now misusing the technology because I use IndexedDB as the cache?
and
How can I make my own version of the StaleWhileRevalidate strategy? I would be happy to understand how to simply make a copy of the existing Workbox version and be able to import it and use it in my Vue.js Service Worker. From there I can make my own necessary code changes.
To make this question a bit easier to answer, these are the underlying subquestions:
First of all, the StaleWhileRevalidate.ts (see link below) is a .ts (TypeScript?) file. Can (should) I simply import this as a module? I propably can. but then I get errors:
When I to import my custom CustomStaleWhileRevalidate.ts in my main.js, I get errors on all of the current import statements because (of course) the workbox-core/_private/ directory doesn't exist.
How to approach this?
This is the current implementation on Github:
https://github.com/GoogleChrome/workbox/blob/master/packages/workbox-strategies/src/StaleWhileRevalidate.ts
I don't think using the built-in StaleWhileRevalidate strategy is the right approach here. It might be possible to do what you're describing using StaleWhileRevalidate along with a number of custom plugin callbacks to override the default behavior... but honestly, you'd end up changing so much via plugins that starting from scratch would make more sense.
What I'd recommend that you do instead is to write a custom handlerCallback function that implements exactly the logic you want, and returns a Response.
// Your full logic goes here.
async function myCustomHandler({event, request}) {
event.waitUntil((() => {
const idbStuff = ...;
const networkResponse = await fetch(...);
// Some IDB operation go here.
return finalResponse;
})());
}
workbox.routing.registerRoute(
'https://www.example.com/api/customers',
myCustomHandler
);
You could do this without Workbox as well, but if you're using Workbox to handle some of your unrelated caching needs, it's probably easiest to also register this logic via a Workbox route.
I studied the documentation for automatic global generation of base components but it is confusing. Can anyone please explain it in detail?
You can use require.context() in order to resolve a directory where components live during webpack's build process. this exposes to you, within the browser, the list of files in that directory. From that, you can use some magic to automatically register them, here's an example:
const files = require.context('./components', true, /\.vue$/i);
files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));
So in the above, we've said that we want webpack to create a context for us of all files in the './components' directory. From there, we can loop over all the keys of the files (which represent the file name) and register them with Vue.component(...)
I recommend watching this video:
https://www.vuemastery.com/courses/real-world-vue-js/global-components
First you can understand why you may want to use global components, then why you would want to automatically global register those components, and then what the registration code (taken from the following link) actually does.
https://v2.vuejs.org/v2/guide/components-registration.html#Automatic-Global-Registration-of-Base-Components
I am trying to localize my Javascript files. For instance, I would have:
var count = 0;
$('#choices .choice').each(function(i) {
$('input', this).each(function() {
count++
$(this).attr('placeholder', '#Message("placeholder.choice") ' + count)
})
})
This would obviously work if the Javascript file is inside the Scala HTML template but I would prefer to have it in a dedicated file.
To begin with, I am wondering if it is a good idea: what about caching file if it's content may change? In this case, there is a single parameter: having it in the URL would solve this problem? Eg: /assets/javascripts/:lang/my-file.js.
And the real question is: is it possible to do that using Play! framework? It does not seem that Javascript templates are supported (or I missed something). Is there a way to do it correctly?
Actually you don't need to translate your JavaScripts dynamically, it's reduntant waste of resources, instead prepare static JS files like messages.en.js, messages.de.js etc and include required file basing on the user's language directly into the view.
Here you have some description how to make it easy (JavaScript approach)
There is a module allowing javascript internationalization using the same mechanism as in Play templates, have a look at :
https://github.com/julienrf/play-jsmessages
This will definitely fits your needs. I use it for a while know with success. You can expose your translations through a javascript file and then use browser caching with a proper fingerprinting configuration.
I'm trying to follow the basic cometd example here: http://dojotoolkit.org/reference-guide/1.7/dojox/cometd.html
It's using the old module loader so I tried the equivalent as follows:
require(["dojo/ready","dojo/io/script","dojox/cometd","dojox/cometd/callbackPollTransport"], function(ready, dontcare, cometd) {
ready(function(){
cometd.init('http://localhost:8080/MyCometD/cometd');
comted.subscribe("/test", function(msg){
console.debug(msg);
});
});
});
This doesn't work and I think it has to do with loading modules - there is some sort of silent error as the code within the ready function does not execute at all. What I found is that when the "dojox/cometd" require statement is present, the code within the ready function does not execute.
Running example: http://jsfiddle.net/Q9W8f/2/
Example with dojox/comted removed: http://jsfiddle.net/mMs2h/4/
I haven't worked with the new module loader that much so I bet I just have some simple misconception.
Help!
It seems like youre correct and that there is a 'wait-loop' for a module requirement that never gets loaded. This may be any of the requirements inside dojox.cometd and you'd need to rewrite the codebase for a fix.
I have had similar issue with the RollingListPane, also in dojox repository - and the developers are saying 'we are 100% AMD compliant with 1.7' however the X in dojox is short for experimental. The developement of dojox modules is not done by the core djtk team and there are still glitches..
Try for starters to avoid using CDN which has performed a >>built macro on every single module. This tends to fail at times whilst using AMD. Instead download the tarball and use a local copy - Not compressed (dojo-release-1.7.2-src)
You can find the hello world example in cometD and ExtJs at following link:
http://jksnu.blogspot.in/2013/08/network-reliability-by-cometd-hellow_16.html