///|
pub(all) enum CacheTier {
CacheStable
CacheRefreshable
CacheTransient
CacheCallerManaged
} derive(Eq)
///|
pub(all) struct CachePlan {
path : String
current : CachePolicy
recommended : CachePolicy
tier : CacheTier
aligned : Bool
reason : String
} derive(Eq)
///|
pub(all) struct PolicyProfile {
total : Int
immutable : Int
revalidate : Int
no_store : Int
runtime : Int
aligned : Int
misaligned : Int
stability_score : Int
immutable_bytes : Int
revalidate_bytes : Int
no_store_bytes : Int
runtime_bytes : Int
} derive(Eq)
///|
pub fn CacheTier::to_wire(self : CacheTier) -> String {
match self {
CacheStable => "stable"
CacheRefreshable => "refreshable"
CacheTransient => "transient"
CacheCallerManaged => "caller-managed"
}
}
///|
pub fn cache_tier(policy : CachePolicy) -> CacheTier {
match policy {
Immutable => CacheStable
Revalidate => CacheRefreshable
NoStore => CacheTransient
Runtime => CacheCallerManaged
}
}
///|
pub fn policy_profile(manifest : Manifest) -> PolicyProfile {
let plans = cache_plans(manifest)
let mut immutable = 0
let mut revalidate = 0
let mut no_store = 0
let mut runtime = 0
let mut aligned = 0
let mut misaligned = 0
let mut immutable_bytes = 0
let mut revalidate_bytes = 0
let mut no_store_bytes = 0
let mut runtime_bytes = 0
for entry in manifest.entries {
match entry.policy {
Immutable => {
immutable = immutable + 1
immutable_bytes = immutable_bytes + entry.bytes
}
Revalidate => {
revalidate = revalidate + 1
revalidate_bytes = revalidate_bytes + entry.bytes
}
NoStore => {
no_store = no_store + 1
no_store_bytes = no_store_bytes + entry.bytes
}
Runtime => {
runtime = runtime + 1
runtime_bytes = runtime_bytes + entry.bytes
}
}
}
for plan in plans {
if plan.aligned {
aligned = aligned + 1
} else {
misaligned = misaligned + 1
}
}
{
total: manifest.entries.length(),
immutable,
revalidate,
no_store,
runtime,
aligned,
misaligned,
stability_score: cache_stability_score(manifest),
immutable_bytes,
revalidate_bytes,
no_store_bytes,
runtime_bytes,
}
}
///|
pub fn cache_plans(manifest : Manifest) -> Array[CachePlan] {
let plans : Array[CachePlan] = []
for entry in manifest.entries {
let recommended = recommended_policy(entry)
plans.push({
path: entry.path,
current: entry.policy,
recommended,
tier: cache_tier(recommended),
aligned: entry.policy == recommended,
reason: cache_plan_reason(entry, recommended),
})
}
plans.sort_by((a, b) => a.path.compare(b.path))
plans
}
///|
pub fn misaligned_cache_plans(manifest : Manifest) -> Array[CachePlan] {
let result : Array[CachePlan] = []
for plan in cache_plans(manifest) {
if !plan.aligned {
result.push(plan)
}
}
result
}
///|
pub fn aligned_cache_plans(manifest : Manifest) -> Array[CachePlan] {
let result : Array[CachePlan] = []
for plan in cache_plans(manifest) {
if plan.aligned {
result.push(plan)
}
}
result
}
///|
pub fn assets_requiring_revalidation(manifest : Manifest) -> Array[Asset] {
let result : Array[Asset] = []
for entry in manifest.entries {
if recommended_policy(entry) == Revalidate {
result.push(entry)
}
}
result
}
///|
pub fn assets_safe_for_immutable(manifest : Manifest) -> Array[Asset] {
let result : Array[Asset] = []
for entry in manifest.entries {
if recommended_policy(entry) == Immutable {
result.push(entry)
}
}
result
}
///|
pub fn policy_alignment_score(manifest : Manifest) -> Int {
if manifest.entries.is_empty() {
return 0
}
let aligned = aligned_cache_plans(manifest).length()
aligned * 100 / manifest.entries.length()
}
///|
pub fn policy_needs_review(manifest : Manifest) -> Bool {
policy_alignment_score(manifest) < 80 ||
assets_with_policy(manifest, NoStore).length() > 0 ||
assets_with_policy(manifest, Runtime).length() > 0
}
///|
pub fn render_policy_profile(profile : PolicyProfile) -> String {
let out = StringBuilder()
out.write_string("policy-profile\n")
out.write_string("total ")
out.write_string(profile.total.to_string())
out.write_string("\nimmutable ")
out.write_string(profile.immutable.to_string())
out.write_string(" ")
out.write_string(profile.immutable_bytes.to_string())
out.write_string("\nrevalidate ")
out.write_string(profile.revalidate.to_string())
out.write_string(" ")
out.write_string(profile.revalidate_bytes.to_string())
out.write_string("\nno-store ")
out.write_string(profile.no_store.to_string())
out.write_string(" ")
out.write_string(profile.no_store_bytes.to_string())
out.write_string("\nruntime ")
out.write_string(profile.runtime.to_string())
out.write_string(" ")
out.write_string(profile.runtime_bytes.to_string())
out.write_string("\naligned ")
out.write_string(profile.aligned.to_string())
out.write_string("\nmisaligned ")
out.write_string(profile.misaligned.to_string())
out.write_string("\nstability ")
out.write_string(profile.stability_score.to_string())
out.write_string("\n")
out.to_string()
}
///|
pub fn render_cache_plans(plans : Array[CachePlan]) -> String {
if plans.is_empty() {
return "(none)\n"
}
let out = StringBuilder()
for plan in plans {
out.write_string(plan.path)
out.write_string(" ")
out.write_string(plan.current.to_wire())
out.write_string(" -> ")
out.write_string(plan.recommended.to_wire())
out.write_string(" ")
out.write_string(plan.tier.to_wire())
if plan.aligned {
out.write_string(" aligned")
} else {
out.write_string(" review")
}
out.write_string(" - ")
out.write_string(plan.reason)
out.write_string("\n")
}
out.to_string()
}
///|
fn cache_plan_reason(entry : Asset, recommended : CachePolicy) -> String {
if entry.policy == recommended {
match recommended {
Immutable => "current policy is suitable for fingerprinted stable assets"
Revalidate => "current policy keeps editable assets refreshable"
NoStore => "current policy avoids storing transient assets"
Runtime => "current policy leaves freshness to the caller"
}
} else {
match recommended {
Immutable => "asset looks stable enough for immutable caching"
Revalidate => "asset should stay refreshable across deploys"
NoStore => "asset should avoid persistent caching"
Runtime => "asset should be managed by the caller at runtime"
}
}
}