diff --git a/.github/workflows/bit.ci.Bswup.yml b/.github/workflows/bit.ci.Bswup.yml
index 5192c57506..2e74e2aad2 100644
--- a/.github/workflows/bit.ci.Bswup.yml
+++ b/.github/workflows/bit.ci.Bswup.yml
@@ -53,3 +53,11 @@ jobs:
- name: dotnet build
run: dotnet build src/Bswup/Bit.Bswup.slnx
+
+ # Runs against Bit.Bswup/wwwroot/*.js, which the build above produces, so this also covers
+ # the build step itself (e.g. the minifier re-introducing downleveled syntax).
+ - name: JS tests (service worker, page script, progress UI)
+ run: |
+ cd src/Bswup/Tests/bit-bswup-js
+ npm ci || npm install
+ npm test
diff --git a/src/Bswup/Bit.Bswup.Demo/Pages/HomePage.razor b/src/Bswup/Bit.Bswup.Demo/Pages/HomePage.razor
index 4ef62a7a95..bb30021363 100644
--- a/src/Bswup/Bit.Bswup.Demo/Pages/HomePage.razor
+++ b/src/Bswup/Bit.Bswup.Demo/Pages/HomePage.razor
@@ -3,7 +3,7 @@
Home
-
222
+111
Hello, world!
diff --git a/src/Bswup/Bit.Bswup.Demo/wwwroot/index.html b/src/Bswup/Bit.Bswup.Demo/wwwroot/index.html
index 951dd57acf..989930555b 100644
--- a/src/Bswup/Bit.Bswup.Demo/wwwroot/index.html
+++ b/src/Bswup/Bit.Bswup.Demo/wwwroot/index.html
@@ -106,17 +106,24 @@
case BswupMessage.activate: return console.log('new version activated:', data.version);
case BswupMessage.downloadStarted:
+ // A background update downloads behind the running app - only a first
+ // install owns the screen (firstInstall rides on every message).
+ if (data?.firstInstall === false) return console.log('downloading update assets started:', data?.version);
appEl.style.display = 'none';
bswupEl.style.display = 'block';
return console.log('downloading assets started:', data?.version);
case BswupMessage.downloadProgress:
+ // Built with textContent (not innerHTML) so asset names can never be
+ // parsed as markup - the same hardening as the bundled progress script.
const li = document.createElement('li');
- li.innerHTML = `${data.index}: ${data.asset.url}: ${data.asset.hash}`
+ const urlEl = document.createElement('b');
+ urlEl.textContent = data.asset.url;
+ li.append(`${data.index}: `, urlEl, `: ${data.asset.hash}`);
assetsUl.prepend(li);
const percent = Math.round(data.percent);
progressBar.style.width = `${percent}%`;
- percentLabel.innerHTML = `${percent} %`;
+ percentLabel.textContent = `${percent} %`;
return console.log('asset downloaded:', data);
case BswupMessage.downloadFinished:
@@ -137,16 +144,34 @@
reloadButton.style.display = 'block';
reloadButton.onclick = data.reload;
return console.log('new update ready.');
+
+ case BswupMessage.error:
+ // This demo deliberately ships a 404ing external asset (see the dev
+ // service-worker.js), so non-fatal errors are expected here: under the
+ // default lax tolerance the install continues and the asset lazy-fills.
+ console.error('installation error:', data);
+ if (data.fatal === false) return;
+ // A fatal failure during a background update leaves the running app
+ // untouched - the previous worker keeps serving it.
+ if (data.firstInstall === false) return;
+ // Fatal first-install failure: bit-bswup.js force-starts Blazor from the
+ // network; reveal the app instead of leaving it booted behind the splash.
+ descriptionLabel.textContent = 'Install failed; starting without offline support...';
+ appEl.style.display = 'block';
+ bswupEl.style.display = 'none';
+ return;
}
}
+
+ handler="bitBswupHandler">