Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

croner

Package Overview
Dependencies
Maintainers
1
Versions
228
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

croner - npm Package Compare versions

Comparing version 1.0.4 to 1.0.5

569

lib/croner.js

@@ -47,311 +47,348 @@

------------------------------------------------------------------------------------ */
(function () {
var root = this,
function raise (err) {
throw new TypeError('Cron parser: ' + err);
}
function partToArray (type, arr, conf, valueIndexOffset) {
// 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.
//
// 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;
var i,x,
confParts,
split,
index,
lower,
upper;
// First off, handle wildcard
if (conf === '*' ) {
for (i = 0; i < arr.length; i++) {
arr[i] = 1;
}
return;
function raise (err) {
throw new TypeError('Cron parser: ' + err);
}
// Check if we need to split
confParts = conf.split(',');
// Recurse into comma separated entries
if (confParts.length > 1) {
for (i = 0; i < confParts.length; i++) {
partToArray(type, arr, confParts[i], valueIndexOffset);
}
return;
}
// Didn't need to recurse, determine if this is a range or a number
if (conf.indexOf('-') === -1) {
// Got a number
index = (parseInt(conf, 10) + valueIndexOffset);
function partToArray (type, arr, conf, valueIndexOffset) {
if (index < 0 || index >= arr.length) {
raise(type + ' value out of range: "' + conf + '"');
var i,x,
confParts,
split,
index,
lower,
upper;
// First off, handle wildcard
if (conf === '*' ) {
for (i = 0; i < arr.length; i++) {
arr[i] = 1;
}
return;
}
// Check if we need to split
confParts = conf.split(',');
// Recurse into comma separated entries
if (confParts.length > 1) {
for (i = 0; i < confParts.length; i++) {
partToArray(type, arr, confParts[i], valueIndexOffset);
}
return;
}
// Didn't need to recurse, determine if this is a range or a number
if (conf.indexOf('-') === -1) {
// Got a number
index = (parseInt(conf, 10) + valueIndexOffset);
arr[index] = 1;
} else {
if (index < 0 || index >= arr.length) {
raise(type + ' value out of range: "' + conf + '"');
}
// Got a range
split = conf.split('-');
arr[index] = 1;
} else {
if (split.length !== 2) {
raise('syntax error, illegal range: "' + conf + '"');
}
// Got a range
split = conf.split('-');
lower = parseInt(split[0], 10) + valueIndexOffset;
upper = parseInt(split[1], 10) + valueIndexOffset;
if (split.length !== 2) {
raise('syntax error, illegal range: "' + conf + '"');
}
if (isNaN(lower)) {
raise('syntax error, illegal lower range (NaN)');
} else if (isNaN(upper)) {
raise('syntax error, illegal upper range (NaN)');
}
lower = parseInt(split[0], 10) + valueIndexOffset;
upper = parseInt(split[1], 10) + valueIndexOffset;
//
if (lower < 0 || upper >= arr.length) {
raise('value out of range: "' + conf + '"');
}
if (isNaN(lower)) {
raise('syntax error, illegal lower range (NaN)');
} else if (isNaN(upper)) {
raise('syntax error, illegal upper range (NaN)');
}
//
if (lower > upper) {
raise('from value is larger than to value: "' + conf + '"');
}
//
if (lower < 0 || upper >= arr.length) {
raise('value out of range: "' + conf + '"');
}
for (x = lower; x <= upper; x++) {
arr[(x + valueIndexOffset)] = 1;
//
if (lower > upper) {
raise('from value is larger than to value: "' + conf + '"');
}
for (x = lower; x <= upper; x++) {
arr[(x + valueIndexOffset)] = 1;
}
}
}
}
function parsePattern(pattern, target) {
function parsePattern(pattern, target) {
// Sanity check
if (typeof pattern !== 'string') {
raise('invalid configuration string ("' + pattern + '").');
}
// Sanity check
if (typeof pattern !== 'string') {
raise('invalid configuration string ("' + pattern + '").');
}
// Split configuration on whitespace
var parts = pattern.trim().replace(/\s+/g, ' ').split(' '),
part,
i,
reValidCron = /[^0-9,-]+/,
hasMonths,
hasDaysOfWeek,
hasDates,
// Split configuration on whitespace
var parts = pattern.trim().replace(/\s+/g, ' ').split(' '),
part,
i,
reValidCron = /[^0-9,-]+/,
hasMonths,
hasDaysOfWeek,
hasDates,
seconds,
minutes,
hours,
days,
months,
daysOfWeek;
seconds,
minutes,
hours,
days,
months,
daysOfWeek;
// Validite number of configuration entries
if (parts.length !== 6) {
raise('invalid configuration format ("' + pattern + '"), exacly five space separated parts required.');
}
// Validite number of configuration entries
if (parts.length !== 6) {
raise('invalid configuration format ("' + pattern + '"), exacly five space separated parts required.');
}
// Validate field content
for (i = 0; i < parts.length; i++) {
part = parts[i].trim();
// Validate field content
for (i = 0; i < parts.length; i++) {
part = parts[i].trim();
// Check that part only contain legal characters ^[0-9-,]+$
if (part !== '*' && reValidCron.test(part)) {
raise('configuration entry ' + (i + 1) + ' (' + part + ') contains illegal characters.');
// Check that part only contain legal characters ^[0-9-,]+$
if (part !== '*' && reValidCron.test(part)) {
raise('configuration entry ' + (i + 1) + ' (' + part + ') contains illegal characters.');
}
}
}
// Check that we dont have both months and daysofweek
hasMonths = (parts[4] !== '*');
hasDaysOfWeek = (parts[5] !== '*');
hasDates = (parts[3] !== '*');
// Check that we dont have both months and daysofweek
hasMonths = (parts[4] !== '*');
hasDaysOfWeek = (parts[5] !== '*');
hasDates = (parts[3] !== '*');
// Month/Date and dayofweek is incompatible
if (hasDaysOfWeek && (hasMonths || hasDates)) {
raise('configuration invalid, you can not combine month/date with day of week.');
}
// Parse parts into arrays, validates as we go
partToArray('seconds', target.seconds, parts[0], 0);
partToArray('minutes', target.minutes, parts[1], 0);
partToArray('hours', target.hours, parts[2], 0);
partToArray('days', target.days, parts[3], -1);
partToArray('months', target.months, parts[4], -1);
partToArray('daysOfWeek', target.daysOfWeek, parts[5], 0);
// 0 = Sunday, 7 = Sunday
if (target.daysOfWeek[0]) {
target.daysOfWeek[7] = 1;
}
// Month/Date and dayofweek is incompatible
if (hasDaysOfWeek && (hasMonths || hasDates)) {
raise('configuration invalid, you can not combine month/date with day of week.');
}
// Parse parts into arrays, validates as we go
partToArray('seconds', target.seconds, parts[0], 0);
partToArray('minutes', target.minutes, parts[1], 0);
partToArray('hours', target.hours, parts[2], 0);
partToArray('days', target.days, parts[3], -1);
partToArray('months', target.months, parts[4], -1);
partToArray('daysOfWeek', target.daysOfWeek, parts[5], 0);
// 0 = Sunday, 7 = Sunday
if (target.daysOfWeek[0]) {
target.daysOfWeek[7] = 1;
}
if (target.daysOfWeek[7]) {
target.daysOfWeek[0] = 1;
if (target.daysOfWeek[7]) {
target.daysOfWeek[0] = 1;
}
}
}
function Cron (pattern) {
var self = this;
function Cron (pattern) {
var self = this;
self.pattern = pattern;
self.pattern = pattern;
self.seconds = Array(60).fill(0); // 0-59
self.minutes = Array(60).fill(0); // 0-59
self.hours = Array(24).fill(0); // 0-23
self.days = Array(31).fill(0); // 0-30 in array, 1-31 in config
self.months = Array(12).fill(0); // 0-11 in array, 1-12 in config
self.daysOfWeek = Array(8).fill(0); // 0-7 Where 0 = Sunday and 7=Sunday;
self.seconds = Array(60).fill(0); // 0-59
self.minutes = Array(60).fill(0); // 0-59
self.hours = Array(24).fill(0); // 0-23
self.days = Array(31).fill(0); // 0-30 in array, 1-31 in config
self.months = Array(12).fill(0); // 0-11 in array, 1-12 in config
self.daysOfWeek = Array(8).fill(0); // 0-7 Where 0 = Sunday and 7=Sunday;
self.schedulerDefaults = {
stopAt: Infinity,
maxRuns: Infinity,
kill: false
};
self.schedulerDefaults = {
stopAt: Infinity,
maxRuns: Infinity,
kill: false
};
parsePattern(pattern, self);
parsePattern(pattern, self);
return this;
}
Cron.prototype.next = function (date) {
return this;
}
Cron.prototype.next = function (date) {
var self = this,
date = date || new Date(),
temp,
var self = this,
date = date || new Date(),
temp,
collection = {
cSecs: date.getSeconds() + 1,
cMins: date.getMinutes(),
cHour: date.getHours(),
cDate: date.getDate(),
cMon: date.getMonth(),
cYear: date.getFullYear(),
},
collection = {
cSecs: date.getSeconds() + 1,
cMins: date.getMinutes(),
cHour: date.getHours(),
cDate: date.getDate(),
cMon: date.getMonth(),
cYear: date.getFullYear(),
},
secs = self.seconds,
mins = self.minutes,
hours = self.hours,
days = self.days,
months = self.months,
secs = self.seconds,
mins = self.minutes,
hours = self.hours,
days = self.days,
months = self.months,
hasDays = !(days.filter(Boolean).length==31),
hasMonths = !(months.filter(Boolean).length==12);
function goUp (what, who, current, increment, valueIndexOffset) {
hasDays = !(days.filter(Boolean).length==31),
hasMonths = !(months.filter(Boolean).length==12);
function goUp (what, who, current, increment, valueIndexOffset) {
var i, found = false, dayChanged;
var i, found = false, dayChanged;
if (what[who[current] + valueIndexOffset]) return true;
if (what[who[current] + valueIndexOffset]) return true;
for (i = (who[current] + valueIndexOffset); i < mins.length; i++) {
if (what[i]) {
who[current] = i-valueIndexOffset;
found = true;
break;
for (i = (who[current] + valueIndexOffset); i < mins.length; i++) {
if (what[i]) {
who[current] = i-valueIndexOffset;
found = true;
break;
}
}
}
if (!found) {
who[increment] += 1;
if (!found) {
who[increment] += 1;
for (i = 0; i < who[current] + valueIndexOffset; i++) {
if (what[i]) {
who[current] = i - valueIndexOffset;
break;
for (i = 0; i < who[current] + valueIndexOffset; i++) {
if (what[i]) {
who[current] = i - valueIndexOffset;
break;
}
}
}
return found;
}
// Count up to minute and hour
var upMinHour = function (collection) {
goUp(secs, collection, 'cSecs','cMins', 0);
goUp(mins, collection, 'cMins','cHour', 0);
goUp(hours, collection, 'cHour','cDate', 0);
};
upMinHour(collection);
dayChanged = false;
return found;
}
// Count up to minute and hour
var upMinHour = function (collection) {
goUp(secs, collection, 'cSecs','cMins', 0);
goUp(mins, collection, 'cMins','cHour', 0);
goUp(hours, collection, 'cHour','cDate', 0);
};
upMinHour(collection);
dayChanged = false;
if (hasDays || hasMonths) {
// Count up to date and month
dayChanged = goUp(days, collection, 'cDate', 'cMon', -1);
goUp(months, collection, 'cMon', 'cYear', 0); // No need to compensate here as javascript count months 0-11
if (hasDays || hasMonths) {
// Count up to date and month
dayChanged = goUp(days, collection, 'cDate', 'cMon', -1);
goUp(months, collection, 'cMon', 'cYear', 0); // No need to compensate here as javascript count months 0-11
return new Date(collection.cYear, collection.cMon, collection.cDate, collection.cHour, collection.cMins, collection.cSecs, 0);
}
while (!self.daysOfWeek[new Date(collection.cYear, collection.cMon, collection.cDate, collection.cHour, collection.cMins, collection.cSecs, 0).getDay()]) {
collection.cDate += 1;
dayChanged = true;
}
// If day changed, we need to re-run hours and minutes
if (dayChanged) {
collection.cMin = collection.cHour = 0;
upMinHour(collection);
}
return new Date(collection.cYear, collection.cMon, collection.cDate, collection.cHour, collection.cMins, collection.cSecs, 0);
}
while (!self.daysOfWeek[new Date(collection.cYear, collection.cMon, collection.cDate, collection.cHour, collection.cMins, collection.cSecs, 0).getDay()]) {
collection.cDate += 1;
dayChanged = true;
Cron.prototype.msToNext = function (prev) {
return (this.next(prev) - new Date().getTime());
}
// If day changed, we need to re-run hours and minutes
if (dayChanged) {
collection.cMin = collection.cHour = 0;
upMinHour(collection);
}
Cron.prototype.schedule = function (opts, func, recurse) {
var self = this,
waitMs,
return new Date(collection.cYear, collection.cMon, collection.cDate, collection.cHour, collection.cMins, collection.cSecs, 0);
}
// Prioritize context before closure,
// to allow testing of maximum delay.
_maxDelay = self.maxDelay || maxDelay;
// Make opts optional
if (!func) {
func = opts;
opts = {};
}
Cron.prototype.msToNext = function (prev) {
return (this.next(prev) - new Date().getTime());
}
// Keep options, or set defaults
opts.paused = (opts.paused === undefined) ? false : opts.paused;
opts.previous = (recurse === false) ? new Date() : opts.startAt || opts.previous;
opts.stopAt = opts.stopAt || this.schedulerDefaults.stopAt;
opts.kill = opts.kill || this.schedulerDefaults.kill;
opts.rest = opts.rest || 0;
if (!opts.maxRuns && opts.maxRuns !== 0) {
opts.maxRuns = this.schedulerDefaults.maxRuns;
}
Cron.prototype.schedule = function (opts, f, recurse) {
var self = this,
waitMs;
// Make opts optional
if ( f === undefined ) {
f = opts;
opts = {};
}
// One-timer
opts.startAt = undefined;
opts.previous = (recurse === false) ? new Date() : opts.startAt || opts.previous;
opts.stopAt = opts.stopAt || this.schedulerDefaults.stopAt;
opts.kill = opts.kill || this.schedulerDefaults.kill;
opts.rest = opts.rest || 0;
if ( opts.maxRuns === undefined ) opts.maxRuns = this.schedulerDefaults.maxRuns;
// Get ms to next run
waitMs = this.msToNext(opts.previous);
// One-timer
opts.startAt = undefined;
// Check for stop conditions
if (opts.maxRuns <= 0) return;
if (opts.stopAt !== Infinity && opts.previous.getTime() + waitMs/1000 > opts.stopAt.getTime() ) return;
if (opts.kill) return;
// Get ms to next run
waitMs = this.msToNext(opts.previous);
// setTimeout cant handle more than Math.pow(2, 32 - 1) - 1 ms
if (waitMs > _maxDelay) {
waitMs = _maxDelay;
}
// Check for stop conditions
if ( opts.maxRuns <= 0 ) return;
if ( opts.stopAt !== Infinity && opts.previous.getTime() + waitMs/1000 > opts.stopAt.getTime() ) return;
if ( opts.kill ) return;
// All ok, go go!
opts.currentTimeout = setTimeout(function () {
// setTimeout cant handle more than Math.pow(2, 32 - 1) - 1 ms
if ( waitMs > 0x7FFFFFFF) {
waitMs = 0x7FFFFFFF;
}
// Are we running? If waitMs is maxed out, this is a blank run
if ( waitMs !== _maxDelay && !opts.paused) {
opts.maxRuns--;
opts.previous = new Date();
func();
}
// All ok, go go!
setTimeout( function() {
// Are we paused? In that case we need to update last run time
if ( opts.paused ) {
opts.previous = new Date();
}
// Are we running? If waitMs is maxed out, this is a blank run
if ( waitMs !== 0x7FFFFFFF ) {
opts.maxRuns--;
opts.previous = new Date();
f();
}
// Recurse
self.schedule(opts, func, true);
}, waitMs );
// Recurse
self.schedule(opts, f, true);
// First run? Return killer
if ( !recurse ) {
return {
}, waitMs );
// Return undefined
stop: function() {
opts.kill = true;
// Stop any awaiting call
if ( opts.currentTimeout ) {
clearTimeout( opts.currentTimeout );
}
},
// First run? Return killer
if ( !recurse ) {
return {
kill: function() {
opts.kill = true;
// Return if pause were successful
pause: function() {
return (opts.paused = true) && !opts.kill;
},
// Return if resume were successful
resume: function () {
return !(opts.paused = false) && !opts.kill;
}
}

@@ -361,22 +398,17 @@ }

}
// Expose
if (typeof module != 'undefined' && typeof module.exports === 'object') {
module.exports = Cron;
} else if (typeof define === 'function' && define.amd) {
define([], function () {
return Cron;
});
} else {
root.cron = Cron;
}
}).call(this);
// Expose to
// ... Node
if (typeof module != 'undefined' && typeof module.exports === 'object') {
module.exports = function (pattern) { return new Cron(pattern); };
// ... AMD
} else if (typeof define === 'function' && define.amd) {
define([], function () {
return function (pattern) { return new Cron(pattern); };
});
// ... Other browser implementations
} else {
this.cron = function (pattern) { return new Cron(pattern); };
}
// Debug shit - To be removed
if(false) {
if(true) {
var Cron = module.exports;

@@ -387,5 +419,12 @@ var scheduler = new Cron('* * * * * *');

var job0 = scheduler.schedule(function() {
console.log('I\'m invincible!!');
console.log('I\'m invincible!!', new Date().getTime());
});
// Pause the invicible job between 5 and 15 seconds
setTimeout( function () { job0.pause(); }, 5000);
setTimeout( function () { job0.resume(); }, 15000);
// Kill the infinite job after 20 seconds, HEH!
setTimeout( function () { job0.stop(); }, 20000);
// Start a job that runs from 5 seconds from now, to 10 seconds from now

@@ -407,5 +446,2 @@ var job1 = scheduler.schedule({

// Kill the infinite job after 20 seconds, HEH!
setTimeout( function () { job0.kill(); }, 20000);
// Start a job that run five times

@@ -416,2 +452,3 @@ scheduler.schedule({maxRuns: 5}, function () {

}
}
{
"name": "croner",
"version": "1.0.4",
"version": "1.0.5",
"description": "Isomorphic JavaScript cron parser and scheduler.",

@@ -5,0 +5,0 @@ "author": "Hexagon <github.com/hexagon>",

@@ -25,3 +25,6 @@

o.msToNext();
o.schedule( [ { startAt: <date>, stopAt: <date>, maxRuns: <integer> } ,] callback);
var job = o.schedule( [ { startAt: <date>, stopAt: <date>, maxRuns: <integer> } ,] callback);
job.pause();
job.resume();
job.stop();

@@ -28,0 +31,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc