Skip to content

Releases: veliovgroup/josk

v6.1.0

19 May 13:42
5d83065

Choose a tag to compare

📦 NPM @6.1.0
☄️ Packosphere @6.1.0

Breaking / behavior changes

  • setInterval / setTimeout: invalid delays (NaN, Infinity, non-numbers) throw at register — was silent corruption of schedule.
  • onError / onExecuted: hook throws/rejections logged, no longer take down scheduler loop.
  • RedisAdapter prefix: stricter validation — {, }, other specials rejected (Cluster-safe).

New

  • RedisAdapter({ useHashTags: true }) — Redis Cluster / KeyDB Cluster: keys josk:{prefix}:* (one slot). Default false — standalone keys josk:prefix:* unchanged.
  • Migration guide: docs/migration-v6-v6.1.md

Fixes / hardening

  • Removed/cleared tasks: skip execution if task gone mid-flight; no spurious onExecuted when remove() fails on setTimeout/setImmediate.
  • Postgres adapter: connection/setup robustness (no public API change).

Action if upgrading

Setup Action
Standalone Redis Drop-in unless bad delays in code
Redis/KeyDB Cluster Enable useHashTags: true; migrate keys or resetOnInit — v6.0 was likely wrong slot layout
Invalid delays in app Fix before upgrade

Docs/skills/CI only otherwise — no new JoSk methods.

Full Changelog: v6.0.0...6.1.0

v6.0.0

15 May 22:56
eb0b57d

Choose a tag to compare

📦 NPM @6.0.0
☄️ Packosphere @6.0.0

What's New

  • 🤝 TS fully typed, thanks to @climba03003
  • 🐘 Postgres Transport
  • ✨ Atomic operations
  • execute mode — one or batch
  • ✨ Now locks and active tasks has owners
  • 🥟 Bun.js compatibility
  • ☄️ meteor@3.4 compatibility
  • 🛢️ Redis driver v4/v5 compatibility
  • 🛢️ Fully refactored Redis Adapter to use Lua scripts with caching
  • 🔧 Improved locks
  • 🧪 Drastically improved tests
  • 😎 AGENTS.md/CLAUDE.md + SKILLS.md

Major Changes

  • ⚠️ Drop Node 14/16/18 support. Engines now node >=20.9.0 and bun >=1.1.0. Users on older Node should stay on josk@5.
  • ⚠️ Default prefix is now default for all drivers, fallback to '' (empty string) to preserve old behavior.
  • ⚠️ Adapters must define/check owners on locks.

v4 to v5 migration

  • MongoAdapter previously defaulted the prefix to '', producing the collection __JobTasks__. v6 defaults to 'default', producing __JobTasks__default. If you used the implicit empty prefix in v4/v5, pass prefix: '' explicitly to preserve the collection name, or migrate data: db.__JobTasks__.renameCollection('__JobTasks__default').
  • Lock release now checks lease ownership; a JoSk instance can no longer release a foreign lease. If you have custom adapters, follow the adapter API contract.
  • If you use cron-parser — bump to ^5 and switch from parser.parseExpression(...) to CronExpressionParser.parse(...).

