Skip to main content

DevelopmentNodeEnvironment_MicrosoftVSCodeDependency_22NodeVersion_Bundle_Clean_Debug_ElectronProfile_EsbuildCompiler_Mountain/ProcessManagement/NodeResolver/
ResolveNodeBinary.rs

1//! Resolve the Node binary used to spawn Cocoon and cache for the life of
2//! the process. If everything fails returns `node` so `Command::new` still
3//! tries a bare PATH lookup at spawn time, matching legacy behaviour while
4//! logging the chain of misses.
5
6use std::sync::OnceLock;
7
8use tauri::{AppHandle, Runtime};
9
10use crate::{
11	ProcessManagement::NodeResolver::{CheckMinMajor, QueryNodeVersion, ResolveUncached, ResolvedNode},
12	dev_log,
13};
14
15static RESOLVED:OnceLock<ResolvedNode::Struct> = OnceLock::new();
16
17pub fn Fn<R:Runtime>(ApplicationHandle:&AppHandle<R>) -> ResolvedNode::Struct {
18	if let Some(Cached) = RESOLVED.get() {
19		return Cached.clone();
20	}
21
22	let Resolved = ResolveUncached::Fn(ApplicationHandle);
23
24	let Version = QueryNodeVersion::Fn(&Resolved.Path);
25
26	match &Version {
27		Some(Reported) => {
28			dev_log!(
29				"cocoon",
30				"[NodeResolver] Using: {} (source={}, version={})",
31				Resolved.Path.display(),
32				Resolved.Source.AsLabel(),
33				Reported
34			);
35
36			CheckMinMajor::Fn(Reported);
37		},
38
39		None => {
40			dev_log!(
41				"cocoon",
42				"[NodeResolver] Using: {} (source={}, version=unknown)",
43				Resolved.Path.display(),
44				Resolved.Source.AsLabel()
45			);
46		},
47	}
48
49	// `OnceLock::set` is benign-racy: parallel callers resolve to the same
50	// value; the first store wins.
51	let _ = RESOLVED.set(Resolved.clone());
52
53	Resolved
54}