turbopack_ecmascript/worker_chunk/
module.rs

1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{ResolvedVc, ValueToString, Vc};
4use turbopack_core::{
5    asset::{Asset, AssetContent},
6    chunk::{
7        ChunkGroupType, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType,
8        ChunkingTypeOption,
9    },
10    ident::AssetIdent,
11    module::{Module, ModuleSideEffects},
12    module_graph::ModuleGraph,
13    reference::{ModuleReference, ModuleReferences},
14    resolve::ModuleResolveResult,
15};
16
17use super::chunk_item::WorkerLoaderChunkItem;
18
19/// The WorkerLoaderModule is a module that creates a separate root chunk group for the given module
20/// and exports a URL to pass to the worker constructor.
21#[turbo_tasks::value]
22pub struct WorkerLoaderModule {
23    pub inner: ResolvedVc<Box<dyn ChunkableModule>>,
24}
25
26#[turbo_tasks::value_impl]
27impl WorkerLoaderModule {
28    #[turbo_tasks::function]
29    pub fn new(module: ResolvedVc<Box<dyn ChunkableModule>>) -> Vc<Self> {
30        Self::cell(WorkerLoaderModule { inner: module })
31    }
32
33    #[turbo_tasks::function]
34    pub fn asset_ident_for(module: Vc<Box<dyn ChunkableModule>>) -> Vc<AssetIdent> {
35        module.ident().with_modifier(rcstr!("worker loader"))
36    }
37}
38
39#[turbo_tasks::value_impl]
40impl Module for WorkerLoaderModule {
41    #[turbo_tasks::function]
42    fn ident(&self) -> Vc<AssetIdent> {
43        Self::asset_ident_for(*self.inner)
44    }
45
46    #[turbo_tasks::function]
47    fn source(&self) -> Vc<turbopack_core::source::OptionSource> {
48        Vc::cell(None)
49    }
50
51    #[turbo_tasks::function]
52    async fn references(self: Vc<Self>) -> Result<Vc<ModuleReferences>> {
53        Ok(Vc::cell(vec![ResolvedVc::upcast(
54            WorkerModuleReference::new(*ResolvedVc::upcast(self.await?.inner))
55                .to_resolved()
56                .await?,
57        )]))
58    }
59
60    #[turbo_tasks::function]
61    fn side_effects(self: Vc<Self>) -> Vc<ModuleSideEffects> {
62        ModuleSideEffects::SideEffectFree.cell()
63    }
64}
65
66#[turbo_tasks::value_impl]
67impl Asset for WorkerLoaderModule {
68    #[turbo_tasks::function]
69    fn content(&self) -> Vc<AssetContent> {
70        panic!("content() should not be called");
71    }
72}
73
74#[turbo_tasks::value_impl]
75impl ChunkableModule for WorkerLoaderModule {
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            WorkerLoaderChunkItem {
84                module: self,
85                module_graph,
86                chunking_context,
87            }
88            .cell(),
89        )
90    }
91}
92
93#[turbo_tasks::value]
94struct WorkerModuleReference {
95    module: ResolvedVc<Box<dyn Module>>,
96}
97
98#[turbo_tasks::value_impl]
99impl WorkerModuleReference {
100    #[turbo_tasks::function]
101    pub fn new(module: ResolvedVc<Box<dyn Module>>) -> Vc<Self> {
102        Self::cell(WorkerModuleReference { module })
103    }
104}
105
106#[turbo_tasks::value_impl]
107impl ChunkableModuleReference for WorkerModuleReference {
108    #[turbo_tasks::function]
109    fn chunking_type(self: Vc<Self>) -> Vc<ChunkingTypeOption> {
110        Vc::cell(Some(ChunkingType::Isolated {
111            _ty: ChunkGroupType::Evaluated,
112            merge_tag: None,
113        }))
114    }
115}
116
117#[turbo_tasks::value_impl]
118impl ModuleReference for WorkerModuleReference {
119    #[turbo_tasks::function]
120    fn resolve_reference(&self) -> Vc<ModuleResolveResult> {
121        *ModuleResolveResult::module(self.module)
122    }
123}
124
125#[turbo_tasks::value_impl]
126impl ValueToString for WorkerModuleReference {
127    #[turbo_tasks::function]
128    fn to_string(&self) -> Vc<RcStr> {
129        Vc::cell(rcstr!("worker module"))
130    }
131}