RAW CHANGELOG

  • Breaking: drop Node 14/16/18 support. Engines now node >=20.9.0 and bun >=1.1.0. Users on older Node should stay on josk@5.
  • Bun runtime support: package runs unmodified on Bun >=1.1.0. The existing Jest suite (test/jest/core.test.js, test/jest/adapters.test.js) doubles as the Bun suite — test files load @jest/globals on Node and bun:test on Bun via a conditional dynamic import, so the same suite runs under both runners. New npm run test:bun script (bun test ./test/jest/) and a test-bun job in the GitHub Actions workflow exercise the same Redis / MongoDB / PostgreSQL service containers under Bun. README gains a "Bun runtime" section.
  • Redis driver: support both redis@^4 and redis@^5. Dev pin updated to redis@^5.12.1. CI matrix runs each Node/Bun job against both driver majors.
  • Switch internal random IDs (lockOwnerId, lease tokens) to crypto.randomUUID().
  • Auto-call ready() for sync handlers declared with no ready parameter (func.length === 0). Handlers that declare ready but never call it continue to zombie-recover, with a debug log to ease diagnosis.
  • New concurrency option on JoSk caps the number of handlers running in parallel inside one instance. Default Infinity.
  • Fix __tick jitter range — interval now spans [minRevolvingDelay, maxRevolvingDelay] instead of [minRevolvingDelay, minRevolvingDelay + maxRevolvingDelay].
  • Postgres adapter: lock acquisition compares against CURRENT_TIMESTAMP on the server side, removing client-clock-skew sensitivity. Migrations are gated by a josk_meta.schema_version row and no longer touch lock rows from other prefixes on every startup. Removed leftover __customPrivateMethod.
  • Mongo adapter: update uses matchedCount instead of modifiedCount to avoid false negatives when the new timestamp coincides with the stored one. releaseLock errors now flow through onError like Redis/Postgres. Default prefix is now 'default'.
  • Redis adapter: cache Lua scripts via SCRIPT LOAD + EVALSHA (falls back to EVAL on NOSCRIPT or unsupported clients). Expand stale-entry scan budget to 1000 (one) / limit*20 (batch) for resilience under load. Reject prefixes that break Cluster hash-tag routing.
  • Mongo adapter doc: tested only against the official mongodb driver. Other Mongo-compatible clients are not supported.
  • TypeScript: post-process tsc output via scripts/strip-internal.mjs to truly strip @internal members (works around TypeScript JSDoc/stripInternal gap). Adapter d.ts files no longer expose __readyPromise, __claim*, __scriptShas, etc.
  • Build emits a proper tsc-generated index.d.cts from a small .cts shim (index.cts) instead of cp index.d.ts index.d.cts. The shim is excluded from the published tarball. CJS consumers now resolve types via genuine CommonJS-shaped declarations rather than a misnamed ESM file.
  • Allow JoSkOnError/JoSkOnExecuted to return Promise<void>. Add positive type tests that built-in adapters conform to JoSkAdapter.
  • README: new sections for execution semantics (at-most-once/exactly-once table), TypeScript usage, prefix mapping per adapter, operational FAQ, v4 → v5 migration guide. Tightened accuracy claim to use maxRevolvingDelay instead of hardcoded ±256ms. Migrated CRON examples to cron-parser@^5 (CronExpressionParser.parse(...)).
  • GitHub Actions workflow added that runs Jest + Mocha live suites across Node 20/22/24 (and the test-bun job under bun@latest) with Redis, MongoDB, and PostgreSQL service containers; uploads coverage on Node 22 / redis@5.
  • AGENTS.md: fix test script names (test:redis etc., not test-redis).
  • Fix npm Mocha suite shutdown by destroying JoSk instances and closing MongoDB/Redis clients.
  • Add shared test helpers and extend same-prefix cluster exactly-once coverage across MongoDB, Redis, PostgreSQL.
  • Add Meteor PostgreSQL package tests and remove invalid Meteor 3.4 release target.
  • Rework storage adapters around owner-bound lease tokens. Lock release now checks lease ownership and no longer deletes foreign live leases after pause or zombie recovery.
  • Add atomic due-task claiming in MongoDB, Redis, PostgreSQL adapters. Redis now uses sorted-set scheduler index plus Lua scripts instead of full scans. PostgreSQL now claims with FOR UPDATE SKIP LOCKED. MongoDB now claims with atomic findOneAndUpdate.
  • Document KeyDB compatibility guidelines for RedisAdapter, including single-writer topology, cluster hash-slot behavior, and active-replication caveats.
  • Add adapter ready() initialization barrier. MongoDB waits for indexes/reset. PostgreSQL waits for schema/reset. Fix startup races where scheduler could tick before storage objects existed.
  • Add execute option to JoSk: one or batch. Default batch for backward-compatible throughput. one claims/executes one task per scheduler lease when lower per-tick work is preferred.
  • Fix PostgreSQL scope isolation by switching task identity to composite (prefix, uid) primary key. Remove completed tasks physically instead of leaving soft-deleted rows behind.
  • Update custom adapter contract, blank adapter example, README, TypeScript definitions, generated CJS bundle.
  • Add full PostgreSQL adapter (PostgresAdapter) with table auto-setup, row-based locking, full test coverage. Follows adapter API, uses pg Pool/Client.
  • Improve TypeScript definitions: added Adapter interface, made adapter required in JoSkOption, fixed return types, JSDoc, updated .d.ts/.d.cts for all adapters including Postgres. Reduced inconsistencies.
  • Update README with Postgres docs, examples, prerequisites, test instructions. Updated links, descriptions.
  • Bump version, add pg to devDeps, new test script and test/npm-postgres.js covering edge cases (zombie, errors, CRON, autoClear, destroy, multiple task types).
  • Fix weak points: better error handling in new adapter, consistent types across TS/JS/docs, added test for uncovered cases like onExecuted with errors, short delays via revolving.
  • Minor: updated package descriptions, Meteor package version.

