-
-
Save lukaslihotzki/b50ccb61ff3a44b48fc4d5ed7e54303f to your computer and use it in GitHub Desktop.
const wrappedFunc = Worklet.prototype.addModule; | |
Worklet.prototype.addModule = async function(url) { | |
try { | |
return await wrappedFunc.call(this, url); | |
} catch (e) { | |
if (e.name != 'AbortError') { | |
throw e; | |
} | |
// assume error is caused by https://bugzilla.mozilla.org/show_bug.cgi?id=1572644 | |
console.warn('direct addModule call failed, resorting to bundling'); | |
const {rollup} = await import('https://unpkg.com/rollup@2.78.0/dist/es/rollup.browser.js'); | |
const generated = await (await rollup({ | |
input: url, | |
onwarn: console.warn, | |
plugins: [ | |
{ | |
resolveId(importee, importer) { | |
return new URL(importee, new URL(importer || window.location.href)).toString(); | |
}, | |
load(id) { | |
return fetch(id).then(response => response.text()); | |
}, | |
} | |
], | |
})).generate({}); | |
const blob = new Blob([generated.output[0].code], {type: 'text/javascript'}); | |
const objectUrl = URL.createObjectURL(blob); | |
try { | |
return await wrappedFunc.call(this, objectUrl); | |
} finally { | |
URL.revokeObjectURL(objectUrl); | |
} | |
} | |
}; |
Where would you put this relative to the worklet scripts? Better question, how do you get this in your project so it imports the worklet scripts?
You can redefine Worklet.prototype.addModule()
in globalThis
scope.
Thanks, but I have to admit I don't understand your answer. I presume it means this polyfill is not intended to be used as presented here; rather, a developer would need to re-write it to fit the particulars of his or her audio worklet implementation. Or simply that this is above my experience level.
This polyfill can be used as is. This code needs to be placed in a script that is included in the main site (where addModule
is used), not in the worklet module itself. For example, include <script type="module" src="polyfill_worklet_import.js"></script>
as the first script element in your HTML (and add polyfill_worklet_import.js
, obviously).
One issue with using a Blob URL or Data URL is ServiceWorker
s do not intercept requests from those URL's.
One issue with using a Blob URL or Data URL is
ServiceWorker
s do not intercept requests from those URL's.
However, the fetches of individual modules are intercepted by ServiceWorker
s. Can you explain the case where you need the ServiceWorker
to intercept the combined source?
Consider communicating with and supplying raw audio data to AudioWorkletGlobalScope
before AudioWorkletProcessor
construction, see WebAudio/web-audio-api#2456. One way to do that is intercepting import
and sending data with respondWith()
. That doesn't work when Blob URL or Data URL are used as Worklet URL w3c/ServiceWorker#712 (comment).
import json from './exports.json' assert {type: "json"};
let data = new Float32Array(json);
self.addEventListener('fetch', async (event) => {
if (
event.request.destination === 'audioworklet' &&
event.request.url.includes('exports.js')
) {
event.respondWith(
new Response(JSON.stringify([...data]), {
headers: { 'content-type': 'application/json' },
})
);
}
});
This should be
throw e
. I updated the gist.