turbopack_ecmascript/async_chunk/
module.rs

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