v5.0.0

10 Apr 22:47
5ad66b1

Choose a tag to compare

📦 NPM @5.0.0
☄️ Packosphere @5.0.0

What's New

  • 🦄 async/await API for all public methods
  • 🚀 Return {Promise} from tasks instead of calling ready()

Major Changes

  • ⚠️ Drop support for callbacks
  • ⚠️ Renamed private methods for clarity
  • ⚠️ Renamed methods of "Adapter" API for clarity
  • ⚠️ opts.adapter now expects instance of the StorageAdapter, was: Class of StorageAdapter
  • ⚠️ Moved opts.prefix and opts.resetOnInit to StorageAdapter's constructor
  • ⚠️ Moved storage-related options opts.client, opts.db, and lockCollectionName to StorageAdapter's constructor

Changes

  • ✨ New options {object} accepted by new RedisAdapter({})
  • ✨ New options {object} accepted by new MongoAdapter({})
  • 👨‍🔬 Refactored tests for the new async/await API
  • 👨‍🔬 Refactored Meteor.js test-suite for the new async/await API
  • 📔 Updated documentation
  • 📔 Updated custom adapter documentation

v4 to v5 migration

Although setInterval and setTimeout now return {Promise} instead of {String} updated clearInterval and clearTimeout methods accept {Promise}, so migration might not be necessary. Next block of code will remain operational in v3/v4 and v5:

const taskId = job.setInterval((ready) => {
  /* code here */
  ready();
}, 2048, 'task-2048ms');

job.clearInterval(taskId);

Migration is necessary only if callbacks of clearInterval and clearTimeout were used. Callbacks need to get replaced by await. setInterval and setTimeout will require using await to obtain timerId.

was in v3/v4:

const taskId = job.setInterval((ready) => {
  /* code here */
  ready();
}, 2048, 'task-2048ms');

job.clearInterval(taskId, () => {
  // task cleared now
});

change to for v5:

const taskId = await job.setInterval((ready) => {
  /* code here */
  ready();
}, 2048, 'task-2048ms');

await job.clearInterval(taskId);
// task cleared now

Now it's possible to return promises, previously ready() was required to call in v3/v4:

job.setInterval((ready) => {
  /* code here */
  ready();
}, 2048, 'task-2048ms');

now simply register async function in v5:

job.setInterval(async () => {
  /* code here */
}, 2048, 'task-2048ms');

or simply return promise in v5:

job.setInterval(() => {
  /* code here */
  return promisedValue; // instance of the Promise
}, 2048, 'task-2048ms');

or async/await the promise in v5:

job.setInterval(async () => {
  /* code here */
  return await promisedValue;
}, 2048, 'task-2048ms');

now calling ready() inside async function will not work in v5:

job.setInterval(async (ready) => {
  /* code here */
  ready(); // <-- won't run, will log a debug message here
}, 2048, 'task-2048ms');

v4.1.0

08 Apr 21:57
3abac04

Choose a tag to compare

📦 NPM @4.1.0
☄️ Packosphere @4.1.0

What's new

  • ✨ Added async .ping() method

v4.0.0

04 Apr 23:16
bbdd279

Choose a tag to compare

📦 NPM @4.0.0
☄️ Packosphere @4.0.0

Major Changes:

  • ⚠️ New way to import and require the package import { JoSk, RedisAdapter, MongoAdapter } from 'josk';
  • ⚠️ Decouple from storage, requires changes in options passed to constructor new JoSk({})
  • 🟥 Added support for Redis as adapter 🥳
  • 🍃 MongoDB as optional adapter 🥳

Changes:

  • 🟥 Added support for Redis, well tested with Redis.io and KeyDB
  • 👨‍💻 Decoupled storage from main codebase
  • ✨ Support for custom storage adapters, see custom adapter documentation
  • opts.adapter {RedisAdapter|MongoAdapter}
  • opts.client {RedisClient}
  • 👨‍🔬 Added tests for Redis
  • 👨‍🔬 Added tests for Redis within Meteor.js
  • 📔 Updated documentation
  • 📔 Created documentation for custom adapter

