Synchronize verified assets incrementally and guard update activation

This commit is contained in:
Jonathan Sykes
2026-10-07 23:40:20 +08:00
parent a1f16f2e3b
commit 54a07a0a2a
15 changed files with 260 additions and 22 deletions

View File

@@ -99,7 +99,7 @@ function withSaveSlot(fn) {
// Snapshot every shipped public file. Hashes describe the served HTML/SW bytes;
// rollback retains the historical recursive tag and single-tag URL stamping.
const ASSET_HASHING = process.env.ASSET_HASHING !== '0';
const assets = createAssetManifest('./public', { hashing: ASSET_HASHING, buildTag: process.env.BUILD_TAG });
const assets = createAssetManifest('./public', { hashing: ASSET_HASHING, assetSync: process.env.ASSET_SYNC !== '0', buildTag: process.env.BUILD_TAG });
const BUILD_TAG = assets.manifest.buildTag;
// BUILD_TIME — human-readable "when was this image built". Written by the
@@ -357,7 +357,8 @@ app.get('/api/manifest', (c) => {
const headers = { 'Cache-Control': 'no-store', ETag: etag };
const matches = (c.req.header('if-none-match') || '').split(',').map(value => value.trim().replace(/^W\//, ''));
if (matches.includes(etag) || matches.includes('*')) return new Response(null, { status: 304, headers });
return c.json(assets.manifest, 200, headers);
const entry = compressedEntry('api-manifest',Buffer.from(JSON.stringify(assets.manifest)), 'application/json; charset=utf-8');
return sendCompressed(c, { ...entry, etag }, 'no-store');
});
app.get('/api/version', (c) =>
@@ -2440,13 +2441,8 @@ app.get('/sw.js', (c) => {
// the moment the fallback literal in sw.js was bumped ('v1.0.3' → 'v1.0.4'),
// after which the replacement silently did nothing, the SW version froze,
// and clients never saw another update no matter how many times we deployed.
const src = _swSource.replace(
/typeof __BUILD_TAG__ !== 'undefined' \? __BUILD_TAG__ : '[^']*'/,
JSON.stringify(BUILD_TAG)
);
if (src === _swSource) {
console.error('[sw] BUILD_TAG injection failed — placeholder not found in sw.js');
}
const src = assets.sw;
if (!/typeof __BUILD_TAG__/.test(_swSource)) console.error('[sw] BUILD_TAG injection failed — placeholder not found in sw.js');
return sendCompressed(c, compressedEntry('sw.js', Buffer.from(src), MIME.js), 'no-store, no-cache, must-revalidate', assets.manifest.files['/sw.js']?.h);
});