The Cron module lets you define schedules in a style similar to UNIX cron expressions.
It also supports partial constraints (e.g., certain months or weekdays), time zone awareness through the DateTime module, and robust error handling.
This module helps you:
Create a Cron instance from individual parts.
Parse and validate cron expressions.
Match existing dates to see if they satisfy a given cron schedule.
Find the next occurrence of a schedule after a given date.
Iterate over future dates that match a schedule.
Convert a Cron instance to a Schedule for use in effectful programs.
Creating a Cron
You can define a cron schedule by specifying numeric constraints for seconds, minutes, hours, days, months, and weekdays. The make function requires you to define all fields representing the schedule’s constraints.
Example (Creating a Cron)
seconds, minutes, and hours: Define the time of day.
days and months: Specify which calendar days and months are valid.
weekdays: Restrict the schedule to specific days of the week.
tz: Optionally define the time zone for the schedule.
If any field is left empty (e.g., months), it is treated as having “no constraints,” allowing any valid value for that part of the date.
Parsing Cron Expressions
Instead of manually constructing a Cron, you can use UNIX-like cron strings and parse them with parse or unsafeParse.
parse
The parse(cronExpression, tz?) function safely parses a cron string into a Cron instance. It returns an Either, which will contain either the parsed Cron or a parsing error.
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stderr with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
constcode=5;
console.error('error #%d', code);
// Prints: error #5, to stderr
console.error('error', code);
// Prints: error 5, to stderr
If formatting elements (e.g. %d) are not found in the first string then
util.inspect() is called on each argument and the
resulting string values are concatenated. See util.format()
for more information.
new (value:number|string|Date) =>Date (+3 overloads)
Date("2025-01-08 04:00:00")
8
9
var console:Console
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
The next function determines the next date that satisfies a given cron schedule, starting from a specified date. If no starting date is provided, the current time is used as the starting point.
If next cannot find a matching date within a predefined number of iterations, it throws an error to prevent infinite loops.
The console module provides a simple debugging console that is similar to the
JavaScript console mechanism provided by web browsers.
The module exports two specific components:
A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
A global console instance configured to write to process.stdout and
process.stderr. The global console can be used without importing the node:console module.
Warning: The global console object's methods are neither consistently
synchronous like the browser APIs they resemble, nor are they consistently
asynchronous like all other Node.js streams. See the note on process I/O for
more information.
Example using the global console:
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(newError('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
Prints to stdout with newline. Multiple arguments can be passed, with the
first used as the primary message and all additional used as substitution
values similar to printf(3)
(the arguments are all passed to util.format()).
To generate multiple future dates that match a cron schedule, you can use the sequence function. This function provides an infinite iterator of matching dates, starting from a specified date.
Example (Generating Future Dates with an Iterator)
// Get the first matching date after the start date
14
console.log(iterator.next().value)
15
// Output: 2021-01-08T04:00:00.000Z
16
17
// Get the second matching date after the start date
18
console.log(iterator.next().value)
19
// Output: 2021-01-09T04:00:00.000Z
Converting to Schedule
The Schedule module allows you to define recurring behaviors, such as retries or periodic events. The cron function bridges the Cron module with the Schedule module, enabling you to create schedules based on cron expressions or Cron instances.
cron
The Schedule.cron function generates a Schedule that triggers at the start of each interval defined by the provided cron expression or Cron instance. When triggered, the schedule produces a tuple [start, end] representing the timestamps (in milliseconds) of the cron interval window.
Example (Creating a Schedule from a Cron)
1
import {
2
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect,
3
import Schedule
Schedule,
4
import TestClock
TestClock,
5
import Fiber
Fiber,
6
import TestContext
TestContext,
7
import Cron
Cron,
8
import Console
Console
9
} from"effect"
10
11
// A helper function to log output at each interval of the schedule
function (typeparameter) Ain <A>(action:Effect.Effect<A>, schedule:Schedule.Schedule<[number, number], void>):void
A>(
13
action: Effect.Effect<A, never, never>
action:
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
interfaceEffect<outA, outE=never, outR=never>
The Effect interface defines a value that describes a workflow or job,
which can succeed or fail.
Details
The Effect interface represents a computation that can model a workflow
involving various types of operations, such as synchronous, asynchronous,
concurrent, and parallel interactions. It operates within a context of type
R, and the result can either be a success with a value of type A or a
failure with an error of type E. The Effect is designed to handle complex
interactions with external resources, offering advanced features such as
fiber-based concurrency, scheduling, interruption handling, and scalability.
This makes it suitable for tasks that require fine-grained control over
concurrency and error management.
To execute an Effect value, you need a Runtime, which provides the
environment necessary to run and manage the computation.
@since ― 2.0.0
@since ― 2.0.0
Effect<
function (typeparameter) Ain <A>(action:Effect.Effect<A>, schedule:Schedule.Schedule<[number, number], void>):void
A Schedule<Out, In, R> defines a recurring schedule, which consumes
values of type In, and which returns values of type Out.
Schedules are defined as a possibly infinite set of intervals spread out over
time. Each interval defines a window in which recurrence is possible.
When schedules are used to repeat or retry effects, the starting boundary of
each interval produced by a schedule is used as the moment when the effect
will be executed again.
Schedules compose in the following primary ways:
Union: performs the union of the intervals of two schedules
Intersection: performs the intersection of the intervals of two schedules
Sequence: concatenates the intervals of one schedule onto another
In addition, schedule inputs and outputs can be transformed, filtered (to
terminate a schedule early in response to some input or output), and so
forth.
A variety of other operators exist for transforming and combining schedules,
and the companion object for Schedule contains all common types of
schedules, both for performing retrying, as well as performing repetition.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to Use
Effect.gen allows you to write code that looks and behaves like synchronous
code, but it can handle asynchronous tasks, errors, and complex control flow
(like loops and conditions). It helps make asynchronous code more readable
and easier to manage.
The generator functions work similarly to async/await but with more
explicit control over the execution of effects. You can yield* values from
effects and return the final result at the end.
The repeat function returns a new effect that repeats the given effect
according to a specified schedule or until the first failure. The scheduled
recurrences are in addition to the initial execution, so repeat(action, Schedule.once) executes action once initially, and if it succeeds, repeats it
an additional time.
new (value:number|string|Date) =>Date (+3 overloads)
Date(
typeOut: [number, number]
Out[0]), new
var Date:DateConstructor
new (value:number|string|Date) =>Date (+3 overloads)
Date(
typeOut: [number, number]
Out[1])]
31
)
32
)
33
)
34
),
35
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
constfork: <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<Fiber.RuntimeFiber<A, E>, never, R>
Returns an effect that forks this effect into its own separate fiber,
returning the fiber immediately, without waiting for it to begin executing
the effect.
You can use the fork method whenever you want to execute an effect in a
new fiber, concurrently and without "blocking" the fiber executing other
effects. Using fibers can be tricky, so instead of using this method
directly, consider other higher-level methods, such as raceWith,
zipPar, and so forth.
The fiber returned by this method has methods to interrupt the fiber and to
wait for it to finish executing the effect. See Fiber for more
information.
Whenever you use this method to launch a new fiber, the new fiber is
attached to the parent fiber's scope. This means when the parent fiber
terminates, the child fiber will be terminated as well, ensuring that no
fibers leak. This behavior is called "auto supervision", and if this
behavior is not desired, you may use the forkDaemon or forkIn methods.
Accesses a TestClock instance in the context and increments the time
by the specified duration, running any actions scheduled for on or before
the new time in order.
Joins the fiber, which suspends the joining fiber until the result of the
fiber has been determined. Attempting to join a fiber that has erred will
result in a catchable error. Joining an interrupted fiber will result in an
"inner interruption" of this fiber, unlike interruption triggered by
another fiber, "inner interruption" can be caught and recovered.
construnPromise: <A, E>(effect:Effect.Effect<A, E, never>, options?: {
readonlysignal?:AbortSignal;
} |undefined) =>Promise<A>
Executes an effect and returns the result as a Promise.
When to Use
Use runPromise when you need to execute an effect and work with the
result using Promise syntax, typically for compatibility with other
promise-based code.
If the effect succeeds, the promise will resolve with the result. If the
effect fails, the promise will reject with an error.
@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.
@example
// Title: Running a Successful Effect as a Promise
Cron schedule that recurs every interval that matches the schedule.
It triggers at the beginning of each cron interval, producing the timestamps of the cron window.
NOTE: expression parameter is validated lazily. Must be a valid cron expression.
@since ― 2.0.0
cron(
constcron:Cron.Cron
cron)
48
49
// Define a dummy action to repeat
50
const
constaction:Effect.Effect<void, never, never>
action=
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
constvoid:Effect.Effect<void, never, never>
export void
Represents an effect that does nothing and produces no value.
When to Use
Use this effect when you need to represent an effect that does nothing.
This is useful in scenarios where you need to satisfy an effect-based
interface or control program flow without performing any operations. For
example, it can be used in situations where you want to return an effect
from a function but do not need to compute or return any result.