next_core/next_server_utility/
server_utility_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_utility_module::NextServerUtilityModule;
8
9/// This transition wraps a module into a marker
10/// [`Vc<NextServerUtilityModule>`].
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 NextServerUtilityTransition {}
17
18#[turbo_tasks::value_impl]
19impl NextServerUtilityTransition {
20    /// Creates a new [`Vc<NextServerUtilityTransition>`].
21    #[turbo_tasks::function]
22    pub fn new() -> Vc<Self> {
23        NextServerUtilityTransition {}.cell()
24    }
25}
26
27#[turbo_tasks::value_impl]
28impl Transition for NextServerUtilityTransition {
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(NextServerUtilityModule::new(module)))
42    }
43}