Skip to main content

write_package_cache_archive

Function write_package_cache_archive 

Source
pub async fn write_package_cache_archive<R: OperatorResolver + ?Sized>(
    resolver: &R,
    request: &PackageCacheArchiveWriteRequest,
    archive: &[u8],
) -> Result<PackageCacheArchiveWriteReceipt, PackageCacheArchiveWriteError>
Expand description

Writes caller-supplied exact archive bytes to one package-cache object.

This low-level operation does not expand the archive, validate a Package Tree, or insert it into a Package Catalog. Direct use with unvalidated bytes can poison a cache because a present malformed cache candidate is terminal. Callers should write registry bytes only after successful expansion, validation, and insertion.

Dropping the returned future yields no receipt, and already-issued storage work may have occurred. The caller retains archive; full replay with the same exact bytes is the recovery contract.

use std::error::Error;
use typst_pack::{
    PackageReadFailures, PackageCatalog, PackageDisposition,
    PackageExpansionLimits,
};
use typst_pack::opendal::OperatorBindings;
use typst_pack::opendal::pack_assembly::{
    PackageRead, RegistryArchiveResidue, insert_read_package,
};
use typst_pack::opendal::write::{
    PackageCacheArchiveWriteRequest, write_package_cache_archive,
};

async fn insert_then_write_registry_archive(
    bindings: &OperatorBindings,
    catalog: &mut PackageCatalog,
    failures: &mut PackageReadFailures,
    read: PackageRead,
) -> Result<Option<RegistryArchiveResidue>, Box<dyn Error>> {
    let Some(residue) = insert_read_package(
        catalog,
        failures,
        read,
        PackageDisposition::Embedded,
        PackageExpansionLimits::reference_v1(),
    )? else {
        return Ok(None);
    };

    let request = PackageCacheArchiveWriteRequest::new(
        residue.destination().clone(),
    )?;
    if let Err(cache_failure) =
        write_package_cache_archive(bindings, &request, residue.bytes()).await
    {
        // Insertion remains successful. The residue retains the exact bytes
        // and destination so the caller can report and replay independently.
        drop(cache_failure);
    }

    Ok(Some(residue))
}