use std::fmt::Debug;
use async_trait::async_trait;
use rspack_cacheable::cacheable;
use rspack_collections::Identifier;
use crate::{ChunkUkey, Compilation, Module, RuntimeCodeTemplate, RuntimeGlobals};
pub struct RuntimeModuleGenerateContext<'a> {
pub compilation: &'a Compilation,
pub runtime_template: &'a RuntimeCodeTemplate<'a>,
}
#[async_trait]
pub trait RuntimeModule:
Module + CustomSourceRuntimeModule + AttachableRuntimeModule + NamedRuntimeModule
{
fn stage(&self) -> RuntimeModuleStage {
RuntimeModuleStage::Normal
}
fn full_hash(&self) -> bool {
false
}
fn dependent_hash(&self) -> bool {
false
}
fn should_isolate(&self) -> bool {
true
}
fn template(&self) -> Vec<(String, String)> {
vec![]
}
async fn generate(
&self,
context: &RuntimeModuleGenerateContext<'_>,
) -> rspack_error::Result<String>;
async fn generate_with_custom(&self, compilation: &Compilation) -> rspack_error::Result<String> {
if let Some(custom_source) = self.get_custom_source() {
Ok(custom_source)
} else {
let runtime_template = compilation.runtime_template.create_runtime_code_template();
let context = RuntimeModuleGenerateContext {
compilation,
runtime_template: &runtime_template,
};
self.generate(&context).await
}
}
fn additional_runtime_requirements(&self, _compilation: &Compilation) -> RuntimeGlobals {
RuntimeGlobals::default()
}
}
#[async_trait]
pub trait AttachableRuntimeModule {
fn attach(&mut self, chunk: ChunkUkey);
}
#[async_trait]
pub trait NamedRuntimeModule {
fn name(&self) -> Identifier;
}
#[async_trait]
pub trait CustomSourceRuntimeModule {
fn set_custom_source(&mut self, source: String);
fn get_custom_source(&self) -> Option<String>;
fn get_constructor_name(&self) -> String;
}
pub type BoxRuntimeModule = Box<dyn RuntimeModule>;
#[cacheable]
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum RuntimeModuleStage {
#[default]
Normal, Basic, Attach, Trigger, }
impl From<u32> for RuntimeModuleStage {
fn from(stage: u32) -> Self {
match stage {
0 => RuntimeModuleStage::Normal,
5 => RuntimeModuleStage::Basic,
10 => RuntimeModuleStage::Attach,
20 => RuntimeModuleStage::Trigger,
_ => RuntimeModuleStage::Normal,
}
}
}
impl From<RuntimeModuleStage> for u32 {
fn from(value: RuntimeModuleStage) -> Self {
match value {
RuntimeModuleStage::Normal => 0,
RuntimeModuleStage::Basic => 5,
RuntimeModuleStage::Attach => 10,
RuntimeModuleStage::Trigger => 20,
}
}
}
pub trait RuntimeModuleExt {
fn boxed(self) -> Box<dyn RuntimeModule>;
}
impl<T: RuntimeModule + 'static> RuntimeModuleExt for T {
fn boxed(self) -> Box<dyn RuntimeModule> {
Box::new(self)
}
}