Download the whole app build behind a loading page

In production, a page request without the running build's cookie gets a
small loading page instead of the app. It downloads every file in
.bunext/public (listed at /build-info.json) into that build's cache,
checks they are all there, hands over to a new service worker waiting
behind an older one, sets the cookie and reloads. The service worker
then serves the app's code from the cache, so later visits load it from
the device.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-20 19:33:15 +01:00
co-authored by Claude Opus 5.5
parent 9778d0b9ff
commit b3057119df
16 changed files with 991 additions and 45 deletions
+23
View File
@@ -11,6 +11,9 @@ import liveRelay from "./live-relay";
import enableForeignKeys from "./functions/backend/db/enable-foreign-keys";
import handleComputerProxy from "./functions/server/computers/handle-computer-proxy";
import handlePwaFile from "./functions/server/pwa/handle-pwa-file";
import handleBuildInfo from "./functions/server/pwa/handle-build-info";
import handlePrecacheGate from "./functions/server/pwa/handle-precache-gate";
import grabPrecacheManifest from "./functions/server/pwa/grab-precache-manifest";
import compressResponse from "./functions/server/compress-response";
import serveLocalCa from "./functions/server/serve-local-ca";
import startHttpRedirect from "./functions/server/start-http-redirect";
@@ -30,6 +33,18 @@ const port = process.env.PORT || 7227;
await enableForeignKeys();
await bunext.bunextInit();
/**
* The running build's id and files, read once: browsers whose build
* cookie doesn't match get the loading page first (production only).
*/
const precache = grabPrecacheManifest();
if (precache) {
bunext.bunextLog.info(
`Build ${precache.build_id}: ${precache.files.length} files to precache`,
);
}
/**
* Web Push needs a key pair; the first start of the main install creates
* it (in the Environment settings) so notifications work without setup.
@@ -111,6 +126,14 @@ const server = Bun.serve({
if (pwa_file) return pwa_file;
const build_info = handleBuildInfo({ pathname: url.pathname });
if (build_info) return build_info;
const loading_page = await handlePrecacheGate({ req, url });
if (loading_page) return loading_page;
const local_ca = await serveLocalCa({ pathname: url.pathname });
if (local_ca) return local_ca;