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