/** This is a basic queue for managing work flows */
class BasicQueue {
/**
* Create a basic queue
* @param {Array} initialQueue Initial array of values
* @param {Function} frozenCB Call back to execute when an op is run while queue is frozen
*/
constructor(initialQueue = [], frozenCB) {
this._queue = Array.isArray(initialQueue) ? initialQueue : [];
this._frozen = false;
this._frozenCB = typeof frozenCB === 'function' ? frozenCB : null;
};
set queue(newQueue) {
if(Array.isArray(newQueue))
this._queue = newQueue;
}
/** @type {Array} */
get queue() {
return this._queue;
}
/** @type {string} */
get length() {
return this._queue.length;
}
set frozen(boolean) {
if(typeof boolean === 'boolean')
this._frozen = boolean;
}
/** @type {Boolean} */
get frozen() {
return this._frozen;
}
set frozenCB(cb) {
if(typeof cb === 'function')
this._frozenCB = cb;
}
/** @type {Function} */
get frozenCB() {
return this._frozenCB;
}
/** Freezes the queue */
freeze() {
this._frozen = true;
}
/** Unfreeze the queue */
unfreeze() {
this._frozen = false;
}
/** Checks if frozen and executes CB if one is provided
* Internal FN designed for lib use
* @returns {Boolean} Indicates if it was frozen
*/
freezeCheck() {
if(!this.frozen)
return false;
if(this.frozenCB)
this.frozenCB(this);
return true;
}
/**
* Adds one item to the end of the queue
* @param {*} item Item to be added to queue
* @returns {Boolean} Indicates if it was successful
*/
add(item) {
if(this.freezeCheck())
return false;
this._queue.push(item);
return true;
}
/**
* Add one item to the beginning of the queue
* @param {*} item Item to be added to queue
* @returns {Boolean} Indicates if it was successful
*/
addToBeginning(item) {
if(this.freezeCheck())
return false;
this._queue.splice(0, 0, item);
return true;
}
/**
* Gets the next items in queue
* @param {Number} qty The quantity to be returned starting from index 0
* @returns {(Array|Boolean)} Returns an array of values or false if frozen
*/
getNext(qty = 1) {
if(this.freezeCheck())
return false;
return this.getIndex(0, qty);
}
/**
* Gets the last item from the queue
* @param {Number} qty The quantity to be returned
* @returns {(Array|Boolean)} Returns an array of values or false if frozen
*/
getLast(qty = 1) {
if(this.freezeCheck())
return false;
return this.getIndex(qty * -1, qty).reverse();
}
/**
* Gets all items currently in the queue
* @returns {Array|Boolean} All items in queue or false if frozen
*/
getAll() {
if(this.freezeCheck())
return false;
return this.getIndex(0, this.length);
}
/**
* Take an item out of the queue at a specific index
* @param {Number} index The index to start at
* @param {Number} qty The number of records to retrieve
* @returns {(Array|Boolean)} Returns an array of values or false if frozen
*/
getIndex(index = 0, qty = 1) {
if(this.freezeCheck())
return false;
return this._queue.splice(index,qty);
}
/**
* Locates the item and removes it from the queue
* @param {*} item Must be the EXACT item (===) comparison done
* @returns {Boolean} Indicates if the item was removed or not
*/
remove(item) {
if(this.freezeCheck())
return false;
const index = this._queue.findIndex(qItem => qItem === item);
if(index === -1)
return false;
return this.removeIndex(index);
}
/**
* Remove one item based on the array index
* @param {Number} index Index of the item to be removed
* @returns {Boolean} Indicates if the item was removed or not
*/
removeIndex(index = 0, qty = 1) {
// Use get index, but only return if false
if(!this.getIndex(index, qty))
return false;
// Return success
return true;
}
}
module.exports = BasicQueue;