Skip to main content

turbopack_ecmascript/async_chunk/
module.rs

1use anyhow::Result;
2use turbo_rcstr::rcstr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbopack_core::{
5    chunk::{ChunkableModule, ChunkingContext, availability_info::AvailabilityInfo},
6    ident::AssetIdent,
7    module::{Module, ModuleSideEffects},
8    module_graph::ModuleGraph,
9    reference::{ModuleReferences, SingleModuleReference},
10};
11
12use crate::async_chunk::chunk_item::AsyncLoaderChunkItem;
13
14/// The AsyncLoaderModule is a module that loads another module async, by
15/// putting it into a separate chunk group.
16#[turbo_tasks::value]
17pub struct AsyncLoaderModule {
18    pub inner: ResolvedVc<Box<dyn ChunkableModule>>,
19    pub chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
20    pub availability_info: AvailabilityInfo,
21}
22
23#[turbo_tasks::value_impl]
24impl AsyncLoaderModule {
25    #[turbo_tasks::function]
26    pub fn new(
27        module: ResolvedVc<Box<dyn ChunkableModule>>,
28        chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
29        availability_info: AvailabilityInfo,
30    ) -> Vc<Self> {
31        Self::cell(AsyncLoaderModule {
32            inner: module,
33            chunking_context,
34            availability_info,
35        })
36    }
37
38    #[turbo_tasks::function]
39    pub fn asset_ident_for(module: Vc<Box<dyn ChunkableModule>>) -> Vc<AssetIdent> {
40        module.ident().with_modifier(rcstr!("async loader"))
41    }
42}
43
44#[turbo_tasks::value_impl]
45impl Module for AsyncLoaderModule {
46    #[turbo_tasks::function]
47    fn ident(&self) -> Vc<AssetIdent> {
48        Self::asset_ident_for(*self.inner)
49    }
50
51    #[turbo_tasks::function]
52    fn source(&self) -> Vc<turbopack_core::source::OptionSource> {
53        Vc::cell(None)
54    }
55
56    #[turbo_tasks::function]
57    async fn references(self: Vc<Self>) -> Result<Vc<ModuleReferences>> {
58        Ok(Vc::cell(vec![ResolvedVc::upcast(
59            SingleModuleReference::new(
60                *ResolvedVc::upcast(self.await?.inner),
61                rcstr!("async module"),
62            )
63            .to_resolved()
64            .await?,
65        )]))
66    }
67
68    #[turbo_tasks::function]
69    fn side_effects(self: Vc<Self>) -> Vc<ModuleSideEffects> {
70        ModuleSideEffects::SideEffectFree.cell()
71    }
72}
73
74#[turbo_tasks::value_impl]
75impl ChunkableModule for AsyncLoaderModule {
76    #[turbo_tasks::function]
77    fn as_chunk_item(
78        self: ResolvedVc<Self>,
79        module_graph: ResolvedVc<ModuleGraph>,
80        chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
81    ) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
82        Vc::upcast(
83            AsyncLoaderChunkItem {
84                chunking_context,
85                module_graph,
86                module: self,
87            }
88            .cell(),
89        )
90    }
91}