use super::{ModuleId, Module, ImportSpec, loader, cache, resolver, import};
use crate::diagnostics::Result;
use crate::eval::Value;
use std::collections::HashMap;
use std::sync::Arc;
#[derive(Debug)]
pub struct ModuleSystem {
loader: loader::ModuleLoader,
cache: cache::ModuleCache,
resolver: resolver::DependencyResolver,
}
impl ModuleSystem {
pub fn new() -> Result<Self> {
let loader = loader::ModuleLoader::new()?;
let cache = cache::ModuleCache::new();
let resolver = resolver::DependencyResolver::new();
Ok(Self {
loader,
cache,
resolver,
})
}
pub fn load_module(&mut self, id: &ModuleId) -> Result<Arc<Module>> {
if let Some(module) = self.cache.get(id) {
return Ok(module);
}
let module = self.loader.load(id)?;
let resolved = self.resolver.resolve_dependencies(module)?;
let module_arc = Arc::new(resolved);
self.cache.insert(id.clone(), module_arc.clone());
Ok(module_arc)
}
pub fn resolve_import(&mut self, import: &ImportSpec) -> Result<HashMap<String, Value>> {
let module = self.load_module(&import.module_id)?;
import::apply_import_config(&module.exports, &import.config)
}
pub fn register_builtin_module(&mut self, module: Module) {
let id = module.id.clone();
self.cache.insert(id, Arc::new(module));
}
pub fn get_module_info(&self, id: &ModuleId) -> Option<Arc<Module>> {
self.cache.get(id)
}
pub fn list_modules(&self) -> Vec<ModuleId> {
self.cache.list_modules()
}
}
impl Default for ModuleSystem {
fn default() -> Self {
Self::new().expect("Failed to create default module system")
}
}