Sign in

    MoonCache

    A transport-independent, explainable HTTP cache policy and runtime toolkit.

    http
    cache
    rfc9111
    Download zip
    Author
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    39

    #MoonCache

    MoonCache is a transport-independent, explainable HTTP cache policy and runtime toolkit for MoonBit. It implements the 0.2.0 cache lifecycle:

    Request -> normalized cache key -> Store lookup -> Vary selection -> freshness decision -> Fetch or conditional revalidation -> 304 merge or replacement -> Store update -> RuntimeResponse + CacheTrace

    It is an HTTP caching semantics layer, not an HTTP protocol stack, generic LRU, cookie jar, or production reverse proxy.

    #Release status

    The 0.2.0 release includes:

    • normalized request, response, header, URI, and saturating time models;
    • private/shared storage rules and authenticated-request protection;
    • RFC 9111 corrected age and freshness calculations;
    • Vary variants with missing-versus-empty field semantics;
    • ETag and Last-Modified conditional requests;
    • 304 Not Modified metadata merging with cached-body retention;
    • an HTTP-specific MemoryStore with deterministic eviction and limits;
    • a native recoverable FileStore with atomic writes, digests, quarantine, and compaction;
    • deterministic request coalescing for concurrent identical fetches;
    • stale resilience: stale-if-error, stale-while-revalidate, only-if-cached, background revalidation, observers, and telemetry;
    • a complete transport-independent CachedRuntime;
    • deterministic FakeTransport and RecordingTransport;
    • redacted text/JSON trace, runtime, and Store statistics reports;
    • a native CLI with scenario commands plus store-backed stats/inspect/purge/verify/clean and a demo caching proxy (serve);
    • optional f4ah6o/http11 and native moonbitlang/async/http adapters;
    • five runnable, self-checking examples including a demo proxy walkthrough;
    • 290 data-driven rule scenarios, differential compatibility fixtures, and deterministic benchmarks — no public-network or real-wait tests.

    • Source: yzy726/MoonCache
    • Package: Ag108/MoonCache
    • License: Apache-2.0

    #Build and test

    moon fmt --check moon check --deny-warn moon test --deny-warn

    The portable packages are also checked explicitly:

    moon check --target native --deny-warn moon check --target js --deny-warn moon check --target wasm-gc --deny-warn

    Add the published release with:

    moon add Ag108/MoonCache@0.2.0

    #Minimal cached runtime

    Add the root package to moon.pkg:

    ///|
    import {
    "Ag108/MoonCache" @mooncache,
    }

    Then inject a Store, a Transport, and time:

    let store = @mooncache.MemoryStore::default()
    let origin = @mooncache.FakeTransport::new([
    @mooncache.TransportResponse::new(
    @mooncache.ResponseMeta::complete(
    200,
    @mooncache.HeaderMap::from_pairs([
    ("Cache-Control", "max-age=60"),
    ]),
    @mooncache.Timestamp::zero(),
    @mooncache.Timestamp::zero(),
    ),
    b"hello",
    ),
    ])
    let runtime = @mooncache.CachedRuntime::new(
    store,
    origin,
    @mooncache.CacheOptions::private_cache(),
    )
    let request = @mooncache.RuntimeRequest::get(
    "https://example.test/greeting",
    )
    let first = try! runtime.execute(request, @mooncache.Timestamp::zero())
    let second = try! runtime.execute(
    request,
    @mooncache.Timestamp::from_seconds(10L),
    )
    println(first.source.label()) // upstream
    println(second.source.label()) // cache

    CacheStore and Transport are open traits, so applications can replace both implementations without changing policy code.

    #CLI

    Scenario commands consume deterministic JSON and never perform a network request:

    moon run cmd/main -- explain examples/scenarios/stale-etag.json moon run cmd/main -- explain examples/scenarios/stale-etag.json --json moon run cmd/main -- validate examples/scenarios/basic-cache.json moon run cmd/main -- replay testdata/scenarios moon run cmd/main -- replay testdata/scenarios --json

    replay sorts paths explicitly and continues after an unreadable or malformed individual file, returning a failing exit code with a complete summary.

    Native FileStore directories can be inspected without a running process:

    moon run cmd/main -- stats --store .cache/mooncache --json moon run cmd/main -- inspect --store .cache/mooncache moon run cmd/main -- purge --store .cache/mooncache --uri https://example.test/data moon run cmd/main -- verify --store .cache/mooncache moon run cmd/main -- clean --store .cache/mooncache

    #Demo proxy

    serve runs a local caching reverse proxy for one upstream origin. It exists to demonstrate the runtime end to end (MISS, HIT, REVALIDATE, 304, STALE-IF-ERROR, VARY, coalescing) and is not part of the library API:

    moon run cmd/main -- serve --listen 127.0.0.1:8080 --upstream 127.0.0.1:9000 \ [--store .cache/mooncache]

    The demo proxy is explicitly not:

    • a production reverse proxy;
    • TLS terminating (HTTP only);
    • CONNECT capable (no tunneling);
    • HTTP/2 or HTTP/3 aware;
    • suitable for untrusted public traffic.

    #Runnable examples

    moon run examples/basic_cache moon run examples/vary_language moon run examples/etag_revalidation moon run examples/shared_private moon run examples/demo_proxy

    ExampleDemonstrates
    basic_cachefirst request misses, second request hits
    vary_languageEnglish and Chinese variants remain independent
    etag_revalidationstale ETag request receives 304 and retains its body
    shared_privateprivate cache reuses a private response; shared cache rejects it
    demo_proxyfull MISS/HIT/REVALIDATE/304/STALE-IF-ERROR/VARY/coalescing walk

    Every example checks its own expected source, body, variant count, or origin call count and exits unsuccessfully on a regression.

    #Optional adapters

    #HTTP11

    adapters/http11 directly converts f4ah6o/http11@0.1.1 request and response types. Origin-form request targets require the caller to supply the absolute URI:

    ///|
    let cached_request = @mooncache_http11.request_to_runtime_at_uri(
    wire_request, "https://example.test/data", request_time,
    )

    The core package does not import HTTP11.

    #Native async HTTP

    adapters/async_http provides AsyncTransport, MoonbitAsyncHttpTransport, ScriptedAsyncTransport, and AsyncCachedRuntime. The real transport currently supports GET, POST, and PUT through moonbitlang/async/http@0.20.2 and receives an injected response clock:

    ///|
    let origin = @mooncache_async.MoonbitAsyncHttpTransport::new(clock)

    ///|
    let client = @mooncache_async.AsyncCachedRuntime::new(
    @mooncache.MemoryStore::default(),
    origin,
    @mooncache.CacheOptions::private_cache(),
    )

    ///|
    let response = client.execute(request, now)

    The adapter is native-only; model and policy portability do not depend on it. See Async adapter.

    #Security defaults

    • no-store, incomplete bodies, Vary: *, and unknown statuses without explicit freshness are not stored.
    • Shared caches reject private responses and authorized requests unless an explicit option/rule permits them.
    • Authorization, Proxy-Authorization, Cookie, and Set-Cookie values are redacted from reports.
    • MemoryStore strips hop-by-hop response fields, strips Set-Cookie by default, and removes request credentials unless a Vary field requires one.
    • Body size, total body bytes, and entry count are bounded.
    • Age arithmetic saturates and clamps backward clocks.
    • Core policy never reads a system clock or accesses the network.

    Read the security model before integrating a shared cache.

    #Documentation

    The generated root interface is pkg.generated.mbti. Adapter packages have their own generated interfaces after moon info.

    #License

    Apache-2.0. See LICENSE.

    CacheObserver

    pub(open) trait CacheObserver {
    fn observe(Self, CacheEvent) -> Unit
    }

    Observer hook for logging, tracing, or application-specific metrics.

    CacheStore

    pub(open) trait CacheStore {
    fn find_variants(Self, PrimaryCacheKey) -> Array[StoredEntry]
    fn put(Self, StoredEntry) -> StorePutResult
    fn remove_variant(Self, PrimaryCacheKey, VariantKey) -> Bool
    fn invalidate_uri(Self, String) -> Int
    fn clear(Self) -> Unit
    fn stats(Self) -> StoreStats
    }

    Transport

    pub(open) trait Transport {
    fn execute(Self, RuntimeRequest) -> TransportResponse raise TransportError
    }

    RuntimeError

    pub suberror RuntimeError {
    RuntimeTransportFailure(String)
    } derive(Eq,
    Debug
    )

    RuntimeError::message

    fn RuntimeError::message(self : RuntimeError) -> String

    ScenarioError

    pub suberror ScenarioError {
    ScenarioError(String)
    } derive(Eq,
    Debug
    )

    ScenarioError::message

    fn ScenarioError::message(self : ScenarioError) -> String

    TransportError

    pub suberror TransportError {
    ScriptExhausted
    ScriptedTransportFailure(String)
    } derive(Eq,
    Debug
    )

    TransportError::message

    fn TransportError::message(self : TransportError) -> String

    ValidationError

    pub suberror ValidationError {
    ExpectedNotModified(Int)
    } derive(Eq,
    Debug
    )

    ValidationError::message

    fn ValidationError::message(self : ValidationError) -> String

    AgeCalculation

    pub(all) struct AgeCalculation {
    apparent_age : DeltaSeconds
    response_delay : DeltaSeconds
    age_value : DeltaSeconds
    corrected_age_value : DeltaSeconds
    corrected_initial_age : DeltaSeconds
    resident_time : DeltaSeconds
    current_age : DeltaSeconds
    clock_clamped : Bool
    overflow_clamped : Bool
    } derive(Eq,
    Debug
    )

    CacheActionKind

    pub(all) enum CacheActionKind {
    ServeFresh
    Revalidate
    Fetch
    ServeStale
    Bypass
    OnlyIfCachedMiss
    } derive(Compare, Eq,
    Debug
    )

    CacheActionKind::label

    fn CacheActionKind::label(self : CacheActionKind) -> String

    CacheControl

    pub(all) struct CacheControl {
    no_cache : Bool
    no_store : Bool
    is_private : Bool
    is_public : Bool
    must_revalidate : Bool
    proxy_revalidate : Bool
    immutable : Bool
    only_if_cached : Bool
    max_age : DeltaSeconds?
    shared_max_age : DeltaSeconds?
    min_fresh : DeltaSeconds?
    max_stale : DeltaSeconds?
    max_stale_unbounded : Bool
    stale_if_error : DeltaSeconds?
    stale_while_revalidate : DeltaSeconds?
    malformed_delta : Bool
    } derive(Eq,
    Debug
    )

    Cache directives used by both request and response policy. Unknown extensions are intentionally ignored; malformed delta-seconds never become permissive values.

    CacheControl::new

    CacheDecision

    pub(all) struct CacheDecision {
    action : CacheActionKind
    trace : CacheTrace
    storage : StorageDecision
    } derive(Eq,
    Debug
    )

    CacheEvent

    pub(all) struct CacheEvent {
    kind : CacheEventKind
    http_method : String
    uri : String
    status : Int?
    body_bytes : Int64
    count : Int64
    duration_milliseconds : Int64
    detail : String?
    } derive(Eq,
    Debug
    )

    Privacy-conscious event payload. Headers and response bodies are never included; URI and error detail remain available to an explicitly attached observer and should be redacted by applications when necessary.

    CacheEvent::new

    fn CacheEvent::new(kind : CacheEventKind, request : RequestMeta, status? : Int?, body_bytes? : Int64, count? : Int64, duration_milliseconds? : Int64, detail? : String?) -> CacheEvent

    CacheEventKind

    pub(all) enum CacheEventKind {
    CacheRequestCompleted
    CacheHit
    CacheMiss
    CacheBypass
    CacheStored
    CacheRevalidated
    CacheNotModified
    CacheStaleServed
    CacheUpstreamFetched
    CacheUpstreamError
    CacheEvicted
    CachePurged
    CacheCoalesced
    CacheBytesSaved
    CacheUpstreamRequestSaved
    CacheBackgroundRevalidation
    CacheBackgroundFailure
    } derive(Compare, Eq,
    Debug
    )

    Stable operational event categories emitted by cache runtimes.

    CacheEventKind::label

    fn CacheEventKind::label(self : CacheEventKind) -> String

    CacheMode

    pub(all) enum CacheMode {
    Private
    Shared
    } derive(Compare, Eq,
    Debug
    )

    CacheMode::from_string

    fn CacheMode::from_string(value : String) -> CacheMode?

    CacheMode::label

    fn CacheMode::label(self : CacheMode) -> String

    CacheOptions

    pub(all) struct CacheOptions {
    mode : CacheMode
    allow_heuristic_freshness : Bool
    heuristic_fraction_per_mille : Int
    max_heuristic_lifetime : DeltaSeconds
    allow_shared_authorized : Bool
    cache_head_responses : Bool
    strip_sensitive_metadata : Bool
    } derive(Eq,
    Debug
    )

    Policy settings with privacy-preserving defaults.

    CacheOptions::private_cache

    fn CacheOptions::private_cache() -> CacheOptions

    CacheOptions::shared_cache

    fn CacheOptions::shared_cache() -> CacheOptions

    CacheOptions::with_cache_head_responses

    fn CacheOptions::with_cache_head_responses(self : CacheOptions, enabled : Bool) -> CacheOptions

    CacheOptions::with_heuristic_freshness

    fn CacheOptions::with_heuristic_freshness(self : CacheOptions, enabled : Bool) -> CacheOptions

    CacheOptions::with_heuristic_settings

    fn CacheOptions::with_heuristic_settings(self : CacheOptions, fraction_per_mille : Int, maximum : DeltaSeconds) -> CacheOptions

    CacheOptions::with_shared_authorized

    fn CacheOptions::with_shared_authorized(self : CacheOptions, enabled : Bool) -> CacheOptions

    CacheReason

    pub(all) struct CacheReason {
    code : CacheReasonCode
    detail : String?
    rfc : String?
    } derive(Eq,
    Debug
    )

    CacheReason::new

    CacheReason::with_detail

    fn CacheReason::with_detail(code : CacheReasonCode, detail : String) -> CacheReason

    CacheReason::with_rfc

    fn CacheReason::with_rfc(code : CacheReasonCode, rfc : String) -> CacheReason

    CacheReasonCode

    pub(all) enum CacheReasonCode {
    StoreAllowed
    StoreMethodUnsupported
    StoreStatusDefault
    StoreStatusExplicit
    StoreStatusUnknown
    StoreNoStore
    StorePrivateShared
    StoreAuthorizationShared
    StoreIncomplete
    StoreVaryStar
    StoreOversized
    StoreCapacityZero
    FreshMaxAge
    FreshSharedMaxAge
    FreshExpires
    FreshHeuristic
    FreshNone
    FreshStillFresh
    FreshStale
    AgeApparent
    AgeCorrected
    AgeClockClamped
    AgeOverflowClamped
    RequestNoStore
    RequestNoCache
    RequestOnlyIfCached
    RequestMaxAge
    RequestMinFresh
    RequestMaxStale
    VaryDefault
    VaryMatched
    VaryMismatch
    VaryMissing
    VaryStar
    RevalidateEtag
    RevalidateLastModified
    RevalidateBoth
    RevalidateCallerCondition
    RevalidateNotModified
    RevalidateModified
    RuntimeHit
    RuntimeMiss
    RuntimeBypass
    RuntimeFetch
    RuntimeStored
    RuntimeNotStored
    RuntimeOnlyIfCachedMiss
    RuntimeCoalesced
    StaleIfError
    StaleWhileRevalidate
    StaleWindowExceeded
    StaleForbidden
    StaleUpstreamError
    StaleBackgroundRevalidation
    StaleBackgroundFailure
    StoreReplaced
    StoreEvictedEntries
    StoreEvictedBytes
    StoreInvalidated
    InvalidateUnsafeMethod
    InvalidateRelatedUri
    InvalidateSkippedSafeMethod
    InvalidateSkippedErrorStatus
    } derive(Compare, Eq,
    Debug
    )

    Stable machine-readable reasons used by policy, store, runtime, and CLI traces. Existing code strings are not repurposed.

    CacheReasonCode::code

    fn CacheReasonCode::code(self : CacheReasonCode) -> String

    CacheReasonCode::message

    fn CacheReasonCode::message(self : CacheReasonCode) -> String

    CacheScenario

    pub(all) struct CacheScenario {
    name : String
    mode : String
    now : Int
    request : ScenarioRequest
    stored_response : ScenarioResponse?
    upstream_response : ScenarioResponse?
    expected : ScenarioExpected?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    Stable, transport-free scenario format used by unit tests and the CLI.

    CacheStats

    pub struct CacheStats {
    // private fields
    }

    Mutable event accumulator. Call snapshot to obtain an immutable report.

    CacheStats::new

    fn CacheStats::new() -> CacheStats

    CacheStats::snapshot

    fn CacheStats::snapshot(self : CacheStats) -> CacheStatsSnapshot

    CacheStatsSnapshot

    pub(all) struct CacheStatsSnapshot {
    requests : Int64
    hits : Int64
    misses : Int64
    bypasses : Int64
    stores : Int64
    revalidations : Int64
    not_modified : Int64
    stale_served : Int64
    upstream_fetches : Int64
    upstream_errors : Int64
    evictions : Int64
    purges : Int64
    purged_entries : Int64
    coalesced_requests : Int64
    saved_bytes : Int64
    saved_upstream_requests : Int64
    validation_samples : Int64
    total_validation_milliseconds : Int64
    average_validation_milliseconds : Int64
    background_revalidations : Int64
    background_failures : Int64
    } derive(Eq,
    Debug
    )

    CacheStatsSnapshot::hit_rate_per_mille

    fn CacheStatsSnapshot::hit_rate_per_mille(self : CacheStatsSnapshot) -> Int

    CacheStatsSnapshot::json_report

    fn CacheStatsSnapshot::json_report(self : CacheStatsSnapshot) -> String

    CacheStatsSnapshot::text_report

    fn CacheStatsSnapshot::text_report(self : CacheStatsSnapshot) -> String

    CacheStatsSnapshot::to_json

    CacheStatsSnapshot::with_coalesced_total

    fn CacheStatsSnapshot::with_coalesced_total(self : CacheStatsSnapshot, total : Int64) -> CacheStatsSnapshot

    Reconcile successful observer events with a request group's authoritative count, including followers whose shared operation failed.

    CacheTelemetry

    pub struct CacheTelemetry {
    // private fields
    }

    Shared runtime telemetry used by portable and async integrations.

    CacheTelemetry::new

    CacheTelemetry::record_background_failure

    fn CacheTelemetry::record_background_failure(self : CacheTelemetry, request : RuntimeRequest, detail : String) -> Unit

    CacheTelemetry::record_background_revalidation

    fn CacheTelemetry::record_background_revalidation(self : CacheTelemetry, request : RuntimeRequest) -> Unit

    CacheTelemetry::record_coalesced

    fn CacheTelemetry::record_coalesced(self : CacheTelemetry, request : RuntimeRequest, response : RuntimeResponse) -> Unit

    CacheTelemetry::record_coalesced_operation

    fn CacheTelemetry::record_coalesced_operation(self : CacheTelemetry, request : RuntimeRequest) -> Unit

    Record a coalesced maintenance operation that has no user response body.

    CacheTelemetry::record_purge

    fn CacheTelemetry::record_purge(self : CacheTelemetry, http_method : String, uri : String, removed : Int) -> Unit

    CacheTelemetry::record_response

    fn CacheTelemetry::record_response(self : CacheTelemetry, request : RuntimeRequest, response : RuntimeResponse, before : StoreStats, after : StoreStats) -> Unit

    Record one non-coalesced runtime result and any Store counter deltas.

    CacheTelemetry::record_upstream_error

    fn CacheTelemetry::record_upstream_error(self : CacheTelemetry, request : RuntimeRequest, detail : String, before : StoreStats, after : StoreStats) -> Unit

    CacheTelemetry::snapshot

    CacheTelemetry::with_observer

    fn[O : CacheObserver] CacheTelemetry::with_observer(self : CacheTelemetry, observer : O) -> CacheTelemetry

    CacheTrace

    pub(all) struct CacheTrace {
    action : CacheActionKind
    reasons : Array[CacheReason]
    age : AgeCalculation?
    freshness_lifetime : DeltaSeconds?
    stale_by : DeltaSeconds?
    primary_key : String?
    selected_variant : String?
    validator : String?
    generated_headers : HeaderMap
    } derive(Eq,
    Debug
    )

    CacheTrace::add_reason

    fn CacheTrace::add_reason(self : CacheTrace, reason : CacheReason) -> Unit

    CacheTrace::copy

    fn CacheTrace::copy(self : CacheTrace) -> CacheTrace

    Deep-copy mutable trace collections for independently returned responses.

    CacheTrace::has_reason

    fn CacheTrace::has_reason(self : CacheTrace, code : CacheReasonCode) -> Bool

    CacheTrace::json_report

    fn CacheTrace::json_report(self : CacheTrace) -> String

    CacheTrace::new

    CacheTrace::text_report

    fn CacheTrace::text_report(self : CacheTrace) -> String

    CacheTrace::to_json

    fn CacheTrace::to_json(self : CacheTrace) -> Json

    CachedRuntime

    pub struct CachedRuntime[S, T] {
    // private fields
    }

    CachedRuntime::clear

    fn[S : CacheStore, T] CachedRuntime::clear(self : CachedRuntime[S, T]) -> Unit

    CachedRuntime::execute

    fn[S : CacheStore, T : Transport] CachedRuntime::execute(self : CachedRuntime[S, T], request : RuntimeRequest, now : Timestamp) -> RuntimeResponse raise RuntimeError

    The error path must inspect err for telemetry messaging before re-raising, so the mechanical errdefer rewrite does not apply here.

    CachedRuntime::new

    fn[S, T] CachedRuntime::new(store : S, transport : T, options : CacheOptions) -> CachedRuntime[S, T]

    CachedRuntime::purge

    fn[S : CacheStore, T] CachedRuntime::purge(self : CachedRuntime[S, T], uri : String) -> Int

    CachedRuntime::stats_snapshot

    fn[S, T] CachedRuntime::stats_snapshot(self : CachedRuntime[S, T]) -> CacheStatsSnapshot

    CachedRuntime::store_stats

    fn[S : CacheStore, T] CachedRuntime::store_stats(self : CachedRuntime[S, T]) -> StoreStats

    CachedRuntime::with_observer

    fn[S, T, O : CacheObserver] CachedRuntime::with_observer(self : CachedRuntime[S, T], observer : O) -> CachedRuntime[S, T]

    DeltaSeconds

    A non-negative number of seconds. Construction and arithmetic saturate instead of wrapping into negative values.

    DeltaSeconds::from_seconds

    fn DeltaSeconds::from_seconds(value : Int64) -> DeltaSeconds

    DeltaSeconds::max

    DeltaSeconds::max_value

    fn DeltaSeconds::max_value() -> DeltaSeconds

    DeltaSeconds::min

    DeltaSeconds::saturating_add

    fn DeltaSeconds::saturating_add(self : DeltaSeconds, other : DeltaSeconds) -> DeltaSeconds

    DeltaSeconds::saturating_scale

    fn DeltaSeconds::saturating_scale(self : DeltaSeconds, numerator : Int64, denominator : Int64) -> DeltaSeconds

    Scale a duration with integer arithmetic. Invalid or non-positive factors produce zero; multiplication is rearranged to avoid overflow.

    DeltaSeconds::saturating_sub

    fn DeltaSeconds::saturating_sub(self : DeltaSeconds, other : DeltaSeconds) -> DeltaSeconds

    DeltaSeconds::seconds

    fn DeltaSeconds::seconds(self : DeltaSeconds) -> Int64

    DeltaSeconds::zero

    FakeTransport

    pub struct FakeTransport {
    // private fields
    }

    FakeTransport::call_count

    fn FakeTransport::call_count(self : FakeTransport) -> Int

    FakeTransport::execute

    FakeTransport::new

    FakeTransport::with_outcomes

    fn FakeTransport::with_outcomes(outcomes : Array[TransportOutcome]) -> FakeTransport

    FreshnessCalculation

    pub(all) struct FreshnessCalculation {
    lifetime : DeltaSeconds
    source : FreshnessSource
    date_value : Timestamp
    expires_value : Timestamp?
    last_modified_value : Timestamp?
    } derive(Eq,
    Debug
    )

    FreshnessSource

    pub(all) enum FreshnessSource {
    SharedMaxAge
    MaxAge
    Expires
    HeuristicLastModified
    NoFreshness
    } derive(Compare, Eq,
    Debug
    )

    FreshnessSource::label

    fn FreshnessSource::label(self : FreshnessSource) -> String

    FreshnessSource::reason

    HeaderMap

    pub struct HeaderMap {
    values : Map[String, Array[String]]
    } derive(Eq,
    Debug
    )

    A case-insensitive, insertion-ordered collection of HTTP fields.

    Repeated fields are retained as separate values. contains distinguishes a missing field from a present field whose value is empty, which is required for correct Vary matching.

    HeaderMap::append

    fn HeaderMap::append(self : HeaderMap, name : String, value : String) -> Bool

    Add one value for name, retaining previous values.

    HeaderMap::contains

    fn HeaderMap::contains(self : HeaderMap, name : String) -> Bool

    HeaderMap::copy

    fn HeaderMap::copy(self : HeaderMap) -> HeaderMap

    Create a deep copy so callers cannot mutate arrays held by the source map.

    HeaderMap::from_pairs

    fn HeaderMap::from_pairs(pairs : Array[(String, String)]) -> HeaderMap

    HeaderMap::get

    fn HeaderMap::get(self : HeaderMap, name : String) -> String?

    Combine repeated field values using the comma convention used by the cache directives handled by MoonCache.

    HeaderMap::get_all

    fn HeaderMap::get_all(self : HeaderMap, name : String) -> Array[String]

    Return a defensive copy of every value for name.

    HeaderMap::get_first

    fn HeaderMap::get_first(self : HeaderMap, name : String) -> String?

    HeaderMap::is_empty

    fn HeaderMap::is_empty(self : HeaderMap) -> Bool

    HeaderMap::length

    fn HeaderMap::length(self : HeaderMap) -> Int

    HeaderMap::names

    fn HeaderMap::names(self : HeaderMap) -> Array[String]

    Return canonical field names in deterministic lexical order.

    HeaderMap::new

    fn HeaderMap::new() -> HeaderMap

    HeaderMap::overlay

    fn HeaderMap::overlay(self : HeaderMap, updates : HeaderMap) -> HeaderMap

    Overlay every field from updates, replacing existing repeated values.

    HeaderMap::pairs

    fn HeaderMap::pairs(self : HeaderMap) -> Array[(String, String)]

    Return normalized field/value pairs in deterministic name order while preserving value order within each repeated field.

    HeaderMap::redacted

    fn HeaderMap::redacted(self : HeaderMap) -> HeaderMap

    Return a copy suitable for diagnostics. Credential and cookie values are replaced while their presence remains visible.

    HeaderMap::remove

    fn HeaderMap::remove(self : HeaderMap, name : String) -> Bool

    HeaderMap::set

    fn HeaderMap::set(self : HeaderMap, name : String, value : String) -> Bool

    Replace all existing values for name. Invalid field names are rejected and leave the map unchanged.

    InvalidationPlan

    pub(all) struct InvalidationPlan {
    uris : Array[String]
    reasons : Array[CacheReason]
    } derive(Eq,
    Debug
    )

    MemoryStore

    pub struct MemoryStore {
    // private fields
    }

    HTTP-specific in-memory store with deterministic logical access ordering.

    MemoryStore::cached_uris

    fn MemoryStore::cached_uris(self : MemoryStore) -> Array[String]

    Return each normalized cached URI once in deterministic lexical order.

    MemoryStore::clear

    fn MemoryStore::clear(self : MemoryStore) -> Unit

    MemoryStore::contains_variant

    fn MemoryStore::contains_variant(self : MemoryStore, key : PrimaryCacheKey, variant : VariantKey) -> Bool

    MemoryStore::default

    fn MemoryStore::default() -> MemoryStore

    MemoryStore::find_variants

    fn MemoryStore::find_variants(self : MemoryStore, key : PrimaryCacheKey) -> Array[StoredEntry]

    MemoryStore::invalidate_uri

    fn MemoryStore::invalidate_uri(self : MemoryStore, uri : String) -> Int

    MemoryStore::new

    MemoryStore::options

    Return the immutable configuration used by this Store.

    MemoryStore::peek_variants

    fn MemoryStore::peek_variants(self : MemoryStore, uri : String) -> Array[StoredEntry]

    Inspect variants for a URI without updating logical access order or lookup counters. Returned entries are defensive copies.

    MemoryStore::put

    fn MemoryStore::put(self : MemoryStore, source_entry : StoredEntry) -> StorePutResult

    MemoryStore::remove_variant

    fn MemoryStore::remove_variant(self : MemoryStore, key : PrimaryCacheKey, variant : VariantKey) -> Bool

    MemoryStore::stats

    fn MemoryStore::stats(self : MemoryStore) -> StoreStats

    MemoryStore::variant_count

    fn MemoryStore::variant_count(self : MemoryStore, uri : String) -> Int

    MemoryStoreOptions

    pub(all) struct MemoryStoreOptions {
    max_entries : Int
    max_body_bytes : Int64
    max_body_size : Int64
    strip_set_cookie : Bool
    strip_request_credentials : Bool
    } derive(Eq,
    Debug
    )

    MemoryStoreOptions::default

    MemoryStoreOptions::with_entry_limit

    fn MemoryStoreOptions::with_entry_limit(self : MemoryStoreOptions, max_entries : Int) -> MemoryStoreOptions

    MemoryStoreOptions::with_limits

    fn MemoryStoreOptions::with_limits(max_entries : Int, max_body_bytes : Int64, max_body_size : Int64) -> MemoryStoreOptions

    MemoryStoreOptions::with_request_credential_stripping

    fn MemoryStoreOptions::with_request_credential_stripping(self : MemoryStoreOptions, strip_request_credentials : Bool) -> MemoryStoreOptions

    fn MemoryStoreOptions::with_set_cookie_stripping(self : MemoryStoreOptions, strip_set_cookie : Bool) -> MemoryStoreOptions

    MemoryStoreOptions::with_single_body_limit

    fn MemoryStoreOptions::with_single_body_limit(self : MemoryStoreOptions, max_body_size : Int64) -> MemoryStoreOptions

    MemoryStoreOptions::with_total_body_limit

    fn MemoryStoreOptions::with_total_body_limit(self : MemoryStoreOptions, max_body_bytes : Int64) -> MemoryStoreOptions

    NotModifiedResult

    pub(all) struct NotModifiedResult {
    entry : StoredEntry
    storage : StorageDecision
    reasons : Array[CacheReason]
    } derive(Eq,
    Debug
    )

    PrimaryCacheKey

    pub(all) struct PrimaryCacheKey {
    http_method : String
    uri : String
    } derive(Compare, Eq, Hash,
    Debug
    )

    The primary lookup key. GET and HEAD compatibility is applied by the variant module when constructing this value.

    PrimaryCacheKey::from_request

    fn PrimaryCacheKey::from_request(request : RequestMeta) -> PrimaryCacheKey?

    PrimaryCacheKey::label

    fn PrimaryCacheKey::label(self : PrimaryCacheKey) -> String

    PrimaryCacheKey::new

    fn PrimaryCacheKey::new(http_method : String, uri : String) -> PrimaryCacheKey

    RecordingTransport

    pub struct RecordingTransport {
    // private fields
    }

    RecordingTransport::call_count

    fn RecordingTransport::call_count(self : RecordingTransport) -> Int

    RecordingTransport::calls

    RecordingTransport::execute

    RecordingTransport::new

    RecordingTransport::with_outcomes

    RequestMeta

    pub(all) struct RequestMeta {
    http_method : String
    uri : String
    headers : HeaderMap
    request_time : Timestamp
    } derive(Eq,
    Debug
    )

    Metadata supplied to the cache policy. The request time is injected by the caller and never read from a system clock.

    RequestMeta::new

    fn RequestMeta::new(http_method : String, uri : String, headers : HeaderMap, request_time : Timestamp) -> RequestMeta

    RequestMeta::simple

    fn RequestMeta::simple(http_method : String, uri : String) -> RequestMeta

    RequestMeta::with_headers

    fn RequestMeta::with_headers(self : RequestMeta, headers : HeaderMap) -> RequestMeta

    RequestMeta::with_request_time

    fn RequestMeta::with_request_time(self : RequestMeta, request_time : Timestamp) -> RequestMeta

    RequestPolicy

    pub(all) struct RequestPolicy {
    bypass : Bool
    force_revalidation : Bool
    only_if_cached : Bool
    max_age : DeltaSeconds?
    min_fresh : DeltaSeconds
    max_stale : DeltaSeconds?
    max_stale_unbounded : Bool
    } derive(Eq,
    Debug
    )

    RequestPolicy::allows_stale

    fn RequestPolicy::allows_stale(self : RequestPolicy, stale_by : DeltaSeconds) -> Bool

    ResponseMeta

    pub(all) struct ResponseMeta {
    status : Int
    headers : HeaderMap
    request_time : Timestamp
    response_time : Timestamp
    body_complete : Bool
    } derive(Eq,
    Debug
    )

    Normalized response metadata. body_complete lets adapters conservatively reject interrupted or size-limited bodies.

    ResponseMeta::complete

    fn ResponseMeta::complete(status : Int, headers : HeaderMap, request_time : Timestamp, response_time : Timestamp) -> ResponseMeta

    ResponseMeta::new

    fn ResponseMeta::new(status : Int, headers : HeaderMap, request_time : Timestamp, response_time : Timestamp, body_complete : Bool) -> ResponseMeta

    ResponseSource

    pub(all) enum ResponseSource {
    CacheSource
    UpstreamSource
    RevalidatedSource
    StaleSource
    OnlyIfCachedSource
    } derive(Compare, Eq,
    Debug
    )

    ResponseSource::label

    fn ResponseSource::label(self : ResponseSource) -> String

    RevalidationPlan

    pub(all) struct RevalidationPlan {
    request : RequestMeta
    generated_headers : HeaderMap
    validator_kind : ValidatorKind?
    reasons : Array[CacheReason]
    } derive(Eq,
    Debug
    )

    RevalidationPlan::can_revalidate

    fn RevalidationPlan::can_revalidate(self : RevalidationPlan) -> Bool

    RuntimeRequest

    pub(all) struct RuntimeRequest {
    meta : RequestMeta
    body : Bytes
    } derive(Eq,
    Debug
    )

    RuntimeRequest::copy

    RuntimeRequest::get

    fn RuntimeRequest::get(uri : String) -> RuntimeRequest

    RuntimeRequest::head

    fn RuntimeRequest::head(uri : String) -> RuntimeRequest

    RuntimeRequest::new

    fn RuntimeRequest::new(meta : RequestMeta, body : Bytes) -> RuntimeRequest

    RuntimeRequest::with_body

    fn RuntimeRequest::with_body(self : RuntimeRequest, body : Bytes) -> RuntimeRequest

    RuntimeRequest::with_headers

    fn RuntimeRequest::with_headers(self : RuntimeRequest, headers : HeaderMap) -> RuntimeRequest

    RuntimeRequest::with_request_time

    fn RuntimeRequest::with_request_time(self : RuntimeRequest, request_time : Timestamp) -> RuntimeRequest

    RuntimeResponse

    pub(all) struct RuntimeResponse {
    meta : ResponseMeta
    body : Bytes
    source : ResponseSource
    trace : CacheTrace
    } derive(Eq,
    Debug
    )

    RuntimeResponse::copy

    Deep-copy mutable metadata and trace state while sharing immutable bytes.

    RuntimeResponse::is_cache_reuse

    fn RuntimeResponse::is_cache_reuse(self : RuntimeResponse) -> Bool

    RuntimeResponse::json_report

    fn RuntimeResponse::json_report(self : RuntimeResponse) -> String

    RuntimeResponse::text_report

    fn RuntimeResponse::text_report(self : RuntimeResponse) -> String

    RuntimeResponse::to_json

    fn RuntimeResponse::to_json(self : RuntimeResponse) -> Json

    Structured runtime report. Response bodies are deliberately excluded; their size is enough for diagnostics and cannot leak cached content.

    ScenarioAnalysis

    pub(all) struct ScenarioAnalysis {
    name : String
    trace : CacheTrace
    valid : Bool
    errors : Array[String]
    } derive(Eq,
    Debug
    )

    ScenarioExpected

    pub(all) struct ScenarioExpected {
    action : String
    reason : String?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    ScenarioRequest

    pub(all) struct ScenarioRequest {
    http_method : String
    uri : String
    headers : Map[String, String]
    request_time : Int?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    ScenarioRequest::to_meta

    ScenarioResponse

    pub(all) struct ScenarioResponse {
    status : Int
    headers : Map[String, String]
    request_time : Int?
    response_time : Int?
    body : String?
    complete : Bool?
    } derive(Eq, ToJson,
    Debug
    ,
    FromJson
    )

    ScenarioResponse::body_bytes

    fn ScenarioResponse::body_bytes(self : ScenarioResponse) -> Bytes

    ScenarioResponse::to_meta

    fn ScenarioResponse::to_meta(self : ScenarioResponse, fallback_request_time : Timestamp) -> ResponseMeta

    StalePolicy

    pub(all) struct StalePolicy {
    is_stale : Bool
    stale_by : DeltaSeconds
    stale_if_error_window : DeltaSeconds?
    stale_while_revalidate_window : DeltaSeconds?
    stale_if_error_allowed : Bool
    stale_while_revalidate_allowed : Bool
    prohibited : Bool
    } derive(Eq,
    Debug
    )

    Evaluation of RFC 5861 stale extensions for one stored response.

    StorageDecision

    pub(all) struct StorageDecision {
    storable : Bool
    policy : StoredPolicy
    reasons : Array[CacheReason]
    } derive(Eq,
    Debug
    )

    StorePutResult

    pub(all) enum StorePutResult {
    StoreInserted
    StoreReplacedResult
    StoreRejectedNoStore
    StoreRejectedOversized
    StoreRejectedCapacity
    } derive(Compare, Eq,
    Debug
    )

    StorePutResult::accepted

    fn StorePutResult::accepted(self : StorePutResult) -> Bool

    StorePutResult::label

    fn StorePutResult::label(self : StorePutResult) -> String

    StoreStats

    pub(all) struct StoreStats {
    entries : Int
    body_bytes : Int64
    puts : Int64
    replacements : Int64
    evictions : Int64
    lookups : Int64
    hits : Int64
    misses : Int64
    invalidated_entries : Int64
    rejected_entries : Int64
    } derive(Eq,
    Debug
    )

    StoreStats::hit_rate_per_mille

    fn StoreStats::hit_rate_per_mille(self : StoreStats) -> Int

    Integer hit ratio in thousandths, suitable for deterministic reports.

    StoreStats::is_empty

    fn StoreStats::is_empty(self : StoreStats) -> Bool

    StoreStats::json_report

    fn StoreStats::json_report(self : StoreStats) -> String

    StoreStats::requests

    fn StoreStats::requests(self : StoreStats) -> Int64

    StoreStats::saved_origin_requests

    fn StoreStats::saved_origin_requests(self : StoreStats) -> Int64

    StoreStats::text_report

    fn StoreStats::text_report(self : StoreStats) -> String

    StoreStats::to_json

    fn StoreStats::to_json(self : StoreStats) -> Json

    StoredEntry

    pub(all) struct StoredEntry {
    primary_key : PrimaryCacheKey
    variant_key : VariantKey
    request : RequestMeta
    response : ResponseMeta
    body : Bytes
    policy : StoredPolicy
    stored_at : Timestamp
    last_accessed_at : Timestamp
    } derive(Eq,
    Debug
    )

    StoredEntry::body_size

    fn StoredEntry::body_size(self : StoredEntry) -> Int64

    StoredEntry::copy

    fn StoredEntry::copy(self : StoredEntry) -> StoredEntry

    Deep-copy mutable metadata while sharing the immutable body bytes.

    StoredEntry::new

    fn StoredEntry::new(primary_key : PrimaryCacheKey, variant_key : VariantKey, request : RequestMeta, response : ResponseMeta, body : Bytes, policy : StoredPolicy, stored_at : Timestamp) -> StoredEntry

    StoredEntry::touch

    fn StoredEntry::touch(self : StoredEntry, now : Timestamp) -> StoredEntry

    StoredPolicy

    pub(all) struct StoredPolicy {
    cacheable : Bool
    freshness_lifetime : DeltaSeconds
    requires_revalidation : Bool
    no_store : Bool
    vary_star : Bool
    must_revalidate : Bool
    proxy_revalidate : Bool
    is_private : Bool
    is_public : Bool
    } derive(Eq,
    Debug
    )

    StoredPolicy::cacheable

    fn StoredPolicy::cacheable(lifetime : DeltaSeconds, requires_revalidation : Bool) -> StoredPolicy

    StoredPolicy::from_directives

    fn StoredPolicy::from_directives(lifetime : DeltaSeconds, directives : CacheControl, vary_star : Bool) -> StoredPolicy

    StoredPolicy::uncacheable

    fn StoredPolicy::uncacheable() -> StoredPolicy

    Timestamp

    A non-negative instant represented as caller-supplied epoch seconds.

    Timestamp::elapsed_since

    fn Timestamp::elapsed_since(self : Timestamp, earlier : Timestamp) -> DeltaSeconds

    Return a non-negative duration even when the supplied clock moved backward.

    Timestamp::from_seconds

    fn Timestamp::from_seconds(value : Int64) -> Timestamp

    Timestamp::saturating_add

    fn Timestamp::saturating_add(self : Timestamp, delta : DeltaSeconds) -> Timestamp

    Timestamp::seconds

    fn Timestamp::seconds(self : Timestamp) -> Int64

    Timestamp::zero

    fn Timestamp::zero() -> Timestamp

    TransportOutcome

    pub(all) enum TransportOutcome {
    TransportSuccess(TransportResponse)
    TransportFailure(String)
    } derive(Eq,
    Debug
    )

    TransportResponse

    pub(all) struct TransportResponse {
    meta : ResponseMeta
    body : Bytes
    } derive(Eq,
    Debug
    )

    TransportResponse::copy

    TransportResponse::new

    fn TransportResponse::new(meta : ResponseMeta, body : Bytes) -> TransportResponse

    ValidatorKind

    pub(all) enum ValidatorKind {
    StrongEtag
    WeakEtag
    LastModified
    StrongEtagAndLastModified
    WeakEtagAndLastModified
    CallerConditions
    } derive(Compare, Eq,
    Debug
    )

    ValidatorKind::label

    fn ValidatorKind::label(self : ValidatorKind) -> String

    VariantKey

    pub(all) struct VariantKey {
    canonical : String
    label : String
    } derive(Compare, Eq, Hash,
    Debug
    )

    An opaque deterministic encoding of the request fields selected by Vary.

    VariantKey::empty

    fn VariantKey::empty() -> VariantKey

    VariantKey::from_canonical

    fn VariantKey::from_canonical(canonical : String, label : String) -> VariantKey

    VariantSelection

    pub(all) struct VariantSelection {
    entry : StoredEntry?
    inspected : Int
    variant_key : VariantKey?
    reasons : Array[CacheReason]
    } derive(Eq,
    Debug
    )

    VaryMatch

    pub(all) struct VaryMatch {
    kind : VaryMatchKind
    differing_field : String?
    stored_key : VariantKey?
    candidate_key : VariantKey?
    reason : CacheReason
    } derive(Eq,
    Debug
    )

    VaryMatchKind

    pub(all) enum VaryMatchKind {
    VaryMatchedResult
    VaryMismatchResult
    VaryStarResult
    } derive(Compare, Eq,
    Debug
    )

    VarySpec

    pub(all) struct VarySpec {
    fields : Array[String]
    star : Bool
    } derive(Eq,
    Debug
    )

    VarySpec::default

    fn VarySpec::default() -> VarySpec

    MAX_DELTA_SECONDS

    let MAX_DELTA_SECONDS : Int64

    The greatest non-negative duration accepted by MoonCache.

    analyze_scenario

    fn analyze_scenario(scenario : CacheScenario) -> ScenarioAnalysis raise ScenarioError

    analyze_scenario_json

    fn analyze_scenario_json(text : String) -> ScenarioAnalysis raise ScenarioError

    build_variant_key

    fn build_variant_key(headers : HeaderMap, vary : VarySpec) -> VariantKey?

    Build an opaque length-prefixed key so missing, empty, repeated, and delimiter-containing values cannot collide.

    cache_control_from_headers

    fn cache_control_from_headers(headers : HeaderMap) -> CacheControl

    cache_origin

    fn cache_origin(uri : String) -> String?

    calculate_current_age

    fn calculate_current_age(response : ResponseMeta, now : Timestamp) -> AgeCalculation

    Calculate corrected current age according to RFC 9111 section 4.2.3.

    calculate_freshness_lifetime

    fn calculate_freshness_lifetime(response : ResponseMeta, options : CacheOptions) -> FreshnessCalculation

    Calculate freshness lifetime using RFC directive precedence. Shared caches prefer s-maxage; explicit expiration precedes the conservative Last-Modified heuristic.

    create_revalidation_plan

    fn create_revalidation_plan(request : RequestMeta, stored_response : ResponseMeta) -> RevalidationPlan

    Generate conditional fields without replacing conditions supplied by the caller. Strong and weak ETags are both valid for If-None-Match.

    evaluate_cached_response

    fn evaluate_cached_response(request : RequestMeta, response : ResponseMeta, options : CacheOptions, now : Timestamp) -> CacheDecision

    Evaluate one matching cached response at the injected time. Variant lookup and conditional header generation are layered on this deterministic policy function.

    evaluate_request_policy

    fn evaluate_request_policy(request : RequestMeta) -> RequestPolicy

    evaluate_stale_policy

    fn evaluate_stale_policy(request : RequestMeta, response : ResponseMeta, options : CacheOptions, now : Timestamp) -> StalePolicy

    Evaluate origin- and client-provided stale permissions without performing I/O. Explicit revalidation requirements remain stronger than extensions.

    evaluate_storage

    fn evaluate_storage(request : RequestMeta, response : ResponseMeta, options : CacheOptions) -> StorageDecision

    Decide whether a complete response may enter the selected cache mode.

    execute_cached

    fn[S : CacheStore, T : Transport] execute_cached(store : S, transport : T, options : CacheOptions, request : RuntimeRequest, now : Timestamp) -> RuntimeResponse raise RuntimeError

    Execute the complete initial-acceptance cache lifecycle.

    explain_scenario_json

    fn explain_scenario_json(text : String) -> String raise ScenarioError

    explain_scenario_text

    fn explain_scenario_text(text : String) -> String raise ScenarioError

    has_usable_validator

    fn has_usable_validator(response : ResponseMeta) -> Bool

    is_default_cacheable_status

    fn is_default_cacheable_status(status : Int) -> Bool

    Statuses defined as heuristically cacheable by RFC 9111. Partial-content status 206 is excluded because range caching is outside the 0.1.3 scope.

    is_safe_http_method

    fn is_safe_http_method(http_method : String) -> Bool

    is_stale_if_error_status

    fn is_stale_if_error_status(status : Int) -> Bool

    RFC 5861 defines these statuses as errors eligible for stale-if-error.

    is_valid_etag

    fn is_valid_etag(value : String) -> Bool

    is_valid_header_name

    fn is_valid_header_name(name : String) -> Bool

    Check the RFC 9110 token grammar used by HTTP field names.

    match_vary

    fn match_vary(stored_request : RequestMeta, candidate_request : RequestMeta, stored_response : ResponseMeta) -> VaryMatch

    merge_not_modified

    fn merge_not_modified(entry : StoredEntry, not_modified : ResponseMeta, options : CacheOptions, now : Timestamp) -> NotModifiedResult raise ValidationError

    Merge a 304 response into a stored entry while retaining the cached status and body, then recompute cacheability, freshness, and variant identity.

    normalize_cache_uri

    fn normalize_cache_uri(uri : String) -> String?

    Normalize an absolute HTTP(S) URI for primary cache lookup.

    Scheme and host are lower-cased, default ports and fragments are removed, an empty path becomes /, and literal dot segments are resolved. Query text and percent-encoded octets are otherwise preserved.

    normalize_header_name

    fn normalize_header_name(name : String) -> String

    Return the canonical representation used for case-insensitive HTTP field names. Leading and trailing whitespace is ignored so adapter input can be normalized at the boundary.

    normalize_header_value

    fn normalize_header_value(value : String) -> String

    Remove optional whitespace around an HTTP field value without changing meaningful whitespace inside the value.

    normalize_method

    fn normalize_method(value : String) -> String

    parse_cache_control

    fn parse_cache_control(value : String) -> CacheControl

    Parse the directive subset needed by MoonCache. Directive names are case-insensitive and repeated numeric directives resolve to the smallest valid value, a conservative deterministic choice.

    parse_delta_seconds

    fn parse_delta_seconds(value : String) -> DeltaSeconds?

    Parse an RFC delta-seconds value. Negative, signed, fractional, and malformed values are rejected. Values that fit Int64 are represented without wrapping.

    parse_http_date

    fn parse_http_date(value : String) -> Timestamp?

    Parse the IMF-fixdate form emitted by modern HTTP senders: Sun, 06 Nov 1994 08:49:37 GMT.

    Obsolete HTTP-date forms belong in optional protocol adapters; the cache core intentionally implements only this narrow interoperable representation.

    parse_scenario

    fn parse_scenario(text : String) -> CacheScenario raise ScenarioError

    parse_vary

    fn parse_vary(headers : HeaderMap) -> VarySpec

    plan_invalidation

    fn plan_invalidation(request : RequestMeta, response : ResponseMeta) -> InvalidationPlan

    RFC 9111 invalidation plan for a non-error response to an unsafe method. Related targets are included only when their resolved URI has the same origin as the request target.

    primary_cache_key

    fn primary_cache_key(request : RequestMeta) -> PrimaryCacheKey?

    Construct the primary key. HEAD shares the GET lookup namespace while retaining its request method in RequestMeta.

    request_has_legacy_no_cache

    fn request_has_legacy_no_cache(headers : HeaderMap) -> Bool

    RFC 9111 retains the older Pragma: no-cache request behavior when Cache-Control is absent. This helper keeps that compatibility isolated.
    fn resolve_related_uri(base : String, reference : String) -> String?

    Resolve the absolute and relative URI forms used by Location and Content-Location for invalidation.

    response_validator_kind

    fn response_validator_kind(response : ResponseMeta) -> ValidatorKind?

    same_cache_origin

    fn same_cache_origin(left : String, right : String) -> Bool

    scenario_to_json

    fn scenario_to_json(scenario : CacheScenario) -> String

    select_variant

    fn select_variant(entries : Array[StoredEntry], request : RequestMeta) -> VariantSelection

    Select the newest matching entry. Equal timestamps keep the store's deterministic iteration order.

    validate_scenario_text

    fn validate_scenario_text(text : String) -> String raise ScenarioError