turbopack_ecmascript/worker_chunk/
module.rs

1use anyhow::Result;
2use turbo_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#[turbo_tasks::function]
20fn modifier() -> Vc<RcStr> {
21    Vc::cell("worker loader".into())
22}
23
24/// The WorkerLoaderModule is a module that creates a separate root chunk group for the given module
25/// and exports a URL to pass to the worker constructor.
26#[turbo_tasks::value]
27pub struct WorkerLoaderModule {
28    pub inner: ResolvedVc<Box<dyn ChunkableModule>>,
29}
30
31#[turbo_tasks::value_impl]
32impl WorkerLoaderModule {
33    #[turbo_tasks::function]
34    pub fn new(module: ResolvedVc<Box<dyn ChunkableModule>>) -> Vc<Self> {
35        Self::cell(WorkerLoaderModule { inner: module })
36    }
37
38    #[turbo_tasks::function]
39    pub fn asset_ident_for(module: Vc<Box<dyn ChunkableModule>>) -> Vc<AssetIdent> {
40        module.ident().with_modifier(modifier())
41    }
42}
43
44#[turbo_tasks::value_impl]
45impl Module for WorkerLoaderModule {
46    #[turbo_tasks::function]
47    fn ident(&self) -> Vc<AssetIdent> {
48        Self::asset_ident_for(*self.inner)
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
61#[turbo_tasks::value_impl]
62impl Asset for WorkerLoaderModule {
63    #[turbo_tasks::function]
64    fn content(&self) -> Vc<AssetContent> {
65        panic!("content() should not be called");
66    }
67}
68
69#[turbo_tasks::value_impl]
70impl ChunkableModule for WorkerLoaderModule {
71    #[turbo_tasks::function]
72    fn as_chunk_item(
73        self: ResolvedVc<Self>,
74        module_graph: ResolvedVc<ModuleGraph>,
75        chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
76    ) -> Vc<Box<dyn turbopack_core::chunk::ChunkItem>> {
77        Vc::upcast(
78            WorkerLoaderChunkItem {
79                module: self,
80                module_graph,
81                chunking_context,
82            }
83            .cell(),
84        )
85    }
86}
87
88#[turbo_tasks::value]
89struct WorkerModuleReference {
90    module: ResolvedVc<Box<dyn Module>>,
91}
92
93#[turbo_tasks::value_impl]
94impl WorkerModuleReference {
95    #[turbo_tasks::function]
96    pub fn new(module: ResolvedVc<Box<dyn Module>>) -> Vc<Self> {
97        Self::cell(WorkerModuleReference { module })
98    }
99}
100
101#[turbo_tasks::value_impl]
102impl ChunkableModuleReference for WorkerModuleReference {
103    #[turbo_tasks::function]
104    fn chunking_type(self: Vc<Self>) -> Vc<ChunkingTypeOption> {
105        Vc::cell(Some(ChunkingType::Isolated {
106            _ty: ChunkGroupType::Evaluated,
107            merge_tag: None,
108        }))
109    }
110}
111
112#[turbo_tasks::value_impl]
113impl ModuleReference for WorkerModuleReference {
114    #[turbo_tasks::function]
115    fn resolve_reference(&self) -> Vc<ModuleResolveResult> {
116        *ModuleResolveResult::module(self.module)
117    }
118}
119
120#[turbo_tasks::value_impl]
121impl ValueToString for WorkerModuleReference {
122    #[turbo_tasks::function]
123    fn to_string(&self) -> Vc<RcStr> {
124        Vc::cell("worker module".into())
125    }
126}