use std::borrow::Cow;
use rolldown_common::ImportKind;
use rolldown_plugin::{HookLoadReturn, HookUsage, Plugin};
mod generated;
use generated::embedded_helpers::{
RUNTIME_HELPER_PREFIX, RUNTIME_HELPER_UNVERSIONED_PREFIX, get_helper_content, is_runtime_helper,
is_virtual_runtime_helper,
};
#[derive(Debug)]
pub struct OxcRuntimePlugin;
impl Plugin for OxcRuntimePlugin {
fn name(&self) -> Cow<'static, str> {
Cow::Borrowed("builtin:oxc-runtime")
}
fn register_hook_usage(&self) -> HookUsage {
HookUsage::ResolveId | HookUsage::Load
}
async fn resolve_id(
&self,
_ctx: &rolldown_plugin::PluginContext,
args: &rolldown_plugin::HookResolveIdArgs<'_>,
) -> rolldown_plugin::HookResolveIdReturn {
if is_runtime_helper(args.specifier) {
let rest = &args.specifier[RUNTIME_HELPER_UNVERSIONED_PREFIX.len()..];
let path_in_helpers: Cow<'_, str> = if rest.ends_with(".js") {
Cow::Borrowed(rest)
} else {
Cow::Owned(rolldown_utils::concat_string!(rest, ".js"))
};
let final_path: Cow<'_, str> =
if path_in_helpers.starts_with("esm/") || matches!(args.kind, ImportKind::Require) {
path_in_helpers
} else {
Cow::Owned(rolldown_utils::concat_string!("esm/", path_in_helpers))
};
let virtual_id = rolldown_utils::concat_string!("\0", RUNTIME_HELPER_PREFIX, final_path);
return Ok(Some(rolldown_plugin::HookResolveIdOutput {
id: virtual_id.into(),
..Default::default()
}));
}
Ok(args.importer.and_then(|importer| {
let importer = importer.strip_prefix('\0')?;
if !is_virtual_runtime_helper(importer) || !args.specifier.starts_with("./") {
return None;
}
let dir_end = importer.rfind('/')?;
let dir = &importer[..dir_end];
let rel = args.specifier[2..].trim_start_matches("./");
let full_path = rolldown_utils::concat_string!("\0", dir, "/", rel);
Some(rolldown_plugin::HookResolveIdOutput { id: full_path.into(), ..Default::default() })
}))
}
fn resolve_id_meta(&self) -> Option<rolldown_plugin::PluginHookMeta> {
Some(rolldown_plugin::PluginHookMeta { order: Some(rolldown_plugin::PluginOrder::Pre) })
}
async fn load(
&self,
_ctx: rolldown_plugin::SharedLoadPluginContext,
args: &rolldown_plugin::HookLoadArgs<'_>,
) -> HookLoadReturn {
Ok(args.id.strip_prefix('\0').and_then(|id| {
get_helper_content(id)
.map(|code| rolldown_plugin::HookLoadOutput { code, ..Default::default() })
}))
}
fn load_meta(&self) -> Option<rolldown_plugin::PluginHookMeta> {
Some(rolldown_plugin::PluginHookMeta { order: Some(rolldown_plugin::PluginOrder::Pre) })
}
}