Comparing version 1.0.15 to 1.1.0
@@ -8,17 +8,3 @@ /* ------------------------------------------------------------------------------------ | ||
------------------------------------------------------------------------------------ | ||
Pattern: | ||
``` | ||
┌──────────────── sec (0 - 59) | ||
| ┌────────────── min (0 - 59) | ||
| │ ┌──────────── hour (0 - 23) | ||
| │ │ ┌────────── day of month (1 - 31) | ||
| │ │ │ ┌──────── month (1 - 12) | ||
| │ │ │ │ ┌────── day of week (0 - 6) | ||
| │ │ │ │ │ (0 to 6 are Sunday to Saturday; 7 is Sunday, the same as 0) | ||
| │ │ │ │ │ | ||
* * * * * * ``` | ||
------------------------------------------------------------------------------------ | ||
License: | ||
@@ -55,8 +41,17 @@ | ||
// Many JS engines stores the delay as a 32-bit signed integer internally. | ||
// This causes an integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately. | ||
// This causes an integer overflow when using delays larger than 2147483647, | ||
// resulting in the timeout being executed immediately. | ||
// | ||
// All JS engines implements an immediate execution of delays larger that a 32-bit int to keep the behaviour concistent. | ||
// All JS engines implements an immediate execution of delays larger that a 32-bit | ||
// int to keep the behaviour concistent. | ||
maxDelay = Math.pow(2, 32 - 1) - 1; | ||
// | ||
// ---- Helper functions ------------------------------------------------------------ | ||
// | ||
function raise (err) { | ||
throw new TypeError("Cron parser: " + err); | ||
@@ -66,2 +61,3 @@ } | ||
function safeDate() { | ||
return new Date(new Date().setMilliseconds(0)); | ||
@@ -71,8 +67,18 @@ } | ||
function fill(arr, val) { | ||
// Simple "Polyfill" for Array.fill on pre ES6 environments | ||
for(var i = 0; i < arr.length; i++) { | ||
arr[i] = val; | ||
} | ||
return arr; | ||
} | ||
// | ||
// ---- CronDate --------------------------------------------------------------------- | ||
// | ||
function CronDate (date) { | ||
@@ -89,3 +95,4 @@ this.seconds = date.getSeconds() + 1; | ||
var startPos = (override === void 0) ? this[target] + offset : 0 + offset, result = false; | ||
var startPos = (override === void 0) ? this[target] + offset : 0 + offset, | ||
result = false; | ||
@@ -106,2 +113,9 @@ for (var i = startPos; i < pattern[target].length; i++) { | ||
// Array of work to be done, consisting of subarrays described below: | ||
// [ | ||
// First item is which member to process, | ||
// Second item is which member to increment if we didn't find a mathch in current item, | ||
// Third item is an offset. if months is handled 0-11 in js date object, and we get 1-12 | ||
// from pattern. Offset should be -1 | ||
// ] | ||
var toDo = [ | ||
@@ -116,13 +130,38 @@ ["seconds", "minutes", 0], | ||
// Ok, we're working our way trough the toDo array, top to bottom | ||
// If we reach 5, work is done | ||
while(doing < 5) { | ||
// findNext sets the current member to next match in pattern | ||
// If time is 00:00:01 and pattern says *:*:05, seconds will | ||
// be set to 5 | ||
if(!this.findNext(toDo[doing][0], pattern, toDo[doing][2])) { | ||
// If pattern didn't provide a match, increment next vanlue (e.g. minues) | ||
this[toDo[doing][1]]++; | ||
// Now when we have gone to next minute, we have to set seconds to the first match | ||
// Now we are at 00:01:05 following the same example. | ||
// | ||
// This goes all the way back to seconds, hence the reverse loop. | ||
while(doing >= 0) { | ||
// Ok, reset current member(e.g. seconds) to first match in pattern, using | ||
// the same method as aerlier | ||
// | ||
// Note the fourth parameter, stating that we should start matching the pattern | ||
// from zero, instead of current time. | ||
this.findNext(toDo[doing][0], pattern, toDo[doing][2], 0); | ||
// Go back up, days -> hours -> minutes -> seconds | ||
doing--; | ||
} | ||
} | ||
// Gp down, seconds -> minutes -> hours -> days -> months -> year | ||
doing++; | ||
} | ||
// This is a special case for weekday, as the user isn't able to combine date/month patterns | ||
// with weekday patterns, it's just to increment days until we get a match. | ||
while (!pattern.daysOfWeek[this.getDate().getDay()]) { | ||
@@ -137,3 +176,9 @@ this.days += 1; | ||
}; | ||
// | ||
// ---- CronPattern --------------------------------------------------------------------- | ||
// | ||
function CronPattern (pattern) { | ||
@@ -260,3 +305,3 @@ | ||
if (split.length !== 2) { | ||
raise("syntax error, illegal range: '" + conf + "'"); | ||
raise("Syntax error, illegal range: '" + conf + "'"); | ||
} | ||
@@ -268,5 +313,5 @@ | ||
if (isNaN(lower)) { | ||
raise("syntax error, illegal lower range (NaN)"); | ||
raise("Syntax error, illegal lower range (NaN)"); | ||
} else if (isNaN(upper)) { | ||
raise("syntax error, illegal upper range (NaN)"); | ||
raise("Syntax error, illegal upper range (NaN)"); | ||
} | ||
@@ -276,3 +321,3 @@ | ||
if (lower < 0 || upper >= arr.length) { | ||
raise("value out of range: '" + conf + "'"); | ||
raise("Value out of range: '" + conf + "'"); | ||
} | ||
@@ -282,3 +327,3 @@ | ||
if (lower > upper) { | ||
raise("from value is larger than to value: '" + conf + "'"); | ||
raise("From value is larger than to value: '" + conf + "'"); | ||
} | ||
@@ -292,3 +337,9 @@ | ||
function Cron (pattern) { | ||
// | ||
// ---- Cron -------------------------------------------------------------------------- | ||
// | ||
function Cron (pattern, options, fn) { | ||
var self = this; | ||
@@ -298,3 +349,3 @@ | ||
if (!(this instanceof Cron)) { | ||
return new Cron(pattern); | ||
return new Cron(pattern, options, fn); | ||
} | ||
@@ -310,3 +361,19 @@ | ||
return this; | ||
// Make options optional | ||
if( typeof options === "function" ) { | ||
fn = options; | ||
options = {}; | ||
} | ||
// Determine what to return, default is self | ||
if( typeof fn === "undefined") { | ||
// Normal initialization, return self | ||
return self; | ||
} else { | ||
// Shorthand schedule requested, return job | ||
return this.schedule(options, fn); | ||
} | ||
} | ||
@@ -413,6 +480,14 @@ | ||
}; | ||
// Expose | ||
// | ||
// ---- Expose ---------------------------------------------------------------------- | ||
// | ||
// -> Node | ||
if (typeof module != "undefined" && typeof module.exports === "object") { | ||
module.exports = Cron; | ||
// -> AMD / Requirejs etc. | ||
} else if (typeof define === "function" && define.amd) { | ||
@@ -422,6 +497,8 @@ define([], function () { | ||
}); | ||
// -> Regular script tag | ||
} else { | ||
root.cron = Cron; | ||
root.Cron = Cron; | ||
} | ||
}).call(this); |
// Licenced under MIT - croner - ©2016 Hexagon <github.com/hexagon> | ||
(function(){"use strict";function t(t){throw new TypeError("Cron parser: "+t)}function e(){return new Date((new Date).setMilliseconds(0))}function s(t,e){for(var s=0;s<t.length;s++)t[s]=e;return t}function r(t){this.seconds=t.getSeconds()+1,this.minutes=t.getMinutes(),this.hours=t.getHours(),this.days=t.getDate(),this.months=t.getMonth(),this.years=t.getFullYear()}function i(t){this.pattern=t,this.seconds=s(Array(60),0),this.minutes=s(Array(60),0),this.hours=s(Array(24),0),this.days=s(Array(31),0),this.months=s(Array(12),0),this.daysOfWeek=s(Array(8),0),this.parse()}function n(t){var e=this;return this instanceof n?(e.pattern=new i(t),e.schedulerDefaults={stopAt:1/0,maxRuns:1/0,kill:!1},this):new n(t)}var a=this,o=Math.pow(2,31)-1;r.prototype.findNext=function(t,e,s,r){for(var i=void 0===r?this[t]+s:0+s,n=!1,a=i;a<e[t].length;a++)if(e[t][a]){this[t]=a-s,n=!0;break}return n},r.prototype.increment=function(t){for(var e=[["seconds","minutes",0],["minutes","hours",0],["hours","days",0],["days","months",-1],["months","years",0]],s=0;5>s;){if(!this.findNext(e[s][0],t,e[s][2]))for(this[e[s][1]]++;s>=0;)this.findNext(e[s][0],t,e[s][2],0),s--;s++}for(;!t.daysOfWeek[this.getDate().getDay()];)this.days+=1},r.prototype.getDate=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,0)},i.prototype.parse=function(){"string"!=typeof this.pattern&&t("invalid configuration string ('"+this.pattern+"').");var e,s,r,i,n,a=this.pattern.trim().replace(/\s+/g," ").split(" "),o=/[^0-9,-]+/;for(6!==a.length&&t("invalid configuration format ('"+this.pattern+"'), exacly five space separated parts required."),s=0;s<a.length;s++)e=a[s].trim(),"*"!==e&&o.test(e)&&t("configuration entry "+(s+1)+" ("+e+") contains illegal characters.");r="*"!==a[4],i="*"!==a[5],n="*"!==a[3],i&&(r||n)&&t("configuration invalid, you can not combine month/date with day of week."),this.partToArray("seconds",this.seconds,a[0],0),this.partToArray("minutes",this.minutes,a[1],0),this.partToArray("hours",this.hours,a[2],0),this.partToArray("days",this.days,a[3],-1),this.partToArray("months",this.months,a[4],-1),this.partToArray("daysOfWeek",this.daysOfWeek,a[5],0),this.daysOfWeek[0]&&(this.daysOfWeek[7]=1),this.daysOfWeek[7]&&(this.daysOfWeek[0]=1)},i.prototype.partToArray=function(e,s,r,i){var n,a,o,u,h,l,p;if("*"!==r)if(o=r.split(","),o.length>1)for(n=0;n<o.length;n++)this.partToArray(e,s,o[n],i);else if(-1===r.indexOf("-"))h=parseInt(r,10)+i,(0>h||h>=s.length)&&t(e+" value out of range: '"+r+"'"),s[h]=1;else for(u=r.split("-"),2!==u.length&&t("syntax error, illegal range: '"+r+"'"),l=parseInt(u[0],10)+i,p=parseInt(u[1],10)+i,isNaN(l)?t("syntax error, illegal lower range (NaN)"):isNaN(p)&&t("syntax error, illegal upper range (NaN)"),(0>l||p>=s.length)&&t("value out of range: '"+r+"'"),l>p&&t("from value is larger than to value: '"+r+"'"),a=l;p>=a;a++)s[a+i]=1;else for(n=0;n<s.length;n++)s[n]=1},n.prototype.next=function(t){var s=new r(t||e());return s.increment(this.pattern),s.getDate()},n.prototype.msToNext=function(t){return t=t||e(),this.next(t)-t.getTime()},n.prototype.schedule=function(t,s,r){var i,n=this,a=n.maxDelay||o;return s||(s=t,t={}),t.paused="undefined"==typeof t.paused?!1:t.paused,t.previous=r===!1?e():t.startAt||t.previous,t.stopAt=t.stopAt||this.schedulerDefaults.stopAt,t.kill=t.kill||this.schedulerDefaults.kill,t.rest=t.rest||0,t.maxRuns||0===t.maxRuns||(t.maxRuns=this.schedulerDefaults.maxRuns),t.startAt=void 0,i=this.msToNext(t.previous),t.maxRuns<=0||t.stopAt!==1/0&&t.previous.getTime()+i/1e3>t.stopAt.getTime()||t.kill?void 0:(i>a&&(i=a),t.currentTimeout=setTimeout(function(){i===a||t.paused||(t.maxRuns--,t.previous=e(),s()),t.paused&&(t.previous=e()),n.schedule(t,s,!0)},i),{stop:function(){t.kill=!0,t.currentTimeout&&clearTimeout(t.currentTimeout)},pause:function(){return(t.paused=!0)&&!t.kill},resume:function(){return!(t.paused=!1)&&!t.kill}})},"undefined"!=typeof module&&"object"==typeof module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):a.cron=n}).call(this); | ||
(function(){"use strict";function t(t){throw new TypeError("Cron parser: "+t)}function e(){return new Date((new Date).setMilliseconds(0))}function s(t,e){for(var s=0;s<t.length;s++)t[s]=e;return t}function r(t){this.seconds=t.getSeconds()+1,this.minutes=t.getMinutes(),this.hours=t.getHours(),this.days=t.getDate(),this.months=t.getMonth(),this.years=t.getFullYear()}function i(t){this.pattern=t,this.seconds=s(Array(60),0),this.minutes=s(Array(60),0),this.hours=s(Array(24),0),this.days=s(Array(31),0),this.months=s(Array(12),0),this.daysOfWeek=s(Array(8),0),this.parse()}function n(t,e,s){var r=this;return this instanceof n?(r.pattern=new i(t),r.schedulerDefaults={stopAt:1/0,maxRuns:1/0,kill:!1},"function"==typeof e&&(s=e,e={}),"undefined"==typeof s?r:this.schedule(e,s)):new n(t,e,s)}var o=this,a=Math.pow(2,31)-1;r.prototype.findNext=function(t,e,s,r){for(var i=void 0===r?this[t]+s:0+s,n=!1,o=i;o<e[t].length;o++)if(e[t][o]){this[t]=o-s,n=!0;break}return n},r.prototype.increment=function(t){for(var e=[["seconds","minutes",0],["minutes","hours",0],["hours","days",0],["days","months",-1],["months","years",0]],s=0;5>s;){if(!this.findNext(e[s][0],t,e[s][2]))for(this[e[s][1]]++;s>=0;)this.findNext(e[s][0],t,e[s][2],0),s--;s++}for(;!t.daysOfWeek[this.getDate().getDay()];)this.days+=1},r.prototype.getDate=function(){return new Date(this.years,this.months,this.days,this.hours,this.minutes,this.seconds,0)},i.prototype.parse=function(){"string"!=typeof this.pattern&&t("invalid configuration string ('"+this.pattern+"').");var e,s,r,i,n,o=this.pattern.trim().replace(/\s+/g," ").split(" "),a=/[^0-9,-]+/;for(6!==o.length&&t("invalid configuration format ('"+this.pattern+"'), exacly five space separated parts required."),s=0;s<o.length;s++)e=o[s].trim(),"*"!==e&&a.test(e)&&t("configuration entry "+(s+1)+" ("+e+") contains illegal characters.");r="*"!==o[4],i="*"!==o[5],n="*"!==o[3],i&&(r||n)&&t("configuration invalid, you can not combine month/date with day of week."),this.partToArray("seconds",this.seconds,o[0],0),this.partToArray("minutes",this.minutes,o[1],0),this.partToArray("hours",this.hours,o[2],0),this.partToArray("days",this.days,o[3],-1),this.partToArray("months",this.months,o[4],-1),this.partToArray("daysOfWeek",this.daysOfWeek,o[5],0),this.daysOfWeek[0]&&(this.daysOfWeek[7]=1),this.daysOfWeek[7]&&(this.daysOfWeek[0]=1)},i.prototype.partToArray=function(e,s,r,i){var n,o,a,u,h,p,l;if("*"!==r)if(a=r.split(","),a.length>1)for(n=0;n<a.length;n++)this.partToArray(e,s,a[n],i);else if(-1===r.indexOf("-"))h=parseInt(r,10)+i,(0>h||h>=s.length)&&t(e+" value out of range: '"+r+"'"),s[h]=1;else for(u=r.split("-"),2!==u.length&&t("Syntax error, illegal range: '"+r+"'"),p=parseInt(u[0],10)+i,l=parseInt(u[1],10)+i,isNaN(p)?t("Syntax error, illegal lower range (NaN)"):isNaN(l)&&t("Syntax error, illegal upper range (NaN)"),(0>p||l>=s.length)&&t("Value out of range: '"+r+"'"),p>l&&t("From value is larger than to value: '"+r+"'"),o=p;l>=o;o++)s[o+i]=1;else for(n=0;n<s.length;n++)s[n]=1},n.prototype.next=function(t){var s=new r(t||e());return s.increment(this.pattern),s.getDate()},n.prototype.msToNext=function(t){return t=t||e(),this.next(t)-t.getTime()},n.prototype.schedule=function(t,s,r){var i,n=this,o=n.maxDelay||a;return s||(s=t,t={}),t.paused="undefined"==typeof t.paused?!1:t.paused,t.previous=r===!1?e():t.startAt||t.previous,t.stopAt=t.stopAt||this.schedulerDefaults.stopAt,t.kill=t.kill||this.schedulerDefaults.kill,t.rest=t.rest||0,t.maxRuns||0===t.maxRuns||(t.maxRuns=this.schedulerDefaults.maxRuns),t.startAt=void 0,i=this.msToNext(t.previous),t.maxRuns<=0||t.stopAt!==1/0&&t.previous.getTime()+i/1e3>t.stopAt.getTime()||t.kill?void 0:(i>o&&(i=o),t.currentTimeout=setTimeout(function(){i===o||t.paused||(t.maxRuns--,t.previous=e(),s()),t.paused&&(t.previous=e()),n.schedule(t,s,!0)},i),{stop:function(){t.kill=!0,t.currentTimeout&&clearTimeout(t.currentTimeout)},pause:function(){return(t.paused=!0)&&!t.kill},resume:function(){return!(t.paused=!1)&&!t.kill}})},"undefined"!=typeof module&&"object"==typeof module.exports?module.exports=n:"function"==typeof define&&define.amd?define([],function(){return n}):o.Cron=n}).call(this); |
{ | ||
"name": "croner", | ||
"version": "1.0.15", | ||
"version": "1.1.0", | ||
"description": "Isomorphic JavaScript cron parser and scheduler.", | ||
@@ -23,3 +23,6 @@ "author": "Hexagon <github.com/hexagon>", | ||
"parser", | ||
"croner" | ||
"croner", | ||
"sheduler", | ||
"timer", | ||
"isomorphic" | ||
], | ||
@@ -26,0 +29,0 @@ "dependencies": {}, |
@@ -7,3 +7,3 @@ | ||
Pure JavaScript Isomorphic cron parser and scheduler without dependencies. | ||
Pure JavaScript minimal isomorphic cron parser and scheduler. Or simply speaking - setInterval on steroids. | ||
@@ -21,29 +21,36 @@ | ||
# Examples | ||
# Usage | ||
## Minimalist scheduling | ||
```javascript | ||
var o = cron( <string pattern> ); | ||
o.next( [ <date previous> ] ); | ||
o.msToNext(); | ||
var job = o.schedule( [ { startAt: <date>, stopAt: <date>, maxRuns: <integer> } ,] callback); | ||
job.pause(); | ||
job.resume(); | ||
job.stop(); | ||
// Run a function each second | ||
Cron('* * * * * *', function () { | ||
console.log('This will run every second'); | ||
}); | ||
``` | ||
## Minimalist scheduling with options | ||
```javascript | ||
// Run a function each second | ||
Cron('* * * * * *', { maxRuns: 5 }, function () { | ||
console.log('This will run each second, but only five times.'); | ||
}); | ||
``` | ||
## Minimalist scheduling with controls | ||
```javascript | ||
// Run a function each second | ||
var job = Cron('* * * * * *', function () { | ||
console.log('This will run each second, but only five times.'); | ||
}); | ||
# Examples | ||
// Pause job | ||
job.pause(); | ||
# Parsing only | ||
```javascript | ||
// Resume job | ||
job.resume(); | ||
// Parse 14:00:00 at next sunday | ||
var parser = cron('0 0 14 * * 7'); | ||
// Stop job | ||
job.stop(); | ||
// Log the actual date object of next run | ||
console.log(parser.next()); | ||
// Log number of milliseconds to next run | ||
console.log(parser.msToNext());` | ||
``` | ||
@@ -55,6 +62,6 @@ | ||
// Run every minute | ||
var scheduler = cron('0 * * * * *'); | ||
var scheduler = Cron('0 * * * * *'); | ||
scheduler.schedule(function() { | ||
console.log('This will run every minute.'); | ||
console.log('This will run every minute'); | ||
}); | ||
@@ -67,3 +74,3 @@ ``` | ||
// Run every minute | ||
var scheduler = cron('0 * * * * *'); | ||
var scheduler = Cron('0 * * * * *'); | ||
@@ -75,4 +82,45 @@ // Schedule with options (all options are optional) | ||
``` | ||
## Scheduling with controls | ||
```javascript | ||
// Run every minute | ||
var scheduler = Cron('0 * * * * *'); | ||
// Schedule with options (all options are optional) | ||
var job = scheduler.schedule({ maxRuns: 5 }, function() { | ||
console.log('This will run every minute.'); | ||
}); | ||
// Pause job | ||
job.pause(); | ||
// Resume job | ||
job.resume(); | ||
// Stop job | ||
job.stop(); | ||
# Full API | ||
```javascript | ||
var o = Cron( <string pattern>[, <object options>] [, <function callback> ] ); | ||
// If Cron is initialized without a scheduled function, cron itself is returned | ||
// and the following member functions is available. | ||
o.next( [ <date previous> ] ); | ||
o.msToNext(); | ||
// If Cron is initialized _with_ a scheduled function, the job is retured instead. | ||
// Otherwise you get a reference to the job when scheduling a new job. | ||
var job = o.schedule( [ { startAt: <date>, stopAt: <date>, maxRuns: <integer> } ,] callback); | ||
// These self-explanatory functions is available to control the job | ||
job.pause(); | ||
job.resume(); | ||
job.stop(); | ||
``` | ||
# Pattern | ||
@@ -79,0 +127,0 @@ ``` |
@@ -284,3 +284,3 @@ /* | ||
if(target.getTime() == scheduler.next().getTime()) { | ||
if(target.getTime() === scheduler.next().getTime()) { | ||
while(prevRun < target) { | ||
@@ -287,0 +287,0 @@ left = scheduler.msToNext(prevRun); |
@@ -284,3 +284,3 @@ /* | ||
if(target.getTime() == scheduler.next().getTime()) { | ||
if(target.getTime() === scheduler.next().getTime()) { | ||
while(prevRun < target) { | ||
@@ -287,0 +287,0 @@ left = scheduler.msToNext(prevRun); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
41141
908
138