turbopack_ecmascript/chunk/
chunk_type.rs

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