turbopack_core/
changed.rs

1use anyhow::Result;
2use turbo_tasks::{
3    Completion, Completions, ResolvedVc, TryJoinIterExt, Vc,
4    graph::{AdjacencyMap, GraphTraversal},
5};
6
7use crate::{
8    asset::Asset,
9    module::Module,
10    output::{ExpandOutputAssetsInput, OutputAsset, OutputAssets, expand_output_assets},
11    reference::primary_referenced_modules,
12};
13
14pub async fn get_referenced_modules(
15    parent: ResolvedVc<Box<dyn Module>>,
16) -> Result<impl Iterator<Item = ResolvedVc<Box<dyn Module>>> + Send> {
17    Ok(primary_referenced_modules(*parent)
18        .owned()
19        .await?
20        .into_iter())
21}
22
23/// Returns a completion that changes when any content of any asset in the whole
24/// asset graph changes.
25#[turbo_tasks::function]
26pub async fn any_content_changed_of_module(
27    root: ResolvedVc<Box<dyn Module>>,
28) -> Result<Vc<Completion>> {
29    let completions = AdjacencyMap::new()
30        .skip_duplicates()
31        .visit([root], get_referenced_modules)
32        .await
33        .completed()?
34        .into_inner()
35        .into_postorder_topological()
36        .map(|m| content_changed(*ResolvedVc::upcast(m)))
37        .map(|v| v.to_resolved())
38        .try_join()
39        .await?;
40
41    Ok(Vc::<Completions>::cell(completions).completed())
42}
43
44/// Returns a completion that changes when any content of any asset in the whole
45/// asset graph changes.
46#[turbo_tasks::function]
47pub async fn any_content_changed_of_output_asset(
48    root: ResolvedVc<Box<dyn OutputAsset>>,
49) -> Result<Vc<Completion>> {
50    let completions =
51        expand_output_assets(std::iter::once(ExpandOutputAssetsInput::Asset(root)), true)
52            .await?
53            .into_iter()
54            .map(|m| content_changed(*ResolvedVc::upcast(m)))
55            .map(|v| v.to_resolved())
56            .try_join()
57            .await?;
58
59    Ok(Vc::<Completions>::cell(completions).completed())
60}
61
62/// Returns a completion that changes when any content of any asset in the given
63/// output asset graphs changes.
64#[turbo_tasks::function]
65pub async fn any_content_changed_of_output_assets(
66    roots: Vc<OutputAssets>,
67) -> Result<Vc<Completion>> {
68    Ok(Vc::<Completions>::cell(
69        roots
70            .await?
71            .iter()
72            .map(|&a| any_content_changed_of_output_asset(*a))
73            .map(|v| v.to_resolved())
74            .try_join()
75            .await?,
76    )
77    .completed())
78}
79
80/// Returns a completion that changes when the content of the given asset
81/// changes.
82#[turbo_tasks::function]
83pub async fn content_changed(asset: Vc<Box<dyn Asset>>) -> Result<Vc<Completion>> {
84    // Reading the file content is enough to add as dependency
85    asset.content().file_content().await?;
86    Ok(Completion::new())
87}