turbopack_core/chunk/
available_modules.rs1use anyhow::Result;
2use turbo_tasks::{FxIndexSet, ReadRef, ResolvedVc, TryJoinIterExt, Vc};
3use turbo_tasks_hash::Xxh3Hash64Hasher;
4
5use crate::module_graph::module_batch::{ChunkableModuleOrBatch, IdentStrings};
6
7#[turbo_tasks::value(transparent)]
8#[derive(Debug, Clone)]
9pub struct AvailableModulesSet(FxIndexSet<ChunkableModuleOrBatch>);
10
11#[turbo_tasks::value]
15pub struct AvailableModules {
16 parent: Option<ResolvedVc<AvailableModules>>,
17 modules: ResolvedVc<AvailableModulesSet>,
18}
19
20#[turbo_tasks::value_impl]
21impl AvailableModules {
22 #[turbo_tasks::function]
23 pub fn new(modules: ResolvedVc<AvailableModulesSet>) -> Vc<Self> {
24 AvailableModules {
25 parent: None,
26 modules,
27 }
28 .cell()
29 }
30
31 #[turbo_tasks::function]
32 pub async fn with_modules(
33 self: ResolvedVc<Self>,
34 modules: ResolvedVc<AvailableModulesSet>,
35 ) -> Result<Vc<Self>> {
36 Ok(AvailableModules {
37 parent: Some(self),
38 modules,
39 }
40 .cell())
41 }
42
43 #[turbo_tasks::function]
44 pub async fn hash(&self) -> Result<Vc<u64>> {
45 let mut hasher = Xxh3Hash64Hasher::new();
46 if let Some(parent) = self.parent {
47 hasher.write_value(parent.hash().await?);
48 } else {
49 hasher.write_value(0u64);
50 }
51 let item_idents = self
52 .modules
53 .await?
54 .iter()
55 .map(|&module| module.ident_strings())
56 .try_join()
57 .await?;
58 for idents in item_idents {
59 match idents {
60 IdentStrings::Single(ident) => hasher.write_value(ident),
61 IdentStrings::Multiple(idents) => {
62 for ident in idents {
63 hasher.write_value(ident);
64 }
65 }
66 IdentStrings::None => {}
67 }
68 }
69 Ok(Vc::cell(hasher.finish()))
70 }
71
72 #[turbo_tasks::function]
73 pub async fn get(&self, module_or_batch: ChunkableModuleOrBatch) -> Result<Vc<bool>> {
74 if self.modules.await?.contains(&module_or_batch) {
75 return Ok(Vc::cell(true));
76 };
77 if let Some(parent) = self.parent {
78 return Ok(parent.get(module_or_batch));
79 }
80 Ok(Vc::cell(false))
81 }
82
83 #[turbo_tasks::function]
84 pub async fn snapshot(&self) -> Result<Vc<AvailableModulesSnapshot>> {
85 let modules = self.modules.await?;
86 let parent = if let Some(parent) = self.parent {
87 Some(parent.snapshot().await?)
88 } else {
89 None
90 };
91
92 Ok(AvailableModulesSnapshot { parent, modules }.cell())
93 }
94}
95
96#[turbo_tasks::value(serialization = "none")]
97#[derive(Debug, Clone)]
98pub struct AvailableModulesSnapshot {
99 parent: Option<ReadRef<AvailableModulesSnapshot>>,
100 modules: ReadRef<AvailableModulesSet>,
101}
102
103impl AvailableModulesSnapshot {
104 pub fn get(&self, module_or_batch: ChunkableModuleOrBatch) -> bool {
105 self.modules.contains(&module_or_batch)
106 || self
107 .parent
108 .as_ref()
109 .is_some_and(|parent| parent.get(module_or_batch))
110 }
111}