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