UNPKG

redux-optimist-promise

Version:

Promise middleware for Redux with automatic binding for redux-optimist

157 lines (128 loc) 4.81 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; exports.resolve = resolve; exports.reject = reject; exports.unresolve = unresolve; exports.unreject = unreject; exports.isResolvedAction = isResolvedAction; exports.isRejectedAction = isRejectedAction; exports.isThenAction = isThenAction; exports.default = optimistPromiseMiddleware; var _fluxStandardAction = require('flux-standard-action'); function isPromise(val) { return val && typeof val.then === 'function'; } var RESOLVED_NAME = '_RESOLVED', REJECTED_NAME = '_REJECTED'; var BEGIN = 'BEGIN'; var COMMIT = 'COMMIT'; var REVERT = 'REVERT'; function resolve(actionName) { return actionName + RESOLVED_NAME; } function reject(actionName) { return actionName + REJECTED_NAME; } function unresolve(resolvedActionName) { return resolvedActionName.split(RESOLVED_NAME)[0]; } function unreject(rejectedActionName) { return rejectedActionName.split(REJECTED_NAME)[0]; } function isResolvedAction(resolvedActionName) { return unresolve(resolvedActionName) !== resolvedActionName; } function isRejectedAction(rejectedActionName) { return unreject(rejectedActionName) !== rejectedActionName; } function isThenAction(thenActionName) { return isResolvedAction(thenActionName) || isRejectedAction(thenActionName); } function optimistPromiseMiddleware() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$throwOnReject = _ref.throwOnReject, throwOnReject = _ref$throwOnReject === undefined ? true : _ref$throwOnReject, _ref$resolvedName = _ref.resolvedName, resolvedName = _ref$resolvedName === undefined ? RESOLVED_NAME : _ref$resolvedName, _ref$rejectedName = _ref.rejectedName, rejectedName = _ref$rejectedName === undefined ? REJECTED_NAME : _ref$rejectedName; RESOLVED_NAME = resolvedName; REJECTED_NAME = rejectedName; var nextTransactionID = 0; return function (_ref2) { var dispatch = _ref2.dispatch; return function (next) { return function (action) { if (!(0, _fluxStandardAction.isFSA)(action) || !action.meta || !isPromise(action.meta.promise)) { return next(action); } var isOptimist = action.meta.optimist; var transactionID = void 0; if (isOptimist) { transactionID = nextTransactionID++; } // (1) Dispatch actionName with meta with arguments apart from promise // Clone original action var newAction = _extends({}, action, { meta: _extends({}, action.meta) }); if (isOptimist) { // Adding optimistic meta newAction.optimist = { type: BEGIN, id: transactionID }; delete newAction.meta.optimist; } if (Object.keys(newAction.meta).length === 1) { delete newAction.meta; } else { // Other arguments, delete promise and optimist only delete newAction.meta.promise; } var skipOptimist = action.meta.skipOptimist; if (!skipOptimist) { next(newAction); } // Create a base for the next action containing the metadata. var nextActionBase = { meta: _extends({}, newAction.meta, { payload: newAction.payload }) }; if (!nextActionBase.meta.payload) { // No payload, no need to include them in the meta. delete nextActionBase.meta.payload; } if (Object.keys(nextActionBase.meta).length === 0) { // No meta was included either, remove all meta. delete nextActionBase.meta; } // (2) Listen to promise and dispatch payload with new actionName return action.meta.promise.then(function (result) { var actionToDispatch = _extends({ type: resolve(action.type), payload: result }, nextActionBase); if (isOptimist) { actionToDispatch.optimist = { type: COMMIT, id: transactionID }; } dispatch(actionToDispatch); return result; }).catch(function (error) { var actionToDispatch = _extends({ type: reject(action.type), payload: error }, nextActionBase); if (isOptimist) { actionToDispatch.optimist = { type: REVERT, id: transactionID }; } dispatch(actionToDispatch); if (throwOnReject) { throw error; } }); }; }; }; }