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        ChunkItem, ChunkItemBatchGroup, ChunkItemBatchWithAsyncModuleInfo,
7        ChunkItemOrBatchWithAsyncModuleInfo,
8    },
9    output::OutputAssets,
10};
11
12use crate::chunk::EcmascriptChunkItemWithAsyncInfo;
13
14#[derive(
15    Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, NonLocalValue, TaskInput,
16)]
17pub enum EcmascriptChunkItemOrBatchWithAsyncInfo {
18    ChunkItem(EcmascriptChunkItemWithAsyncInfo),
19    Batch(ResolvedVc<EcmascriptChunkBatchWithAsyncInfo>),
20}
21
22impl EcmascriptChunkItemOrBatchWithAsyncInfo {
23    pub async fn from_chunk_item_or_batch(
24        item: &ChunkItemOrBatchWithAsyncModuleInfo,
25    ) -> Result<Self> {
26        Ok(match item {
27            ChunkItemOrBatchWithAsyncModuleInfo::ChunkItem(chunk_item) => {
28                EcmascriptChunkItemOrBatchWithAsyncInfo::ChunkItem(
29                    EcmascriptChunkItemWithAsyncInfo::from_chunk_item(chunk_item)?,
30                )
31            }
32            &ChunkItemOrBatchWithAsyncModuleInfo::Batch(batch) => {
33                EcmascriptChunkItemOrBatchWithAsyncInfo::Batch(
34                    EcmascriptChunkBatchWithAsyncInfo::from_batch(*batch)
35                        .to_resolved()
36                        .await?,
37                )
38            }
39        })
40    }
41
42    pub fn references(&self) -> Vc<OutputAssets> {
43        match self {
44            EcmascriptChunkItemOrBatchWithAsyncInfo::ChunkItem(item) => {
45                item.chunk_item.references()
46            }
47            EcmascriptChunkItemOrBatchWithAsyncInfo::Batch(batch) => batch.references(),
48        }
49    }
50}
51
52#[turbo_tasks::value]
53pub struct EcmascriptChunkBatchWithAsyncInfo {
54    pub chunk_items: Vec<EcmascriptChunkItemWithAsyncInfo>,
55}
56
57#[turbo_tasks::value_impl]
58impl EcmascriptChunkBatchWithAsyncInfo {
59    #[turbo_tasks::function]
60    pub async fn from_batch(batch: Vc<ChunkItemBatchWithAsyncModuleInfo>) -> Result<Vc<Self>> {
61        Ok(Self {
62            chunk_items: batch
63                .await?
64                .chunk_items
65                .iter()
66                .map(EcmascriptChunkItemWithAsyncInfo::from_chunk_item)
67                .collect::<Result<Vec<_>>>()?,
68        }
69        .cell())
70    }
71
72    #[turbo_tasks::function]
73    pub async fn references(&self) -> Result<Vc<OutputAssets>> {
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            references.extend(item.chunk_item.references().await?.into_iter().copied());
78        }
79        Ok(Vc::cell(references))
80    }
81}
82
83#[turbo_tasks::value]
84pub struct EcmascriptChunkItemBatchGroup {
85    pub items: Vec<EcmascriptChunkItemOrBatchWithAsyncInfo>,
86}
87
88#[turbo_tasks::value_impl]
89impl EcmascriptChunkItemBatchGroup {
90    #[turbo_tasks::function]
91    pub async fn from_chunk_item_batch_group(
92        batch_group: Vc<ChunkItemBatchGroup>,
93    ) -> Result<Vc<Self>> {
94        Ok(Self {
95            items: batch_group
96                .await?
97                .items
98                .iter()
99                .map(EcmascriptChunkItemOrBatchWithAsyncInfo::from_chunk_item_or_batch)
100                .try_join()
101                .await?,
102        }
103        .cell())
104    }
105}