UNPKG

@evertbouw/redux-toolkit

Version:
469 lines (390 loc) 14.5 kB
'use strict'; function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var redux = require('redux'); var reselect = require('reselect'); var reduxDevtoolsExtension = require('redux-devtools-extension'); var thunkMiddleware = _interopDefault(require('redux-thunk')); var createImmutableStateInvariantMiddleware = _interopDefault(require('redux-immutable-state-invariant')); 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); } /** * 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. */ 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; } /** * 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 = {}; } 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$ignoredPaths = _options.ignoredPaths, ignoredPaths = _options$ignoredPaths === void 0 ? [] : _options$ignoredPaths; return function (storeAPI) { return function (next) { return function (action) { if (ignoredActions.length && ignoredActions.indexOf(action.type) !== -1) { return next(action); } var foundActionNonSerializableValue = findNonSerializableValue(action, [], isSerializable, getEntries); 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)'); } var result = next(action); 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)"); } return result; }; }; }; } function isBoolean(x) { return typeof x === 'boolean'; } /** * 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 = []; if (thunk) { if (isBoolean(thunk)) { middlewareArray.push(thunkMiddleware); } else { middlewareArray.push(thunkMiddleware.withExtraArgument(thunk.extraArgument)); } } { 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 = "development" === '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 _ref = options || {}, _ref$reducer = _ref.reducer, reducer = _ref$reducer === void 0 ? undefined : _ref$reducer, _ref$middleware = _ref.middleware, middleware = _ref$middleware === void 0 ? getDefaultMiddleware() : _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 = redux.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 = redux.applyMiddleware.apply(void 0, middleware); var finalCompose = redux.compose; if (devTools) { finalCompose = reduxDevtoolsExtension.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 redux.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; } /** * 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 builder = { addCase: function addCase(typeOrActionCreator, reducer) { 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; } }; builderCallback(builder); return actionsMap; } function createReducer(initialState, mapOrBuilderCallback) { var actionsMap = typeof mapOrBuilderCallback === 'function' ? executeReducerBuilderCallback(mapOrBuilderCallback) : mapOrBuilderCallback; return function (state, action) { if (state === void 0) { state = initialState; } var reducer = actionsMap[action.type]; return reducer === undefined ? state : reducer(state, action); }; } 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 extraReducers = typeof options.extraReducers === 'undefined' ? {} : typeof options.extraReducers === 'function' ? executeReducerBuilderCallback(options.extraReducers) : options.extraReducers; 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); return { name: name, reducer: reducer, actions: actionCreators, caseReducers: sliceCaseReducersByName }; } Object.keys(redux).forEach(function (k) { if (k !== 'default') Object.defineProperty(exports, k, { enumerable: true, get: function () { return redux[k]; } }); }); Object.defineProperty(exports, 'createSelector', { enumerable: true, get: function () { return reselect.createSelector; } }); exports.configureStore = configureStore; exports.createAction = createAction; exports.createReducer = createReducer; exports.createSerializableStateInvariantMiddleware = createSerializableStateInvariantMiddleware; exports.createSlice = createSlice; exports.findNonSerializableValue = findNonSerializableValue; exports.getDefaultMiddleware = getDefaultMiddleware; exports.getType = getType; exports.isPlain = isPlain; //# sourceMappingURL=redux-toolkit.cjs.development.js.map