Description
Background
This module is based on coincident orchestration and a great achievement of that module, despite requiring inevitably special headers to allow SharedArrayBuffer, is that no code evaluation ever happens: it's all about proxies, Atomics or standard Web features, without "eval" like security concerns ever.
At the same time, because of those required special headers and to make this module as portable as possible when it comes to workers support, without needing to rely on foreign headers at all when that's desired, this module pre-bundles some file before publishing, also providing a nonce that 3rd party bundlers can use to eventually allow the xworker
Blob code whenever CSP rules are both present and rightly strict / paranoid in terms of which code is trusted and which one isn't.
Such nonce is indeed embedded in the package.json
as sha-256 value and, for whoever is wondering what is that about indeed, that's the checksum for the ./worker/xworker.js
file that the build artifact creates before this module reaches npm (or just to even pass integration tests).
Current State
I had strong discussions against evaluating any code in the worker space because of CSP constraints and possible attached shenanigans, but while I am still fully convinced not evaluating anything in the worker space is actually desirable, automatically defeating tons of different classes of potential attacks to the code, this choice, and my position, is very likely limiting the DX related to hooks and/or the ability to actually pass callbacks to the worker as JS things to do and execute at the right time, like it is already for the main thread story, helped by the fact in there there's no need to survive postMessage related dances, so it's easier to add callbacks to onBeforeRun
and friends without ever worry about CSP contraints.
However, while working, thinking, refactoring, and working on other things around this PR, I've wondered myself why shouldn't developers be able to define for either main or workers the very same list of hooks, also providing a way in the worker to deal with the current interpreter before (or after) any code runs at all, enabling tons of features that otherwise need to branch between main and workers all the time ... heck, I even think that PR is wrong in somehow branching main VS thread, as in an ideal world we want to just define these hooks, and stop caring about which one is running where, as long as there is any mean/way to disambiguate the hook is running in a main thread, or a worker one:
- onReady
- onBeforeRun
- onBeforeRunAsync
- onAfterRun
- onAfterRunAsync
- codeBeforeRun
- codeBeforeRunAsync
- codeAfterRun
- codeAfterRunAsync
If we had these normalized no matter where, simply adding some detail to their callbacks when possible (I still think code is about python or other interpreters code, and these already provide a way to disambiguate, as it s for pyscript
module, but other hooks can also provide as global IS_WORKER
flag if needed), the only hook that'd be left over to date is the onWorkerReady
one, because this is a hook that makes sense only on the main thread, as that provides the xworker
referece to eventually attach utilities before the worker even runs via sync
or anything else we want or need in the future.
In short, I wonder if just having all hooks normalized for all worlds makes sense, but then again, callbacks posted as strings to workers won't be able to carry their own outer scope like it is for main, so that it is still somehow desirable to disambiguate hooks by main
one and thread
one, where callbacks without outer scope dependencies can work regardless for both cases, but it's still possible to fine-tune those callbacks that wouldn't.
The code story would be the same for both main and thread, so that even in main it would be possible to add code related hooks, instead of just JS one, but basically anyone would be free to actually hook their own code or plugin at any time around the lifecycle of a polyscript script enabled script or custom type ... after all, for workers that would be just enabling extra trust to an already inevitably evaluated part of the project.
What do you you think?