v0.11.0
This release smooths out batch progress reporting and ships a new CompletionWatcher API that lets the frontend wait for batch completion via Echo broadcasts with a polling fallback — the same primitive useBatchCompletion is built on. No PHP changes; this is a frontend-only release.
Fixed
- Batch progress no longer jitters between files.
BatchUploaderused to assignthis.progressa per-step value ((filesCompleted / total) * 100) on everyfileComplete, which clobbered the smooth, chunk-driven progress that the worker loop had been interpolating into it. The result was a UI bar that crept up smoothly during a file, then snapped to a discrete step value at the boundary, then crept again. Removes the step assignment soprogressadvances continuously across the whole batch as chunks finish, regardless of file count. CompletionWatcherkeeps polling on transient errors. The watcher'sonErrorcallback used to fire with a single(error)argument and the consumer had no way to distinguish a one-off network blip from a fatal subscription failure. Signature is now(error, isFatal)— the watcher itself only flagsisFatal=truewhen the Echo subscription gives up; transient HTTP failures during polling no longer cancel the watch.useBatchCompletionmirrors this and only flipsisWaitingtofalseon the fatal branch, so the composable stays in the "waiting" state through retryable errors.
Added
CompletionWatcherandwatchBatchCompletion()in@netipar/chunky-core. A broadcast-or-poll primitive: subscribes to the batch's private channel via Echo and resolves onBatchCompleted/BatchPartiallyCompleted, with a status-endpoint poll as a fallback when Echo is unavailable or slow to subscribe. Surfaces lifecycle throughonComplete,onPartiallyCompleted,onError(error, isFatal), plus thecancel()returned fromwatchBatchCompletion. Useful when the upload finishes on one tab/process and the UI that needs to react to it lives somewhere else.useBatchCompletionVue 3 composable in@netipar/chunky-vue3. WrapsCompletionWatcherwith reactiveisWaiting,isComplete,result, anderrorrefs and an auto-cancel on unmount. Mirrors the new fatal/transient error semantics — the composable stays in the waiting state through transient failures.fileProgressevent onBatchUploader({ batchId, uploadId, file, progress, fileIndex }) emitted on every chunk progress tick, so consumers can drive a per-file progress bar without subscribing to the active uploader.useBatchUploadexposes the matchingonFileProgresscallback.- Continuous batch progress.
BatchUploader.progressnow interpolates across the whole batch (file boundary smoothing baked into the chunk-driven progress emission) — see the matching Fixed entry above. - Echo subscription lifecycle hooks.
listenForUserandlistenForBatchCompleteaccept optionalonSubscribed/onSubscribeErrorcallbacks that route to the underlying channel'ssubscribed()/error()hooks when available.EchoChannel'ssubscribed?anderror?hooks are now part of the type, witherrorcallback typed as(err: unknown)instead ofany.
Changed
FileProgressEvent.uploadIdis nowstring(wasstring | null). The id is always set by the time afileProgressevent fires.EchoChannel.error?callback parameter isunknown(wasany). Preserves the runtime contract while removing the implicit-any escape hatch for consumers.
Refactored
- Shared
http.tsutil in@netipar/chunky-coreconsolidates CSRF token discovery and request-header construction. Three call sites (BatchUploader,ChunkUploader,CompletionWatcher) now share one implementation instead of each rolling their own.
npm packages
- All packages bumped to
0.11.0(core, vue3, react, alpine). React and Alpine carry no source changes; they re-publish for version-sync consistency. Sister packages continue to require@netipar/chunky-coreviaworkspace:^, which resolves to^0.11.0on publish.
Migration notes (none required)
- The
CompletionWatcher.onErrorsignature change(error)→(error, isFatal)is on a brand-new, previously-unpublished API; no existing consumer is affected. TheFileProgressEvent.uploadIdandEchoChannel.error?type tightenings are non-breaking on the JS runtime — they only fail TypeScript builds that were relying on the looser types, and in both cases the looser types were unsound in practice.