next_core/next_server_component/
server_component_transition.rs

1use anyhow::{Result, bail};
2use turbo_tasks::Vc;
3use turbopack::{ModuleAssetContext, transition::Transition};
4use turbopack_core::module::Module;
5use turbopack_ecmascript::chunk::EcmascriptChunkPlaceable;
6
7use super::server_component_module::NextServerComponentModule;
8
9/// This transition wraps a module into a marker
10/// [`Vc<NextServerComponentModule>`].
11///
12/// When walking the module graph to build the client reference manifest, this
13/// is used to determine under which server component CSS client references are
14/// required. Ultimately, this tells Next.js what CSS to inject into the page.
15#[turbo_tasks::value(shared)]
16pub struct NextServerComponentTransition {}
17
18#[turbo_tasks::value_impl]
19impl NextServerComponentTransition {
20    /// Creates a new [`Vc<NextServerComponentTransition>`].
21    #[turbo_tasks::function]
22    pub fn new() -> Vc<Self> {
23        NextServerComponentTransition {}.cell()
24    }
25}
26
27#[turbo_tasks::value_impl]
28impl Transition for NextServerComponentTransition {
29    #[turbo_tasks::function]
30    async fn process_module(
31        self: Vc<Self>,
32        module: Vc<Box<dyn Module>>,
33        _context: Vc<ModuleAssetContext>,
34    ) -> Result<Vc<Box<dyn Module>>> {
35        let Some(module) =
36            Vc::try_resolve_sidecast::<Box<dyn EcmascriptChunkPlaceable>>(module).await?
37        else {
38            bail!("not an ecmascript module");
39        };
40
41        Ok(Vc::upcast(NextServerComponentModule::new(module)))
42    }
43}