turbopack_ecmascript/chunk/
chunk_type.rs

1use anyhow::{Result, bail};
2use turbo_rcstr::RcStr;
3use turbo_tasks::{ResolvedVc, TryJoinIterExt, ValueDefault, ValueToString, Vc};
4use turbopack_core::{
5    chunk::{
6        AsyncModuleInfo, Chunk, ChunkItem, ChunkItemBatchGroup,
7        ChunkItemOrBatchWithAsyncModuleInfo, ChunkType, ChunkingContext, round_chunk_item_size,
8    },
9    output::OutputAssets,
10};
11
12use super::{EcmascriptChunk, EcmascriptChunkContent, EcmascriptChunkItem};
13use crate::chunk::batch::{EcmascriptChunkItemBatchGroup, EcmascriptChunkItemOrBatchWithAsyncInfo};
14
15#[turbo_tasks::value]
16#[derive(Default)]
17pub struct EcmascriptChunkType {}
18
19#[turbo_tasks::value_impl]
20impl ValueToString for EcmascriptChunkType {
21    #[turbo_tasks::function]
22    fn to_string(&self) -> Vc<RcStr> {
23        Vc::cell("ecmascript".into())
24    }
25}
26
27#[turbo_tasks::value_impl]
28impl ChunkType for EcmascriptChunkType {
29    #[turbo_tasks::function]
30    fn is_style(self: Vc<Self>) -> Vc<bool> {
31        Vc::cell(false)
32    }
33
34    #[turbo_tasks::function]
35    async fn chunk(
36        &self,
37        chunking_context: Vc<Box<dyn ChunkingContext>>,
38        chunk_items: Vec<ChunkItemOrBatchWithAsyncModuleInfo>,
39        batch_groups: Vec<ResolvedVc<ChunkItemBatchGroup>>,
40        referenced_output_assets: Vc<OutputAssets>,
41    ) -> Result<Vc<Box<dyn Chunk>>> {
42        let Some(chunking_context) =
43            Vc::try_resolve_downcast::<Box<dyn ChunkingContext>>(chunking_context).await?
44        else {
45            bail!("Ecmascript chunking context not found");
46        };
47
48        let content = EcmascriptChunkContent {
49            chunk_items: chunk_items
50                .iter()
51                .map(EcmascriptChunkItemOrBatchWithAsyncInfo::from_chunk_item_or_batch)
52                .try_join()
53                .await?,
54            batch_groups: batch_groups
55                .into_iter()
56                .map(|batch_group| {
57                    EcmascriptChunkItemBatchGroup::from_chunk_item_batch_group(*batch_group)
58                        .to_resolved()
59                })
60                .try_join()
61                .await?,
62            referenced_output_assets: referenced_output_assets.owned().await?,
63        }
64        .cell();
65        Ok(Vc::upcast(EcmascriptChunk::new(chunking_context, content)))
66    }
67
68    #[turbo_tasks::function]
69    async fn chunk_item_size(
70        &self,
71        _chunking_context: Vc<Box<dyn ChunkingContext>>,
72        chunk_item: Vc<Box<dyn ChunkItem>>,
73        async_module_info: Option<Vc<AsyncModuleInfo>>,
74    ) -> Result<Vc<usize>> {
75        let Some(chunk_item) =
76            Vc::try_resolve_downcast::<Box<dyn EcmascriptChunkItem>>(chunk_item).await?
77        else {
78            bail!("Chunk item is not an ecmascript chunk item but reporting chunk type ecmascript");
79        };
80        Ok(Vc::cell(
81            chunk_item
82                .content_with_async_module_info(async_module_info)
83                .await
84                .map_or(0, |content| round_chunk_item_size(content.inner_code.len())),
85        ))
86    }
87}
88
89#[turbo_tasks::value_impl]
90impl ValueDefault for EcmascriptChunkType {
91    #[turbo_tasks::function]
92    fn value_default() -> Vc<Self> {
93        Self::default().cell()
94    }
95}