turbopack_core/chunk/
data.rs1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{ReadRef, ResolvedVc, TryJoinIterExt, ValueToString, Vc};
4use turbo_tasks_fs::FileSystemPath;
5use turbo_tasks_hash::Xxh3Hash64Hasher;
6
7use crate::{
8 chunk::{ModuleId, OutputChunk, OutputChunkRuntimeInfo},
9 output::{OutputAsset, OutputAssets},
10};
11
12#[turbo_tasks::value]
13pub struct ChunkData {
14 pub path: String,
15 pub included: Vec<ReadRef<ModuleId>>,
16 pub excluded: Vec<ReadRef<ModuleId>>,
17 pub module_chunks: Vec<String>,
18 pub references: ResolvedVc<OutputAssets>,
19}
20
21#[turbo_tasks::value(transparent)]
22pub struct ChunkDataOption(Option<ResolvedVc<ChunkData>>);
23
24#[turbo_tasks::value(transparent)]
29pub struct ChunksData(Vec<ResolvedVc<ChunkData>>);
30
31#[turbo_tasks::value_impl]
32impl ChunksData {
33 #[turbo_tasks::function]
34 pub async fn hash(&self) -> Result<Vc<u64>> {
35 let mut hasher = Xxh3Hash64Hasher::new();
36 for chunk in self.0.iter() {
37 hasher.write_value(chunk.await?.path.as_str());
38 }
39 Ok(Vc::cell(hasher.finish()))
40 }
41}
42
43#[turbo_tasks::function]
44fn module_chunk_reference_description() -> Vc<RcStr> {
45 Vc::cell("module chunk".into())
46}
47
48#[turbo_tasks::value_impl]
49impl ChunkData {
50 #[turbo_tasks::function]
51 pub async fn hash(&self) -> Result<Vc<u64>> {
52 let mut hasher = Xxh3Hash64Hasher::new();
53 hasher.write_value(self.path.as_str());
54 for module in &self.included {
55 hasher.write_value(module);
56 }
57 for module in &self.excluded {
58 hasher.write_value(module);
59 }
60 for module_chunk in &self.module_chunks {
61 hasher.write_value(module_chunk.as_str());
62 }
63 for reference in self.references.await?.iter() {
64 hasher.write_value(reference.path().to_string().await?);
65 }
66
67 Ok(Vc::cell(hasher.finish()))
68 }
69
70 #[turbo_tasks::function]
71 pub async fn from_asset(
72 output_root: Vc<FileSystemPath>,
73 chunk: Vc<Box<dyn OutputAsset>>,
74 ) -> Result<Vc<ChunkDataOption>> {
75 let output_root = output_root.await?;
76 let path = chunk.path().await?;
77 let Some(path) = output_root.get_path_to(&path) else {
81 return Ok(Vc::cell(None));
82 };
83 let path = path.to_string();
84
85 let Some(output_chunk) = Vc::try_resolve_sidecast::<Box<dyn OutputChunk>>(chunk).await?
86 else {
87 return Ok(Vc::cell(Some(
88 ChunkData {
89 path,
90 included: Vec::new(),
91 excluded: Vec::new(),
92 module_chunks: Vec::new(),
93 references: OutputAssets::empty().to_resolved().await?,
94 }
95 .resolved_cell(),
96 )));
97 };
98
99 let runtime_info = output_chunk.runtime_info().await?;
100
101 let OutputChunkRuntimeInfo {
102 included_ids,
103 excluded_ids,
104 module_chunks,
105 placeholder_for_future_extensions: _,
106 } = &*runtime_info;
107
108 let included = if let Some(included_ids) = included_ids {
109 included_ids.await?.iter().copied().try_join().await?
110 } else {
111 Vec::new()
112 };
113 let excluded = if let Some(excluded_ids) = excluded_ids {
114 excluded_ids.await?.iter().copied().try_join().await?
115 } else {
116 Vec::new()
117 };
118 let (module_chunks, module_chunks_references) = if let Some(module_chunks) = module_chunks {
119 module_chunks
120 .await?
121 .iter()
122 .copied()
123 .map(|chunk| {
124 let output_root = output_root.clone();
125
126 async move {
127 let chunk_path = chunk.path().await?;
128 Ok(output_root
129 .get_path_to(&chunk_path)
130 .map(|path| (path.to_owned(), chunk)))
131 }
132 })
133 .try_join()
134 .await?
135 .into_iter()
136 .flatten()
137 .unzip()
138 } else {
139 (Vec::new(), Vec::new())
140 };
141
142 Ok(Vc::cell(Some(
143 ChunkData {
144 path,
145 included,
146 excluded,
147 module_chunks,
148 references: ResolvedVc::cell(module_chunks_references),
149 }
150 .resolved_cell(),
151 )))
152 }
153
154 #[turbo_tasks::function]
155 pub async fn from_assets(
156 output_root: Vc<FileSystemPath>,
157 chunks: Vc<OutputAssets>,
158 ) -> Result<Vc<ChunksData>> {
159 Ok(Vc::cell(
160 chunks
161 .await?
162 .iter()
163 .map(|&chunk| ChunkData::from_asset(output_root, *chunk))
164 .try_join()
165 .await?
166 .into_iter()
167 .flat_map(|chunk| *chunk)
168 .collect(),
169 ))
170 }
171
172 #[turbo_tasks::function]
174 pub fn references(&self) -> Vc<OutputAssets> {
175 *self.references
176 }
177}