packages/oae-util/lib/counter.js
/*!
* Copyright 2014 Apereo Foundation (AF) Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://opensource.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import * as EmitterAPI from 'oae-emitter';
/**
* A utility structure that allows one to increment and decrement a count, firing bound handlers
* when the count becomes `0`
*
* @function Counter
* @return {Object} An object with several functions that manipulate the counter
*/
const Counter = function () {
let _count = 0;
const _emitter = new EmitterAPI.EventEmitter();
const that = {};
/**
* Set the current count of the counter to zero
*
*/
that.zero = function () {
_count = 0;
_emitter.emit('empty');
};
/**
* Get the current count of the counter
*
* @return {Number} The current count
*/
that.get = function () {
return _count;
};
/**
* Increment the current count by the provided amount
*
* @param {Number} [incrBy] How much to increment the counter by. Default: 1
*/
that.incr = function (incrBy = 1) {
_count += incrBy;
};
/**
* Decrement the current count by the provided amount. If decrementing by this amount brings the
* count down to 0, then whatever handlers are waiting on it to become `0` will be fired. The
* value of the counter cannot be less than `0`, therefore decrementing an empty counter will
* result in no change, and no offset for future incrementing
*
* @param {Number} [decrBy] How much to decrement the counter by. Default: 1
*/
that.decr = function (decrBy = 1) {
// If the count is already "empty", just ensure we're settled at 0 and don't fire any events
if (_count <= 0) {
_count = 0;
return;
}
// Decrement by the provided amount, and if we become empty, fire the empty event in case
// anyone is waiting
_count -= decrBy;
if (_count <= 0) {
_count = 0;
_emitter.emit('empty');
}
};
/**
* Fire the given handler when the count becomes `0`. If the count is currently `0`, the handler
* is fired immediately
*
* @param {Function} handler Invoked when the count becomes `0`
* @returns {EventEmitter} Returns the promise that the `handler` function will be called once for the `empty` event
*/
that.whenZero = function (handler) {
if (_count <= 0) {
return handler();
}
return _emitter.once('empty', handler);
};
return that;
};
export { Counter as default };