easy-peasy
Version:
Easy peasy global state for React
913 lines (775 loc) • 30.5 kB
JavaScript
import produce, { setAutoFreeze } from 'immer';
import React, { createContext, useContext, useState, useRef, useEffect } from 'react';
import shallowEqual from 'shallowequal';
import { compose, createStore as createStore$1, applyMiddleware } from 'redux';
import reduxThunk from 'redux-thunk';
import memoizerific from 'memoizerific';
var StoreContext = createContext();
var isStateObject = function isStateObject(x) {
return x !== null && typeof x === 'object' && !Array.isArray(x);
};
var get = function get(path, target) {
return path.reduce(function (acc, cur) {
return isStateObject(acc) ? acc[cur] : undefined;
}, target);
};
var set = function set(path, target, value) {
path.reduce(function (acc, cur, idx) {
if (idx + 1 === path.length) {
acc[cur] = value;
} else {
acc[cur] = acc[cur] || {};
}
return acc[cur];
}, target);
};
function useStoreState(mapState, dependencies) {
if (dependencies === void 0) {
dependencies = [];
}
var store = useContext(StoreContext);
var _useState = useState(function () {
return mapState(store.getState());
}),
state = _useState[0],
setState = _useState[1];
var _useState2 = useState(null),
error = _useState2[0],
setError = _useState2[1]; // As our effect only fires on mount and unmount it won't have the state
// changes visible to it, therefore we use a mutable ref to track this.
var stateRef = useRef(state); // Helps avoid firing of events when unsubscribed, i.e. unmounted
var isActive = useRef(true); // Tracks when a hooked component is unmounting
var unmounted = useRef(false); // Throwing the error inline allows error boundaries the opportunity to
// catch the error
if (error) {
throw error;
}
useEffect(function () {
isActive.current = true;
var calculateState = function calculateState() {
if (!isActive.current) {
return;
}
try {
var newState = mapState(store.getState());
if (newState === stateRef.current || isStateObject(newState) && isStateObject(stateRef.current) && shallowEqual(newState, stateRef.current)) {
// Do nothing
return;
}
stateRef.current = newState;
setState(function () {
return stateRef.current;
});
} catch (err) {
// see https://github.com/reduxjs/react-redux/issues/1179
// There is a possibility mapState will fail as the props/state that
// the component has received is stale. Therefore we will afford the
// application a small window of opportunity, where if they unmount
// the component or provide it with new "valid" props (which will
// subsequently cause a refreshed subscription cycle) then we will not
// throw an error.
// This is by no means a robust solution. We should track the
// associated issue in the hope for a more dependable solution.
// Setting the listener as "inactive", this can only be changed if the
// incoming dependencies are different (i.e. props have changed)
isActive.current = false;
setTimeout(function () {
if (!unmounted.current && !isActive.current) {
setError(err);
}
}, 200); // give a window of opportunity
}
};
calculateState();
var unsubscribe = store.subscribe(calculateState);
return function () {
isActive.current = false;
unsubscribe();
};
}, dependencies); // This effect will set the ref value to indicate that the component has
// unmounted
useEffect(function () {
return function () {
unmounted.current = true;
};
}, []);
return state;
}
function useStoreActions(mapActions) {
var store = useContext(StoreContext);
return mapActions(store.dispatch);
}
function useStoreDispatch() {
var store = useContext(StoreContext);
return store.dispatch;
}
/* Aliased hooks. These are deprecated */
var useActions = useStoreActions;
var useDispatch = useStoreDispatch;
var useStore = useStoreState;
function createTypedHooks() {
return {
useActions: useActions,
useDispatch: useDispatch,
useStore: useStore,
useStoreActions: useStoreActions,
useStoreDispatch: useStoreDispatch,
useStoreState: useStoreState
};
}
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);
}
var actionNameSymbol = '🙈actionName🙈';
var actionSymbol = '🙈action🙈';
var listenSymbol = '🙈listen🙈';
var metaSymbol = '🙈meta🙈';
var reducerSymbol = '🙈reducer🙈';
var selectDependenciesSymbol = '🙈selectDependencies🙈';
var selectImpSymbol = '🙈selectImp🙈';
var selectStateSymbol = '🙈selectState🙈';
var selectSymbol = '🙈select🙈';
var selectorSymbol = '🙈selector🙈';
var selectorConfigSymbol = '🙈selectorConfig🙈';
var selectorStateSymbol = '🙈selectorState🙈';
var thunkSymbol = '🙈thunk🙈';
var actionName = function actionName(action) {
return action[actionNameSymbol];
};
var thunkStartName = function thunkStartName(action) {
return action[actionNameSymbol] + "(started)";
};
var thunkCompleteName = function thunkCompleteName(action) {
return action[actionNameSymbol] + "(completed)";
};
var thunkFailName = function thunkFailName(action) {
return action[actionNameSymbol] + "(failed)";
};
var action = function action(fn) {
fn[actionSymbol] = true;
return fn;
};
var listen = function listen(fn) {
fn[listenSymbol] = true;
return fn;
};
var thunk = function thunk(fn) {
fn[thunkSymbol] = true;
return fn;
};
var select = function select(fn, dependencies) {
fn[selectSymbol] = true;
fn[selectDependenciesSymbol] = dependencies;
fn[selectStateSymbol] = {};
return fn;
};
var selector = function selector(args, fn, config) {
fn[selectorSymbol] = true;
fn[selectorConfigSymbol] = {
args: args,
config: config
};
return fn;
};
var reducer = function reducer(fn) {
fn[reducerSymbol] = true;
return fn;
};
var maxSelectFnMemoize = 100;
var tick = function tick() {
return new Promise(function (resolve) {
return setTimeout(resolve);
});
};
var errorToPayload = function errorToPayload(err) {
if (err instanceof Error) {
return {
message: err.message,
stack: err.stack
};
}
if (typeof err === 'string') {
return err;
}
return undefined;
};
function createStoreInternals(_ref) {
var disableInternalSelectFnMemoize = _ref.disableInternalSelectFnMemoize,
initialState = _ref.initialState,
injections = _ref.injections,
isRebind = _ref.isRebind,
model = _ref.model,
reducerEnhancer = _ref.reducerEnhancer,
references = _ref.references;
var wrapFnWithMemoize = function wrapFnWithMemoize(x) {
return !disableInternalSelectFnMemoize && typeof x === 'function' ? memoizerific(maxSelectFnMemoize)(x) : x;
};
var defaultState = initialState || {};
var actionThunks = {};
var actionCreators = {};
var actionCreatorDict = {};
var customReducers = [];
var selectorReducers = [];
var listenDefinitions = [];
var thunkListenersDict = {};
var actionListenersDict = {};
var actionReducersDict = {};
var selectorId = 0;
var selectorsDict = {};
var recursiveExtractDefsFromModel = function recursiveExtractDefsFromModel(current, parentPath) {
return Object.keys(current).forEach(function (key) {
var value = current[key];
var path = [].concat(parentPath, [key]);
var meta = {
parent: parentPath,
path: path
};
if (typeof value === 'function') {
if (value[actionSymbol]) {
var name = "@action." + path.join('.');
value[actionNameSymbol] = name;
value[metaSymbol] = meta; // Action Reducer
var actionReducer = value;
actionReducer[actionNameSymbol] = name;
actionReducersDict[name] = actionReducer;
var actionCreator = function actionCreator(payload) {
var result = references.dispatch({
type: actionReducer[actionNameSymbol],
payload: payload
});
return result;
};
actionCreator[actionNameSymbol] = name;
actionCreatorDict[name] = actionCreator;
set(path, actionCreators, actionCreator);
} else if (value[thunkSymbol]) {
var _name = "@thunk." + path.join('.');
value[actionNameSymbol] = _name; // Thunk Action
var action = function action(payload) {
return value(get(parentPath, actionCreators), payload, {
dispatch: references.dispatch,
getState: function getState() {
return get(parentPath, references.getState());
},
getStoreState: references.getState,
injections: injections,
meta: meta
});
};
set(path, actionThunks, action); // Thunk Action Creator
var _actionCreator = function _actionCreator(payload) {
return tick().then(function () {
return references.dispatch({
type: _name + "(started)",
payload: payload
});
}).then(function () {
return references.dispatch(function () {
return action(payload);
});
}).then(function (result) {
references.dispatch({
type: _name + "(completed)",
payload: payload
});
return result;
}).catch(function (err) {
references.dispatch({
type: _name + "(failed)",
payload: payload,
error: errorToPayload(err)
});
throw err;
});
};
_actionCreator[actionNameSymbol] = _name;
actionCreatorDict[_name] = _actionCreator;
set(path, actionCreators, _actionCreator);
} else if (value[selectorSymbol]) {
selectorId += 1;
var selectorInstanceId = selectorId;
var _value$selectorConfig = value[selectorConfigSymbol],
args = _value$selectorConfig.args,
config = _value$selectorConfig.config;
var argSelectors = args && Array.isArray(args) ? args : [function (state) {
return state;
}];
var limit = typeof config === 'object' && typeof config.limit === 'number' && config.limit > 0 ? config.number : 1;
var internalSelect = memoizerific(limit)(value);
var changeIdx = 0;
var createArgumentChangeTracker = function createArgumentChangeTracker() {
var internalChecker = memoizerific(1)(function () {
changeIdx += 1;
return changeIdx;
});
var argumentChangeTracker = function argumentChangeTracker(storeState) {
var localState = get(parentPath, storeState);
var resolvedArgs = argSelectors.reduce(function (acc, argSelector) {
acc.push(argSelector(localState, storeState));
return acc;
}, []);
return internalChecker.apply(void 0, resolvedArgs);
};
return argumentChangeTracker;
};
var createSelector = function createSelector() {
var selector = function selector() {
var storeState = references.getState();
var localState = get(parentPath, storeState);
var selectorArgs = argSelectors.reduce(function (acc, argSelector) {
return [].concat(acc, [argSelector(localState, storeState)]);
}, []);
for (var _len = arguments.length, runtimeArgs = new Array(_len), _key = 0; _key < _len; _key++) {
runtimeArgs[_key] = arguments[_key];
}
return internalSelect.apply(void 0, selectorArgs.concat(runtimeArgs));
};
selector[selectorStateSymbol] = {
argumentChangeTracker: createArgumentChangeTracker(),
createSelector: createSelector,
meta: meta,
selectorId: selectorInstanceId
};
return selector;
};
var selector = createSelector();
selectorsDict[selectorId] = selector;
set(path, defaultState, selector);
} else if (value[selectSymbol]) {
value[selectStateSymbol] = {
parentPath: parentPath,
key: key,
executed: false
};
selectorReducers.push(value);
} else if (value[reducerSymbol]) {
customReducers.push({
path: path,
reducer: value
});
} else if (value[listenSymbol]) {
listenDefinitions.push(value);
value[metaSymbol] = meta;
} else if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn("Easy Peasy: Found a function at path " + path.join('.') + " in your model. Version 2 required that you wrap your action functions with the \"action\" helper");
}
} else if (isStateObject(value) && Object.keys(value).length > 0) {
var existing = get(path, defaultState);
if (existing == null) {
set(path, defaultState, {});
}
recursiveExtractDefsFromModel(value, path);
} else {
// State
var initialParentRef = get(parentPath, initialState);
if (!isRebind && initialParentRef && key in initialParentRef) {
set(path, defaultState, initialParentRef[key]);
} else {
set(path, defaultState, value);
}
}
});
};
recursiveExtractDefsFromModel(model, []);
selectorReducers.forEach(function (selector) {
selector[selectImpSymbol] = function (state) {
return wrapFnWithMemoize(selector(state));
};
});
listenDefinitions.forEach(function (def) {
def.listeners = def.listeners || {};
var on = function on(target, handler) {
if (typeof handler !== 'function') {
return;
}
var meta = def[metaSymbol];
handler[metaSymbol] = meta;
if (!handler[actionSymbol] && !handler[thunkSymbol]) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line
console.warn("Easy Peasy: you must provide either an \"action\" or \"thunk\" to your listeners. Found an invalid handler at \"" + meta.path.join('.') + "\"");
}
return;
}
var targetActionName;
if (typeof target === 'function' && target[actionNameSymbol] && actionCreatorDict[target[actionNameSymbol]]) {
if (target[thunkSymbol]) {
targetActionName = thunkCompleteName(target);
} else {
targetActionName = target[actionNameSymbol];
}
} else if (typeof target === 'string') {
targetActionName = target;
}
if (targetActionName) {
if (handler[thunkSymbol]) {
thunkListenersDict[targetActionName] = thunkListenersDict[targetActionName] || [];
thunkListenersDict[targetActionName].push(handler);
} else {
actionListenersDict[targetActionName] = actionListenersDict[targetActionName] || [];
actionListenersDict[targetActionName].push({
path: meta.parent,
handler: handler
});
}
def.listeners[targetActionName] = def.listeners[targetActionName] || [];
def.listeners[targetActionName].push(handler);
}
};
def(on);
});
var runSelectorReducer = function runSelectorReducer(state, selector) {
var _selector$selectState = selector[selectStateSymbol],
parentPath = _selector$selectState.parentPath,
key = _selector$selectState.key,
executed = _selector$selectState.executed;
if (executed) {
return state;
}
var dependencies = selector[selectDependenciesSymbol];
var stateAfterDependencies = dependencies ? dependencies.reduce(runSelectorReducer, state) : state;
var newState = stateAfterDependencies;
if (parentPath.length > 0) {
var target = get(parentPath, stateAfterDependencies);
if (target) {
if (!selector.prevState || selector.prevState !== get(parentPath, state)) {
var newValue = selector[selectImpSymbol](target);
newState = produce(state, function (draft) {
var updateTarget = get(parentPath, draft);
updateTarget[key] = newValue;
});
selector.prevState = get(parentPath, newState);
}
}
} else if (!selector.prevState || selector.prevState !== state) {
var _newValue = selector[selectImpSymbol](stateAfterDependencies);
newState = produce(state, function (draft) {
draft[key] = _newValue;
});
selector.prevState = newState;
}
selector[selectStateSymbol].executed = true;
return newState;
};
var runSelectors = function runSelectors(state) {
return selectorReducers.reduce(runSelectorReducer, state);
};
var createReducer = function createReducer() {
var runActionReducerAtPath = function runActionReducerAtPath(state, action, actionReducer, path) {
var current = get(path, state);
if (path.length === 0) {
return produce(state, function (_draft) {
return actionReducer(_draft, action.payload);
});
}
return produce(state, function (draft) {
set(actionReducer[metaSymbol].parent, draft, produce(current, function (_draft) {
return actionReducer(_draft, action.payload);
}));
});
};
var reducerForActions = function reducerForActions(state, action) {
var actionReducer = actionReducersDict[action.type];
if (actionReducer) {
return runActionReducerAtPath(state, action, actionReducer, actionReducer[metaSymbol].parent);
}
return state;
};
var reducerForListeners = function reducerForListeners(state, action) {
var target = action.type === '@@EP/LISTENER' ? action.actionName : action.type;
var actionListeners = actionListenersDict[target];
if (actionListeners) {
var targetAction = action.type === '@@EP/LISTENER' ? {
type: target,
payload: action.payload
} : action;
return actionListeners.reduce(function (newState, _ref2) {
var path = _ref2.path,
handler = _ref2.handler;
return runActionReducerAtPath(newState, targetAction, handler, path);
}, state);
}
return state;
};
var reducerForCustomReducers = function reducerForCustomReducers(state, action) {
return produce(state, function (draft) {
customReducers.forEach(function (_ref3) {
var p = _ref3.path,
red = _ref3.reducer;
var current = get(p, draft);
set(p, draft, red(current, action));
});
});
};
var isInitial = true;
var selectsReducer = function selectsReducer(state) {
var stateAfterSelectors = runSelectors(state);
isInitial = false;
selectorReducers.forEach(function (selector) {
selector[selectStateSymbol].executed = false;
});
return stateAfterSelectors;
};
var selectorsReducer = function selectorsReducer(state) {
var selectors = Object.values(selectorsDict);
return produce(state, function (draft) {
selectors.forEach(function (selector) {
var selectorState = selector[selectorStateSymbol];
var parentState = get(selectorState.meta.parent, state);
var recreateSelector = function recreateSelector() {
var newSelector = selectorState.createSelector();
newSelector[selectorState.prevState] = parentState;
selectorsDict[selectorState.selectorId] = newSelector;
set(selectorState.meta.path, draft, newSelector);
};
if (selectorState.prevState == null) {
selectorState.prevState = selectorState.argumentChangeTracker(state);
} else {
var nextId = selectorState.argumentChangeTracker(state);
if (selectorState.prevState !== nextId) {
selectorState.prevState = nextId;
recreateSelector();
}
}
});
});
};
var rootReducer = function rootReducer(state, action) {
var stateAfterActions = reducerForActions(state, action);
var stateAfterListeners = reducerForListeners(stateAfterActions, action);
var stateAfterCustomReducers = reducerForCustomReducers(stateAfterListeners, action);
var stateAfterSelect = state !== stateAfterCustomReducers || isInitial ? selectsReducer(stateAfterCustomReducers) : stateAfterCustomReducers;
return selectorsReducer(stateAfterSelect);
};
return rootReducer;
};
return {
actionCreators: actionCreators,
actionListenersDict: actionListenersDict,
defaultState: defaultState,
listenDefinitions: listenDefinitions,
reducer: reducerEnhancer(createReducer()),
thunkListenersDict: thunkListenersDict
};
}
function createStore(model, options) {
if (options === void 0) {
options = {};
}
var _options = options,
compose$1 = _options.compose,
_options$devTools = _options.devTools,
devTools = _options$devTools === void 0 ? true : _options$devTools,
_options$disableInter = _options.disableInternalSelectFnMemoize,
disableInternalSelectFnMemoize = _options$disableInter === void 0 ? false : _options$disableInter,
_options$enhancers = _options.enhancers,
enhancers = _options$enhancers === void 0 ? [] : _options$enhancers,
_options$initialState = _options.initialState,
initialState = _options$initialState === void 0 ? {} : _options$initialState,
injections = _options.injections,
_options$middleware = _options.middleware,
middleware = _options$middleware === void 0 ? [] : _options$middleware,
_options$mockActions = _options.mockActions,
mockActions = _options$mockActions === void 0 ? false : _options$mockActions,
_options$name = _options.name,
storeName = _options$name === void 0 ? "EasyPeasyStore" : _options$name,
_options$reducerEnhan = _options.reducerEnhancer,
reducerEnhancer = _options$reducerEnhan === void 0 ? function (rootReducer) {
return rootReducer;
} : _options$reducerEnhan;
var modelDefinition = _extends({}, model, {
logFullState: thunk(function (actions, payload, _ref) {
var getState = _ref.getState;
// eslint-disable-next-line no-console
console.log(JSON.stringify(getState(), null, 2));
}),
replaceState: action(function (state, payload) {
return payload;
})
});
var references = {};
var mockedActions = [];
var dispatchThunk = function dispatchThunk(thunk, payload) {
return thunk(get(thunk[metaSymbol].parent, references.internals.actionCreators), payload, {
dispatch: references.dispatch,
getState: function getState() {
return get(thunk[metaSymbol].parent, references.getState());
},
getStoreState: references.getState,
injections: injections,
meta: thunk[metaSymbol]
});
};
var dispatchThunkListeners = function dispatchThunkListeners(name, payload) {
var listensForAction = references.internals.thunkListenersDict[name];
return listensForAction && listensForAction.length > 0 ? Promise.all(listensForAction.map(function (listenForAction) {
return dispatchThunk(listenForAction, payload);
})) : Promise.resolve();
};
var dispatchActionStringListeners = function dispatchActionStringListeners() {
return function (next) {
return function (action) {
var result = next(action);
if (references.internals.thunkListenersDict[action.type]) {
dispatchThunkListeners(action.type, action.payload);
}
return result;
};
};
};
var composeEnhancers = compose$1 || (devTools && typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
name: storeName
}) : compose);
var bindStoreInternals = function bindStoreInternals(state, isRebind) {
if (isRebind === void 0) {
isRebind = false;
}
references.internals = createStoreInternals({
disableInternalSelectFnMemoize: disableInternalSelectFnMemoize,
initialState: state,
injections: injections,
model: modelDefinition,
reducerEnhancer: reducerEnhancer,
references: references,
isRebind: isRebind
});
};
bindStoreInternals(initialState);
var mockActionsMiddleware = function mockActionsMiddleware() {
return function (next) {
return function (action) {
if (mockActions) {
if (action == null || typeof action === 'object' && action.type === '@@EP/LISTENER') ; else {
mockedActions.push(action);
}
return undefined;
}
return next(action);
};
};
};
var store = createStore$1(references.internals.reducer, references.internals.defaultState, composeEnhancers.apply(void 0, [applyMiddleware.apply(void 0, [reduxThunk, dispatchActionStringListeners].concat(middleware, [mockActionsMiddleware]))].concat(enhancers)));
store.getMockedActions = function () {
return [].concat(mockedActions);
};
store.clearMockedActions = function () {
mockedActions = [];
};
references.dispatch = store.dispatch;
references.getState = store.getState; // attach the action creators to dispatch
var bindActionCreators = function bindActionCreators(actionCreators) {
Object.keys(store.dispatch).forEach(function (actionsKey) {
delete store.dispatch[actionsKey];
});
Object.keys(actionCreators).forEach(function (key) {
store.dispatch[key] = actionCreators[key];
});
};
bindActionCreators(references.internals.actionCreators);
var rebindStore = function rebindStore() {
bindStoreInternals(store.getState(), true);
store.replaceReducer(references.internals.reducer);
store.dispatch.replaceState(references.internals.defaultState);
bindActionCreators(references.internals.actionCreators);
};
store.addModel = function (key, modelForKey) {
if (modelDefinition[key] && process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn("The store model already contains a model definition for \"" + key + "\"");
store.removeModel(key);
}
modelDefinition[key] = modelForKey;
rebindStore();
};
store.removeModel = function (key) {
if (!modelDefinition[key]) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line no-console
console.warn("The store model does not contain a model definition for \"" + key + "\"");
}
return;
}
delete modelDefinition[key];
rebindStore();
};
var dispatchActionListener = function dispatchActionListener(actionName, payload) {
return store.dispatch({
type: '@@EP/LISTENER',
payload: payload,
actionName: actionName
});
};
var resolveActionName = function resolveActionName(action) {
return typeof action === 'function' ? action[actionSymbol] ? actionName(action) : action[thunkSymbol] ? thunkCompleteName(action) : undefined : typeof action === 'string' ? action : undefined;
};
var dispatchHandler = function dispatchHandler(handler, actionName, payload) {
if (handler[thunkSymbol]) {
return dispatchThunk(handler, payload);
}
};
store.triggerListener = function (listener, action, payload) {
var actionName = resolveActionName(action);
if (listener.listeners[actionName] && listener.listeners[actionName].length > 0) {
if (listener.listeners[actionName].some(function (handler) {
return handler[actionSymbol];
})) {
dispatchActionListener(actionName, payload);
}
var thunkHandlers = listener.listeners[actionName].filter(function (handler) {
return handler[thunkSymbol];
});
return thunkHandlers.length > 0 ? Promise.all(thunkHandlers.map(function (handler) {
return dispatchHandler(handler, actionName, payload);
})).then(function () {
return undefined;
}) : Promise.resolve();
}
return Promise.resolve();
};
store.triggerListeners = function (action, payload) {
var actionName = resolveActionName(action);
if (actionName) {
var actionListenerHandlers = references.internals.actionListenersDict[actionName];
if (actionListenerHandlers && actionListenerHandlers.length > 0) {
dispatchActionListener(actionName, payload);
}
var thunkListenerHandlers = references.internals.thunkListenersDict[actionName];
return thunkListenerHandlers && thunkListenerHandlers.length > 0 ? Promise.all(thunkListenerHandlers.map(function (handler) {
return dispatchThunk(handler, payload);
})).then(function () {
return undefined;
}) : Promise.resolve();
}
return Promise.resolve();
};
return store;
}
var StoreProvider = function StoreProvider(_ref) {
var children = _ref.children,
store = _ref.store;
return React.createElement(StoreContext.Provider, {
value: store
}, children);
};
/**
* immer is an implementation detail, so we are not going to use its auto freeze
* behaviour, which throws errors if trying to mutate state. It's also risky
* for production builds as has a perf overhead.
*
* @see https://github.com/mweststrate/immer#auto-freezing
*/
setAutoFreeze(false);
export { StoreProvider, action, actionName, createStore, createTypedHooks, listen, reducer, select, selector, thunk, thunkCompleteName, thunkFailName, thunkStartName, useActions, useDispatch, useStore, useStoreActions, useStoreDispatch, useStoreState };
//# sourceMappingURL=easy-peasy.esm.js.map