New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@time-provider/addon-cron

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@time-provider/addon-cron

Cron scheduling addon for Time-Provider. Inject time. Control it in tests.

latest
Source
npmnpm
Version
0.5.0
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

NPM jsr jsr score types Node.js ^18.18 || >=20.4 Deno ~1.39.1 || >=1.43 module ESM + CJS CodeQL check codecov npm downloads dependencies unpacked-size minified size openssf best practices license

Time-Provider ~ Cron Addon

Time-Provider

Description

This is the cron scheduling addon for Time-Provider.
Extends the library with a scheduler.cron facade that runs a callback on a schedule described by a standard 5-field cron expression (minute hour day-of-month month day-of-week), evaluated in the runtime's own local timezone.

The expression parser and next-occurrence calculator are hand-rolled, with zero runtime dependencies. It supports *, single values, a-b ranges, .../n steps and comma-separated lists on every field, the usual 3-letter month/day names (JAN-DEC, SUN-SAT, case-insensitive), the 7 Sunday alias, and the POSIX quirk where a match on either day-of-month or day-of-week counts when both are restricted. It does not support seconds, or the L/W/# special characters some cron implementations add.

Just like the plugin packages, this addon is tree-shakable.
It is split into a default (system/real-time) entry point and a deterministic one, so each import pulls in only the code it needs:

  • @time-provider/addon-cron - for a system (real time) Time-Provider created via @time-provider/core. Schedules run on real native timers.
  • @time-provider/addon-cron/deterministic - for a deterministic Time-Provider (fixed/manual/sequential) created via @time-provider/core/deterministic. Schedules run against that runtime's own simulated clock.

Usage

import { createTimeProvider } from "@time-provider/core";
import { createTimeProvider as createDeterministicTimeProvider } from "@time-provider/core/deterministic";
import { plugin } from "@time-provider/plugin-native";
import { plugin as deterministicPlugin } from "@time-provider/plugin-native/deterministic";
import { addon } from "@time-provider/addon-cron";
import { addon as deterministicAddon } from "@time-provider/addon-cron/deterministic";

// System: runs on real native timers, in the runtime's local timezone.
const timeProvider = createTimeProvider
  .for(plugin)
  .use(addon)
  .withTimezone("Europe/Paris")
  .create();
const handle = timeProvider.scheduler.cron.schedule("0 9 * * MON-FRI", () =>
  console.log("Good morning!"),
);
// ...
handle.dispose();

// Deterministic: runs against the runtime's own simulated clock.
using manual = createDeterministicTimeProvider
  .for(deterministicPlugin)
  .use(deterministicAddon)
  .asManual()
  .withInitialTime("2024-01-01T00:00:00.000Z")
  .create();
using handle = manual.scheduler.cron.schedule("*/15 * * * *", () =>
  console.log("Every 15 minutes"),
);
manual.clock.moveBy({ minutes: 15 });

JSON schedules

schedule also accepts a JSON ICronSpec instead of a cron expression string, for callers who'd rather avoid the positional/symbolic syntax. Each field (minute, hour, dayOfMonth, month, dayOfWeek) defaults to every value when omitted, and otherwise accepts a number, a numeric string (e.g. "9"), a name (e.g. "JAN", "MON"), a { from, to, step? } range, or an array mixing any of those. month and dayOfWeek only accept their own names - giving a day-of-week name to hour, or a month name to dayOfWeek, is a compile-time type error, not just a runtime one:

timeProvider.scheduler.cron.schedule({ hour: 9, dayOfWeek: ["MON", "WED", "FRI"] }, () =>
  console.log("Good morning!"),
);

timeProvider.scheduler.cron.schedule({ minute: { from: 0, to: 45, step: 15 } }, () =>
  console.log("Every 15 minutes"),
);

Timezones and callbacks that throw

Schedules are read in the runtime's own local timezone, captured when schedule() is called - so a schedule created after clock.withTimezone(...) uses the new timezone, while one already running keeps the timezone it started with. Wall-clock times that a DST transition skips resolve to the first instant past the gap, and ones it repeats resolve to the earlier of the two.

A cron callback is an ordinary timer callback, so one that throws follows the runtime's usual rule (see ITimers): the exception propagates in a Node-like environment, and is logged in a browser-like one. Either way that schedule stops, exactly as a recurring timer callback that throws does - catch inside your own callback if a failing run shouldn't end the job.

License

MIT

Keywords

clock

FAQs

Package last updated on 28 Sep 2026

Related posts