From fc3f3d2091ace8a43fb34e8e7429075d960ce52f Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Thu, 2 Jan 2025 17:48:48 -0800 Subject: [PATCH] refactor(turbopack/next-api): Make VcArc use OperationVc --- crates/napi/src/next_api/endpoint.rs | 26 ++++---- crates/napi/src/next_api/project.rs | 62 +++++++++++-------- crates/napi/src/next_api/utils.rs | 9 ++- crates/next-api/src/app.rs | 14 ++--- crates/next-api/src/entrypoints.rs | 2 +- .../next-api/src/global_module_id_strategy.rs | 12 ++-- crates/next-api/src/lib.rs | 1 + crates/next-api/src/operation.rs | 38 ++++++------ crates/next-api/src/pages.rs | 4 -- crates/next-api/src/project.rs | 32 +++++----- crates/next-api/src/route.rs | 61 +++++++----------- 11 files changed, 125 insertions(+), 136 deletions(-) diff --git a/crates/napi/src/next_api/endpoint.rs b/crates/napi/src/next_api/endpoint.rs index 60752af3b59325..785a0917b4de2b 100644 --- a/crates/napi/src/next_api/endpoint.rs +++ b/crates/napi/src/next_api/endpoint.rs @@ -10,9 +10,7 @@ use next_api::{ }, }; use tracing::Instrument; -use turbo_tasks::{ - get_effects, Completion, Effects, OperationVc, ReadRef, ResolvedVc, Vc, VcValueType, -}; +use turbo_tasks::{get_effects, Completion, Effects, OperationVc, ReadRef, Vc, VcValueType}; use turbopack_core::{ diagnostics::PlainDiagnostic, error::PrettyPrintError, @@ -91,10 +89,10 @@ impl From> for NapiWrittenEndpoint { // some async functions (in this case `endpoint_write_to_disk`) can cause // higher-ranked lifetime errors. See https://github.com/rust-lang/rust/issues/102211 // 2. the type_complexity clippy lint. -pub struct ExternalEndpoint(pub VcArc>>); +pub struct ExternalEndpoint(pub VcArc>); impl Deref for ExternalEndpoint { - type Target = VcArc>>; + type Target = VcArc>; fn deref(&self) -> &Self::Target { &self.0 @@ -135,9 +133,9 @@ struct WrittenEndpointWithIssues { #[turbo_tasks::function] async fn get_written_endpoint_with_issues( - endpoint: ResolvedVc>, + endpoint_op: OperationVc>, ) -> Result> { - let write_to_disk = endpoint_write_to_disk_operation(endpoint); + let write_to_disk = endpoint_write_to_disk_operation(endpoint_op); let (written, issues, diagnostics, effects) = strongly_consistent_catch_collectables(write_to_disk).await?; Ok(WrittenEndpointWithIssues { @@ -155,10 +153,10 @@ pub async fn endpoint_write_to_disk( #[napi(ts_arg_type = "{ __napiType: \"Endpoint\" }")] endpoint: External, ) -> napi::Result> { let turbo_tasks = endpoint.turbo_tasks().clone(); - let endpoint = ***endpoint; + let endpoint_op = ***endpoint; let (written, issues, diags) = turbo_tasks .run_once(async move { - let operation = get_written_endpoint_with_issues(endpoint); + let operation = get_written_endpoint_with_issues(endpoint_op); let WrittenEndpointWithIssues { written, issues, @@ -191,8 +189,8 @@ pub fn endpoint_server_changed_subscribe( func, move || { async move { - let operation = subscribe_issues_and_diags(endpoint, issues); - let result = operation.strongly_consistent().await?; + let vc = subscribe_issues_and_diags(endpoint, issues); + let result = vc.strongly_consistent().await?; result.effects.apply().await?; Ok(result) } @@ -241,10 +239,10 @@ impl Eq for EndpointIssuesAndDiags {} #[turbo_tasks::function] async fn subscribe_issues_and_diags( - endpoint: ResolvedVc>, + endpoint_op: OperationVc>, should_include_issues: bool, ) -> Result> { - let changed = endpoint_server_changed_operation(endpoint); + let changed = endpoint_server_changed_operation(endpoint_op); if should_include_issues { let (changed_value, issues, diagnostics, effects) = @@ -280,7 +278,7 @@ pub fn endpoint_client_changed_subscribe( func, move || { async move { - let changed = endpoint.client_changed(); + let changed = endpoint.connect().client_changed(); // We don't capture issues and diagnostics here since we don't want to be // notified when they change changed.strongly_consistent().await?; diff --git a/crates/napi/src/next_api/project.rs b/crates/napi/src/next_api/project.rs index 4790b4adf987c3..f39f37fa2fc8f2 100644 --- a/crates/napi/src/next_api/project.rs +++ b/crates/napi/src/next_api/project.rs @@ -8,11 +8,14 @@ use napi::{ }; use next_api::{ entrypoints::Entrypoints, + operation::{ + EntrypointsOperation, InstrumentationOperation, MiddlewareOperation, RouteOperation, + }, project::{ - DefineEnv, DraftModeOptions, Instrumentation, Middleware, PartialProjectOptions, Project, - ProjectContainer, ProjectOptions, WatchOptions, + DefineEnv, DraftModeOptions, PartialProjectOptions, Project, ProjectContainer, + ProjectOptions, WatchOptions, }, - route::{Endpoint, Route}, + route::Endpoint, }; use next_core::tracing_presets::{ TRACING_NEXT_OVERVIEW_TARGETS, TRACING_NEXT_TARGETS, TRACING_NEXT_TURBOPACK_TARGETS, @@ -25,7 +28,8 @@ use tracing::Instrument; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Registry}; use turbo_rcstr::RcStr; use turbo_tasks::{ - get_effects, Completion, Effects, ReadRef, ResolvedVc, TransientInstance, UpdateInfo, Vc, + get_effects, Completion, Effects, OperationVc, ReadRef, ResolvedVc, TransientInstance, + UpdateInfo, Vc, }; use turbo_tasks_fs::{ get_relative_path_to, util::uri_from_file, DiskFileSystem, FileContent, FileSystem, @@ -517,38 +521,38 @@ struct NapiRoute { } impl NapiRoute { - fn from_route(pathname: String, value: Route, turbo_tasks: &NextTurboTasks) -> Self { - let convert_endpoint = |endpoint: Vc>| { + fn from_route(pathname: String, value: RouteOperation, turbo_tasks: &NextTurboTasks) -> Self { + let convert_endpoint = |endpoint: OperationVc>| { Some(External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), endpoint, )))) }; match value { - Route::Page { + RouteOperation::Page { html_endpoint, data_endpoint, } => NapiRoute { pathname, r#type: "page", - html_endpoint: convert_endpoint(*html_endpoint), - data_endpoint: convert_endpoint(*data_endpoint), + html_endpoint: convert_endpoint(html_endpoint), + data_endpoint: convert_endpoint(data_endpoint), ..Default::default() }, - Route::PageApi { endpoint } => NapiRoute { + RouteOperation::PageApi { endpoint } => NapiRoute { pathname, r#type: "page-api", - endpoint: convert_endpoint(*endpoint), + endpoint: convert_endpoint(endpoint), ..Default::default() }, - Route::AppPage(pages) => NapiRoute { + RouteOperation::AppPage(pages) => NapiRoute { pathname, r#type: "app-page", pages: Some( pages .into_iter() .map(|page_route| AppPageNapiRoute { - original_name: Some(page_route.original_name), + original_name: Some(page_route.original_name.into_owned()), html_endpoint: convert_endpoint(page_route.html_endpoint), rsc_endpoint: convert_endpoint(page_route.rsc_endpoint), }) @@ -556,17 +560,17 @@ impl NapiRoute { ), ..Default::default() }, - Route::AppRoute { + RouteOperation::AppRoute { original_name, endpoint, } => NapiRoute { pathname, - original_name: Some(original_name), + original_name: Some(original_name.into_owned()), r#type: "app-route", - endpoint: convert_endpoint(*endpoint), + endpoint: convert_endpoint(endpoint), ..Default::default() }, - Route::Conflict => NapiRoute { + RouteOperation::Conflict => NapiRoute { pathname, r#type: "conflict", ..Default::default() @@ -581,7 +585,7 @@ struct NapiMiddleware { } impl NapiMiddleware { - fn from_middleware(value: &Middleware, turbo_tasks: &NextTurboTasks) -> Result { + fn from_middleware(value: &MiddlewareOperation, turbo_tasks: &NextTurboTasks) -> Result { Ok(NapiMiddleware { endpoint: External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), @@ -598,7 +602,10 @@ struct NapiInstrumentation { } impl NapiInstrumentation { - fn from_instrumentation(value: &Instrumentation, turbo_tasks: &NextTurboTasks) -> Result { + fn from_instrumentation( + value: &InstrumentationOperation, + turbo_tasks: &NextTurboTasks, + ) -> Result { Ok(NapiInstrumentation { node_js: External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), @@ -622,9 +629,9 @@ struct NapiEntrypoints { pub pages_error_endpoint: External, } -#[turbo_tasks::value(serialization = "none", local)] +#[turbo_tasks::value(serialization = "none")] struct EntrypointsWithIssues { - entrypoints: ReadRef, + entrypoints: ReadRef, issues: Arc>>, diagnostics: Arc>>, effects: Arc, @@ -634,7 +641,8 @@ struct EntrypointsWithIssues { async fn get_entrypoints_with_issues( container: ResolvedVc, ) -> Result> { - let entrypoints_operation = project_container_entrypoints_operation(container); + let entrypoints_operation = + EntrypointsOperation::new(project_container_entrypoints_operation(container)); let entrypoints = entrypoints_operation .connect() .strongly_consistent() @@ -653,6 +661,8 @@ async fn get_entrypoints_with_issues( #[turbo_tasks::function(operation)] fn project_container_entrypoints_operation( + // the container is a long-lived object with internally mutable state, there's no risk of it + // becoming stale container: ResolvedVc, ) -> Vc { container.entrypoints() @@ -710,15 +720,15 @@ pub fn project_entrypoints_subscribe( .transpose()?, pages_document_endpoint: External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), - *entrypoints.pages_document_endpoint, + entrypoints.pages_document_endpoint, ))), pages_app_endpoint: External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), - *entrypoints.pages_app_endpoint, + entrypoints.pages_app_endpoint, ))), pages_error_endpoint: External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), - *entrypoints.pages_error_endpoint, + entrypoints.pages_error_endpoint, ))), }, issues: issues @@ -760,7 +770,7 @@ async fn hmr_update( } #[turbo_tasks::function(operation)] -async fn project_hmr_update_operation( +fn project_hmr_update_operation( project: ResolvedVc, identifier: RcStr, state: ResolvedVc, diff --git a/crates/napi/src/next_api/utils.rs b/crates/napi/src/next_api/utils.rs index 65da31c7ddc91c..7969477c91959c 100644 --- a/crates/napi/src/next_api/utils.rs +++ b/crates/napi/src/next_api/utils.rs @@ -175,13 +175,12 @@ pub fn create_turbo_tasks( #[derive(Clone)] pub struct VcArc { turbo_tasks: NextTurboTasks, - /// The Vc. Must be resolved, otherwise you are referencing an inactive - /// operation. - vc: T, + /// The Vc. Must be unresolved, otherwise you are referencing an inactive operation. + vc: OperationVc, } impl VcArc { - pub fn new(turbo_tasks: NextTurboTasks, vc: T) -> Self { + pub fn new(turbo_tasks: NextTurboTasks, vc: OperationVc) -> Self { Self { turbo_tasks, vc } } @@ -191,7 +190,7 @@ impl VcArc { } impl Deref for VcArc { - type Target = T; + type Target = OperationVc; fn deref(&self) -> &Self::Target { &self.vc diff --git a/crates/next-api/src/app.rs b/crates/next-api/src/app.rs index 6227e55a1a545e..1583ca4a9dab3f 100644 --- a/crates/next-api/src/app.rs +++ b/crates/next-api/src/app.rs @@ -732,8 +732,8 @@ pub fn app_entry_point_to_route( pages .into_iter() .map(|page| AppPageRoute { - original_name: page.to_string(), - html_endpoint: Vc::upcast( + original_name: RcStr::from(page.to_string()), + html_endpoint: ResolvedVc::upcast( AppEndpoint { ty: AppEndpointType::Page { ty: AppPageEndpointType::Html, @@ -742,9 +742,9 @@ pub fn app_entry_point_to_route( app_project, page: page.clone(), } - .cell(), + .resolved_cell(), ), - rsc_endpoint: Vc::upcast( + rsc_endpoint: ResolvedVc::upcast( AppEndpoint { ty: AppEndpointType::Page { ty: AppPageEndpointType::Rsc, @@ -753,7 +753,7 @@ pub fn app_entry_point_to_route( app_project, page, } - .cell(), + .resolved_cell(), ), }) .collect(), @@ -763,7 +763,7 @@ pub fn app_entry_point_to_route( path, root_layouts, } => Route::AppRoute { - original_name: page.to_string(), + original_name: page.to_string().into(), endpoint: ResolvedVc::upcast( AppEndpoint { ty: AppEndpointType::Route { path, root_layouts }, @@ -774,7 +774,7 @@ pub fn app_entry_point_to_route( ), }, AppEntrypoint::AppMetadata { page, metadata } => Route::AppRoute { - original_name: page.to_string(), + original_name: page.to_string().into(), endpoint: ResolvedVc::upcast( AppEndpoint { ty: AppEndpointType::Metadata { metadata }, diff --git a/crates/next-api/src/entrypoints.rs b/crates/next-api/src/entrypoints.rs index 78c40b8ae20443..9567dfb0154c08 100644 --- a/crates/next-api/src/entrypoints.rs +++ b/crates/next-api/src/entrypoints.rs @@ -6,7 +6,7 @@ use crate::{ route::{Endpoint, Route}, }; -#[turbo_tasks::value(shared, local)] +#[turbo_tasks::value(shared)] pub struct Entrypoints { pub routes: FxIndexMap, pub middleware: Option, diff --git a/crates/next-api/src/global_module_id_strategy.rs b/crates/next-api/src/global_module_id_strategy.rs index 5ec6719d5a771a..09c77b88cac9ca 100644 --- a/crates/next-api/src/global_module_id_strategy.rs +++ b/crates/next-api/src/global_module_id_strategy.rs @@ -31,14 +31,12 @@ impl GlobalModuleIdStrategyBuilder { preprocessed_module_ids.push(preprocess_module_ids(*entrypoints.pages_document_endpoint)); if let Some(middleware) = &entrypoints.middleware { - preprocessed_module_ids.push(preprocess_module_ids(middleware.endpoint)); + preprocessed_module_ids.push(preprocess_module_ids(*middleware.endpoint)); } if let Some(instrumentation) = &entrypoints.instrumentation { - let node_js = instrumentation.node_js; - let edge = instrumentation.edge; - preprocessed_module_ids.push(preprocess_module_ids(node_js)); - preprocessed_module_ids.push(preprocess_module_ids(edge)); + preprocessed_module_ids.push(preprocess_module_ids(*instrumentation.node_js)); + preprocessed_module_ids.push(preprocess_module_ids(*instrumentation.edge)); } for (_, route) in entrypoints.routes.iter() { @@ -56,9 +54,9 @@ impl GlobalModuleIdStrategyBuilder { Route::AppPage(page_routes) => { for page_route in page_routes { preprocessed_module_ids - .push(preprocess_module_ids(page_route.html_endpoint)); + .push(preprocess_module_ids(*page_route.html_endpoint)); preprocessed_module_ids - .push(preprocess_module_ids(page_route.rsc_endpoint)); + .push(preprocess_module_ids(*page_route.rsc_endpoint)); } } Route::AppRoute { diff --git a/crates/next-api/src/lib.rs b/crates/next-api/src/lib.rs index 26fe340398f735..23c4c1e0dff7c2 100644 --- a/crates/next-api/src/lib.rs +++ b/crates/next-api/src/lib.rs @@ -15,6 +15,7 @@ mod loadable_manifest; mod middleware; mod module_graph; mod nft_json; +pub mod operation; mod pages; pub mod paths; pub mod project; diff --git a/crates/next-api/src/operation.rs b/crates/next-api/src/operation.rs index d073facf35c805..b42fad21f910e0 100644 --- a/crates/next-api/src/operation.rs +++ b/crates/next-api/src/operation.rs @@ -1,18 +1,24 @@ use anyhow::Result; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; -use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, OperationVc, RcStr, Vc}; +use turbo_rcstr::RcStr; +use turbo_tasks::{ + debug::ValueDebugFormat, trace::TraceRawVcs, NonLocalValue, OperationVc, ResolvedVc, Vc, +}; use crate::{ entrypoints::Entrypoints, route::{Endpoint, Route}, }; -/// A derived type of Entrypoints, but with OperationVc for every endpoint. +/// Based on [`Entrypoints`], but with [`OperationVc`][OperationVc] for every endpoint. +/// +/// This is used when constructing `ExternalEndpoint`s in the `napi` crate. +/// +/// This is important as `OperationVc`s can be stored in the VersionedContentMap and can be exposed +/// to JS via napi. /// /// This is needed to call `write_to_disk` which expects an `OperationVc`. -/// This is important as OperationVcs can be stored in the VersionedContentMap and can be exposed to -/// JS via napi. #[turbo_tasks::value(shared)] pub struct EntrypointsOperation { pub routes: IndexMap, @@ -25,7 +31,7 @@ pub struct EntrypointsOperation { #[turbo_tasks::value_impl] impl EntrypointsOperation { - #[turbo_tasks::function] + #[turbo_tasks::function(operation)] pub async fn new(entrypoints: OperationVc) -> Result> { let e = entrypoints.connect().await?; Ok(Self { @@ -85,20 +91,16 @@ fn wrap_route(route: &Route, entrypoints: OperationVc) -> RouteOper } } -#[turbo_tasks::function] -fn wrap_endpoint( - endpoint: Vc>, +/// Given a resolved `Endpoint` and the `Entrypoints` operation that it comes from, connect the +/// operation and return a `OperationVc` of the `Entrypoint`. This `Endpoint` operation will keep +/// the entire `Entrypoints` operation alive. +#[turbo_tasks::function(operation)] +fn wrap( + endpoint: ResolvedVc>, op: OperationVc, ) -> Vc> { let _ = op.connect(); - endpoint -} - -fn wrap( - endpoint: Vc>, - op: OperationVc, -) -> OperationVc> { - OperationVc::new(wrap_endpoint(endpoint, op)) + *endpoint } #[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat, NonLocalValue)] @@ -124,7 +126,7 @@ pub enum RouteOperation { }, AppPage(Vec), AppRoute { - original_name: String, + original_name: RcStr, endpoint: OperationVc>, }, Conflict, @@ -142,7 +144,7 @@ pub enum RouteOperation { NonLocalValue, )] pub struct AppPageRouteOperation { - pub original_name: String, + pub original_name: RcStr, pub html_endpoint: OperationVc>, pub rsc_endpoint: OperationVc>, } diff --git a/crates/next-api/src/pages.rs b/crates/next-api/src/pages.rs index 6708ed5029af9d..698b28dba951cf 100644 --- a/crates/next-api/src/pages.rs +++ b/crates/next-api/src/pages.rs @@ -210,10 +210,6 @@ impl PagesProject { add_dir_to_routes(&mut routes, *pages, make_page_route).await?; } - for route in routes.values_mut() { - route.resolve().await?; - } - Ok(Vc::cell(routes)) } diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index 159f7a5dc36d75..572a514e710424 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -232,18 +232,18 @@ pub struct DefineEnv { pub nodejs: Vec<(RcStr, RcStr)>, } -#[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat)] +#[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat, NonLocalValue)] pub struct Middleware { - pub endpoint: Vc>, + pub endpoint: ResolvedVc>, } -#[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat)] +#[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat, NonLocalValue)] pub struct Instrumentation { - pub node_js: Vc>, - pub edge: Vc>, + pub node_js: ResolvedVc>, + pub edge: ResolvedVc>, } -#[turbo_tasks::value(local)] +#[turbo_tasks::value] pub struct ProjectContainer { name: RcStr, options_state: State>, @@ -739,7 +739,7 @@ impl Project { let mut modules = Vec::new(); async fn add_endpoint( - endpoint: Vc>, + endpoint: ResolvedVc>, modules: &mut Vec>>, ) -> Result<()> { let root_modules = endpoint.root_modules().await?; @@ -752,9 +752,9 @@ impl Project { let entrypoints = self.entrypoints().await?; modules.extend(self.client_main_modules().await?.iter().copied()); - add_endpoint(*entrypoints.pages_error_endpoint, &mut modules).await?; - add_endpoint(*entrypoints.pages_app_endpoint, &mut modules).await?; - add_endpoint(*entrypoints.pages_document_endpoint, &mut modules).await?; + add_endpoint(entrypoints.pages_error_endpoint, &mut modules).await?; + add_endpoint(entrypoints.pages_app_endpoint, &mut modules).await?; + add_endpoint(entrypoints.pages_document_endpoint, &mut modules).await?; if let Some(middleware) = &entrypoints.middleware { add_endpoint(middleware.endpoint, &mut modules).await?; @@ -773,10 +773,10 @@ impl Project { html_endpoint, data_endpoint: _, } => { - add_endpoint(**html_endpoint, &mut modules).await?; + add_endpoint(*html_endpoint, &mut modules).await?; } Route::PageApi { endpoint } => { - add_endpoint(**endpoint, &mut modules).await?; + add_endpoint(*endpoint, &mut modules).await?; } Route::AppPage(page_routes) => { for AppPageRoute { @@ -792,7 +792,7 @@ impl Project { original_name: _, endpoint, } => { - add_endpoint(**endpoint, &mut modules).await?; + add_endpoint(*endpoint, &mut modules).await?; } Route::Conflict => { tracing::info!("WARN: conflict"); @@ -1061,7 +1061,7 @@ impl Project { let middleware = self.find_middleware(); let middleware = if let FindContextFileResult::Found(..) = *middleware.await? { Some(Middleware { - endpoint: self.middleware_endpoint(), + endpoint: self.middleware_endpoint().to_resolved().await?, }) } else { None @@ -1070,8 +1070,8 @@ impl Project { let instrumentation = self.find_instrumentation(); let instrumentation = if let FindContextFileResult::Found(..) = *instrumentation.await? { Some(Instrumentation { - node_js: self.instrumentation_endpoint(false), - edge: self.instrumentation_endpoint(true), + node_js: self.instrumentation_endpoint(false).to_resolved().await?, + edge: self.instrumentation_endpoint(true).to_resolved().await?, }) } else { None diff --git a/crates/next-api/src/route.rs b/crates/next-api/src/route.rs index 7c0e5b3fe457f2..4e6248a2706176 100644 --- a/crates/next-api/src/route.rs +++ b/crates/next-api/src/route.rs @@ -1,34 +1,31 @@ -use anyhow::Result; use serde::{Deserialize, Serialize}; use turbo_rcstr::RcStr; use turbo_tasks::{ - debug::ValueDebugFormat, trace::TraceRawVcs, Completion, FxIndexMap, ResolvedVc, Vc, + debug::ValueDebugFormat, trace::TraceRawVcs, Completion, FxIndexMap, NonLocalValue, + OperationVc, ResolvedVc, Vc, }; use turbopack_core::module::Modules; use crate::paths::ServerPath; -#[derive(TraceRawVcs, Serialize, Deserialize, PartialEq, Eq, ValueDebugFormat, Clone, Debug)] +#[derive( + TraceRawVcs, + Serialize, + Deserialize, + PartialEq, + Eq, + ValueDebugFormat, + Clone, + Debug, + NonLocalValue, +)] pub struct AppPageRoute { - pub original_name: String, - pub html_endpoint: Vc>, - pub rsc_endpoint: Vc>, + pub original_name: RcStr, + pub html_endpoint: ResolvedVc>, + pub rsc_endpoint: ResolvedVc>, } -impl AppPageRoute { - async fn resolve(&mut self) -> Result<()> { - let Self { - html_endpoint, - rsc_endpoint, - .. - } = self; - *html_endpoint = html_endpoint.resolve().await?; - *rsc_endpoint = rsc_endpoint.resolve().await?; - Ok(()) - } -} - -#[turbo_tasks::value(shared, local)] +#[turbo_tasks::value(shared)] #[derive(Clone, Debug)] pub enum Route { Page { @@ -40,24 +37,12 @@ pub enum Route { }, AppPage(Vec), AppRoute { - original_name: String, + original_name: RcStr, endpoint: ResolvedVc>, }, Conflict, } -impl Route { - pub async fn resolve(&mut self) -> Result<()> { - if let Route::AppPage(routes) = self { - for route in routes { - route.resolve().await?; - } - } - - Ok(()) - } -} - #[turbo_tasks::value_trait(local)] pub trait Endpoint { fn write_to_disk(self: Vc) -> Vc; @@ -68,16 +53,16 @@ pub trait Endpoint { #[turbo_tasks::function(operation)] pub fn endpoint_write_to_disk_operation( - endpoint: ResolvedVc>, + endpoint: OperationVc>, ) -> Vc { - endpoint.write_to_disk() + endpoint.connect().write_to_disk() } #[turbo_tasks::function(operation)] pub fn endpoint_server_changed_operation( - endpoint: ResolvedVc>, + endpoint: OperationVc>, ) -> Vc { - endpoint.server_changed() + endpoint.connect().server_changed() } #[turbo_tasks::value(shared)] @@ -97,5 +82,5 @@ pub enum WrittenEndpoint { /// The routes as map from pathname to route. (pathname includes the leading /// slash) -#[turbo_tasks::value(transparent, local)] +#[turbo_tasks::value(transparent)] pub struct Routes(FxIndexMap);