A sound implementation does not ask users to refresh until it works. Each phase has an input, an output, a timeout, and a terminal state. OPFS provides private random-access storage suited to sparse chunks and large temporary files. It is not a user-visible download folder and disappears with site data.
Browser capability depends on version, permission, visibility, and device policy. Use capability detection and an explained fallback instead of treating one development machine as the product contract.
Define the system contract first
Write the following choices as reviewable rules instead of scattering them across callbacks and UI conditions. Explicit rules make scaling, compatibility, and diagnosis less dependent on guesswork.
- Use synchronous access handles in a dedicated Worker while the main thread receives status.
- Store logical size and written ranges in a manifest; file length is not proof of completeness.
- Fall back to IndexedDB after capability detection while preserving one task protocol.
OPFS is a fast temporary backend, not durable user storage. It needs fallback, manifests, export, and cleanup to support large files safely.
What can break that contract
An abnormal path is more than an error banner. It decides how in-flight work stops, how the peer learns the outcome, what residue remains, and whether the next operation inherits it.
- Multiple Workers contend for one synchronous handle and leave tasks waiting forever.
- Completion never exports or prompts to save, leaving the file hidden in private storage.
- Cancelled and expired tasks retain OPFS files, accumulating sensitive data and quota usage.
How to test the contract line by line
Observe both endpoints, persisted records, and operational signals during verification. One button state or one successful response cannot prove the complete loop.
- Write random ranges, refresh, and read back to verify sparse state and final digest.
- Simulate handle contention, Worker crashes, and quota exhaustion with recoverable outcomes.
- Inspect file lifecycle after complete, cancel, expiry, and site-data clearing.
The result must be correct, recoverable, and explainable. If any part depends on refreshing the page or an engineer guessing, the protocol loop remains incomplete.