tiny-essentials
Version:
Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.
150 lines (139 loc) • 4.41 kB
JavaScript
'use strict';
// @ts-nocheck
/**
* Class representing an asynchronous save system with callback support.
*
* This class is designed to handle database operations asynchronously and supports
* adding multiple operations to a queue, as well as running callbacks after each action.
*
* @class SaveAsync
*/
class SaveAsync {
/**
* Creates an instance of SaveAsync.
*
* @param {object} db - The database reference to interact with (e.g., Firebase or other DB).
*/
constructor(db) {
this.db = db;
this.list = [];
this.callbacks = {};
this.using = false;
}
/**
* Registers a callback to be run when a specific action type is executed.
*
* @param {string} where - The action type (e.g., "set", "push", etc.).
* @param {Function} callback - The callback function to run when the action is performed.
* @returns {boolean} Returns `true` if the callback is successfully registered.
*/
on(where, callback) {
if (!Array.isArray(this.callbacks[where])) this.callbacks[where] = [];
this.callbacks[where].push(callback);
return true;
}
/**
* Runs all callbacks associated with a specific action type.
*
* @param {string} type - The action type (e.g., "set", "push", etc.).
* @param {any} data - The data passed to the callback(s).
* @param {string} [where] - The location (optional) where the action was performed.
*/
_runCallbacks(type, data, where) {
if (Array.isArray(this.callbacks[type]))
for (const item in this.callbacks[type])
if (typeof this.callbacks[type][item] === 'function')
this.callbacks[type][item](data, where);
}
/**
* Processes the queued actions and executes them one by one.
*
* Each action in the queue is processed asynchronously. Once one action completes,
* the next action in the queue is triggered.
*/
action() {
// Insert
if (this.list.length > 0) {
// Get Item
const post = this.list.shift();
const tinyThis = this;
// Try
try {
if (typeof post.where !== 'string') {
if (post.data) {
this.db[post.type](post.data)
.then(() => {
this._runCallbacks(post.type, post.data);
tinyThis.action();
})
.catch((err) => {
console.error(err);
});
} else {
this.db[post.type]()
.then(() => {
this._runCallbacks(post.type);
tinyThis.action();
})
.catch((err) => {
console.error(err);
});
}
} else {
if (post.data) {
this.db
.child(post.where)
[post.type](post.data)
.then(() => {
this._runCallbacks(post.type, post.data, post.where);
tinyThis.action();
})
.catch((err) => {
console.error(err);
});
} else {
this.db
.child(post.where)
[post.type]()
.then(() => {
this._runCallbacks(post.type, null, post.where);
tinyThis.action();
})
.catch((err) => {
console.error(err);
});
}
}
} catch (err) {
// Error
console.error(err);
}
}
// Nope
else this.using = false;
}
/**
* Inserts a new action into the queue.
*
* The action will be executed when the system is ready (i.e., when the queue is not in use).
*
* @param {object} [data={}] - The data to be saved (optional).
* @param {string} [type='set'] - The type of the database action (e.g., 'set', 'push', etc.).
* @param {string|null} [where=null] - The location where the data should be stored (optional).
*/
insert(data = {}, type = 'set', where = null) {
// Insert
if (data !== null) {
if (where !== null) this.list.push({ where: String(where), data: data, type: type });
else this.list.push({ data: data, type: type });
} else {
if (where !== null) this.list.push({ where: String(where), type: type });
else this.list.push({ type: type });
}
if (!this.using) {
this.using = true;
this.action();
}
}
}
module.exports = SaveAsync;