Skip to content

Commit ae9132d

Browse files
committed
refactor: optimize dependency registration in RscRenderer
- Simplified the logic in `register_dependency_if_needed` by removing unnecessary cloning of dependencies. - Enhanced the handling of dependency paths using a stack and visited set to avoid redundant processing. - Improved clarity and performance in resolving potential paths for dependencies, ensuring only valid paths are considered.
1 parent 9396be6 commit ae9132d

File tree

1 file changed

+76
-72
lines changed

1 file changed

+76
-72
lines changed

crates/rari/src/rsc/renderer.rs

Lines changed: 76 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ impl RscRenderer {
406406

407407
for dep in &dependencies {
408408
let dep_owned = dep.clone();
409-
if let Err(e) = Box::pin(self.register_dependency_if_needed(dep_owned.clone())).await {
409+
if let Err(e) = self.register_dependency_if_needed(dep_owned).await {
410410
error!(
411411
"[RSC] Warning: Failed to register dependency '{dep}' for component '{component_id}': {e}"
412412
);
@@ -524,93 +524,97 @@ impl RscRenderer {
524524
}
525525

526526
async fn register_dependency_if_needed(&mut self, dep: String) -> Result<(), RariError> {
527-
if !dep.starts_with("./") && !dep.starts_with("../") {
528-
return Ok(());
529-
}
527+
let mut stack: Vec<String> = vec![dep];
528+
let mut visited: FxHashSet<String> = FxHashSet::default();
530529

531530
let base_path = std::env::current_dir().unwrap_or_default();
532531
let src_dir = base_path.join("src");
532+
let extensions = [".ts", ".tsx", ".js", ".jsx"];
533533

534-
let mut resolved_path_candidates = Vec::new();
535-
536-
let clean_dep = dep.trim_start_matches("./").trim_start_matches("../");
537-
538-
if dep.starts_with("../") {
539-
let up_count = dep.matches("../").count();
540-
let remaining_path = dep.replacen("../", "", up_count);
534+
while let Some(current) = stack.pop() {
535+
if !visited.insert(current.clone()) {
536+
continue;
537+
}
541538

542-
if up_count == 1 {
543-
resolved_path_candidates.push(src_dir.join(&remaining_path));
544-
} else if up_count == 2 {
545-
resolved_path_candidates.push(base_path.join(&remaining_path));
539+
if !current.starts_with("./") && !current.starts_with("../") {
540+
continue;
546541
}
547-
} else if dep.starts_with("./") {
548-
resolved_path_candidates.push(src_dir.join("components").join(clean_dep));
549-
resolved_path_candidates.push(src_dir.join(clean_dep));
550-
}
551542

552-
let extensions = [".ts", ".tsx", ".js", ".jsx"];
553-
let mut potential_paths = Vec::new();
543+
let clean_dep = current.trim_start_matches("./").trim_start_matches("../");
554544

555-
for base_path_candidate in &resolved_path_candidates {
556-
for ext in &extensions {
557-
potential_paths.push(base_path_candidate.with_extension(&ext[1..]));
545+
let mut resolved_path_candidates: Vec<std::path::PathBuf> = Vec::new();
546+
if current.starts_with("../") {
547+
let up_count = current.matches("../").count();
548+
let remaining_path = current.replacen("../", "", up_count);
549+
if up_count == 1 {
550+
resolved_path_candidates.push(src_dir.join(&remaining_path));
551+
} else if up_count == 2 {
552+
resolved_path_candidates.push(base_path.join(&remaining_path));
553+
}
554+
} else if current.starts_with("./") {
555+
resolved_path_candidates.push(src_dir.join("components").join(clean_dep));
556+
resolved_path_candidates.push(src_dir.join(clean_dep));
558557
}
559558

560-
for ext in &extensions {
561-
potential_paths.push(base_path_candidate.join(format!("index{ext}")));
559+
let mut potential_paths: Vec<std::path::PathBuf> = Vec::new();
560+
for base_path_candidate in &resolved_path_candidates {
561+
for ext in &extensions {
562+
potential_paths.push(base_path_candidate.with_extension(&ext[1..]));
563+
}
564+
for ext in &extensions {
565+
potential_paths.push(base_path_candidate.join(format!("index{ext}")));
566+
}
562567
}
563-
}
564-
565-
for potential_path in &potential_paths {
566-
if potential_path.exists() {
567-
if let Ok(content) = std::fs::read_to_string(potential_path) {
568-
let dep_component_id = potential_path
569-
.file_stem()
570-
.unwrap_or_default()
571-
.to_string_lossy()
572-
.to_string();
573-
574-
let path_components: Vec<&str> = potential_path
575-
.strip_prefix(base_path.join("src"))
576-
.unwrap_or(potential_path)
577-
.components()
578-
.filter_map(|c| c.as_os_str().to_str())
579-
.collect();
580-
581-
let unique_dep_id = if path_components.len() > 1 {
582-
format!(
583-
"{}_{}",
584-
path_components[0..path_components.len() - 1].join("_"),
585-
dep_component_id
586-
)
587-
} else {
588-
dep_component_id.clone()
589-
};
590-
591-
let already_registered = {
592-
let registry = self.component_registry.lock();
593-
registry.is_component_registered(&unique_dep_id)
594-
};
595-
596-
if !already_registered {
597-
if Self::is_react_component_file(&content) {
598-
let sub_dependencies = extract_dependencies(&content);
599-
for sub_dep in sub_dependencies {
600-
let _ = Box::pin(self.register_dependency_if_needed(sub_dep)).await;
601-
}
602568

603-
self.register_component_without_loading(&unique_dep_id, &content)
604-
.await?;
569+
for potential_path in &potential_paths {
570+
if potential_path.exists() {
571+
if let Ok(content) = std::fs::read_to_string(potential_path) {
572+
let dep_component_id = potential_path
573+
.file_stem()
574+
.unwrap_or_default()
575+
.to_string_lossy()
576+
.to_string();
577+
578+
let path_components: Vec<&str> = potential_path
579+
.strip_prefix(base_path.join("src"))
580+
.unwrap_or(potential_path)
581+
.components()
582+
.filter_map(|c| c.as_os_str().to_str())
583+
.collect();
584+
585+
let unique_dep_id = if path_components.len() > 1 {
586+
format!(
587+
"{}_{}",
588+
path_components[0..path_components.len() - 1].join("_"),
589+
dep_component_id
590+
)
605591
} else {
606-
debug!(
607-
"Skipping registration of '{}' as it's not a React component",
608-
unique_dep_id
609-
);
592+
dep_component_id.clone()
593+
};
594+
595+
let already_registered = {
596+
let registry = self.component_registry.lock();
597+
registry.is_component_registered(&unique_dep_id)
598+
};
599+
600+
if !already_registered {
601+
if Self::is_react_component_file(&content) {
602+
let sub_dependencies = extract_dependencies(&content);
603+
for sub_dep in sub_dependencies {
604+
stack.push(sub_dep);
605+
}
606+
self.register_component_without_loading(&unique_dep_id, &content)
607+
.await?;
608+
} else {
609+
debug!(
610+
"Skipping registration of '{}' as it's not a React component",
611+
unique_dep_id
612+
);
613+
}
610614
}
611615
}
616+
break;
612617
}
613-
break;
614618
}
615619
}
616620

0 commit comments

Comments
 (0)