turbopack_ecmascript/chunk/
batch.rs

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