Upload progress tracking
Use case
Show a progress bar during file uploads.
Smallest working example
import { createClient } from '@parcely/core'
const http = createClient({ baseURL: 'https://api.example.com' })
const form = new FormData()
form.set('file', largeFile)
await http.post('/upload', form, {
onUploadProgress: ({ loaded, total, percent }) => {
console.log(`${loaded} / ${total} bytes (${percent}%)`)
},
})
Progress event shape
interface ProgressEvent {
loaded: number // bytes transferred so far
total?: number // total bytes (undefined if unknown)
percent?: number // 0–100 (undefined if total is unknown)
}
Runtime support matrix
| Runtime | Upload progress support |
|---|---|
| Node 20+ | Full support via ReadableStream request body wrapping |
| Chromium 105+ | Full support via duplex: 'half' + ReadableStream request body |
| Safari / Firefox | Terminal callback only (loaded === total on completion) |
On Safari and Firefox, fetch does not support streaming request bodies. parcely falls back to a single progress callback at completion and emits a one-shot console.warn explaining the browser limitation in development mode.
Axios equivalent
// axios:
await http.post('/upload', form, {
onUploadProgress: (e) => console.log(e.loaded, e.total),
})
// parcely (adds percent):
await http.post('/upload', form, {
onUploadProgress: ({ loaded, total, percent }) =>
console.log(loaded, total, percent),
})
Notes and gotchas
- parcely automatically sets
duplex: 'half'on the fetch options whenonUploadProgressis provided and the body is streamable. totalandpercentareundefinedwhen the stream length is not knowable.- Stream errors during upload produce
HttpErrorwithcode: 'ERR_NETWORK'.