You can use the port of an AudioWorkletProcessor to send data back to the main thread (or any other thread).

this.port.postMessage(someProcessedNumber);

Every AudioWorkletNode has a port as well which can be used to receive the message.

Using the MessagePort will generate some garbage on the audio thread which makes the garbage collection run from time to time. It's also not the most performant way to transfer data.

If that's an issue you can use a SharedArrayBuffer instead which the AudioWorkletProcessor uses to write the data and the AudioWorkletNode uses to read the data.

ringbuf.js is a library which aims to make this process as easy as possible.