The way extensions are injected into the Isolate changed dramatically between Sept 2021 and Jan 2024. Now ops are available in the virtual module ext:core/ops.
2.7 KiB
When I first created starmelon in September 2021 there was a hacky workaround
for setTimeout I had to inject into the generated javascript. Now in Nov 2023
after upgrading deno to 0.127 I find that globalThis.__boostrap.timers is no
longer defined. Now the elm code seems to work without requring this hack.
However I don't have any correctness tests for starmelon. To reduce the risk of
forgetting how it was working I have included the hacks from
src/exec/scripting.rs:168
// I think that when I set this script to be the main module, I am skipping the
// deno/runtime/js/99_main.js script that sets up a bunch of global variables. If I
// manually add the timer related code below then setTimeout works again.
// NB. there are 706 lines of setup code that add a bunch of apis to the global window
// scope. Figure out if I need to include all of them. For example, starmelon does not need
// to perform http calls right now, but I eventually want to.
final_script.push_str("const { setTimeout } = globalThis.__bootstrap.timers;\n");
final_script.push_str(
"Deno.core.setMacrotaskCallback(globalThis.__bootstrap.timers.handleTimerMacrotask);\n",
);
final_script.push_str("globalThis.setTimeout = setTimeout;\n");
Somewhere between deno_runtime version 0.127 and 0.147 they decided to remove
deno_core::op macro and replace it with deno_core::op2. As far as I can
tell, the op2 macro offers greater control of how values are passed between
Rust and JavaScript.
In Jan 2024 they moved operations to a virtual module
import { op_example } from "ext:core/ops. You can only access this virtual
module in the bootstrap ESM scripts of an deno_core::Extension. Consequently
what I have done is write a bootstrap script that imports the ops and reassigns
them as properties of globalThis.Extension object. All of my extensions are
merged onto the same object. It appears the Deno.core is deleted by the time
the deno_runtime::worker::MainWorker runs the main module.
Deno[Deno.internal].core.ops still exists but does not contain the ops our
Extensions defined.
An aside is that if you construct a JsRuntime directly and add Extensions then
those ops will show up on Deno.core.ops. But they will not be enumerable
properties, so you will have to use Object.getOwnPropertyNames(Deno.core.ops)
to visually confirm the ops are there. My current understanding in April 2024
is that MainWorker includes a JsRuntime, but then also applies all of the
deno_runtime extensions that make the JS enviroment feature comparable with
Node. For example setTimeout does not exist in a new JsRuntime but does exist
in a new MainWorker.
You can find some of the extensions that Deno provides in [https://github.com/denoland/deno/tree/main/runtime/js]