deferred-interval
Advanced tools
Comparing version 0.1.2 to 1.0.0
@@ -1,138 +0,110 @@ | ||
/* jshint node: true, strict: true */ | ||
'use strict'; | ||
/** | ||
* @module interval | ||
* @requires eventemitter3 | ||
*/ | ||
const EventEmitter = require('eventemitter3'); | ||
const _tick = Symbol('_tick'); | ||
"use strict"; | ||
const DeferredInterval = class DeferredInterval extends EventEmitter { | ||
constructor() { | ||
super(); | ||
var EventEmitter = require('eventemitter3'); | ||
Object.defineProperty(this, 'alive', { | ||
value: false, | ||
writable: true, | ||
}); | ||
Object.defineProperty(this, 'ticks', { | ||
value: 0, | ||
writable: true, | ||
}); | ||
Object.defineProperty(this, 'delay', { | ||
value: -1, | ||
writable: true, | ||
}); | ||
var tick = function () { | ||
if (this.alive) { | ||
this.funct.call(null, function done () { | ||
this.timer = setTimeout(tick.bind(this), this.delay); | ||
}.bind(this), this.ticks); | ||
Object.defineProperty(this, 'timer', { | ||
value: undefined, | ||
writable: true, | ||
}); | ||
Object.defineProperty(this, 'funct', { | ||
value: undefined, | ||
writable: true, | ||
}); | ||
} | ||
this.ticks++; | ||
this.emit('tick', this.ticks); | ||
}; | ||
get [Symbol.toStringTag]() { | ||
return 'DeferredInterval'; | ||
} | ||
[_tick]() { | ||
this.ticks++; | ||
if (this.alive) { | ||
this.funct(() => { | ||
this.timer = setTimeout(this[_tick].bind(this), this.delay); | ||
}, this.ticks); | ||
} | ||
/** | ||
* Interval - Replacement for setInterval | ||
* | ||
* @constructor | ||
*/ | ||
this.emit('tick', this.ticks); | ||
} | ||
var Interval = function () { | ||
this.alive = false; | ||
this.ticks = 0; | ||
this.delay = -1; | ||
this.timer = undefined; | ||
this.funct = undefined; | ||
}; | ||
Interval.prototype = Object.create(EventEmitter.prototype); | ||
start(callback, delay, immediate) { | ||
this.emit('start'); | ||
this.alive = true; | ||
this.delay = delay; | ||
this.funct = callback; | ||
if (immediate) { | ||
this[_tick](); | ||
return; | ||
} | ||
/** | ||
* Starts executing a callback on a given interval | ||
* | ||
* @param {function} callback The function to execute on each tick | ||
* @param {Number} delay How long, in milliseconds, each interval should be delayed | ||
* @param {Boolean} immediate If the callback should be executed immediately on start | ||
*/ | ||
this.timer = setTimeout(this[_tick].bind(this), this.delay); | ||
} | ||
Interval.prototype.start = function (callback, delay, immediate) { | ||
this.alive = true; | ||
this.delay = delay; | ||
this.funct = callback; | ||
pause(delay) { | ||
this.emit('pause'); | ||
if (immediate) { | ||
tick.call(this); | ||
return; | ||
} | ||
this.timer = setTimeout(tick.bind(this), this.delay); | ||
this.alive = false; | ||
this.emit('start'); | ||
}; | ||
clearTimeout(this.timer); | ||
if (delay) { | ||
setTimeout(this.resume.bind(this, true), delay); | ||
} | ||
} | ||
resume(immediate) { | ||
this.emit('resume'); | ||
/** | ||
* Pauses execution of the callback | ||
* | ||
* @param {Number} delay How long the pause should last. If no values is given the pause is until resume is done manually | ||
*/ | ||
this.alive = true; | ||
Interval.prototype.pause = function (delay) { | ||
this.alive = false; | ||
clearTimeout(this.timer); | ||
if (immediate) { | ||
this[_tick](); | ||
return; | ||
} | ||
if (delay) { | ||
setTimeout(this.resume.bind(this), delay); | ||
this.timer = setTimeout(this[_tick].bind(this), this.delay); | ||
} | ||
this.emit('pause'); | ||
}; | ||
stop() { | ||
this.emit('stop'); | ||
this.alive = false; | ||
this.ticks = 0; | ||
this.delay = -1; | ||
this.funct = undefined; | ||
clearTimeout(this.timer); | ||
} | ||
/** | ||
* Resumes executing the callback after a pause | ||
* | ||
* @param {Boolean} immediate If the callback should be executed immediately on resume | ||
*/ | ||
Interval.prototype.resume = function (immediate) { | ||
this.alive = true; | ||
if (immediate) { | ||
tick.call(this); | ||
return; | ||
} | ||
this.timer = setTimeout(tick.bind(this), this.delay); | ||
this.emit('resume'); | ||
adjust(delay) { | ||
this.delay = delay; | ||
return this.delay; | ||
} | ||
}; | ||
/** | ||
* Stops execution of the callback - Everything is reset. | ||
*/ | ||
Interval.prototype.stop = function () { | ||
this.alive = false; | ||
this.ticks = 0; | ||
this.delay = -1; | ||
this.funct = undefined; | ||
clearTimeout(this.timer); | ||
this.emit('stop'); | ||
}; | ||
/** | ||
* Adjust the delay of the execution of the callback function | ||
* | ||
* @param {Number} delay How long, in milliseconds, each interval should be delayed | ||
*/ | ||
Interval.prototype.adjust = function (delay) { | ||
this.delay = delay; | ||
return this.delay; | ||
}; | ||
module.exports = Interval; | ||
module.exports = DeferredInterval; |
{ | ||
"name": "deferred-interval", | ||
"version": "0.1.2", | ||
"description": "A set interval that defer the start of the next delay until the callback is executed.", | ||
"version": "1.0.0", | ||
"description": "A secure setInterval that defer the execution of the next interval only when the scheduled function have executed.", | ||
"main": "lib/interval.js", | ||
@@ -14,4 +14,6 @@ "repository": { | ||
"scripts": { | ||
"pretest": "jshint ./lib/*.js ./test/*.js", | ||
"test": "mocha ./test/*.js --reporter spec" | ||
"test": "tap test/*.js", | ||
"test:coverage": "tap test/*.js --cov", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix" | ||
}, | ||
@@ -27,9 +29,11 @@ "keywords": [ | ||
"dependencies": { | ||
"eventemitter3": "1.x" | ||
"eventemitter3": "3.1.0" | ||
}, | ||
"devDependencies": { | ||
"jshint": "latest", | ||
"mocha": "latest", | ||
"chai": "latest" | ||
"eslint": "^4.19.1", | ||
"eslint-config-airbnb-base": "^13.0.0", | ||
"eslint-plugin-import": "^2.12.0", | ||
"lolex": "^2.7.0", | ||
"tap": "^12.0.1" | ||
} | ||
} |
# deferred-interval | ||
A set interval that defer the start of the next delay until the callback is | ||
executed. | ||
A secure `setInterval` that defer the execution of the next interval only when the scheduled | ||
function have executed. | ||
## Installation | ||
@@ -15,3 +14,2 @@ | ||
## Basic example | ||
@@ -22,8 +20,8 @@ | ||
```js | ||
var Interval = require('deferred-interval'); | ||
const Interval = require('deferred-interval'); | ||
var schedule = new Interval(); | ||
schedule.start(function (done, ticks) { | ||
console.log('tick number:', ticks); | ||
done(); | ||
const schedule = new Interval(); | ||
schedule.start((done, ticks) => { | ||
console.log('tick number:', ticks); | ||
done(); | ||
}, 10000); | ||
@@ -33,3 +31,2 @@ ``` | ||
## API | ||
@@ -39,3 +36,2 @@ | ||
### .start(callback, delay, immediate) | ||
@@ -49,3 +45,2 @@ | ||
### .pause(delay) | ||
@@ -55,6 +50,5 @@ | ||
* `delay` - How long the pause should last. If no values is given the pause is | ||
* `delay` - How long the pause should last. If no values is given the pause is | ||
until resume is done manually | ||
### .resume(immediate) | ||
@@ -66,3 +60,2 @@ | ||
### .stop() | ||
@@ -72,3 +65,2 @@ | ||
### .adjust(delay) | ||
@@ -81,25 +73,13 @@ | ||
## Environments | ||
Browser and node.js. This module use [EventEmitter3](https://github.com/primus/EventEmitter3) | ||
Browser and node.js. This module use [EventEmitter3](https://github.com/primus/EventEmitter3) | ||
which works fine in browsers. | ||
## License | ||
## Tests | ||
```bash | ||
$ npm test | ||
``` | ||
Tests are written in [mocha](http://visionmedia.github.io/mocha/). | ||
## License | ||
The MIT License (MIT) | ||
Copyright (c) 2014 - Trygve Lie post@trygve-lie.com | ||
Copyright (c) 2018 - Trygve Lie post@trygve-lie.com | ||
@@ -122,2 +102,2 @@ Permission is hereby granted, free of charge, to any person obtaining a copy | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
THE SOFTWARE. |
@@ -1,25 +0,353 @@ | ||
/* jshint node: true, strict: true */ | ||
/* global describe: true, it: true, before: true */ | ||
'use strict'; | ||
"use strict"; | ||
const lolex = require('lolex'); | ||
const tap = require('tap'); | ||
var mocha = require('mocha'), | ||
assert = require('chai').assert, | ||
Interval = require('../'); | ||
const Interval = require('../'); | ||
/** | ||
* Constructor | ||
*/ | ||
tap.test('Constructor() - object type - should be TtlMemCache', (t) => { | ||
const interval = new Interval(); | ||
t.equal(Object.prototype.toString.call(interval), '[object DeferredInterval]'); | ||
t.end(); | ||
}); | ||
/** | ||
* .start() | ||
*/ | ||
describe('a()', function(){ | ||
tap.test('.set() - delay: 2000ms, immidiate: not set - should run callback once after 2000ms', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
describe('b', function(){ | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000); | ||
it('c', function(){ | ||
clock.tick(2500); | ||
assert.equal('a', 'a'); | ||
t.equal(count, 1); | ||
t.end(); | ||
}); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.set() - delay: 2000ms, immidiate: false - should run callback once after 2000ms', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(2500); | ||
t.equal(count, 1); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.set() - delay: 2000ms, immidiate: true - should run callback twice after 2000ms', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, true); | ||
clock.tick(2500); | ||
t.equal(count, 2); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.set() - delay: 2000ms, immidiate: false - should emit start event once', (t) => { | ||
const clock = lolex.install(); | ||
const interval = new Interval(); | ||
interval.on('start', () => { | ||
t.ok(true); | ||
t.end(); | ||
}); | ||
}); | ||
interval.start((done) => { | ||
done(); | ||
}, 2000, false); | ||
clock.tick(2500); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.set() - delay: 2000ms, immidiate: true - should emit "start" event once', (t) => { | ||
const clock = lolex.install(); | ||
const interval = new Interval(); | ||
interval.on('start', () => { | ||
t.ok(true); | ||
t.end(); | ||
}); | ||
interval.start((done) => { | ||
done(); | ||
}, 2000, true); | ||
clock.tick(2500); | ||
clock.uninstall(); | ||
}); | ||
/** | ||
* .pause() | ||
*/ | ||
tap.test('.pause() - delay: 1000ms - should run callback after delay', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
t.equal(count, 2); | ||
interval.pause(10000); | ||
clock.tick(11000); | ||
t.equal(count, 3); | ||
clock.tick(4000); | ||
t.equal(count, 5); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.pause() - delay: not set - should pause', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
t.equal(count, 2); | ||
interval.pause(); | ||
clock.tick(11000); | ||
t.equal(count, 2); | ||
clock.tick(4000); | ||
t.equal(count, 2); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.pause() - call method - should emit "pause" event once', (t) => { | ||
const clock = lolex.install(); | ||
const interval = new Interval(); | ||
interval.on('pause', () => { | ||
t.ok(true); | ||
t.end(); | ||
}); | ||
interval.start((done) => { | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
interval.pause(); | ||
clock.uninstall(); | ||
}); | ||
/** | ||
* .resume() | ||
*/ | ||
tap.test('.resume() - immediate: not set - should resume and start with fresh timer', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
t.equal(count, 2); | ||
interval.pause(); | ||
clock.tick(11000); | ||
t.equal(count, 2); | ||
interval.resume(); | ||
clock.tick(1000); | ||
t.equal(count, 2); | ||
clock.tick(2000); | ||
t.equal(count, 3); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.resume() - immediate: true - should resume stright away', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
t.equal(count, 2); | ||
interval.pause(); | ||
clock.tick(11000); | ||
t.equal(count, 2); | ||
interval.resume(true); | ||
clock.tick(1000); | ||
t.equal(count, 3); | ||
clock.tick(2000); | ||
t.equal(count, 4); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.resume() - call method - should emit "resume" event once', (t) => { | ||
const clock = lolex.install(); | ||
const interval = new Interval(); | ||
interval.on('resume', () => { | ||
t.ok(true); | ||
t.end(); | ||
}); | ||
interval.start((done) => { | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
interval.pause(); | ||
clock.tick(10000); | ||
interval.resume(); | ||
clock.uninstall(); | ||
}); | ||
/** | ||
* .stop() | ||
*/ | ||
tap.test('.stop() - call method - should stop', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
t.equal(count, 2); | ||
interval.stop(); | ||
clock.tick(11000); | ||
t.equal(count, 2); | ||
clock.tick(4000); | ||
t.equal(count, 2); | ||
t.end(); | ||
clock.uninstall(); | ||
}); | ||
tap.test('.stop() - call method - should emit "stop" event once', (t) => { | ||
const clock = lolex.install(); | ||
const interval = new Interval(); | ||
interval.on('stop', () => { | ||
t.ok(true); | ||
t.end(); | ||
}); | ||
interval.start((done) => { | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
interval.stop(); | ||
clock.uninstall(); | ||
}); | ||
/** | ||
* .adjust() | ||
*/ | ||
tap.test('.adjust() - delay: 1000 ms - should change interval to new delay', (t) => { | ||
const clock = lolex.install(); | ||
let count = 0; | ||
const interval = new Interval(); | ||
interval.start((done, ticks) => { | ||
count = ticks; | ||
done(); | ||
}, 2000, false); | ||
clock.tick(5000); | ||
t.equal(count, 2); | ||
interval.adjust(1000); | ||
clock.tick(2000); | ||
t.equal(count, 4); | ||
t.end(); | ||
clock.uninstall(); | ||
}); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
18370
7
329
1
5
94
1
+ Addedeventemitter3@3.1.0(transitive)
- Removedeventemitter3@1.2.0(transitive)
Updatedeventemitter3@3.1.0