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:
parent
bffb130bd4
commit
663dfe2d54
@ -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)
|
||||||
@ -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)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user