@warlock.js/scheduler 4.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/cjs/cron-parser.d.ts +98 -0
- package/cjs/cron-parser.d.ts.map +1 -0
- package/cjs/cron-parser.js +193 -0
- package/cjs/cron-parser.js.map +1 -0
- package/cjs/index.d.ts +44 -0
- package/cjs/index.d.ts.map +1 -0
- package/cjs/index.js +1 -0
- package/cjs/index.js.map +1 -0
- package/cjs/job.d.ts +331 -0
- package/cjs/job.d.ts.map +1 -0
- package/cjs/job.js +611 -0
- package/cjs/job.js.map +1 -0
- package/cjs/scheduler.d.ts +178 -0
- package/cjs/scheduler.d.ts.map +1 -0
- package/cjs/scheduler.js +305 -0
- package/cjs/scheduler.js.map +1 -0
- package/cjs/types.d.ts +63 -0
- package/cjs/types.d.ts.map +1 -0
- package/cjs/utils.d.ts +3 -0
- package/cjs/utils.d.ts.map +1 -0
- package/esm/cron-parser.d.ts +98 -0
- package/esm/cron-parser.d.ts.map +1 -0
- package/esm/cron-parser.js +193 -0
- package/esm/cron-parser.js.map +1 -0
- package/esm/index.d.ts +44 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -0
- package/esm/job.d.ts +331 -0
- package/esm/job.d.ts.map +1 -0
- package/esm/job.js +611 -0
- package/esm/job.js.map +1 -0
- package/esm/scheduler.d.ts +178 -0
- package/esm/scheduler.d.ts.map +1 -0
- package/esm/scheduler.js +305 -0
- package/esm/scheduler.js.map +1 -0
- package/esm/types.d.ts +63 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/utils.d.ts +3 -0
- package/esm/utils.d.ts.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import dayjs from'dayjs';/**
|
|
2
|
+
* Cron expression parser
|
|
3
|
+
*
|
|
4
|
+
* Supports standard 5-field cron expressions:
|
|
5
|
+
* ```
|
|
6
|
+
* ┌───────────── minute (0-59)
|
|
7
|
+
* │ ┌───────────── hour (0-23)
|
|
8
|
+
* │ │ ┌───────────── day of month (1-31)
|
|
9
|
+
* │ │ │ ┌───────────── month (1-12)
|
|
10
|
+
* │ │ │ │ ┌───────────── day of week (0-6, Sunday = 0)
|
|
11
|
+
* │ │ │ │ │
|
|
12
|
+
* * * * * *
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* Supports:
|
|
16
|
+
* - `*` - any value
|
|
17
|
+
* - `5` - specific value
|
|
18
|
+
* - `1,3,5` - list of values
|
|
19
|
+
* - `1-5` - range of values
|
|
20
|
+
* - `* /5` - step values (every 5)
|
|
21
|
+
* - `1-10/2` - range with step
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const parser = new CronParser("0 9 * * 1-5"); // 9 AM weekdays
|
|
26
|
+
* const nextRun = parser.nextRun();
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
class CronParser {
|
|
30
|
+
_expression;
|
|
31
|
+
_fields;
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new CronParser instance
|
|
34
|
+
*
|
|
35
|
+
* @param expression - Standard 5-field cron expression
|
|
36
|
+
* @throws Error if expression is invalid
|
|
37
|
+
*/
|
|
38
|
+
constructor(_expression) {
|
|
39
|
+
this._expression = _expression;
|
|
40
|
+
this._fields = this._parse(_expression);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get the parsed cron fields
|
|
44
|
+
*/
|
|
45
|
+
get fields() {
|
|
46
|
+
return this._fields;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get the original expression
|
|
50
|
+
*/
|
|
51
|
+
get expression() {
|
|
52
|
+
return this._expression;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Calculate the next run time from a given date
|
|
56
|
+
*
|
|
57
|
+
* @param from - Starting date (defaults to now)
|
|
58
|
+
* @returns Next run time as Dayjs
|
|
59
|
+
*/
|
|
60
|
+
nextRun(from = dayjs()) {
|
|
61
|
+
let date = from.add(1, "minute").second(0).millisecond(0);
|
|
62
|
+
// Maximum iterations to prevent infinite loops
|
|
63
|
+
const maxIterations = 366 * 24 * 60; // 1 year of minutes
|
|
64
|
+
let iterations = 0;
|
|
65
|
+
while (iterations < maxIterations) {
|
|
66
|
+
iterations++;
|
|
67
|
+
// Check month
|
|
68
|
+
if (!this._fields.months.includes(date.month() + 1)) {
|
|
69
|
+
date = date.add(1, "month").date(1).hour(0).minute(0);
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
// Check day of month
|
|
73
|
+
if (!this._fields.daysOfMonth.includes(date.date())) {
|
|
74
|
+
date = date.add(1, "day").hour(0).minute(0);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// Check day of week
|
|
78
|
+
if (!this._fields.daysOfWeek.includes(date.day())) {
|
|
79
|
+
date = date.add(1, "day").hour(0).minute(0);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Check hour
|
|
83
|
+
if (!this._fields.hours.includes(date.hour())) {
|
|
84
|
+
date = date.add(1, "hour").minute(0);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// Check minute
|
|
88
|
+
if (!this._fields.minutes.includes(date.minute())) {
|
|
89
|
+
date = date.add(1, "minute");
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// All fields match!
|
|
93
|
+
return date;
|
|
94
|
+
}
|
|
95
|
+
throw new Error(`Could not find next run time for cron expression: ${this._expression}`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if a given date matches the cron expression
|
|
99
|
+
*
|
|
100
|
+
* @param date - Date to check
|
|
101
|
+
* @returns true if the date matches
|
|
102
|
+
*/
|
|
103
|
+
matches(date) {
|
|
104
|
+
return (this._fields.minutes.includes(date.minute()) &&
|
|
105
|
+
this._fields.hours.includes(date.hour()) &&
|
|
106
|
+
this._fields.daysOfMonth.includes(date.date()) &&
|
|
107
|
+
this._fields.months.includes(date.month() + 1) &&
|
|
108
|
+
this._fields.daysOfWeek.includes(date.day()));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Parse a cron expression into fields
|
|
112
|
+
*/
|
|
113
|
+
_parse(expression) {
|
|
114
|
+
const parts = expression.trim().split(/\s+/);
|
|
115
|
+
if (parts.length !== 5) {
|
|
116
|
+
throw new Error(`Invalid cron expression: "${expression}". Expected 5 fields (minute hour day month weekday).`);
|
|
117
|
+
}
|
|
118
|
+
const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
|
|
119
|
+
return {
|
|
120
|
+
minutes: this._parseField(minute, 0, 59),
|
|
121
|
+
hours: this._parseField(hour, 0, 23),
|
|
122
|
+
daysOfMonth: this._parseField(dayOfMonth, 1, 31),
|
|
123
|
+
months: this._parseField(month, 1, 12),
|
|
124
|
+
daysOfWeek: this._parseField(dayOfWeek, 0, 6),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Parse a single cron field
|
|
129
|
+
*
|
|
130
|
+
* @param field - Field value (e.g., "*", "5", "1-5", "* /2", "1,3,5")
|
|
131
|
+
* @param min - Minimum allowed value
|
|
132
|
+
* @param max - Maximum allowed value
|
|
133
|
+
* @returns Array of matching values
|
|
134
|
+
*/
|
|
135
|
+
_parseField(field, min, max) {
|
|
136
|
+
const values = new Set();
|
|
137
|
+
// Handle lists (e.g., "1,3,5")
|
|
138
|
+
const parts = field.split(",");
|
|
139
|
+
for (const part of parts) {
|
|
140
|
+
// Handle step values (e.g., "*/5" or "1-10/2")
|
|
141
|
+
const [range, stepStr] = part.split("/");
|
|
142
|
+
const step = stepStr ? parseInt(stepStr, 10) : 1;
|
|
143
|
+
if (isNaN(step) || step < 1) {
|
|
144
|
+
throw new Error(`Invalid step value in cron field: "${field}"`);
|
|
145
|
+
}
|
|
146
|
+
let rangeStart;
|
|
147
|
+
let rangeEnd;
|
|
148
|
+
if (range === "*") {
|
|
149
|
+
// Wildcard - all values
|
|
150
|
+
rangeStart = min;
|
|
151
|
+
rangeEnd = max;
|
|
152
|
+
}
|
|
153
|
+
else if (range.includes("-")) {
|
|
154
|
+
// Range (e.g., "1-5")
|
|
155
|
+
const [startStr, endStr] = range.split("-");
|
|
156
|
+
rangeStart = parseInt(startStr, 10);
|
|
157
|
+
rangeEnd = parseInt(endStr, 10);
|
|
158
|
+
if (isNaN(rangeStart) || isNaN(rangeEnd)) {
|
|
159
|
+
throw new Error(`Invalid range in cron field: "${field}"`);
|
|
160
|
+
}
|
|
161
|
+
if (rangeStart < min || rangeEnd > max || rangeStart > rangeEnd) {
|
|
162
|
+
throw new Error(`Range out of bounds in cron field: "${field}" (valid: ${min}-${max})`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Single value
|
|
167
|
+
const value = parseInt(range, 10);
|
|
168
|
+
if (isNaN(value)) {
|
|
169
|
+
throw new Error(`Invalid value in cron field: "${field}"`);
|
|
170
|
+
}
|
|
171
|
+
if (value < min || value > max) {
|
|
172
|
+
throw new Error(`Value out of bounds in cron field: "${field}" (valid: ${min}-${max})`);
|
|
173
|
+
}
|
|
174
|
+
rangeStart = value;
|
|
175
|
+
rangeEnd = value;
|
|
176
|
+
}
|
|
177
|
+
// Add values with step
|
|
178
|
+
for (let i = rangeStart; i <= rangeEnd; i += step) {
|
|
179
|
+
values.add(i);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return Array.from(values).sort((a, b) => a - b);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Parse a cron expression string
|
|
187
|
+
*
|
|
188
|
+
* @param expression - Cron expression (5 fields)
|
|
189
|
+
* @returns CronParser instance
|
|
190
|
+
*/
|
|
191
|
+
function parseCron(expression) {
|
|
192
|
+
return new CronParser(expression);
|
|
193
|
+
}export{CronParser,parseCron};//# sourceMappingURL=cron-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-parser.js","sources":["../src/cron-parser.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
package/esm/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @warlock.js/scheduler
|
|
3
|
+
*
|
|
4
|
+
* A production-ready job scheduler with cron-like functionality.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { Scheduler, job } from "@warlock.js/scheduler";
|
|
9
|
+
*
|
|
10
|
+
* const scheduler = new Scheduler();
|
|
11
|
+
*
|
|
12
|
+
* // Add observability
|
|
13
|
+
* scheduler.on('job:error', (name, error) => console.error(`${name} failed:`, error));
|
|
14
|
+
*
|
|
15
|
+
* // Schedule jobs with fluent API
|
|
16
|
+
* scheduler.addJob(
|
|
17
|
+
* job("cleanup", async () => {
|
|
18
|
+
* await cleanupExpiredTokens();
|
|
19
|
+
* })
|
|
20
|
+
* .daily()
|
|
21
|
+
* .at("03:00")
|
|
22
|
+
* .inTimezone("America/New_York")
|
|
23
|
+
* .preventOverlap()
|
|
24
|
+
* .retry(3, 1000)
|
|
25
|
+
* );
|
|
26
|
+
*
|
|
27
|
+
* // Or use cron expressions
|
|
28
|
+
* scheduler.addJob(
|
|
29
|
+
* job("reports", sendReports).cron("0 9 * * 1-5") // 9 AM weekdays
|
|
30
|
+
* );
|
|
31
|
+
*
|
|
32
|
+
* // Start and handle graceful shutdown
|
|
33
|
+
* scheduler.start();
|
|
34
|
+
* process.on('SIGTERM', () => scheduler.shutdown());
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @packageDocumentation
|
|
38
|
+
*/
|
|
39
|
+
export { CronParser, parseCron } from "./cron-parser";
|
|
40
|
+
export { Job, job } from "./job";
|
|
41
|
+
export { Scheduler, scheduler } from "./scheduler";
|
|
42
|
+
export type { CronFields } from "./cron-parser";
|
|
43
|
+
export type { Day, JobIntervals, JobResult, JobStatus, RetryConfig, SchedulerEvents, TimeType, } from "./types";
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGnD,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,YAAY,EACV,GAAG,EACH,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,eAAe,EACf,QAAQ,GACT,MAAM,SAAS,CAAC"}
|
package/esm/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{CronParser,parseCron}from'./cron-parser.js';export{Job,job}from'./job.js';export{Scheduler,scheduler}from'./scheduler.js';//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/esm/job.d.ts
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { type Dayjs } from "dayjs";
|
|
2
|
+
import type { Day, JobIntervals, JobResult, TimeType } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Job class represents a scheduled task with configurable timing and execution options.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const job = new Job("cleanup", async () => {
|
|
9
|
+
* await cleanupOldFiles();
|
|
10
|
+
* })
|
|
11
|
+
* .everyDay()
|
|
12
|
+
* .at("03:00")
|
|
13
|
+
* .inTimezone("America/New_York")
|
|
14
|
+
* .preventOverlap()
|
|
15
|
+
* .retry(3, 1000);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare class Job {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
private readonly _callback;
|
|
21
|
+
/**
|
|
22
|
+
* Interval configuration for scheduling
|
|
23
|
+
*/
|
|
24
|
+
private _intervals;
|
|
25
|
+
/**
|
|
26
|
+
* Last execution timestamp
|
|
27
|
+
*/
|
|
28
|
+
private _lastRun;
|
|
29
|
+
/**
|
|
30
|
+
* Whether the job is currently executing
|
|
31
|
+
*/
|
|
32
|
+
private _isRunning;
|
|
33
|
+
/**
|
|
34
|
+
* Skip execution if job is already running
|
|
35
|
+
*/
|
|
36
|
+
private _skipIfRunning;
|
|
37
|
+
/**
|
|
38
|
+
* Retry configuration
|
|
39
|
+
*/
|
|
40
|
+
private _retryConfig;
|
|
41
|
+
/**
|
|
42
|
+
* Timezone for scheduling (defaults to system timezone)
|
|
43
|
+
*/
|
|
44
|
+
private _timezone;
|
|
45
|
+
/**
|
|
46
|
+
* Cron expression parser (mutually exclusive with interval config)
|
|
47
|
+
*/
|
|
48
|
+
private _cronParser;
|
|
49
|
+
/**
|
|
50
|
+
* Promise resolver for completion waiting
|
|
51
|
+
*/
|
|
52
|
+
private _completionResolver;
|
|
53
|
+
/**
|
|
54
|
+
* Next scheduled execution time
|
|
55
|
+
*/
|
|
56
|
+
nextRun: Dayjs | null;
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new Job instance
|
|
59
|
+
*
|
|
60
|
+
* @param name - Unique identifier for the job
|
|
61
|
+
* @param callback - Function to execute when the job runs
|
|
62
|
+
*/
|
|
63
|
+
constructor(name: string, _callback: (job: Job) => Promise<unknown> | unknown);
|
|
64
|
+
/**
|
|
65
|
+
* Returns true if the job is currently executing
|
|
66
|
+
*/
|
|
67
|
+
get isRunning(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Returns the last execution timestamp
|
|
70
|
+
*/
|
|
71
|
+
get lastRun(): Dayjs | null;
|
|
72
|
+
/**
|
|
73
|
+
* Returns the current interval configuration (readonly)
|
|
74
|
+
*/
|
|
75
|
+
get intervals(): Readonly<JobIntervals>;
|
|
76
|
+
/**
|
|
77
|
+
* Set a custom interval for job execution
|
|
78
|
+
*
|
|
79
|
+
* @param value - Number of time units
|
|
80
|
+
* @param timeType - Type of time unit
|
|
81
|
+
* @returns this for chaining
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* job.every(5, "minute"); // Run every 5 minutes
|
|
86
|
+
* job.every(2, "hour"); // Run every 2 hours
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
every(value: number, timeType: TimeType): this;
|
|
90
|
+
/**
|
|
91
|
+
* Run job every second (use with caution - high frequency)
|
|
92
|
+
*/
|
|
93
|
+
everySecond(): this;
|
|
94
|
+
/**
|
|
95
|
+
* Run job every specified number of seconds
|
|
96
|
+
*/
|
|
97
|
+
everySeconds(seconds: number): this;
|
|
98
|
+
/**
|
|
99
|
+
* Run job every minute
|
|
100
|
+
*/
|
|
101
|
+
everyMinute(): this;
|
|
102
|
+
/**
|
|
103
|
+
* Run job every specified number of minutes
|
|
104
|
+
*/
|
|
105
|
+
everyMinutes(minutes: number): this;
|
|
106
|
+
/**
|
|
107
|
+
* Run job every hour
|
|
108
|
+
*/
|
|
109
|
+
everyHour(): this;
|
|
110
|
+
/**
|
|
111
|
+
* Run job every specified number of hours
|
|
112
|
+
*/
|
|
113
|
+
everyHours(hours: number): this;
|
|
114
|
+
/**
|
|
115
|
+
* Run job every day at midnight
|
|
116
|
+
*/
|
|
117
|
+
everyDay(): this;
|
|
118
|
+
/**
|
|
119
|
+
* Alias for everyDay()
|
|
120
|
+
*/
|
|
121
|
+
daily(): this;
|
|
122
|
+
/**
|
|
123
|
+
* Run job twice a day (every 12 hours)
|
|
124
|
+
*/
|
|
125
|
+
twiceDaily(): this;
|
|
126
|
+
/**
|
|
127
|
+
* Run job every week
|
|
128
|
+
*/
|
|
129
|
+
everyWeek(): this;
|
|
130
|
+
/**
|
|
131
|
+
* Alias for everyWeek()
|
|
132
|
+
*/
|
|
133
|
+
weekly(): this;
|
|
134
|
+
/**
|
|
135
|
+
* Run job every month
|
|
136
|
+
*/
|
|
137
|
+
everyMonth(): this;
|
|
138
|
+
/**
|
|
139
|
+
* Alias for everyMonth()
|
|
140
|
+
*/
|
|
141
|
+
monthly(): this;
|
|
142
|
+
/**
|
|
143
|
+
* Run job every year
|
|
144
|
+
*/
|
|
145
|
+
everyYear(): this;
|
|
146
|
+
/**
|
|
147
|
+
* Alias for everyYear()
|
|
148
|
+
*/
|
|
149
|
+
yearly(): this;
|
|
150
|
+
/**
|
|
151
|
+
* Alias for everyMinute() - job runs continuously every minute
|
|
152
|
+
*/
|
|
153
|
+
always(): this;
|
|
154
|
+
/**
|
|
155
|
+
* Schedule job using a cron expression
|
|
156
|
+
*
|
|
157
|
+
* Supports standard 5-field cron syntax:
|
|
158
|
+
* ```
|
|
159
|
+
* ┌───────────── minute (0-59)
|
|
160
|
+
* │ ┌───────────── hour (0-23)
|
|
161
|
+
* │ │ ┌───────────── day of month (1-31)
|
|
162
|
+
* │ │ │ ┌───────────── month (1-12)
|
|
163
|
+
* │ │ │ │ ┌───────────── day of week (0-6, Sunday = 0)
|
|
164
|
+
* │ │ │ │ │
|
|
165
|
+
* * * * * *
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* Supports:
|
|
169
|
+
* - '*' - any value
|
|
170
|
+
* - '5' - specific value
|
|
171
|
+
* - '1,3,5' - list of values
|
|
172
|
+
* - '1-5' - range of values
|
|
173
|
+
* - 'x/5' - step values (every 5)
|
|
174
|
+
* - '1-10/2' - range with step
|
|
175
|
+
*
|
|
176
|
+
* @param expression - Standard 5-field cron expression
|
|
177
|
+
* @returns this for chaining
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* job.cron("0 9 * * 1-5"); // 9 AM weekdays
|
|
182
|
+
* job.cron("x/5 * * * *"); // Every 5 minutes
|
|
183
|
+
* job.cron("0 0 1 * *"); // First day of month at midnight
|
|
184
|
+
* job.cron("0 x/2 * * *"); // Every 2 hours
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
cron(expression: string): this;
|
|
188
|
+
/**
|
|
189
|
+
* Get the cron expression if one is set
|
|
190
|
+
*/
|
|
191
|
+
get cronExpression(): string | null;
|
|
192
|
+
/**
|
|
193
|
+
* Schedule job on a specific day
|
|
194
|
+
*
|
|
195
|
+
* @param day - Day of week (string) or day of month (number 1-31)
|
|
196
|
+
* @returns this for chaining
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```typescript
|
|
200
|
+
* job.on("monday"); // Run on Mondays
|
|
201
|
+
* job.on(15); // Run on the 15th of each month
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
on(day: Day | number): this;
|
|
205
|
+
/**
|
|
206
|
+
* Schedule job at a specific time
|
|
207
|
+
*
|
|
208
|
+
* @param time - Time in HH:mm or HH:mm:ss format
|
|
209
|
+
* @returns this for chaining
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* job.daily().at("09:00"); // Run daily at 9 AM
|
|
214
|
+
* job.weekly().at("14:30"); // Run weekly at 2:30 PM
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
at(time: string): this;
|
|
218
|
+
/**
|
|
219
|
+
* Run task at the beginning of the specified time period
|
|
220
|
+
*
|
|
221
|
+
* @param type - Time type (day, month, year)
|
|
222
|
+
*/
|
|
223
|
+
beginOf(type: TimeType): this;
|
|
224
|
+
/**
|
|
225
|
+
* Run task at the end of the specified time period
|
|
226
|
+
*
|
|
227
|
+
* @param type - Time type (day, month, year)
|
|
228
|
+
*/
|
|
229
|
+
endOf(type: TimeType): this;
|
|
230
|
+
/**
|
|
231
|
+
* Set the timezone for this job's scheduling
|
|
232
|
+
*
|
|
233
|
+
* @param tz - IANA timezone string (e.g., "America/New_York", "Europe/London")
|
|
234
|
+
* @returns this for chaining
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* job.daily().at("09:00").inTimezone("America/New_York");
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
inTimezone(tz: string): this;
|
|
242
|
+
/**
|
|
243
|
+
* Prevent overlapping executions of this job
|
|
244
|
+
*
|
|
245
|
+
* When enabled, if the job is already running when it's scheduled to run again,
|
|
246
|
+
* the new execution will be skipped.
|
|
247
|
+
*
|
|
248
|
+
* @param skip - Whether to skip if already running (default: true)
|
|
249
|
+
* @returns this for chaining
|
|
250
|
+
*/
|
|
251
|
+
preventOverlap(skip?: boolean): this;
|
|
252
|
+
/**
|
|
253
|
+
* Configure automatic retry on failure
|
|
254
|
+
*
|
|
255
|
+
* @param maxRetries - Maximum number of retry attempts
|
|
256
|
+
* @param delay - Delay between retries in milliseconds
|
|
257
|
+
* @param backoffMultiplier - Optional multiplier for exponential backoff
|
|
258
|
+
* @returns this for chaining
|
|
259
|
+
*
|
|
260
|
+
* @example
|
|
261
|
+
* ```typescript
|
|
262
|
+
* job.retry(3, 1000); // Retry 3 times with 1s delay
|
|
263
|
+
* job.retry(5, 1000, 2); // Exponential backoff: 1s, 2s, 4s, 8s, 16s
|
|
264
|
+
* ```
|
|
265
|
+
*/
|
|
266
|
+
retry(maxRetries: number, delay?: number, backoffMultiplier?: number): this;
|
|
267
|
+
/**
|
|
268
|
+
* Terminate the job and clear all scheduling data
|
|
269
|
+
*/
|
|
270
|
+
terminate(): this;
|
|
271
|
+
/**
|
|
272
|
+
* Prepare the job by calculating the next run time
|
|
273
|
+
* Called by the scheduler when starting
|
|
274
|
+
*/
|
|
275
|
+
prepare(): void;
|
|
276
|
+
/**
|
|
277
|
+
* Determine if the job should run now
|
|
278
|
+
*
|
|
279
|
+
* @returns true if the job should execute
|
|
280
|
+
*/
|
|
281
|
+
shouldRun(): boolean;
|
|
282
|
+
/**
|
|
283
|
+
* Execute the job
|
|
284
|
+
*
|
|
285
|
+
* @returns Promise resolving to the job result
|
|
286
|
+
*/
|
|
287
|
+
run(): Promise<JobResult>;
|
|
288
|
+
/**
|
|
289
|
+
* Wait for the job to complete
|
|
290
|
+
* Useful for graceful shutdown
|
|
291
|
+
*
|
|
292
|
+
* @returns Promise that resolves when the job completes
|
|
293
|
+
*/
|
|
294
|
+
waitForCompletion(): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Get current time, respecting timezone if set
|
|
297
|
+
*/
|
|
298
|
+
private _now;
|
|
299
|
+
/**
|
|
300
|
+
* Execute the callback with retry logic
|
|
301
|
+
*/
|
|
302
|
+
private _executeWithRetry;
|
|
303
|
+
/**
|
|
304
|
+
* Calculate retry delay with optional exponential backoff
|
|
305
|
+
*/
|
|
306
|
+
private _calculateRetryDelay;
|
|
307
|
+
/**
|
|
308
|
+
* Sleep for specified milliseconds
|
|
309
|
+
*/
|
|
310
|
+
private _sleep;
|
|
311
|
+
/**
|
|
312
|
+
* Calculate the next run time based on interval or cron configuration
|
|
313
|
+
*/
|
|
314
|
+
private _determineNextRun;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Factory function to create a new Job instance
|
|
318
|
+
*
|
|
319
|
+
* @param name - Unique identifier for the job
|
|
320
|
+
* @param callback - Function to execute when the job runs
|
|
321
|
+
* @returns New Job instance
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```typescript
|
|
325
|
+
* const cleanupJob = job("cleanup", async () => {
|
|
326
|
+
* await db.deleteExpiredTokens();
|
|
327
|
+
* }).daily().at("03:00");
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
export declare function job(name: string, callback: (job: Job) => Promise<unknown> | unknown): Job;
|
|
331
|
+
//# sourceMappingURL=job.d.ts.map
|
package/esm/job.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../src/job.ts"],"names":[],"mappings":"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"}
|