UNPKG

@taraai/read-write

Version:

Synchronous NoSQL/Firestore for React

125 lines (101 loc) 3.85 kB
"use strict"; 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); }