Changelog
Version v0.15.0
What’s Changed
Breaking Changes
triggerJob/triggerJobsrenamed torescheduleJob/rescheduleJobswith an optionalscheduleparameter ({ at: Date } | { afterMs: number }). Omitting it reschedules to now (previous behavior). A past time clamps to now. Onlypendingjobs are reschedulable. Batch validation is atomic.- Error classes renamed:
JobNotTriggerableError/JobsNotTriggerableError→JobNotReschedulableError/JobsNotReschedulableError. New batch error variantsJobsNotFoundErrorandJobsNotReschedulableErrorforrescheduleJobs. Thestatusproperty removed from the singular error; the batch variant exposesjobIds. - Observability event renamed:
jobTriggered→jobRescheduled. Now also emitted on worker retry (not just client reschedules), making it the single signal for “scheduledAt changed.”jobAttemptFailedis now a pure failure event —rescheduledAt/rescheduledAfterMsremoved.scheduleAfterMsdropped fromjobCreatedandjobRescheduledevents. StateProvidergains requiredtransactionConcurrencyfield ("concurrent" | "serialized"). Custom provider authors must declare it.- Dashboard:
POST /jobs/:id/triggerrenamed to/reschedule; “Trigger now” button renamed to “Reschedule”. - OTEL: Counter
queuert.job.triggered→queuert.job.rescheduled; log entryjob_triggered→job_rescheduled.
Features
- Blocker chain cap: A job can declare at most 100 blocker chains.
startChain,startChains, andcontinueWiththrow the newBlockerLimitExceededErrorwhen exceeded. - Dashboard UX improvements: Infinite scroll on list views (chains, jobs, chain detail), real links on cards (right-click/Cmd-click to open in new tab), and smart back navigation that preserves filters.
Bug Fixes
createProcessorstype resolution: Previously resolved job type names from the local slice only; now resolves from all registered slices."incomplete"dedup scope: Multi-step chains that continued past the root job are now correctly matched. Previously, once the root completed, the chain was no longer matched even though it was still running.- Concurrent unblock race (
@queuert/postgres,@queuert/sqlite): Row-level locks on blocked jobs duringunblockJobsprevent a race where concurrent blocker completions could leave dependent jobs stranded inblockedstatus.job_blockerPK widened to support duplicate chain IDs.
Performance
- Autovacuum tuning (
@queuert/postgres): New migration pinsautovacuum_vacuum_threshold = 5000/scale_factor = 0onjobandjob_blockertables, replacing size-proportional0.02. Gives predictable vacuum cadence regardless of table size.
Packages
All packages released at 0.15.0: queuert, @queuert/postgres, @queuert/sqlite, @queuert/redis, @queuert/nats, @queuert/otel, @queuert/dashboard.