Skip to content
4 changes: 3 additions & 1 deletion src/Bswup/Bit.Bswup.Demo/wwwroot/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

self.assetsExclude = [/\.scp\.css$/, /weather\.json$/];
self.caseInsensitiveUrl = true;
self.precachedAssetsInclude = [/favicon\.ico$/, /icon-512\.png$/, /bit-bw-64\.png$/];

self.externalAssets = [
{
"url": "not-found/script.file.js"
}
];
// 'lax' opts into best-effort installs: the demo intentionally references a non-existent
// asset to exercise the progress / error reporting UI. Under the default 'strict' setting
// that would abort the install. See README.md > errorTolerance.
self.errorTolerance = 'lax';

self.importScripts('_content/Bit.Bswup/bit-bswup.sw.js');
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

self.assetsExclude = [/\.scp\.css$/, /weather\.json$/];
self.caseInsensitiveUrl = true;
self.precachedAssetsInclude = [/favicon\.ico$/, /icon-512\.png$/, /bit-bw-64\.png$/];

//self.externalAssets = [
// {
Expand Down
22 changes: 20 additions & 2 deletions src/Bswup/Bit.Bswup/BswupProgress.razor
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,27 @@
</div>
<p id="bit-bswup-percent">0 %</p>
<ul id="bit-bswup-assets" style="display: @(ShowAssets ? "block" : "none");"></ul>
<div id="bit-bswup-error" class="bit-bswup-error" style="display: none;" role="alert">
<p class="bit-bswup-error-title">Update failed to install</p>
<p id="bit-bswup-error-message" class="bit-bswup-error-message"></p>
<pre id="bit-bswup-error-details" class="bit-bswup-error-details"></pre>
<button id="bit-bswup-error-retry" type="button">Retry</button>
</div>
</div>
<button id="bit-bswup-reload">Update ready to install!</button>
}
<img style="display: none" src=""
onerror="BitBswupProgress.start(@(AutoReload ? "true" : "false"), @(ShowLogs ? "true" : "false"), @(ShowAssets ? "true" : "false"), '@(AppContainer)', @(HideApp ? "true" : "false"), @(AutoHide ? "true" : "false"), '@(Handler)')">
<script>
if (window.BitBswupProgress !== undefined) {
window.BitBswupProgress.start(
@(AutoReload ? "true" : "false"),
@(ShowLogs ? "true" : "false"),
@(ShowAssets ? "true" : "false"),
'@(AppContainer)',
@(HideApp ? "true" : "false"),
@(AutoHide ? "true" : "false"),
'@(Handler)');
Comment thread
msynk marked this conversation as resolved.
Outdated
Comment thread
msynk marked this conversation as resolved.
Outdated
Comment thread
msynk marked this conversation as resolved.
Outdated
} else {
console.error('BitBswupProgress not found');
}
</script>
</div>
62 changes: 62 additions & 0 deletions src/Bswup/Bit.Bswup/Scripts/bit-bswup.progress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
const percentEl = document.getElementById('bit-bswup-percent');
const assetsEl = document.getElementById('bit-bswup-assets');
const reloadButton = document.getElementById('bit-bswup-reload');
const errorEl = document.getElementById('bit-bswup-error');
const errorMessageEl = document.getElementById('bit-bswup-error-message');
const errorDetailsEl = document.getElementById('bit-bswup-error-details');
const errorRetryButton = document.getElementById('bit-bswup-error-retry');

const appElOriginalDisplay = appEl && appEl.style.display;

Expand Down Expand Up @@ -100,13 +104,71 @@
reloadButton && (reloadButton.onclick = data.reload);
}
return showLogs_ ? console.log('new update is ready.') : undefined;

case BswupMessage.error:
// Reveal the install panel even if no progress event landed first
// (manifest validation failures fire before any progress message).
hideApp_ && appEl && (appEl.style.display = 'none');
bswupEl && (bswupEl.style.display = 'block');

Comment thread
msynk marked this conversation as resolved.
// The error supersedes any in-flight progress. Hide the bar and the
// percentage so a stale partial value (e.g. "47%") isn't left sitting
// next to the failure message.
if (progressEl && progressEl.parentElement) progressEl.parentElement.style.display = 'none';
if (percentEl) percentEl.style.display = 'none';

if (errorEl) {
errorEl.style.display = 'block';
if (errorMessageEl) errorMessageEl.textContent = (data && data.message) || 'Service worker install failed.';
if (errorDetailsEl) {
const reasonText = data && data.reason ? `[${data.reason}] ` : '';
const urlText = data && data.url ? `\nasset: ${data.url}` : '';
const hashText = data && data.hash ? `\nhash: ${data.hash}` : '';
errorDetailsEl.textContent = `${reasonText}${urlText}${hashText}`.trim();
}
if (errorRetryButton) {
// Some failures are deterministic - a plain reload re-fetches the
// same broken bytes and fails identically. A manifest that won't
// parse or an SRI/integrity mismatch needs a redeploy (or fixed
// CDN/proxy), not a retry. For those, hide the retry button so we
// don't invite a pointless reload loop; keep it for transient
// failures (network/fetch/cache) where reloading can genuinely help.
const nonRetriableReasons = ['manifest', 'integrity', 'install-incomplete'];
const isRetriable = !(data && nonRetriableReasons.indexOf(data.reason) !== -1);
if (isRetriable) {
errorRetryButton.style.display = 'inline-block';
errorRetryButton.onclick = () => {
if (data && typeof data.reload === 'function') {
data.reload();
} else {
window.location.reload();
}
};
} else {
errorRetryButton.style.display = 'none';
errorRetryButton.onclick = null;
Comment thread
msynk marked this conversation as resolved.
}
}
}
// Always log errors regardless of showLogs - this is actionable info.
console.error('BitBswup install error:', data);
return;
}
}
}
};

function config(newConfig: IBswupProgressConfigs) {
Object.assign(_config, newConfig);

// Keep the assets list visibility in sync when toggled at runtime.
// The <ul> is server-rendered with an inline display style based on the
// initial ShowAssets parameter, so flipping the config alone wouldn't
// reveal/hide it without also updating the element here.
if (newConfig.showAssets !== undefined) {
const assetsEl = document.getElementById('bit-bswup-assets');
if (assetsEl) assetsEl.style.display = newConfig.showAssets ? 'block' : 'none';
}
}
}());

Expand Down
2 changes: 1 addition & 1 deletion src/Bswup/Bit.Bswup/Scripts/bit-bswup.sw-cleanup.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
self['bit-bswup.sw-cleanup version'] = '10.4.5';
(self as any)['bit-bswup.sw-cleanup version'] = '10.4.5';

self.addEventListener('install', e => e.waitUntil(removeBswup()));

Expand Down
Loading
Loading