1use anyhow::Result;
2use turbo_rcstr::rcstr;
3use turbo_tasks::{ResolvedVc, Vc};
4use turbopack_core::{
5 asset::{Asset, AssetContent},
6 chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext},
7 ident::AssetIdent,
8 module::Module,
9 module_graph::ModuleGraph,
10 output::{OutputAsset, OutputAssets},
11 source::Source,
12};
13use turbopack_ecmascript::{
14 chunk::{
15 EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
16 EcmascriptChunkType, EcmascriptExports,
17 },
18 runtime_functions::TURBOPACK_EXPORT_VALUE,
19 utils::StringifyJs,
20};
21
22use crate::output_asset::StaticOutputAsset;
23
24#[turbo_tasks::value]
25#[derive(Clone)]
26pub struct StaticUrlJsModule {
27 pub source: ResolvedVc<Box<dyn Source>>,
28}
29
30#[turbo_tasks::value_impl]
31impl StaticUrlJsModule {
32 #[turbo_tasks::function]
33 pub fn new(source: ResolvedVc<Box<dyn Source>>) -> Vc<Self> {
34 Self::cell(StaticUrlJsModule { source })
35 }
36
37 #[turbo_tasks::function]
38 fn static_output_asset(
39 &self,
40 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
41 ) -> Vc<StaticOutputAsset> {
42 StaticOutputAsset::new(*chunking_context, *self.source)
43 }
44}
45
46#[turbo_tasks::value_impl]
47impl Module for StaticUrlJsModule {
48 #[turbo_tasks::function]
49 fn ident(&self) -> Vc<AssetIdent> {
50 self.source
51 .ident()
52 .with_modifier(rcstr!("static in ecmascript"))
53 }
54}
55
56#[turbo_tasks::value_impl]
57impl Asset for StaticUrlJsModule {
58 #[turbo_tasks::function]
59 fn content(&self) -> Vc<AssetContent> {
60 self.source.content()
61 }
62}
63
64#[turbo_tasks::value_impl]
65impl ChunkableModule for StaticUrlJsModule {
66 #[turbo_tasks::function]
67 async fn as_chunk_item(
68 self: ResolvedVc<Self>,
69 _module_graph: Vc<ModuleGraph>,
70 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
71 ) -> Result<Vc<Box<dyn turbopack_core::chunk::ChunkItem>>> {
72 Ok(Vc::upcast(StaticUrlJsChunkItem::cell(
73 StaticUrlJsChunkItem {
74 module: self,
75 chunking_context,
76 static_asset: self
77 .static_output_asset(*ResolvedVc::upcast(chunking_context))
78 .to_resolved()
79 .await?,
80 },
81 )))
82 }
83}
84
85#[turbo_tasks::value_impl]
86impl EcmascriptChunkPlaceable for StaticUrlJsModule {
87 #[turbo_tasks::function]
88 fn get_exports(&self) -> Vc<EcmascriptExports> {
89 EcmascriptExports::Value.into()
90 }
91}
92
93#[turbo_tasks::value]
94struct StaticUrlJsChunkItem {
95 module: ResolvedVc<StaticUrlJsModule>,
96 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
97 static_asset: ResolvedVc<StaticOutputAsset>,
98}
99
100#[turbo_tasks::value_impl]
101impl ChunkItem for StaticUrlJsChunkItem {
102 #[turbo_tasks::function]
103 fn asset_ident(&self) -> Vc<AssetIdent> {
104 self.module.ident()
105 }
106
107 #[turbo_tasks::function]
108 fn references(&self) -> Vc<OutputAssets> {
109 Vc::cell(vec![ResolvedVc::upcast(self.static_asset)])
110 }
111
112 #[turbo_tasks::function]
113 fn chunking_context(&self) -> Vc<Box<dyn ChunkingContext>> {
114 *ResolvedVc::upcast(self.chunking_context)
115 }
116
117 #[turbo_tasks::function]
118 async fn ty(&self) -> Result<Vc<Box<dyn ChunkType>>> {
119 Ok(Vc::upcast(
120 Vc::<EcmascriptChunkType>::default().resolve().await?,
121 ))
122 }
123
124 #[turbo_tasks::function]
125 fn module(&self) -> Vc<Box<dyn Module>> {
126 *ResolvedVc::upcast(self.module)
127 }
128}
129
130#[turbo_tasks::value_impl]
131impl EcmascriptChunkItem for StaticUrlJsChunkItem {
132 #[turbo_tasks::function]
133 async fn content(&self) -> Result<Vc<EcmascriptChunkItemContent>> {
134 Ok(EcmascriptChunkItemContent {
135 inner_code: format!(
136 "{TURBOPACK_EXPORT_VALUE}({path});",
137 path = StringifyJs(
138 &self
139 .chunking_context
140 .asset_url(self.static_asset.path().await?.clone_value())
141 .await?
142 )
143 )
144 .into(),
145 ..Default::default()
146 }
147 .into())
148 }
149}
150
151pub fn register() {
152 turbo_tasks::register();
153 turbo_tasks_fs::register();
154 turbopack_core::register();
155 turbopack_ecmascript::register();
156 include!(concat!(env!("OUT_DIR"), "/register.rs"));
157}