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 ```rust // 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]