Skip to content

Release notes

Eugene Lazutkin edited this page May 7, 2026 · 2 revisions

Release Notes

1.4.0

Bare import 'time-queues' now works at runtime — added an index.js barrel and a "." entry in package.json#exports. New Scheduler.onError hook and MicroTask.cancelError for richer task lifecycle control. Several user-observable bug fixes. Adopted js-check (dual-tsconfig pattern) for unused-vars / undeclared-refs / control-flow checks without ESLint's transitive-dep cost.

New API surface

  • Bare imports: import * as pkg from 'time-queues'; (or import {sleep, Scheduler, ...} from 'time-queues';) now resolves at runtime. Subpath imports (time-queues/sleep.js etc.) continue to work unchanged.
  • Scheduler.onError: optional callback (error, task) => void invoked when a scheduled task.fn throws. Default null; if unset, exceptions surface via unhandled rejection. Either way, the scheduler loop continues — one failing task no longer stalls the rest.
  • MicroTask.cancelError: read-only getter exposing the error supplied to the first cancel(error) call, or null. Useful for inspecting why a non-promised task was canceled.
  • MicroTask cancel/resolve hardening: resolve() now throws if called before makePromise() (was a silent no-op that hung subscribers). cancel(error) stores the error and replays it on a later makePromise() — the freshly-created promise settles immediately as CancelTaskError(cause: error).

Bug fixes

  • whenLoaded.remove(fn) and whenDomLoaded.remove(fn): actual list-toolkit method is getNodeIterator, not getNodeIterable — both functions previously crashed at runtime.
  • Scheduler.repeat(0): no longer infinite-loops the scheduler. Next-delay computation clamps to ≥1ms.
  • PageWatcher: can be safely imported in Node now. The module-level singleton's getState() previously crashed with ReferenceError: document is not defined outside DOM.
  • Retainer.get() race: concurrent get() calls before the first create() resolves now share the same in-flight promise — create() runs at most once per zero-counter interval.
  • Retainer.release(): deferred destroy errors no longer silently swallowed; surface as standard unhandled rejection events (consistent with the immediately path).
  • random-dist.normal() skewness: skew-normal computation now uses two N(0,1) samples (the second from Box-Muller's sin arm) instead of mixing the uniform v. The previous output didn't correspond to a recognized statistical distribution.

Tooling

  • js-check adopted via tsconfig.check.json + npm run js-check script (also wired into CI). 30 → 0 errors after fixing the typo bugs and tightening sidecars.
  • Fleet alignment: HTTPS submodule URLs, CI Node matrix [22, 24, 26], engines.node: ">=22", paired .claude/commands/ workflow files, tuned .github/dependabot.yml (grouped + versioning-strategy: increase-if-necessary).
  • JSDoc stripped from .js source files; // @ts-self-types directives in place. .d.ts is the sole source of truth for types + docs.

.d.ts tightening

  • ListQueue.list: List<MicroTask> and Scheduler.queue: MinHeap<Task> fields now declared (instance fields visible to consumers).
  • Retainer.value is now readonly.
  • Counter.notify() method declared (called by setter / increment / decrement / advance — and by user when mutating count directly).
  • processTasks() declared on FrameQueue, IdleQueue, Scheduler (the timer callbacks).
  • Internal handles privatized (Throttler.#handle, Retainer.#handle, Retainer.#creating).
  • LimitedQueue.wrap static helper → module-private function.
  • MicroTaskQueue.returnArgs static → module-private.

Refactor

  • Hoisted _drainBatch(batchMs, taskContext) helper to ListQueue; FrameQueue and IdleQueue share it (-32 lines across the two subclasses).
  • MicroTaskQueue.schedule() argument shadowing cleaned up (outer scheduleArgs, inner invocationArgs).

Tests

  • 103 → 112 tests; 668 → 733 asserts cross-runtime (Node, Bun, Deno).
  • New tests for: bare-import barrel surface, Counter.notify() direct-mutation flow, Retainer concurrent gets, Scheduler.repeat(0) clamp, Scheduler onError handling, MicroTask resolve/cancel error paths.

Documentation

  • Wiki: refreshed Scheduler, MicroTask, Retainer, Throttler pages for the new API surface and the pacing-vs-throttle reframing on Throttler (rate-limiting / pacing semantics, not classical throttle — every call is honored, none are dropped).
  • ARCHITECTURE.md: updated for new structures and helpers.
  • llms.txt / llms-full.txt: regenerated against current API.

1.3.2

Bug fixes, improved TypeScript declarations, expanded test coverage, and documentation corrections.

Bug fixes

  • Scheduler: processTasks() now skips canceled tasks instead of executing them.
  • Scheduler: dequeue() guards against already-removed tasks.
  • Scheduler: repeat() stops re-enqueueing when task.isCanceled is set.
  • LimitedQueue: Constructor now validates the limit parameter (applies Math.max(1, limit)).
  • PageWatcher: pause() no longer calls dead super.pause() path; event listeners are removed correctly.
  • PageWatcher: clear() now cancels tasks like ListQueue does.
  • Retainer: release() wraps destroy() in try/catch to prevent unhandled rejections.

TypeScript declarations

  • LimitedQueue.d.ts: enqueue and schedule callbacks now correctly include {task, queue} argument.
  • Various .d.ts files refined for accuracy: Scheduler, FrameQueue, IdleQueue, ListQueue, MicroTask, MicroTaskQueue, PageWatcher, Throttler, Counter, index, random-dist, random-sleep.

Tests

  • Added CommonJS test (test-cjs.cjs).
  • Added many new unit tests for Counter, LimitedQueue, ListQueue, Retainer, Scheduler, Throttler, random-dist.
  • Added TypeScript typing tests for CancelTaskError, MicroTask, LimitedQueue, and browser types.

Documentation

  • Fixed ARCHITECTURE.md: corrected whenDomLoaded/whenLoaded export descriptions, fixed GitHub URLs.
  • Fixed wiki/whenLoaded().md: corrected description (page load, not DOM load).
  • Fixed wiki/Counter.md: removed incorrect LimitedQueue/Counter association.
  • Updated wiki/Scheduler.md: documented repeat() cancellation behavior.
  • Updated file layout in AGENTS.md and rule files to include .mjs/.cjs test patterns.

Clone this wiki locally