wasmerio / rusty_jsc

Rust bindings for the JavaScriptCore engine.
MIT License
99 stars 7 forks source link

WebCore #6

Open lukeed opened 1 year ago

lukeed commented 1 year ago

Hey, this looks great!

Applogies if this is a silly question, I’ve essentially just started exploring the space :)

Is it possible to load & call into WebCore APIs; eg fetch?

Also, perhaps relatedly, how I can discover what the context provides by default? I see the punjs (lol, A+) example runs a console.log script but 1) where is console coming from? 2) I don’t see it log, so is that effectively a noop since evaluateScript only prints the return value? Or do I have to define my own console global callback which passes thru to println?

Thanks !

mishushakov commented 1 year ago

Hey, no, WebAPIs are implemented by runtimes, not by JavaScript engines. In the latter case you will have to re-implement all the WebAPIs yourself using what is called a callback, which allows you to call Rust code from JavaScript and the other way around.

If you want the APIs included, you're better off using something like Deno (the deno_runtime crate in particular):

https://github.com/denoland/deno/blob/main/runtime/README.md

Here's an example:

test.js

const request = await fetch('https://example.com')
const html = await request.text()

console.log(html)

main.rs

use std::path::Path;
use std::rc::Rc;

use deno_core::anyhow::Ok;
use deno_core::error::AnyError;
use deno_runtime::deno_core::FsModuleLoader;
use deno_runtime::deno_core::ModuleSpecifier;
use deno_runtime::permissions::PermissionsContainer;
use deno_runtime::worker::MainWorker;
use deno_runtime::worker::WorkerOptions;

#[tokio::main]
async fn main() -> Result<(), AnyError> {
  let js_path = Path::new("src/test.js").canonicalize().unwrap();
  let main_module = ModuleSpecifier::from_file_path(js_path).unwrap();

  let mut worker = MainWorker::bootstrap_from_options(
    main_module.clone(),
    PermissionsContainer::allow_all(),
    WorkerOptions {
      module_loader: Rc::new(FsModuleLoader),
      ..Default::default()
    },
  );

  worker.execute_main_module(&main_module).await?;
  worker.run_event_loop(false).await?;
  Ok(())
}