turbopack_ecmascript/worker_chunk/
chunk_item.rs1use anyhow::Result;
2use indoc::formatdoc;
3use turbo_rcstr::rcstr;
4use turbo_tasks::{ResolvedVc, TryJoinIterExt, 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::value_impl]
34impl WorkerLoaderChunkItem {
35 #[turbo_tasks::function]
36 async fn chunks(&self) -> Result<Vc<OutputAssets>> {
37 let module = self.module.await?;
38
39 Ok(self.chunking_context.evaluated_chunk_group_assets(
40 module.inner.ident().with_modifier(rcstr!("worker")),
41 ChunkGroup::Isolated(ResolvedVc::upcast(module.inner)),
42 *self.module_graph,
43 AvailabilityInfo::Root,
44 ))
45 }
46
47 #[turbo_tasks::function]
48 async fn chunks_data(self: Vc<Self>) -> Result<Vc<ChunksData>> {
49 let this = self.await?;
50 Ok(ChunkData::from_assets(
51 this.chunking_context.output_root().owned().await?,
52 self.chunks(),
53 ))
54 }
55}
56
57#[turbo_tasks::value_impl]
58impl EcmascriptChunkItem for WorkerLoaderChunkItem {
59 #[turbo_tasks::function]
60 async fn content(self: Vc<Self>) -> Result<Vc<EcmascriptChunkItemContent>> {
61 let chunks_data = self.chunks_data().await?;
62 let chunks_data = chunks_data.iter().try_join().await?;
63 let chunks_data: Vec<_> = chunks_data
64 .iter()
65 .map(|chunk_data| EcmascriptChunkData::new(chunk_data))
66 .collect();
67
68 let code = formatdoc! {
69 r#"
70 {TURBOPACK_EXPORT_VALUE}({TURBOPACK_WORKER_BLOB_URL}({chunks:#}));
71 "#,
72 chunks = StringifyJs(&chunks_data),
73 };
74
75 Ok(EcmascriptChunkItemContent {
76 inner_code: code.into(),
77 ..Default::default()
78 }
79 .into())
80 }
81}
82
83#[turbo_tasks::value_impl]
84impl ChunkItem for WorkerLoaderChunkItem {
85 #[turbo_tasks::function]
86 fn asset_ident(&self) -> Vc<AssetIdent> {
87 self.module.ident()
88 }
89
90 #[turbo_tasks::function]
91 fn content_ident(&self) -> Vc<AssetIdent> {
92 self.module.ident()
93 }
94
95 #[turbo_tasks::function]
96 fn references(self: Vc<Self>) -> Vc<OutputAssets> {
97 self.chunks()
98 }
99
100 #[turbo_tasks::function]
101 fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
102 *ResolvedVc::upcast(self.chunking_context)
103 }
104
105 #[turbo_tasks::function]
106 async fn ty(&self) -> Result<Vc<Box<dyn ChunkType>>> {
107 Ok(Vc::upcast(
108 Vc::<EcmascriptChunkType>::default().resolve().await?,
109 ))
110 }
111
112 #[turbo_tasks::function]
113 fn module(&self) -> Vc<Box<dyn Module>> {
114 *ResolvedVc::upcast(self.module)
115 }
116}