@taraai/read-write
Version:
Synchronous NoSQL/Firestore for React
82 lines (71 loc) • 2.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.CALL_FIRESTORE = void 0;
exports.default = reduxFirestoreMiddleware;
var _constants = require("./constants");
function callFirestore(firebaseInstance, callInfoObj) {
const {
method
} = callInfoObj;
let {
modelArgs,
methodArgs
} = callInfoObj;
if (!Array.isArray(modelArgs)) modelArgs = [modelArgs];
if (!Array.isArray(methodArgs)) methodArgs = [methodArgs];
if (!firebaseInstance || !firebaseInstance.firestore) {
throw new Error('firestore is not a Firebase namespace');
}
return !methodArgs ? firebaseInstance.firestore()[method] : firebaseInstance.firestore()[method].apply(firebaseInstance, methodArgs);
}
const CALL_FIRESTORE = 'CALL_FIRESTORE';
exports.CALL_FIRESTORE = CALL_FIRESTORE;
const typesMap = {
get: [_constants.actionTypes.GET_REQUEST, _constants.actionTypes.GET_SUCCESS, _constants.actionTypes.GET_FAILURE]
};
function reduxFirestoreMiddleware(firestore) {
return store => next => action => {
const callAPI = action.type === CALL_FIRESTORE ? action : undefined;
if (typeof callAPI === 'undefined') return next(action);
let {
method
} = callAPI;
if (typeof method === 'function') method = method(store.getState());
if (typeof method !== 'string') throw new Error('Specify a method.');
const {
args
} = callAPI;
const types = typesMap[method];
if (!Array.isArray(types) || types.length !== 3) {
throw new Error('Expected an array of three action types.');
}
if (!types.every(type => typeof type === 'string')) {
throw new Error('Expected action types to be strings.');
}
function actionWith(data) {
const finalAction = { ...action,
...data
};
delete finalAction[CALL_FIRESTORE];
return finalAction;
}
const [requestType, successType, failureType] = types;
next({
type: requestType
});
const callInfoObj = {
method
};
return callFirestore(firestore, callInfoObj).then(response => next({
response,
method,
args,
type: successType
})).catch(error => next(actionWith({
type: failureType,
error: error.message || error || 'Something bad happened'
})));
};
}