Skip to content

Instantly share code, notes, and snippets.

@queviva
Last active February 1, 2024 23:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save queviva/651e7ab3590cb19e96eb0166db5851a5 to your computer and use it in GitHub Desktop.
Save queviva/651e7ab3590cb19e96eb0166db5851a5 to your computer and use it in GitHub Desktop.
inline web werkers without external scripts
...
<style> werk-er { display: none; } </style>
...
<werk-er id="zero">
const f = new class {
constructor () { ... }
meth0 (x,y,z) { ... }
meth1 (x,y,z) { ... }
}();
onmessage = (e, [a, ...b] = [...e.data]) => f[a](b);
</werk-er>
<werk-er id="one"> ... </werk-er>
<werk-er id="two"> ... </werk-er>
...
<script defer>
const WZ = [...document.querySelectorAll('werk-er')]
.reduce((a, v, i, _, n=(v.id||i)) => (
a[n] = new Worker(window.URL.createObjectURL(new Blob(
[v.textContent], {type:'text/javascript'})
)), a[n].spit = (...p) => a[n].postMessage(p), a
),{});
WZ.zero.spit('meth0',1,2,3);
WZ.one.postMessage([4,5,6]);
WZ.two.onmessage = e => { ... };
</script>
@queviva
Copy link
Author

queviva commented Dec 15, 2023

for inline web werkers that do not require a separate, external, script file

use a hyphen to create a valid custom tag named werk-er that doesn't display

<style> werk-er { display: none; } </style>

then create tags filled with any code you want

<werk-er id="doCrazyMath"> ... </werk-er>
<werk-er id="getHugeFile"> ... </werk-er>

the example given here is for the most useful possible synchronous class;
it allows you to post messages that directly invoke specific methods inside the werk-er

in a defer'ed <script> include the first line of Blob-building code;
it will create an object called WZ, from which you can refer to any werk-er
by its id [or by index# if there is no id]

const WZ = [...document.querySelectorAll('werk-er')]
.reduce((a, v, i, _, n=(v.id||i)) => (
  a[n] = new Worker(window.URL.createObjectURL(new Blob(
    [v.textContent], {type:'text/javascript'}
  ))), a[n].spit = (...p) => a[n].postMessage(p), a
),{});

for example you would post messages to a werk-er whose id is zero like this:

WZ.zero.postMessage('one message');

or this:

WZ.zero.postMessage(['more', 'than', 1, 'message']);

but that's too much typing, and only allows one parameter,
so the WZ code here creates an apodo named spit which allows you to
post many-optioned messages to the werk-er; again the example here
would allow you to pass any parameters you want to any method in the
werk-er like this:

WZ.zero.spit('meth0', [1,2], 'tre');

and, ofcourse, listen for messages from the werk-er like this:

WZ.zero.onmessage = e => { ... };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment