use crate::error::RariError;
use crate::runtime::module_loader::RariModuleLoader;
use crate::runtime::ops::StreamOpState;
use crate::runtime::runtime_factory::constants::{
API_HANDLER_INIT_SCRIPT, COMPONENT_LOADER_INIT_SCRIPT, COOKIES_INIT_SCRIPT,
ENV_INJECTION_SCRIPT, METADATA_COLLECTOR_INIT_SCRIPT, MODULE_CHECK_SCRIPT,
};
use cow_utils::CowUtils;
use deno_core::{Extension, JsRuntime, RuntimeOptions};
use rustc_hash::FxHashMap;
use std::borrow::Cow;
use std::rc::Rc;
pub fn create_deno_runtime(
env_vars: Option<FxHashMap<String, String>>,
) -> Result<(JsRuntime, Rc<RariModuleLoader>), RariError> {
let module_loader = Rc::new(RariModuleLoader::new());
let streaming_ops = get_streaming_ops();
let ext_options = crate::runtime::ext::ExtensionOptions::default();
let mut extensions = crate::runtime::ext::extensions(&ext_options, false);
extensions.push(Extension {
name: "rari:streaming",
ops: Cow::Owned(streaming_ops),
op_state_fn: Some(Box::new(|state| {
state.put(StreamOpState::default());
let mut feature_checker = deno_features::FeatureChecker::default();
feature_checker.enable_feature("broadcast-channel");
feature_checker.enable_feature("webgpu");
feature_checker.enable_feature("kv");
feature_checker.enable_feature("cron");
feature_checker.enable_feature("net");
feature_checker.enable_feature("worker-options");
state.put(std::sync::Arc::new(feature_checker));
})),
..Default::default()
});
let options = RuntimeOptions {
module_loader: Some(module_loader.clone()),
extensions,
extension_transpiler: Some(module_loader.as_extension_transpiler()),
..Default::default()
};
let mut runtime = JsRuntime::new(options);
if let Some(env_vars) = env_vars {
let env_script = ENV_INJECTION_SCRIPT.cow_replace(
"const envVars = {};",
&format!(
"const envVars = {};",
serde_json::to_string(&env_vars).unwrap_or_else(|_| "{}".to_string())
),
);
if let Err(err) = runtime.execute_script("env_vars.js", env_script.into_owned()) {
eprintln!("[rari] Failed to inject environment variables: {err}");
}
}
if let Err(err) =
runtime.execute_script("module_registration_check.js", MODULE_CHECK_SCRIPT.to_string())
{
eprintln!("[rari] Failed to check module registration extension: {err}");
}
runtime.execute_script("api_handler_init.js", API_HANDLER_INIT_SCRIPT.to_string()).map_err(
|e| RariError::internal(format!("Failed to initialize API handler helper: {e}")),
)?;
runtime
.execute_script("metadata_collector_init.js", METADATA_COLLECTOR_INIT_SCRIPT.to_string())
.map_err(|e| {
RariError::internal(format!("Failed to initialize metadata collector helper: {e}"))
})?;
runtime
.execute_script("component_loader_init.js", COMPONENT_LOADER_INIT_SCRIPT.to_string())
.map_err(|e| {
RariError::internal(format!("Failed to initialize component loader helper: {e}"))
})?;
runtime
.execute_script("cookies_init.js", COOKIES_INIT_SCRIPT.to_string())
.map_err(|e| RariError::internal(format!("Failed to initialize cookies helper: {e}")))?;
Ok((runtime, module_loader))
}
fn get_streaming_ops() -> Vec<deno_core::OpDecl> {
crate::runtime::ops::get_streaming_ops()
}