floCloudAPI v2.4.3

- Fixed a rare bug where array has empty value
- now `null` is supported by objectData update (ie, objects can now have null as value)
This commit is contained in:
sairajzero 2022-11-06 04:27:24 +05:30
parent bffb130bd4
commit 663dfe2d54

View File

@ -1,4 +1,4 @@
(function(EXPORTS) { //floCloudAPI v2.4.2e (function (EXPORTS) { //floCloudAPI v2.4.3
/* FLO Cloud operations to send/request application data*/ /* FLO Cloud operations to send/request application data*/
'use strict'; 'use strict';
const floCloudAPI = EXPORTS; const floCloudAPI = EXPORTS;
@ -94,7 +94,7 @@
}); });
var kBucket; var kBucket;
const K_Bucket = floCloudAPI.K_Bucket = function(masterID, nodeList) { const K_Bucket = floCloudAPI.K_Bucket = function (masterID, nodeList) {
const decodeID = floID => { const decodeID = floID => {
let k = bitjs.Base58.decode(floID); let k = bitjs.Base58.decode(floID);
@ -128,7 +128,7 @@
}); });
self.isNode = floID => _CO.includes(floID); self.isNode = floID => _CO.includes(floID);
self.innerNodes = function(id1, id2) { self.innerNodes = function (id1, id2) {
if (!_CO.includes(id1) || !_CO.includes(id2)) if (!_CO.includes(id1) || !_CO.includes(id2))
throw Error('Given nodes are not supernode'); throw Error('Given nodes are not supernode');
let iNodes = [] let iNodes = []
@ -139,7 +139,7 @@
} }
return iNodes return iNodes
} }
self.outterNodes = function(id1, id2) { self.outterNodes = function (id1, id2) {
if (!_CO.includes(id1) || !_CO.includes(id2)) if (!_CO.includes(id1) || !_CO.includes(id2))
throw Error('Given nodes are not supernode'); throw Error('Given nodes are not supernode');
let oNodes = [] let oNodes = []
@ -150,7 +150,7 @@
} }
return oNodes return oNodes
} }
self.prevNode = function(id, N = 1) { self.prevNode = function (id, N = 1) {
let n = N || _CO.length; let n = N || _CO.length;
if (!_CO.includes(id)) if (!_CO.includes(id))
throw Error('Given node is not supernode'); throw Error('Given node is not supernode');
@ -164,7 +164,7 @@
} }
return (N == 1 ? pNodes[0] : pNodes) return (N == 1 ? pNodes[0] : pNodes)
} }
self.nextNode = function(id, N = 1) { self.nextNode = function (id, N = 1) {
let n = N || _CO.length; let n = N || _CO.length;
if (!_CO.includes(id)) if (!_CO.includes(id))
throw Error('Given node is not supernode'); throw Error('Given node is not supernode');
@ -179,7 +179,7 @@
} }
return (N == 1 ? nNodes[0] : nNodes) return (N == 1 ? nNodes[0] : nNodes)
} }
self.closestNode = function(id, N = 1) { self.closestNode = function (id, N = 1) {
let decodedId = decodeID(id); let decodedId = decodeID(id);
let n = N || _CO.length; let n = N || _CO.length;
let cNodes = _KB.closest(decodedId, n) let cNodes = _KB.closest(decodedId, n)
@ -293,8 +293,8 @@
fetch_ActiveAPI(floID, data).then(response => { fetch_ActiveAPI(floID, data).then(response => {
if (response.ok) if (response.ok)
response.json() response.json()
.then(result => resolve(result)) .then(result => resolve(result))
.catch(error => reject(error)) .catch(error => reject(error))
else response.text() else response.text()
.then(result => reject(response.status + ": " + result)) //Error Message from Node .then(result => reject(response.status + ": " + result)) //Error Message from Node
.catch(error => reject(error)) .catch(error => reject(error))
@ -370,21 +370,21 @@
const util = floCloudAPI.util = {}; const util = floCloudAPI.util = {};
const encodeMessage = util.encodeMessage = function(message) { const encodeMessage = util.encodeMessage = function (message) {
return btoa(unescape(encodeURIComponent(JSON.stringify(message)))) return btoa(unescape(encodeURIComponent(JSON.stringify(message))))
} }
const decodeMessage = util.decodeMessage = function(message) { const decodeMessage = util.decodeMessage = function (message) {
return JSON.parse(decodeURIComponent(escape(atob(message)))) return JSON.parse(decodeURIComponent(escape(atob(message))))
} }
const filterKey = util.filterKey = function(type, options = {}) { const filterKey = util.filterKey = function (type, options = {}) {
return type + (options.comment ? ':' + options.comment : '') + return type + (options.comment ? ':' + options.comment : '') +
'|' + (options.group || options.receiverID || DEFAULT.adminID) + '|' + (options.group || options.receiverID || DEFAULT.adminID) +
'|' + (options.application || DEFAULT.application); '|' + (options.application || DEFAULT.application);
} }
const proxyID = util.proxyID = function(address) { const proxyID = util.proxyID = function (address) {
if (!address) if (!address)
return; return;
var bytes; var bytes;
@ -489,7 +489,7 @@
} }
//set status as online for user_id //set status as online for user_id
floCloudAPI.setStatus = function(options = {}) { floCloudAPI.setStatus = function (options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let callback = options.callback instanceof Function ? options.callback : DEFAULT.callback; let callback = options.callback instanceof Function ? options.callback : DEFAULT.callback;
var request = { var request = {
@ -508,7 +508,7 @@
} }
//request status of floID(s) in trackList //request status of floID(s) in trackList
floCloudAPI.requestStatus = function(trackList, options = {}) { floCloudAPI.requestStatus = function (trackList, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!Array.isArray(trackList)) if (!Array.isArray(trackList))
trackList = [trackList]; trackList = [trackList];
@ -525,7 +525,7 @@
} }
//send any message to supernode cloud storage //send any message to supernode cloud storage
const sendApplicationData = floCloudAPI.sendApplicationData = function(message, type, options = {}) { const sendApplicationData = floCloudAPI.sendApplicationData = function (message, type, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var data = { var data = {
senderID: user.id, senderID: user.id,
@ -547,7 +547,7 @@
} }
//request any data from supernode cloud //request any data from supernode cloud
const requestApplicationData = floCloudAPI.requestApplicationData = function(type, options = {}) { const requestApplicationData = floCloudAPI.requestApplicationData = function (type, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var request = { var request = {
receiverID: options.receiverID || DEFAULT.adminID, receiverID: options.receiverID || DEFAULT.adminID,
@ -650,7 +650,7 @@
*/ */
//tag data in supernode cloud (subAdmin access only) //tag data in supernode cloud (subAdmin access only)
floCloudAPI.tagApplicationData = function(vectorClock, tag, options = {}) { floCloudAPI.tagApplicationData = function (vectorClock, tag, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (!floGlobals.subAdmins.includes(user.id)) if (!floGlobals.subAdmins.includes(user.id))
return reject("Only subAdmins can tag data") return reject("Only subAdmins can tag data")
@ -671,7 +671,7 @@
} }
//note data in supernode cloud (receiver only or subAdmin allowed if receiver is adminID) //note data in supernode cloud (receiver only or subAdmin allowed if receiver is adminID)
floCloudAPI.noteApplicationData = function(vectorClock, note, options = {}) { floCloudAPI.noteApplicationData = function (vectorClock, note, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var request = { var request = {
receiverID: options.receiverID || DEFAULT.adminID, receiverID: options.receiverID || DEFAULT.adminID,
@ -690,7 +690,7 @@
} }
//send general data //send general data
floCloudAPI.sendGeneralData = function(message, type, options = {}) { floCloudAPI.sendGeneralData = function (message, type, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (options.encrypt) { if (options.encrypt) {
let encryptionKey = options.encrypt === true ? let encryptionKey = options.encrypt === true ?
@ -704,7 +704,7 @@
} }
//request general data //request general data
floCloudAPI.requestGeneralData = function(type, options = {}) { floCloudAPI.requestGeneralData = function (type, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var fk = filterKey(type, options) var fk = filterKey(type, options)
lastVC[fk] = parseInt(lastVC[fk]) || 0; lastVC[fk] = parseInt(lastVC[fk]) || 0;
@ -728,7 +728,7 @@
} }
//request an object data from supernode cloud //request an object data from supernode cloud
floCloudAPI.requestObjectData = function(objectName, options = {}) { floCloudAPI.requestObjectData = function (objectName, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
options.lowerVectorClock = options.lowerVectorClock || lastVC[objectName] + 1; options.lowerVectorClock = options.lowerVectorClock || lastVC[objectName] + 1;
options.senderID = [false, null].includes(options.senderID) ? null : options.senderID = [false, null].includes(options.senderID) ? null :
@ -765,7 +765,7 @@
}) })
} }
floCloudAPI.closeRequest = function(requestID) { floCloudAPI.closeRequest = function (requestID) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let conn = _liveRequest[requestID] let conn = _liveRequest[requestID]
if (!conn) if (!conn)
@ -779,7 +779,7 @@
} }
//reset or initialize an object and send it to cloud //reset or initialize an object and send it to cloud
floCloudAPI.resetObjectData = function(objectName, options = {}) { floCloudAPI.resetObjectData = function (objectName, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let message = { let message = {
reset: appObjects[objectName] reset: appObjects[objectName]
@ -793,7 +793,7 @@
} }
//update the diff and send it to cloud //update the diff and send it to cloud
floCloudAPI.updateObjectData = function(objectName, options = {}) { floCloudAPI.updateObjectData = function (objectName, options = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let message = { let message = {
diff: diff.find(lastCommit.get(objectName), appObjects[ diff: diff.find(lastCommit.get(objectName), appObjects[
@ -812,7 +812,7 @@
findDiff(original, updatedObj) returns an object with the added, deleted and updated differences findDiff(original, updatedObj) returns an object with the added, deleted and updated differences
mergeDiff(original, allDiff) returns a new object from original object merged with all differences (allDiff is returned object of findDiff) mergeDiff(original, allDiff) returns a new object from original object merged with all differences (allDiff is returned object of findDiff)
*/ */
var diff = (function() { var diff = (function () {
const isDate = d => d instanceof Date; const isDate = d => d instanceof Date;
const isEmpty = o => Object.keys(o).length === 0; const isEmpty = o => Object.keys(o).length === 0;
const isObject = o => o != null && typeof o === 'object'; const isObject = o => o != null && typeof o === 'object';
@ -986,23 +986,23 @@
}, {}); }, {});
}; };
const mergeRecursive = (obj1, obj2) => { const mergeRecursive = (obj1, obj2, deleteMode = false) => {
for (var p in obj2) { for (var p in obj2) {
try { try {
if (obj2[p].constructor == Object) if (obj2[p].constructor == Object)
obj1[p] = mergeRecursive(obj1[p], obj2[p]); obj1[p] = mergeRecursive(obj1[p], obj2[p], deleteMode);
// Property in destination object set; update its value. // Property in destination object set; update its value.
else if (Ext.isArray(obj2[p])) { else if (Array.isArray(obj2[p])) {
// obj1[p] = []; // obj1[p] = [];
if (obj2[p].length < 1) if (obj2[p].length < 1)
obj1[p] = obj2[p]; obj1[p] = obj2[p];
else else
obj1[p] = mergeRecursive(obj1[p], obj2[p]); obj1[p] = mergeRecursive(obj1[p], obj2[p], deleteMode);
} else } else
obj1[p] = obj2[p]; obj1[p] = deleteMode && obj2[p] === null ? undefined : obj2[p];
} catch (e) { } catch (e) {
// Property in destination object not set; create it and set its value. // Property in destination object not set; create it and set its value.
obj1[p] = obj2[p]; obj1[p] = deleteMode && obj2[p] === null ? undefined : obj2[p];
} }
} }
return obj1; return obj1;
@ -1011,23 +1011,17 @@
const cleanse = (obj) => { const cleanse = (obj) => {
Object.keys(obj).forEach(key => { Object.keys(obj).forEach(key => {
var value = obj[key]; var value = obj[key];
if (typeof value === "object" && value !== null) { if (typeof value === "object" && value !== null)
// Recurse... obj[key] = cleanse(value);
cleanse(value); else if (typeof value === 'undefined')
// ...and remove if now "empty" (NOTE: insert your definition of "empty" here) delete obj[key]; // undefined, remove it
//if (!Object.keys(value).length)
// delete obj[key];
} else if (value === null)
delete obj[key]; // null, remove it
}); });
if (obj.constructor.toString().indexOf("Array") != -1) { if (Array.isArray(obj))
obj = obj.filter(function(el) { obj = obj.filter(v => typeof v !== 'undefined');
return el != null;
});
}
return obj; return obj;
} }
const findDiff = (lhs, rhs) => ({ const findDiff = (lhs, rhs) => ({
added: addedDiff(lhs, rhs), added: addedDiff(lhs, rhs),
deleted: deletedDiff(lhs, rhs), deleted: deletedDiff(lhs, rhs),
@ -1039,7 +1033,7 @@
if (Object.keys(diff.updated).length !== 0) if (Object.keys(diff.updated).length !== 0)
obj = mergeRecursive(obj, diff.updated) obj = mergeRecursive(obj, diff.updated)
if (Object.keys(diff.deleted).length !== 0) { if (Object.keys(diff.deleted).length !== 0) {
obj = mergeRecursive(obj, diff.deleted) obj = mergeRecursive(obj, diff.deleted, true)
obj = cleanse(obj) obj = cleanse(obj)
} }
if (Object.keys(diff.added).length !== 0) if (Object.keys(diff.added).length !== 0)