Compare commits

...

3 Commits

Author SHA1 Message Date
spinline
e878d1fe33 chore(ui): add debug logs for SSE connection lifecycle
All checks were successful
Build MIPS Binary / build (push) Successful in 1m56s
2026-02-21 00:29:27 +03:00
spinline
d88084fb9a fix(ui): fix service worker crashes for chrome extensions and bump cache version
All checks were successful
Build MIPS Binary / build (push) Successful in 1m57s
2026-02-21 00:25:28 +03:00
spinline
f8639f2967 chore(ui): add debug logs for SSE deserialization errors
All checks were successful
Build MIPS Binary / build (push) Successful in 1m56s
2026-02-21 00:23:23 +03:00
2 changed files with 46 additions and 25 deletions

View File

@@ -88,10 +88,13 @@ pub fn provide_torrent_store() {
let mut disconnect_notified = false; let mut disconnect_notified = false;
loop { loop {
log::info!("[SSE] Attempting to connect to /api/events...");
let es_result = EventSource::new("/api/events"); let es_result = EventSource::new("/api/events");
match es_result { match es_result {
Ok(mut es) => { Ok(mut es) => {
log::info!("[SSE] EventSource instantiated successfully.");
if let Ok(mut stream) = es.subscribe("message") { if let Ok(mut stream) = es.subscribe("message") {
log::info!("[SSE] Subscribed to 'message' events.");
let mut got_first_message = false; let mut got_first_message = false;
while let Some(Ok((_, msg))) = stream.next().await { while let Some(Ok((_, msg))) = stream.next().await {
if !got_first_message { if !got_first_message {
@@ -105,29 +108,40 @@ pub fn provide_torrent_store() {
} }
if let Some(data_str) = msg.data().as_string() { if let Some(data_str) = msg.data().as_string() {
if let Ok(bytes) = BASE64.decode(&data_str) { log::info!("[SSE] Received message: {:?}", data_str.chars().take(50).collect::<String>());
if let Ok(event) = rmp_serde::from_slice::<AppEvent>(&bytes) { match BASE64.decode(&data_str) {
match event { Ok(bytes) => {
AppEvent::FullList(list, _) => { match rmp_serde::from_slice::<AppEvent>(&bytes) {
torrents_for_sse.update(|map| { Ok(event) => {
let new_hashes: std::collections::HashSet<String> = list.iter().map(|t| t.hash.clone()).collect(); match event {
map.retain(|hash, _| new_hashes.contains(hash)); AppEvent::FullList(list, _) => {
for new_torrent in list { map.insert(new_torrent.hash.clone(), new_torrent); } torrents_for_sse.update(|map| {
}); let new_hashes: std::collections::HashSet<String> = list.iter().map(|t| t.hash.clone()).collect();
} map.retain(|hash, _| new_hashes.contains(hash));
AppEvent::Update(patch) => { for new_torrent in list { map.insert(new_torrent.hash.clone(), new_torrent); }
if let Some(hash) = patch.hash.clone() { });
torrents_for_sse.update(|map| { if let Some(t) = map.get_mut(&hash) { t.apply(patch); } }); }
} AppEvent::Update(patch) => {
} if let Some(hash) = patch.hash.clone() {
AppEvent::Stats(stats) => { global_stats_for_sse.set(stats); } torrents_for_sse.update(|map| { if let Some(t) = map.get_mut(&hash) { t.apply(patch); } });
AppEvent::Notification(n) => { }
show_toast(n.level.clone(), n.message.clone()); }
if n.message.contains("tamamlandı") || n.level == shared::NotificationLevel::Error { AppEvent::Stats(stats) => { global_stats_for_sse.set(stats); }
show_browser_notification("VibeTorrent", &n.message); AppEvent::Notification(n) => {
show_toast(n.level.clone(), n.message.clone());
if n.message.contains("tamamlandı") || n.level == shared::NotificationLevel::Error {
show_browser_notification("VibeTorrent", &n.message);
}
}
} }
},
Err(e) => {
log::error!("[SSE] Failed to deserialize AppEvent: {:?}", e);
} }
} }
},
Err(e) => {
log::error!("[SSE] Failed to decode base64: {:?}", e);
} }
} }
} }

View File

@@ -1,4 +1,4 @@
const CACHE_NAME = "vibetorrent-v2"; const CACHE_NAME = "vibetorrent-v3";
const ASSETS_TO_CACHE = [ const ASSETS_TO_CACHE = [
"/", "/",
"/index.html", "/index.html",
@@ -51,6 +51,11 @@ self.addEventListener("activate", (event) => {
self.addEventListener("fetch", (event) => { self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url); const url = new URL(event.request.url);
// Skip unsupported schemes (like chrome-extension://)
if (!url.protocol.startsWith("http")) {
return;
}
// Network-first strategy for API calls // Network-first strategy for API calls
if (url.pathname.startsWith("/api/")) { if (url.pathname.startsWith("/api/")) {
event.respondWith( event.respondWith(
@@ -75,10 +80,12 @@ self.addEventListener("fetch", (event) => {
fetch(event.request) fetch(event.request)
.then((response) => { .then((response) => {
// Cache the latest version of the HTML // Cache the latest version of the HTML
const responseToCache = response.clone(); if (response && response.status === 200) {
caches.open(CACHE_NAME).then((cache) => { const responseToCache = response.clone();
cache.put(event.request, responseToCache); caches.open(CACHE_NAME).then((cache) => {
}); cache.put(event.request, responseToCache);
});
}
return response; return response;
}) })
.catch(() => { .catch(() => {