denoland/deno_core

Evaluate updated module

gearonix opened this issue · 3 comments

async fn run_js(file_path: &str) -> Result<(), AnyError> {
    let main_module = deno_core::resolve_path(file_path, env::current_dir()?.as_path())?;
    let mut js_runtime = deno_core::JsRuntime::new(deno_core::RuntimeOptions {
        module_loader: Some(Rc::new(TsModuleLoader)),
        startup_snapshot: Some(RUNTIME_SNAPSHOT),
        extensions: vec![runjs::init_ops()],
        ..Default::default()
    });

    fs::write(file_path, "console.log(\"1\")")?;

    // js_runtime.lazy_load_es_module_with_code()
    let mod_id = js_runtime.load_main_es_module(&main_module).await?;
    let _ = js_runtime.mod_evaluate(mod_id).await?;
    // [out]: "hello 1"
    js_runtime.run_event_loop(Default::default()).await?;

    fs::write(file_path, "console.log(\"2\")")?;
    
    // should log [out]: "hello 2"
    let _ = js_runtime.mod_evaluate(mod_id).await?;
    // got error
    // assertion `left == right` failed: Module already evaluated.
    // Perhaps you've re-provided a module or extension that was already included in the snapshot

    Ok(())
}

Should I create a new JsRuntime instance and load the updated file?

.mod_evaluate() evaluates modules that have already been loaded into memory. It doesn't reload files from disk.

    let main_module = deno_core::resolve_path(file_path, env::current_dir()?.as_path())?;
 
    fs::write(file_path, "console.log(\"1\")")?;

    // js_runtime.lazy_load_es_module_with_code()
    let mod_id = js_runtime.load_side_es_module(&main_module).await?;
    let _ = js_runtime.mod_evaluate(mod_id).await?;
    // [out]: "hello 1"
    js_runtime.run_event_loop(Default::default()).await?;

    // main_module updated here, now it contains 
    // source code below
    fs::write(file_path, "console.log(\"2\")")?;

    // Maybe something like .update_side_es_module?
    let mod_id = js_runtime.load_side_es_module(&main_module).await?;

    let _ = js_runtime.mod_evaluate(mod_id).await?;
    // should log [out]: "hello 2"
    // but got error
    // assertion `left == right` failed: Module already evaluated.
    // Perhaps you've re-provided a module or extension that was already included in the snapshot
    js_runtime.run_event_loop(Default::default()).await?;

Ok, now I understand. Is this possible in deno_core? How can such functionality be achieved?

@marvinhagemeister opened a pull request here #890