/**
* Creates a worker.
*
* @example
* ```js
* // When running in a web browser.
* import createWorkerInBrowser from './createWorkerInBrowser.ts'
*
* // Create a worker.
* const workerFn = createWorkerFn(
* // Creates a worker in a given environment.
* createWorkerInBrowser,
*
* // (optional) Filters `transferList` argument.
* undefined,
*
* // Any "outside" dependencies that're referenced in the function (below).
* [() => [outsideVar1, outsideVar2, func1, func2]],
*
* // Returns a function in the worker that processes input data.
* (respond) => {
* return (data) => {
* // Process the data (perform some kind of calculation).
* const result = processData(data)
* // Post the result of the calculation back to the main thread.
* respond(result) // (optional) add `transferList` argument.
* }
* },
*
* // A function in the main thread that will be called every time
* // when the worker has finished processing the data
* // (or threw an error while doing that).
* (error, result) => {
* if (error) {
* workerFn.stop()
* throw error
* }
* // If no more data will be passed to the worker, it should be terminated.
* workerFn.stop()
* console.log(result)
* }
* )
*
* workerFn.start()
*
* // Post a message with some data to the worker
* // so that it starts processing the data
* // and later posts a message back to the main thread
* // with the result of the calculation.
* workerFn.input(inputData) // (optional) add `transferList` argument.
* ```
*
* @param {function} createWorkerInEnvironment — Creates a worker in a given environment. The worker must call globally-available `onMessage(data)` function every time it receives a message, and it must define a `var postMessage = (data) => void` function that posts a message to the parent (main) thread.
* @param {function} createInputHandler — A "creator" that creates a function that will be called with message data every time a message is sent to this worker. The "creator" function receives a single argument — a function that posts data back to the main thread, with two arguments: `outputData` and (optional) `transferList`.
* @param {function} onError — This function will be called every time when there was an error while processing an incoming message. It would be logical to call `worker.terminate()` inside this function.
* @param {function} onOutput — This function will be called every time when done processing an incoming message.
* @param {function} getFromCache — Could be used to add caching. Has no arguments. Returns the cached value.
* @param {function} setInCache — Could be used to add caching. Receives the value to cache as an argument. Doesn't return anything.
* @returns {Worker} — An object with methods: `start(getDependenciesFunctionOrArrayOfGetDependenciesFunctions)`, `stop()`, `input(data, [transferList])`. Calling `stop()` requests termination of the worker. Calling `stop()` multiple times is safe and will not throw any errors.
*/
export default function createWorker(createWorkerInEnvironment: CreateWorkerInEnvironment, createInputHandler: CreateInputHandler, onError: (error: unknown) => void, onOutput: (inputSentTimestampAndInputReceivedTimestampAndOutputSentTimestampAndOutput: InputSentTimestampAndInputReceivedTimestampAndOutputSentTimestampAndOutput