@trap_stevo/legendarybuilderpronodejs-utilities
Version:
The legendary computational utility API that makes your application a legendary application. ~ Created by Steven Compton
748 lines (543 loc) • 20.2 kB
JavaScript
/*
Created by Hassan Steven Compton.
March 2, 2024.
*/
const fs = require("fs");
const HUDUtilityManager = require("../HUDManagers/HUDUtilityManager.js");
async function GetAllKeysAsync(currentRealTimeDB, nodeID)
{
try
{
const snapshot = await currentRealTimeDB.ref(`${nodeID}`).once('value');
return Object.keys(snapshot.val() || {});
}
catch (error)
{
console.log(error);
return [];
}
}
async function getDeepIDByInputDataAsync(currentRealTimeDB, nodeID, attrName, inputData, index, analyticsType = "PBGChatAnalytics")
{
try
{
const nodeSize = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
if (nodeSize === 0) return null;
var desiredIndex = null;
const snapshots = await currentRealTimeDB.ref(`${nodeID}/${index}`).once('value');
var i = 0;
snapshots.forEach((snapshot) => {
const item = snapshot.val();
if (item && item[attrName] === inputData)
{
desiredIndex = i;
}
i++;
});
return desiredIndex;
}
catch (error)
{
console.log(error);
return null;
}
}
async function getIDByInputDataAsync(currentRealTimeDB, nodeID, attrName, inputData, analyticsType = "PBGChatAnalytics")
{
try
{
const nodeSize = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
if (nodeSize === 0) return null;
for (let i = 0; i < nodeSize; i++)
{
const snapshot = await currentRealTimeDB.ref(`${nodeID}/${i}`).once('value');
const item = snapshot.val();
if (item && item[attrName] === inputData)
{
return i;
}
}
return null;
}
catch (error)
{
console.log(error);
return null;
}
}
async function getNextDataIndexAsync(currentRealTimeDB, nodeID, analyticsType = "PBGChatAnalytics")
{
const currentDataSize = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
return currentDataSize + 1;
}
async function getCurrentDataIndexAsync(currentRealTimeDB, nodeID, analyticsType = "PBGChatAnalytics")
{
const currentDataSize = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
return currentDataSize;
}
async function getAllCurrentDataAsync(currentRealTimeDB, nodeID, multi = false, nodeAnalyticID = "", analyticsType = "PBGChatAnalytics")
{
try
{
const nodeSize = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeAnalyticID === "" ? nodeID : nodeAnalyticID);
if (nodeSize === 0) return {};
const currentData = {};
for (let i = 0; i < nodeSize; i++)
{
if (multi)
{
const snapshot = await currentRealTimeDB.ref(`${nodeID}/${i}`).once('value');
const dataJson = snapshot.val();
for (let itemIndex = 0; itemIndex < dataJson.length; itemIndex++)
{
const item = dataJson[itemIndex];
currentData[itemIndex] = item;
}
}
else
{
const snapshot = await currentRealTimeDB.ref(`${nodeID}/${i}`).once('value');
currentData[i] = snapshot.val();
}
}
return currentData;
}
catch (error)
{
console.log(error);
return {};
}
}
async function GetNextInnerDataIndex(currentRealTimeDB, nodeID, index, currentCount = false)
{
try
{
const snapshot = await currentRealTimeDB.ref(`${nodeID}/${index}`).once('value');
const data = snapshot.val();
if (!data) return 0;
const maxIndex = Object.keys(data).reduce((max, key) => Math.max(max, parseInt(key)), 0);
return currentCount ? maxIndex : maxIndex + 1;
}
catch (error)
{
console.log(error);
return 0;
}
}
async function addToAnalyticsSizeAsync(currentRealTimeDB, analyticsID, nodeID)
{
try
{
const nodeRef = currentRealTimeDB.ref(`${analyticsID}/${nodeID}`);
const snapshot = await nodeRef.once('value');
let nodeSize = snapshot.val();
nodeSize = (nodeSize !== null && !isNaN(nodeSize)) ? nodeSize : 0;
await nodeRef.set(nodeSize + 1);
return true;
}
catch (error)
{
console.log(error);
return false;
}
}
async function subtractAnalyticsSizeAsync(currentRealTimeDB, analyticsID, nodeID)
{
try
{
const nodeRef = currentRealTimeDB.ref(`${analyticsID}/${nodeID}`);
const snapshot = await nodeRef.once('value');
let nodeSize = snapshot.val();
if (nodeSize === null || isNaN(nodeSize) || nodeSize <= 0)
{
return false;
}
await nodeRef.set(nodeSize - 1);
return true;
}
catch (error)
{
console.log(error);
return false;
}
}
async function getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsID, nodeID)
{
try
{
const snapshot = await currentRealTimeDB.ref(`${analyticsID}/${nodeID}`).once('value');
const currentDataSize = snapshot.val();
return currentDataSize !== null ? currentDataSize : 0;
}
catch (error)
{
console.log(error);
return 0;
}
}
async function CheckForMultiDesiredData(currentRealTimeDB, nodeID, dataID, data)
{
try
{
const currentNodeSnapshot = currentRealTimeDB.ref(nodeID).once('value');
var desiredData = [];
currentNodeSnapshot.foreach((currentNodeData) => {
const currentData = currentNodeData.val()[dataID];
if (HUDUtilityManager.deepEqualData(currentData, data) === true)
{
desiredData.push(currentNodeData.val());
}
});
return desiredData;
}
catch (error)
{
console.log(error);
return null;
}
}
async function CheckForDesiredData(currentRealTimeDB, nodeID, dataID, data)
{
try
{
const currentNodeSnapshot = currentRealTimeDB.ref(nodeID).once('value');
var desiredData = null;
currentNodeSnapshot.foreach((currentNodeData) => {
const currentData = currentNodeData.val()[dataID];
if (HUDUtilityManager.deepEqualData(currentData, data) === true)
{
desiredData = currentNodeData.val();
return;
}
});
return desiredData;
}
catch (error)
{
console.log(error);
return null;
}
}
async function CheckDeepWriteDataTraffic(currentRealTimeDB, nodeID, index, data, currentInnerIndexCount = false)
{
try
{
const innerDataIndex = await GetNextInnerDataIndex(currentRealTimeDB, nodeID, index.toString(), currentInnerIndexCount);
const currentNode = currentRealTimeDB.ref(`${nodeID}/${index}/${innerDataIndex}`);
await currentNode.set(data);
const currentData = await currentNode.once('value');
return HUDUtilityManager.deepEqualData(currentData.val(), data);
}
catch (error)
{
console.log(error);
return false;
}
}
async function GetDesiredData(currentRealTimeDB, dataRef)
{
try
{
const desiredDataSnapshot = await currentRealTimeDB.ref(dataRef).once('value');
const desiredData = desiredDataSnapshot.val();
return desiredData ? desiredData : null;
}
catch (error)
{
console.log(`Did not get data from ${dataRef}: `, error);
return null;
}
}
async function AddDeepDataWithAutoIncrement(currentRealTimeDB, nodeID, data, inputIndex = null, recordAnalytics = true, currentCountIndex = false, analyticsID = "", analyticsType = "PBGChatAnalytics")
{
try
{
const maxRetries = 5;
let retries = 0;
let dataWriteSuccessful = false;
let desiredIndex = 0;
while (!dataWriteSuccessful && retries < maxRetries)
{
let currentIndex = inputIndex !== null ? inputIndex : await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
dataWriteSuccessful = await CheckDeepWriteDataTraffic(currentRealTimeDB, nodeID, currentIndex, data, currentCountIndex);
if (!dataWriteSuccessful)
{
await new Promise(resolve => setTimeout(resolve, 100));
retries++;
}
else
{
if (analyticsID !== "" && recordAnalytics && !(await addToAnalyticsSizeAsync(currentRealTimeDB, analyticsType, analyticsID)))
{
await currentRealTimeDB.ref(`${analyticsType}/${analyticsID}`).set(1);
}
desiredIndex = currentIndex;
}
}
return [dataWriteSuccessful, desiredIndex];
}
catch (error)
{
console.log(error);
return [false, 0];
}
}
async function CheckWriteDataMirrorDataIDTraffic(currentRealTimeDB, nodeID, index, data)
{
try
{
const currentNode = currentRealTimeDB.ref(`${nodeID}/${index}/${data}`);
if (currentNode === null || currentNode === undefined) { return false; }
await currentNode.set(data);
const currentData = await currentNode.once('value');
return HUDUtilityManager.deepEqualData(currentData.val(), data);
}
catch (error)
{
console.log(error);
return false;
}
}
async function CheckWriteDataTraffic(currentRealTimeDB, nodeID, index, data)
{
try
{
const currentNode = currentRealTimeDB.ref(`${nodeID}/${index}`);
await currentNode.set(data);
const currentData = await currentNode.once('value');
return HUDUtilityManager.deepEqualData(currentData.val(), data);
}
catch (error)
{
console.log(error);
return false;
}
}
async function AddDataWithAutoIncrement(currentRealTimeDB, nodeID, data, mirrorDataID = false, analyticsID = "", analyticsType = "PBGChatAnalytics")
{
try
{
const maxRetries = 5;
let retries = 0;
let dataWriteSuccessful = false;
let desiredIndex = 0;
while (!dataWriteSuccessful && retries < maxRetries)
{
let currentIndex = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
if (!mirrorDataID)
{
dataWriteSuccessful = await CheckWriteDataTraffic(currentRealTimeDB, nodeID, currentIndex, data);
}
else
{
dataWriteSuccessful = await CheckWriteDataMirrorDataIDTraffic(currentRealTimeDB, nodeID, currentIndex, data);
}
if (!dataWriteSuccessful)
{
await new Promise(resolve => setTimeout(resolve, 100));
retries++;
}
else
{
if (analyticsID !== "" && !(await addToAnalyticsSizeAsync(currentRealTimeDB, analyticsType, analyticsID)))
{
await currentRealTimeDB.ref(`${analyticsType}/${analyticsID}`).set(1);
}
desiredIndex = currentIndex;
}
}
return [dataWriteSuccessful, desiredIndex];
}
catch (error)
{
console.log(error);
return [false, 0];
}
}
async function AddUniqueDesiredData(currentRealTimeDB, nodeID, analyticsID, analyticsAccessID, uniqueDataName, uniqueDataPrimaryKeyID, uniqueDataID, uniqueDataInput, uniqueData, mirrorID = false)
{
try
{
const currentIndex = await getCurrentDataIndexAsync(currentRealTimeDB, nodeID, analyticsAccessID);
const indexData = await getIDByInputDataAsync(currentRealTimeDB, nodeID, uniqueDataID, uniqueDataInput !== null && uniqueDataInput !== undefined ? uniqueDataInput : -1, analyticsAccessID);
var index = indexData;
if (index === null)
{
index = currentIndex;
var uniqueDesiredData = {
[uniqueDataPrimaryKeyID] : index,
...uniqueData
};
await AddDataWithAutoIncrement(currentRealTimeDB, nodeID, uniqueDesiredData, mirrorID, analyticsID, analyticsAccessID);
}
return index;
}
catch (error)
{
console.log(`Did not add ${uniqueDataName}: ` + uniqueDataInput, error);
return null;
}
}
async function DeleteDeeperData(currentRealTimeDB, nodeID, index, innerIndex, analyticsID = "", analyticsType = "PBGChatAnalytics")
{
return new Promise(async (resolve, reject) => {
try
{
let currentIndex = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
const dataRef = await currentRealTimeDB.ref(`${nodeID}/${index}/${innerIndex}`);
await dataRef.remove().then(async () => {
console.log(`Successfully deleted ${index} in ${nodeID}!`);
await subtractAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
resolve(true);
})
.catch((error) => {
console.error(`Did not delete ${index} in ${nodeID}: `, error);
resolve(false);
return;
});
return;
}
catch (error)
{
console.log(error);
resolve(false);
}
});
}
async function DeleteData(currentRealTimeDB, nodeID, index, analyticsID = "", analyticsType = "PBGChatAnalytics")
{
return new Promise(async (resolve, reject) => {
try
{
let currentIndex = await getCurrentAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
const dataRef = await currentRealTimeDB.ref(`${nodeID}/${index}`);
await dataRef.remove().then(async () => {
console.log(`Successfully deleted ${index} in ${nodeID}!`);
await subtractAnalyticsSizeAsync(currentRealTimeDB, analyticsType, nodeID);
resolve(true);
})
.catch((error) => {
console.error(`Did not delete ${index} in ${nodeID}: `, error);
resolve(false);
return;
});
return;
}
catch (error)
{
console.log(error);
resolve(false);
}
});
}
async function UpdateDataAsync(currentRealTimeDB, nodeID, index, updateData)
{
try
{
const nodeRef = currentRealTimeDB.ref(`${nodeID}/${index}`);
await nodeRef.update(updateData);
return true;
}
catch (error)
{
console.log(error);
return false;
}
}
function listenForDeeperDataMostRecentUpdate(currentRealTimeDB, nodeID, index, currentIndex, onUpdated)
{
const ref = currentRealTimeDB.ref(`${nodeID}/${index}/${currentIndex}`);
ref.off();
ref.orderByKey().limitToLast(1).on('value', snapshot => {
onUpdated(snapshot.val());
});
}
async function listenForDeepDataWithDesiredDataMostRecentUpdate(currentRealTimeDB, nodeID, index, inputID, desiredID, onUpdated)
{
const currentNodeSnapshot = await currentRealTimeDB.ref(`${nodeID}`).once("value");
var desiredIndex = null;
await currentNodeSnapshot.forEach(async (currentNode) => {
const currentNodeData = currentNode.val();
if (HUDUtilityManager.deepEqualData(currentNodeData[inputID], index) === true)
{
desiredIndex = currentNodeData[desiredID];
}
});
if (desiredIndex === null) { return; }
const ref = currentRealTimeDB.ref(`${nodeID}/${desiredIndex}`);
ref.off();
ref.orderByKey().limitToLast(1).on('value', snapshot => {
onUpdated(snapshot.val());
});
}
function listenForDeepDataMostRecentUpdate(currentRealTimeDB, nodeID, index, onUpdated)
{
const ref = currentRealTimeDB.ref(`${nodeID}/${index}`);
ref.off();
ref.orderByKey().limitToLast(1).on('value', snapshot => {
onUpdated(snapshot.val());
});
}
function listenForDataMostRecentUpdate(currentRealTimeDB, nodeID, onUpdated)
{
const ref = currentRealTimeDB.ref(nodeID);
ref.off();
ref.orderByKey().limitToLast(1).on('value', snapshot => {
onUpdated(snapshot.val());
});
}
function listenForDeeperDataUpdates(currentRealTimeDB, nodeID, index, currentIndex, onUpdated)
{
const ref = currentRealTimeDB.ref(`${nodeID}/${index}/${currentIndex}`);
ref.off();
ref.on('value', snapshot => {
onUpdated(snapshot.val());
});
}
function listenForDeepDataUpdates(currentRealTimeDB, nodeID, index, onUpdated)
{
const ref = currentRealTimeDB.ref(`${nodeID}/${index}`);
ref.off();
ref.on('value', snapshot => {
onUpdated(snapshot.val());
});
}
function listenForDataUpdates(currentRealTimeDB, nodeID, onUpdated)
{
const ref = currentRealTimeDB.ref(nodeID);
ref.off();
ref.on('value', snapshot => {
onUpdated(snapshot.val());
});
}
module.exports = {
GetAllKeysAsync,
getDeepIDByInputDataAsync,
getIDByInputDataAsync,
getNextDataIndexAsync,
getCurrentDataIndexAsync,
getAllCurrentDataAsync,
GetNextInnerDataIndex,
getCurrentAnalyticsSizeAsync,
addToAnalyticsSizeAsync,
subtractAnalyticsSizeAsync,
CheckForMultiDesiredData,
CheckForDesiredData,
CheckDeepWriteDataTraffic,
AddDeepDataWithAutoIncrement,
CheckWriteDataMirrorDataIDTraffic,
CheckWriteDataTraffic,
GetDesiredData,
AddDataWithAutoIncrement,
AddUniqueDesiredData,
DeleteDeeperData,
DeleteData,
UpdateDataAsync,
listenForDeeperDataMostRecentUpdate,
listenForDeepDataWithDesiredDataMostRecentUpdate,
listenForDeepDataMostRecentUpdate,
listenForDataMostRecentUpdate,
listenForDeeperDataUpdates,
listenForDeepDataUpdates,
listenForDataUpdates
};