Changelog
Version v0.13.0
What’s Changed
Features
- Worker defaults:
createInProcessWorkeraccepts a newdefaults: { backoffConfig?, leaseConfig? }option for fleet-wide fallbacks. Resolution order is processor → registry → workerdefaults→ library default.InProcessWorkerDefaultsis exported from the package root. - Required cross-slice middleware: new
requiredAttemptMiddlewareoption oncreateInProcessWorkerenforces (at compile time against the merged slice middleware, and at runtime by reference identity) that every slice includes the listedAttemptMiddlewareinstances as an in-order subsequence. The worker does not execute them itself — this guarantees cross-cutting concerns (auth, tracing, logging) are wired into every slice without giving up the per-slice middleware model. - Multi-slice validation: validation adapters now accept either a single external slice or a
readonlyarray, restoring the multi-slice composition path that was removed alongsidemergeJobTypeRegistriesin 0.12. New publicJobTypesDefinitions<T>resolves either form to the mergedBaseJobTypeDefinitionsrecord. RuntimeTypere-export from@queuert/postgresand@queuert/sqliteso custom state-provider authors can type their serialization/parsing without reaching into@queuert/typed-sql.- New
state-sqlite-bunexample demonstrates@queuert/sqliterunning onbun:sqlite.
Breaking Changes
workerId→workerName:createInProcessWorker’s identity option is renamed toworkerName— an optional human-readable label restricted to/^[A-Za-z0-9._-]+$/. The runtime always appends a random UUID to produce the final worker id (${workerName}-${uuid}, or just${uuid}when omitted), making duplicate worker ids impossible to express. Observability events and error fields continue to expose the full id underworkerId.- Validation adapter signatures: adapters accept the “single slice or readonly array” shape
createClientalready takes.ExternalJobTypeDefinitionsis no longer exported — useJobTypeDefinitionsfor a single slice orJobTypesDefinitionsfor either form. Adapter authors implementingrunValidationAdapterConformancemust add abuildWithExternalSlicesfixture, andbuildWithExternalSlice’sblockerstightens from a readonly array to a tuple — schemas under test must switch fromarray(...)totuple([...])(z.tuple,v.tuple,Type.Tuple,type([...])). - Stricter public error fields: contextual fields on
JobNotFoundError,ChainNotFoundError,JobTakenByAnotherWorkerError,JobAlreadyCompletedError,JobNotTriggerableError, andWaitChainTimeoutError(jobId,chainTypeName, etc.) are now non-optionalstring/number, and their constructor options are required — caught errors no longer need null-checks.JobTakenByAnotherWorkerError.leasedByis nowstring | null(an omitted constructor option is normalized tonull); narrowings via=== undefinedshould switch to=== null. @queuert/otelattribute renames: every metric attribute key is renamed to OpenTelemetry semantic-convention style (lowercase, dotted) to align with the span attributes already emitted by the tracing layer. Metric names are unchanged, so queries still resolve — but dashboards, alerts, and recording rules that group by or filter on the old keys silently return empty results until updated.workerId→queuert.worker.id,typeName→queuert.job.type,chainTypeName→queuert.chain.type,continued→queuert.job.continued,operation→queuert.adapter.operation. Two value encodings also changed onqueuert.job.completed:queuert.job.continuedis now a real boolean (not"true"/"false"), andqueuert.worker.idis omitted for workerless completions (no longer the literal string"null").executeSql.iduniqueness: in@queuert/postgresand@queuert/sqlite,executeSql’sidnow uniquely identifies the resolved SQL within a provider — the template applier folds variants likeschema/tablePrefixinto a hashed suffix. The built-inpg.Poolprovider drops its SHA1 name-hash (query.name = id); built-inbetter-sqlite3andnode:sqliteproviders drop their per-database SQL→Statement maps and key the cache byid. Custom providers can do the same.
Bug Fixes
- Relax the generic bound on
AttemptMiddleware’sTStateAdapterfromStateAdapter<BaseTxContext, any>toStateAdapter<any, any>. The previous bound was unusable in practice: because the transaction-context type parameter appears in contravariant positions, no concrete adapter with a non-emptytxCtxcould satisfyStateAdapter<BaseTxContext = {}, any>. Adapter-aware middleware and generic test helpers now type-check withoutanyworkarounds.
Packages
All packages released at 0.13.0: queuert, @queuert/postgres, @queuert/sqlite, @queuert/redis, @queuert/nats, @queuert/otel, @queuert/dashboard.