croner 3.0.49 → 4.0.53
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 +44 -34
- package/dist/croner.min.js +1 -1
- package/dist/croner.min.mjs +1 -1
- package/dist-legacy/croner.cjs +1 -1
- package/package.json +7 -5
- package/src/croner.js +95 -127
- package/src/date.js +59 -33
- package/src/pattern.js +1 -14
- package/test/src/suite.cjs +110 -7
- package/types/croner.d.ts +28 -26
- package/types/date.d.ts +3 -2
package/README.md
CHANGED
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
[](https://travis-ci.org/Hexagon/croner) [](https://badge.fury.io/js/croner) [](https://www.codacy.com/gh/Hexagon/croner/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Hexagon/croner&utm_campaign=Badge_Grade)
|
|
4
4
|
[](https://github.com/Hexagon/croner/blob/master/LICENSE) [](https://www.jsdelivr.com/package/npm/croner)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
* Trigger functions in javascript using [Cron](https://en.wikipedia.org/wiki/Cron#CRON_expression) syntax.
|
|
7
|
+
* Pause, resume or stop exection efter a task is scheduled.
|
|
8
|
+
* Find first date of next month, find date of next tuesday, etc.
|
|
9
|
+
* Supports Node.js from 4.0 to current. Both require (commonjs) and import (module).
|
|
10
|
+
* Supports browser use ([UMD](https://github.com/umdjs/umd) (standalone, requirejs etc.), [ES-module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules))
|
|
11
|
+
* *Experimental:* Schedule in other timezone than default.
|
|
7
12
|
|
|
8
13
|
Documented with [JSDoc](https://jsdoc.app/) for intellisense, and include [TypeScript](https://www.typescriptlang.org/) typings.
|
|
9
14
|
|
|
10
15
|
```html
|
|
11
|
-
<script src="https://cdn.jsdelivr.net/npm/croner@
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.js"></script>
|
|
12
17
|
```
|
|
13
18
|
|
|
14
19
|
```javascript
|
|
@@ -16,15 +21,18 @@ Documented with [JSDoc](https://jsdoc.app/) for intellisense, and include [TypeS
|
|
|
16
21
|
Cron('* * * * * *', function () {
|
|
17
22
|
console.log('This will run every second');
|
|
18
23
|
});
|
|
24
|
+
|
|
25
|
+
// What date is next sunday?
|
|
26
|
+
console.log(Cron('0 0 0 * * 7').next().toLocaleDateString());
|
|
19
27
|
```
|
|
20
28
|
|
|
21
29
|
## Installation
|
|
22
30
|
|
|
23
31
|
### Manual
|
|
24
32
|
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
33
|
+
* Download latest [zipball](http://github.com/Hexagon/croner/zipball/master/)
|
|
34
|
+
* Unpack
|
|
35
|
+
* Grab ```croner.min.js``` ([UMD](https://github.com/umdjs/umd)) or ```croner.min.mjs``` ([ES-module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)) from the [dist/](/dist) folder
|
|
28
36
|
|
|
29
37
|
### Node.js
|
|
30
38
|
|
|
@@ -46,14 +54,14 @@ const Cron = require("croner");
|
|
|
46
54
|
To use as a [UMD](https://github.com/umdjs/umd)-module (stand alone, [RequireJS](https://requirejs.org/) etc.)
|
|
47
55
|
|
|
48
56
|
```html
|
|
49
|
-
<script src="https://cdn.jsdelivr.net/npm/croner@
|
|
57
|
+
<script src="https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.js"></script>
|
|
50
58
|
```
|
|
51
59
|
|
|
52
60
|
To use as a [ES-module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)
|
|
53
61
|
|
|
54
62
|
```html
|
|
55
63
|
<script type="module">
|
|
56
|
-
import Cron from "https://cdn.jsdelivr.net/npm/croner@
|
|
64
|
+
import Cron from "https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.mjs";
|
|
57
65
|
|
|
58
66
|
// ... see usage section ...
|
|
59
67
|
</script>
|
|
@@ -64,7 +72,7 @@ To use as a [ES-module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/
|
|
|
64
72
|
<script type="importmap">
|
|
65
73
|
{
|
|
66
74
|
"imports": {
|
|
67
|
-
"croner": "https://cdn.jsdelivr.net/npm/croner@
|
|
75
|
+
"croner": "https://cdn.jsdelivr.net/npm/croner@4/dist/croner.min.mjs"
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
</script>
|
|
@@ -85,10 +93,20 @@ Cron('* * * * * *', function () {
|
|
|
85
93
|
});
|
|
86
94
|
```
|
|
87
95
|
|
|
96
|
+
### Find dates
|
|
97
|
+
```javascript
|
|
98
|
+
// Find next month
|
|
99
|
+
let nextMonth = Cron('0 0 0 1 * *').next(),
|
|
100
|
+
nextSunday = Cron('0 0 0 * * 7').next();
|
|
101
|
+
|
|
102
|
+
console.log("First day of next month: " + nextMonth.toLocaleDateString());
|
|
103
|
+
console.log("Next sunday: " + nextSunday.toLocaleDateString());
|
|
104
|
+
```
|
|
105
|
+
|
|
88
106
|
### Minimalist scheduling with stepping and custom timezone
|
|
89
107
|
```javascript
|
|
90
108
|
// Run a function every fifth second
|
|
91
|
-
Cron('*/5 * * * * *', { timezone: 'Europe/Stockholm' } function () {
|
|
109
|
+
Cron('*/5 * * * * *', { timezone: 'Europe/Stockholm' }, function () {
|
|
92
110
|
console.log('This will run every fifth second');
|
|
93
111
|
});
|
|
94
112
|
```
|
|
@@ -142,49 +160,41 @@ scheduler.schedule(function() {
|
|
|
142
160
|
```javascript
|
|
143
161
|
|
|
144
162
|
// Run every minute
|
|
145
|
-
var scheduler = Cron('0 * * * * *');
|
|
163
|
+
var scheduler = Cron('0 * * * * *', { maxRuns: 5 });
|
|
146
164
|
|
|
147
165
|
// Schedule with options (all options are optional)
|
|
148
|
-
scheduler.schedule(
|
|
166
|
+
scheduler.schedule(function() {
|
|
149
167
|
console.log('This will run every minute.');
|
|
150
168
|
});
|
|
151
169
|
```
|
|
152
|
-
### Scheduling with
|
|
170
|
+
### Scheduling with controls
|
|
153
171
|
```javascript
|
|
154
172
|
let scheduler = Cron('* * * * * *')
|
|
155
173
|
|
|
156
|
-
|
|
174
|
+
scheduler.schedule(function () {
|
|
157
175
|
console.log('This will run every second. Pause on second 10. Resume on second 15. And quit on second 20.');
|
|
158
176
|
console.log('Current second: ', new Date().getSeconds());
|
|
159
|
-
console.log('Previous run: ' + scheduler.
|
|
177
|
+
console.log('Previous run: ' + scheduler.previous());
|
|
160
178
|
console.log('Next run: ' + scheduler.next());
|
|
161
179
|
});
|
|
162
180
|
|
|
163
|
-
Cron('10 * * * * *', {maxRuns: 1}, () =>
|
|
164
|
-
Cron('15 * * * * *', {maxRuns: 1}, () =>
|
|
165
|
-
Cron('20 * * * * *', {maxRuns: 1}, () =>
|
|
181
|
+
Cron('10 * * * * *', {maxRuns: 1}, () => scheduler.pause());
|
|
182
|
+
Cron('15 * * * * *', {maxRuns: 1}, () => scheduler.resume());
|
|
183
|
+
Cron('20 * * * * *', {maxRuns: 1}, () => scheduler.stop());
|
|
166
184
|
```
|
|
167
185
|
|
|
168
186
|
## Full API
|
|
169
187
|
```javascript
|
|
170
188
|
|
|
171
|
-
var
|
|
172
|
-
```
|
|
173
|
-
```javascript
|
|
174
|
-
// If Cron is initialized without a scheduled function, cron itself is returned
|
|
175
|
-
// and the following member functions is available.
|
|
176
|
-
o.next( [ <date previous> ] );
|
|
177
|
-
o.msToNext();
|
|
178
|
-
o.previous();
|
|
179
|
-
|
|
180
|
-
// If Cron is initialized _with_ a scheduled function, the job is retured instead.
|
|
181
|
-
// Otherwise you get a reference to the job when scheduling a new job.
|
|
182
|
-
var job = o.schedule( [ { startAt: <date|string>, stopAt: <date|string>, maxRuns: <integer>, timezone: <string> } ,] callback);
|
|
189
|
+
var scheduler = Cron( <string pattern> [, { startAt: <date|string>, stopAt: <date|string>, maxRuns: <integer>, timezone: <string> } ] [, <function job> ] )
|
|
183
190
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
191
|
+
scheduler.next( [ <date previous> ] );
|
|
192
|
+
scheduler.msToNext( [ <date previous> ] );
|
|
193
|
+
scheduler.previous();
|
|
194
|
+
scheduler.schedule( <fn job> );
|
|
195
|
+
scheduler.pause();
|
|
196
|
+
scheduler.resume();
|
|
197
|
+
scheduler.stop();
|
|
188
198
|
|
|
189
199
|
```
|
|
190
200
|
|
|
@@ -204,4 +214,4 @@ job.stop();
|
|
|
204
214
|
|
|
205
215
|
## License
|
|
206
216
|
|
|
207
|
-
MIT
|
|
217
|
+
MIT
|
package/dist/croner.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Cron=e():t.Cron=e()}(this,(function(){return(()=>{"use strict";var t={d:(e,r)=>{for(var
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Cron=e():t.Cron=e()}(this,(function(){return(()=>{"use strict";var t={d:(e,r)=>{for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>i});function r(t,e){if(this.timezone=e,t&&t instanceof Date)this.fromDate(t);else if(void 0===t)this.fromDate(new Date);else if(t&&"string"==typeof t)this.fromString(t);else{if(!(t instanceof r))throw new TypeError("CronDate: Invalid type ("+typeof t+") passed as parameter to CronDate constructor");this.fromCronDate(t)}}function o(t){this.pattern=t,this.seconds=Array(60).fill(0),this.minutes=Array(60).fill(0),this.hours=Array(24).fill(0),this.days=Array(31).fill(0),this.months=Array(12).fill(0),this.daysOfWeek=Array(8).fill(0),this.parse()}r.prototype.fromDate=function(t){let e=t.getTime();this.timezone&&(t=function(t,e){return new Date(t.toLocaleString("en-US",{timeZone:e}))}(t,this.timezone));let r=t.getTime();this.UTCmsOffset=r-e,this.milliseconds=t.getMilliseconds(),this.seconds=t.getSeconds(),this.minutes=t.getMinutes(),this.hours=t.getHours(),this.days=t.getDate(),this.months=t.getMonth(),this.years=t.getFullYear()},r.prototype.fromCronDate=function(t){this.UTCmsOffset=t.UTCmsOffset,this.timezone=t.timezone;let e=new Date(t.years,t.months,t.days,t.hours,t.minutes,t.seconds,t.milliseconds);this.milliseconds=e.getMilliseconds(),this.seconds=e.getSeconds(),this.minutes=e.getMinutes(),this.hours=e.getHours(),this.days=e.getDate(),this.months=e.getMonth(),this.years=e.getFullYear()},r.prototype.fromString=function(t){let e=Date.parse(t);if(isNaN(e))throw new TypeError("CronDate: Provided string value for CronDate could not be parsed as date.");this.fromDate(new Date(e))},r.prototype.increment=function(t,e){e||(this.seconds+=1);let o=this.getTime();this.milliseconds=0;let n=this,s=function(t,e,r,o){for(let s=void 0===o?n[t]+r:0+r;s<e[t].length;s++)if(e[t][s])return n[t]=s-r,!0;return!1},i=function(){for(;h>=0;)s(a[h][0],t,a[h][2],0),h--},a=[["seconds","minutes",0],["minutes","hours",0],["hours","days",0],["days","months",-1],["months","years",0]],h=0;for(;h<5;)s(a[h][0],t,a[h][2])||(this[a[h][1]]++,i()),h++;for(;!t.daysOfWeek[this.getDate().getDay()];)this.days+=1,h=2,i();return o!=n.getTime()?(n=new r(n),this.years>=4e3?null:n.increment(t,!0)):this},r.prototype.getDate=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,this.milliseconds-this.UTCmsOffset)},r.prototype.getTime=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,this.milliseconds-this.UTCmsOffset).getTime()},o.prototype.parse=function(){if("string"!=typeof this.pattern&&this.pattern.constructor!==String)throw new TypeError("CronPattern: Pattern has to be of type string.");let t,e,r=this.pattern.trim().replace(/\s+/g," ").split(" "),o=/[^/*0-9,-]+/;if(r.length<5||r.length>6)throw new TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exacly five or six space separated parts required.");for(5===r.length&&r.unshift("0"),e=0;e<r.length;e++)if(t=r[e].trim(),o.test(t))throw new TypeError("CronPattern: configuration entry "+(e+1)+" ("+t+") contains illegal characters.");this.partToArray("seconds",r[0],0),this.partToArray("minutes",r[1],0),this.partToArray("hours",r[2],0),this.partToArray("days",r[3],-1),this.partToArray("months",r[4],-1),this.partToArray("daysOfWeek",r[5],0),this.daysOfWeek[7]&&(this.daysOfWeek[0]=1)},o.prototype.partToArray=function(t,e,r){let o,n,s,i,a,h=this[t];if("*"!==e)if(n=e.split(","),n.length>1)for(o=0;o<n.length;o++)this.partToArray(t,n[o],r);else if(-1!==e.indexOf("-")){if(n=e.split("-"),2!==n.length)throw new TypeError("CronPattern: Syntax error, illegal range: '"+e+"'");if(s=parseInt(n[0],10)+r,i=parseInt(n[1],10)+r,isNaN(s))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(i))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(s<0||i>=h.length)throw new TypeError("CronPattern: Value out of range: '"+e+"'");if(s>i)throw new TypeError("CronPattern: From value is larger than to value: '"+e+"'");for(o=s;o<=i;o++)h[o+r]=1}else if(-1!==e.indexOf("/")){if(n=e.split("/"),2!==n.length)throw new TypeError("CronPattern: Syntax error, illegal stepping: '"+e+"'");if("*"!==n[0])throw new TypeError("CronPattern: Syntax error, left part of / needs to be * : '"+e+"'");if(a=parseInt(n[1],10),isNaN(a))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(0===a)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(a>h.length)throw new TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+h.length+")");for(o=0;o<h.length;o+=a)h[o+r]=1}else{if(o=parseInt(e,10)+r,o<0||o>=h.length)throw new TypeError("CronPattern: "+t+" value out of range: '"+e+"'");h[o]=1}else for(o=0;o<h.length;o++)h[o]=1};const n=Math.pow(2,31)-1;function s(t,e,r){return this instanceof s?(this.pattern=new o(t),"function"==typeof e&&(r=e,e=void 0),this.options=this.processOptions(e),void 0!==r&&this.schedule(r),this):new s(t,e,r)}s.prototype.processOptions=function(t){return void 0===t&&(t={}),t.paused=void 0!==t.paused&&t.paused,t.maxRuns=void 0===t.maxRuns?1/0:t.maxRuns,t.kill=!1,t.startAt&&(t.startAt=new r(t.startAt,t.timezone)),t.stopAt&&(t.stopAt=new r(t.stopAt,t.timezone)),t},s.prototype.next=function(t){let e=this._next(t);return e?e.getDate():null},s.prototype.previous=function(){return this.previousrun?this.previousrun.getDate():null},s.prototype._next=function(t){t=new r(t,this.options.timezone),this.options.startAt&&t&&t.getTime()<this.options.startAt.getTime()&&(t=new r(this.options.startAt,this.options.timezone));let e=new r(t,this.options.timezone).increment(this.pattern);return null===e||this.options.maxRuns<=0||this.options.kill||this.options.stopAt&&e.getTime()>=this.options.stopAt.getTime()?null:e},s.prototype.msToNext=function(t){t=t||new r(void 0,this.options.timezone);let e=this._next(t);return e?e.getTime()-t.getTime():null},s.prototype.stop=function(){this.options.kill=!0,this.currentTimeout&&clearTimeout(this.currentTimeout)},s.prototype.pause=function(){return(this.options.paused=!0)&&!this.options.kill},s.prototype.resume=function(){return!(this.options.paused=!1)&&!this.options.kill},s.prototype.schedule=function(t){let e=this,o=this.msToNext(e.previousrun),s=e.maxDelay||n;return o>s&&(o=s),null!==o&&(e.currentTimeout=setTimeout((function(){o!==s&&(e.options.paused||(e.options.maxRuns--,t()),e.previousrun=new r(void 0,e.options.timezone)),e.schedule(t)}),o)),this};const i=s;return e.default})()}));
|
package/dist/croner.min.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var t={d:(e,r)=>{for(var s in r)t.o(r,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:r[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{P:()=>
|
|
1
|
+
var t={d:(e,r)=>{for(var s in r)t.o(r,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:r[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{P:()=>o,Z:()=>i});function r(t,e){if(this.timezone=e,t&&t instanceof Date)this.fromDate(t);else if(void 0===t)this.fromDate(new Date);else if(t&&"string"==typeof t)this.fromString(t);else{if(!(t instanceof r))throw new TypeError("CronDate: Invalid type ("+typeof t+") passed as parameter to CronDate constructor");this.fromCronDate(t)}}function s(t){this.pattern=t,this.seconds=Array(60).fill(0),this.minutes=Array(60).fill(0),this.hours=Array(24).fill(0),this.days=Array(31).fill(0),this.months=Array(12).fill(0),this.daysOfWeek=Array(8).fill(0),this.parse()}r.prototype.fromDate=function(t){let e=t.getTime();this.timezone&&(t=function(t,e){return new Date(t.toLocaleString("en-US",{timeZone:e}))}(t,this.timezone));let r=t.getTime();this.UTCmsOffset=r-e,this.milliseconds=t.getMilliseconds(),this.seconds=t.getSeconds(),this.minutes=t.getMinutes(),this.hours=t.getHours(),this.days=t.getDate(),this.months=t.getMonth(),this.years=t.getFullYear()},r.prototype.fromCronDate=function(t){this.UTCmsOffset=t.UTCmsOffset,this.timezone=t.timezone;let e=new Date(t.years,t.months,t.days,t.hours,t.minutes,t.seconds,t.milliseconds);this.milliseconds=e.getMilliseconds(),this.seconds=e.getSeconds(),this.minutes=e.getMinutes(),this.hours=e.getHours(),this.days=e.getDate(),this.months=e.getMonth(),this.years=e.getFullYear()},r.prototype.fromString=function(t){let e=Date.parse(t);if(isNaN(e))throw new TypeError("CronDate: Provided string value for CronDate could not be parsed as date.");this.fromDate(new Date(e))},r.prototype.increment=function(t,e){e||(this.seconds+=1);let s=this.getTime();this.milliseconds=0;let n=this,o=function(t,e,r,s){for(let o=void 0===s?n[t]+r:0+r;o<e[t].length;o++)if(e[t][o])return n[t]=o-r,!0;return!1},i=function(){for(;h>=0;)o(a[h][0],t,a[h][2],0),h--},a=[["seconds","minutes",0],["minutes","hours",0],["hours","days",0],["days","months",-1],["months","years",0]],h=0;for(;h<5;)o(a[h][0],t,a[h][2])||(this[a[h][1]]++,i()),h++;for(;!t.daysOfWeek[this.getDate().getDay()];)this.days+=1,h=2,i();return s!=n.getTime()?(n=new r(n),this.years>=4e3?null:n.increment(t,!0)):this},r.prototype.getDate=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,this.milliseconds-this.UTCmsOffset)},r.prototype.getTime=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,this.milliseconds-this.UTCmsOffset).getTime()},s.prototype.parse=function(){if("string"!=typeof this.pattern&&this.pattern.constructor!==String)throw new TypeError("CronPattern: Pattern has to be of type string.");let t,e,r=this.pattern.trim().replace(/\s+/g," ").split(" "),s=/[^/*0-9,-]+/;if(r.length<5||r.length>6)throw new TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exacly five or six space separated parts required.");for(5===r.length&&r.unshift("0"),e=0;e<r.length;e++)if(t=r[e].trim(),s.test(t))throw new TypeError("CronPattern: configuration entry "+(e+1)+" ("+t+") contains illegal characters.");this.partToArray("seconds",r[0],0),this.partToArray("minutes",r[1],0),this.partToArray("hours",r[2],0),this.partToArray("days",r[3],-1),this.partToArray("months",r[4],-1),this.partToArray("daysOfWeek",r[5],0),this.daysOfWeek[7]&&(this.daysOfWeek[0]=1)},s.prototype.partToArray=function(t,e,r){let s,n,o,i,a,h=this[t];if("*"!==e)if(n=e.split(","),n.length>1)for(s=0;s<n.length;s++)this.partToArray(t,n[s],r);else if(-1!==e.indexOf("-")){if(n=e.split("-"),2!==n.length)throw new TypeError("CronPattern: Syntax error, illegal range: '"+e+"'");if(o=parseInt(n[0],10)+r,i=parseInt(n[1],10)+r,isNaN(o))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(i))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(o<0||i>=h.length)throw new TypeError("CronPattern: Value out of range: '"+e+"'");if(o>i)throw new TypeError("CronPattern: From value is larger than to value: '"+e+"'");for(s=o;s<=i;s++)h[s+r]=1}else if(-1!==e.indexOf("/")){if(n=e.split("/"),2!==n.length)throw new TypeError("CronPattern: Syntax error, illegal stepping: '"+e+"'");if("*"!==n[0])throw new TypeError("CronPattern: Syntax error, left part of / needs to be * : '"+e+"'");if(a=parseInt(n[1],10),isNaN(a))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(0===a)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(a>h.length)throw new TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+h.length+")");for(s=0;s<h.length;s+=a)h[s+r]=1}else{if(s=parseInt(e,10)+r,s<0||s>=h.length)throw new TypeError("CronPattern: "+t+" value out of range: '"+e+"'");h[s]=1}else for(s=0;s<h.length;s++)h[s]=1};const n=Math.pow(2,31)-1;function o(t,e,r){return this instanceof o?(this.pattern=new s(t),"function"==typeof e&&(r=e,e=void 0),this.options=this.processOptions(e),void 0!==r&&this.schedule(r),this):new o(t,e,r)}o.prototype.processOptions=function(t){return void 0===t&&(t={}),t.paused=void 0!==t.paused&&t.paused,t.maxRuns=void 0===t.maxRuns?1/0:t.maxRuns,t.kill=!1,t.startAt&&(t.startAt=new r(t.startAt,t.timezone)),t.stopAt&&(t.stopAt=new r(t.stopAt,t.timezone)),t},o.prototype.next=function(t){let e=this._next(t);return e?e.getDate():null},o.prototype.previous=function(){return this.previousrun?this.previousrun.getDate():null},o.prototype._next=function(t){t=new r(t,this.options.timezone),this.options.startAt&&t&&t.getTime()<this.options.startAt.getTime()&&(t=new r(this.options.startAt,this.options.timezone));let e=new r(t,this.options.timezone).increment(this.pattern);return null===e||this.options.maxRuns<=0||this.options.kill||this.options.stopAt&&e.getTime()>=this.options.stopAt.getTime()?null:e},o.prototype.msToNext=function(t){t=t||new r(void 0,this.options.timezone);let e=this._next(t);return e?e.getTime()-t.getTime():null},o.prototype.stop=function(){this.options.kill=!0,this.currentTimeout&&clearTimeout(this.currentTimeout)},o.prototype.pause=function(){return(this.options.paused=!0)&&!this.options.kill},o.prototype.resume=function(){return!(this.options.paused=!1)&&!this.options.kill},o.prototype.schedule=function(t){let e=this,s=this.msToNext(e.previousrun),o=e.maxDelay||n;return s>o&&(s=o),null!==s&&(e.currentTimeout=setTimeout((function(){s!==o&&(e.options.paused||(e.options.maxRuns--,t()),e.previousrun=new r(void 0,e.options.timezone)),e.schedule(t)}),s)),this};const i=o;var a=e.P,h=e.Z;export{a as Cron,h as default};
|
package/dist-legacy/croner.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Cron=e():t.Cron=e()}(this,(function(){return(()=>{"use strict";var t={d:(e,r)=>{for(var
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Cron=e():t.Cron=e()}(this,(function(){return(()=>{"use strict";var t={d:(e,r)=>{for(var o in r)t.o(r,o)&&!t.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:r[o]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>i});function r(t,e){if(this.timezone=e,t&&t instanceof Date)this.fromDate(t);else if(void 0===t)this.fromDate(new Date);else if(t&&"string"==typeof t)this.fromString(t);else{if(!(t instanceof r))throw new TypeError("CronDate: Invalid type ("+typeof t+") passed as parameter to CronDate constructor");this.fromCronDate(t)}}function o(t){this.pattern=t,this.seconds=Array(60).fill(0),this.minutes=Array(60).fill(0),this.hours=Array(24).fill(0),this.days=Array(31).fill(0),this.months=Array(12).fill(0),this.daysOfWeek=Array(8).fill(0),this.parse()}r.prototype.fromDate=function(t){let e=t.getTime();this.timezone&&(t=function(t,e){return new Date(t.toLocaleString("en-US",{timeZone:e}))}(t,this.timezone));let r=t.getTime();this.UTCmsOffset=r-e,this.milliseconds=t.getMilliseconds(),this.seconds=t.getSeconds(),this.minutes=t.getMinutes(),this.hours=t.getHours(),this.days=t.getDate(),this.months=t.getMonth(),this.years=t.getFullYear()},r.prototype.fromCronDate=function(t){this.UTCmsOffset=t.UTCmsOffset,this.timezone=t.timezone;let e=new Date(t.years,t.months,t.days,t.hours,t.minutes,t.seconds,t.milliseconds);this.milliseconds=e.getMilliseconds(),this.seconds=e.getSeconds(),this.minutes=e.getMinutes(),this.hours=e.getHours(),this.days=e.getDate(),this.months=e.getMonth(),this.years=e.getFullYear()},r.prototype.fromString=function(t){let e=Date.parse(t);if(isNaN(e))throw new TypeError("CronDate: Provided string value for CronDate could not be parsed as date.");this.fromDate(new Date(e))},r.prototype.increment=function(t,e){e||(this.seconds+=1);let o=this.getTime();this.milliseconds=0;let n=this,s=function(t,e,r,o){for(let s=void 0===o?n[t]+r:0+r;s<e[t].length;s++)if(e[t][s])return n[t]=s-r,!0;return!1},i=function(){for(;h>=0;)s(a[h][0],t,a[h][2],0),h--},a=[["seconds","minutes",0],["minutes","hours",0],["hours","days",0],["days","months",-1],["months","years",0]],h=0;for(;h<5;)s(a[h][0],t,a[h][2])||(this[a[h][1]]++,i()),h++;for(;!t.daysOfWeek[this.getDate().getDay()];)this.days+=1,h=2,i();return o!=n.getTime()?(n=new r(n),this.years>=4e3?null:n.increment(t,!0)):this},r.prototype.getDate=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,this.milliseconds-this.UTCmsOffset)},r.prototype.getTime=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,this.milliseconds-this.UTCmsOffset).getTime()},o.prototype.parse=function(){if("string"!=typeof this.pattern&&this.pattern.constructor!==String)throw new TypeError("CronPattern: Pattern has to be of type string.");let t,e,r=this.pattern.trim().replace(/\s+/g," ").split(" "),o=/[^/*0-9,-]+/;if(r.length<5||r.length>6)throw new TypeError("CronPattern: invalid configuration format ('"+this.pattern+"'), exacly five or six space separated parts required.");for(5===r.length&&r.unshift("0"),e=0;e<r.length;e++)if(t=r[e].trim(),o.test(t))throw new TypeError("CronPattern: configuration entry "+(e+1)+" ("+t+") contains illegal characters.");this.partToArray("seconds",r[0],0),this.partToArray("minutes",r[1],0),this.partToArray("hours",r[2],0),this.partToArray("days",r[3],-1),this.partToArray("months",r[4],-1),this.partToArray("daysOfWeek",r[5],0),this.daysOfWeek[7]&&(this.daysOfWeek[0]=1)},o.prototype.partToArray=function(t,e,r){let o,n,s,i,a,h=this[t];if("*"!==e)if(n=e.split(","),n.length>1)for(o=0;o<n.length;o++)this.partToArray(t,n[o],r);else if(-1!==e.indexOf("-")){if(n=e.split("-"),2!==n.length)throw new TypeError("CronPattern: Syntax error, illegal range: '"+e+"'");if(s=parseInt(n[0],10)+r,i=parseInt(n[1],10)+r,isNaN(s))throw new TypeError("CronPattern: Syntax error, illegal lower range (NaN)");if(isNaN(i))throw new TypeError("CronPattern: Syntax error, illegal upper range (NaN)");if(s<0||i>=h.length)throw new TypeError("CronPattern: Value out of range: '"+e+"'");if(s>i)throw new TypeError("CronPattern: From value is larger than to value: '"+e+"'");for(o=s;o<=i;o++)h[o+r]=1}else if(-1!==e.indexOf("/")){if(n=e.split("/"),2!==n.length)throw new TypeError("CronPattern: Syntax error, illegal stepping: '"+e+"'");if("*"!==n[0])throw new TypeError("CronPattern: Syntax error, left part of / needs to be * : '"+e+"'");if(a=parseInt(n[1],10),isNaN(a))throw new TypeError("CronPattern: Syntax error, illegal stepping: (NaN)");if(0===a)throw new TypeError("CronPattern: Syntax error, illegal stepping: 0");if(a>h.length)throw new TypeError("CronPattern: Syntax error, steps cannot be greater than maximum value of part ("+h.length+")");for(o=0;o<h.length;o+=a)h[o+r]=1}else{if(o=parseInt(e,10)+r,o<0||o>=h.length)throw new TypeError("CronPattern: "+t+" value out of range: '"+e+"'");h[o]=1}else for(o=0;o<h.length;o++)h[o]=1};const n=Math.pow(2,31)-1;function s(t,e,r){return this instanceof s?(this.pattern=new o(t),"function"==typeof e&&(r=e,e=void 0),this.options=this.processOptions(e),void 0!==r&&this.schedule(r),this):new s(t,e,r)}s.prototype.processOptions=function(t){return void 0===t&&(t={}),t.paused=void 0!==t.paused&&t.paused,t.maxRuns=void 0===t.maxRuns?1/0:t.maxRuns,t.kill=!1,t.startAt&&(t.startAt=new r(t.startAt,t.timezone)),t.stopAt&&(t.stopAt=new r(t.stopAt,t.timezone)),t},s.prototype.next=function(t){let e=this._next(t);return e?e.getDate():null},s.prototype.previous=function(){return this.previousrun?this.previousrun.getDate():null},s.prototype._next=function(t){t=new r(t,this.options.timezone),this.options.startAt&&t&&t.getTime()<this.options.startAt.getTime()&&(t=new r(this.options.startAt,this.options.timezone));let e=new r(t,this.options.timezone).increment(this.pattern);return null===e||this.options.maxRuns<=0||this.options.kill||this.options.stopAt&&e.getTime()>=this.options.stopAt.getTime()?null:e},s.prototype.msToNext=function(t){t=t||new r(void 0,this.options.timezone);let e=this._next(t);return e?e.getTime()-t.getTime():null},s.prototype.stop=function(){this.options.kill=!0,this.currentTimeout&&clearTimeout(this.currentTimeout)},s.prototype.pause=function(){return(this.options.paused=!0)&&!this.options.kill},s.prototype.resume=function(){return!(this.options.paused=!1)&&!this.options.kill},s.prototype.schedule=function(t){let e=this,o=this.msToNext(e.previousrun),s=e.maxDelay||n;return o>s&&(o=s),null!==o&&(e.currentTimeout=setTimeout((function(){o!==s&&(e.options.paused||(e.options.maxRuns--,t()),e.previousrun=new r(void 0,e.options.timezone)),e.schedule(t)}),o)),this};const i=s;return e.default})()}));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "croner",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "4.0.53",
|
|
4
|
+
"description": "Trigger functions in javascript using Cron syntax. No deps. All features.",
|
|
5
5
|
"author": "Hexagon <github.com/hexagon>",
|
|
6
6
|
"contributors": [
|
|
7
7
|
{
|
|
@@ -25,11 +25,12 @@
|
|
|
25
25
|
"isomorphic"
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
|
-
"test": "npm run test:
|
|
29
|
-
"test:
|
|
28
|
+
"test": "npm run test:coverage",
|
|
29
|
+
"test:dist": "mocha",
|
|
30
|
+
"test:coverage": "c8 --reporter=text mocha test/test.croner.js",
|
|
30
31
|
"test:lint": "eslint ./**/*.js ./**/*.cjs",
|
|
31
32
|
"test:lint:fix": "eslint --fix ./**/*.js ./**/*.cjs",
|
|
32
|
-
"build": "npm run test:lint && npm run build:typings && npm run build:webpack && npm run test:
|
|
33
|
+
"build": "npm run test:lint && npm run build:typings && npm run build:webpack && npm run test:coverage && npm run build:finalize",
|
|
33
34
|
"build:webpack": "webpack",
|
|
34
35
|
"build:typings": "tsc",
|
|
35
36
|
"build:finalize": "echo \"All good\""
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
},
|
|
53
54
|
"types": "types/croner.d.ts",
|
|
54
55
|
"devDependencies": {
|
|
56
|
+
"c8": "^7.10.0",
|
|
55
57
|
"eslint": "^7.32.0",
|
|
56
58
|
"mocha": "^9.1.2",
|
|
57
59
|
"should": "^13.2.3",
|
package/src/croner.js
CHANGED
|
@@ -35,10 +35,8 @@ import { CronPattern } from "./pattern.js";
|
|
|
35
35
|
*
|
|
36
36
|
* @typedef {Object} CronOptions - Cron scheduler options
|
|
37
37
|
* @property {boolean} [paused] - Job is paused
|
|
38
|
-
* @property {boolean} [kill] - Job is about to be killed
|
|
38
|
+
* @property {boolean} [kill] - Job is about to be killed or killed
|
|
39
39
|
* @property {number} [maxRuns] - Maximum nuber of executions
|
|
40
|
-
* @property {number} [currentTimeout] - Internal: setTimeout "id"
|
|
41
|
-
* @property {CronNextResult} [previous] - Previous run time
|
|
42
40
|
* @property {string | Date} [startAt] - When to start running
|
|
43
41
|
* @property {string | Date} [stopAt] - When to stop running
|
|
44
42
|
* @property {string} [timezone] - Time zone in Europe/Stockholm format
|
|
@@ -99,36 +97,53 @@ function Cron (pattern, options, fn) {
|
|
|
99
97
|
/** @type {CronPattern} */
|
|
100
98
|
self.pattern = new CronPattern(pattern);
|
|
101
99
|
|
|
102
|
-
/** @type {CronOptions} */
|
|
103
|
-
self.schedulerDefaults = {
|
|
104
|
-
maxRuns: Infinity,
|
|
105
|
-
kill: false
|
|
106
|
-
};
|
|
107
|
-
|
|
108
100
|
// Make options optional
|
|
109
101
|
if( typeof options === "function" ) {
|
|
110
102
|
fn = options;
|
|
111
|
-
options =
|
|
103
|
+
options = void 0;
|
|
112
104
|
}
|
|
113
105
|
|
|
114
|
-
/**
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
/** @type {CronOptions} */
|
|
107
|
+
this.options = this.processOptions(options);
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Allow shorthand scheduling
|
|
117
111
|
*/
|
|
118
|
-
|
|
112
|
+
if( fn !== void 0 ) {
|
|
113
|
+
this.schedule(fn);
|
|
114
|
+
}
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
if( fn === void 0 ) {
|
|
122
|
-
// Normal initialization, return self
|
|
123
|
-
return self;
|
|
116
|
+
return this;
|
|
124
117
|
|
|
125
|
-
|
|
126
|
-
// Shorthand schedule requested, return job
|
|
127
|
-
return this.schedule(options, fn);
|
|
118
|
+
}
|
|
128
119
|
|
|
120
|
+
/**
|
|
121
|
+
*
|
|
122
|
+
* @param {CronOptions} options
|
|
123
|
+
* @returns {CronOptions}
|
|
124
|
+
*/
|
|
125
|
+
Cron.prototype.processOptions = function (options) {
|
|
126
|
+
|
|
127
|
+
// If no options are passed, create empty object
|
|
128
|
+
if (options === void 0) {
|
|
129
|
+
options = {};
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
|
|
132
|
+
// Keep options, or set defaults
|
|
133
|
+
options.paused = (options.paused === void 0) ? false : options.paused;
|
|
134
|
+
options.maxRuns = (options.maxRuns === void 0) ? Infinity : options.maxRuns;
|
|
135
|
+
options.kill = false;
|
|
136
|
+
|
|
137
|
+
// startAt is set, validate it
|
|
138
|
+
if( options.startAt ) {
|
|
139
|
+
options.startAt = new CronDate(options.startAt, options.timezone);
|
|
140
|
+
}
|
|
141
|
+
if( options.stopAt ) {
|
|
142
|
+
options.stopAt = new CronDate(options.stopAt, options.timezone);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return options;
|
|
146
|
+
};
|
|
132
147
|
|
|
133
148
|
/**
|
|
134
149
|
* Find next runtime, based on supplied date. Strips milliseconds.
|
|
@@ -147,7 +162,7 @@ Cron.prototype.next = function (prev) {
|
|
|
147
162
|
* @returns {Date | null} - Previous run time
|
|
148
163
|
*/
|
|
149
164
|
Cron.prototype.previous = function () {
|
|
150
|
-
return this.
|
|
165
|
+
return this.previousrun ? this.previousrun.getDate() : null;
|
|
151
166
|
};
|
|
152
167
|
|
|
153
168
|
/**
|
|
@@ -155,24 +170,25 @@ Cron.prototype.previous = function () {
|
|
|
155
170
|
* @private
|
|
156
171
|
*
|
|
157
172
|
* @param {Date} prev - Input pattern
|
|
158
|
-
* @returns {
|
|
173
|
+
* @returns {CronDate | null} - Next run time
|
|
159
174
|
*/
|
|
160
175
|
Cron.prototype._next = function (prev) {
|
|
161
|
-
|
|
162
|
-
prev = new CronDate(prev, this.
|
|
176
|
+
|
|
177
|
+
prev = new CronDate(prev, this.options.timezone);
|
|
163
178
|
|
|
164
179
|
// Previous run should never be before startAt
|
|
165
|
-
if( this.
|
|
166
|
-
prev = new CronDate(this.
|
|
180
|
+
if( this.options.startAt && prev && prev.getTime() < this.options.startAt.getTime() ) {
|
|
181
|
+
prev = new CronDate(this.options.startAt, this.options.timezone);
|
|
167
182
|
}
|
|
168
183
|
|
|
169
184
|
// Calculate next run
|
|
170
|
-
let nextRun = new CronDate(prev, this.
|
|
185
|
+
let nextRun = new CronDate(prev, this.options.timezone).increment(this.pattern);
|
|
171
186
|
|
|
172
187
|
// Check for stop condition
|
|
173
|
-
if ((
|
|
174
|
-
(this.
|
|
175
|
-
(this.
|
|
188
|
+
if ((nextRun === null) ||
|
|
189
|
+
(this.options.maxRuns <= 0) ||
|
|
190
|
+
(this.options.kill) ||
|
|
191
|
+
(this.options.stopAt && nextRun.getTime() >= this.options.stopAt.getTime() )) {
|
|
176
192
|
return null;
|
|
177
193
|
} else {
|
|
178
194
|
// All seem good, return next run
|
|
@@ -181,23 +197,6 @@ Cron.prototype._next = function (prev) {
|
|
|
181
197
|
|
|
182
198
|
};
|
|
183
199
|
|
|
184
|
-
/**
|
|
185
|
-
* Validate (and cleans) options. Raises error on failure.
|
|
186
|
-
*
|
|
187
|
-
* @param {CronOptions} opts - Input options
|
|
188
|
-
* @returns {CronOptions} - Clean and validated options.
|
|
189
|
-
*/
|
|
190
|
-
Cron.prototype.validateOpts = function (opts) {
|
|
191
|
-
// startAt is set, validate it
|
|
192
|
-
if( opts.startAt ) {
|
|
193
|
-
opts.startAt = new CronDate(opts.startAt, opts.timezone);
|
|
194
|
-
}
|
|
195
|
-
if( opts.stopAt ) {
|
|
196
|
-
opts.stopAt = new CronDate(opts.stopAt, opts.timezone);
|
|
197
|
-
}
|
|
198
|
-
return opts;
|
|
199
|
-
};
|
|
200
|
-
|
|
201
200
|
/**
|
|
202
201
|
* Returns number of milliseconds to next run
|
|
203
202
|
*
|
|
@@ -205,7 +204,7 @@ Cron.prototype.validateOpts = function (opts) {
|
|
|
205
204
|
* @returns {number | null}
|
|
206
205
|
*/
|
|
207
206
|
Cron.prototype.msToNext = function (prev) {
|
|
208
|
-
prev = prev || new CronDate(void 0, this.
|
|
207
|
+
prev = prev || new CronDate(void 0, this.options.timezone);
|
|
209
208
|
let next = this._next(prev);
|
|
210
209
|
if( next ) {
|
|
211
210
|
return (next.getTime() - prev.getTime());
|
|
@@ -215,115 +214,84 @@ Cron.prototype.msToNext = function (prev) {
|
|
|
215
214
|
};
|
|
216
215
|
|
|
217
216
|
/**
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
* @signature
|
|
221
|
-
* @param {CronOptions | Function} [options] - Options
|
|
222
|
-
* @param {Function} [func] - Function to be run each iteration of pattern
|
|
223
|
-
* @returns {CronJob}
|
|
224
|
-
*
|
|
217
|
+
* Stop execution
|
|
218
|
+
* @public
|
|
225
219
|
*/
|
|
226
|
-
Cron.prototype.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
if( !func ) {
|
|
232
|
-
func = opts;
|
|
233
|
-
|
|
234
|
-
// If options isn't passed to schedule, use stored options
|
|
235
|
-
opts = this.opts;
|
|
220
|
+
Cron.prototype.stop = function () {
|
|
221
|
+
this.options.kill = true;
|
|
222
|
+
// Stop any awaiting call
|
|
223
|
+
if( this.currentTimeout ) {
|
|
224
|
+
clearTimeout( this.currentTimeout );
|
|
236
225
|
}
|
|
226
|
+
};
|
|
237
227
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this._schedule(func);
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// Return control functions
|
|
252
|
-
return {
|
|
253
|
-
|
|
254
|
-
// Return undefined
|
|
255
|
-
stop: function() {
|
|
256
|
-
self.opts.kill = true;
|
|
257
|
-
// Stop any awaiting call
|
|
258
|
-
if( self.opts.currentTimeout ) {
|
|
259
|
-
clearTimeout( self.opts.currentTimeout );
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
|
-
|
|
263
|
-
// Return bool wether pause were successful
|
|
264
|
-
pause: function() {
|
|
265
|
-
return (self.opts.paused = true) && !self.opts.kill;
|
|
266
|
-
},
|
|
267
|
-
|
|
268
|
-
// Return bool wether resume were successful
|
|
269
|
-
resume: function () {
|
|
270
|
-
return !(self.opts.paused = false) && !self.opts.kill;
|
|
271
|
-
}
|
|
228
|
+
/**
|
|
229
|
+
* Pause execution
|
|
230
|
+
* @public
|
|
231
|
+
*
|
|
232
|
+
* @returns {boolean} - Wether pause was successful
|
|
233
|
+
*/
|
|
234
|
+
Cron.prototype.pause = function () {
|
|
235
|
+
return (this.options.paused = true) && !this.options.kill;
|
|
236
|
+
};
|
|
272
237
|
|
|
273
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Pause execution
|
|
240
|
+
* @public
|
|
241
|
+
*
|
|
242
|
+
* @returns {boolean} - Wether resume was successful
|
|
243
|
+
*/
|
|
244
|
+
Cron.prototype.resume = function () {
|
|
245
|
+
return !(this.options.paused = false) && !this.options.kill;
|
|
274
246
|
};
|
|
275
247
|
|
|
276
248
|
/**
|
|
277
249
|
* Schedule a new job
|
|
278
|
-
* @
|
|
250
|
+
* @public
|
|
279
251
|
*
|
|
280
|
-
* @param {Function}
|
|
252
|
+
* @param {Function} func - Function to be run each iteration of pattern
|
|
281
253
|
* @returns {CronJob}
|
|
282
254
|
*/
|
|
283
|
-
Cron.prototype.
|
|
255
|
+
Cron.prototype.schedule = function (func) {
|
|
284
256
|
|
|
285
257
|
let self = this,
|
|
286
|
-
|
|
258
|
+
|
|
259
|
+
// Get ms to next run
|
|
260
|
+
waitMs = this.msToNext(self.previousrun),
|
|
287
261
|
|
|
288
262
|
// Prioritize context before closure,
|
|
289
263
|
// to allow testing of maximum delay.
|
|
290
264
|
_maxDelay = self.maxDelay || maxDelay;
|
|
291
265
|
|
|
292
|
-
// Get ms to next run
|
|
293
|
-
waitMs = this.msToNext(self.opts.previous);
|
|
294
|
-
|
|
295
|
-
// Check for stop conditions
|
|
296
|
-
if ( waitMs === null ) {
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
266
|
// setTimeout cant handle more than Math.pow(2, 32 - 1) - 1 ms
|
|
301
267
|
if( waitMs > _maxDelay ) {
|
|
302
268
|
waitMs = _maxDelay;
|
|
303
269
|
}
|
|
304
270
|
|
|
305
271
|
// All ok, go go!
|
|
306
|
-
|
|
272
|
+
if ( waitMs !== null ) {
|
|
273
|
+
self.currentTimeout = setTimeout(function () {
|
|
307
274
|
|
|
308
|
-
|
|
309
|
-
|
|
275
|
+
// Are we running? If waitMs is maxed out, this is a blank run
|
|
276
|
+
if( waitMs !== _maxDelay ) {
|
|
310
277
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
278
|
+
if ( !self.options.paused ) {
|
|
279
|
+
self.options.maxRuns--;
|
|
280
|
+
func();
|
|
281
|
+
}
|
|
315
282
|
|
|
316
|
-
|
|
283
|
+
self.previousrun = new CronDate(void 0, self.options.timezone);
|
|
284
|
+
}
|
|
317
285
|
|
|
318
|
-
|
|
286
|
+
// Recurseg
|
|
287
|
+
self.schedule(func);
|
|
319
288
|
|
|
320
|
-
|
|
321
|
-
|
|
289
|
+
}, waitMs );
|
|
290
|
+
}
|
|
322
291
|
|
|
323
|
-
|
|
292
|
+
return this;
|
|
324
293
|
|
|
325
294
|
};
|
|
326
295
|
|
|
327
|
-
|
|
328
296
|
export default Cron;
|
|
329
297
|
export { Cron };
|
package/src/date.js
CHANGED
|
@@ -10,7 +10,7 @@ import convertTZ from "./timezone.js";
|
|
|
10
10
|
function CronDate (date, timezone) {
|
|
11
11
|
|
|
12
12
|
this.timezone = timezone;
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
if (date && date instanceof Date) {
|
|
15
15
|
this.fromDate(date);
|
|
16
16
|
} else if (date === void 0) {
|
|
@@ -20,7 +20,7 @@ function CronDate (date, timezone) {
|
|
|
20
20
|
} else if (date instanceof CronDate) {
|
|
21
21
|
this.fromCronDate(date);
|
|
22
22
|
} else {
|
|
23
|
-
throw new TypeError("CronDate: Invalid type passed as parameter to CronDate constructor");
|
|
23
|
+
throw new TypeError("CronDate: Invalid type (" + typeof date + ") passed as parameter to CronDate constructor");
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -60,14 +60,18 @@ CronDate.prototype.fromDate = function (date) {
|
|
|
60
60
|
CronDate.prototype.fromCronDate = function (date) {
|
|
61
61
|
|
|
62
62
|
this.UTCmsOffset = date.UTCmsOffset;
|
|
63
|
+
this.timezone = date.timezone;
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
65
|
+
// Recreate date object to avoid getDate > 31 etc...
|
|
66
|
+
let newDate = new Date(date.years, date.months, date.days, date.hours, date.minutes, date.seconds, date.milliseconds);
|
|
67
|
+
|
|
68
|
+
this.milliseconds = newDate.getMilliseconds();
|
|
69
|
+
this.seconds = newDate.getSeconds();
|
|
70
|
+
this.minutes = newDate.getMinutes();
|
|
71
|
+
this.hours = newDate.getHours();
|
|
72
|
+
this.days = newDate.getDate();
|
|
73
|
+
this.months = newDate.getMonth();
|
|
74
|
+
this.years = newDate.getFullYear();
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -93,11 +97,17 @@ CronDate.prototype.fromString = function (str) {
|
|
|
93
97
|
* @public
|
|
94
98
|
*
|
|
95
99
|
* @param {string} pattern - The pattern used to increment current state
|
|
96
|
-
* @
|
|
100
|
+
* @param {boolean} [rerun=false] - If this is an internal incremental run
|
|
101
|
+
* @return {CronDate|null} - Returns itself for chaining, or null if increment wasnt possible
|
|
97
102
|
*/
|
|
98
|
-
CronDate.prototype.increment = function (pattern) {
|
|
103
|
+
CronDate.prototype.increment = function (pattern, rerun) {
|
|
104
|
+
|
|
105
|
+
if (!rerun) {
|
|
106
|
+
this.seconds += 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let origTime = this.getTime();
|
|
99
110
|
|
|
100
|
-
this.seconds += 1;
|
|
101
111
|
this.milliseconds = 0;
|
|
102
112
|
|
|
103
113
|
let self = this,
|
|
@@ -119,14 +129,33 @@ CronDate.prototype.increment = function (pattern) {
|
|
|
119
129
|
let startPos = (override === void 0) ? self[target] + offset : 0 + offset;
|
|
120
130
|
|
|
121
131
|
for( let i = startPos; i < pattern[target].length; i++ ) {
|
|
132
|
+
|
|
122
133
|
if( pattern[target][i] ) {
|
|
123
134
|
self[target] = i-offset;
|
|
124
135
|
return true;
|
|
125
136
|
}
|
|
126
137
|
}
|
|
127
|
-
|
|
128
138
|
return false;
|
|
129
139
|
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
resetPrevious = function () {
|
|
143
|
+
// Now when we have gone to next minute, we have to set seconds to the first match
|
|
144
|
+
// Now we are at 00:01:05 following the same example.
|
|
145
|
+
//
|
|
146
|
+
// This goes all the way back to seconds, hence the reverse loop.
|
|
147
|
+
while(doing >= 0) {
|
|
148
|
+
|
|
149
|
+
// Ok, reset current member(e.g. seconds) to first match in pattern, using
|
|
150
|
+
// the same method as aerlier
|
|
151
|
+
//
|
|
152
|
+
// Note the fourth parameter, stating that we should start matching the pattern
|
|
153
|
+
// from zero, instead of current time.
|
|
154
|
+
findNext(toDo[doing][0], pattern, toDo[doing][2], 0);
|
|
155
|
+
|
|
156
|
+
// Go back up, days -> hours -> minutes -> seconds
|
|
157
|
+
doing--;
|
|
158
|
+
}
|
|
130
159
|
};
|
|
131
160
|
|
|
132
161
|
// Array of work to be done, consisting of subarrays described below:
|
|
@@ -152,27 +181,11 @@ CronDate.prototype.increment = function (pattern) {
|
|
|
152
181
|
// findNext sets the current member to next match in pattern
|
|
153
182
|
// If time is 00:00:01 and pattern says *:*:05, seconds will
|
|
154
183
|
// be set to 5
|
|
155
|
-
if(!findNext(toDo[doing][0], pattern, toDo[doing][2])) {
|
|
156
184
|
|
|
157
|
-
|
|
185
|
+
// If pattern didn't provide a match, increment next vanlue (e.g. minues)
|
|
186
|
+
if(!findNext(toDo[doing][0], pattern, toDo[doing][2])) {
|
|
158
187
|
this[toDo[doing][1]]++;
|
|
159
|
-
|
|
160
|
-
// Now when we have gone to next minute, we have to set seconds to the first match
|
|
161
|
-
// Now we are at 00:01:05 following the same example.
|
|
162
|
-
//
|
|
163
|
-
// This goes all the way back to seconds, hence the reverse loop.
|
|
164
|
-
while(doing >= 0) {
|
|
165
|
-
|
|
166
|
-
// Ok, reset current member(e.g. seconds) to first match in pattern, using
|
|
167
|
-
// the same method as aerlier
|
|
168
|
-
//
|
|
169
|
-
// Note the fourth parameter, stating that we should start matching the pattern
|
|
170
|
-
// from zero, instead of current time.
|
|
171
|
-
findNext(toDo[doing][0], pattern, toDo[doing][2], 0);
|
|
172
|
-
|
|
173
|
-
// Go back up, days -> hours -> minutes -> seconds
|
|
174
|
-
doing--;
|
|
175
|
-
}
|
|
188
|
+
resetPrevious();
|
|
176
189
|
}
|
|
177
190
|
|
|
178
191
|
// Gp down, seconds -> minutes -> hours -> days -> months -> year
|
|
@@ -183,9 +196,22 @@ CronDate.prototype.increment = function (pattern) {
|
|
|
183
196
|
// with weekday patterns, it's just to increment days until we get a match.
|
|
184
197
|
while (!pattern.daysOfWeek[this.getDate().getDay()]) {
|
|
185
198
|
this.days += 1;
|
|
199
|
+
doing = 2;
|
|
200
|
+
resetPrevious();
|
|
186
201
|
}
|
|
187
202
|
|
|
188
|
-
|
|
203
|
+
// If anything changed, recreate this CronDate and run again without incrementing
|
|
204
|
+
if (origTime != self.getTime()) {
|
|
205
|
+
self = new CronDate(self);
|
|
206
|
+
if (this.years >= 4000) {
|
|
207
|
+
// Stop incrementing, an impossible pattern is used
|
|
208
|
+
return null;
|
|
209
|
+
} else {
|
|
210
|
+
return self.increment(pattern, true);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
189
215
|
|
|
190
216
|
};
|
|
191
217
|
|
package/src/pattern.js
CHANGED
|
@@ -37,10 +37,7 @@ CronPattern.prototype.parse = function () {
|
|
|
37
37
|
let parts = this.pattern.trim().replace(/\s+/g, " ").split(" "),
|
|
38
38
|
part,
|
|
39
39
|
i,
|
|
40
|
-
reValidCron = /[^/*0-9,-]
|
|
41
|
-
hasMonths,
|
|
42
|
-
hasDaysOfWeek,
|
|
43
|
-
hasDates;
|
|
40
|
+
reValidCron = /[^/*0-9,-]+/;
|
|
44
41
|
|
|
45
42
|
// Validite number of configuration entries
|
|
46
43
|
if( parts.length < 5 || parts.length > 6 ) {
|
|
@@ -62,16 +59,6 @@ CronPattern.prototype.parse = function () {
|
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
61
|
|
|
65
|
-
// Check that we dont have both months and daysofweek
|
|
66
|
-
hasMonths = (parts[4] !== "*");
|
|
67
|
-
hasDaysOfWeek = (parts[5] !== "*");
|
|
68
|
-
hasDates = (parts[3] !== "*");
|
|
69
|
-
|
|
70
|
-
// Month/Date and dayofweek is incompatible
|
|
71
|
-
if( hasDaysOfWeek && (hasMonths || hasDates) ) {
|
|
72
|
-
throw new TypeError("CronPattern: configuration invalid, you can not combine month/date with day of week.");
|
|
73
|
-
}
|
|
74
|
-
|
|
75
62
|
// Parse parts into arrays, validates as we go
|
|
76
63
|
this.partToArray("seconds", parts[0], 0);
|
|
77
64
|
this.partToArray("minutes", parts[1], 0);
|
package/test/src/suite.cjs
CHANGED
|
@@ -120,6 +120,13 @@ module.exports = function (Cron) {
|
|
|
120
120
|
}).should.throw();
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
+
it("Multiple stepping should throw", function () {
|
|
124
|
+
(function(){
|
|
125
|
+
let scheduler = new Cron("* */5/5 * * * *");
|
|
126
|
+
scheduler.next();
|
|
127
|
+
}).should.throw();
|
|
128
|
+
});
|
|
129
|
+
|
|
123
130
|
it("Missing lower range should throw", function () {
|
|
124
131
|
(function(){
|
|
125
132
|
let scheduler = new Cron("* -9 * * * *");
|
|
@@ -134,6 +141,27 @@ module.exports = function (Cron) {
|
|
|
134
141
|
}).should.throw();
|
|
135
142
|
});
|
|
136
143
|
|
|
144
|
+
it("Higher upper range than lower range should throw", function () {
|
|
145
|
+
(function(){
|
|
146
|
+
let scheduler = new Cron("* 12-2 * * * *");
|
|
147
|
+
scheduler.next();
|
|
148
|
+
}).should.throw();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("Rangerange should throw", function () {
|
|
152
|
+
(function(){
|
|
153
|
+
let scheduler = new Cron("* 0-0-0 * * * *");
|
|
154
|
+
scheduler.next();
|
|
155
|
+
}).should.throw();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it("Invalid data type of pattern should throw", function () {
|
|
159
|
+
(function(){
|
|
160
|
+
let scheduler = new Cron(new Date());
|
|
161
|
+
scheduler.next();
|
|
162
|
+
}).should.throw();
|
|
163
|
+
});
|
|
164
|
+
|
|
137
165
|
it("Valid range should not throw", function () {
|
|
138
166
|
(function(){
|
|
139
167
|
let scheduler = new Cron("* 0-9 * * * *");
|
|
@@ -182,6 +210,13 @@ module.exports = function (Cron) {
|
|
|
182
210
|
scheduler.next();
|
|
183
211
|
}).should.throw();
|
|
184
212
|
});
|
|
213
|
+
|
|
214
|
+
it("Array passed as next date should throw", function () {
|
|
215
|
+
(function(){
|
|
216
|
+
let scheduler = new Cron("* * * * * *");
|
|
217
|
+
scheduler.next([]);
|
|
218
|
+
}).should.throw();
|
|
219
|
+
});
|
|
185
220
|
|
|
186
221
|
it("Valid days should not throw", function () {
|
|
187
222
|
(function(){
|
|
@@ -365,15 +400,14 @@ module.exports = function (Cron) {
|
|
|
365
400
|
|
|
366
401
|
it("* * * * * * with maxRuns: 1 should return undefined after 1.5 seconds", function (done) {
|
|
367
402
|
let
|
|
368
|
-
scheduler = new Cron("* * * * * *");
|
|
369
|
-
scheduler.schedule(
|
|
403
|
+
scheduler = new Cron("* * * * * *", { maxRuns: 1 });
|
|
404
|
+
scheduler.schedule(function () {});
|
|
370
405
|
setTimeout(function () {
|
|
371
406
|
let nextRun = scheduler.next();
|
|
372
407
|
// Do comparison
|
|
373
408
|
should.equal(nextRun, void 0);
|
|
374
409
|
done();
|
|
375
410
|
},1500);
|
|
376
|
-
|
|
377
411
|
});
|
|
378
412
|
|
|
379
413
|
it("0 0 0 * * * with 40 iterations should return 40 days from now", function () {
|
|
@@ -524,10 +558,7 @@ module.exports = function (Cron) {
|
|
|
524
558
|
nextRun0.getTime().should.equal(nextRun7.getTime());
|
|
525
559
|
});
|
|
526
560
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
describe("Comprehensive testing ( will fail first day of the year)", function () {
|
|
530
|
-
it("Test milliseconds to 01:01:91 XXXX-01-01 (most often next year), 1000s steps", function () {
|
|
561
|
+
it("Test milliseconds to 01:01:01 XXXX-01-01 (most often next year), 1000s steps", function () {
|
|
531
562
|
|
|
532
563
|
let prevRun = new Date(new Date().setMilliseconds(0)),
|
|
533
564
|
target = new Date(new Date((prevRun.getFullYear()+1) + "-01-01 01:01:01").getTime()),
|
|
@@ -569,5 +600,77 @@ module.exports = function (Cron) {
|
|
|
569
600
|
}
|
|
570
601
|
|
|
571
602
|
});
|
|
603
|
+
it("Test when next thursday 1st november occurr, starting from 2021-10-13 00:00:00", function () {
|
|
604
|
+
//Cron("0 0 0 1 11 4").next(new Date(1634076000000)).getTime().should.equal(1888182000000);
|
|
605
|
+
Cron("0 0 0 1 11 4").next(new Date(1634076000000)).getFullYear().should.equal(2029);
|
|
606
|
+
});
|
|
607
|
+
it("getTime should return expcted difference with different timezones (now)", function () {
|
|
608
|
+
let timeStockholm = Cron("* * * * * *", {timezone: "Europe/Stockholm"}).next(new Date()).getTime(),
|
|
609
|
+
timeNewYork = Cron("* * * * * *", {timezone: "America/New_York"}).next(new Date()).getTime();
|
|
610
|
+
|
|
611
|
+
// The time right now should be the same in utc wether in new york or stockholm
|
|
612
|
+
timeStockholm.should.be.above(timeNewYork-1000);
|
|
613
|
+
timeStockholm.should.be.below(timeNewYork+1000);
|
|
614
|
+
});
|
|
615
|
+
/*it("getTime should return expcted difference with different timezones (net sunday 1st november)", function () {
|
|
616
|
+
let timeStockholm = Cron("* * * 1 11 4", {timezone: "Europe/Stockholm"}).next(new Date(1634076000000)).getTime(),
|
|
617
|
+
timeNewYork = Cron("* * * 1 11 4", {timezone: "America/New_York"}).next(new Date(1634076000000)).getTime();
|
|
618
|
+
|
|
619
|
+
// The time when next sunday 1st november occur should be with 6 hours difference (seen from utc)
|
|
620
|
+
timeStockholm.should.equal(timeNewYork-6*1000*3600);
|
|
621
|
+
});*/
|
|
622
|
+
it("maxRuns should be inherited from scheduler to job", function () {
|
|
623
|
+
let scheduler = Cron("* * * 1 11 4", {maxRuns: 14}),
|
|
624
|
+
job = scheduler.schedule(() => {});
|
|
625
|
+
job.options.maxRuns.should.equal(14);
|
|
626
|
+
job.stop();
|
|
627
|
+
});
|
|
628
|
+
it("Next saturday at 29th of february should occur 2048", function () {
|
|
629
|
+
let nextSaturday29feb = Cron("0 0 0 29 2 6").next(new Date(1634076000000));
|
|
630
|
+
nextSaturday29feb.getFullYear().should.equal(2048);
|
|
631
|
+
});
|
|
632
|
+
it("Impossible combination should result in null", function () {
|
|
633
|
+
let impossible = Cron("0 0 0 30 2 6").next(new Date(1634076000000));
|
|
634
|
+
should.equal(null, impossible);
|
|
635
|
+
});
|
|
636
|
+
it("shorthand schedule without options should not throw, and execute", function (done) {
|
|
637
|
+
(function(){
|
|
638
|
+
let job = Cron("* * * * * *",() => { job.stop(); done(); });
|
|
639
|
+
}).should.not.throw();
|
|
640
|
+
});
|
|
641
|
+
it("sanity check start stop resume", function () {
|
|
642
|
+
let job = Cron("* * * 1 11 4",() => {});
|
|
643
|
+
(function(){
|
|
644
|
+
job.pause();
|
|
645
|
+
job.resume();
|
|
646
|
+
job.stop();
|
|
647
|
+
}).should.not.throw();
|
|
648
|
+
});
|
|
649
|
+
it("pause by options work", function (done) {
|
|
650
|
+
let job = Cron("* * * * * *",{paused:true},() => { throw new Error("This should not happen"); });
|
|
651
|
+
setTimeout(function () {
|
|
652
|
+
job.stop();
|
|
653
|
+
done();
|
|
654
|
+
},1500);
|
|
655
|
+
});
|
|
656
|
+
it("previous run time should be null if not yet executed", function () {
|
|
657
|
+
let job = Cron("* * * 1 11 4",() => {});
|
|
658
|
+
let result = job.previous();
|
|
659
|
+
should.equal(result,null);
|
|
660
|
+
job.stop();
|
|
661
|
+
});
|
|
662
|
+
it("previous run time should be set if executed", function (done) {
|
|
663
|
+
let
|
|
664
|
+
scheduler = new Cron("* * * * * *", { maxRuns: 1 });
|
|
665
|
+
scheduler.schedule(function () {});
|
|
666
|
+
setTimeout(function () {
|
|
667
|
+
let previous = scheduler.previous();
|
|
668
|
+
// Do comparison
|
|
669
|
+
previous.should.be.above(new Date().getTime()-3000);
|
|
670
|
+
previous.should.be.below(new Date().getTime()+3000);
|
|
671
|
+
scheduler.stop();
|
|
672
|
+
done();
|
|
673
|
+
},1500);
|
|
674
|
+
});
|
|
572
675
|
});
|
|
573
676
|
};
|
package/types/croner.d.ts
CHANGED
|
@@ -9,21 +9,13 @@ export type CronOptions = {
|
|
|
9
9
|
*/
|
|
10
10
|
paused?: boolean;
|
|
11
11
|
/**
|
|
12
|
-
* - Job is about to be killed
|
|
12
|
+
* - Job is about to be killed or killed
|
|
13
13
|
*/
|
|
14
14
|
kill?: boolean;
|
|
15
15
|
/**
|
|
16
16
|
* - Maximum nuber of executions
|
|
17
17
|
*/
|
|
18
18
|
maxRuns?: number;
|
|
19
|
-
/**
|
|
20
|
-
* - Internal: setTimeout "id"
|
|
21
|
-
*/
|
|
22
|
-
currentTimeout?: number;
|
|
23
|
-
/**
|
|
24
|
-
* - Previous run time
|
|
25
|
-
*/
|
|
26
|
-
previous?: CronNextResult;
|
|
27
19
|
/**
|
|
28
20
|
* - When to start running
|
|
29
21
|
*/
|
|
@@ -95,12 +87,13 @@ export class Cron {
|
|
|
95
87
|
/** @type {CronPattern} */
|
|
96
88
|
pattern: CronPattern;
|
|
97
89
|
/** @type {CronOptions} */
|
|
98
|
-
|
|
90
|
+
options: CronOptions;
|
|
99
91
|
/**
|
|
100
|
-
*
|
|
101
|
-
* @
|
|
92
|
+
*
|
|
93
|
+
* @param {CronOptions} options
|
|
94
|
+
* @returns {CronOptions}
|
|
102
95
|
*/
|
|
103
|
-
|
|
96
|
+
processOptions(options: CronOptions): CronOptions;
|
|
104
97
|
/**
|
|
105
98
|
* Find next runtime, based on supplied date. Strips milliseconds.
|
|
106
99
|
*
|
|
@@ -115,13 +108,6 @@ export class Cron {
|
|
|
115
108
|
*/
|
|
116
109
|
previous(): Date | null;
|
|
117
110
|
private _next;
|
|
118
|
-
/**
|
|
119
|
-
* Validate (and cleans) options. Raises error on failure.
|
|
120
|
-
*
|
|
121
|
-
* @param {CronOptions} opts - Input options
|
|
122
|
-
* @returns {CronOptions} - Clean and validated options.
|
|
123
|
-
*/
|
|
124
|
-
validateOpts(opts: CronOptions): CronOptions;
|
|
125
111
|
/**
|
|
126
112
|
* Returns number of milliseconds to next run
|
|
127
113
|
*
|
|
@@ -129,17 +115,33 @@ export class Cron {
|
|
|
129
115
|
* @returns {number | null}
|
|
130
116
|
*/
|
|
131
117
|
msToNext(prev?: CronNextResult): number | null;
|
|
118
|
+
/**
|
|
119
|
+
* Stop execution
|
|
120
|
+
* @public
|
|
121
|
+
*/
|
|
122
|
+
public stop(): void;
|
|
123
|
+
/**
|
|
124
|
+
* Pause execution
|
|
125
|
+
* @public
|
|
126
|
+
*
|
|
127
|
+
* @returns {boolean} - Wether pause was successful
|
|
128
|
+
*/
|
|
129
|
+
public pause(): boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Pause execution
|
|
132
|
+
* @public
|
|
133
|
+
*
|
|
134
|
+
* @returns {boolean} - Wether resume was successful
|
|
135
|
+
*/
|
|
136
|
+
public resume(): boolean;
|
|
132
137
|
/**
|
|
133
138
|
* Schedule a new job
|
|
139
|
+
* @public
|
|
134
140
|
*
|
|
135
|
-
* @
|
|
136
|
-
* @param {CronOptions | Function} [options] - Options
|
|
137
|
-
* @param {Function} [func] - Function to be run each iteration of pattern
|
|
141
|
+
* @param {Function} func - Function to be run each iteration of pattern
|
|
138
142
|
* @returns {CronJob}
|
|
139
|
-
*
|
|
140
143
|
*/
|
|
141
|
-
schedule(
|
|
142
|
-
private _schedule;
|
|
144
|
+
public schedule(func: Function): CronJob;
|
|
143
145
|
}
|
|
144
146
|
import { CronDate } from "./date.js";
|
|
145
147
|
import { CronPattern } from "./pattern.js";
|
package/types/date.d.ts
CHANGED
|
@@ -32,9 +32,10 @@ export class CronDate {
|
|
|
32
32
|
* @public
|
|
33
33
|
*
|
|
34
34
|
* @param {string} pattern - The pattern used to increment current state
|
|
35
|
-
* @
|
|
35
|
+
* @param {boolean} [rerun=false] - If this is an internal incremental run
|
|
36
|
+
* @return {CronDate|null} - Returns itself for chaining, or null if increment wasnt possible
|
|
36
37
|
*/
|
|
37
|
-
public increment(pattern: string):
|
|
38
|
+
public increment(pattern: string, rerun?: boolean): CronDate | null;
|
|
38
39
|
/**
|
|
39
40
|
* Convert current state back to a javascript Date()
|
|
40
41
|
* @public
|