Schedule@rhythmjs/schedule
API reference
Every export across the four subpaths: job factories and the service on the root, the shared types, the Cron engine on /cron, and startScheduler on /scheduler.
On this page
@rhythmjs/schedule#
function cronJob(name: string, schedule: string, handler: JobHandler, options?: JobOptions): ScheduleJob;
function intervalJob(name: string, ms: number, handler: JobHandler, options?: JobOptions): ScheduleJob;
function timeoutJob(name: string, ms: number, handler: JobHandler, options?: JobOptions): ScheduleJob;Job factories. Each validates that handler is a function and freezes the options into the job value: timezone is kept only when given, overlap defaults to "skip", disabled to false.
const cronPatterns: {
everySecond: "* * * * * *"; everyMinute: "* * * * *";
every5Minutes: "*/5 * * * *"; every10Minutes: "*/10 * * * *";
every30Minutes: "*/30 * * * *"; hourly: "0 * * * *";
daily: "0 0 * * *"; weekly: "0 0 * * 0";
monthly: "0 0 1 * *"; yearly: "0 0 1 1 *";
};function createScheduleService(...jobs: ScheduleJob[]): ScheduleService;Builds the registry and state map. Throws on duplicate job names; every service method that takes a name throws unknown job "name" for unregistered names.
const scheduleModule: {
forRoot(...jobs: ScheduleJob[]): Rhythm<...>; // context: { scheduleService }
};All types below are re-exported from the root as well.
ScheduleService#
interface ScheduleService {
readonly jobs: readonly ScheduleJob[];
add(job: ScheduleJob): void;
remove(name: string): void;
run(name: string): Promise<JobRunResult>;
runDue(date?: Date): Promise<JobRunResult[]>;
nextRun(name: string, from?: Date): Date | null;
state(name: string): JobState;
}run(name)#- Executes one job now. Returns
{ name, ran: false }when the job is disabled, or already running withoverlap: "skip". Otherwise runs the handler, recordslastRunandruns, captures a thrown error's message intolastErrorand the result, and always reportsdurationMs(rounded). runDue(date?)#- For every enabled cron job, computes the occurrence in the minute containing
date(default now) and runs the job when that occurrence falls at or beforedate. Returns the results in registry order. nextRun(name, from?)#- The next occurrence of a cron job strictly after
from(default now);nullfor interval and timeout jobs, or when the pattern can never occur again. state(name)#{ running, runs, lastRun?, lastError? }plusnextRunfor cron jobs.lastErrorclears on the next successful run.add(job) / remove(name) / jobs#- Dynamic registry.
addthrows on duplicates;removethrows on unknown names, and a running scheduler's timer for a removed job cancels itself on its next fire;jobsreturns a fresh array.
@rhythmjs/schedule/types#
JobHandler#() => void | Promise<void>.JobKind#"cron" | "interval" | "timeout".OverlapPolicy#"skip" | "allow".JobOptions#{ timezone?: string; overlap?: OverlapPolicy; disabled?: boolean }.ScheduleJob#- The frozen job value:
{ name, kind, schedule: string | number, handler, timezone?, overlap, disabled }. JobState#{ running: boolean; runs: number; lastRun?: Date; lastError?: string; nextRun?: Date }.JobRunResult#{ name: string; ran: boolean; durationMs?: number; error?: string }.ScheduleContext#{ scheduleService: ScheduleService }, the context slice the module declares.
@rhythmjs/schedule/cron#
interface CronOptions { timezone?: string }
class Cron {
readonly pattern: string;
constructor(pattern: string, options?: CronOptions);
nextRun(from?: Date): Date | null;
}The dependency-free cron engine. The constructor throws on malformed patterns (field counts other than 5 or 6, out-of-range values, reversed ranges, zero steps, unknown names) and on unknown timezones. Accepted syntax per field: *, values, names (jan-dec, sun-sat), lists (a,b,c), ranges (a-b), steps (*/n, a-b/n, a/n meaning a to max), plus the @yearly, @annually, @monthly, @weekly, @daily, @hourly aliases. Six fields add leading seconds; five fields imply second zero. Day-of-week 7 is Sunday.
nextRun(from?) returns the next occurrence strictly after from at second resolution. When both day-of-month and day-of-week are restricted (neither starts with *), a date matching either is due. With timezone set, wall-clock fields are evaluated in that zone via Intl.DateTimeFormat; a time erased by a DST spring-forward gap is skipped to the next real occurrence. The search is bounded (about eight years); an impossible date such as February 30 returns null.
@rhythmjs/schedule/scheduler#
interface Scheduler { stop(): void }
function startScheduler(service: ScheduleService): Scheduler;Snapshots service.jobs and arms every enabled job: cron jobs via a setTimeout chain that re-arms after each run (service.run enforces the overlap policy), intervals via setInterval, timeouts via a single setTimeout. Delays above 2³¹−1 ms re-arm in chunks instead of firing early. stop() clears every timer and prevents re-arming; a run already in flight completes.