Skip to main content

turbopack_ecmascript/hmr/
merger.rs

1use anyhow::{Result, bail};
2use turbo_tasks::{ResolvedVc, TryJoinIterExt, Vc};
3use turbopack_core::version::{VersionedContent, VersionedContentMerger, VersionedContents};
4
5use crate::hmr::{EcmascriptHmrChunkContent, content::EcmascriptMergedChunkContent};
6
7/// Merges multiple [`EcmascriptHmrChunkContent`] into a single
8/// [`EcmascriptMergedChunkContent`]. This allows the chunk list to produce a
9/// single `EcmascriptMergedUpdate` for multiple chunks updating at the same time.
10#[turbo_tasks::value]
11pub struct EcmascriptChunkContentMerger;
12
13#[turbo_tasks::value_impl]
14impl EcmascriptChunkContentMerger {
15    #[turbo_tasks::function]
16    pub fn new() -> Vc<Self> {
17        Self::cell(EcmascriptChunkContentMerger)
18    }
19}
20
21#[turbo_tasks::value_impl]
22impl VersionedContentMerger for EcmascriptChunkContentMerger {
23    #[turbo_tasks::function]
24    async fn merge(
25        &self,
26        contents: Vc<VersionedContents>,
27    ) -> Result<Vc<Box<dyn VersionedContent>>> {
28        let contents = contents
29            .await?
30            .iter()
31            .map(|content| async move {
32                if let Some(content) =
33                    ResolvedVc::try_sidecast::<Box<dyn EcmascriptHmrChunkContent>>(*content)
34                {
35                    Ok(content)
36                } else {
37                    bail!("expected Vc<Box<dyn EcmascriptHmrChunkContent>>")
38                }
39            })
40            .try_join()
41            .await?;
42
43        Ok(Vc::upcast(EcmascriptMergedChunkContent { contents }.cell()))
44    }
45}