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,
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    async fn references(self: Vc<Self>) -> Result<Vc<ModuleReferences>> {
48        Ok(Vc::cell(vec![ResolvedVc::upcast(
49            WorkerModuleReference::new(*ResolvedVc::upcast(self.await?.inner))
50                .to_resolved()
51                .await?,
52        )]))
53    }
54}
55
56#[turbo_tasks::value_impl]
57impl Asset for WorkerLoaderModule {
58    #[turbo_tasks::function]
59    fn content(&self) -> Vc<AssetContent> {
60        panic!("content() should not be called");
61    }
62}
63
64#[turbo_tasks::value_impl]
65impl ChunkableModule for WorkerLoaderModule {
66    #[turbo_tasks::function]
67    fn as_chunk_item(
68        self: ResolvedVc<Self>,
69        module_graph: ResolvedVc<ModuleGraph>,
70        chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
71    ) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
72        Vc::upcast(
73            WorkerLoaderChunkItem {
74                module: self,
75                module_graph,
76                chunking_context,
77            }
78            .cell(),
79        )
80    }
81}
82
83#[turbo_tasks::value]
84struct WorkerModuleReference {
85    module: ResolvedVc<Box<dyn Module>>,
86}
87
88#[turbo_tasks::value_impl]
89impl WorkerModuleReference {
90    #[turbo_tasks::function]
91    pub fn new(module: ResolvedVc<Box<dyn Module>>) -> Vc<Self> {
92        Self::cell(WorkerModuleReference { module })
93    }
94}
95
96#[turbo_tasks::value_impl]
97impl ChunkableModuleReference for WorkerModuleReference {
98    #[turbo_tasks::function]
99    fn chunking_type(self: Vc<Self>) -> Vc<ChunkingTypeOption> {
100        Vc::cell(Some(ChunkingType::Isolated {
101            _ty: ChunkGroupType::Evaluated,
102            merge_tag: None,
103        }))
104    }
105}
106
107#[turbo_tasks::value_impl]
108impl ModuleReference for WorkerModuleReference {
109    #[turbo_tasks::function]
110    fn resolve_reference(&self) -> Vc<ModuleResolveResult> {
111        *ModuleResolveResult::module(self.module)
112    }
113}
114
115#[turbo_tasks::value_impl]
116impl ValueToString for WorkerModuleReference {
117    #[turbo_tasks::function]
118    fn to_string(&self) -> Vc<RcStr> {
119        Vc::cell(rcstr!("worker module"))
120    }
121}