UWebUpdate class abstract

Keeps a Flutter web app on the build that is actually deployed.

A browser can keep serving a superseded app from three independent places: the HTTP disk cache (a Cache-Control: immutable asset is not even revalidated on a normal reload), the CacheStorage buckets that older Flutter service workers filled, and a service worker that stays waiting until every tab of the site is closed. refresh clears all three and reloads into the deployed build; hasUpdate says whether that is worth doing. Every member is a no-op off the web.

Detection is only as good as the signal the build carries. Build with --dart-define=U_BUILD_ID=<pubspec version> to get an exact answer:

flutter build web --dart-define=U_BUILD_ID=$(grep "^version:" pubspec.yaml | cut -d " " -f2)

Without it, hasUpdate falls back to comparing the browser's cached flutter_bootstrap.js against the server's, which misses the case where only main.dart.js is stale. refresh itself never depends on any of this and always works.

// The blunt one: a button that always lands on whatever is deployed.
UButton(title: U.s.refresh, onTap: UWebUpdate.refresh);

// Ask the user once, right after the app starts.
unawaited(UWebUpdate.checkAndRefresh());

// The solid default, already wired into initU: silent at startup, ask for anything found later.
UWebUpdate.startWatching();

// Keep every open tab current without ever asking.
UWebUpdate.startWatching(silent: true);

// Read what is deployed, e.g. to show it next to the running version.
final UWebBuild? deployed = await UWebUpdate.serverBuild();

Constructors

UWebUpdate()

Properties

hashCode → int
The hash code for this object.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() → String
A string representation of this object.
inherited

Operators

operator ==(Object other) → bool
The equality operator.
inherited

Static Properties

timeout ↔ Duration
How long a probe of the server may take before it is treated as "nothing new".
getter/setter pair

Static Methods

cachedBuild() → Future<UWebBuild?>
The build the browser would serve from its own HTTP cache, which is what this tab is running.
checkAndRefresh({bool silent = false, bool once = true, bool bustUrl = false, String? title, String? message, String? confirmText, String? cancelText}) → Future<bool>
Checks the server and, when a newer build is deployed, reloads into it. Returns whether a refresh started.
hasUpdate() → Future<bool>
Whether the server holds a build other than the one this tab is running.
refresh({List<String> assets = defaultAssets, bool bustUrl = false}) → Future<void>
Throws away every browser-side copy of the app and reloads into the deployed build.
runningServiceWorkerVersion() → String?
Service worker version serving this page, or null when no service worker controls it.
serverBuild() → Future<UWebBuild?>
The build the server is serving right now, read past every cache. Null off the web or when offline.
startWatching({Duration interval = const Duration(minutes: 15), bool silent = false, bool checkNow = true, bool silentOnStart = true, bool onVisible = true, bool bustUrl = false}) → void
Watches for new builds: once at startup, every interval, and whenever the tab is brought back to the foreground. Safe to call before runApp. End it with stopWatching.
stopWatching() → void

Constants

buildId → const String
Build id compiled into this bundle by --dart-define=U_BUILD_ID=..., empty when not passed.
defaultAssets → const List<String>
Files re-downloaded before reloading, relative to the deployment base. Missing ones are ignored.