@warlock.js/scheduler 4.0.48 → 4.0.59

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.
@@ -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 CHANGED
@@ -1,5 +1 @@
1
- export { CronParser, parseCron } from './cron-parser';
2
- export { Job, job } from './job';
3
- export { Scheduler, scheduler } from './scheduler';
4
- //# sourceMappingURL=index.js.map
5
- //# sourceMappingURL=index.js.map
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 CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js","sourcesContent":[]}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
package/esm/job.d.ts ADDED
@@ -0,0 +1,332 @@
1
+ import { type Dayjs } from "dayjs";
2
+ import type { Day, JobIntervals, JobResult, TimeType } from "./types";
3
+ export type JobCallback = (job: Job) => Promise<any>;
4
+ /**
5
+ * Job class represents a scheduled task with configurable timing and execution options.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const job = new Job("cleanup", async () => {
10
+ * await cleanupOldFiles();
11
+ * })
12
+ * .everyDay()
13
+ * .at("03:00")
14
+ * .inTimezone("America/New_York")
15
+ * .preventOverlap()
16
+ * .retry(3, 1000);
17
+ * ```
18
+ */
19
+ export declare class Job {
20
+ readonly name: string;
21
+ private readonly _callback;
22
+ /**
23
+ * Interval configuration for scheduling
24
+ */
25
+ private _intervals;
26
+ /**
27
+ * Last execution timestamp
28
+ */
29
+ private _lastRun;
30
+ /**
31
+ * Whether the job is currently executing
32
+ */
33
+ private _isRunning;
34
+ /**
35
+ * Skip execution if job is already running
36
+ */
37
+ private _skipIfRunning;
38
+ /**
39
+ * Retry configuration
40
+ */
41
+ private _retryConfig;
42
+ /**
43
+ * Timezone for scheduling (defaults to system timezone)
44
+ */
45
+ private _timezone;
46
+ /**
47
+ * Cron expression parser (mutually exclusive with interval config)
48
+ */
49
+ private _cronParser;
50
+ /**
51
+ * Promise resolver for completion waiting
52
+ */
53
+ private _completionResolver;
54
+ /**
55
+ * Next scheduled execution time
56
+ */
57
+ nextRun: Dayjs | null;
58
+ /**
59
+ * Creates a new Job instance
60
+ *
61
+ * @param name - Unique identifier for the job
62
+ * @param callback - Function to execute when the job runs
63
+ */
64
+ constructor(name: string, _callback: JobCallback);
65
+ /**
66
+ * Returns true if the job is currently executing
67
+ */
68
+ get isRunning(): boolean;
69
+ /**
70
+ * Returns the last execution timestamp
71
+ */
72
+ get lastRun(): Dayjs | null;
73
+ /**
74
+ * Returns the current interval configuration (readonly)
75
+ */
76
+ get intervals(): Readonly<JobIntervals>;
77
+ /**
78
+ * Set a custom interval for job execution
79
+ *
80
+ * @param value - Number of time units
81
+ * @param timeType - Type of time unit
82
+ * @returns this for chaining
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * job.every(5, "minute"); // Run every 5 minutes
87
+ * job.every(2, "hour"); // Run every 2 hours
88
+ * ```
89
+ */
90
+ every(value: number, timeType: TimeType): this;
91
+ /**
92
+ * Run job every second (use with caution - high frequency)
93
+ */
94
+ everySecond(): this;
95
+ /**
96
+ * Run job every specified number of seconds
97
+ */
98
+ everySeconds(seconds: number): this;
99
+ /**
100
+ * Run job every minute
101
+ */
102
+ everyMinute(): this;
103
+ /**
104
+ * Run job every specified number of minutes
105
+ */
106
+ everyMinutes(minutes: number): this;
107
+ /**
108
+ * Run job every hour
109
+ */
110
+ everyHour(): this;
111
+ /**
112
+ * Run job every specified number of hours
113
+ */
114
+ everyHours(hours: number): this;
115
+ /**
116
+ * Run job every day at midnight
117
+ */
118
+ everyDay(): this;
119
+ /**
120
+ * Alias for everyDay()
121
+ */
122
+ daily(): this;
123
+ /**
124
+ * Run job twice a day (every 12 hours)
125
+ */
126
+ twiceDaily(): this;
127
+ /**
128
+ * Run job every week
129
+ */
130
+ everyWeek(): this;
131
+ /**
132
+ * Alias for everyWeek()
133
+ */
134
+ weekly(): this;
135
+ /**
136
+ * Run job every month
137
+ */
138
+ everyMonth(): this;
139
+ /**
140
+ * Alias for everyMonth()
141
+ */
142
+ monthly(): this;
143
+ /**
144
+ * Run job every year
145
+ */
146
+ everyYear(): this;
147
+ /**
148
+ * Alias for everyYear()
149
+ */
150
+ yearly(): this;
151
+ /**
152
+ * Alias for everyMinute() - job runs continuously every minute
153
+ */
154
+ always(): this;
155
+ /**
156
+ * Schedule job using a cron expression
157
+ *
158
+ * Supports standard 5-field cron syntax:
159
+ * ```
160
+ * ┌───────────── minute (0-59)
161
+ * │ ┌───────────── hour (0-23)
162
+ * │ │ ┌───────────── day of month (1-31)
163
+ * │ │ │ ┌───────────── month (1-12)
164
+ * │ │ │ │ ┌───────────── day of week (0-6, Sunday = 0)
165
+ * │ │ │ │ │
166
+ * * * * * *
167
+ * ```
168
+ *
169
+ * Supports:
170
+ * - '*' - any value
171
+ * - '5' - specific value
172
+ * - '1,3,5' - list of values
173
+ * - '1-5' - range of values
174
+ * - 'x/5' - step values (every 5)
175
+ * - '1-10/2' - range with step
176
+ *
177
+ * @param expression - Standard 5-field cron expression
178
+ * @returns this for chaining
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * job.cron("0 9 * * 1-5"); // 9 AM weekdays
183
+ * job.cron("x/5 * * * *"); // Every 5 minutes
184
+ * job.cron("0 0 1 * *"); // First day of month at midnight
185
+ * job.cron("0 x/2 * * *"); // Every 2 hours
186
+ * ```
187
+ */
188
+ cron(expression: string): this;
189
+ /**
190
+ * Get the cron expression if one is set
191
+ */
192
+ get cronExpression(): string | null;
193
+ /**
194
+ * Schedule job on a specific day
195
+ *
196
+ * @param day - Day of week (string) or day of month (number 1-31)
197
+ * @returns this for chaining
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * job.on("monday"); // Run on Mondays
202
+ * job.on(15); // Run on the 15th of each month
203
+ * ```
204
+ */
205
+ on(day: Day | number): this;
206
+ /**
207
+ * Schedule job at a specific time
208
+ *
209
+ * @param time - Time in HH:mm or HH:mm:ss format
210
+ * @returns this for chaining
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * job.daily().at("09:00"); // Run daily at 9 AM
215
+ * job.weekly().at("14:30"); // Run weekly at 2:30 PM
216
+ * ```
217
+ */
218
+ at(time: string): this;
219
+ /**
220
+ * Run task at the beginning of the specified time period
221
+ *
222
+ * @param type - Time type (day, month, year)
223
+ */
224
+ beginOf(type: TimeType): this;
225
+ /**
226
+ * Run task at the end of the specified time period
227
+ *
228
+ * @param type - Time type (day, month, year)
229
+ */
230
+ endOf(type: TimeType): this;
231
+ /**
232
+ * Set the timezone for this job's scheduling
233
+ *
234
+ * @param tz - IANA timezone string (e.g., "America/New_York", "Europe/London")
235
+ * @returns this for chaining
236
+ *
237
+ * @example
238
+ * ```typescript
239
+ * job.daily().at("09:00").inTimezone("America/New_York");
240
+ * ```
241
+ */
242
+ inTimezone(tz: string): this;
243
+ /**
244
+ * Prevent overlapping executions of this job
245
+ *
246
+ * When enabled, if the job is already running when it's scheduled to run again,
247
+ * the new execution will be skipped.
248
+ *
249
+ * @param skip - Whether to skip if already running (default: true)
250
+ * @returns this for chaining
251
+ */
252
+ preventOverlap(skip?: boolean): this;
253
+ /**
254
+ * Configure automatic retry on failure
255
+ *
256
+ * @param maxRetries - Maximum number of retry attempts
257
+ * @param delay - Delay between retries in milliseconds
258
+ * @param backoffMultiplier - Optional multiplier for exponential backoff
259
+ * @returns this for chaining
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * job.retry(3, 1000); // Retry 3 times with 1s delay
264
+ * job.retry(5, 1000, 2); // Exponential backoff: 1s, 2s, 4s, 8s, 16s
265
+ * ```
266
+ */
267
+ retry(maxRetries: number, delay?: number, backoffMultiplier?: number): this;
268
+ /**
269
+ * Terminate the job and clear all scheduling data
270
+ */
271
+ terminate(): this;
272
+ /**
273
+ * Prepare the job by calculating the next run time
274
+ * Called by the scheduler when starting
275
+ */
276
+ prepare(): void;
277
+ /**
278
+ * Determine if the job should run now
279
+ *
280
+ * @returns true if the job should execute
281
+ */
282
+ shouldRun(): boolean;
283
+ /**
284
+ * Execute the job
285
+ *
286
+ * @returns Promise resolving to the job result
287
+ */
288
+ run(): Promise<JobResult>;
289
+ /**
290
+ * Wait for the job to complete
291
+ * Useful for graceful shutdown
292
+ *
293
+ * @returns Promise that resolves when the job completes
294
+ */
295
+ waitForCompletion(): Promise<void>;
296
+ /**
297
+ * Get current time, respecting timezone if set
298
+ */
299
+ private _now;
300
+ /**
301
+ * Execute the callback with retry logic
302
+ */
303
+ private _executeWithRetry;
304
+ /**
305
+ * Calculate retry delay with optional exponential backoff
306
+ */
307
+ private _calculateRetryDelay;
308
+ /**
309
+ * Sleep for specified milliseconds
310
+ */
311
+ private _sleep;
312
+ /**
313
+ * Calculate the next run time based on interval or cron configuration
314
+ */
315
+ private _determineNextRun;
316
+ }
317
+ /**
318
+ * Factory function to create a new Job instance
319
+ *
320
+ * @param name - Unique identifier for the job
321
+ * @param callback - Function to execute when the job runs
322
+ * @returns New Job instance
323
+ *
324
+ * @example
325
+ * ```typescript
326
+ * const cleanupJob = job("cleanup", async () => {
327
+ * await db.deleteExpiredTokens();
328
+ * }).daily().at("03:00");
329
+ * ```
330
+ */
331
+ export declare function job(name: string, callback: JobCallback): Job;
332
+ //# sourceMappingURL=job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../src/job.ts"],"names":[],"mappings":"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"}