redux-devshare
Version:
[![NPM version][npm-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Code Climate][climate-image]][climate-url] [![Code Coverage][coverage-i
311 lines (266 loc) • 10.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.unWatchEvents = exports.watchEvents = exports.unWatchEvent = exports.watchEvent = undefined;
var _isString2 = require('lodash/isString');
var _isString3 = _interopRequireDefault(_isString2);
var _map2 = require('lodash/map');
var _map3 = _interopRequireDefault(_map2);
var _filter2 = require('lodash/filter');
var _filter3 = _interopRequireDefault(_filter2);
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _constants = require('../constants');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _Promise = typeof Promise === 'undefined' ? require('es6-promise').Promise : Promise;
var getWatchPath = function getWatchPath(event, path) {
return event + ':' + (path.substring(0, 1) === '/' ? '' : '/') + path;
};
/**
* @description Set a new watcher
* @param {Object} firebase - Internal firebase object
* @param {String} event - Type of event to watch for
* @param {String} path - Path to watch with watcher
* @param {String} queryId - Id of query
*/
var setWatcher = function setWatcher(devshare, event, path) {
var queryId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
var id = queryId ? event + ':/' + queryId : getWatchPath(event, path);
if (devshare._.watchers[id]) {
devshare._.watchers[id]++;
} else {
devshare._.watchers[id] = 1;
}
return devshare._.watchers[id];
};
/**
* @description Get count of currently attached watchers
* @param {Object} firebase - Internal firebase object
* @param {String} event - Type of event to watch for
* @param {String} path - Path to watch with watcher
* @param {String} queryId - Id of query
*/
var getWatcherCount = function getWatcherCount(devshare, event, path) {
var queryId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
var id = queryId ? event + ':/' + queryId : getWatchPath(event, path);
return devshare._.watchers[id];
};
/**
* @description Get query id from query path
* @param {String} path - Path from which to get query id
*/
var getQueryIdFromPath = function getQueryIdFromPath(path) {
var origPath = path;
var pathSplitted = path.split('#');
path = pathSplitted[0];
var isQuery = pathSplitted.length > 1;
var queryParams = isQuery ? pathSplitted[1].split('&') : [];
var queryId = isQuery ? queryParams.map(function (param) {
var splittedParam = param.split('=');
if (splittedParam[0] === 'queryId') {
return splittedParam[1];
}
}).filter(function (q) {
return q;
}) : undefined;
return queryId && queryId.length > 0 ? queryId[0] : isQuery ? origPath : undefined;
};
/**
* @description Remove/Unset a watcher
* @param {Object} firebase - Internal firebase object
* @param {String} event - Type of event to watch for
* @param {String} path - Path to watch with watcher
* @param {String} queryId - Id of query
*/
var unsetWatcher = function unsetWatcher(devshare, event, path) {
var queryId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
var id = queryId || getQueryIdFromPath(path);
path = path.split('#')[0];
if (!id) {
id = getWatchPath(event, path);
}
if (devshare._.watchers[id] <= 1) {
delete devshare._.watchers[id];
if (event !== 'first_child') {
devshare.firebase.database().ref().child(path).off(event);
}
} else if (devshare._.watchers[id]) {
devshare._.watchers[id]--;
}
};
/**
* @description Watch a specific event type
* @param {Object} firebase - Internal firebase object
* @param {Function} dispatch - Action dispatch function
* @param {String} event - Type of event to watch for
* @param {String} path - Path to watch with watcher
* @param {String} dest
* @param {Boolean} onlyLastEvent - Whether or not to listen to only the last event
*/
var watchEvent = exports.watchEvent = function watchEvent(devshare, dispatch, event, path, dest) {
var onlyLastEvent = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
var isQuery = false;
var queryParams = [];
var queryId = getQueryIdFromPath(path);
if (queryId) {
var pathSplitted = path.split('#');
path = pathSplitted[0];
isQuery = true;
queryParams = pathSplitted[1].split('&');
}
var watchPath = !dest ? path : path + '@' + dest;
var counter = getWatcherCount(devshare, event, watchPath, queryId);
if (counter > 0) {
if (onlyLastEvent) {
// listen only to last query on same path
if (queryId) {
unsetWatcher(devshare, event, path, queryId);
} else {
return;
}
}
}
setWatcher(devshare, event, watchPath, queryId);
if (event === 'first_child') {
// return
return devshare.firebase.database().ref().child(path).orderByKey().limitToFirst(1).once('value', function (snapshot) {
if (snapshot.val() === null) {
dispatch({
type: _constants.NO_VALUE,
path: path
});
}
});
}
var query = devshare.firebase.database().ref().child(path);
if (isQuery) {
var doNotParse = false;
queryParams.forEach(function (param) {
param = param.split('=');
switch (param[0]) {
case 'orderByValue':
query = query.orderByValue();
doNotParse = true;
break;
case 'orderByPriority':
query = query.orderByPriority();
doNotParse = true;
break;
case 'orderByKey':
query = query.orderByKey();
doNotParse = true;
break;
case 'orderByChild':
query = query.orderByChild(param[1]);
break;
case 'limitToFirst':
query = query.limitToFirst(parseInt(param[1], 10));
break;
case 'limitToLast':
query = query.limitToLast(parseInt(param[1], 10));
break;
case 'equalTo':
var equalToParam = !doNotParse ? parseInt(param[1], 10) || param[1] : param[1];
equalToParam = equalToParam === 'null' ? null : equalToParam;
query = param.length === 3 ? query.equalTo(equalToParam, param[2]) : query.equalTo(equalToParam);
break;
case 'startAt':
var startAtParam = !doNotParse ? parseInt(param[1], 10) || param[1] : param[1];
startAtParam = startAtParam === 'null' ? null : startAtParam;
query = param.length === 3 ? query.startAt(startAtParam, param[2]) : query.startAt(startAtParam);
break;
case 'endAt':
var endAtParam = !doNotParse ? parseInt(param[1], 10) || param[1] : param[1];
endAtParam = endAtParam === 'null' ? null : endAtParam;
query = param.length === 3 ? query.endAt(endAtParam, param[2]) : query.endAt(endAtParam);
break;
default:
break;
}
});
}
var runQuery = function runQuery(q, e, p, params) {
q.on(e, function (snapshot) {
var data = e === 'child_removed' ? undefined : snapshot.val();
var resultPath = dest || e === 'value' ? p : p + '/' + snapshot.key;
if (dest && e !== 'child_removed') {
data = {
_id: snapshot.key,
val: snapshot.val()
};
}
var populates = (0, _filter3.default)(params, function (param) {
return params.indexOf('populate');
}).map(function (p) {
return p.split('=')[1];
});
// Dispatch standard if no populates
if (!populates || !populates.length) {
dispatch({
type: _constants.SET,
path: resultPath,
data: data,
snapshot: snapshot
});
} else {
//
var populate = populates[0];
var listToPopulate = snapshot.val();
var paramToPopulate = populate.split(':')[0];
var populateRoot = populate.split(':')[1];
var listRef = devshare.firebase.database().ref().child(populateRoot);
var promises = (0, _map3.default)(listToPopulate, function (item) {
return _Promise.all((0, _map3.default)(item[paramToPopulate], function (objId) {
return !(0, _isString3.default)(objId) ? _Promise.reject('Population id is not a string.\n Type: ' + (typeof objId === 'undefined' ? 'undefined' : _typeof(objId)) + '\n Id: ' + JSON.stringify(objId)) : listRef.child(objId).once('value').then(function (snap) {
return snap.val();
});
})).then(function (populatedList) {
var newItem = item;
newItem[paramToPopulate] = populatedList;
return newItem;
});
});
_Promise.all(promises).then(function (list) {
dispatch({
type: _constants.SET,
path: resultPath,
data: list
});
});
}
});
};
runQuery(query, event, path, queryParams);
};
/**
* @description Remove watcher from an event
* @param {Object} firebase - Internal firebase object
* @param {String} event - Event for which to remove the watcher
* @param {String} path - Path of watcher to remove
*/
var unWatchEvent = exports.unWatchEvent = function unWatchEvent(devshare, event, path) {
var queryId = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
return unsetWatcher(devshare, event, path, queryId);
};
/**
* @description Add watchers to a list of events
* @param {Object} firebase - Internal firebase object
* @param {Function} dispatch - Action dispatch function
* @param {Array} events - List of events for which to add watchers
*/
var watchEvents = exports.watchEvents = function watchEvents(devshare, dispatch, events) {
return events.forEach(function (event) {
return watchEvent(devshare, dispatch, event.name, event.path);
});
};
/**
* @description Remove watchers from a list of events
* @param {Object} firebase - Internal firebase object
* @param {Array} events - List of events for which to remove watchers
*/
var unWatchEvents = exports.unWatchEvents = function unWatchEvents(devshare, events) {
return events.forEach(function (event) {
return unWatchEvent(devshare, event.name, event.path);
});
};
exports.default = { watchEvents: watchEvents, unWatchEvents: unWatchEvents };