@taraai/read-write
Version:
Synchronous NoSQL/Firestore for React
233 lines (191 loc) • 6.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.applyParamsToQuery = applyParamsToQuery;
exports.getQueryIdFromPath = getQueryIdFromPath;
exports.getWatchPath = getWatchPath;
exports.getWatcherCount = getWatcherCount;
exports.orderedFromSnapshot = orderedFromSnapshot;
exports.populateAndDispatch = populateAndDispatch;
exports.setWatcher = setWatcher;
exports.unsetWatcher = unsetWatcher;
var _forEach2 = _interopRequireDefault(require("lodash/forEach"));
var _isNaN2 = _interopRequireDefault(require("lodash/isNaN"));
var _constants = require("../constants");
var _populate = require("./populate");
var _index = require("./index");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function tryParseToNumber(value) {
const result = Number(value);
if ((0, _isNaN2.default)(result)) {
return value;
}
return result;
}
function getWatchPath(event, path) {
if (!event || event === '' || !path) {
throw new Error('Event and path are required');
}
return `${event}:${path.substring(0, 1) === '/' ? '' : '/'}${path}`;
}
function getQueryIdFromPath(path, event) {
if (!(0, _index.isString)(path)) {
throw new Error('Query path must be a string');
}
const origPath = path;
const pathSplitted = path.split('#');
path = pathSplitted[0];
const isQuery = pathSplitted.length > 1;
const queryParams = isQuery ? pathSplitted[1].split('&') : [];
const queryId = isQuery ? queryParams.map(param => {
const splittedParam = param.split('=');
if (splittedParam[0] === 'queryId') {
return splittedParam[1];
}
}).filter(q => q) : undefined;
return queryId && queryId.length > 0 ? event ? `${event}:/${queryId}` : queryId[0] : isQuery ? origPath : undefined;
}
function setWatcher(firebase, dispatch, event, path, queryId) {
const id = queryId || getQueryIdFromPath(path, event) || getWatchPath(event, path);
if (firebase._.watchers[id]) {
firebase._.watchers[id]++;
} else {
firebase._.watchers[id] = 1;
}
dispatch({
type: _constants.actionTypes.SET_LISTENER,
path,
payload: {
id
}
});
return firebase._.watchers[id];
}
function getWatcherCount(firebase, event, path, queryId) {
const id = queryId || getQueryIdFromPath(path, event) || getWatchPath(event, path);
return firebase._.watchers[id];
}
function unsetWatcher(firebase, dispatch, event, path, queryId) {
const id = queryId || getQueryIdFromPath(path, event) || getWatchPath(event, path);
path = path.split('#')[0];
const {
watchers
} = firebase._;
if (watchers[id] <= 1) {
delete watchers[id];
if (event !== 'first_child' && event !== 'once') {
firebase.database().ref().child(path).off(event);
}
} else if (watchers[id]) {
watchers[id]--;
}
dispatch({
type: _constants.actionTypes.UNSET_LISTENER,
path,
payload: {
id
}
});
}
function applyParamsToQuery(queryParams, query) {
let doNotParse = false;
if (queryParams) {
queryParams.forEach(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 'notParsed':
doNotParse = true;
break;
case 'parsed':
doNotParse = false;
break;
case 'equalTo':
let equalToParam = !doNotParse ? tryParseToNumber(param[1]) : param[1];
equalToParam = equalToParam === 'null' ? null : equalToParam;
equalToParam = equalToParam === 'false' ? false : equalToParam;
equalToParam = equalToParam === 'true' ? true : equalToParam;
query = param.length === 3 ? query.equalTo(equalToParam, param[2]) : query.equalTo(equalToParam);
break;
case 'startAt':
let startAtParam = !doNotParse ? tryParseToNumber(param[1]) : param[1];
startAtParam = startAtParam === 'null' ? null : startAtParam;
query = param.length === 3 ? query.startAt(startAtParam, param[2]) : query.startAt(startAtParam);
break;
case 'endAt':
let endAtParam = !doNotParse ? tryParseToNumber(param[1]) : param[1];
endAtParam = endAtParam === 'null' ? null : endAtParam;
query = param.length === 3 ? query.endAt(endAtParam, param[2]) : query.endAt(endAtParam);
break;
}
});
}
return query;
}
function orderedFromSnapshot(snap) {
if (snap.hasChildren && !snap.hasChildren()) {
return null;
}
const ordered = [];
if (snap.forEach) {
snap.forEach(child => {
ordered.push({
key: child.key,
value: child.val()
});
});
}
return ordered.length ? ordered : null;
}
function populateAndDispatch(firebase, dispatch, config) {
const {
data,
populates,
snapshot,
path,
storeAs
} = config;
return (0, _populate.promisesForPopulate)(firebase, snapshot.key, data, populates).then(results => {
(0, _forEach2.default)(results, (result, path) => {
dispatch({
type: _constants.actionTypes.MERGE,
path,
data: result
});
});
dispatch({
type: _constants.actionTypes.SET,
path: storeAs || path,
data,
ordered: orderedFromSnapshot(snapshot)
});
return results;
}).catch(err => {
dispatch({
type: _constants.actionTypes.ERROR,
payload: err
});
return Promise.reject(err);
});
}