starmelon/README.md

49 lines
2.7 KiB
Markdown
Raw Permalink Normal View History

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]