diff --git a/js/CHANGELOG.md b/js/CHANGELOG.md index 50069c580..1a8f980cb 100644 --- a/js/CHANGELOG.md +++ b/js/CHANGELOG.md @@ -7,16 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.0] - 2026-10-26 + ### Added +- Add optional `delete`, `deleteMany`, and `deleteBefore` pilot interceptors for job deletion through the client and job cleaner. Hooks run within the deletion transaction and can extend or replace the standard deletion. [PR #1502](https://github.com/riverqueue/river/pull/1502). - Add `@riverqueue/driver-knex` for inserting jobs on Postgres inside Knex transactions, including batches, unique jobs, and nested savepoints. Configure its `knexTransactionAdapter` on `PgDriver` to use native Knex transactions with `completeTx` in workers. [PR #1516](https://github.com/riverqueue/river/pull/1516). - Support native Prisma interactive transactions with `completeTx` in workers and `{ tx }` on Postgres client operations. Configure `prismaTransactionAdapter` from `@riverqueue/driver-prisma` on `PgDriver` to commit application writes and job completion together. [PR #1517](https://github.com/riverqueue/river/pull/1517). -- Support Node.js 24 across all packages. On runtimes without native `Temporal`, preload an application-provided polyfill before importing River, including in worker threads. River validates runtime support on library import and never installs or replaces a global polyfill. The standalone `riverqueue` CLI supplies its own polyfill when needed. Node.js 26 uses native `Temporal`. +- Support Node.js 24 across all packages. On runtimes without native `Temporal`, preload an application-provided polyfill before importing River, including in worker threads. River validates runtime support on library import and never installs or replaces a global polyfill. The standalone `riverqueue` CLI supplies its own polyfill when needed. Node.js 26 uses native `Temporal`. [PR #1497](https://github.com/riverqueue/river/pull/1497), [PR #1548](https://github.com/riverqueue/river/pull/1548). ### Changed - **Breaking:** Resumable steps can no longer be nested. Calls fail before running child callbacks, preventing unreachable resume points and rolled-back parent checkpoints from being saved again. [PR #1534](https://github.com/riverqueue/river/pull/1534). -- Like River for Go, `insertMany` rejects an empty batch with a `ValidationError` instead of returning an empty result. [PR #1504](https://github.com/riverqueue/river/pull/1504). +- **Breaking:** Like River for Go, `insertMany` rejects an empty batch with a `ValidationError` instead of returning an empty result. [PR #1504](https://github.com/riverqueue/river/pull/1504). - Like River for Go, the client no longer caps `maxAttempts` at 32767: SQLite stores wider attempt counts, and the Postgres and Prisma drivers clamp `maxAttempts` to their 16-bit column on insert instead of failing. [PR #1504](https://github.com/riverqueue/river/pull/1504). - Like River for Go's `ResumableStep`, a failed resumable step records the step's own error as the attempt's error instead of wrapping it in a `LifecycleError`. [PR #1504](https://github.com/riverqueue/river/pull/1504). @@ -24,12 +27,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Refresh a durable periodic job's saved row only after its next run time is loaded at startup or committed. When a startup write rolled back, keep-alive could revive an expired row, and the next leader enqueued every run since the row's old next run time. [PR #1540](https://github.com/riverqueue/river/pull/1540). - Fail retries that omit a saved cursor-only step, while preserving their checkpoints for recovery. Jobs with an existing step marker retain their behavior, including legacy stale cursor entries. [PR #1534](https://github.com/riverqueue/river/pull/1534). - - Replace whole top-level metadata values on SQLite, including JSON null, matching Postgres. Completed resumable cursor steps no longer run again because of stale cursor entries. [PR #1533](https://github.com/riverqueue/river/pull/1533). - -- Preserve first-step resumable cursors on failure and step progress on snooze. Transactional checkpoints no longer leak into deferred updates after rollback or a failed write; rolling back a successful checkpoint write may replay earlier unpersisted steps. - -- Worker threads respect cancellation received while loading a handler module, before invoking its handler. +- Preserve first-step resumable cursors on failure and step progress on snooze. Transactional checkpoints no longer leak into deferred updates after rollback or a failed write; rolling back a successful checkpoint write may replay earlier unpersisted steps. [PR #1521](https://github.com/riverqueue/river/pull/1521). +- Worker threads respect cancellation received while loading a handler module, before invoking its handler. [PR #1497](https://github.com/riverqueue/river/pull/1497). - Like River for Go, a leader whose renewal finds its term gone, because it expired or another process replaced it, gives up leadership at once instead of running maintenance until its local deadline passes. [PR #1504](https://github.com/riverqueue/river/pull/1504). - `updateQueue` raising a full queue's `maxWorkers` starts jobs at once instead of waiting for a running job to finish. [PR #1504](https://github.com/riverqueue/river/pull/1504). diff --git a/js/cli/package.json b/js/cli/package.json index feb782e99..60464f966 100644 --- a/js/cli/package.json +++ b/js/cli/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/cli", - "version": "0.2.0", + "version": "0.3.0", "description": "Command-line migrations, benchmarks, and upgrade codemods for River TypeScript.", "type": "module", "sideEffects": [ @@ -50,10 +50,10 @@ }, "dependencies": { "@js-temporal/polyfill": "^0.5.1", - "@riverqueue/driver-pg": "workspace:0.2.0", - "@riverqueue/migrate": "workspace:0.2.0", + "@riverqueue/driver-pg": "workspace:0.3.0", + "@riverqueue/migrate": "workspace:0.3.0", "pg": "^8.23.1", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "peerDependencies": { "@types/node": ">=24", diff --git a/js/driver/knex/package.json b/js/driver/knex/package.json index 7ece2898b..23d30da89 100644 --- a/js/driver/knex/package.json +++ b/js/driver/knex/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/driver-knex", - "version": "0.2.0", + "version": "0.3.0", "description": "Knex driver for the riverqueue TypeScript client.", "type": "module", "sideEffects": false, @@ -45,12 +45,12 @@ "peerDependencies": { "knex": "^3.1.0", "pg": "^8.0.0", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "devDependencies": { "knex": "^3.1.0", "pg": "^8.23.1", - "riverqueue": "workspace:0.2.0", + "riverqueue": "workspace:0.3.0", "typescript": "^6.0.3" }, "keywords": [ diff --git a/js/driver/pg/package.json b/js/driver/pg/package.json index e590ac2cb..cf0a00e7a 100644 --- a/js/driver/pg/package.json +++ b/js/driver/pg/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/driver-pg", - "version": "0.2.0", + "version": "0.3.0", "description": "Complete node-postgres backend for River's TypeScript runtime.", "type": "module", "sideEffects": false, @@ -48,7 +48,7 @@ "peerDependencies": { "@types/pg": ">=8", "pg": ">=8.0.0", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "peerDependenciesMeta": { "@types/pg": { @@ -58,7 +58,7 @@ "devDependencies": { "@types/pg": "^8.23.1", "pg": "^8.23.1", - "riverqueue": "workspace:0.2.0", + "riverqueue": "workspace:0.3.0", "typescript": "^6.0.3" }, "keywords": [ diff --git a/js/driver/prisma/package.json b/js/driver/prisma/package.json index 5488ae04b..5861e230e 100644 --- a/js/driver/prisma/package.json +++ b/js/driver/prisma/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/driver-prisma", - "version": "0.2.0", + "version": "0.3.0", "description": "Prisma driver for the riverqueue TypeScript client.", "type": "module", "sideEffects": false, @@ -44,13 +44,13 @@ }, "peerDependencies": { "@prisma/client": ">=5.0.0", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "devDependencies": { "@prisma/adapter-pg": "7.10.1", "@prisma/client": "7.10.1", "prisma": "7.10.1", - "riverqueue": "workspace:0.2.0", + "riverqueue": "workspace:0.3.0", "typescript": "^6.0.3" }, "keywords": [ diff --git a/js/driver/sqlite/package.json b/js/driver/sqlite/package.json index 004f55c30..f660c5d64 100644 --- a/js/driver/sqlite/package.json +++ b/js/driver/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/driver-sqlite", - "version": "0.2.0", + "version": "0.3.0", "description": "First-party node:sqlite backend for River.", "type": "module", "sideEffects": false, @@ -46,7 +46,7 @@ }, "peerDependencies": { "@types/node": ">=24", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "peerDependenciesMeta": { "@types/node": { @@ -54,9 +54,9 @@ } }, "devDependencies": { - "@riverqueue/migrate": "workspace:0.2.0", + "@riverqueue/migrate": "workspace:0.3.0", "@types/node": "^26.6.5", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "keywords": [ "river", diff --git a/js/migrate/package.json b/js/migrate/package.json index 4f75b1c2d..b9c353162 100644 --- a/js/migrate/package.json +++ b/js/migrate/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/migrate", - "version": "0.2.0", + "version": "0.3.0", "description": "Canonical River database migrations for JavaScript and TypeScript.", "type": "module", "sideEffects": false, @@ -46,7 +46,7 @@ }, "peerDependencies": { "@types/node": ">=24", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "peerDependenciesMeta": { "@types/node": { @@ -54,10 +54,10 @@ } }, "devDependencies": { - "@riverqueue/driver-pg": "workspace:0.2.0", + "@riverqueue/driver-pg": "workspace:0.3.0", "@types/node": "^26.6.5", "pg": "^8.23.1", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "keywords": [ "river", diff --git a/js/package.json b/js/package.json index 94554531c..3af9c2287 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "riverqueue", - "version": "0.2.0", + "version": "0.3.0", "description": "TypeScript implementation of River, a fast and reliable background job system.", "type": "module", "sideEffects": [ diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index b3b623e16..e895f47dc 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -94,16 +94,16 @@ importers: specifier: ^0.5.1 version: 0.5.1 '@riverqueue/driver-pg': - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../driver/pg '@riverqueue/migrate': - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../migrate pg: specifier: ^8.23.1 version: 8.23.1 riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:.. devDependencies: '@types/node': @@ -125,7 +125,7 @@ importers: specifier: ^8.23.1 version: 8.23.1 riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../.. typescript: specifier: ^6.0.3 @@ -144,7 +144,7 @@ importers: specifier: ^8.23.1 version: 8.23.1 riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../.. typescript: specifier: ^6.0.3 @@ -162,7 +162,7 @@ importers: specifier: 7.10.1 version: 7.10.1(@types/node@26.6.5)(@types/react@19.3.0)(magicast@0.5.5)(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(typescript@6.0.3) riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../.. typescript: specifier: ^6.0.3 @@ -171,13 +171,13 @@ importers: driver/sqlite: devDependencies: '@riverqueue/migrate': - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../../migrate '@types/node': specifier: ^26.6.5 version: 26.6.5 riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../.. examples/graceful-shutdown: @@ -389,7 +389,7 @@ importers: migrate: devDependencies: '@riverqueue/driver-pg': - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../driver/pg '@types/node': specifier: ^26.6.5 @@ -398,28 +398,28 @@ importers: specifier: ^8.23.1 version: 8.23.1 riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:.. test: devDependencies: riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:.. worker-threads: devDependencies: '@riverqueue/driver-sqlite': - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../driver/sqlite '@riverqueue/migrate': - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:../migrate '@types/node': specifier: ^26.6.5 version: 26.6.5 riverqueue: - specifier: workspace:0.2.0 + specifier: workspace:0.3.0 version: link:.. packages: diff --git a/js/test/package.json b/js/test/package.json index bf2ab4ebe..1d5d73dc1 100644 --- a/js/test/package.json +++ b/js/test/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/test", - "version": "0.2.0", + "version": "0.3.0", "description": "Typed test helpers for River jobs, workers, and clients.", "type": "module", "sideEffects": false, @@ -44,10 +44,10 @@ "provenance": true }, "peerDependencies": { - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "devDependencies": { - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "keywords": [ "river", diff --git a/js/worker-threads/package.json b/js/worker-threads/package.json index 13f217965..d97737f72 100644 --- a/js/worker-threads/package.json +++ b/js/worker-threads/package.json @@ -1,6 +1,6 @@ { "name": "@riverqueue/worker-threads", - "version": "0.2.0", + "version": "0.3.0", "description": "Optional bounded worker-thread executor for River TypeScript.", "type": "module", "sideEffects": [ @@ -48,7 +48,7 @@ }, "peerDependencies": { "@types/node": ">=24", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "peerDependenciesMeta": { "@types/node": { @@ -56,10 +56,10 @@ } }, "devDependencies": { - "@riverqueue/driver-sqlite": "workspace:0.2.0", - "@riverqueue/migrate": "workspace:0.2.0", + "@riverqueue/driver-sqlite": "workspace:0.3.0", + "@riverqueue/migrate": "workspace:0.3.0", "@types/node": "^26.6.5", - "riverqueue": "workspace:0.2.0" + "riverqueue": "workspace:0.3.0" }, "keywords": [ "river",