UNPKG

@taraai/read-write

Version:

Synchronous NoSQL/Firestore for React

128 lines (110 loc) 3.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.mapWithFirebaseAndDispatch = mapWithFirebaseAndDispatch; exports.wrapInDispatch = wrapInDispatch; var _isFunction = _interopRequireDefault(require("lodash/isFunction")); var _isObject = _interopRequireDefault(require("lodash/isObject")); var _mapValues = _interopRequireDefault(require("lodash/mapValues")); var _mutate = _interopRequireDefault(require("./mutate")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function makePayload(_ref, valToPass) { let { payload } = _ref; return typeof payload === 'function' ? payload(valToPass) : payload; } function wrapInDispatch(dispatch, _ref2) { let { ref = {}, meta = {}, method, args = [], types } = _ref2; if (!(0, _isFunction.default)(dispatch)) { throw new Error('dispatch is not a function'); } const [requestingType, successType, errorType] = types; const startAction = { type: (0, _isObject.default)(requestingType) ? requestingType.type : requestingType, meta, payload: (0, _isObject.default)(requestingType) ? requestingType.payload : { args } }; const optimistic = new Promise((resolve, reject) => { Object.defineProperty(startAction, '_promise', { enumerable: false, configurable: false, writable: false, value: { resolve, reject } }); if (method !== 'mutate') { resolve(); } dispatch(startAction); }); if ((ref && ref.options && ref.options.databaseURL || null) === null) return Promise.resolve(); const saved = method === 'mutate' ? (0, _mutate.default)(ref, ...args) : ref[method](...args); saved.then(result => { const successIsObject = (0, _isObject.default)(successType); const actionObj = { type: successIsObject ? successType.type : successType, meta, payload: successIsObject && successType.payload ? makePayload(successType, result) : { args } }; if (successIsObject && successType.preserve) { actionObj.preserve = successType.preserve; } if (successIsObject && successType.merge) { actionObj.merge = successType.merge; } dispatch(actionObj); return result; }).catch(err => { dispatch({ type: errorType, meta, payload: err }); return err; }); return new Promise((done, error) => { Promise.race([new Promise(resolve => setTimeout(resolve, 30000, ['timeout'])), Promise.allSettled([saved, optimistic])]).then(_ref3 => { let [firestore, memory] = _ref3; if (firestore === 'timeout') return error(`Timed out after 30 seconds when saving ${JSON.stringify(args)}.`); if (memory.status === 'rejected') return error(memory.reason); if (firestore.status === 'rejected') return error(firestore.reason); return done(firestore.value); }); }); } function createWithFirebaseAndDispatch(firebase, dispatch) { return func => function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return func.apply(firebase, [firebase, dispatch, ...args]); }; } function mapWithFirebaseAndDispatch(firebase, dispatch, actions, aliases) { const withFirebaseAndDispatch = createWithFirebaseAndDispatch(firebase, dispatch); return { ...(0, _mapValues.default)(actions, withFirebaseAndDispatch), ...aliases.reduce((acc, _ref4) => { let { action, name } = _ref4; return { ...acc, [name]: withFirebaseAndDispatch(action) }; }, {}) }; }