Skip to main content

turbopack_ecmascript/chunk/
batch.rs

1use anyhow::Result;
2use bincode::{Decode, Encode};
3use turbo_tasks::{ResolvedVc, TryJoinIterExt, Vc, trace::TraceRawVcs};
4use turbopack_core::{
5    chunk::{
6        ChunkItemBatchGroup, ChunkItemBatchWithAsyncModuleInfo, ChunkItemOrBatchWithAsyncModuleInfo,
7    },
8    output::{OutputAssetsReference, OutputAssetsWithReferenced},
9};
10
11use crate::chunk::EcmascriptChunkItemWithAsyncInfo;
12
13#[turbo_tasks::task_input]
14#[derive(Debug, Clone, Hash, PartialEq, Eq, TraceRawVcs, Encode, Decode)]
15pub enum EcmascriptChunkItemOrBatchWithAsyncInfo {
16    ChunkItem(EcmascriptChunkItemWithAsyncInfo),
17    Batch(ResolvedVc<EcmascriptChunkBatchWithAsyncInfo>),
18}
19
20impl EcmascriptChunkItemOrBatchWithAsyncInfo {
21    pub async fn from_chunk_item_or_batch(
22        item: &ChunkItemOrBatchWithAsyncModuleInfo,
23    ) -> Result<Self> {
24        Ok(match item {
25            ChunkItemOrBatchWithAsyncModuleInfo::ChunkItem(chunk_item) => {
26                EcmascriptChunkItemOrBatchWithAsyncInfo::ChunkItem(
27                    EcmascriptChunkItemWithAsyncInfo::from_chunk_item(chunk_item)?,
28                )
29            }
30            &ChunkItemOrBatchWithAsyncModuleInfo::Batch(batch) => {
31                EcmascriptChunkItemOrBatchWithAsyncInfo::Batch(
32                    EcmascriptChunkBatchWithAsyncInfo::from_batch(*batch)
33                        .to_resolved()
34                        .await?,
35                )
36            }
37        })
38    }
39
40    pub fn references(&self) -> Vc<OutputAssetsWithReferenced> {
41        match self {
42            EcmascriptChunkItemOrBatchWithAsyncInfo::ChunkItem(item) => {
43                item.chunk_item.references()
44            }
45            EcmascriptChunkItemOrBatchWithAsyncInfo::Batch(batch) => batch.references(),
46        }
47    }
48}
49
50#[turbo_tasks::value]
51pub struct EcmascriptChunkBatchWithAsyncInfo {
52    pub chunk_items: Vec<EcmascriptChunkItemWithAsyncInfo>,
53}
54
55#[turbo_tasks::value_impl]
56impl EcmascriptChunkBatchWithAsyncInfo {
57    #[turbo_tasks::function]
58    pub async fn from_batch(batch: Vc<ChunkItemBatchWithAsyncModuleInfo>) -> Result<Vc<Self>> {
59        Ok(Self {
60            chunk_items: batch
61                .await?
62                .chunk_items
63                .iter()
64                .map(EcmascriptChunkItemWithAsyncInfo::from_chunk_item)
65                .collect::<Result<Vec<_>>>()?,
66        }
67        .cell())
68    }
69
70    #[turbo_tasks::function]
71    pub async fn references(&self) -> Result<Vc<OutputAssetsWithReferenced>> {
72        let mut output_assets = Vec::new();
73        let mut referenced_output_assets = Vec::new();
74        let mut references = Vec::new();
75        // We expect most references to be empty, and avoiding try_join to avoid allocating the Vec
76        for item in &self.chunk_items {
77            let r = item.chunk_item.references().await?;
78            output_assets.extend(r.assets.await?);
79            referenced_output_assets.extend(r.referenced_assets.await?);
80            references.extend(r.references.await?);
81        }
82        Ok(OutputAssetsWithReferenced {
83            assets: ResolvedVc::cell(output_assets),
84            referenced_assets: ResolvedVc::cell(referenced_output_assets),
85            references: ResolvedVc::cell(references),
86        }
87        .cell())
88    }
89}
90
91#[turbo_tasks::value]
92pub struct EcmascriptChunkItemBatchGroup {
93    pub items: Vec<EcmascriptChunkItemOrBatchWithAsyncInfo>,
94}
95
96#[turbo_tasks::value_impl]
97impl EcmascriptChunkItemBatchGroup {
98    #[turbo_tasks::function]
99    pub async fn from_chunk_item_batch_group(
100        batch_group: Vc<ChunkItemBatchGroup>,
101    ) -> Result<Vc<Self>> {
102        Ok(Self {
103            items: batch_group
104                .await?
105                .items
106                .iter()
107                .map(EcmascriptChunkItemOrBatchWithAsyncInfo::from_chunk_item_or_batch)
108                .try_join()
109                .await?,
110        }
111        .cell())
112    }
113}