Repository URL to install this package:
|
Version:
3.12.2 ▾
|
var _rejectionsErrors;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
import nanoid from './nanoid';
import handleError from './handleError';
import { isPlain } from '@reduxjs/toolkit';
var REJECTIONS = {
CONDITION: 'Condition',
ABORTED: 'Aborted',
REJECTED_WITH_VALUE: 'RejectedWithValue'
};
var rejectionsErrors = (_rejectionsErrors = {}, _defineProperty(_rejectionsErrors, REJECTIONS.REJECTED_WITH_VALUE, {
name: 'Rejected',
message: 'Rejected with a value.'
}), _defineProperty(_rejectionsErrors, REJECTIONS.CONDITION, {
name: 'Condition',
message: 'Cancelled due to `condition` callback returning false.'
}), _defineProperty(_rejectionsErrors, REJECTIONS.ABORTED, {
name: 'Abort',
message: 'Aborted through signal of abort.'
}), _rejectionsErrors);
var getSerializedValue = function getSerializedValue(val, path, isDev) {
if (isPlain(val)) {
return val;
}
if (isDev) {
console.warn("Non-serializable value is detected in the path (".concat(path, "), it's already has been handled and won't be passed so dismiss this warning in-case u don't care about passing this payload as it's passed as an empty object ({}):"), val);
}
return {};
};
var createActionCreator = function createActionCreator(type) {
function actionCreator(payload, meta) {
var isDev = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
var error = arguments.length > 3 ? arguments[3] : undefined;
var action = {
type: type
};
if (payload !== undefined) {
action.payload = getSerializedValue(payload, "(action.payload) of action ".concat(action.type), isDev);
}
if (meta !== undefined) {
action.meta = getSerializedValue(meta, "(action.meta) of action ".concat(action.type), isDev);
}
if (error !== undefined) {
action.error = getSerializedValue(error, "(action.error) of action ".concat(action.type), isDev);
}
return action;
}
actionCreator.toString = function () {
return type;
};
actionCreator.type = type;
actionCreator.match = function (action) {
return action && action.type === type;
};
return actionCreator;
};
/**
* Exact Similar to createAsyncThunk with some extra options:
* 1. supporting both async & sync thunk functions
* 2. added 1 more dispatched action ${actionType}/(loading, fulfilled, rejected & *final*)
* 3. `skipDispatch` or don't provide `actionType` - incase of not wanting to dispatch any action and only need to trigger the sync/async function or manual handling for actions.
* 4. `informError` - incase of wanting to inform the error to the user (ex. in a toast) and not dispatching any action.
* 5. `throwRejection` - if u want to throw the error of the promise and u will handle it by catching the error by (handlePromise utility function) or .catch, then provide this `true`.
*
* @param {Function} dispatchedFn - the function that will be called when the thunk is dispatched
* @param {Object} options - the options passed for configuring the function operation
* @param {String} options.actionType - the action type that will be dispatched
* @param {Function} options.condition - the condition that will be checked before calling the dispatchedFn,
* -- `true`/`resolved promise` do the normal dispatch,
* -- `false`/`rejected promise` cancels the dispatched function implementation and return empty resolved promise.
* @param {Boolean} options.skipDispatch - incase of NOT wanting to dispatch any action and only need to trigger the sync/async function or manual handling for actions.
* @param {Boolean} options.skipPendingDispatch - it disables the dispatching of pending action, and only dispatches the fulfilled/rejected/final actions.
* @param {Boolean} options.informError - incase of wanting to inform the error to the user (ex. in a toast).
* @param {Boolean} options.throwRejection - incase of NOT wanting to handle the rejection in the return of dispatch from the function side, in that case u have to catch it urself ex. of dispatch(...).catch(...)
*
* @returns Function - the thunk function
*/
var createThunk = function createThunk(dispatchedFn) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var _options$actionType = options.actionType,
actionType = _options$actionType === void 0 ? '' : _options$actionType,
condition = options.condition,
_options$skipDispatch = options.skipDispatch,
skipDispatch = _options$skipDispatch === void 0 ? false : _options$skipDispatch,
_options$skipPendingD = options.skipPendingDispatch,
skipPendingDispatch = _options$skipPendingD === void 0 ? false : _options$skipPendingD,
_options$informError = options.informError,
informError = _options$informError === void 0 ? false : _options$informError;
function payloadCreator(payload) {
function thunkCreator(dispatch, getState, extra) {
// if `true`, then we must handle .catch in the return of dispatch, ex. of dispatch(...).catch(...)
var _options$throwRejecti = options.throwRejection,
throwRejection = _options$throwRejecti === void 0 ? false : _options$throwRejecti;
var shouldDispatch = actionType && !skipDispatch;
var avoidPendingDispatch = skipPendingDispatch;
var abortController = new AbortController();
var isRequestFinished = false;
var signal = abortController.signal;
var abort = function abort() {
if (isRequestFinished) {
return;
}
abortController.abort();
};
var requestId = nanoid();
// If the thunk function is sync then call it and return, no need to call the following logic of async function.
// async keyword is required to be prefixed to the function to act as async thunk, otherwise it will be sync.
// !TODO: Return back when problem with babel build if fixed on hub
// if (dispatchedFn.constructor && dispatchedFn.constructor.name !== 'AsyncFunction' instanceof Promise) {
var isAsync = false;
try {
// console.log('dispatchedFn.constructor.name: ', dispatchedFn?.constructor?.name)
if (dispatchedFn.constructor && dispatchedFn.constructor.name === 'AsyncFunction') {
isAsync = true;
} else {
isAsync = dispatchedFn() instanceof Promise;
}
} catch (error) {}
if (!isAsync) {
var thunkApi = {
dispatch: dispatch,
getState: getState,
extra: extra
};
return dispatchedFn(payload, thunkApi);
}
async function asyncThunkFn() {
var _ref2;
var isDev = extra.filerobot.opts.dev;
var fulfillWithValue = function fulfillWithValue(value) {
return Promise.resolve(value);
};
var _rejectWithValue = function rejectWithValue(value, cbk) {
cbk();
return Promise.reject(value);
};
var replacedMetaArg = null;
var dispatchError = function dispatchError(reason, err) {
if (shouldDispatch) {
var _ref;
dispatch(payloadCreator.rejected(reason === REJECTIONS.REJECTED_WITH_VALUE ? err : undefined, {
arg: (_ref = replacedMetaArg || payload) !== null && _ref !== void 0 ? _ref : {},
requestId: requestId,
requestStatus: 'rejected',
aborted: reason === REJECTIONS.ABORTED
// condition: reason === REJECTIONS.CONDITION
}, isDev, rejectionsErrors[reason] || err));
}
};
var thunkApi = {
dispatch: dispatch,
getState: getState,
extra: extra,
signal: signal,
abort: abort,
requestId: requestId,
replaceActionsMetaArg: function replaceActionsMetaArg(metaArg) {
replacedMetaArg = metaArg;
},
// sets object in the action.meta.arg properties
skipDispatch: function skipDispatch() {
shouldDispatch = false;
},
skipPendingDispatch: function skipPendingDispatch() {
avoidPendingDispatch = true;
},
rejectWithValue: function rejectWithValue(value) {
return _rejectWithValue(value, function () {
return dispatchError(REJECTIONS.REJECTED_WITH_VALUE, value);
});
},
fulfillWithValue: fulfillWithValue
};
if (typeof condition === 'function') {
var result = condition(payload, thunkApi);
if (result instanceof Promise) {
var conditionResult = await result;
if (!conditionResult) {
// dispatchError(REJECTIONS.CONDITION)
return Promise.resolve();
}
}
if (!result) {
// dispatchError(REJECTIONS.CONDITION)
return Promise.resolve();
}
}
// We moved it after calling the function, in case the function's body calls (skipDispatch function), in that case we won't dispatch the actions.
var functionResult = dispatchedFn(payload, thunkApi);
var properMetaArg = (_ref2 = replacedMetaArg || payload) !== null && _ref2 !== void 0 ? _ref2 : {};
if (shouldDispatch && !avoidPendingDispatch) {
dispatch(payloadCreator.pending(undefined, {
arg: properMetaArg,
requestId: requestId,
requestStatus: 'pending'
}, isDev));
}
var dispatchFinal = function dispatchFinal() {
if (shouldDispatch) {
dispatch(payloadCreator["final"](undefined, {
arg: properMetaArg,
requestId: requestId,
requestStatus: 'final'
}), isDev);
}
};
signal.addEventListener('abort', function () {
dispatchError(REJECTIONS.ABORTED);
dispatchFinal();
}, {
once: true
});
var returnedPromise = functionResult.then(function (res) {
if (shouldDispatch) {
dispatch(payloadCreator.fulfilled(isPlain(res) ? res : {}, {
arg: properMetaArg,
requestId: requestId,
requestStatus: 'fulfilled'
}, isDev));
}
return res;
})["catch"](function (err) {
if (isDev) {
console.error(err.stack || err.message || (err === null || err === void 0 ? void 0 : err.toString()) || err);
}
if (shouldDispatch) {
var message = err.message || (err === null || err === void 0 ? void 0 : err.toString());
dispatchError(undefined, _objectSpread({
message: message
}, err));
}
// !TODO: Check if we should make informError `true` by default instead of `false` or not.
if (informError) {
var _thunkApi$extra$filer;
handleError(err, (_thunkApi$extra$filer = thunkApi.extra.filerobot) === null || _thunkApi$extra$filer === void 0 ? void 0 : _thunkApi$extra$filer.info);
}
if (throwRejection) {
return Promise.reject(err);
}
})["finally"](function () {
isRequestFinished = true;
dispatchFinal();
});
return returnedPromise;
}
var returnedThunkPromise = asyncThunkFn();
returnedThunkPromise.abort = abort;
returnedThunkPromise.requestId = requestId;
returnedThunkPromise.signal = signal;
returnedThunkPromise.throwRejection = function () {
throwRejection = true;
return returnedThunkPromise;
};
return returnedThunkPromise;
}
return thunkCreator;
}
if (actionType && !skipDispatch) {
payloadCreator.pending = createActionCreator("".concat(actionType, "/pending"));
payloadCreator.fulfilled = createActionCreator("".concat(actionType, "/fulfilled"));
payloadCreator.rejected = createActionCreator("".concat(actionType, "/rejected"));
payloadCreator["final"] = createActionCreator("".concat(actionType, "/final"));
payloadCreator.typePrefix = actionType;
}
return payloadCreator;
};
export default createThunk;