From 175a6f73b4cf96c76e1c14e7ec055ba2d0056a4d Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Wed, 14 Jan 2026 17:37:50 +0000 Subject: [PATCH] fix(webtorrent): support webseeds in health checks Updated `probePeers` in `js/webtorrent.js` to detect `ws` (WebSeed) parameters in magnet links. If a web seed is present, the torrent is now considered "healthy" with at least one peer, even if tracker probing fails or returns zero peers. This ensures videos hosted on R2 (or other HTTP sources) are correctly marked as available in the UI. --- js/webtorrent.js | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/js/webtorrent.js b/js/webtorrent.js index 25efa6f5..23bcc1b4 100644 --- a/js/webtorrent.js +++ b/js/webtorrent.js @@ -172,7 +172,9 @@ export class TorrentClient { const { magnet: augmentedMagnet, appended, hasProbeTrackers } = appendProbeTrackers(magnet, trackers); - if (!hasProbeTrackers) { + const hasWebSeed = magnet.includes("ws=") || magnet.includes("webSeed="); + + if (!hasProbeTrackers && !hasWebSeed) { return { healthy: false, peers: 0, @@ -230,10 +232,15 @@ export class TorrentClient { ? performance.now() : Date.now(); + const isHealthy = Boolean(overrides.healthy) || hasWebSeed; + const peersCount = + (Number.isFinite(overrides.peers) ? overrides.peers : 0) || + (hasWebSeed ? 1 : 0); + resolve({ - healthy: false, - peers: 0, - reason: "timeout", + healthy: isHealthy, + peers: peersCount, + reason: isHealthy ? "peer" : "timeout", appendedTrackers: appended, hasProbeTrackers, usedTrackers: trackers, @@ -248,6 +255,15 @@ export class TorrentClient { maxWebConns: safeMaxWebConns, }); } catch (err) { + // If we have a webseed, we can consider it healthy even if adding fails (unlikely, but safe) + if (hasWebSeed) { + finalize({ + healthy: true, + peers: 1, + reason: "peer", + }); + return; + } finalize({ reason: "error", error: toError(err), @@ -264,19 +280,26 @@ export class TorrentClient { torrent.once("wire", settleHealthy); torrent.once("error", (err) => { - finalize({ - healthy: false, - reason: "error", - error: toError(err), - peers: Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0))), - }); + const peers = Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0))); + // If webseed exists, ignore error and report healthy + if (hasWebSeed) { + finalize({ healthy: true, peers: Math.max(1, peers), reason: "peer" }); + } else { + finalize({ + healthy: false, + reason: "error", + error: toError(err), + peers, + }); + } }); if (safeTimeout > 0) { timeoutId = setTimeout(() => { + const peers = Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0))); finalize({ - healthy: false, - peers: Math.max(0, Math.floor(normalizeNumber(torrent?.numPeers, 0))), + healthy: hasWebSeed, + peers: hasWebSeed ? Math.max(1, peers) : peers, }); }, safeTimeout); }