Types
All types are exported from the package root.
import type { JobContext, JobHandler, RunRecord, SchedulerOptions } from 'anarchon';JobHandler
Section titled “JobHandler”type JobHandler<Data = unknown> = (ctx: JobContext<Data>) => unknown;The function a job runs. Sync or async. Returning means success; throwing means failure, or interrupted when ctx.signal was aborted by stop() or a takeover first.
JobContext
Section titled “JobContext”interface JobContext<Data = unknown> { name: string; slot: number; scheduledAt: Date; instanceId: string; manual: boolean; data: Data; signal: AbortSignal; attempt: number; reason: RunReason;}Guide: Writing handlers.
JobData, JobDataProvider
Section titled “JobData, JobDataProvider”type JobData = object | string | number | boolean | null | JobDataProvider;type JobDataProvider = (run: Omit<JobContext, 'data'>) => unknown; // may return a promiseWhat the data option of a scheduler, a job and runNow() takes: a value, or a function called when a run starts. Guide: Run data.
RunReason
Section titled “RunReason”type RunReason = 'scheduled' | 'manual' | 'catch-up' | 'takeover';| Value | Meaning |
|---|---|
'scheduled' |
The run was due |
'manual' |
runNow() was called |
'catch-up' |
It was due while every instance was down |
'takeover' |
A backup started the next attempt of a run whose runner was gone |
JobOptions, EveryJobOptions, CronJobOptions, AtJobOptions
Section titled “JobOptions, EveryJobOptions, CronJobOptions, AtJobOptions”interface LeaseJobOptions { overlap?: 'skip' | 'allow'; maxAttempts?: number; catchUpMs?: number;}
interface JobOptions extends LeaseJobOptions { jitterMs?: number; maxLateMs?: number; historySize?: number; historyTtlMs?: number; timeoutMs?: number;}
interface EveryJobOptions extends JobOptions { offsetMs?: number;}
interface CronJobOptions extends JobOptions { timezone?: string;}
type AtJobOptions = Omit<JobOptions, 'overlap'>;
type JobOptionsFor<B, Options = JobOptions> = /* Options, without LeaseJobOptions when B has no leases */;See Options.
Decorator types
Section titled “Decorator types”type DecoratedJobOptions<Options> = Options & { name?: string; // default: Class-method scheduler?: string | Scheduler; // default: the default scheduler};
interface RegisterOptions { prefix?: string; defaults?: JobOptions & { timezone?: string };}
interface ConfigureOptions extends Omit<SchedulerOptions, 'backend' | 'name'> { backend?: Backend | ((name: string) => Backend); autoStart?: boolean;}| Type | What it is |
|---|---|
DecoratedJobOptions |
What @Every, @Cron and @At accept when the name isn’t the first argument |
JobPlacement |
{ scheduler? }, the part of it that the form with the name first also accepts |
JobDecorator, ScheduledDecorator |
What the method decorators and @Scheduled() return: decorators in both the standard and the legacy style |
RegisterOptions |
The options of scheduler.register() |
ConfigureOptions |
The settings Scheduler.configure() takes |
See Decorators.
JobInfo
Section titled “JobInfo”What jobs() returns for each job.
interface JobInfo { name: string; type: 'cron' | 'every' | 'once'; schedule: string; // e.g. 'every 10s', 'cron "0 8 * * 1-5" (Europe/Athens)' nextRunAt: Date | null; runningHere: number; // runs of this job executing on this instance now}RunKey, RunEvent, RunRecord
Section titled “RunKey, RunEvent, RunRecord”RunKey names one run: a job and its scheduled time. RunEvent adds when it was due and which instance it is about; RunRecord and the run events (RunStartEvent, SkipEvent, LostEvent) extend it, so one function can read any of them. A RunRecord is one attempt of one run. Returned by history(), lastRun() and runNow(), and the payload of success.
interface RunKey { job: string; slot: number;}
interface RunEvent extends RunKey { scheduledAt: Date; instanceId: string;}
interface RunRecord extends RunEvent { manual: boolean; attempt: number; reason?: RunReason; status: RunStatus; startedAt: Date; finishedAt?: Date; durationMs?: number; error?: string;}RunStatus
Section titled “RunStatus”type RunStatus = 'running' | 'success' | 'failed' | 'interrupted';Guide: History.
Scheduler
Section titled “Scheduler”SchedulerOptions, LeaseSchedulerOptions
Section titled “SchedulerOptions, LeaseSchedulerOptions”interface LeaseSchedulerOptions { leaseMs?: number; heartbeatMs?: number;}
type SchedulerOptions<B extends Backend = Backend> = { backend: B; /* ... */ } & /* LeaseSchedulerOptions when B may have leases */;Scheduler takes its backend’s type, Scheduler<B>, so its options and those of every(), cron() and at() depend on the backend. A backend “has leases” when its runs may be set: PostgreSQL, SQLite, Redis or Valkey with the lease strategy, and any value typed only as Backend. On the others, LeaseSchedulerOptions and LeaseJobOptions aren’t offered. See Options.
Logger
Section titled “Logger”interface Logger { info?(message: string, ...meta: unknown[]): void; warn(message: string, ...meta: unknown[]): void; error(message: string, ...meta: unknown[]): void;}console, pino and winston loggers all fit.
KeyValueStrategies, KeyValueStrategyName, KeyValueStrategy
Section titled “KeyValueStrategies, KeyValueStrategyName, KeyValueStrategy”interface KeyValueStrategies { redis: 'lease' | 'stream-id' | 'idmp' | 'script'; valkey: 'lease' | 'stream-id' | 'script';}type KeyValueStrategyName<Server extends keyof KeyValueStrategies = 'redis'> = KeyValueStrategies[Server];
// A name, or { name, ...that strategy's settings }type KeyValueStrategy<Name = KeyValueStrategyName> = | Name | { name: 'idmp'; durationSec?: number; maxSize?: number } | { name: 'script'; windowMs?: number } | { name: 'lease' | 'stream-id' };The strategies of the key-value backends, by server. KeyValueStrategy is the strategy option of RedisBackend; ValkeyBackend takes KeyValueStrategy<KeyValueStrategyName<'valkey'>>, with no idmp because Valkey can’t run it. A strategy’s settings go inside it, so they can’t be given to another strategy. lease (the default) also gives no overlapping runs, backup runners, catch-up and retries. stream-id, script and idmp (Redis 8.6+) only decide who runs each time. Redis and Valkey explains each one. The database and broker backends have no strategy option: PostgreSQL and SQLite always follow the lease rules, and RabbitMQ and NATS always make a simple claim.
IdmpOptions, ScriptOptions
Section titled “IdmpOptions, ScriptOptions”interface IdmpOptions { durationSec?: number; // 1 to 86400, default 300 maxSize?: number; // 1 to 10000, default 1000}
interface ScriptOptions { windowMs?: number; // default 300000}The settings of { name: 'idmp' } and { name: 'script' }.
Events
Section titled “Events”SchedulerEvents, RunStartEvent, RunFailureEvent, RunInterruptedEvent, SkipEvent, LostEvent and SchedulerErrorEvent are described in Events.
Backends
Section titled “Backends”These matter when you write a backend.
Backend
Section titled “Backend”interface Backend { readonly name: string; readonly dedupeWindowMs: number; checkJob?(job: JobLimits): void; init(): Promise<void>; prepareJob(job: string, historySize: number): Promise<void>; claim(input: ClaimInput): Promise<boolean>; recordClaim?(input: ClaimInput): Promise<void>; recordManualRun(input: ClaimInput): Promise<number | void>; saveResult(job: string, result: StoredResult, historySize: number, historyTtlMs?: number): Promise<void>; history(job: string, limit: number): Promise<RunRecord[]>; readonly runs?: RunStore; close(): Promise<void>;}ClaimInput
Section titled “ClaimInput”interface ClaimInput { job: string; slot: number; token: string; instanceId: string; historySize: number; historyTtlMs?: number;}StoredResult
Section titled “StoredResult”What the runner stores when an attempt ends.
interface StoredResult { slot: number; by: string; attempt?: number; status: 'success' | 'failed' | 'interrupted'; startedAt: number; finishedAt: number; durationMs: number; error?: string;}JobLimits
Section titled “JobLimits”What checkJob() receives, so a backend can refuse a job it can’t run safely.
interface JobLimits { name: string; jitterMs: number; maxLateMs: number; minGapMs: number; // the smallest gap between two runs historySize: number; historyTtlMs?: number;}RunStore
Section titled “RunStore”The optional lease capability of a backend.
interface RunStore { claim(input: RunClaim): Promise<ClaimOutcome>; heartbeat(job: string, slot: number, token: string, leaseMs: number): Promise<boolean>; finish(job: string, slot: number, token: string, status: 'success' | 'failed' | 'interrupted'): Promise<boolean>; release(job: string, slot: number, token: string): Promise<boolean>; active(job: string): Promise<Array<{ slot: number; attempt: number; alive: boolean }>>;}RunClaim
Section titled “RunClaim”interface RunClaim extends ClaimInput { mode: 'new' | 'takeover'; reason: RunReason; leaseMs: number; overlap: 'skip' | 'allow'; maxAttempts: number; maxLateMs?: number; keepMs?: number;}ClaimOutcome
Section titled “ClaimOutcome”type ClaimOutcome = | { kind: 'won'; attempt: number } | { kind: 'running'; attempt: number } | { kind: 'done' } | { kind: 'overlap'; slot: number } | { kind: 'none' } | { kind: 'late'; lateMs: number };Each outcome is explained in Run lifecycle.
Client shapes
Section titled “Client shapes”The minimal shape anarchon needs from each client library. You pass a real client; these types exist so anarchon doesn’t depend on the libraries themselves.
| Type | Matches |
|---|---|
KeyValueConnection |
Anything accepted as redis (RedisBackend) or valkey (ValkeyBackend) |
KeyValueClient |
{ send(command, args) } |
KeyValueConnectionOptions |
{ host, port, username, password, db } |
IORedisLike, NodeRedisLike, ValkeyGlideLike |
ioredis / iovalkey, node-redis, Valkey GLIDE |
PgPoolLike, PgClientLike, PostgresJsLike |
pg Pool, pg Client, postgres.js |
SqliteDatabaseLike, LibsqlClientLike |
node:sqlite / better-sqlite3, @libsql/client |
SqlClient, SqlQuery, SqlRow, SqlValue |
The { all, transaction } adapter of the SQL backends |
SqlDialect |
What a subclass of SqlBackend gives for another SQL database |
RabbitMQConnectionLike, NatsConnectionLike |
An amqplib connection, a NATS connection |
Backend option types: RedisBackendOptions, ValkeyBackendOptions, PostgresBackendOptions, SqliteBackendOptions, RabbitMQBackendOptions, NatsBackendOptions. See Options.