- From: Pauan <notifications@github.com>
- Date: Mon, 27 Jan 2020 04:45:52 -0800
- To: w3c/ServiceWorker <ServiceWorker@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <w3c/ServiceWorker/issues/1499/578730536@github.com>
The summary is that @moshevds wants to write their service worker entirely in Wasm, without any JS at all. Right now that's not possible, because:
1. [esm-integration](https://github.com/WebAssembly/esm-integration) requires top-level `await` which has been banned in service workers.
2. wasm-bindgen can't generate code which uses top-level `await` to load the `.wasm` file... because top-level `await` has been banned.
3. wasm-bindgen can't generate code which loads the `.wasm` file synchronously... because sync XHR has been banned.
4. wasm-bindgen *could* convert the `.wasm` file into base64 and embed it inside the `.js` file and use the synchronous `WebAssembly` APIs to load it... except that won't work if there is a 4 KB size limit.
So right now it's not really possible to create a service worker which is pure Wasm.
Instead you have to create a `.js` file which loads and caches the `.wasm` file, and defines the event listeners, like this:
```js
async function load(url) {
const cache = await caches.open("offline");
try {
const response = await fetch(url);
if (response.ok) {
await cache.put(url, response);
return response;
} else {
throw new Error("Invalid status code: " + response.status);
}
} catch (e) {
const response = await cache.match(url);
if (response) {
return response;
} else {
throw e;
}
}
}
async function loadWasm(url) {
const response = await load(url);
const bytes = await response.arrayBuffer();
await wasm_bindgen(bytes);
}
function events(...names) {
importScripts("./path/to/wasm.js");
const wasm = loadWasm("./path/to/wasm_bg.wasm");
self.addEventListener("install", (event) => {
event.waitUntil(wasm);
});
names.forEach((name) => {
const f = wasm_bindgen[name];
self.addEventListener(name, (event) => {
event.waitUntil(wasm.then(() => f(event)));
});
});
}
events("fetch", "push", "message");
```
From wasm-bindgen's perspective, the ideal solution is for the browser to have built-in support for `.wasm` (such as with [esm-integration](https://github.com/WebAssembly/esm-integration)).
Removing the 4 KB limit isn't a great solution, since it still requires base64-encoding the `.wasm` file and embedding it into the `.js` file, and it also doesn't handle caching/offline use.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/ServiceWorker/issues/1499#issuecomment-578730536
Received on Monday, 27 January 2020 12:45:54 UTC