turbopack_ecmascript/worker_chunk/
chunk_item.rs1use anyhow::Result;
2use indoc::formatdoc;
3use turbo_rcstr::RcStr;
4use turbo_tasks::{ResolvedVc, TryJoinIterExt, Value, Vc};
5use turbopack_core::{
6 chunk::{
7 ChunkData, ChunkItem, ChunkType, ChunkingContext, ChunkingContextExt, ChunksData,
8 availability_info::AvailabilityInfo,
9 },
10 ident::AssetIdent,
11 module::Module,
12 module_graph::{ModuleGraph, chunk_group_info::ChunkGroup},
13 output::OutputAssets,
14};
15
16use super::module::WorkerLoaderModule;
17use crate::{
18 chunk::{
19 EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType,
20 data::EcmascriptChunkData,
21 },
22 runtime_functions::{TURBOPACK_EXPORT_VALUE, TURBOPACK_WORKER_BLOB_URL},
23 utils::StringifyJs,
24};
25
26#[turbo_tasks::value(shared)]
27pub struct WorkerLoaderChunkItem {
28 pub module: ResolvedVc<WorkerLoaderModule>,
29 pub module_graph: ResolvedVc<ModuleGraph>,
30 pub chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
31}
32
33#[turbo_tasks::function]
34pub fn worker_modifier() -> Vc<RcStr> {
35 Vc::cell("worker".into())
36}
37
38#[turbo_tasks::value_impl]
39impl WorkerLoaderChunkItem {
40 #[turbo_tasks::function]
41 async fn chunks(&self) -> Result<Vc<OutputAssets>> {
42 let module = self.module.await?;
43
44 Ok(self.chunking_context.evaluated_chunk_group_assets(
45 module.inner.ident().with_modifier(worker_modifier()),
46 ChunkGroup::Isolated(ResolvedVc::upcast(module.inner)),
47 *self.module_graph,
48 Value::new(AvailabilityInfo::Root),
49 ))
50 }
51
52 #[turbo_tasks::function]
53 async fn chunks_data(self: Vc<Self>) -> Result<Vc<ChunksData>> {
54 let this = self.await?;
55 Ok(ChunkData::from_assets(
56 this.chunking_context.output_root(),
57 self.chunks(),
58 ))
59 }
60}
61
62#[turbo_tasks::value_impl]
63impl EcmascriptChunkItem for WorkerLoaderChunkItem {
64 #[turbo_tasks::function]
65 async fn content(self: Vc<Self>) -> Result<Vc<EcmascriptChunkItemContent>> {
66 let chunks_data = self.chunks_data().await?;
67 let chunks_data = chunks_data.iter().try_join().await?;
68 let chunks_data: Vec<_> = chunks_data
69 .iter()
70 .map(|chunk_data| EcmascriptChunkData::new(chunk_data))
71 .collect();
72
73 let code = formatdoc! {
74 r#"
75 {TURBOPACK_EXPORT_VALUE}({TURBOPACK_WORKER_BLOB_URL}({chunks:#}));
76 "#,
77 chunks = StringifyJs(&chunks_data),
78 };
79
80 Ok(EcmascriptChunkItemContent {
81 inner_code: code.into(),
82 ..Default::default()
83 }
84 .into())
85 }
86}
87
88#[turbo_tasks::function]
89fn chunk_reference_description() -> Vc<RcStr> {
90 Vc::cell("worker chunk".into())
91}
92
93#[turbo_tasks::value_impl]
94impl ChunkItem for WorkerLoaderChunkItem {
95 #[turbo_tasks::function]
96 fn asset_ident(&self) -> Vc<AssetIdent> {
97 self.module.ident()
98 }
99
100 #[turbo_tasks::function]
101 fn content_ident(&self) -> Vc<AssetIdent> {
102 self.module.ident()
103 }
104
105 #[turbo_tasks::function]
106 fn references(self: Vc<Self>) -> Vc<OutputAssets> {
107 self.chunks()
108 }
109
110 #[turbo_tasks::function]
111 fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
112 *ResolvedVc::upcast(self.chunking_context)
113 }
114
115 #[turbo_tasks::function]
116 async fn ty(&self) -> Result<Vc<Box<dyn ChunkType>>> {
117 Ok(Vc::upcast(
118 Vc::<EcmascriptChunkType>::default().resolve().await?,
119 ))
120 }
121
122 #[turbo_tasks::function]
123 fn module(&self) -> Vc<Box<dyn Module>> {
124 *ResolvedVc::upcast(self.module)
125 }
126}