Add contract-checked fallback and background asset synchronization

This commit is contained in:
Jonathan Sykes
2026-10-08 00:30:31 +08:00
parent 895f20a4c9
commit f804a23761
2 changed files with 38 additions and 4 deletions

View File

@@ -33,6 +33,14 @@
return keep;
}
function fallback(manifest, previous, path) {
if (!manifest.files[path] || !previous?.files[path]) return null;
const group = Object.keys(manifest.groups).find(name => manifest.groups[name].files.includes(path));
if (!group || !previous.groups[group]?.files.includes(path) ||
manifest.groups[group].contract !== previous.groups[group].contract) return null;
return url(path, previous.files[path]);
}
async function state(cache) {
const response = await cache.match(STATE);
return response ? response.json() : null;
@@ -47,10 +55,12 @@
return { ready: missing === 0, missing, version: manifest.buildTag };
}
async function syncAssets(manifest, { cache, fetchFn, concurrency = 6, attempts = 3, activeLayout }) {
async function syncAssets(manifest, { cache, fetchFn, concurrency = 6, attempts = 3, activeLayout, groups }) {
const previous = (await state(cache))?.current;
const missing = [];
for (const path of blocking(manifest, previous, activeLayout)) {
const selected = groups ? [...new Set(groups.flatMap(name => manifest.groups[name]?.files || []))].sort()
: blocking(manifest, previous, activeLayout);
for (const path of selected) {
const key = url(path, manifest.files[path]);
const response = await cache.match(key);
if (!response || response.headers.get('X-Asset-Hash') !== manifest.files[path].h) missing.push(key);
@@ -80,7 +90,7 @@
}
}));
if (failure) throw failure;
if (!(await status(manifest, cache, { previous, activeLayout })).ready) throw new Error('Incomplete blocking assets');
if (!groups && !(await status(manifest, cache, { previous, activeLayout })).ready) throw new Error('Incomplete blocking assets');
return { refreshed: count, caches: 1 };
}
@@ -106,7 +116,7 @@
return next;
}
const api = { CACHE, STATE, url, paths, blocking, plan, retained, status, syncAssets, state, commit };
const api = { CACHE, STATE, url, paths, blocking, plan, retained, fallback, status, syncAssets, state, commit };
if (typeof module !== 'undefined' && module.exports) module.exports = api;
else root.AssetSyncCore = api;
})(typeof globalThis !== 'undefined' ? globalThis : this);