turbopack_browser/ecmascript/
chunk.rs1use anyhow::Result;
2use turbo_rcstr::{RcStr, rcstr};
3use turbo_tasks::{FxIndexSet, ResolvedVc, ValueToString, Vc};
4use turbo_tasks_fs::FileSystemPath;
5use turbopack_core::{
6 asset::{Asset, AssetContent},
7 chunk::{Chunk, ChunkingContext, OutputChunk, OutputChunkRuntimeInfo},
8 ident::AssetIdent,
9 introspect::{Introspectable, IntrospectableChildren},
10 output::{OutputAsset, OutputAssets},
11 source_map::{GenerateSourceMap, OptionStringifiedSourceMap, SourceMapAsset},
12 version::VersionedContent,
13};
14use turbopack_ecmascript::chunk::EcmascriptChunk;
15
16use crate::{BrowserChunkingContext, ecmascript::content::EcmascriptBrowserChunkContent};
17
18#[turbo_tasks::value(shared)]
20pub struct EcmascriptBrowserChunk {
21 chunking_context: ResolvedVc<BrowserChunkingContext>,
22 chunk: ResolvedVc<EcmascriptChunk>,
23}
24
25#[turbo_tasks::value_impl]
26impl EcmascriptBrowserChunk {
27 #[turbo_tasks::function]
29 pub fn new(
30 chunking_context: ResolvedVc<BrowserChunkingContext>,
31 chunk: ResolvedVc<EcmascriptChunk>,
32 ) -> Vc<Self> {
33 EcmascriptBrowserChunk {
34 chunking_context,
35 chunk,
36 }
37 .cell()
38 }
39
40 #[turbo_tasks::function]
41 async fn source_map(self: Vc<Self>) -> Result<Vc<SourceMapAsset>> {
42 let this = self.await?;
43 Ok(SourceMapAsset::new(
44 Vc::upcast(*this.chunking_context),
45 this.ident_for_path(),
46 Vc::upcast(self),
47 ))
48 }
49}
50
51impl EcmascriptBrowserChunk {
52 fn ident_for_path(&self) -> Vc<AssetIdent> {
53 self.chunk
54 .ident()
55 .with_modifier(rcstr!("ecmascript dev chunk"))
56 }
57}
58
59#[turbo_tasks::value_impl]
60impl ValueToString for EcmascriptBrowserChunk {
61 #[turbo_tasks::function]
62 fn to_string(&self) -> Vc<RcStr> {
63 Vc::cell(rcstr!("Ecmascript Dev Chunk"))
64 }
65}
66
67#[turbo_tasks::value_impl]
68impl OutputChunk for EcmascriptBrowserChunk {
69 #[turbo_tasks::function]
70 async fn runtime_info(&self) -> Result<Vc<OutputChunkRuntimeInfo>> {
71 Ok(OutputChunkRuntimeInfo {
72 included_ids: Some(self.chunk.entry_ids().to_resolved().await?),
73 ..Default::default()
74 }
75 .cell())
76 }
77}
78
79#[turbo_tasks::value_impl]
80impl EcmascriptBrowserChunk {
81 #[turbo_tasks::function]
82 async fn own_content(self: Vc<Self>) -> Result<Vc<EcmascriptBrowserChunkContent>> {
83 let this = self.await?;
84 Ok(EcmascriptBrowserChunkContent::new(
85 *this.chunking_context,
86 self,
87 this.chunk.chunk_content(),
88 self.source_map(),
89 ))
90 }
91
92 #[turbo_tasks::function]
93 pub fn chunk(&self) -> Result<Vc<Box<dyn Chunk>>> {
94 Ok(Vc::upcast(*self.chunk))
95 }
96}
97
98#[turbo_tasks::value_impl]
99impl OutputAsset for EcmascriptBrowserChunk {
100 #[turbo_tasks::function]
101 async fn path(self: Vc<Self>) -> Result<Vc<FileSystemPath>> {
102 let this = self.await?;
103 let ident = this.ident_for_path();
104 Ok(this
105 .chunking_context
106 .chunk_path(Some(Vc::upcast(self)), ident, rcstr!(".js")))
107 }
108
109 #[turbo_tasks::function]
110 fn size_bytes(self: Vc<Self>) -> Vc<Option<u64>> {
111 self.own_content().content().len()
112 }
113
114 #[turbo_tasks::function]
115 async fn references(self: Vc<Self>) -> Result<Vc<OutputAssets>> {
116 let this = self.await?;
117 let chunk_references = this.chunk.references().await?;
118 let include_source_map = *this
119 .chunking_context
120 .reference_chunk_source_maps(Vc::upcast(self))
121 .await?;
122 let mut references =
123 Vec::with_capacity(chunk_references.len() + if include_source_map { 1 } else { 0 });
124
125 references.extend(chunk_references.iter().copied());
126
127 if include_source_map {
128 references.push(ResolvedVc::upcast(self.source_map().to_resolved().await?));
129 }
130
131 Ok(Vc::cell(references))
132 }
133}
134
135#[turbo_tasks::value_impl]
136impl Asset for EcmascriptBrowserChunk {
137 #[turbo_tasks::function]
138 fn content(self: Vc<Self>) -> Vc<AssetContent> {
139 self.own_content().content()
140 }
141
142 #[turbo_tasks::function]
143 fn versioned_content(self: Vc<Self>) -> Vc<Box<dyn VersionedContent>> {
144 Vc::upcast(self.own_content())
145 }
146}
147
148#[turbo_tasks::value_impl]
149impl GenerateSourceMap for EcmascriptBrowserChunk {
150 #[turbo_tasks::function]
151 fn generate_source_map(self: Vc<Self>) -> Vc<OptionStringifiedSourceMap> {
152 self.own_content().generate_source_map()
153 }
154
155 #[turbo_tasks::function]
156 fn by_section(self: Vc<Self>, section: RcStr) -> Vc<OptionStringifiedSourceMap> {
157 self.own_content().by_section(section)
158 }
159}
160
161#[turbo_tasks::value_impl]
162impl Introspectable for EcmascriptBrowserChunk {
163 #[turbo_tasks::function]
164 fn ty(&self) -> Vc<RcStr> {
165 Vc::cell(rcstr!("dev ecmascript chunk"))
166 }
167
168 #[turbo_tasks::function]
169 fn title(self: Vc<Self>) -> Vc<RcStr> {
170 self.path().to_string()
171 }
172
173 #[turbo_tasks::function]
174 fn details(&self) -> Vc<RcStr> {
175 Vc::cell(rcstr!("generates a development ecmascript chunk"))
176 }
177
178 #[turbo_tasks::function]
179 fn children(&self) -> Result<Vc<IntrospectableChildren>> {
180 let mut children = FxIndexSet::default();
181 let chunk = ResolvedVc::upcast::<Box<dyn Introspectable>>(self.chunk);
182 children.insert((rcstr!("chunk"), chunk));
183 Ok(Vc::cell(children))
184 }
185}