From 6527fb6729405a13ec6c43511048e6cd6e1f694a Mon Sep 17 00:00:00 2001 From: Shinrai Date: Sat, 3 Oct 2026 19:28:00 -0700 Subject: [PATCH 1/2] docs: add v2.0.5 release changelog and promote it in What's New Covers #55 (task-level postDelay/startDelay, deprecated delay/start aliases, delay-gate fix), #56 (callback failures without an error listener), #57 (invalid-priority warning), #59 (regression tests for #52) and #50 (README restructure). --- README.md | 10 +++--- docs/changelog/v2/v2.0.5.md | 63 +++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 docs/changelog/v2/v2.0.5.md diff --git a/README.md b/README.md index 5e2f089..958b9cc 100644 --- a/README.md +++ b/README.md @@ -16,18 +16,18 @@ Use it with callbacks or promises, from ESM or CommonJS, with full TypeScript de ## ✨ What's New -### Latest: v2.0.4 (October 2026) +### Latest: v2.0.5 (October 2026) -- **Clearer `require()` failure on older Node.js** — The CommonJS entry now throws an `ERR_REQUIRE_ESM` error that names the supported Node.js versions (`^20.19.0` or `>=22.12.0`) and points to `import()`, instead of a bare error on versions without `require(esm)`. Behavior on supported versions is unchanged. -- **Security patch for development tooling** — Updates `brace-expansion` to 5.0.12, fixing [GHSA-q2hr-2g5m-vwhr](https://github.com/advisories/GHSA-q2hr-2g5m-vwhr), a quadratic-time denial of service in a development-only dependency pulled in by `minimatch`. `@eslint/css` moves to 2.0.0 and `prettier` to 3.9.9. -- [View full v2.0.4 Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.4.md) +- **Task-level `postDelay` / `startDelay` work as documented** — `enqueue()` now honors the documented `postDelay` and `startDelay` task options, and a task-level completion delay is enforced even when the task's priority has no `postDelay` of its own. The old `delay` / `start` names still work as deprecated aliases and emit one `deprecation` warning per queue instance. +- **Safer failure reporting** — A failing callback-style task no longer crashes the process when no `error` listener is attached; the failure always reaches the callback, and the `error` event is emitted only when someone listens. Non-integer `priorities` keys now produce an `invalid-priority` warning instead of being dropped silently. The README was rewritten to the CLDMV layout with every example on the current API. +- [View full v2.0.5 Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.5.md) ### Recent Releases +- **v2.0.4** (October 2026) — Clearer `require()` error on Node.js without `require(esm)`; `brace-expansion` security patch in development tooling ([Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.4.md)) - **v2.0.3** (October 2026) — Development toolchain moves to vitest 5; bundle-size and v4 workflow updates; verbatim Apache-2.0 license text ([Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.3.md)) - **v2.0.2** (September 2026) — Development dependency update (`@humanfs/node`); no other changes ([Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.2.md)) - **v2.0.1** (September 2026) — Fix: a task's timeout timer is now cleared when the task fails or is cancelled ([Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.1.md)) -- **v2.0.0** (August 2026) — `HoldMyTask` and its aliases are the real class again (breaking for code adapted to v1.6.1's factories); scheduler deadlock fix; `holdmytask-dev` export condition ([Changelog](https://github.com/CLDMV/holdmytask/blob/master/docs/changelog/v2/v2.0.0.md)) 📚 **For complete version history and detailed release notes, see the [docs/changelog/](https://github.com/CLDMV/holdmytask/tree/master/docs/changelog/) folder.** diff --git a/docs/changelog/v2/v2.0.5.md b/docs/changelog/v2/v2.0.5.md new file mode 100644 index 0000000..71d5066 --- /dev/null +++ b/docs/changelog/v2/v2.0.5.md @@ -0,0 +1,63 @@ +# HoldMyTask v2.0.5 Changelog + +**Release Date**: October 2026 +**Release Type**: Patch +**Branch**: `release/2.0.5` + +--- + +## Overview + +v2.0.5 fixes three long-standing problems in how the queue reads its options and reports failures. The documented task-level `postDelay` / `startDelay` options now actually work (the old `delay` / `start` names become deprecated aliases), a callback-style task failure no longer crashes the process when no `error` listener is attached, and a `priorities` key that is not an integer is now reported instead of being dropped silently. The README was rewritten to the CLDMV layout and every example now uses the current API. + +Runtime behavior changes in a few observable ways, all described below: code that still passes `delay` or `start` to `enqueue()` now receives a deprecation `warning` event, a task-level completion delay is now enforced even when the task's priority has no `postDelay` of its own, a callback-style task failure is no longer thrown as an unhandled `error` event, and a non-integer priority key now produces an `invalid-priority` warning. No option was removed and no exported signature changed. + +--- + +## 🐛 Bug Fixes + +### Task-level `postDelay` / `startDelay` are honored; `delay` / `start` are deprecated aliases ([#55](https://github.com/CLDMV/holdmytask/pull/55)) + +`enqueue()` only read the task-level `delay` and `start` options, although its JSDoc already pointed at `postDelay`. Passing the documented name gave no delay at all. `enqueue()` now treats `postDelay` and `startDelay` as the current task-level names, matching the names already used in `priorities`, `coalescing.defaults` and `coalescing.keys`. `delay` and `start` still work and map onto the new names; when both forms are given, the current name wins. `postDelay: -1` bypasses an active delay period exactly as `delay: -1` did, and the caller's options object is never mutated. `getPriorityConfig()` and `getCoalescingConfig()` accept both names in their `taskOptions` argument. + +**New warning:** each deprecated task-level alias now emits a `warning` event of type `"deprecation"` (with `deprecated` and `replacement` fields), in the same shape the priority and coalescing levels already used. The warning fires once per alias per queue instance, not once per task, so a hot enqueue path does not flood listeners. No warning is emitted when the replacement name is also present. + +**Scheduler fix:** the delay gate between tasks used to require the completed task's _priority_ to have a positive `postDelay`. A task-level completion delay on a priority without one was recorded but never enforced, which was true of the old `delay` name as well. The gate now relies on the computed next-available time alone, so a task-level `postDelay` (or `delay`) takes effect regardless of the priority's configuration. Code that relied on a task-level delay being ignored in that situation will now see the delay applied. Closes [#51](https://github.com/CLDMV/holdmytask/issues/51). + +### Callback-style task failures no longer require an `error` listener ([#56](https://github.com/CLDMV/holdmytask/pull/56)) + +When a callback-style task failed, timed out, was aborted or expired, the queue emitted `error`. `HoldMyTask` is an `EventEmitter`, so with no `error` listener that emit threw: the process crashed (an unhandled rejection for failures, an uncaught exception from the scheduler for expiry), and for failures the task's callback never ran. Task-failure `error` events are now emitted only when at least one `error` listener is attached. The failure always reaches the task's callback with the documented payload (`{ type: "error", error }`, `{ type: "timeout", message }`, `{ type: "canceled", message: "Task was aborted" }`, or the expiry error). + +Listeners that are attached see the same events as before. The difference is for queues without one: a callback task failure is no longer thrown. An error thrown by the callback itself is still emitted unconditionally, so a bug inside a callback is not silently swallowed, and the `error` events for invalid `enqueue()` arguments and rejected `configurePriority()` / `configureCoalescingKey()` input are unchanged. Promise-style tasks are unchanged and report failures only through the rejected promise. Closes [#53](https://github.com/CLDMV/holdmytask/issues/53). + +### Non-integer priority keys are reported instead of dropped silently ([#57](https://github.com/CLDMV/holdmytask/pull/57)) + +The constructor ran `priorities` (and the deprecated `delays`) keys through `parseInt` and discarded anything that came back `NaN`, so a config such as `priorities: { high: { postDelay: 100 } }` did nothing, and a key such as `"2.5"` was truncated without notice. Any non-integer key now emits a `warning` event of type `"invalid-priority"` with `message`, `option` (`"priorities"` or `"delays"`), `key` and `priority` fields. A key that cannot be read as a number is still ignored (`priority: null`); a fractional key keeps its historical meaning, the truncated priority, but is reported. Integer keys, including negative ones, are unaffected. The constructor still never throws for configuration, so a config that constructed fine on v2.0.4 still constructs fine. Closes [#54](https://github.com/CLDMV/holdmytask/issues/54). + +--- + +## 🧪 Tests + +- New suites: `TaskLevelDelayNames` ([#55](https://github.com/CLDMV/holdmytask/pull/55)), `CallbackErrorWithoutListener` ([#56](https://github.com/CLDMV/holdmytask/pull/56)) and `PriorityKeyValidation` ([#57](https://github.com/CLDMV/holdmytask/pull/57)). +- `PostDelayAfterAwait` ([#59](https://github.com/CLDMV/holdmytask/pull/59)) adds deterministic fake-timer coverage for `postDelay` when the next task is enqueued after awaiting the previous one: promise API after `await`, promise API in the resolving microtask, and callback API enqueuing from the completion callback, in both smart-scheduling and polling modes. All cases pass on the current code; the report in [#52](https://github.com/CLDMV/holdmytask/issues/52) could not be reproduced, and the issue is closed with these tests as regression coverage. + +## 📚 Documentation + +- The README was restructured to the CLDMV layout and every example was updated from deprecated option names to the current API ([#50](https://github.com/CLDMV/holdmytask/pull/50)). It now documents the task-level `postDelay` / `startDelay` options, the optional `error` listener for callback-style tasks, both `warning` event types (`deprecation` and `invalid-priority`), and a table of every deprecated option with its replacement. +- The JSDoc and generated `types/` declarations for `enqueue()` list `postDelay` and `startDelay`, with `delay` and `start` marked deprecated. +- **NEW:** [docs/changelog/v2/v2.0.5.md](./v2.0.5.md) — this changelog. + +## 🔧 Dependencies + +_No dependency updates_ + +--- + +## Upgrade notes + +No breaking API changes — drop-in for [v2.0.4](./v2.0.4.md), with these behavior differences to check: + +- Replace task-level `delay` with `postDelay` and `start` with `startDelay` in `enqueue()` calls. The old names keep working, but each emits one `deprecation` warning per queue instance. +- A task-level `postDelay` (or `delay`) is now enforced even when the task's priority has no `postDelay`. If a queue depended on that delay being ignored, remove it from the task options. +- A callback-style task failure is no longer thrown when no `error` listener is attached; handle failures in the task callback, or attach an `error` listener if the queue-level event is wanted. +- Check `priorities` / `delays` configs for non-integer keys. They behave as before, but now emit an `invalid-priority` warning. From 8342f42a2eeafd09dfb6b1c57a7f59e3b1c3490f Mon Sep 17 00:00:00 2001 From: Shinrai Date: Sat, 3 Oct 2026 20:35:22 -0700 Subject: [PATCH 2/2] docs: list the fix-headers 2.1.4 bump (#61) in the v2.0.5 notes --- docs/changelog/v2/v2.0.5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog/v2/v2.0.5.md b/docs/changelog/v2/v2.0.5.md index 71d5066..9617832 100644 --- a/docs/changelog/v2/v2.0.5.md +++ b/docs/changelog/v2/v2.0.5.md @@ -49,7 +49,7 @@ The constructor ran `priorities` (and the deprecated `delays`) keys through `par ## 🔧 Dependencies -_No dependency updates_ +- `@cldmv/fix-headers` (dev dependency) `^2.1.1` → `^2.1.4` ([#61](https://github.com/CLDMV/holdmytask/pull/61)). Version 2.1.4 no longer writes a JavaScript comment into JSON or Markdown files, processes every repeated `--input`, and never walks dependency folders such as `node_modules`. Only `package.json` and the lockfile changed; no file headers were restamped and the published package is unaffected. ---