Skip to content

Changelog

Version v0.13.0

What’s Changed

Features

  • Worker defaults: createInProcessWorker accepts a new defaults: { backoffConfig?, leaseConfig? } option for fleet-wide fallbacks. Resolution order is processor → registry → worker defaults → library default. InProcessWorkerDefaults is exported from the package root.
  • Required cross-slice middleware: new requiredAttemptMiddleware option on createInProcessWorker enforces (at compile time against the merged slice middleware, and at runtime by reference identity) that every slice includes the listed AttemptMiddleware instances 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 readonly array, restoring the multi-slice composition path that was removed alongside mergeJobTypeRegistries in 0.12. New public JobTypesDefinitions<T> resolves either form to the merged BaseJobTypeDefinitions record.
  • RuntimeType re-export from @queuert/postgres and @queuert/sqlite so custom state-provider authors can type their serialization/parsing without reaching into @queuert/typed-sql.
  • New state-sqlite-bun example demonstrates @queuert/sqlite running on bun:sqlite.

Breaking Changes

  • workerId → workerName: createInProcessWorker’s identity option is renamed to workerName — 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 under workerId.
  • Validation adapter signatures: adapters accept the “single slice or readonly array” shape createClient already takes. ExternalJobTypeDefinitions is no longer exported — use JobTypeDefinitions for a single slice or JobTypesDefinitions for either form. Adapter authors implementing runValidationAdapterConformance must add a buildWithExternalSlices fixture, and buildWithExternalSlice’s blockers tightens from a readonly array to a tuple — schemas under test must switch from array(...) to tuple([...]) (z.tuple, v.tuple, Type.Tuple, type([...])).
  • Stricter public error fields: contextual fields on JobNotFoundError, ChainNotFoundError, JobTakenByAnotherWorkerError, JobAlreadyCompletedError, JobNotTriggerableError, and WaitChainTimeoutError (jobId, chainTypeName, etc.) are now non-optional string / number, and their constructor options are required — caught errors no longer need null-checks. JobTakenByAnotherWorkerError.leasedBy is now string | null (an omitted constructor option is normalized to null); narrowings via === undefined should switch to === null.
  • @queuert/otel attribute 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 on queuert.job.completed: queuert.job.continued is now a real boolean (not "true" / "false"), and queuert.worker.id is omitted for workerless completions (no longer the literal string "null").
  • executeSql.id uniqueness: in @queuert/postgres and @queuert/sqlite, executeSql’s id now uniquely identifies the resolved SQL within a provider — the template applier folds variants like schema / tablePrefix into a hashed suffix. The built-in pg.Pool provider drops its SHA1 name-hash (query.name = id); built-in better-sqlite3 and node:sqlite providers drop their per-database SQL→Statement maps and key the cache by id. Custom providers can do the same.

Bug Fixes

  • Relax the generic bound on AttemptMiddleware’s TStateAdapter from StateAdapter<BaseTxContext, any> to StateAdapter<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-empty txCtx could satisfy StateAdapter<BaseTxContext = {}, any>. Adapter-aware middleware and generic test helpers now type-check without any workarounds.

Packages

All packages released at 0.13.0: queuert, @queuert/postgres, @queuert/sqlite, @queuert/redis, @queuert/nats, @queuert/otel, @queuert/dashboard.