Dev Dependencies:

  • 📦 chai@5.1.0, was v4.4.1
  • 📦 mocha@10.4.0, was v10.3.0
  • 📦 Added redis@4.6.13

v3.1.1

02 Apr 19:33
0296a0c

Choose a tag to compare

📦 NPM @3.1.1
☄️ Packosphere @3.1.1

Major Changes:

  • 👨‍🔧 Fix #16 — CommonJS compatibility

Changes:

  • 🤝 Compatibility with ESM and CommonJS import/export, thanks to @masterbater for reporting the issue #16

Dev Dependencies:

  • 📦 bson@6.6.0, was v6.3.0
  • 📦 Removed rudiment dependency pathval, was v2.0.0

v3.1.0

01 Apr 00:22
a0ba80e

Choose a tag to compare

📦 NPM @3.1.0
☄️ Meteor.js @3.1.0

Major Changes:

  • ⚠️ Minimal required version of Node.js now is @>=14.20.0, was @>=8.9.0
  • 📦 Packaged as ES Module

Changes:

  • 🤝 Compatibility with mongod server, tested with @4.4.29, @5.0.25, @6.0.14, and @7.0.6
  • 🤝 Compatibility with mongodb driver for node.js, tested with @4.17.2, @5.9.2, and @6.5.0
  • 🤝 Compatibility with the latest nodejs releases, tested with @14.21.3, @18.19.1, @20.11.1, and @21.7.1
  • 🤝 Compatibility with the latest Meteor.js and its packages
  • 🤝 Compatibility with upcoming meteor@3.0.0 and its packages

Dev Dependencies:

  • 📦 bson@6.3.0, was v4.6.1
  • 📦 bson-ext@4.0.3, was v4.0.2
  • 📦 chai@4.4.1, was v4.3.6
  • 📦 cron-parser@4.9.0, was v4.5.0
  • 📦 mocha@10.3.0, was v10.0.0
  • 📦 mongodb@6.5.0, was v4.7.0
  • 📦 pathval@2.0.0, was v1.1.1

v3.0.2

03 Jul 12:00
a77c44a

Choose a tag to compare

  • 👨‍💻 Refactor locking mechanism to avoid dead-locking and minimize DB/Collection locking operations
  • 📔 Update documentation
  • 📦 Run tests with cron-parser@4.5.0
  • 👷‍♂️ Create .meteorignore

v3.0.1

10 Jun 12:18
88c4ce4

Choose a tag to compare

  • 👨‍💻 Make sure call-check-loop spins even on rare MongoDB errors
  • 🤝 Support meteor@2.7.3

Dependencies:

Development packages used for testing

  • 📦 [dev] bson@4.6.4, was v4.6.3
  • 📦 [dev] mongodb@4.7.0, was v4.6.0

v3.0.0

13 May 04:35
51ff340

Choose a tag to compare

📦 v3.0.0

Now ☄️ meteor and 📦 NPM follow the same versioning pattern. In this release we have added couple of new features and improved existing codebase.

New features:

  • opts.lockCollectionNamenew JoSk() constructor option
  • opts.debugnew JoSk() constructor option
  • 👨‍💻 ready() — Function passed as an argument to a scheduled task now accepts a callback, see CRON usage example
  • 👨‍💻 JoSk#clearTimeout() and JoSk#clearInterval() — Methods now accept callback as a last argument

Major changes:

  • 👷‍♂️ Now all JoSk instances share the same *.lock collection, this behavior can get changed using opts.lockCollectionName constructor option

Other changes:

  • 📔 Add examples for CRON instructions usage
  • 👨‍🔬 Improve test-cases coverage to 97%
  • 👨‍💻 Overall codebase refactoring and performance improvements
  • 🤝 Compatibility and support of mongod@5.0.8 (Mongo Database)
  • 🤝 Compatibility and support of mongodb@4.6.0 (MongoDB node.js driver)
  • 🤝 Compatibility ans support of meteor@2.7.1

Dependencies:

  • 📦 [dev] mongodb@4.6.0, was v4.5.0
  • 📦 [dev] added cron-parser@4.4.0 for CRON tasks tests