summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/downloads.js20
1 files changed, 19 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
index b1eade6..87d18b7 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/downloads.js
@@ -338,6 +338,16 @@ async function _claimController(budgetMs) {
// requests never reach the fetch handler, so the worker would take our stream
// and never be asked for it — the download then freezes after exactly one
// chunk, which is how that was found.
+ //
+ // Ask for the claim *before* waiting, not after. A page that is uncontrolled
+ // while an active worker exists will not be claimed on its own — a document
+ // fetched by a hard reload is exactly that shape — so the whole control
+ // budget is spent waiting for something that is not coming, and it was: about
+ // thirty seconds during which somebody clicks download and watches four rows
+ // hang. Asking first costs one message and makes the common case immediate.
+ if (!navigator.serviceWorker.controller && reg.active) {
+ try { reg.active.postMessage({ type: 'mbdl-claim' }); } catch { /* gone */ }
+ }
const controller = await _awaitControl(left());
if (controller) return controller;
// Active but not controlling after the whole budget. `sw.js` calls
@@ -367,10 +377,17 @@ async function _claimController(budgetMs) {
*/
export function primeServiceWorker() {
if (!STREAMS_VIA_SW) return;
- serviceWorker().then((worker) => worker && _repairIfBypassed(worker))
+ _priming = serviceWorker()
+ .then((worker) => worker && _repairIfBypassed(worker))
.catch(() => {});
}
+// Resolved once the check below has run. A download that starts while it is
+// still in flight waits for it rather than racing it: on a page that turns out
+// to be unservable the click would otherwise spend thirty seconds failing on a
+// path that is about to be repaired.
+let _priming = null;
+
// How long to wait for the worker to answer the one-byte self-test below.
// Milliseconds when it works; a page that cannot stream at all is worth four
// seconds to find out about, once, at boot.
@@ -495,6 +512,7 @@ export async function openStreamedDownload(filename, size = 0, {
servedMs = SW_SERVED_BUDGET_MS,
attempts = SW_ATTEMPTS,
} = {}) {
+ if (_priming) { try { await _priming; } catch { /* reported already */ } }
for (let attempt = 1; attempt <= attempts; attempt++) {
const target = await _attemptStreamedDownload(
filename, size, attempt, controlMs, servedMs);