rspack_core 0.100.1

rspack core
Documentation
use futures::Future;
use rspack_collections::Identifier;
use rspack_error::{Diagnostic, Result};
use rspack_sources::BoxSource;

use crate::{
  ArtifactExt, Chunk, Compilation, MemoryGCStorage, SourceType,
  incremental::{Incremental, IncrementalPasses},
};

#[derive(Debug, Default)]
pub struct ChunkRenderCacheArtifact {
  storage: Option<MemoryGCStorage<BoxSource>>,
}

impl ArtifactExt for ChunkRenderCacheArtifact {
  const PASS: IncrementalPasses = IncrementalPasses::CHUNK_ASSET;

  fn recover(_incremental: &Incremental, new: &mut Self, old: &mut Self) {
    *new = std::mem::take(old);
    new.start_next_generation();
  }
}

impl ChunkRenderCacheArtifact {
  pub fn new(storage: MemoryGCStorage<BoxSource>) -> Self {
    Self {
      storage: Some(storage),
    }
  }
  pub fn start_next_generation(&self) {
    if let Some(storage) = &self.storage {
      storage.start_next_generation();
    }
  }
  pub async fn use_cache<G, F>(
    &self,
    compilation: &Compilation,
    chunk: &Chunk,
    source_type: &SourceType,
    generator: G,
  ) -> Result<(BoxSource, Vec<Diagnostic>)>
  where
    G: FnOnce() -> F,
    F: Future<Output = Result<(BoxSource, Vec<Diagnostic>)>>,
  {
    let Some(storage) = &self.storage else {
      panic!("ChunkRenderCacheArtifact storage is not set");
    };
    let Some(content_hash) =
      chunk.content_hash_by_source_type(&compilation.chunk_hashes_artifact, source_type)
    else {
      return generator().await;
    };
    let cache_key = Identifier::from(content_hash.encoded());
    if let Some(value) = storage.get(&cache_key) {
      Ok((value, Vec::new()))
    } else {
      let res = generator().await?;
      storage.set(cache_key, res.0.clone());
      Ok(res)
    }
  }
}