turbopack_dev_server/source/
wrapping_source.rs1use anyhow::Result;
2use turbo_rcstr::RcStr;
3use turbo_tasks::{OperationVc, ResolvedVc, TryJoinIterExt, Value, Vc};
4
5use super::{
6 ContentSourceContent, ContentSourceData, ContentSourceDataVary, GetContentSourceContent,
7 GetContentSourceContents, Rewrite, RewriteType,
8};
9
10#[turbo_tasks::value_trait]
18pub trait ContentSourceProcessor {
19 fn process(self: Vc<Self>, content: Vc<ContentSourceContent>) -> Vc<ContentSourceContent>;
20}
21
22#[turbo_tasks::value]
27pub struct WrappedGetContentSourceContent {
28 inner: ResolvedVc<Box<dyn GetContentSourceContent>>,
29 processor: ResolvedVc<Box<dyn ContentSourceProcessor>>,
30}
31
32#[turbo_tasks::value_impl]
33impl WrappedGetContentSourceContent {
34 #[turbo_tasks::function]
35 pub fn new(
36 inner: ResolvedVc<Box<dyn GetContentSourceContent>>,
37 processor: ResolvedVc<Box<dyn ContentSourceProcessor>>,
38 ) -> Vc<Self> {
39 WrappedGetContentSourceContent { inner, processor }.cell()
40 }
41}
42
43#[turbo_tasks::function(operation)]
44async fn wrap_sources_operation(
45 sources: OperationVc<GetContentSourceContents>,
46 processor: ResolvedVc<Box<dyn ContentSourceProcessor>>,
47) -> Result<Vc<GetContentSourceContents>> {
48 Ok(Vc::cell(
49 sources
50 .connect()
51 .await?
52 .iter()
53 .map(|s| {
54 Vc::upcast::<Box<dyn GetContentSourceContent>>(WrappedGetContentSourceContent::new(
55 **s, *processor,
56 ))
57 })
58 .map(|v| async move { v.to_resolved().await })
59 .try_join()
60 .await?,
61 ))
62}
63
64#[turbo_tasks::value_impl]
65impl GetContentSourceContent for WrappedGetContentSourceContent {
66 #[turbo_tasks::function]
67 fn vary(&self) -> Vc<ContentSourceDataVary> {
68 self.inner.vary()
69 }
70
71 #[turbo_tasks::function]
72 async fn get(
73 &self,
74 path: RcStr,
75 data: Value<ContentSourceData>,
76 ) -> Result<Vc<ContentSourceContent>> {
77 let res = self.inner.get(path, data);
78 if let ContentSourceContent::Rewrite(rewrite) = &*res.await? {
79 let rewrite = rewrite.await?;
80 return Ok(ContentSourceContent::Rewrite(
81 Rewrite {
82 ty: match &rewrite.ty {
83 RewriteType::Location { .. } | RewriteType::ContentSource { .. } => todo!(
84 "Rewrites for WrappedGetContentSourceContent are not implemented yet"
85 ),
86 RewriteType::Sources { sources } => RewriteType::Sources {
87 sources: wrap_sources_operation(*sources, self.processor),
88 },
89 },
90 response_headers: rewrite.response_headers,
91 request_headers: rewrite.request_headers,
92 }
93 .resolved_cell(),
94 )
95 .cell());
96 }
97 Ok(self.processor.process(res))
98 }
99}