turbopack_core/source_map/
source_map_asset.rs1use anyhow::Result;
2use bincode::{Decode, Encode};
3use turbo_rcstr::{RcStr, rcstr};
4use turbo_tasks::{
5 FxIndexSet, NonLocalValue, ResolvedVc, ValueToString, Vc, debug::ValueDebugFormat,
6};
7use turbo_tasks_fs::{File, FileContent, FileSystemPath};
8
9use crate::{
10 asset::{Asset, AssetContent},
11 chunk::ChunkingContext,
12 ident::AssetIdent,
13 introspect::{Introspectable, IntrospectableChildren},
14 output::{OutputAsset, OutputAssetsReference},
15 source_map::{GenerateSourceMap, SourceMap},
16};
17
18#[derive(PartialEq, Eq, NonLocalValue, ValueDebugFormat, Encode, Decode)]
19enum PathType {
20 Fixed {
21 path: FileSystemPath,
22 },
23 FromIdent {
24 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
25 ident_for_path: ResolvedVc<AssetIdent>,
26 },
27}
28
29#[turbo_tasks::value]
31pub struct SourceMapAsset {
32 path_ty: PathType,
33 generate_source_map: ResolvedVc<Box<dyn GenerateSourceMap>>,
34}
35
36#[turbo_tasks::value_impl]
37impl SourceMapAsset {
38 #[turbo_tasks::function]
39 pub fn new(
40 chunking_context: ResolvedVc<Box<dyn ChunkingContext>>,
41 ident_for_path: ResolvedVc<AssetIdent>,
42 generate_source_map: ResolvedVc<Box<dyn GenerateSourceMap>>,
43 ) -> Vc<Self> {
44 SourceMapAsset {
45 path_ty: PathType::FromIdent {
46 chunking_context,
47 ident_for_path,
48 },
49 generate_source_map,
50 }
51 .cell()
52 }
53
54 #[turbo_tasks::function]
55 pub fn new_fixed(
56 path: FileSystemPath,
57 generate_source_map: ResolvedVc<Box<dyn GenerateSourceMap>>,
58 ) -> Vc<Self> {
59 SourceMapAsset {
60 path_ty: PathType::Fixed { path },
61 generate_source_map,
62 }
63 .cell()
64 }
65}
66
67#[turbo_tasks::value_impl]
68impl OutputAssetsReference for SourceMapAsset {}
69
70#[turbo_tasks::value_impl]
71impl OutputAsset for SourceMapAsset {
72 #[turbo_tasks::function]
73 async fn path(self: Vc<Self>) -> Result<Vc<FileSystemPath>> {
74 let this = self.await?;
77 Ok(match &this.path_ty {
78 PathType::FromIdent {
79 chunking_context,
80 ident_for_path,
81 } => chunking_context
82 .chunk_path(
83 Some(Vc::upcast(self)),
84 **ident_for_path,
85 None,
86 rcstr!(".js"),
87 )
88 .await?
89 .append(".map")?
90 .cell(),
91 PathType::Fixed { path } => path.append(".map")?.cell(),
92 })
93 }
94}
95
96#[turbo_tasks::value_impl]
97impl Asset for SourceMapAsset {
98 #[turbo_tasks::function]
99 async fn content(&self) -> Result<Vc<AssetContent>> {
100 let content = self.generate_source_map.generate_source_map();
101 if content.await?.is_content() {
102 Ok(AssetContent::file(content))
103 } else {
104 Ok(AssetContent::file(
105 FileContent::Content(File::from(SourceMap::empty_rope())).cell(),
106 ))
107 }
108 }
109}
110
111#[turbo_tasks::value_impl]
112impl Introspectable for SourceMapAsset {
113 #[turbo_tasks::function]
114 fn ty(&self) -> Vc<RcStr> {
115 Vc::cell(rcstr!("source map"))
116 }
117
118 #[turbo_tasks::function]
119 fn title(self: Vc<Self>) -> Vc<RcStr> {
120 self.path().to_string()
121 }
122
123 #[turbo_tasks::function]
124 fn details(&self) -> Vc<RcStr> {
125 Vc::cell(rcstr!("source map of an asset"))
126 }
127
128 #[turbo_tasks::function]
129 fn children(&self) -> Result<Vc<IntrospectableChildren>> {
130 let mut children = FxIndexSet::default();
131 if let Some(asset) =
132 ResolvedVc::try_sidecast::<Box<dyn Introspectable>>(self.generate_source_map)
133 {
134 children.insert((rcstr!("asset"), asset));
135 }
136 Ok(Vc::cell(children))
137 }
138}