use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::rc::Rc;
use uuid::Uuid;
use wasm_bindgen::prelude::*;
use super::LoadModuleError;
mod component;
use crate::engine::EngineRef;
pub use component::BrowserComponentExecutor;
pub(crate) use component::{compile as compile_component, BrowserComponent};
pub struct SharedLoader {
engine: Cell<Option<EngineRef>>,
prepared: RefCell<HashMap<Uuid, component::PreparedComponent>>,
}
pub type SharedLoaderRc = Rc<SharedLoader>;
impl SharedLoader {
pub fn new() -> SharedLoaderRc {
Rc::new(SharedLoader {
engine: Cell::new(None),
prepared: RefCell::new(HashMap::new()),
})
}
pub async fn prepare(self: Rc<Self>, id: Uuid, executable: Vec<u8>) -> Result<(), JsValue> {
let engine_ptr = self
.engine
.get()
.ok_or_else(|| JsValue::from_str("SharedLoader: set_engine not called"))?;
if !crate::component_layout::is_component(&executable) {
return Err(JsValue::from_str(&format!(
"module {id} is a core module: Arora loads guests as components, built for \
wasm32-wasip2"
)));
}
let prepared = component::prepare(engine_ptr, &executable).await?;
self.prepared.borrow_mut().insert(id, prepared);
Ok(())
}
}
fn js_to_load_err(e: JsValue) -> LoadModuleError {
LoadModuleError::Internal(format!("js error: {e:?}"))
}