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.
49 lines
2.7 KiB
Markdown
49 lines
2.7 KiB
Markdown
|
|
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]
|