Merge retry hardening with DSP cache opt-in

This commit is contained in:
Jonathan Sykes
2026-10-10 23:00:32 +08:00
10 changed files with 282 additions and 26 deletions

View File

@@ -60,12 +60,14 @@ async function call(zeroName, tauriName, payload = {}) {
// Generic fetch wrapper — returns parsed JSON or throws with a human message.
async function webFetch(path, opts = {}) {
if ((opts.method || 'GET').toUpperCase() === 'GET' && window.AsyncGuard?.getJson)
return AsyncGuard.getJson(path, opts, {
// Some upstream failures are represented by HTTP 200 + {ok:false}; do
// not expose those transient responses as a manual Retry state either.
retryResult: value => value?.ok === false && /\b(?:408|425|429|5\d\d)\b|temporar|timed?\s*out|network|connection|upstream|unavailable|available right now/i.test(String(value.error || value.message || '')),
});
const res = await fetch(path, opts);
if (!res.ok) {
let msg = `HTTP ${res.status}`;
try { const j = await res.json(); msg = j.error || msg; } catch { /* non-JSON */ }
throw new Error(msg);
}
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
@@ -573,7 +575,7 @@ const API = {
? webFetch(`/api/search?q=${encodeURIComponent(query)}${refresh ? '&refresh=1' : ''}`)
: call('yt.search', 'yt_search', { query }),
related: (meta, { refresh = false } = {}) => WEB && /^[\w-]{11}$/.test(meta.id)
? fetch(`/api/related?${new URLSearchParams({ videoId: meta.id, title: meta.title || '', channel: meta.channel || meta.artist || '', ...(refresh ? { refresh: '1' } : {}) })}`).then(response => response.json())
? webFetch(`/api/related?${new URLSearchParams({ videoId: meta.id, title: meta.title || '', channel: meta.channel || meta.artist || '', ...(refresh ? { refresh: '1' } : {}) })}`)
: API.search(meta.title || meta.channel, { refresh }),
// Videos the server already knows — answers fast while the real search loads.
searchLocal: (query) => WEB
@@ -8666,9 +8668,7 @@ const RUNNING_BUILD = (() => {
let _knownBuildTag = null;
async function fetchServerBuild() {
const res = await fetch('/api/version', { cache: 'no-store' });
if (!res.ok) return null;
const data = await res.json();
const data = await webFetch('/api/version', { cache: 'no-store' });
return data.buildTag || null;
}