Background Upload via SharedWorker
Start a simulated or real upload, then open Browse or Settings while it runs. The progress bar follows you. A SharedWorker sends the chunks, extendedLifetime (Chrome 148+) keeps it alive between pages, and session-scoped signals carry the progress.
uploadStatus, uploadPct, uploadFileName, and byte counters for every tab of your session, in a custom upload: scope built from Scope::sessionScope(). Each write broadcasts that scope, and when the new page's SSE stream opens, the server pushes the current state (no polling, no local storage).File.slice()) and POSTs them one by one to the uploadChunk action. Between each await the worker may receive a connect message with fresh URLs from the new page, making mid-upload navigation transparent.beforeunload handler covers other navigation. The guard is automatically suppressed on Chrome 148+ once the worker's workerBorn timestamp confirms it survived.| Name | Size | Modified | Type |
|---|---|---|---|
| Projects | - | 2026-04-10 | Folder |
| quarterly-report-q1-2026.pdf | 2.4 MB | 2026-04-01 | |
| architecture-diagram.png | 840 KB | 2026-03-28 | PNG |
| staging-backup-2026-03-15.tar.gz | 12.1 GB | 2026-03-15 | tar.gz |
| CHANGELOG.md | 64 KB | 2026-04-12 | Markdown |
Signals
uploadStatus
string custom scope initial: "idle" Upload lifecycle: idle | uploading | complete | cancelled.
uploadPct
int custom scope initial: 0 Upload progress 0 to 100. Authoritative server value: navigation gaps self-heal on next chunk.
uploadFileName
string custom scope initial: empty string Filename displayed in the progress bar.
uploadTotalBytes
int custom scope initial: 0 Total file size in bytes (virtual or real).
uploadedBytes
int custom scope initial: 0 Bytes transferred so far.
uploadFileInfo
string custom scope initial: empty string Human-readable file metadata for real uploads, e.g. "3.2 MB · PDF". Empty for simulated uploads.
uploadMode
string tab scope initial: "sim" Which form is shown: sim (SharedWorker simulation) or real (multipart upload). TAB-scoped: each tab can differ.
Actions
startUpload
Initialises the upload signals (status=uploading, total, filename); the writes reach every tab of the session. Called by the worker before the chunk loop.
receiveChunk
Simulated mode only. Called by SharedWorker every 200 ms. Updates pct and uploadedBytes from the worker's authoritative value, which heals navigation gaps.
uploadChunk
Real file mode only. Receives a 512 KB slice from the SharedWorker chunk loop. Tracks offset and size, updates pct/uploadedBytes, sets status=complete and formats uploadFileInfo on the final chunk.
setMode
Switches uploadMode between sim and real, clears file errors, re-renders the form block.
cancelUpload
Resets all upload signals to idle. Works from any sub-page.
resetUpload
Clears completed/cancelled state so a new upload can begin.
Views
file-upload.html.twig
Mode toggle, sim form (filename + size/speed pickers), real file form. Real uploads use File.slice() chunks (512 KB each) sent by the SharedWorker via uploadChunk. Navigation guard shown on non-Chrome browsers.
file-upload-browse.html.twig
Fake file browser sub-page showing live upload row during transfer.
file-upload-settings.html.twig
Fake settings sub-page proving upload state survives any navigation.