@taraai/read-write
Version:
Synchronous NoSQL/Firestore for React
125 lines (101 loc) • 3.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = useCache;
var _has = _interopRequireDefault(require("lodash/has"));
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
var _pick = _interopRequireDefault(require("lodash/pick"));
var _react = require("react");
var _reactRedux = require("react-redux");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const document = (_ref, _ref2) => {
let {
databaseOverrides = {},
database = {}
} = _ref;
let [path, id] = _ref2;
const override = databaseOverrides[path] && databaseOverrides[path][id];
const doc = database[path] && database[path][id];
if (override) return { ...doc,
...override
};
return doc;
};
const selectDocument = function (cache, id, path) {
let fields = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
if (id === undefined || path === undefined) return undefined;
const doc = document(cache, [path, id]);
if (!doc) return doc;
if (typeof fields === 'string') {
return doc[fields];
}
if (doc && fields) {
return (0, _pick.default)(doc, ['id', 'path', ...fields]);
}
return doc;
};
const selectList = function (cache) {
let {
id,
path,
ordered,
via
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
let fields = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (!ordered) return ordered;
if (ordered.length === 0 && selectDocument(cache, id, path, fields) === null) return null;
const docs = ordered.reduce((arr, _ref3) => {
let [path, id] = _ref3;
const doc = selectDocument(cache, id, path, fields);
if (doc) {
arr.push(doc);
}
return arr;
}, []);
return id && Array.isArray(docs) ? docs[0] : docs;
};
const selectAlias = (state, alias) => state && state.firestore && state.firestore.cache && state.firestore.cache[alias] || undefined;
function useCache(alias) {
let selection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
const value = typeof selection === 'string' ? selection : null;
const [fields, setFields] = (0, _react.useState)(Array.isArray(selection) ? selection : value);
const postFnc = typeof selection === 'function' ? (0, _react.useCallback)(selection) : null;
const [localAlias, setAlias] = (0, _react.useState)(alias);
(0, _react.useEffect)(() => {
if (!(0, _isEqual.default)(alias, localAlias)) {
setAlias(alias);
}
if (!(0, _isEqual.default)(fields, Array.isArray(selection) ? selection : value)) {
setFields(Array.isArray(selection) ? selection : value);
}
}, [alias, selection, value]);
const selector = (0, _react.useMemo)(() => function readSelector(state) {
const {
firestore: {
cache
} = {}
} = state || {};
if (!cache || !localAlias) return undefined;
const aliases = localAlias;
const isPathId = (0, _has.default)(localAlias, 'path');
if (isPathId) {
return selectDocument(cache, localAlias.id, localAlias.path, fields);
}
const isMultiple = Array.isArray(aliases);
const listsAndDocs = (isMultiple ? aliases : [aliases]).map(alias => {
const isAlias = typeof alias === 'string';
if (isAlias) {
const queryResults = selectAlias(state, alias);
if (!queryResults) return undefined;
return selectList(cache, queryResults, fields);
}
return selectDocument(cache, alias.id, alias.path, fields);
});
if (isMultiple) {
return postFnc ? postFnc(listsAndDocs) : listsAndDocs;
}
return (postFnc ? postFnc(listsAndDocs) : listsAndDocs)[0];
}, [localAlias, postFnc, fields]);
return (0, _reactRedux.useSelector)(selector, _isEqual.default);
}