Releases: veliovgroup/josk
v6.1.0
📦 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.RedisAdapterprefix: stricter validation —{,}, other specials rejected (Cluster-safe).
New
RedisAdapter({ useHashTags: true })— Redis Cluster / KeyDB Cluster: keysjosk:{prefix}:*(one slot). Defaultfalse— standalone keysjosk:prefix:*unchanged.- Migration guide: docs/migration-v6-v6.1.md
Fixes / hardening
- Removed/cleared tasks: skip execution if task gone mid-flight; no spurious
onExecutedwhenremove()fails onsetTimeout/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
📦 NPM @6.0.0
☄️ Packosphere @6.0.0
What's New
- 🤝 TS fully typed, thanks to @climba03003
- 🐘 Postgres Transport
- ✨ Atomic operations
- ✨
executemode —oneorbatch - ✨ Now locks and active tasks has owners
- 🥟 Bun.js compatibility
- ☄️
meteor@3.4compatibility - 🛢️ 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 nownode >=20.9.0andbun >=1.1.0. Users on older Node should stay onjosk@5.⚠️ Default prefix is nowdefaultfor all drivers, fallback to''(empty string) to preserve old behavior.⚠️ Adapters must define/check owners on locks.
v4 to v5 migration
MongoAdapterpreviously 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, passprefix: ''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^5and switch fromparser.parseExpression(...)toCronExpressionParser.parse(...).
RAW CHANGELOG
- Breaking: drop Node 14/16/18 support. Engines now
node >=20.9.0andbun >=1.1.0. Users on older Node should stay onjosk@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/globalson Node andbun:teston Bun via a conditional dynamic import, so the same suite runs under both runners. Newnpm run test:bunscript (bun test ./test/jest/) and atest-bunjob 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@^4andredis@^5. Dev pin updated toredis@^5.12.1. CI matrix runs each Node/Bun job against both driver majors. - Switch internal random IDs (
lockOwnerId, lease tokens) tocrypto.randomUUID(). - Auto-call
ready()for sync handlers declared with noreadyparameter (func.length === 0). Handlers that declarereadybut never call it continue to zombie-recover, with a debug log to ease diagnosis. - New
concurrencyoption onJoSkcaps the number of handlers running in parallel inside one instance. DefaultInfinity. - Fix
__tickjitter range — interval now spans[minRevolvingDelay, maxRevolvingDelay]instead of[minRevolvingDelay, minRevolvingDelay + maxRevolvingDelay]. - Postgres adapter: lock acquisition compares against
CURRENT_TIMESTAMPon the server side, removing client-clock-skew sensitivity. Migrations are gated by ajosk_meta.schema_versionrow and no longer touch lock rows from other prefixes on every startup. Removed leftover__customPrivateMethod. - Mongo adapter:
updateusesmatchedCountinstead ofmodifiedCountto avoid false negatives when the new timestamp coincides with the stored one.releaseLockerrors now flow throughonErrorlike Redis/Postgres. Default prefix is now'default'. - Redis adapter: cache Lua scripts via
SCRIPT LOAD+EVALSHA(falls back toEVALonNOSCRIPTor 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
mongodbdriver. Other Mongo-compatible clients are not supported. - TypeScript: post-process
tscoutput viascripts/strip-internal.mjsto truly strip@internalmembers (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.ctsfrom a small.ctsshim (index.cts) instead ofcp 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/JoSkOnExecutedto returnPromise<void>. Add positive type tests that built-in adapters conform toJoSkAdapter. - 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
maxRevolvingDelayinstead of hardcoded±256ms. Migrated CRON examples tocron-parser@^5(CronExpressionParser.parse(...)). - GitHub Actions workflow added that runs Jest + Mocha live suites across Node 20/22/24 (and the
test-bunjob underbun@latest) with Redis, MongoDB, and PostgreSQL service containers; uploads coverage on Node 22 / redis@5. - AGENTS.md: fix test script names (
test:redisetc., nottest-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.4release 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 atomicfindOneAndUpdate. - 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
executeoption toJoSk:oneorbatch. Defaultbatchfor backward-compatible throughput.oneclaims/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, usespgPool/Client. - Improve TypeScript definitions: added
Adapterinterface, madeadapterrequired inJoSkOption, fixed return types, JSDoc, updated.d.ts/.d.ctsfor all adapters including Postgres. Reduced inconsistencies. - Update README with Postgres docs, examples, prerequisites, test instructions. Updated links, descriptions.
- Bump version, add
pgto devDeps, new test script andtest/npm-postgres.jscovering 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
📦 NPM @5.0.0
☄️ Packosphere @5.0.0
What's New
- 🦄
async/awaitAPI 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.adapternow expects instance of the StorageAdapter, was: Class of StorageAdapter⚠️ Movedopts.prefixandopts.resetOnInitto StorageAdapter's constructor⚠️ Moved storage-related optionsopts.client,opts.db, andlockCollectionNameto 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 nowNow 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
v4.0.0
📦 NPM @4.0.0
☄️ Packosphere @4.0.0
Major Changes:
⚠️ New way toimportandrequirethe packageimport { JoSk, RedisAdapter, MongoAdapter } from 'josk';⚠️ Decouple from storage, requires changes in options passed to constructornew 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, wasv4.4.1 - 📦
mocha@10.4.0, wasv10.3.0 - 📦 Added
redis@4.6.13
v3.1.1
v3.1.0
📦 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
mongodserver, tested with@4.4.29,@5.0.25,@6.0.14, and@7.0.6 - 🤝 Compatibility with
mongodbdriver for node.js, tested with@4.17.2,@5.9.2, and@6.5.0 - 🤝 Compatibility with the latest
nodejsreleases, 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.0and its packages
Dev Dependencies:
- 📦
bson@6.3.0, wasv4.6.1 - 📦
bson-ext@4.0.3, wasv4.0.2 - 📦
chai@4.4.1, wasv4.3.6 - 📦
cron-parser@4.9.0, wasv4.5.0 - 📦
mocha@10.3.0, wasv10.0.0 - 📦
mongodb@6.5.0, wasv4.7.0 - 📦
pathval@2.0.0, wasv1.1.1
v3.0.2
- 👨💻 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
- 👨💻 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, wasv4.6.3 - 📦
[dev]mongodb@4.7.0, wasv4.6.0
v3.0.0
📦 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.lockCollectionName—new JoSk()constructor option - ✨
opts.debug—new JoSk()constructor option - 👨💻
ready()— Function passed as an argument to a scheduled task now accepts a callback, see CRON usage example - 👨💻
JoSk#clearTimeout()andJoSk#clearInterval()— Methods now accept callback as a last argument
Major changes:
- 👷♂️ Now all JoSk instances share the same
*.lockcollection, this behavior can get changed usingopts.lockCollectionNameconstructor 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, wasv4.5.0 - 📦
[dev]addedcron-parser@4.4.0for CRON tasks tests