fix(offline): exact-size quota eviction and budgeted manifest sync - #46
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The service worker's quota handling used fake sizes everywhere: 5 MiB assumed per evicted entry, a flat 20 MiB free-space margin, and files were recorded as cached even when they were evicted. On small-quota browsers (Safari, iOS) a large site thrashed: the sync downloaded the whole manifest, hit the quota wall, evicted the just-cached files, and marked them cached anyway — leaving offline coverage at a few tail files that were never re-fetched.
Changes
cache-manifest.jsonnow ships asizesmap — exact byte count of every built file (docsforge/build.py). Additive;files/versionunchanged, so existing SWs and stored previous-files lists stay compatible.makeSpaceIfNeededaccounts each entry at its actual size (Content-Length, falling back to reading the body) and frees untilavailable + freedcovers the required bytes plus a proportional 10%-of-quota margin. No more 5 MiB guess, no more 20 MiB floor.storage.estimate()free space and reserves a flat 20 MiB per download (the usage estimate lags behind in-flight writes). Once the budget is exhausted the sync stops instead of downloading files that will only be evicted again; unbudgeted files are cached on demand when visited. A single resource larger than the whole quota is never cached.docsforge-manifest-fileslist (both during sync and between syncs), so a later sync re-fetches what was actually evicted.Tests
sizesmap present, every manifest key covered, values match the built files on disk.sizesmatchesos.path.getsizefor a real build.--quota-override-size-mb): budget test (25 MiB quota → exactly 1 file synced, tracked files all really cached) and eviction test (3 MiB quota, 2×2 MiB assets → LRU evicted with measured accounting, cache within quota, no tracked-but-missing files). Both skip when the override isn't honoured.docsforge/templates/assets/javascripts/bundle.min.jswas regenerated bybuild_frontend.py— semantically identical (esbuild identifier-mangling only), fixing a pre-existing committed-vs-built drift so the frontend parity check stays green.Changelog: 12.5.5 section (en + zh).