diff --git a/crates/next-api/src/module_graph.rs b/crates/next-api/src/module_graph.rs index e9991ea1715f90..0c7928140071e9 100644 --- a/crates/next-api/src/module_graph.rs +++ b/crates/next-api/src/module_graph.rs @@ -1098,9 +1098,9 @@ impl ReducedGraphs { } } -#[turbo_tasks::function] -async fn get_reduced_graphs_for_endpoint_inner( - project: Vc, +#[turbo_tasks::function(operation)] +async fn get_reduced_graphs_for_endpoint_inner_operation( + project: ResolvedVc, entry: ResolvedVc>, ) -> Result> { let (is_single_page, graphs) = match &*project.next_mode().await? { @@ -1172,15 +1172,16 @@ async fn get_reduced_graphs_for_endpoint_inner( /// references, etc). #[turbo_tasks::function] pub async fn get_reduced_graphs_for_endpoint( - project: Vc, - entry: Vc>, + project: ResolvedVc, + entry: ResolvedVc>, ) -> Result> { // TODO get rid of this function once everything inside of // `get_reduced_graphs_for_endpoint_inner` calls `take_collectibles()` when needed - let result = get_reduced_graphs_for_endpoint_inner(project, entry); + let result_op = get_reduced_graphs_for_endpoint_inner_operation(project, entry); + let result_vc = result_op.connect(); if project.next_mode().await?.is_production() { - result.strongly_consistent().await?; - let _issues = result.take_collectibles::>(); + result_vc.strongly_consistent().await?; + let _issues = result_op.take_collectibles::>(); } - Ok(result) + Ok(result_vc) } diff --git a/turbopack/crates/turbopack-dev-server/src/http.rs b/turbopack/crates/turbopack-dev-server/src/http.rs index 2bb4e1369bd997..61c26454752e27 100644 --- a/turbopack/crates/turbopack-dev-server/src/http.rs +++ b/turbopack/crates/turbopack-dev-server/src/http.rs @@ -43,7 +43,7 @@ enum GetFromSourceResult { /// Resolves a [SourceRequest] within a [super::ContentSource], returning the /// corresponding content as a #[turbo_tasks::function(operation)] -async fn get_from_source( +async fn get_from_source_operation( source: OperationVc>, request: TransientInstance, ) -> Result> { @@ -63,7 +63,7 @@ async fn get_from_source( } } ResolveSourceRequestResult::HttpProxy(proxy) => { - GetFromSourceResult::HttpProxy(proxy.await?) + GetFromSourceResult::HttpProxy(proxy.connect().await?) } ResolveSourceRequestResult::NotFound => GetFromSourceResult::NotFound, } @@ -83,7 +83,7 @@ pub async fn process_request_with_content_source( )> { let original_path = request.uri().path().to_string(); let request = http_request_to_source_request(request).await?; - let result_op = get_from_source(source, TransientInstance::new(request)); + let result_op = get_from_source_operation(source, TransientInstance::new(request)); let result_vc = result_op.connect(); let resolved_result = result_vc.resolve_strongly_consistent().await?; apply_effects(result_op).await?; @@ -93,7 +93,7 @@ pub async fn process_request_with_content_source( issue_reporter, IssueSeverity::Fatal.cell(), Some(&original_path), - Some("get_from_source"), + Some("get_from_source_operation"), ) .await?; match &*resolved_result.await? { diff --git a/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs b/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs index 4fbcbbc0d4e96b..4b87068f418aca 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs @@ -55,11 +55,10 @@ impl ContentSource for IssueFilePathContentSource { #[turbo_tasks::function] async fn get_routes(self: ResolvedVc) -> Result> { let this = self.await?; - let routes = this - .source - .get_routes() + let routes = content_source_get_routes_operation(this.source) .issue_file_path(this.file_path.map(|v| *v), &*this.description) - .await?; + .await? + .connect(); Ok(routes.map_routes(Vc::upcast( IssueContextContentSourceMapper { source: self }.cell(), ))) @@ -71,6 +70,13 @@ impl ContentSource for IssueFilePathContentSource { } } +#[turbo_tasks::function(operation)] +fn content_source_get_routes_operation( + source: ResolvedVc>, +) -> Vc { + source.get_routes() +} + #[turbo_tasks::value] struct IssueContextContentSourceMapper { source: ResolvedVc, @@ -104,12 +110,10 @@ impl GetContentSourceContent for IssueContextGetContentSourceContent { #[turbo_tasks::function] async fn vary(&self) -> Result> { let source = self.source.await?; - let result = self - .get_content - .vary() + Ok(get_content_source_vary_operation(self.get_content) .issue_file_path(source.file_path.map(|v| *v), &*source.description) - .await?; - Ok(result) + .await? + .connect()) } #[turbo_tasks::function] @@ -119,15 +123,31 @@ impl GetContentSourceContent for IssueContextGetContentSourceContent { data: Value, ) -> Result> { let source = self.source.await?; - let result = self - .get_content - .get(path, data) - .issue_file_path(source.file_path.map(|v| *v), &*source.description) - .await?; - Ok(result) + Ok( + get_content_source_get_operation(self.get_content, path, data) + .issue_file_path(source.file_path.map(|v| *v), &*source.description) + .await? + .connect(), + ) } } +#[turbo_tasks::function(operation)] +fn get_content_source_vary_operation( + get_content: ResolvedVc>, +) -> Vc { + get_content.vary() +} + +#[turbo_tasks::function(operation)] +fn get_content_source_get_operation( + get_content: ResolvedVc>, + path: RcStr, + data: Value, +) -> Vc { + get_content.get(path, data) +} + #[turbo_tasks::value_impl] impl Introspectable for IssueFilePathContentSource { #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-dev-server/src/source/mod.rs b/turbopack/crates/turbopack-dev-server/src/source/mod.rs index f11b6cb8b3feb7..3f8c31f03dd3c0 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/mod.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/mod.rs @@ -19,8 +19,8 @@ use futures::{stream::Stream as StreamTrait, TryStreamExt}; use serde::{Deserialize, Serialize}; use turbo_rcstr::RcStr; use turbo_tasks::{ - trace::TraceRawVcs, util::SharedError, Completion, NonLocalValue, ResolvedVc, Upcast, Value, - ValueDefault, Vc, + trace::TraceRawVcs, util::SharedError, Completion, NonLocalValue, OperationVc, ResolvedVc, + Upcast, Value, ValueDefault, Vc, }; use turbo_tasks_bytes::{Bytes, Stream, StreamRead}; use turbo_tasks_fs::FileSystemPath; @@ -92,7 +92,7 @@ pub struct StaticContent { pub enum ContentSourceContent { NotFound, Static(ResolvedVc), - HttpProxy(ResolvedVc), + HttpProxy(OperationVc), Rewrite(ResolvedVc), /// Continue with the next route Next, diff --git a/turbopack/crates/turbopack-dev-server/src/source/resolve.rs b/turbopack/crates/turbopack-dev-server/src/source/resolve.rs index 94e0574e6cb6d3..69e43b91c24a63 100644 --- a/turbopack/crates/turbopack-dev-server/src/source/resolve.rs +++ b/turbopack/crates/turbopack-dev-server/src/source/resolve.rs @@ -26,7 +26,7 @@ use super::{ pub enum ResolveSourceRequestResult { NotFound, Static(ResolvedVc, ResolvedVc), - HttpProxy(Vc), + HttpProxy(OperationVc), } /// Resolves a [SourceRequest] within a [super::ContentSource], returning the @@ -120,7 +120,7 @@ pub async fn resolve_source_request( .cell()); } ContentSourceContent::HttpProxy(proxy_result) => { - return Ok(ResolveSourceRequestResult::HttpProxy(**proxy_result).cell()); + return Ok(ResolveSourceRequestResult::HttpProxy(*proxy_result).cell()); } ContentSourceContent::Next => continue, } diff --git a/turbopack/crates/turbopack-dev-server/src/update/stream.rs b/turbopack/crates/turbopack-dev-server/src/update/stream.rs index 80ba3f4b29a28b..71daef8c81edde 100644 --- a/turbopack/crates/turbopack-dev-server/src/update/stream.rs +++ b/turbopack/crates/turbopack-dev-server/src/update/stream.rs @@ -25,7 +25,7 @@ use crate::source::{resolve::ResolveSourceRequestResult, ProxyResult}; type GetContentFn = Box OperationVc + Send + Sync>; -async fn peek_issues(source: Vc) -> Result>> { +async fn peek_issues(source: OperationVc) -> Result>> { let captured = source.peek_issues_with_path().await?; captured.get_plain_issues().await @@ -41,15 +41,24 @@ fn extend_issues(issues: &mut Vec>, new_issues: Vec>, + from: ResolvedVc>, +) -> Vc { + content.update(*from) +} + #[turbo_tasks::function] async fn get_update_stream_item( resource: RcStr, from: Vc, get_content: TransientInstance, ) -> Result> { - let content_vc = get_content().connect(); + let content_op = get_content(); + let content_vc = content_op.connect(); let content_result = content_vc.strongly_consistent().await; - let mut plain_issues = peek_issues(content_vc).await?; + let mut plain_issues = peek_issues(content_op).await?; let content_value = match content_result { Ok(content) => content, @@ -89,27 +98,26 @@ async fn get_update_stream_item( } let resolved_content = static_content.content; - let from = from.get(); - let update = resolved_content.update(from); + let from = from.get().to_resolved().await?; + let update_op = versioned_content_update_operation(resolved_content, from); - extend_issues(&mut plain_issues, peek_issues(update).await?); - - let update = update.await?; + extend_issues(&mut plain_issues, peek_issues(update_op).await?); Ok(UpdateStreamItem::Found { - update, + update: update_op.connect().await?, issues: plain_issues, } .cell()) } - ResolveSourceRequestResult::HttpProxy(proxy_result) => { - let proxy_result_value = proxy_result.await?; + ResolveSourceRequestResult::HttpProxy(proxy_result_op) => { + let proxy_result_vc = proxy_result_op.connect(); + let proxy_result_value = proxy_result_vc.await?; if proxy_result_value.status == 404 { return Ok(UpdateStreamItem::NotFound.cell()); } - extend_issues(&mut plain_issues, peek_issues(proxy_result).await?); + extend_issues(&mut plain_issues, peek_issues(proxy_result_op).await?); let from = from.get(); if let Some(from) = Vc::try_resolve_downcast_type::(from).await? { @@ -124,7 +132,7 @@ async fn get_update_stream_item( Ok(UpdateStreamItem::Found { update: Update::Total(TotalUpdate { - to: Vc::upcast::>(proxy_result) + to: Vc::upcast::>(proxy_result_vc) .into_trait_ref() .await?, }) @@ -195,7 +203,9 @@ impl UpdateStream { ResolveSourceRequestResult::Static(static_content, _) => { static_content.await?.content.version() } - ResolveSourceRequestResult::HttpProxy(proxy_result) => Vc::upcast(proxy_result), + ResolveSourceRequestResult::HttpProxy(proxy_result) => { + Vc::upcast(proxy_result.connect()) + } _ => Vc::upcast(NotFoundVersion::new()), }; let version_state = VersionState::new(version.into_trait_ref().await?).await?; diff --git a/turbopack/crates/turbopack-mdx/src/lib.rs b/turbopack/crates/turbopack-mdx/src/lib.rs index 994375343a6da3..a33b9f7b5e4df2 100644 --- a/turbopack/crates/turbopack-mdx/src/lib.rs +++ b/turbopack/crates/turbopack-mdx/src/lib.rs @@ -122,17 +122,22 @@ impl Source for MdxTransformedAsset { #[turbo_tasks::value_impl] impl Asset for MdxTransformedAsset { #[turbo_tasks::function] - async fn content(self: Vc) -> Result> { + async fn content(self: ResolvedVc) -> Result> { let this = self.await?; - Ok(*self - .process() + Ok(*transform_process_operation(self) .issue_file_path(this.source.ident().path(), "MDX processing") .await? + .connect() .await? .content) } } +#[turbo_tasks::function(operation)] +fn transform_process_operation(asset: ResolvedVc) -> Vc { + asset.process() +} + #[turbo_tasks::value_impl] impl MdxTransformedAsset { #[turbo_tasks::function] diff --git a/turbopack/crates/turbopack-node/src/evaluate.rs b/turbopack/crates/turbopack-node/src/evaluate.rs index 75ea1a96fb9baa..58b4a4f9f614f4 100644 --- a/turbopack/crates/turbopack-node/src/evaluate.rs +++ b/turbopack/crates/turbopack-node/src/evaluate.rs @@ -84,12 +84,12 @@ struct EmittedEvaluatePoolAssets { entrypoint: ResolvedVc, } -#[turbo_tasks::function] -async fn emit_evaluate_pool_assets( +#[turbo_tasks::function(operation)] +async fn emit_evaluate_pool_assets_operation( module_asset: ResolvedVc>, - asset_context: Vc>, - chunking_context: Vc>, - runtime_entries: Option>, + asset_context: ResolvedVc>, + chunking_context: ResolvedVc>, + runtime_entries: Option>, ) -> Result> { let runtime_asset = asset_context .process( @@ -174,18 +174,18 @@ async fn emit_evaluate_pool_assets( #[turbo_tasks::function] async fn emit_evaluate_pool_assets_with_effects( - module_asset: Vc>, - asset_context: Vc>, - chunking_context: Vc>, - runtime_entries: Option>, + module_asset: ResolvedVc>, + asset_context: ResolvedVc>, + chunking_context: ResolvedVc>, + runtime_entries: Option>, ) -> Result> { - let operation = emit_evaluate_pool_assets( + let operation = emit_evaluate_pool_assets_operation( module_asset, asset_context, chunking_context, runtime_entries, ); - let result = operation.resolve_strongly_consistent().await?; + let result = operation.connect().resolve_strongly_consistent().await?; apply_effects(operation).await?; Ok(result) } diff --git a/turbopack/crates/turbopack-node/src/render/node_api_source.rs b/turbopack/crates/turbopack-node/src/render/node_api_source.rs index d21530864e8e64..eb15696cdadb9f 100644 --- a/turbopack/crates/turbopack-node/src/render/node_api_source.rs +++ b/turbopack/crates/turbopack-node/src/render/node_api_source.rs @@ -14,7 +14,7 @@ use turbopack_dev_server::source::{ GetContentSourceContent, }; -use super::{render_proxy::render_proxy, RenderData}; +use super::{render_proxy::render_proxy_operation, RenderData}; use crate::{get_intermediate_asset, node_entry::NodeEntry, route_matcher::RouteMatcher}; /// Creates a [NodeApiContentSource]. @@ -128,34 +128,30 @@ impl GetContentSourceContent for NodeApiContentSource { anyhow::bail!("Missing request data") }; let entry = (*self.entry).entry(data.clone()).await?; - Ok(ContentSourceContent::HttpProxy( - render_proxy( - *self.cwd, - *self.env, - self.server_root.join(path.clone()), - *entry.module, - *entry.runtime_entries, - *entry.chunking_context, - *entry.intermediate_output_path, - *entry.output_root, - *entry.project_dir, - RenderData { - params: params.clone(), - method: method.clone(), - url: url.clone(), - original_url: original_url.clone(), - raw_query: raw_query.clone(), - raw_headers: raw_headers.clone(), - path: format!("/{}", path).into(), - data: Some(self.render_data.await?), - } - .cell(), - **body, - self.debug, - ) - .to_resolved() - .await?, - ) + Ok(ContentSourceContent::HttpProxy(render_proxy_operation( + self.cwd, + self.env, + self.server_root.join(path.clone()).to_resolved().await?, + entry.module, + entry.runtime_entries, + entry.chunking_context, + entry.intermediate_output_path, + entry.output_root, + entry.project_dir, + RenderData { + params: params.clone(), + method: method.clone(), + url: url.clone(), + original_url: original_url.clone(), + raw_query: raw_query.clone(), + raw_headers: raw_headers.clone(), + path: format!("/{}", path).into(), + data: Some(self.render_data.await?), + } + .resolved_cell(), + *body, + self.debug, + )) .cell()) } } diff --git a/turbopack/crates/turbopack-node/src/render/render_proxy.rs b/turbopack/crates/turbopack-node/src/render/render_proxy.rs index 0f5d09f92c503a..e0b30c90284b67 100644 --- a/turbopack/crates/turbopack-node/src/render/render_proxy.rs +++ b/turbopack/crates/turbopack-node/src/render/render_proxy.rs @@ -32,8 +32,8 @@ use crate::{ }; /// Renders a module as static HTML in a node.js process. -#[turbo_tasks::function] -pub async fn render_proxy( +#[turbo_tasks::function(operation)] +pub async fn render_proxy_operation( cwd: ResolvedVc, env: ResolvedVc>, path: ResolvedVc, diff --git a/turbopack/crates/turbopack-node/src/render/render_static.rs b/turbopack/crates/turbopack-node/src/render/render_static.rs index 4408e910461dad..bad6a17427755d 100644 --- a/turbopack/crates/turbopack-node/src/render/render_static.rs +++ b/turbopack/crates/turbopack-node/src/render/render_static.rs @@ -72,8 +72,8 @@ impl StaticResult { } /// Renders a module as static HTML in a node.js process. -#[turbo_tasks::function] -pub async fn render_static( +#[turbo_tasks::function(operation)] +pub async fn render_static_operation( cwd: ResolvedVc, env: ResolvedVc>, path: ResolvedVc, diff --git a/turbopack/crates/turbopack-node/src/render/rendered_source.rs b/turbopack/crates/turbopack-node/src/render/rendered_source.rs index d057429afa6cee..a16f4b9e991a92 100644 --- a/turbopack/crates/turbopack-node/src/render/rendered_source.rs +++ b/turbopack/crates/turbopack-node/src/render/rendered_source.rs @@ -1,7 +1,7 @@ use anyhow::Result; use serde_json::Value as JsonValue; use turbo_rcstr::RcStr; -use turbo_tasks::{FxIndexSet, ResolvedVc, Value, Vc}; +use turbo_tasks::{FxIndexSet, OperationVc, ResolvedVc, Value, Vc}; use turbo_tasks_env::ProcessEnv; use turbo_tasks_fs::FileSystemPath; use turbopack_core::{ @@ -27,7 +27,7 @@ use turbopack_dev_server::{ }; use super::{ - render_static::{render_static, StaticResult}, + render_static::{render_static_operation, StaticResult}, RenderData, }; use crate::{ @@ -186,17 +186,17 @@ impl GetContentSourceContent for NodeRenderContentSource { anyhow::bail!("Missing request data") }; let entry = (*self.entry).entry(data.clone()).await?; - let result = render_static( - *self.cwd, - *self.env, - self.server_root.join(path.clone()), - *entry.module, - *entry.runtime_entries, - *self.fallback_page, - *entry.chunking_context, - *entry.intermediate_output_path, - *entry.output_root, - *entry.project_dir, + let result_op = render_static_operation( + self.cwd, + self.env, + self.server_root.join(path.clone()).to_resolved().await?, + entry.module, + entry.runtime_entries, + self.fallback_page, + entry.chunking_context, + entry.intermediate_output_path, + entry.output_root, + entry.project_dir, RenderData { params: params.clone(), method: method.clone(), @@ -207,7 +207,7 @@ impl GetContentSourceContent for NodeRenderContentSource { path: pathname.as_str().into(), data: Some(self.render_data.await?), } - .cell(), + .resolved_cell(), self.debug, ) .issue_file_path( @@ -215,7 +215,7 @@ impl GetContentSourceContent for NodeRenderContentSource { format!("server-side rendering {}", pathname), ) .await?; - Ok(match *result.await? { + Ok(match *result_op.connect().await? { StaticResult::Content { content, status_code, @@ -229,20 +229,35 @@ impl GetContentSourceContent for NodeRenderContentSource { status, headers, ref body, - } => ContentSourceContent::HttpProxy( - ProxyResult { - status, - headers: headers.await?.clone_value(), - body: body.clone(), - } - .resolved_cell(), - ) - .cell(), + } => { + ContentSourceContent::HttpProxy(static_streamed_content_to_proxy_result_operation( + result_op, + ProxyResult { + status, + headers: headers.await?.clone_value(), + body: body.clone(), + } + .resolved_cell(), + )) + .cell() + } StaticResult::Rewrite(rewrite) => ContentSourceContent::Rewrite(rewrite).cell(), }) } } +#[turbo_tasks::function(operation)] +async fn static_streamed_content_to_proxy_result_operation( + result_op: OperationVc, + proxy_result: ResolvedVc, +) -> Result> { + // we already assume `result_op`'s value here because we're called inside of a match arm, but + // await `result_op` anyways, so that if it generates any collectible issues, they're captured + // here. + let _ = result_op.connect().await?; + Ok(*proxy_result) +} + #[turbo_tasks::function] fn introspectable_type() -> Vc { Vc::cell("node render content source".into()) diff --git a/turbopack/crates/turbopack-node/src/transforms/postcss.rs b/turbopack/crates/turbopack-node/src/transforms/postcss.rs index 2d65fc79e561dd..66b25291d11e81 100644 --- a/turbopack/crates/turbopack-node/src/transforms/postcss.rs +++ b/turbopack/crates/turbopack-node/src/transforms/postcss.rs @@ -162,17 +162,24 @@ impl Source for PostCssTransformedAsset { #[turbo_tasks::value_impl] impl Asset for PostCssTransformedAsset { #[turbo_tasks::function] - async fn content(self: Vc) -> Result> { + async fn content(self: ResolvedVc) -> Result> { let this = self.await?; - Ok(*self - .process() + Ok(*transform_process_operation(self) .issue_file_path(this.source.ident().path(), "PostCSS processing") .await? + .connect() .await? .content) } } +#[turbo_tasks::function(operation)] +fn transform_process_operation( + asset: ResolvedVc, +) -> Vc { + asset.process() +} + #[turbo_tasks::value] struct ProcessPostCssResult { content: ResolvedVc,