I’m working on implementing some custom JS code that relies on a web worker to do some data processing in the background without jamming up the main thread. My code works great outside of WeWeb but I can’t figure out how to implement it in WeWeb so it’ll work.
I previously managed to implement the functionality I need in the main thread, using @raydeck 's awesome tool https://weweb-embed.statechange.ai/ to import the library I need on page load (this thread was very helpful in figuring that out) then executing the actual code as part of a button-click triggered workflow.
Now I’m struggling with how to adapt this approach (or find another approach) for a web worker context.
Specifically, here are the main things I’m stuck on:
- Where to put the contents of my worker.js file so my main script can access it?
- Conversely, where to put the contents of my script.js file so it can refer to my worker.js file, and so I can call the function it defines in a JS workflow action?
At this point I really only need this to work on one particular page.
Here’s the code from my script.js file:
// Create a new Worker instance, pointing to the path of our worker.js file
const myWorker = new Worker('js/worker.js', { type: 'module' });
// Function to send data to the worker for processing
function processText(text) {
myWorker.postMessage({ text: text });
}
// Event listener to handle messages received from the worker
myWorker.addEventListener('message', function(event) {
// Check the type of message received
if (event.data.status && event.data.status === 'complete') {
// Handle the completed output
console.log('Feature extraction output:', event.data.output);
} else {
// This could be a progress update or any other message
console.log('Worker message:', event.data);
}
}, false);
// Example usage: Send some text to the worker for processing
processText('What is a large language model?');
And here is the code from my worker.js file:
import { pipeline, env } from 'https://cdn.jsdelivr.net/npm/@xenova/transformers';
// Skip local model check since we are downloading the model from the Hugging Face Hub.
env.allowLocalModels = false;
class PipelineSingleton {
static task = 'text2text-generation';
static model = 'Xenova/LaMini-Flan-T5-783M';
static instance = null;
static async getInstance(progress_callback = null) {
if (this.instance === null) {
this.instance = pipeline(this.task, this.model, {
progress_callback,
});
}
return this.instance;
}
}
// Listen for messages from the main thread
self.addEventListener('message', async (event) => {
// Retrieve the pipeline. When called for the first time,
// this will load the pipeline and save it for future use.
const generator = await PipelineSingleton.getInstance(x => {
// We also add a progress callback to the pipeline so that we can
// track model loading.
self.postMessage(x);
});
// Actually perform the generation
let output = await generator(event.data.text);
// Send the output back to the main thread
self.postMessage({ status: 'complete', output: output });
});
In short: what is the best way to implement this in WeWeb, i.e. what do I need to put where, in order for it to work? Ideally both in the editor and in prod.
I will be immensely grateful to anyone who can provide any kind of direction on this!
Thanks