next_napi_bindings/next_api/
analyze.rs1use std::{iter::once, sync::Arc};
2
3use anyhow::Result;
4use next_api::{
5 analyze::{AnalyzeDataOutputAsset, ModulesDataOutputAsset},
6 project::ProjectContainer,
7};
8use turbo_tasks::{Effects, ReadRef, ResolvedVc, TryJoinIterExt, Vc};
9use turbopack_core::{diagnostics::PlainDiagnostic, issue::PlainIssue, output::OutputAssets};
10
11use crate::next_api::utils::strongly_consistent_catch_collectables;
12
13#[turbo_tasks::value(serialization = "none")]
14pub struct WriteAnalyzeResult {
15 pub issues: Arc<Vec<ReadRef<PlainIssue>>>,
16 pub diagnostics: Arc<Vec<ReadRef<PlainDiagnostic>>>,
17 pub effects: Arc<Effects>,
18}
19
20#[turbo_tasks::function(operation)]
21pub async fn write_analyze_data_with_issues_operation(
22 project: ResolvedVc<ProjectContainer>,
23 app_dir_only: bool,
24) -> Result<Vc<WriteAnalyzeResult>> {
25 let analyze_data_op = write_analyze_data_with_issues_operation_inner(project, app_dir_only);
26 let filter = project.project().issue_filter();
27
28 let (_analyze_data, issues, diagnostics, effects) =
29 strongly_consistent_catch_collectables(analyze_data_op, filter).await?;
30
31 Ok(WriteAnalyzeResult {
32 issues,
33 diagnostics,
34 effects,
35 }
36 .cell())
37}
38
39#[turbo_tasks::function(operation)]
40async fn write_analyze_data_with_issues_operation_inner(
41 project: ResolvedVc<ProjectContainer>,
42 app_dir_only: bool,
43) -> Result<()> {
44 let analyze_data_op = get_analyze_data_operation(project, app_dir_only);
45
46 project
47 .project()
48 .emit_all_output_assets(analyze_data_op)
49 .as_side_effect()
50 .await?;
51
52 Ok(())
53}
54
55#[turbo_tasks::function(operation)]
56async fn get_analyze_data_operation(
57 container: ResolvedVc<ProjectContainer>,
58 app_dir_only: bool,
59) -> Result<Vc<OutputAssets>> {
60 let project = container.project();
61 let project = project.with_next_config(project.next_config().with_analyze_config());
62
63 let analyze_output_root = project
64 .node_root()
65 .owned()
66 .await?
67 .join("diagnostics/analyze/data")?;
68 let whole_app_module_graphs = project.whole_app_module_graphs();
69 let analyze_output_root = &analyze_output_root;
70 let analyze_data = project
71 .get_all_endpoint_groups(app_dir_only)
72 .await?
73 .iter()
74 .map(|(key, endpoint_group)| async move {
75 let output_assets = endpoint_group.output_assets();
76 let analyze_data = AnalyzeDataOutputAsset::new(
77 analyze_output_root
78 .join(&key.to_string())?
79 .join("analyze.data")?,
80 output_assets,
81 )
82 .to_resolved()
83 .await?;
84
85 Ok(ResolvedVc::upcast(analyze_data))
86 })
87 .try_join()
88 .await?;
89
90 whole_app_module_graphs.as_side_effect().await?;
91
92 let modules_data = ResolvedVc::upcast(
93 ModulesDataOutputAsset::new(
94 analyze_output_root.join("modules.data")?,
95 Vc::cell(vec![whole_app_module_graphs.await?.full]),
96 )
97 .to_resolved()
98 .await?,
99 );
100
101 Ok(Vc::cell(
102 analyze_data
103 .iter()
104 .cloned()
105 .chain(once(modules_data))
106 .collect(),
107 ))
108}