UNPKG

@reduxjs/toolkit

Version:

The official, opinionated, batteries-included toolset for efficient Redux development

1,674 lines (1,394 loc) 58.4 kB
import createNextState, { isDraft, current, isDraftable, enableES5 } from 'immer'; export { default as createNextState, current, freeze } from 'immer'; import { compose, combineReducers, applyMiddleware, createStore } from 'redux'; export * from 'redux'; import { createSelector } from 'reselect'; export { createSelector } from 'reselect'; import thunkMiddleware from 'redux-thunk'; /** * "Draft-Safe" version of `reselect`'s `createSelector`: * If an `immer`-drafted object is passed into the resulting selector's first argument, * the selector will act on the current draft value, instead of returning a cached value * that might be possibly outdated if the draft has been modified since. * @public */ var createDraftSafeSelector = function createDraftSafeSelector() { var selector = createSelector.apply(void 0, arguments); var wrappedSelector = function wrappedSelector(value) { for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { rest[_key - 1] = arguments[_key]; } return selector.apply(void 0, [isDraft(value) ? current(value) : value].concat(rest)); }; return wrappedSelector; }; function _extends() { _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; }; return _extends.apply(this, arguments); } function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _construct(Parent, args, Class) { if (isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } /** * @public */ var composeWithDevTools = typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : function () { if (arguments.length === 0) return undefined; if (typeof arguments[0] === 'object') return compose; return compose.apply(null, arguments); }; /** * Returns true if the passed value is "plain" object, i.e. an object whose * protoype is the root `Object.prototype`. This includes objects created * using object literals, but not for instance for class instances. * * @param {any} value The value to inspect. * @returns {boolean} True if the argument appears to be a plain object. * * @public */ function isPlainObject(value) { if (typeof value !== 'object' || value === null) return false; var proto = value; while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto); } return Object.getPrototypeOf(value) === proto; } function getTimeMeasureUtils(maxDelay, fnName) { var elapsed = 0; return { measureTime: function measureTime(fn) { var started = Date.now(); try { return fn(); } finally { var finished = Date.now(); elapsed += finished - started; } }, warnIfExceeded: function warnIfExceeded() { if (elapsed > maxDelay) { console.warn(fnName + " took " + elapsed + "ms, which is more than the warning threshold of " + maxDelay + "ms. \nIf your state or actions are very large, you may want to disable the middleware as it might cause too much of a slowdown in development mode. See https://redux-toolkit.js.org/api/getDefaultMiddleware for instructions.\nIt is disabled in production builds, so you don't need to worry about that."); } } }; } /** * @public */ var MiddlewareArray = /*#__PURE__*/ function (_Array) { _inheritsLoose(MiddlewareArray, _Array); function MiddlewareArray() { return _Array.apply(this, arguments) || this; } var _proto = MiddlewareArray.prototype; _proto.concat = function concat() { var _Array$prototype$conc; for (var _len = arguments.length, arr = new Array(_len), _key = 0; _key < _len; _key++) { arr[_key] = arguments[_key]; } return _construct(MiddlewareArray, (_Array$prototype$conc = _Array.prototype.concat).call.apply(_Array$prototype$conc, [this].concat(arr))); }; _proto.prepend = function prepend() { for (var _len2 = arguments.length, arr = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { arr[_key2] = arguments[_key2]; } if (arr.length === 1 && Array.isArray(arr[0])) { return _construct(MiddlewareArray, arr[0].concat(this)); } return _construct(MiddlewareArray, arr.concat(this)); }; return MiddlewareArray; }( /*#__PURE__*/ _wrapNativeSuper(Array)); var isProduction = process.env.NODE_ENV === 'production'; var prefix = 'Invariant failed'; // Throw an error if the condition fails // Strip out error messages for production // > Not providing an inline default argument for message as the result is smaller function invariant(condition, message) { if (condition) { return; } // Condition not passed // In production we strip the message but still throw if (isProduction) { throw new Error(prefix); } // When not in production we allow the message to pass through // *This block will be removed in production builds* throw new Error(prefix + ": " + (message || '')); } function stringify(obj, serializer, indent, decycler) { return JSON.stringify(obj, getSerialize(serializer, decycler), indent); } function getSerialize(serializer, decycler) { var stack = [], keys = []; if (!decycler) decycler = function decycler(_, value) { if (stack[0] === value) return '[Circular ~]'; return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'; }; return function (key, value) { if (stack.length > 0) { var thisPos = stack.indexOf(this); ~thisPos ? stack.splice(thisPos + 1) : stack.push(this); ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key); if (~stack.indexOf(value)) value = decycler.call(this, key, value); } else stack.push(value); return serializer == null ? value : serializer.call(this, key, value); }; } /** * The default `isImmutable` function. * * @public */ function isImmutableDefault(value) { return typeof value !== 'object' || value === null || typeof value === 'undefined'; } function trackForMutations(isImmutable, ignorePaths, obj) { var trackedProperties = trackProperties(isImmutable, ignorePaths, obj); return { detectMutations: function detectMutations() { return _detectMutations(isImmutable, ignorePaths, trackedProperties, obj); } }; } function trackProperties(isImmutable, ignorePaths, obj, path) { if (ignorePaths === void 0) { ignorePaths = []; } if (path === void 0) { path = []; } var tracked = { value: obj }; if (!isImmutable(obj)) { tracked.children = {}; for (var key in obj) { var childPath = path.concat(key); if (ignorePaths.length && ignorePaths.indexOf(childPath.join('.')) !== -1) { continue; } tracked.children[key] = trackProperties(isImmutable, ignorePaths, obj[key], childPath); } } return tracked; } function _detectMutations(isImmutable, ignorePaths, trackedProperty, obj, sameParentRef, path) { if (ignorePaths === void 0) { ignorePaths = []; } if (sameParentRef === void 0) { sameParentRef = false; } if (path === void 0) { path = []; } var prevObj = trackedProperty ? trackedProperty.value : undefined; var sameRef = prevObj === obj; if (sameParentRef && !sameRef && !Number.isNaN(obj)) { return { wasMutated: true, path: path }; } if (isImmutable(prevObj) || isImmutable(obj)) { return { wasMutated: false }; } // Gather all keys from prev (tracked) and after objs var keysToDetect = {}; Object.keys(trackedProperty.children).forEach(function (key) { keysToDetect[key] = true; }); Object.keys(obj).forEach(function (key) { keysToDetect[key] = true; }); var keys = Object.keys(keysToDetect); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var childPath = path.concat(key); if (ignorePaths.length && ignorePaths.indexOf(childPath.join('.')) !== -1) { continue; } var result = _detectMutations(isImmutable, ignorePaths, trackedProperty.children[key], obj[key], sameRef, childPath); if (result.wasMutated) { return result; } } return { wasMutated: false }; } /** * Creates a middleware that checks whether any state was mutated in between * dispatches or during a dispatch. If any mutations are detected, an error is * thrown. * * @param options Middleware options. * * @public */ function createImmutableStateInvariantMiddleware(options) { if (options === void 0) { options = {}; } if (process.env.NODE_ENV === 'production') { return function () { return function (next) { return function (action) { return next(action); }; }; }; } var _options = options, _options$isImmutable = _options.isImmutable, isImmutable = _options$isImmutable === void 0 ? isImmutableDefault : _options$isImmutable, ignoredPaths = _options.ignoredPaths, _options$warnAfter = _options.warnAfter, warnAfter = _options$warnAfter === void 0 ? 32 : _options$warnAfter, ignore = _options.ignore; // Alias ignore->ignoredPaths, but prefer ignoredPaths if present ignoredPaths = ignoredPaths || ignore; var track = trackForMutations.bind(null, isImmutable, ignoredPaths); return function (_ref) { var getState = _ref.getState; var state = getState(); var tracker = track(state); var result; return function (next) { return function (action) { var measureUtils = getTimeMeasureUtils(warnAfter, 'ImmutableStateInvariantMiddleware'); measureUtils.measureTime(function () { state = getState(); result = tracker.detectMutations(); // Track before potentially not meeting the invariant tracker = track(state); !!result.wasMutated ? process.env.NODE_ENV !== "production" ? invariant(false, "A state mutation was detected between dispatches, in the path '" + (result.path || []).join('.') + "'. This may cause incorrect behavior. (https://redux.js.org/troubleshooting#never-mutate-reducer-arguments)") : invariant(false) : void 0; }); var dispatchedAction = next(action); measureUtils.measureTime(function () { state = getState(); result = tracker.detectMutations(); // Track before potentially not meeting the invariant tracker = track(state); result.wasMutated && (!!result.wasMutated ? process.env.NODE_ENV !== "production" ? invariant(false, "A state mutation was detected inside a dispatch, in the path: " + (result.path || []).join('.') + ". Take a look at the reducer(s) handling the action " + stringify(action) + ". (https://redux.js.org/troubleshooting#never-mutate-reducer-arguments)") : invariant(false) : void 0); }); measureUtils.warnIfExceeded(); return dispatchedAction; }; }; }; } /** * Returns true if the passed value is "plain", i.e. a value that is either * directly JSON-serializable (boolean, number, string, array, plain object) * or `undefined`. * * @param val The value to check. * * @public */ function isPlain(val) { return typeof val === 'undefined' || val === null || typeof val === 'string' || typeof val === 'boolean' || typeof val === 'number' || Array.isArray(val) || isPlainObject(val); } /** * @public */ function findNonSerializableValue(value, path, isSerializable, getEntries, ignoredPaths) { if (path === void 0) { path = []; } if (isSerializable === void 0) { isSerializable = isPlain; } if (ignoredPaths === void 0) { ignoredPaths = []; } var foundNestedSerializable; if (!isSerializable(value)) { return { keyPath: path.join('.') || '<root>', value: value }; } if (typeof value !== 'object' || value === null) { return false; } var entries = getEntries != null ? getEntries(value) : Object.entries(value); var hasIgnoredPaths = ignoredPaths.length > 0; for (var _iterator = entries, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var _ref2 = _ref, property = _ref2[0], nestedValue = _ref2[1]; var nestedPath = path.concat(property); if (hasIgnoredPaths && ignoredPaths.indexOf(nestedPath.join('.')) >= 0) { continue; } if (!isSerializable(nestedValue)) { return { keyPath: nestedPath.join('.'), value: nestedValue }; } if (typeof nestedValue === 'object') { foundNestedSerializable = findNonSerializableValue(nestedValue, nestedPath, isSerializable, getEntries, ignoredPaths); if (foundNestedSerializable) { return foundNestedSerializable; } } } return false; } /** * Creates a middleware that, after every state change, checks if the new * state is serializable. If a non-serializable value is found within the * state, an error is printed to the console. * * @param options Middleware options. * * @public */ function createSerializableStateInvariantMiddleware(options) { if (options === void 0) { options = {}; } if (process.env.NODE_ENV === 'production') { return function () { return function (next) { return function (action) { return next(action); }; }; }; } var _options = options, _options$isSerializab = _options.isSerializable, isSerializable = _options$isSerializab === void 0 ? isPlain : _options$isSerializab, getEntries = _options.getEntries, _options$ignoredActio = _options.ignoredActions, ignoredActions = _options$ignoredActio === void 0 ? [] : _options$ignoredActio, _options$ignoredActio2 = _options.ignoredActionPaths, ignoredActionPaths = _options$ignoredActio2 === void 0 ? ['meta.arg'] : _options$ignoredActio2, _options$ignoredPaths = _options.ignoredPaths, ignoredPaths = _options$ignoredPaths === void 0 ? [] : _options$ignoredPaths, _options$warnAfter = _options.warnAfter, warnAfter = _options$warnAfter === void 0 ? 32 : _options$warnAfter; return function (storeAPI) { return function (next) { return function (action) { if (ignoredActions.length && ignoredActions.indexOf(action.type) !== -1) { return next(action); } var measureUtils = getTimeMeasureUtils(warnAfter, 'SerializableStateInvariantMiddleware'); measureUtils.measureTime(function () { var foundActionNonSerializableValue = findNonSerializableValue(action, [], isSerializable, getEntries, ignoredActionPaths); if (foundActionNonSerializableValue) { var keyPath = foundActionNonSerializableValue.keyPath, value = foundActionNonSerializableValue.value; console.error("A non-serializable value was detected in an action, in the path: `" + keyPath + "`. Value:", value, '\nTake a look at the logic that dispatched this action: ', action, '\n(See https://redux.js.org/faq/actions#why-should-type-be-a-string-or-at-least-serializable-why-should-my-action-types-be-constants)', '\n(To allow non-serializable values see: https://redux-toolkit.js.org/usage/usage-guide#working-with-non-serializable-data)'); } }); var result = next(action); measureUtils.measureTime(function () { var state = storeAPI.getState(); var foundStateNonSerializableValue = findNonSerializableValue(state, [], isSerializable, getEntries, ignoredPaths); if (foundStateNonSerializableValue) { var keyPath = foundStateNonSerializableValue.keyPath, value = foundStateNonSerializableValue.value; console.error("A non-serializable value was detected in the state, in the path: `" + keyPath + "`. Value:", value, "\nTake a look at the reducer(s) handling this action type: " + action.type + ".\n(See https://redux.js.org/faq/organizing-state#can-i-put-functions-promises-or-other-non-serializable-items-in-my-store-state)"); } }); measureUtils.warnIfExceeded(); return result; }; }; }; } function isBoolean(x) { return typeof x === 'boolean'; } function curryGetDefaultMiddleware() { return function curriedGetDefaultMiddleware(options) { return getDefaultMiddleware(options); }; } /** * Returns any array containing the default middleware installed by * `configureStore()`. Useful if you want to configure your store with a custom * `middleware` array but still keep the default set. * * @return The default middleware used by `configureStore()`. * * @public */ function getDefaultMiddleware(options) { if (options === void 0) { options = {}; } var _options = options, _options$thunk = _options.thunk, thunk = _options$thunk === void 0 ? true : _options$thunk, _options$immutableChe = _options.immutableCheck, immutableCheck = _options$immutableChe === void 0 ? true : _options$immutableChe, _options$serializable = _options.serializableCheck, serializableCheck = _options$serializable === void 0 ? true : _options$serializable; var middlewareArray = new MiddlewareArray(); if (thunk) { if (isBoolean(thunk)) { middlewareArray.push(thunkMiddleware); } else { middlewareArray.push(thunkMiddleware.withExtraArgument(thunk.extraArgument)); } } if (process.env.NODE_ENV !== 'production') { if (immutableCheck) { /* PROD_START_REMOVE_UMD */ var immutableOptions = {}; if (!isBoolean(immutableCheck)) { immutableOptions = immutableCheck; } middlewareArray.unshift(createImmutableStateInvariantMiddleware(immutableOptions)); /* PROD_STOP_REMOVE_UMD */ } if (serializableCheck) { var serializableOptions = {}; if (!isBoolean(serializableCheck)) { serializableOptions = serializableCheck; } middlewareArray.push(createSerializableStateInvariantMiddleware(serializableOptions)); } } return middlewareArray; } var IS_PRODUCTION = process.env.NODE_ENV === 'production'; /** * A friendly abstraction over the standard Redux `createStore()` function. * * @param config The store configuration. * @returns A configured Redux store. * * @public */ function configureStore(options) { var curriedGetDefaultMiddleware = curryGetDefaultMiddleware(); var _ref = options || {}, _ref$reducer = _ref.reducer, reducer = _ref$reducer === void 0 ? undefined : _ref$reducer, _ref$middleware = _ref.middleware, middleware = _ref$middleware === void 0 ? curriedGetDefaultMiddleware() : _ref$middleware, _ref$devTools = _ref.devTools, devTools = _ref$devTools === void 0 ? true : _ref$devTools, _ref$preloadedState = _ref.preloadedState, preloadedState = _ref$preloadedState === void 0 ? undefined : _ref$preloadedState, _ref$enhancers = _ref.enhancers, enhancers = _ref$enhancers === void 0 ? undefined : _ref$enhancers; var rootReducer; if (typeof reducer === 'function') { rootReducer = reducer; } else if (isPlainObject(reducer)) { rootReducer = combineReducers(reducer); } else { throw new Error('"reducer" is a required argument, and must be a function or an object of functions that can be passed to combineReducers'); } var middlewareEnhancer = applyMiddleware.apply(void 0, typeof middleware === 'function' ? middleware(curriedGetDefaultMiddleware) : middleware); var finalCompose = compose; if (devTools) { finalCompose = composeWithDevTools(_extends({ // Enable capture of stack traces for dispatched Redux actions trace: !IS_PRODUCTION }, typeof devTools === 'object' && devTools)); } var storeEnhancers = [middlewareEnhancer]; if (Array.isArray(enhancers)) { storeEnhancers = [middlewareEnhancer].concat(enhancers); } else if (typeof enhancers === 'function') { storeEnhancers = enhancers(storeEnhancers); } var composedEnhancer = finalCompose.apply(void 0, storeEnhancers); return createStore(rootReducer, preloadedState, composedEnhancer); } function createAction(type, prepareAction) { function actionCreator() { if (prepareAction) { var prepared = prepareAction.apply(void 0, arguments); if (!prepared) { throw new Error('prepareAction did not return an object'); } return _extends({ type: type, payload: prepared.payload }, 'meta' in prepared && { meta: prepared.meta }, {}, 'error' in prepared && { error: prepared.error }); } return { type: type, payload: arguments.length <= 0 ? undefined : arguments[0] }; } actionCreator.toString = function () { return "" + type; }; actionCreator.type = type; actionCreator.match = function (action) { return action.type === type; }; return actionCreator; } function isFSA(action) { return isPlainObject(action) && typeof action.type === 'string' && Object.keys(action).every(isValidKey); } function isValidKey(key) { return ['type', 'payload', 'error', 'meta'].indexOf(key) > -1; } /** * Returns the action type of the actions created by the passed * `createAction()`-generated action creator (arbitrary action creators * are not supported). * * @param action The action creator whose action type to get. * @returns The action type used by the action creator. * * @public */ function getType(actionCreator) { return "" + actionCreator; } function executeReducerBuilderCallback(builderCallback) { var actionsMap = {}; var actionMatchers = []; var defaultCaseReducer; var builder = { addCase: function addCase(typeOrActionCreator, reducer) { if (process.env.NODE_ENV !== 'production') { /* to keep the definition by the user in line with actual behavior, we enforce `addCase` to always be called before calling `addMatcher` as matching cases take precedence over matchers */ if (actionMatchers.length > 0) { throw new Error('`builder.addCase` should only be called before calling `builder.addMatcher`'); } if (defaultCaseReducer) { throw new Error('`builder.addCase` should only be called before calling `builder.addDefaultCase`'); } } var type = typeof typeOrActionCreator === 'string' ? typeOrActionCreator : typeOrActionCreator.type; if (type in actionsMap) { throw new Error('addCase cannot be called with two reducers for the same action type'); } actionsMap[type] = reducer; return builder; }, addMatcher: function addMatcher(matcher, reducer) { if (process.env.NODE_ENV !== 'production') { if (defaultCaseReducer) { throw new Error('`builder.addMatcher` should only be called before calling `builder.addDefaultCase`'); } } actionMatchers.push({ matcher: matcher, reducer: reducer }); return builder; }, addDefaultCase: function addDefaultCase(reducer) { if (process.env.NODE_ENV !== 'production') { if (defaultCaseReducer) { throw new Error('`builder.addDefaultCase` can only be called once'); } } defaultCaseReducer = reducer; return builder; } }; builderCallback(builder); return [actionsMap, actionMatchers, defaultCaseReducer]; } function createReducer(initialState, mapOrBuilderCallback, actionMatchers, defaultCaseReducer) { if (actionMatchers === void 0) { actionMatchers = []; } var _ref = typeof mapOrBuilderCallback === 'function' ? executeReducerBuilderCallback(mapOrBuilderCallback) : [mapOrBuilderCallback, actionMatchers, defaultCaseReducer], actionsMap = _ref[0], finalActionMatchers = _ref[1], finalDefaultCaseReducer = _ref[2]; return function (state, action) { if (state === void 0) { state = initialState; } var caseReducers = [actionsMap[action.type]].concat(finalActionMatchers.filter(function (_ref2) { var matcher = _ref2.matcher; return matcher(action); }).map(function (_ref3) { var reducer = _ref3.reducer; return reducer; })); if (caseReducers.filter(function (cr) { return !!cr; }).length === 0) { caseReducers = [finalDefaultCaseReducer]; } return caseReducers.reduce(function (previousState, caseReducer) { if (caseReducer) { if (isDraft(previousState)) { // If it's already a draft, we must already be inside a `createNextState` call, // likely because this is being wrapped in `createReducer`, `createSlice`, or nested // inside an existing draft. It's safe to just pass the draft to the mutator. var draft = previousState; // We can assume this is already a draft var result = caseReducer(draft, action); if (typeof result === 'undefined') { return previousState; } return result; } else if (!isDraftable(previousState)) { // If state is not draftable (ex: a primitive, such as 0), we want to directly // return the caseReducer func and not wrap it with produce. var _result = caseReducer(previousState, action); if (typeof _result === 'undefined') { if (previousState === null) { return previousState; } throw Error('A case reducer on a non-draftable value must not return undefined'); } return _result; } else { // @ts-ignore createNextState() produces an Immutable<Draft<S>> rather // than an Immutable<S>, and TypeScript cannot find out how to reconcile // these two types. return createNextState(previousState, function (draft) { return caseReducer(draft, action); }); } } return previousState; }, state); }; } function getType$1(slice, actionKey) { return slice + "/" + actionKey; } /** * A function that accepts an initial state, an object full of reducer * functions, and a "slice name", and automatically generates * action creators and action types that correspond to the * reducers and state. * * The `reducer` argument is passed to `createReducer()`. * * @public */ function createSlice(options) { var name = options.name, initialState = options.initialState; if (!name) { throw new Error('`name` is a required option for createSlice'); } var reducers = options.reducers || {}; var _ref = typeof options.extraReducers === 'undefined' ? [] : typeof options.extraReducers === 'function' ? executeReducerBuilderCallback(options.extraReducers) : [options.extraReducers], _ref$ = _ref[0], extraReducers = _ref$ === void 0 ? {} : _ref$, _ref$2 = _ref[1], actionMatchers = _ref$2 === void 0 ? [] : _ref$2, _ref$3 = _ref[2], defaultCaseReducer = _ref$3 === void 0 ? undefined : _ref$3; var reducerNames = Object.keys(reducers); var sliceCaseReducersByName = {}; var sliceCaseReducersByType = {}; var actionCreators = {}; reducerNames.forEach(function (reducerName) { var maybeReducerWithPrepare = reducers[reducerName]; var type = getType$1(name, reducerName); var caseReducer; var prepareCallback; if ('reducer' in maybeReducerWithPrepare) { caseReducer = maybeReducerWithPrepare.reducer; prepareCallback = maybeReducerWithPrepare.prepare; } else { caseReducer = maybeReducerWithPrepare; } sliceCaseReducersByName[reducerName] = caseReducer; sliceCaseReducersByType[type] = caseReducer; actionCreators[reducerName] = prepareCallback ? createAction(type, prepareCallback) : createAction(type); }); var finalCaseReducers = _extends({}, extraReducers, {}, sliceCaseReducersByType); var reducer = createReducer(initialState, finalCaseReducers, actionMatchers, defaultCaseReducer); return { name: name, reducer: reducer, actions: actionCreators, caseReducers: sliceCaseReducersByName }; } function getInitialEntityState() { return { ids: [], entities: {} }; } function createInitialStateFactory() { function getInitialState(additionalState) { if (additionalState === void 0) { additionalState = {}; } return Object.assign(getInitialEntityState(), additionalState); } return { getInitialState: getInitialState }; } function createSelectorsFactory() { function getSelectors(selectState) { var selectIds = function selectIds(state) { return state.ids; }; var selectEntities = function selectEntities(state) { return state.entities; }; var selectAll = createDraftSafeSelector(selectIds, selectEntities, function (ids, entities) { return ids.map(function (id) { return entities[id]; }); }); var selectId = function selectId(_, id) { return id; }; var selectById = function selectById(entities, id) { return entities[id]; }; var selectTotal = createDraftSafeSelector(selectIds, function (ids) { return ids.length; }); if (!selectState) { return { selectIds: selectIds, selectEntities: selectEntities, selectAll: selectAll, selectTotal: selectTotal, selectById: createDraftSafeSelector(selectEntities, selectId, selectById) }; } var selectGlobalizedEntities = createDraftSafeSelector(selectState, selectEntities); return { selectIds: createDraftSafeSelector(selectState, selectIds), selectEntities: selectGlobalizedEntities, selectAll: createDraftSafeSelector(selectState, selectAll), selectTotal: createDraftSafeSelector(selectState, selectTotal), selectById: createDraftSafeSelector(selectGlobalizedEntities, selectId, selectById) }; } return { getSelectors: getSelectors }; } function createSingleArgumentStateOperator(mutator) { var operator = createStateOperator(function (_, state) { return mutator(state); }); return function operation(state) { return operator(state, undefined); }; } function createStateOperator(mutator) { return function operation(state, arg) { function isPayloadActionArgument(arg) { return isFSA(arg); } var runMutator = function runMutator(draft) { if (isPayloadActionArgument(arg)) { mutator(arg.payload, draft); } else { mutator(arg, draft); } }; if (isDraft(state)) { // we must already be inside a `createNextState` call, likely because // this is being wrapped in `createReducer` or `createSlice`. // It's safe to just pass the draft to the mutator. runMutator(state); // since it's a draft, we'll just return it return state; } else { // @ts-ignore createNextState() produces an Immutable<Draft<S>> rather // than an Immutable<S>, and TypeScript cannot find out how to reconcile // these two types. return createNextState(state, runMutator); } }; } function selectIdValue(entity, selectId) { var key = selectId(entity); if (process.env.NODE_ENV !== 'production' && key === undefined) { console.warn('The entity passed to the `selectId` implementation returned undefined.', 'You should probably provide your own `selectId` implementation.', 'The entity that was passed:', entity, 'The `selectId` implementation:', selectId.toString()); } return key; } function createUnsortedStateAdapter(selectId) { function addOneMutably(entity, state) { var key = selectIdValue(entity, selectId); if (key in state.entities) { return; } state.ids.push(key); state.entities[key] = entity; } function addManyMutably(entities, state) { if (!Array.isArray(entities)) { entities = Object.values(entities); } for (var _iterator = entities, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var entity = _ref; addOneMutably(entity, state); } } function setAllMutably(entities, state) { if (!Array.isArray(entities)) { entities = Object.values(entities); } state.ids = []; state.entities = {}; addManyMutably(entities, state); } function removeOneMutably(key, state) { return removeManyMutably([key], state); } function removeManyMutably(keys, state) { var didMutate = false; keys.forEach(function (key) { if (key in state.entities) { delete state.entities[key]; didMutate = true; } }); if (didMutate) { state.ids = state.ids.filter(function (id) { return id in state.entities; }); } } function removeAllMutably(state) { Object.assign(state, { ids: [], entities: {} }); } function takeNewKey(keys, update, state) { var original = state.entities[update.id]; var updated = Object.assign({}, original, update.changes); var newKey = selectIdValue(updated, selectId); var hasNewKey = newKey !== update.id; if (hasNewKey) { keys[update.id] = newKey; delete state.entities[update.id]; } state.entities[newKey] = updated; return hasNewKey; } function updateOneMutably(update, state) { return updateManyMutably([update], state); } function updateManyMutably(updates, state) { var newKeys = {}; var updatesPerEntity = {}; updates.forEach(function (update) { // Only apply updates to entities that currently exist if (update.id in state.entities) { // If there are multiple updates to one entity, merge them together updatesPerEntity[update.id] = { id: update.id, // Spreads ignore falsy values, so this works even if there isn't // an existing update already at this key changes: _extends({}, updatesPerEntity[update.id] ? updatesPerEntity[update.id].changes : null, {}, update.changes) }; } }); updates = Object.values(updatesPerEntity); var didMutateEntities = updates.length > 0; if (didMutateEntities) { var didMutateIds = updates.filter(function (update) { return takeNewKey(newKeys, update, state); }).length > 0; if (didMutateIds) { state.ids = state.ids.map(function (id) { return newKeys[id] || id; }); } } } function upsertOneMutably(entity, state) { return upsertManyMutably([entity], state); } function upsertManyMutably(entities, state) { if (!Array.isArray(entities)) { entities = Object.values(entities); } var added = []; var updated = []; for (var _iterator2 = entities, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { var _ref2; if (_isArray2) { if (_i2 >= _iterator2.length) break; _ref2 = _iterator2[_i2++]; } else { _i2 = _iterator2.next(); if (_i2.done) break; _ref2 = _i2.value; } var entity = _ref2; var id = selectIdValue(entity, selectId); if (id in state.entities) { updated.push({ id: id, changes: entity }); } else { added.push(entity); } } updateManyMutably(updated, state); addManyMutably(added, state); } return { removeAll: createSingleArgumentStateOperator(removeAllMutably), addOne: createStateOperator(addOneMutably), addMany: createStateOperator(addManyMutably), setAll: createStateOperator(setAllMutably), updateOne: createStateOperator(updateOneMutably), updateMany: createStateOperator(updateManyMutably), upsertOne: createStateOperator(upsertOneMutably), upsertMany: createStateOperator(upsertManyMutably), removeOne: createStateOperator(removeOneMutably), removeMany: createStateOperator(removeManyMutably) }; } function createSortedStateAdapter(selectId, sort) { var _createUnsortedStateA = createUnsortedStateAdapter(selectId), removeOne = _createUnsortedStateA.removeOne, removeMany = _createUnsortedStateA.removeMany, removeAll = _createUnsortedStateA.removeAll; function addOneMutably(entity, state) { return addManyMutably([entity], state); } function addManyMutably(newModels, state) { if (!Array.isArray(newModels)) { newModels = Object.values(newModels); } var models = newModels.filter(function (model) { return !(selectIdValue(model, selectId) in state.entities); }); if (models.length !== 0) { merge(models, state); } } function setAllMutably(models, state) { if (!Array.isArray(models)) { models = Object.values(models); } state.entities = {}; state.ids = []; addManyMutably(models, state); } function updateOneMutably(update, state) { return updateManyMutably([update], state); } function takeUpdatedModel(models, update, state) { if (!(update.id in state.entities)) { return false; } var original = state.entities[update.id]; var updated = Object.assign({}, original, update.changes); var newKey = selectIdValue(updated, selectId); delete state.entities[update.id]; models.push(updated); return newKey !== update.id; } function updateManyMutably(updates, state) { var models = []; updates.forEach(function (update) { return takeUpdatedModel(models, update, state); }); if (models.length !== 0) { merge(models, state); } } function upsertOneMutably(entity, state) { return upsertManyMutably([entity], state); } function upsertManyMutably(entities, state) { if (!Array.isArray(entities)) { entities = Object.values(entities); } var added = []; var updated = []; for (var _iterator = entities, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var entity = _ref; var id = selectIdValue(entity, selectId); if (id in state.entities) { updated.push({ id: id, changes: entity }); } else { added.push(entity); } } updateManyMutably(updated, state); addManyMutably(added, state); } function areArraysEqual(a, b) { if (a.length !== b.length) { return false; } for (var i = 0; i < a.length && i < b.length; i++) { if (a[i] === b[i]) { continue; } return false; } return true; } function merge(models, state) { models.sort(sort); // Insert/overwrite all new/updated models.forEach(function (model) { state.entities[selectId(model)] = model; }); var allEntities = Object.values(state.entities); allEntities.sort(sort); var newSortedIds = allEntities.map(selectId); var ids = state.ids; if (!areArraysEqual(ids, newSortedIds)) { state.ids = newSortedIds; } } return { removeOne: removeOne, removeMany: removeMany, removeAll: removeAll, addOne: createStateOperator(addOneMutably), updateOne: createStateOperator(updateOneMutably), upsertOne: createStateOperator(upsertOneMutably), setAll: createStateOperator(setAllMutably), addMany: createStateOperator(addManyMutably), updateMany: createStateOperator(updateManyMutably), upsertMany: createStateOperator(upsertManyMutably) }; } /** * * @param options * * @public */ function createEntityAdapter(options) { if (options === void 0) { options = {}; } var _sortComparer$selectI = _extends({ sortComparer: false, selectId: function selectId(instance) { return instance.id; } }, options), selectId = _sortComparer$selectI.selectId, sortComparer = _sortComparer$selectI.sortComparer; var stateFactory = createInitialStateFactory(); var selectorsFactory = createSelectorsFactory(); var stateAdapter = sortComparer ? createSortedStateAdapter(selectId, sortComparer) : createUnsortedStateAdapter(selectId); return _extends({ selectId: selectId, sortComparer: sortComparer }, stateFactory, {}, selectorsFactory, {}, stateAdapter); } // A type of promise-like that resolves synchronously and supports only one observer const _iteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator"))) : "@@iterator"; const _asyncIteratorSymbol = /*#__PURE__*/ typeof Symbol !== "undefined" ? (Symbol.asyncIterator || (Symbol.asyncIterator = Symbol("Symbol.asyncIterator"))) : "@@asyncIterator"; // Asynchronously call a function and send errors to recovery continuation function _catch(body, recover) { try { var result = body(); } catch(e) { return recover(e); } if (result && result.then) { return result.then(void 0, recover); } return result; } // Borrowed from https://github.com/ai/nanoid/blob/3.0.2/non-secure/index.js // This alphabet uses `A-Za-z0-9_-` symbols. A genetic algorithm helped // optimize the gzip compression for this alphabet. var urlAlphabet = 'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW'; /** * * @public */ var nanoid = function nanoid(size) { if (size === void 0) { size = 21; } var id = ''; // A compact alternative for `for (var i = 0; i < step; i++)`. var i = size; while (i--) { // `| 0` is more compact and faster than `Math.floor()`. id += urlAlphabet[Math.random() * 64 | 0]; } return id; }; var commonProperties = ['name', 'message', 'stack', 'code']; var RejectWithValue = function RejectWithValue(payload) { this.payload = payload; this.name = 'RejectWithValue'; this.message = 'Rejected'; }; // Reworked from https://github.com/sindresorhus/serialize-error var miniSerializeError = function miniSerializeError(value) { if (typeof value === 'object' && value !== null) { var simpleError = {}; for (var _iterator = commonProperties, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var property = _ref; if (typeof value[property] === 'string') { simpleError[property] = value[property]; } } return simpleError; } return { message: String(value) }; }; /** * * @param typePrefix * @param payloadCreator * @param options * * @public */ function createAsyncThunk(typePrefix, payloadCreator, options) { var fulfilled = createAction(typePrefix + '/fulfilled', function (result, requestId, arg) { return { payload: result, meta: { arg: arg, requestId: requestId, requestStatus: 'fulfilled' } }; }); var pending = createAction(typePrefix + '/pending', function (requestId, arg) { return { payload: undefined, meta: { arg: arg, requestId: requestId, requestStatus: 'pending' } }; }); var rejected = createAction(typePrefix + '/rejected', function (error, requestId, arg) { var rejectedWithValue = error instanceof RejectWithValue; var aborted = !!error && error.name === 'AbortError'; var condition = !!error && error.name === 'ConditionError'; return { payload: error instanceof RejectWithValue ? error.payload : undefined, error: (options && options.serializeError || miniSerializeError)(error || 'Rejected'), meta: { arg: arg, requestId: requestId, rejectedWithValue: rejectedWithValue, requestStatus: 'rejected', aborted: aborted, condition: condition } }; }); var displayedWarning = false; var AC = typeof AbortController !== 'undefined' ? AbortController : /*#__PURE__*/ function () { function _class() { this.signal = { aborted: false, addEventListener: function addEventListener() {}, dispatchEvent: function dispatchEvent() { return false; }, onabort: function onabort() {}, removeEventListener: function removeEventListener() {} }; } var _proto = _class.prototype; _proto.abort = function abort() { if (process.env.NODE_ENV !== 'production') { if (!displayedWarning) { displayedWarning = true; console.info("This platform does not implement AbortController. \nIf you want to use the AbortController to react to `abort` events, please consider importing a polyfill like 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'."); } } }; return _class; }(); function actionCreator(arg) { return function (dispatch, getState, extra) { var requestId = nanoid(); var abortController = new AC(); var abortReason; var abortedPromise = new Promise(function (_, reject) { return abortController.signal.addEventListener('abort', function () { return reject({ name: 'AbortError', message: abortReason || 'Aborted' }); }); }); var started = false; function abort(reason) { if (started) { abortReason = reason; abortController.abort(); } } var promise = function () { try { var _temp3 = function _temp3(_result) { if (_exit2) return _result; // We dispatch the result action _after_ the catch, to avoid having any errors // here get swallowed by the try/catch block, // per https://twitter.com/dan_abramov/status/770914221638942720 // and https://redux-toolkit.js.org/tutorials/advanced-tutorial#async-error-handling-logic-in-thunks var skipDispatch = options && !options.dispatchConditionRejection && rejected.match(finalAction) && finalAction.meta.condition; if (!skipDispatch) { dispatch(finalAction); } return finalAction; }; var _exit2 = false; var finalAction; var _temp4 = _catch(function () { if (options && options.condition && options.condition(arg, { getState: getState, extra: extra }) === false) { // eslint-disable-next-line no-throw-literal throw { name: 'ConditionError', message: 'Aborted due to condition