@warlock.js/scheduler 4.0.47 → 4.0.57
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/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 -34
- package/cjs/index.js.map +1 -1
- package/cjs/job.d.ts +332 -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 +182 -0
- package/cjs/scheduler.d.ts.map +1 -0
- package/cjs/scheduler.js +313 -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 -5
- package/esm/index.js.map +1 -1
- package/esm/job.d.ts +332 -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 +182 -0
- package/esm/scheduler.d.ts.map +1 -0
- package/esm/scheduler.js +313 -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 +27 -40
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Job, JobCallback } from "./job";
|
|
2
|
+
import type { SchedulerEvents } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Type-safe event emitter interface for Scheduler events
|
|
5
|
+
*/
|
|
6
|
+
interface TypedEventEmitter<TEvents extends Record<string, unknown[]>> {
|
|
7
|
+
on<K extends keyof TEvents>(event: K, listener: (...args: TEvents[K]) => void): this;
|
|
8
|
+
once<K extends keyof TEvents>(event: K, listener: (...args: TEvents[K]) => void): this;
|
|
9
|
+
off<K extends keyof TEvents>(event: K, listener: (...args: TEvents[K]) => void): this;
|
|
10
|
+
emit<K extends keyof TEvents>(event: K, ...args: TEvents[K]): boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const Scheduler_base: new () => TypedEventEmitter<SchedulerEvents>;
|
|
13
|
+
/**
|
|
14
|
+
* Scheduler class manages and executes scheduled jobs.
|
|
15
|
+
*
|
|
16
|
+
* Features:
|
|
17
|
+
* - Event-based observability
|
|
18
|
+
* - Parallel or sequential job execution
|
|
19
|
+
* - Drift compensation for accurate timing
|
|
20
|
+
* - Graceful shutdown with job draining
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const scheduler = new Scheduler();
|
|
25
|
+
*
|
|
26
|
+
* scheduler.on('job:error', (jobName, error) => {
|
|
27
|
+
* logger.error(`Job ${jobName} failed:`, error);
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* scheduler
|
|
31
|
+
* .addJob(cleanupJob)
|
|
32
|
+
* .addJob(reportJob)
|
|
33
|
+
* .runInParallel(true)
|
|
34
|
+
* .start();
|
|
35
|
+
*
|
|
36
|
+
* // Graceful shutdown
|
|
37
|
+
* process.on('SIGTERM', () => scheduler.shutdown());
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare class Scheduler extends Scheduler_base implements TypedEventEmitter<SchedulerEvents> {
|
|
41
|
+
/**
|
|
42
|
+
* List of registered jobs
|
|
43
|
+
*/
|
|
44
|
+
private _jobs;
|
|
45
|
+
/**
|
|
46
|
+
* Reference to the current timeout for stopping
|
|
47
|
+
*/
|
|
48
|
+
private _timeoutId;
|
|
49
|
+
/**
|
|
50
|
+
* Tick interval in milliseconds (how often to check for due jobs)
|
|
51
|
+
*/
|
|
52
|
+
private _tickInterval;
|
|
53
|
+
/**
|
|
54
|
+
* Whether to run due jobs in parallel
|
|
55
|
+
*/
|
|
56
|
+
private _runInParallel;
|
|
57
|
+
/**
|
|
58
|
+
* Maximum concurrent jobs when running in parallel
|
|
59
|
+
*/
|
|
60
|
+
private _maxConcurrency;
|
|
61
|
+
/**
|
|
62
|
+
* Flag indicating scheduler is shutting down
|
|
63
|
+
*/
|
|
64
|
+
private _isShuttingDown;
|
|
65
|
+
/**
|
|
66
|
+
* Returns true if the scheduler is currently running
|
|
67
|
+
*/
|
|
68
|
+
get isRunning(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Returns the number of registered jobs
|
|
71
|
+
*/
|
|
72
|
+
get jobCount(): number;
|
|
73
|
+
/**
|
|
74
|
+
* Add a job to the scheduler
|
|
75
|
+
*
|
|
76
|
+
* @param job - Job instance to schedule
|
|
77
|
+
* @returns this for chaining
|
|
78
|
+
*/
|
|
79
|
+
addJob(job: Job): this;
|
|
80
|
+
/**
|
|
81
|
+
* Alias to create a new job directly and store it
|
|
82
|
+
*/
|
|
83
|
+
newJob(name: string, jobCallback: JobCallback): Job;
|
|
84
|
+
/**
|
|
85
|
+
* Add multiple jobs to the scheduler
|
|
86
|
+
*
|
|
87
|
+
* @param jobs - Array of Job instances
|
|
88
|
+
* @returns this for chaining
|
|
89
|
+
*/
|
|
90
|
+
addJobs(jobs: Job[]): this;
|
|
91
|
+
/**
|
|
92
|
+
* Remove a job from the scheduler by name
|
|
93
|
+
*
|
|
94
|
+
* @param jobName - Name of the job to remove
|
|
95
|
+
* @returns true if job was found and removed
|
|
96
|
+
*/
|
|
97
|
+
removeJob(jobName: string): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Get a job by name
|
|
100
|
+
*
|
|
101
|
+
* @param jobName - Name of the job to find
|
|
102
|
+
* @returns Job instance or undefined
|
|
103
|
+
*/
|
|
104
|
+
getJob(jobName: string): Job | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Get all registered jobs
|
|
107
|
+
*
|
|
108
|
+
* @returns Array of registered jobs (readonly)
|
|
109
|
+
*/
|
|
110
|
+
list(): readonly Job[];
|
|
111
|
+
/**
|
|
112
|
+
* Set the tick interval (how often to check for due jobs)
|
|
113
|
+
*
|
|
114
|
+
* @param ms - Interval in milliseconds (minimum 100ms)
|
|
115
|
+
* @returns this for chaining
|
|
116
|
+
*/
|
|
117
|
+
runEvery(ms: number): this;
|
|
118
|
+
/**
|
|
119
|
+
* Configure whether jobs should run in parallel
|
|
120
|
+
*
|
|
121
|
+
* @param parallel - Enable parallel execution
|
|
122
|
+
* @param maxConcurrency - Maximum concurrent jobs (default: 10)
|
|
123
|
+
* @returns this for chaining
|
|
124
|
+
*/
|
|
125
|
+
runInParallel(parallel: boolean, maxConcurrency?: number): this;
|
|
126
|
+
/**
|
|
127
|
+
* Start the scheduler
|
|
128
|
+
*
|
|
129
|
+
* @throws Error if scheduler is already running
|
|
130
|
+
*/
|
|
131
|
+
start(): void;
|
|
132
|
+
/**
|
|
133
|
+
* Stop the scheduler immediately
|
|
134
|
+
*
|
|
135
|
+
* Note: This does not wait for running jobs to complete.
|
|
136
|
+
* Use shutdown() for graceful termination.
|
|
137
|
+
*/
|
|
138
|
+
stop(): void;
|
|
139
|
+
/**
|
|
140
|
+
* Gracefully shutdown the scheduler
|
|
141
|
+
*
|
|
142
|
+
* Stops scheduling new jobs and waits for currently running jobs to complete.
|
|
143
|
+
*
|
|
144
|
+
* @param timeout - Maximum time to wait for jobs (default: 30000ms)
|
|
145
|
+
* @returns Promise that resolves when shutdown is complete
|
|
146
|
+
*/
|
|
147
|
+
shutdown(timeout?: number): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* Schedule the next tick
|
|
150
|
+
*/
|
|
151
|
+
private _scheduleTick;
|
|
152
|
+
/**
|
|
153
|
+
* Execute a scheduler tick - check and run due jobs
|
|
154
|
+
*/
|
|
155
|
+
private _tick;
|
|
156
|
+
/**
|
|
157
|
+
* Run jobs sequentially
|
|
158
|
+
*/
|
|
159
|
+
private _runJobsSequentially;
|
|
160
|
+
/**
|
|
161
|
+
* Run jobs in parallel with concurrency limit
|
|
162
|
+
*/
|
|
163
|
+
private _runJobsInParallel;
|
|
164
|
+
/**
|
|
165
|
+
* Run a single job and emit events
|
|
166
|
+
*/
|
|
167
|
+
private _runJob;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Default scheduler instance for simple use cases
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* import { scheduler, job } from "@warlock.js/scheduler";
|
|
175
|
+
*
|
|
176
|
+
* scheduler.addJob(job("cleanup", cleanupFn).daily());
|
|
177
|
+
* scheduler.start();
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
export declare const scheduler: Scheduler;
|
|
181
|
+
export {};
|
|
182
|
+
//# sourceMappingURL=scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../src/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAa,eAAe,EAAE,MAAM,SAAS,CAAC;AAE1D;;GAEG;AACH,UAAU,iBAAiB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;IACnE,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrF,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvF,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACtF,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACvE;wCA8BoC,kBAAkB,eAAe,CAAC;AA5BvE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,SACX,SAAQ,cACR,YAAW,iBAAiB,CAAC,eAAe,CAAC;IAM7C;;OAEG;IACH,OAAO,CAAC,KAAK,CAAa;IAE1B;;OAEG;IACH,OAAO,CAAC,UAAU,CAA+B;IAEjD;;OAEG;IACH,OAAO,CAAC,aAAa,CAAQ;IAE7B;;OAEG;IACH,OAAO,CAAC,cAAc,CAAS;IAE/B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAM;IAE7B;;OAEG;IACH,OAAO,CAAC,eAAe,CAAS;IAMhC;;OAEG;IACH,IAAW,SAAS,IAAI,OAAO,CAE9B;IAED;;OAEG;IACH,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAMD;;;;;OAKG;IACI,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAK7B;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW;IAMpD;;;;;OAKG;IACI,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAKjC;;;;;OAKG;IACI,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAS1C;;;;;OAKG;IACI,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAI/C;;;;OAIG;IACI,IAAI,IAAI,SAAS,GAAG,EAAE;IAI7B;;;;;OAKG;IACI,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQjC;;;;;;OAMG;IACI,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,cAAc,SAAK,GAAG,IAAI;IAUlE;;;;OAIG;IACI,KAAK,IAAI,IAAI;IAoBpB;;;;;OAKG;IACI,IAAI,IAAI,IAAI;IASnB;;;;;;;OAOG;IACU,QAAQ,CAAC,OAAO,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBrD;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;YACW,KAAK;IAyBnB;;OAEG;YACW,oBAAoB;IAOlC;;OAEG;YACW,kBAAkB;IAchC;;OAEG;YACW,OAAO;CAatB;AAMD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,WAAkB,CAAC"}
|
package/cjs/scheduler.js
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
'use strict';var events=require('events'),job=require('./job.js');/**
|
|
2
|
+
* Scheduler class manages and executes scheduled jobs.
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Event-based observability
|
|
6
|
+
* - Parallel or sequential job execution
|
|
7
|
+
* - Drift compensation for accurate timing
|
|
8
|
+
* - Graceful shutdown with job draining
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const scheduler = new Scheduler();
|
|
13
|
+
*
|
|
14
|
+
* scheduler.on('job:error', (jobName, error) => {
|
|
15
|
+
* logger.error(`Job ${jobName} failed:`, error);
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* scheduler
|
|
19
|
+
* .addJob(cleanupJob)
|
|
20
|
+
* .addJob(reportJob)
|
|
21
|
+
* .runInParallel(true)
|
|
22
|
+
* .start();
|
|
23
|
+
*
|
|
24
|
+
* // Graceful shutdown
|
|
25
|
+
* process.on('SIGTERM', () => scheduler.shutdown());
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
class Scheduler extends events.EventEmitter {
|
|
29
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
// Private Properties
|
|
31
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* List of registered jobs
|
|
34
|
+
*/
|
|
35
|
+
_jobs = [];
|
|
36
|
+
/**
|
|
37
|
+
* Reference to the current timeout for stopping
|
|
38
|
+
*/
|
|
39
|
+
_timeoutId = null;
|
|
40
|
+
/**
|
|
41
|
+
* Tick interval in milliseconds (how often to check for due jobs)
|
|
42
|
+
*/
|
|
43
|
+
_tickInterval = 1000;
|
|
44
|
+
/**
|
|
45
|
+
* Whether to run due jobs in parallel
|
|
46
|
+
*/
|
|
47
|
+
_runInParallel = false;
|
|
48
|
+
/**
|
|
49
|
+
* Maximum concurrent jobs when running in parallel
|
|
50
|
+
*/
|
|
51
|
+
_maxConcurrency = 10;
|
|
52
|
+
/**
|
|
53
|
+
* Flag indicating scheduler is shutting down
|
|
54
|
+
*/
|
|
55
|
+
_isShuttingDown = false;
|
|
56
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
57
|
+
// Public Getters
|
|
58
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Returns true if the scheduler is currently running
|
|
61
|
+
*/
|
|
62
|
+
get isRunning() {
|
|
63
|
+
return this._timeoutId !== null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns the number of registered jobs
|
|
67
|
+
*/
|
|
68
|
+
get jobCount() {
|
|
69
|
+
return this._jobs.length;
|
|
70
|
+
}
|
|
71
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
72
|
+
// Configuration Methods (Fluent API)
|
|
73
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
74
|
+
/**
|
|
75
|
+
* Add a job to the scheduler
|
|
76
|
+
*
|
|
77
|
+
* @param job - Job instance to schedule
|
|
78
|
+
* @returns this for chaining
|
|
79
|
+
*/
|
|
80
|
+
addJob(job) {
|
|
81
|
+
this._jobs.push(job);
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Alias to create a new job directly and store it
|
|
86
|
+
*/
|
|
87
|
+
newJob(name, jobCallback) {
|
|
88
|
+
const job$1 = new job.Job(name, jobCallback);
|
|
89
|
+
this.addJob(job$1);
|
|
90
|
+
return job$1;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Add multiple jobs to the scheduler
|
|
94
|
+
*
|
|
95
|
+
* @param jobs - Array of Job instances
|
|
96
|
+
* @returns this for chaining
|
|
97
|
+
*/
|
|
98
|
+
addJobs(jobs) {
|
|
99
|
+
this._jobs.push(...jobs);
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Remove a job from the scheduler by name
|
|
104
|
+
*
|
|
105
|
+
* @param jobName - Name of the job to remove
|
|
106
|
+
* @returns true if job was found and removed
|
|
107
|
+
*/
|
|
108
|
+
removeJob(jobName) {
|
|
109
|
+
const index = this._jobs.findIndex((j) => j.name === jobName);
|
|
110
|
+
if (index !== -1) {
|
|
111
|
+
this._jobs.splice(index, 1);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get a job by name
|
|
118
|
+
*
|
|
119
|
+
* @param jobName - Name of the job to find
|
|
120
|
+
* @returns Job instance or undefined
|
|
121
|
+
*/
|
|
122
|
+
getJob(jobName) {
|
|
123
|
+
return this._jobs.find((j) => j.name === jobName);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get all registered jobs
|
|
127
|
+
*
|
|
128
|
+
* @returns Array of registered jobs (readonly)
|
|
129
|
+
*/
|
|
130
|
+
list() {
|
|
131
|
+
return this._jobs;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Set the tick interval (how often to check for due jobs)
|
|
135
|
+
*
|
|
136
|
+
* @param ms - Interval in milliseconds (minimum 100ms)
|
|
137
|
+
* @returns this for chaining
|
|
138
|
+
*/
|
|
139
|
+
runEvery(ms) {
|
|
140
|
+
if (ms < 100) {
|
|
141
|
+
throw new Error("Tick interval must be at least 100ms");
|
|
142
|
+
}
|
|
143
|
+
this._tickInterval = ms;
|
|
144
|
+
return this;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Configure whether jobs should run in parallel
|
|
148
|
+
*
|
|
149
|
+
* @param parallel - Enable parallel execution
|
|
150
|
+
* @param maxConcurrency - Maximum concurrent jobs (default: 10)
|
|
151
|
+
* @returns this for chaining
|
|
152
|
+
*/
|
|
153
|
+
runInParallel(parallel, maxConcurrency = 10) {
|
|
154
|
+
this._runInParallel = parallel;
|
|
155
|
+
this._maxConcurrency = maxConcurrency;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
159
|
+
// Lifecycle Methods
|
|
160
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
161
|
+
/**
|
|
162
|
+
* Start the scheduler
|
|
163
|
+
*
|
|
164
|
+
* @throws Error if scheduler is already running
|
|
165
|
+
*/
|
|
166
|
+
start() {
|
|
167
|
+
if (this.isRunning) {
|
|
168
|
+
throw new Error("Scheduler is already running.");
|
|
169
|
+
}
|
|
170
|
+
if (this._jobs.length === 0) {
|
|
171
|
+
throw new Error("Cannot start scheduler with no jobs.");
|
|
172
|
+
}
|
|
173
|
+
// Prepare all jobs (calculate initial next run times)
|
|
174
|
+
for (const job of this._jobs) {
|
|
175
|
+
job.prepare();
|
|
176
|
+
}
|
|
177
|
+
this._isShuttingDown = false;
|
|
178
|
+
this._scheduleTick();
|
|
179
|
+
this.emit("scheduler:started");
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Stop the scheduler immediately
|
|
183
|
+
*
|
|
184
|
+
* Note: This does not wait for running jobs to complete.
|
|
185
|
+
* Use shutdown() for graceful termination.
|
|
186
|
+
*/
|
|
187
|
+
stop() {
|
|
188
|
+
if (this._timeoutId) {
|
|
189
|
+
clearTimeout(this._timeoutId);
|
|
190
|
+
this._timeoutId = null;
|
|
191
|
+
}
|
|
192
|
+
this.emit("scheduler:stopped");
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Gracefully shutdown the scheduler
|
|
196
|
+
*
|
|
197
|
+
* Stops scheduling new jobs and waits for currently running jobs to complete.
|
|
198
|
+
*
|
|
199
|
+
* @param timeout - Maximum time to wait for jobs (default: 30000ms)
|
|
200
|
+
* @returns Promise that resolves when shutdown is complete
|
|
201
|
+
*/
|
|
202
|
+
async shutdown(timeout = 30000) {
|
|
203
|
+
this._isShuttingDown = true;
|
|
204
|
+
this.stop();
|
|
205
|
+
// Get all currently running jobs
|
|
206
|
+
const runningJobs = this._jobs.filter((j) => j.isRunning);
|
|
207
|
+
if (runningJobs.length > 0) {
|
|
208
|
+
// Wait for jobs to complete or timeout
|
|
209
|
+
await Promise.race([
|
|
210
|
+
Promise.all(runningJobs.map((j) => j.waitForCompletion())),
|
|
211
|
+
new Promise((resolve) => setTimeout(resolve, timeout)),
|
|
212
|
+
]);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
216
|
+
// Private Methods
|
|
217
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
218
|
+
/**
|
|
219
|
+
* Schedule the next tick
|
|
220
|
+
*/
|
|
221
|
+
_scheduleTick() {
|
|
222
|
+
if (this._isShuttingDown)
|
|
223
|
+
return;
|
|
224
|
+
const startTime = Date.now();
|
|
225
|
+
// Use setImmediate for first tick to allow event handlers to be registered
|
|
226
|
+
this._timeoutId = setTimeout(async () => {
|
|
227
|
+
await this._tick();
|
|
228
|
+
// Calculate time spent and adjust next tick for drift compensation
|
|
229
|
+
const elapsed = Date.now() - startTime;
|
|
230
|
+
Math.max(this._tickInterval - elapsed, 0);
|
|
231
|
+
this._scheduleTick();
|
|
232
|
+
}, this._tickInterval);
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Execute a scheduler tick - check and run due jobs
|
|
236
|
+
*/
|
|
237
|
+
async _tick() {
|
|
238
|
+
this.emit("scheduler:tick", new Date());
|
|
239
|
+
// Find jobs that should run
|
|
240
|
+
const dueJobs = this._jobs.filter((job) => {
|
|
241
|
+
if (!job.shouldRun())
|
|
242
|
+
return false;
|
|
243
|
+
// Skip if overlap prevention is enabled and job is running
|
|
244
|
+
if (job.isRunning) {
|
|
245
|
+
this.emit("job:skip", job.name, "Job is already running");
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
return true;
|
|
249
|
+
});
|
|
250
|
+
if (dueJobs.length === 0)
|
|
251
|
+
return;
|
|
252
|
+
if (this._runInParallel) {
|
|
253
|
+
await this._runJobsInParallel(dueJobs);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
await this._runJobsSequentially(dueJobs);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Run jobs sequentially
|
|
261
|
+
*/
|
|
262
|
+
async _runJobsSequentially(jobs) {
|
|
263
|
+
for (const job of jobs) {
|
|
264
|
+
if (this._isShuttingDown)
|
|
265
|
+
break;
|
|
266
|
+
await this._runJob(job);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Run jobs in parallel with concurrency limit
|
|
271
|
+
*/
|
|
272
|
+
async _runJobsInParallel(jobs) {
|
|
273
|
+
// Simple batching for concurrency control
|
|
274
|
+
const batches = [];
|
|
275
|
+
for (let i = 0; i < jobs.length; i += this._maxConcurrency) {
|
|
276
|
+
batches.push(jobs.slice(i, i + this._maxConcurrency));
|
|
277
|
+
}
|
|
278
|
+
for (const batch of batches) {
|
|
279
|
+
if (this._isShuttingDown)
|
|
280
|
+
break;
|
|
281
|
+
await Promise.allSettled(batch.map((job) => this._runJob(job)));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Run a single job and emit events
|
|
286
|
+
*/
|
|
287
|
+
async _runJob(job) {
|
|
288
|
+
this.emit("job:start", job.name);
|
|
289
|
+
const result = await job.run();
|
|
290
|
+
if (result.success) {
|
|
291
|
+
this.emit("job:complete", job.name, result);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
this.emit("job:error", job.name, result.error);
|
|
295
|
+
}
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
300
|
+
// Default Export
|
|
301
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
302
|
+
/**
|
|
303
|
+
* Default scheduler instance for simple use cases
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```typescript
|
|
307
|
+
* import { scheduler, job } from "@warlock.js/scheduler";
|
|
308
|
+
*
|
|
309
|
+
* scheduler.addJob(job("cleanup", cleanupFn).daily());
|
|
310
|
+
* scheduler.start();
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
const scheduler = new Scheduler();exports.Scheduler=Scheduler;exports.scheduler=scheduler;//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sources":["../src/scheduler.ts"],"sourcesContent":[null],"names":["EventEmitter","job","Job"],"mappings":"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"}
|
package/cjs/types.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time unit types for scheduling intervals
|
|
3
|
+
*/
|
|
4
|
+
export type TimeType = "second" | "minute" | "hour" | "day" | "week" | "month" | "year";
|
|
5
|
+
/**
|
|
6
|
+
* Days of the week (lowercase for consistency)
|
|
7
|
+
*/
|
|
8
|
+
export type Day = "sunday" | "monday" | "tuesday" | "wednesday" | "thursday" | "friday" | "saturday";
|
|
9
|
+
/**
|
|
10
|
+
* Job interval configuration
|
|
11
|
+
*/
|
|
12
|
+
export type JobIntervals = {
|
|
13
|
+
/** Day of week or day of month */
|
|
14
|
+
day?: Day | number;
|
|
15
|
+
/** Time of day in HH:mm format */
|
|
16
|
+
time?: string;
|
|
17
|
+
/** Recurring interval configuration */
|
|
18
|
+
every?: {
|
|
19
|
+
type?: TimeType;
|
|
20
|
+
value?: number;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Result of a job execution
|
|
25
|
+
*/
|
|
26
|
+
export type JobResult = {
|
|
27
|
+
/** Whether the job completed successfully */
|
|
28
|
+
success: boolean;
|
|
29
|
+
/** Execution duration in milliseconds */
|
|
30
|
+
duration: number;
|
|
31
|
+
/** Error if the job failed */
|
|
32
|
+
error?: unknown;
|
|
33
|
+
/** Number of retry attempts made */
|
|
34
|
+
retries?: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Job execution status
|
|
38
|
+
*/
|
|
39
|
+
export type JobStatus = "idle" | "running" | "completed" | "failed";
|
|
40
|
+
/**
|
|
41
|
+
* Retry configuration for jobs
|
|
42
|
+
*/
|
|
43
|
+
export type RetryConfig = {
|
|
44
|
+
/** Maximum number of retry attempts */
|
|
45
|
+
maxRetries: number;
|
|
46
|
+
/** Delay between retries in milliseconds */
|
|
47
|
+
delay: number;
|
|
48
|
+
/** Backoff multiplier for exponential backoff */
|
|
49
|
+
backoffMultiplier?: number;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Scheduler event types for observability
|
|
53
|
+
*/
|
|
54
|
+
export type SchedulerEvents = {
|
|
55
|
+
"job:start": [jobName: string];
|
|
56
|
+
"job:complete": [jobName: string, result: JobResult];
|
|
57
|
+
"job:error": [jobName: string, error: unknown];
|
|
58
|
+
"job:skip": [jobName: string, reason: string];
|
|
59
|
+
"scheduler:started": [];
|
|
60
|
+
"scheduler:stopped": [];
|
|
61
|
+
"scheduler:tick": [timestamp: Date];
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAExF;;GAEG;AACH,MAAM,MAAM,GAAG,GACX,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,WAAW,GACX,UAAU,GACV,QAAQ,GACR,UAAU,CAAC;AAEf;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,kCAAkC;IAClC,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC;IACnB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,QAAQ,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IACtB,6CAA6C;IAC7C,OAAO,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEpE;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,uCAAuC;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IACrD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAC/C,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,mBAAmB,EAAE,EAAE,CAAC;IACxB,mBAAmB,EAAE,EAAE,CAAC;IACxB,gBAAgB,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;CACrC,CAAC"}
|
package/cjs/utils.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAE9B,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,UAU1C"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type Dayjs } from "dayjs";
|
|
2
|
+
/**
|
|
3
|
+
* Parsed cron expression fields
|
|
4
|
+
*/
|
|
5
|
+
export type CronFields = {
|
|
6
|
+
/** Minutes (0-59) */
|
|
7
|
+
minutes: number[];
|
|
8
|
+
/** Hours (0-23) */
|
|
9
|
+
hours: number[];
|
|
10
|
+
/** Days of month (1-31) */
|
|
11
|
+
daysOfMonth: number[];
|
|
12
|
+
/** Months (1-12) */
|
|
13
|
+
months: number[];
|
|
14
|
+
/** Days of week (0-6, Sunday = 0) */
|
|
15
|
+
daysOfWeek: number[];
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Cron expression parser
|
|
19
|
+
*
|
|
20
|
+
* Supports standard 5-field cron expressions:
|
|
21
|
+
* ```
|
|
22
|
+
* ┌───────────── minute (0-59)
|
|
23
|
+
* │ ┌───────────── hour (0-23)
|
|
24
|
+
* │ │ ┌───────────── day of month (1-31)
|
|
25
|
+
* │ │ │ ┌───────────── month (1-12)
|
|
26
|
+
* │ │ │ │ ┌───────────── day of week (0-6, Sunday = 0)
|
|
27
|
+
* │ │ │ │ │
|
|
28
|
+
* * * * * *
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Supports:
|
|
32
|
+
* - `*` - any value
|
|
33
|
+
* - `5` - specific value
|
|
34
|
+
* - `1,3,5` - list of values
|
|
35
|
+
* - `1-5` - range of values
|
|
36
|
+
* - `* /5` - step values (every 5)
|
|
37
|
+
* - `1-10/2` - range with step
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const parser = new CronParser("0 9 * * 1-5"); // 9 AM weekdays
|
|
42
|
+
* const nextRun = parser.nextRun();
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare class CronParser {
|
|
46
|
+
private readonly _expression;
|
|
47
|
+
private readonly _fields;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a new CronParser instance
|
|
50
|
+
*
|
|
51
|
+
* @param expression - Standard 5-field cron expression
|
|
52
|
+
* @throws Error if expression is invalid
|
|
53
|
+
*/
|
|
54
|
+
constructor(_expression: string);
|
|
55
|
+
/**
|
|
56
|
+
* Get the parsed cron fields
|
|
57
|
+
*/
|
|
58
|
+
get fields(): Readonly<CronFields>;
|
|
59
|
+
/**
|
|
60
|
+
* Get the original expression
|
|
61
|
+
*/
|
|
62
|
+
get expression(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Calculate the next run time from a given date
|
|
65
|
+
*
|
|
66
|
+
* @param from - Starting date (defaults to now)
|
|
67
|
+
* @returns Next run time as Dayjs
|
|
68
|
+
*/
|
|
69
|
+
nextRun(from?: Dayjs): Dayjs;
|
|
70
|
+
/**
|
|
71
|
+
* Check if a given date matches the cron expression
|
|
72
|
+
*
|
|
73
|
+
* @param date - Date to check
|
|
74
|
+
* @returns true if the date matches
|
|
75
|
+
*/
|
|
76
|
+
matches(date: Dayjs): boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Parse a cron expression into fields
|
|
79
|
+
*/
|
|
80
|
+
private _parse;
|
|
81
|
+
/**
|
|
82
|
+
* Parse a single cron field
|
|
83
|
+
*
|
|
84
|
+
* @param field - Field value (e.g., "*", "5", "1-5", "* /2", "1,3,5")
|
|
85
|
+
* @param min - Minimum allowed value
|
|
86
|
+
* @param max - Maximum allowed value
|
|
87
|
+
* @returns Array of matching values
|
|
88
|
+
*/
|
|
89
|
+
private _parseField;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Parse a cron expression string
|
|
93
|
+
*
|
|
94
|
+
* @param expression - Cron expression (5 fields)
|
|
95
|
+
* @returns CronParser instance
|
|
96
|
+
*/
|
|
97
|
+
export declare function parseCron(expression: string): CronParser;
|
|
98
|
+
//# sourceMappingURL=cron-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-parser.d.ts","sourceRoot":"","sources":["../src/cron-parser.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,KAAK,EAAE,MAAM,OAAO,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,qBAAqB;IACrB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mBAAmB;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,2BAA2B;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oBAAoB;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,qCAAqC;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,UAAU;IASF,OAAO,CAAC,QAAQ,CAAC,WAAW;IAR/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IAErC;;;;;OAKG;gBACiC,WAAW,EAAE,MAAM;IAIvD;;OAEG;IACH,IAAW,MAAM,IAAI,QAAQ,CAAC,UAAU,CAAC,CAExC;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,MAAM,CAE9B;IAED;;;;;OAKG;IACI,OAAO,CAAC,IAAI,GAAE,KAAe,GAAG,KAAK;IA+C5C;;;;;OAKG;IACI,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO;IAUpC;;OAEG;IACH,OAAO,CAAC,MAAM;IAoBd;;;;;;;OAOG;IACH,OAAO,CAAC,WAAW;CA2DpB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAExD"}
|