My web app is using a web assembly module for some non trivial operations. It has a service worker set up to handle push notifications. Both the main thread and the push notification handler need access to the web assembly module.
Is there a recommended approach to sharing the wasm module?
My first thought was to put it in the service worker and have the main thread call the worker, but then it might become idled and the worker would need to load and initialize the wasm module again which takes about 800ms. I could also use a shared worker, but I don't believe the service worker can spawn a shared worker, so the solution wouldn't work if the main thread is closed.
Is there a canonical way of doing this?
Related
I have two separate applications under the same origin but on different pages (say origin/a/ and origin/b/). Each page registers a service worker, which operates under its own scope. Whilst service workers are restricted to the pages they are registered on, they share the same caches from the origin. And if I want each service worker to clean up its old caches, it turns out it wipes out also the caches created by another service worker.
I ended up defining a scope const in service workers and manually checking if the cache name starts with it. However, this seems a bit fragile since one could rename this scope, and the cache will get lost. Another approach of using self.registration.scope as a cache name part looks better but also cannot guarantee consistent behaviour for nested pages that could contain yet another service worker.
Is there any consistent way to bind a cache to a service worker that I am missing?
as you might already know, you should put your service workers inside the base directory so that it has the scope of the whole project, otherwise some features (e.g. navigator.serviceWorker.ready()) won't be available.
My problem is that I've initially put my service worker inside a directory and now I feel kinda trapped.
I use the service worker to register and handle web push notifications and I'm wondering if I would lose all my current subscriptions if I move it to the base directory
N.B. It's mandatory that the service worker registered will remain the same, no new service worker should be registered
If you don't want to move your service worker in base directory. You can use "Service-Worker-Allowed" header in your response. If this header is present then your service worker will be registered even if your sw.js file is in nested directory.
Service-Worker-Allowed header '/'
here the the official documentation regarding this header.
https://w3c.github.io/ServiceWorker/#service-worker-allowed
I have a shell application which is the container application that performs all the API communication. Also, I do have multiple Micro application which just broadcast the API request signal to shell application.
Now, keeping the security in mind, as a shell application how it can ensure that API request signal is coming from the trusted micro app which I own.
To be very precise, My ask is, is there a way to let shell application know that the signal is coming from the micro app that it owns and not from any untrusted(like hacking, XSS) source
As per the Micro-Frontend architecture each Micro Frontend should make call to it's own API (micro service). However, your Shell app can provide some common/global library which can help the Micro Frontends make the AJAX call. But the onus of making the call must remain with the individual micro frontend.
From your question it is unclear if your apps are running in iframes, or are being loaded directly into your page.
In the case of iFrames your using postMessage and you can check the origin on received message via event.origin. Compare this with a list of allowed domains.
If your micro apps are directly on your page then you just control what is allowed to load into them.
So, in most microfrontends, each microapp does its own API calls to the corresponding microservice on the backend, and the shell app is ignorant of it. The most the shell app would do relative to this is passing some app config to all microapps which has config like the hostname of the various backends, and, an auth token if all the backends are using the same auth.
But to ensure the shell app doesn't have, say, an advertisement with malicious code trying to pose as another microapp, well..
how are the microapps talking to the shell? Is there a common custom event? The name of the customEvent would have to be known to the intruder, but that's only security-by-obscurity, which isn't real.
other methods like postMessage are between window objects, which I don't think help your case.
You might be able to re-use the authToken that the shell and microapps both know, since it was communicated at startup. But if you have microapps that come and go that won't work either.
If a service worker is associated to a web page, does it inherit its permissions (for example to show notifications)? Could I use a service worker to create notification?
In general it seems that service worker inherits page permissions, and you can use a service worker to create notifications, if your page has received permissions for that. On the other hand not everything is available to the service worker API. For example, Geolocation access has been proposed, but is apparently not yet available. So you'll have to look at things case-by-case.
Notifications are indeed one of the best use cases for service worker, since your service worker, once registered, can actually create notifications even if your page is not open in the user's browser. Here is an tutorial for push notifications with service workers in Chrome. You could also create notifications normally without the whole push part though. Just keep in mind that your service worker needs to be woken up by some event or other in order to do anything.
Is it possible to access a shared worker created in the main thread in a dedicated worker created by that same main thread? My initial thoughts are no as this could cause a lot of concurrency issues, but I don't have a full understanding of the internals of WebWorkers yet to decide definitively.
My use case would be to have a dedicated worker open up a web socket channel with the server to retrieve a streaming data source. This data would then be sent into a shared worker that will provide functions to manipulate it and return results via transferable objects. I do not want to combine these objects into a single worker since I want to be able to plug in different modules for doing the data manipulation, and do not want to have to duplicate the code to talk with the web socket.
Is it possible to access a shared worker created in the main thread in a dedicated worker created by that same main thread?
Yes. Just create a SharedWorker as a sub-worker (and it will be shared), or create a MessageChannel between the shared and the dedicated worker.
this could cause a lot of concurrency issues
No. Inter-Worker communication is evented and asynchronous.
This data would then be sent into a shared worker that will provide functions to manipulate
That doesn't sound as if you needed a shared worker for that. For "providing functions", a simple library that is loaded into the dedicated worker (which does the websocket communication) will suffice. You might even load libraries dynamically, using some kine of dependency management in the worker. There's no need to duplicate the web socket code.