The worker Feature

The worker feature lets you create Web Workers whose functions are transparently exposed to the main thread. You define functions inside the worker, and call them from hyperscript or JavaScript as if they were local -- the runtime handles the async communication for you.

Installing

The worker feature is an extension and must be included separately, after hyperscript itself:

<script src="https://cdn.jsdelivr.net/npm/hyperscript.org@0.9.91/dist/_hyperscript.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/hyperscript.org@0.9.91/dist/ext/worker.min.js"></script>

Or if you're using npm: import 'hyperscript.org/dist/ext/worker.js' after importing hyperscript.

Here's a simple example:

worker Incrementer
  js
    function _increment(n) { return n + 1 }
  end
  def increment(n) return _increment(n) end
end

Any function declarations (declared with def) will be exposed on the main thread, so the above worker can be invoked as Incrementer.increment(4) in either _hyperscript or JavaScript. The body of the function will then run in the worker and the result returned asynchronously to the main thread. As a result, the worker feature can be used to perform calculations in a non-blocking way, and although these worker functions return promises, _hyperscript's [async-transparent] nature means you can call them as if they were synchronous. In summary:

Because it runs in a Web Worker, the code inside a worker body cannot access the DOM or the window global scope. It also can't access scripts included in the main thread, which is what the external-scripts feature is for. URLs passed in as external scripts, if relative, need to be relative to the HTML document which spawns the worker.

Examples

Run CPU-heavy operations in a worker

<script type="text/hyperscript">
  worker Miner("/scripts/mine-crypto.js")
  	js
  		var miner = new CryptoMiner();
  		return { miner }
  	end

  	def startMining() miner.start() end
  	def stopMining() miner.stop() end
  end
</script>

<label>
  <input
    type="checkbox"
    _="on change
                            if me.checked Miner.startMining()
                            else Miner.stopMining()"
  />
  Disable ads <small>and enable cryptocurrency mining</small>
</label>

Syntax

worker <worker-name>[(<external-script-url>*)]
  (<function-declaration> | <js-block>)+
end