bit Bswup

Preparing the app for offline use, please wait...

0%

bit platform logo Bswup
NuGet GitHub

Migrating to v-10-6-0

v-10-6-0 is a resilience-focused release. Most changes are internal hardening; this page lists what is visible when upgrading.

Action items

Check these four things

1. Updates no longer auto-reload. BswupProgress.AutoReload now defaults to false - updates announce themselves through the reload button. Set AutoReload="true" to restore the old behavior.

2. Blocked URLs answer 403. prohibitedUrls matches are answered with 403 Forbidden (previously 405). Code detecting a blocked URL by status must check for 403.

3. String entries now take effect. Strings in the URL-matching lists (assetsInclude, assetsExclude, prohibitedUrls, serverHandledUrls, serverRenderedUrls) are now matched literally as substrings. Previous releases silently ignored them - audit any strings sitting in those lists, because they take effect for the first time after upgrading.

4. Hand-written splash markup needs one edit. Move <button id="bit-bswup-reload"> outside the #bit-bswup overlay (and give it a z-index), optionally adding a visually-hidden <span id="bit-bswup-reload-status" role="status"> next to it. The built-in handling no longer reveals the overlay for updates, so a button left inside it would never become visible. The BswupProgress component ships this layout already.

Behavior changes

  • Cache buckets are scope-qualified: bit-bswup:<scope-path> - <version> (previously bit-bswup - <version>). Multiple Bswup apps on one origin no longer evict each other's caches; the migration from legacy-named buckets is automatic and does not re-download.
  • Under the default lax tolerance, the asset download now runs inside the install event (waitUntil): the browser keeps the worker alive for the whole download, and updateReady is only raised once the new version is fully staged - previously it could fire while the download had barely started.
  • assetsUrl defaults to a path resolved against the service worker script's own location (previously root-absolute), so apps mounted on a sub-path work without configuration.
  • The cleanup callback only prunes when no update is staged or staging, and BitBswup.forceRefresh()'s default filter clears only this app's own, legacy, and Blazor caches. The same staged-or-staging guard protects every cache-pruning path, so a prune can never race a newer install's freshly written bucket.
  • Requests carrying a Range header are answered with real 206 Partial Content slices from cached bodies (cached media now plays in Safari), and partial responses are never written to the cache.
  • Updates found later in the same session as the first install are treated as real updates: updateReady is raised, downloadFinished carries firstInstall: false, and accepting them runs the normal SKIP_WAITING flow. Previously a long-lived tab kept classifying every later update as another first install.
  • Navigations whose URL is itself a managed asset (e.g. opening /manifest.json directly) are served that asset instead of the SPA default document.
  • An update's re-download of the default document and of hash-less assets no longer deletes the existing cache entry first: if the refresh fails (offline mid-update), the previous copy keeps serving - including offline navigation.
  • The built-in progress UI stays out of the way during background updates: the full-screen splash is first-install only (downloadStarted/downloadProgress payloads carry firstInstall so custom handlers can do the same), the reload button lives outside the overlay, it is announced via a role="status" region, and the overlay no longer swallows clicks outside its content.
  • A first install completes even when no handler function is registered at all (previously the app waited out the full stallTimeout behind the splash).
  • The cleanup worker unregisters its own registration during teardown and no longer claims clients; the page reloads on UNREGISTER only while actually controlled, removing a reload-loop hazard.
  • The passive-mode background top-up after first boot is deterministic: it fills every asset still missing from the cache.
  • The default asset excludes cover all shipped worker-script variants (bit-bswup.sw.min.js, bit-bswup.sw-cleanup.js, bit-bswup.sw-cleanup.min.js).
  • A manifest or externalAssets entry whose URL cannot be parsed is skipped with a non-fatal request error instead of killing the whole service worker at startup.
  • A navigation to a URL that only a RegExp externalAssets pattern matches is served the app shell, never the pattern asset - and a shell cache miss during navigation is refilled from the shell's own URL, never from the navigated route's URL.
  • WAITING_SKIPPED and UNREGISTER never reload an uncontrolled page anymore; they make sure the app is booted instead. Activating a first install through BitBswup.skipWaiting() completes the seamless claim-and-start flow instead of reloading.
  • A page that loads while an update is already mid-install now observes it: updateReady / stateChanged fire in that tab when the update finishes staging.
  • An exception thrown by the app's bitBswupHandler no longer breaks the update pipeline (it is logged, and the remaining messages still dispatch).

New capabilities

  • Update polling: the updateInterval / updateOnVisibility script attributes, a registration-aware BitBswup.checkForUpdate(), and the updateNotFound / updateCheckFailed events.
  • Install robustness: errorTolerance (lax/strict), transient-failure retries (maxRetries, retryDelay), the stallTimeout first-install watchdog, and structured error payloads (reason, fatal, firstInstall - including the terminal install-infra reason).
  • Storage: persistStorage / BitBswup.persistStorage() for eviction-resistant storage, and cacheVersion for manual control of cache-bucket rotation.
  • Registration: automatic retry with the default scope when the browser rejects the configured scope, and fingerprint-tolerant Blazor entry-script detection for .NET 9+ @Assets[...] references.