- Create `docs/webtorrent-architecture.md` detailing the "Webseeds are Peers" strategy. - Update `docs/video-availability-checks.md` with cross-reference. - Add "CRITICAL" warning comments to `js/webtorrent.js` and `js/gridHealth.js` to prevent regressions. - Enhance `tests/webtorrent-regression.test.mjs` to explicitly verify `urlList` passing in mocks. Co-authored-by: PR0M3TH3AN <[email protected]>
4.9 KiB
Video availability checks
This document explains how bitvid probes URL and torrent availability, caches results, and uses those outcomes to decide whether video cards remain visible. For playback behavior that depends on these probes, see Playback fallback.
URL health checks (hosted URL/CDN)
Observation & trigger
js/urlHealthObserver.js wires a card observer that looks for cards containing a URL health badge ([data-url-health-state]). When a card intersects the viewport, the observer:
- Reads
data-url-health-urlanddata-url-health-event-idfrom the card or badge. - Skips checks if the current state is already resolved (anything other than
checking). - Calls the
onCheckhandler provided by the caller (currentlybitvidApp.handleUrlHealthBadge).
Orchestration
js/app.js owns the badge/probe orchestration:
handleUrlHealthBadgetrims the URL, checks cache, and sets the badge tocheckingif no cached entry exists.- It deduplicates probes using the in-flight cache (via
getInFlightUrlProbe/setInFlightUrlProbeinjs/state/cache.js). probeUrl(..., { confirmPlayable: true })returns an outcome that is normalized into a badge state:ok→healthyopaque/unknown→unknowntimeout→timeouterror→offline
updateUrlHealthBadgeupdates the badge UI and mirrorsdata-url-health-stateon the card, then callsupdateVideoCardSourceVisibilityto reflect the state.
Caching
js/state/cache.js stores URL health entries keyed by event ID with TTL support:
getCachedUrlHealth(eventId, url)checks in-memory first, then local storage; mismatched URLs or expired entries are discarded.storeUrlHealth(eventId, url, result, ttlMs)writesstatus,message,url,expiresAt, andlastCheckedAt.- Constants exported in
urlHealthConstantscontrol caching and retry:URL_HEALTH_TTL_MS(default TTL)URL_HEALTH_TIMEOUT_RETRY_MS(shorter TTL fortimeout/unknown)URL_PROBE_TIMEOUT_RETRY_MS(probe timeout fallback used byprobeUrl)
Torrent (stream) health checks
For a detailed architectural overview of the WebTorrent implementation, including webseed handling and Service Worker integration, see WebTorrent Architecture & Strategy.
Card-level probes (js/gridHealth.js)
The grid health module manages per-card WebTorrent probes and badge updates:
- Uses an
IntersectionObserverto trigger checks as cards become visible (prioritized by viewport proximity). - Builds a probe queue with concurrency limits, in-flight de-duping, and a short cache (
PROBE_CACHE_TTL_MS). torrentClient.probePeersperforms the actual peer lookup, bounded byPROBE_TIMEOUT_MSandPROBE_POLL_COUNT.- Results are normalized via
normalizeResult:healthyis only true when peers > 0.peersis clamped to ≥ 0 (and to ≥ 1 when healthy).reasonis normalized into known values such astimeout,no-trackers,invalid, etc.
setBadgeappliesdata-stream-health-state,data-stream-health-peers, anddata-stream-health-reasonon both the card and badge, then callsupdateVideoCardSourceVisibility.
Card visibility rules
js/utils/cardSourceVisibility.js centralizes hide/show behavior based on health datasets:
- If the viewer owns the card (
data-owner-is-viewer="true"), the card always remains visible. - Otherwise, the card is hidden only when both sources are known bad and neither is pending:
data-url-health-stateis nothealthyand notchecking, anddata-stream-health-stateis nothealthyand notchecking.
- Any pending status keeps the card visible until a definitive result arrives.
js/ui/components/VideoCard.js is responsible for setting the dataset values that drive this logic:
- URL datasets:
data-url-health-state,data-url-health-reason,data-url-health-event-id,data-url-health-url. - Stream datasets:
data-stream-health-state,data-stream-health-reason,data-stream-health-peers. - Magnet presence:
data-magnetanddata-torrent-supported.
Probe timeline (typical flow)
- Card render —
VideoCardsets the initial dataset fields, usuallycheckingwhen a source exists. - Badge attachment —
bitvidApprenders badge markup and wires observers (attachUrlHealthBadges/attachHealthBadges). - Scroll/observer trigger — as cards enter the viewport,
urlHealthObserverandgridHealthschedule probes. - Cache reuse — if cached results exist (URL cache in
js/state/cache.js, torrent cache injs/gridHealth.js/js/healthService.js), the badges update immediately without re-probing. - Probe completion — results update badge text, dataset state, and card visibility (
updateVideoCardSourceVisibility).
For how these checks interact with playback fallbacks, see Playback fallback.