feat(pwa): telefona kurulum, uygulama kabuğu önbelleği, güncelleme bildirimi, çevrimdışı uyarısı
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
//! Derlenmiş arayüzün (frontend/dist) sunulması — tek sayfa uygulama (SPA).
|
||||
//!
|
||||
//! - `/assets/*` : adları içerik özetli (hash) → 1 yıl önbellek, `immutable`
|
||||
//! - diğer dosyalar (favicon, ikonlar): 1 saat önbellek
|
||||
//! - PWA: `sw.js`, `manifest.webmanifest` → hiç önbelleğe alınmaz (yeni sürüm hemen fark edilsin)
|
||||
//! - diğer dosyalar (favicon, ikonlar, `workbox-<hash>.js`): 1 saat önbellek
|
||||
//! - olmayan yol (`/defter`, `/plan` ...) → `index.html` (yönlendirmeyi React Router yapar)
|
||||
//! - HTML hiç önbelleğe alınmaz → yeni sürüm yayınlanınca hemen yüklenir
|
||||
|
||||
@@ -24,19 +25,54 @@ pub fn router(dir: &Path) -> Router {
|
||||
}
|
||||
|
||||
async fn cache_headers(req: Request, next: Next) -> Response {
|
||||
let is_asset = req.uri().path().starts_with("/assets/");
|
||||
let path = req.uri().path().to_string();
|
||||
let mut res = next.run(req).await;
|
||||
|
||||
let is_html = res
|
||||
.headers()
|
||||
.get(header::CONTENT_TYPE)
|
||||
.is_some_and(|v| v.as_bytes().starts_with(b"text/html"));
|
||||
let policy = match (is_html, is_asset) {
|
||||
(true, _) => "no-cache",
|
||||
(false, true) => "public, max-age=31536000, immutable",
|
||||
(false, false) => "public, max-age=3600",
|
||||
};
|
||||
res.headers_mut()
|
||||
.insert(header::CACHE_CONTROL, HeaderValue::from_static(policy));
|
||||
res.headers_mut().insert(
|
||||
header::CACHE_CONTROL,
|
||||
HeaderValue::from_static(cache_policy(&path, is_html)),
|
||||
);
|
||||
res
|
||||
}
|
||||
|
||||
/// Yol ve içerik türüne göre `Cache-Control`
|
||||
fn cache_policy(path: &str, is_html: bool) -> &'static str {
|
||||
const NO_CACHE: &str = "no-cache";
|
||||
if is_html || matches!(path, "/sw.js" | "/manifest.webmanifest" | "/registerSW.js") {
|
||||
NO_CACHE
|
||||
} else if path.starts_with("/assets/") {
|
||||
"public, max-age=31536000, immutable"
|
||||
} else {
|
||||
"public, max-age=3600"
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::cache_policy;
|
||||
|
||||
#[test]
|
||||
fn cache_rules() {
|
||||
assert_eq!(cache_policy("/", true), "no-cache");
|
||||
assert_eq!(
|
||||
cache_policy("/defter", true),
|
||||
"no-cache",
|
||||
"SPA → index.html"
|
||||
);
|
||||
assert_eq!(cache_policy("/sw.js", false), "no-cache");
|
||||
assert_eq!(cache_policy("/manifest.webmanifest", false), "no-cache");
|
||||
assert_eq!(
|
||||
cache_policy("/assets/index-AbC123.js", false),
|
||||
"public, max-age=31536000, immutable"
|
||||
);
|
||||
assert_eq!(cache_policy("/icon-192.png", false), "public, max-age=3600");
|
||||
assert_eq!(
|
||||
cache_policy("/workbox-2ff6bd68.js", false),
|
||||
"public, max-age=3600"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user