redux
Advanced tools
Comparing version 5.0.0-alpha.1 to 5.0.0-alpha.2
@@ -21,10 +21,5 @@ /** | ||
const randomString = () => Math.random().toString(36).substring(7).split('').join('.'); | ||
const ActionTypes = { | ||
INIT: `@@redux/INIT${ | ||
randomString()}`, | ||
REPLACE: `@@redux/REPLACE${ | ||
randomString()}`, | ||
INIT: `@@redux/INIT${randomString()}`, | ||
REPLACE: `@@redux/REPLACE${randomString()}`, | ||
PROBE_UNKNOWN_ACTION: () => `@@redux/PROBE_UNKNOWN_ACTION${randomString()}` | ||
@@ -40,7 +35,5 @@ }; | ||
let proto = obj; | ||
while (Object.getPrototypeOf(proto) !== null) { | ||
proto = Object.getPrototypeOf(proto); | ||
} | ||
return Object.getPrototypeOf(obj) === proto; | ||
@@ -54,3 +47,2 @@ } | ||
const type = typeof val; | ||
switch (type) { | ||
@@ -66,3 +58,2 @@ case 'boolean': | ||
} | ||
if (Array.isArray(val)) return 'array'; | ||
@@ -72,3 +63,2 @@ if (isDate(val)) return 'date'; | ||
const constructorName = ctorName(val); | ||
switch (constructorName) { | ||
@@ -82,16 +72,12 @@ case 'Symbol': | ||
return constructorName; | ||
} // other | ||
} | ||
// other | ||
return Object.prototype.toString.call(val).slice(8, -1).toLowerCase().replace(/\s/g, ''); | ||
} | ||
function ctorName(val) { | ||
return typeof val.constructor === 'function' ? val.constructor.name : null; | ||
} | ||
function isError(val) { | ||
return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number'; | ||
} | ||
function isDate(val) { | ||
@@ -101,10 +87,7 @@ if (val instanceof Date) return true; | ||
} | ||
function kindOf(val) { | ||
let typeOfVal = typeof val; | ||
if (process.env.NODE_ENV !== 'production') { | ||
typeOfVal = miniKindOf(val); | ||
} | ||
return typeOfVal; | ||
@@ -117,7 +100,5 @@ } | ||
} | ||
if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.'); | ||
} | ||
if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') { | ||
@@ -127,3 +108,2 @@ enhancer = preloadedState; | ||
} | ||
if (typeof enhancer !== 'undefined') { | ||
@@ -133,10 +113,9 @@ if (typeof enhancer !== 'function') { | ||
} | ||
return enhancer(createStore)(reducer, preloadedState); | ||
} | ||
let currentReducer = reducer; | ||
let currentState = preloadedState; | ||
let currentListeners = []; | ||
let currentListeners = new Map(); | ||
let nextListeners = currentListeners; | ||
let listenerIdCounter = 0; | ||
let isDispatching = false; | ||
@@ -150,6 +129,8 @@ /** | ||
*/ | ||
function ensureCanMutateNextListeners() { | ||
if (nextListeners === currentListeners) { | ||
nextListeners = currentListeners.slice(); | ||
nextListeners = new Map(); | ||
currentListeners.forEach((listener, key) => { | ||
nextListeners.set(key, listener); | ||
}); | ||
} | ||
@@ -162,4 +143,2 @@ } | ||
*/ | ||
function getState() { | ||
@@ -169,3 +148,2 @@ if (isDispatching) { | ||
} | ||
return currentState; | ||
@@ -196,4 +174,2 @@ } | ||
*/ | ||
function subscribe(listener) { | ||
@@ -203,10 +179,9 @@ if (typeof listener !== 'function') { | ||
} | ||
if (isDispatching) { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.'); | ||
} | ||
let isSubscribed = true; | ||
ensureCanMutateNextListeners(); | ||
nextListeners.push(listener); | ||
const listenerId = listenerIdCounter++; | ||
nextListeners.set(listenerId, listener); | ||
return function unsubscribe() { | ||
@@ -216,11 +191,8 @@ if (!isSubscribed) { | ||
} | ||
if (isDispatching) { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.'); | ||
} | ||
isSubscribed = false; | ||
ensureCanMutateNextListeners(); | ||
const index = nextListeners.indexOf(listener); | ||
nextListeners.splice(index, 1); | ||
nextListeners.delete(listenerId); | ||
currentListeners = null; | ||
@@ -254,4 +226,2 @@ }; | ||
*/ | ||
function dispatch(action) { | ||
@@ -261,11 +231,8 @@ if (!isPlainObject(action)) { | ||
} | ||
if (typeof action.type === 'undefined') { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(8) : 'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.'); | ||
} | ||
if (isDispatching) { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.'); | ||
} | ||
try { | ||
@@ -277,10 +244,6 @@ isDispatching = true; | ||
} | ||
const listeners = currentListeners = nextListeners; | ||
for (let i = 0; i < listeners.length; i++) { | ||
const listener = listeners[i]; | ||
listeners.forEach(listener => { | ||
listener(); | ||
} | ||
}); | ||
return action; | ||
@@ -296,20 +259,15 @@ } | ||
* @param nextReducer The reducer for the store to use instead. | ||
* @returns The same store instance with a new reducer in place. | ||
*/ | ||
function replaceReducer(nextReducer) { | ||
if (typeof nextReducer !== 'function') { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(10) : `Expected the nextReducer to be a function. Instead, received: '${kindOf(nextReducer)}`); | ||
} // TODO: do this more elegantly | ||
currentReducer = nextReducer; // This action has a similar effect to ActionTypes.INIT. | ||
} | ||
currentReducer = nextReducer; | ||
// This action has a similar effect to ActionTypes.INIT. | ||
// Any reducers that existed in both the new and old rootReducer | ||
// will receive the previous state. This effectively populates | ||
// the new state tree with any relevant data from the old one. | ||
dispatch({ | ||
type: ActionTypes.REPLACE | ||
}); // change the type of the store by casting it to the new store | ||
return store; | ||
}); | ||
} | ||
@@ -322,4 +280,2 @@ /** | ||
*/ | ||
function observable() { | ||
@@ -340,6 +296,4 @@ const outerSubscribe = subscribe; | ||
} | ||
function observeState() { | ||
const observerAsObserver = observer; | ||
if (observerAsObserver.next) { | ||
@@ -349,3 +303,2 @@ observerAsObserver.next(getState()); | ||
} | ||
observeState(); | ||
@@ -357,13 +310,10 @@ const unsubscribe = outerSubscribe(observeState); | ||
}, | ||
[$$observable]() { | ||
return this; | ||
} | ||
}; | ||
} // When a store is created, an "INIT" action is dispatched so that every | ||
} | ||
// When a store is created, an "INIT" action is dispatched so that every | ||
// reducer returns their initial state. This effectively populates | ||
// the initial state tree. | ||
dispatch({ | ||
@@ -396,4 +346,2 @@ type: ActionTypes.INIT | ||
/* eslint-enable no-console */ | ||
try { | ||
@@ -405,3 +353,2 @@ // This error was thrown as a convenience so that if you enable | ||
} catch (e) {} // eslint-disable-line no-empty | ||
} | ||
@@ -412,11 +359,8 @@ | ||
const argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer'; | ||
if (reducerKeys.length === 0) { | ||
return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.'; | ||
} | ||
if (!isPlainObject(inputState)) { | ||
return `The ${argumentName} has unexpected type of "${kindOf(inputState)}". Expected argument to be an object with the following ` + `keys: "${reducerKeys.join('", "')}"`; | ||
} | ||
const unexpectedKeys = Object.keys(inputState).filter(key => !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key]); | ||
@@ -427,3 +371,2 @@ unexpectedKeys.forEach(key => { | ||
if (action && action.type === ActionTypes.REPLACE) return; | ||
if (unexpectedKeys.length > 0) { | ||
@@ -433,3 +376,2 @@ return `Unexpected ${unexpectedKeys.length > 1 ? 'keys' : 'key'} ` + `"${unexpectedKeys.join('", "')}" found in ${argumentName}. ` + `Expected to find one of the known reducer keys instead: ` + `"${reducerKeys.join('", "')}". Unexpected keys will be ignored.`; | ||
} | ||
function assertReducerShape(reducers) { | ||
@@ -441,7 +383,5 @@ Object.keys(reducers).forEach(key => { | ||
}); | ||
if (typeof initialState === 'undefined') { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(12) : `The slice reducer for key "${key}" returned undefined during initialization. ` + `If the state passed to the reducer is undefined, you must ` + `explicitly return the initial state. The initial state may ` + `not be undefined. If you don't want to set a value for this reducer, ` + `you can use null instead of undefined.`); | ||
} | ||
if (typeof reducer(undefined, { | ||
@@ -454,10 +394,7 @@ type: ActionTypes.PROBE_UNKNOWN_ACTION() | ||
} | ||
function combineReducers(reducers) { | ||
const reducerKeys = Object.keys(reducers); | ||
const finalReducers = {}; | ||
for (let i = 0; i < reducerKeys.length; i++) { | ||
const key = reducerKeys[i]; | ||
if (process.env.NODE_ENV !== 'production') { | ||
@@ -468,3 +405,2 @@ if (typeof reducers[key] === 'undefined') { | ||
} | ||
if (typeof reducers[key] === 'function') { | ||
@@ -474,14 +410,10 @@ finalReducers[key] = reducers[key]; | ||
} | ||
const finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same | ||
const finalReducerKeys = Object.keys(finalReducers); | ||
// This is used to make sure we don't warn about the same | ||
// keys multiple times. | ||
let unexpectedKeyCache; | ||
if (process.env.NODE_ENV !== 'production') { | ||
unexpectedKeyCache = {}; | ||
} | ||
let shapeAssertionError; | ||
try { | ||
@@ -492,3 +424,2 @@ assertReducerShape(finalReducers); | ||
} | ||
return function combination(state = {}, action) { | ||
@@ -498,6 +429,4 @@ if (shapeAssertionError) { | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
const warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache); | ||
if (warningMessage) { | ||
@@ -507,6 +436,4 @@ warning(warningMessage); | ||
} | ||
let hasChanged = false; | ||
const nextState = {}; | ||
for (let i = 0; i < finalReducerKeys.length; i++) { | ||
@@ -517,3 +444,2 @@ const key = finalReducerKeys[i]; | ||
const nextStateForKey = reducer(previousStateForKey, action); | ||
if (typeof nextStateForKey === 'undefined') { | ||
@@ -523,7 +449,5 @@ const actionType = action && action.type; | ||
} | ||
nextState[key] = nextStateForKey; | ||
hasChanged = hasChanged || nextStateForKey !== previousStateForKey; | ||
} | ||
hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length; | ||
@@ -539,3 +463,2 @@ return hasChanged ? nextState : state; | ||
} | ||
function bindActionCreators(actionCreators, dispatch) { | ||
@@ -545,12 +468,8 @@ if (typeof actionCreators === 'function') { | ||
} | ||
if (typeof actionCreators !== 'object' || actionCreators === null) { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(16) : `bindActionCreators expected an object or a function, but instead received: '${kindOf(actionCreators)}'. ` + `Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?`); | ||
} | ||
const boundActionCreators = {}; | ||
for (const key in actionCreators) { | ||
const actionCreator = actionCreators[key]; | ||
if (typeof actionCreator === 'function') { | ||
@@ -560,3 +479,2 @@ boundActionCreators[key] = bindActionCreator(actionCreator, dispatch); | ||
} | ||
return boundActionCreators; | ||
@@ -570,7 +488,5 @@ } | ||
} | ||
if (funcs.length === 1) { | ||
return funcs[0]; | ||
} | ||
return funcs.reduce((a, b) => (...args) => a(b(...args))); | ||
@@ -582,7 +498,5 @@ } | ||
const store = createStore(reducer, preloadedState); | ||
let dispatch = () => { | ||
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.'); | ||
}; | ||
const middlewareAPI = { | ||
@@ -594,3 +508,4 @@ getState: store.getState, | ||
dispatch = compose(...chain)(store.dispatch); | ||
return { ...store, | ||
return { | ||
...store, | ||
dispatch | ||
@@ -597,0 +512,0 @@ }; |
{ | ||
"name": "redux", | ||
"version": "5.0.0-alpha.1", | ||
"version": "5.0.0-alpha.2", | ||
"description": "Predictable state container for JavaScript apps", | ||
@@ -50,14 +50,13 @@ "license": "MIT", | ||
"lint": "eslint --ext js,ts src test", | ||
"check-types": "tsc --noEmit", | ||
"test": "jest && tsc -p test/typescript", | ||
"test:types": "tsc -p test/typescript", | ||
"test:watch": "jest --watch", | ||
"test:cov": "jest --coverage", | ||
"check-types": "tsc --noEmit && echo \"Types compiled\"", | ||
"test": "vitest --run", | ||
"test:types": "tsc -p test/typescript && echo \"Typetests passed\"", | ||
"test:watch": "vitest", | ||
"test:cov": "vitest --coverage", | ||
"build": "rollup -c", | ||
"pretest": "npm run build", | ||
"prepublishOnly": "npm run clean && npm run check-types && npm run format:check && npm run lint && npm test", | ||
"prepublishOnly": "yarn clean && yarn check-types && yarn format:check && yarn lint && yarn test && yarn build", | ||
"examples:lint": "eslint --ext js,ts examples", | ||
"examples:test": "cross-env CI=true babel-node examples/testAll.js" | ||
"examples:test": "cross-env CI=true babel-node examples/testAll.js", | ||
"tsc": "tsc" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
@@ -78,7 +77,6 @@ "@babel/cli": "^7.18.10", | ||
"@rollup/plugin-replace": "^5.0.0", | ||
"@types/jest": "^29.0.0", | ||
"@rollup/plugin-terser": "^0.4.0", | ||
"@types/node": "^18.7.16", | ||
"@typescript-eslint/eslint-plugin": "^5.36.2", | ||
"@typescript-eslint/parser": "^5.36.2", | ||
"babel-jest": "^29.0.3", | ||
"cross-env": "^7.0.3", | ||
@@ -94,3 +92,2 @@ "eslint": "^8.23.0", | ||
"glob": "^8.0.3", | ||
"jest": "^29.0.3", | ||
"netlify-plugin-cache": "^1.0.3", | ||
@@ -100,7 +97,6 @@ "prettier": "^2.7.1", | ||
"rollup": "^3.12.0", | ||
"@rollup/plugin-terser": "^0.4.0", | ||
"rollup-plugin-typescript2": "^0.34.1", | ||
"rxjs": "^7.5.6", | ||
"ts-jest": "^29.0.0", | ||
"typescript": "^4.8.3" | ||
"typescript": "^4.8.3", | ||
"vitest": "^0.27.2" | ||
}, | ||
@@ -107,0 +103,0 @@ "npmName": "redux", |
import compose from './compose' | ||
import { Middleware, MiddlewareAPI } from './types/middleware' | ||
import { AnyAction } from './types/actions' | ||
import { | ||
StoreEnhancer, | ||
Dispatch, | ||
PreloadedState, | ||
StoreEnhancerStoreCreator | ||
} from './types/store' | ||
import { StoreEnhancer, Dispatch, PreloadedState } from './types/store' | ||
import { Reducer } from './types/reducers' | ||
@@ -63,3 +58,3 @@ | ||
): StoreEnhancer<any> { | ||
return (createStore: StoreEnhancerStoreCreator) => | ||
return createStore => | ||
<S, A extends AnyAction>( | ||
@@ -66,0 +61,0 @@ reducer: Reducer<S, A>, |
@@ -9,3 +9,3 @@ import $$observable from './utils/symbol-observable' | ||
Observer, | ||
ExtendState | ||
ListenerCallback | ||
} from './types/store' | ||
@@ -43,6 +43,11 @@ import { Action } from './types/actions' | ||
*/ | ||
export function createStore<S, A extends Action, Ext = {}, StateExt = never>( | ||
export function createStore< | ||
S, | ||
A extends Action, | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
>( | ||
reducer: Reducer<S, A>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
): Store<S, A, StateExt> & Ext | ||
/** | ||
@@ -73,12 +78,22 @@ * @deprecated | ||
*/ | ||
export function createStore<S, A extends Action, Ext = {}, StateExt = never>( | ||
export function createStore< | ||
S, | ||
A extends Action, | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
>( | ||
reducer: Reducer<S, A>, | ||
preloadedState?: PreloadedState<S>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
export function createStore<S, A extends Action, Ext = {}, StateExt = never>( | ||
): Store<S, A, StateExt> & Ext | ||
export function createStore< | ||
S, | ||
A extends Action, | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
>( | ||
reducer: Reducer<S, A>, | ||
preloadedState?: PreloadedState<S> | StoreEnhancer<Ext, StateExt>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext { | ||
): Store<S, A, StateExt> & Ext { | ||
if (typeof reducer !== 'function') { | ||
@@ -120,3 +135,3 @@ throw new Error( | ||
preloadedState as PreloadedState<S> | ||
) as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
) as Store<S, A, StateExt> & Ext | ||
} | ||
@@ -126,4 +141,5 @@ | ||
let currentState = preloadedState as S | ||
let currentListeners: (() => void)[] | null = [] | ||
let currentListeners: Map<number, ListenerCallback> | null = new Map() | ||
let nextListeners = currentListeners | ||
let listenerIdCounter = 0 | ||
let isDispatching = false | ||
@@ -140,3 +156,6 @@ | ||
if (nextListeners === currentListeners) { | ||
nextListeners = currentListeners.slice() | ||
nextListeners = new Map() | ||
currentListeners.forEach((listener, key) => { | ||
nextListeners.set(key, listener) | ||
}) | ||
} | ||
@@ -206,3 +225,4 @@ } | ||
ensureCanMutateNextListeners() | ||
nextListeners.push(listener) | ||
const listenerId = listenerIdCounter++ | ||
nextListeners.set(listenerId, listener) | ||
@@ -224,4 +244,3 @@ return function unsubscribe() { | ||
ensureCanMutateNextListeners() | ||
const index = nextListeners.indexOf(listener) | ||
nextListeners.splice(index, 1) | ||
nextListeners.delete(listenerId) | ||
currentListeners = null | ||
@@ -283,7 +302,5 @@ } | ||
const listeners = (currentListeners = nextListeners) | ||
for (let i = 0; i < listeners.length; i++) { | ||
const listener = listeners[i] | ||
listeners.forEach(listener => { | ||
listener() | ||
} | ||
}) | ||
return action | ||
@@ -300,7 +317,4 @@ } | ||
* @param nextReducer The reducer for the store to use instead. | ||
* @returns The same store instance with a new reducer in place. | ||
*/ | ||
function replaceReducer<NewState, NewActions extends A>( | ||
nextReducer: Reducer<NewState, NewActions> | ||
): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext { | ||
function replaceReducer(nextReducer: Reducer<S, A>): void { | ||
if (typeof nextReducer !== 'function') { | ||
@@ -314,4 +328,3 @@ throw new Error( | ||
// TODO: do this more elegantly | ||
;(currentReducer as unknown as Reducer<NewState, NewActions>) = nextReducer | ||
currentReducer = nextReducer | ||
@@ -323,10 +336,2 @@ // This action has a similar effect to ActionTypes.INIT. | ||
dispatch({ type: ActionTypes.REPLACE } as A) | ||
// change the type of the store by casting it to the new store | ||
return store as unknown as Store< | ||
ExtendState<NewState, StateExt>, | ||
NewActions, | ||
StateExt, | ||
Ext | ||
> & | ||
Ext | ||
} | ||
@@ -389,3 +394,3 @@ | ||
[$$observable]: observable | ||
} as unknown as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
} as unknown as Store<S, A, StateExt> & Ext | ||
return store | ||
@@ -427,8 +432,8 @@ } | ||
A extends Action, | ||
Ext = {}, | ||
StateExt = never | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
>( | ||
reducer: Reducer<S, A>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
): Store<S, A, StateExt> & Ext | ||
/** | ||
@@ -467,4 +472,4 @@ * Creates a Redux store that holds the state tree. | ||
A extends Action, | ||
Ext = {}, | ||
StateExt = never | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
>( | ||
@@ -474,8 +479,8 @@ reducer: Reducer<S, A>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
): Store<S, A, StateExt> & Ext | ||
export function legacy_createStore< | ||
S, | ||
A extends Action, | ||
Ext = {}, | ||
StateExt = never | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
>( | ||
@@ -485,4 +490,4 @@ reducer: Reducer<S, A>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext { | ||
): Store<S, A, StateExt> & Ext { | ||
return createStore(reducer, preloadedState as any, enhancer) | ||
} |
@@ -21,4 +21,3 @@ // functions | ||
StoreEnhancer, | ||
StoreEnhancerStoreCreator, | ||
ExtendState | ||
StoreEnhancerStoreCreator | ||
} from './types/store' | ||
@@ -25,0 +24,0 @@ // reducers |
@@ -6,16 +6,2 @@ import { Action, AnyAction } from './actions' | ||
/** | ||
* Extend the state | ||
* | ||
* This is used by store enhancers and store creators to extend state. | ||
* If there is no state extension, it just returns the state, as is, otherwise | ||
* it returns the state joined with its extension. | ||
* | ||
* Reference for future devs: | ||
* https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919 | ||
*/ | ||
export type ExtendState<State, Extension> = [Extension] extends [never] | ||
? State | ||
: State & Extension | ||
/** | ||
* Internal "virtual" symbol used to make the `CombinedState` type unique. | ||
@@ -95,2 +81,4 @@ */ | ||
export type ListenerCallback = () => void | ||
declare global { | ||
@@ -136,3 +124,2 @@ interface SymbolConstructor { | ||
* @template StateExt any extension to state from store enhancers | ||
* @template Ext any extensions to the store from store enhancers | ||
*/ | ||
@@ -142,4 +129,3 @@ export interface Store< | ||
A extends Action = AnyAction, | ||
StateExt = never, | ||
Ext = {} | ||
StateExt extends {} = {} | ||
> { | ||
@@ -179,3 +165,3 @@ /** | ||
*/ | ||
getState(): S | ||
getState(): S & StateExt | ||
@@ -206,3 +192,3 @@ /** | ||
*/ | ||
subscribe(listener: () => void): Unsubscribe | ||
subscribe(listener: ListenerCallback): Unsubscribe | ||
@@ -218,5 +204,3 @@ /** | ||
*/ | ||
replaceReducer<NewState, NewActions extends Action>( | ||
nextReducer: Reducer<NewState, NewActions> | ||
): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext | ||
replaceReducer(nextReducer: Reducer<S, A>): void | ||
@@ -229,3 +213,3 @@ /** | ||
*/ | ||
[Symbol.observable](): Observable<S> | ||
[Symbol.observable](): Observable<S & StateExt> | ||
} | ||
@@ -245,11 +229,11 @@ | ||
export interface StoreCreator { | ||
<S, A extends Action, Ext = {}, StateExt = never>( | ||
<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>( | ||
reducer: Reducer<S, A>, | ||
enhancer?: StoreEnhancer<Ext, StateExt> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
<S, A extends Action, Ext = {}, StateExt = never>( | ||
): Store<S, A, StateExt> & Ext | ||
<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>( | ||
reducer: Reducer<S, A>, | ||
preloadedState?: PreloadedState<S>, | ||
enhancer?: StoreEnhancer<Ext> | ||
): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
): Store<S, A, StateExt> & Ext | ||
} | ||
@@ -278,11 +262,14 @@ | ||
*/ | ||
export type StoreEnhancer<Ext = {}, StateExt = never> = ( | ||
next: StoreEnhancerStoreCreator<Ext, StateExt> | ||
) => StoreEnhancerStoreCreator<Ext, StateExt> | ||
export type StoreEnhancerStoreCreator<Ext = {}, StateExt = never> = < | ||
S = any, | ||
A extends Action = AnyAction | ||
export type StoreEnhancer<Ext extends {} = {}, StateExt extends {} = {}> = < | ||
NextExt extends {}, | ||
NextStateExt extends {} | ||
>( | ||
next: StoreEnhancerStoreCreator<NextExt, NextStateExt> | ||
) => StoreEnhancerStoreCreator<NextExt & Ext, NextStateExt & StateExt> | ||
export type StoreEnhancerStoreCreator< | ||
Ext extends {} = {}, | ||
StateExt extends {} = {} | ||
> = <S = any, A extends Action = AnyAction>( | ||
reducer: Reducer<S, A>, | ||
preloadedState?: PreloadedState<S> | ||
) => Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext | ||
) => Store<S, A, StateExt> & Ext |
@@ -1,2 +0,2 @@ | ||
declare type Func<T extends any[], R> = (...a: T) => R; | ||
type Func<T extends any[], R> = (...a: T) => R; | ||
/** | ||
@@ -3,0 +3,0 @@ * Composes single-argument functions from right to left. The rightmost |
@@ -1,2 +0,2 @@ | ||
import { Store, PreloadedState, StoreEnhancer, ExtendState } from './types/store'; | ||
import { Store, PreloadedState, StoreEnhancer } from './types/store'; | ||
import { Action } from './types/actions'; | ||
@@ -29,3 +29,3 @@ import { Reducer } from './types/reducers'; | ||
*/ | ||
export declare function createStore<S, A extends Action, Ext = {}, StateExt = never>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
export declare function createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, StateExt> & Ext; | ||
/** | ||
@@ -56,3 +56,3 @@ * @deprecated | ||
*/ | ||
export declare function createStore<S, A extends Action, Ext = {}, StateExt = never>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
export declare function createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, StateExt> & Ext; | ||
/** | ||
@@ -88,3 +88,3 @@ * Creates a Redux store that holds the state tree. | ||
*/ | ||
export declare function legacy_createStore<S, A extends Action, Ext = {}, StateExt = never>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
export declare function legacy_createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, StateExt> & Ext; | ||
/** | ||
@@ -120,2 +120,2 @@ * Creates a Redux store that holds the state tree. | ||
*/ | ||
export declare function legacy_createStore<S, A extends Action, Ext = {}, StateExt = never>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
export declare function legacy_createStore<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, StateExt> & Ext; |
@@ -7,3 +7,3 @@ import { createStore, legacy_createStore } from './createStore'; | ||
import __DO_NOT_USE__ActionTypes from './utils/actionTypes'; | ||
export { CombinedState, PreloadedState, Dispatch, Unsubscribe, Observable, Observer, Store, StoreCreator, StoreEnhancer, StoreEnhancerStoreCreator, ExtendState } from './types/store'; | ||
export { CombinedState, PreloadedState, Dispatch, Unsubscribe, Observable, Observer, Store, StoreCreator, StoreEnhancer, StoreEnhancerStoreCreator } from './types/store'; | ||
export { Reducer, ReducerFromReducersMapObject, ReducersMapObject, StateFromReducersMapObject, ActionFromReducer, ActionFromReducersMapObject } from './types/reducers'; | ||
@@ -10,0 +10,0 @@ export { ActionCreator, ActionCreatorsMapObject } from './types/actions'; |
@@ -26,3 +26,3 @@ import { Action, AnyAction } from './actions'; | ||
*/ | ||
export declare type Reducer<S = any, A extends Action = AnyAction> = (state: S | undefined, action: A) => S; | ||
export type Reducer<S = any, A extends Action = AnyAction> = (state: S | undefined, action: A) => S; | ||
/** | ||
@@ -33,3 +33,3 @@ * Object whose values correspond to different reducer functions. | ||
*/ | ||
export declare type ReducersMapObject<S = any, A extends Action = AnyAction> = { | ||
export type ReducersMapObject<S = any, A extends Action = AnyAction> = { | ||
[K in keyof S]: Reducer<S[K], A>; | ||
@@ -42,3 +42,3 @@ }; | ||
*/ | ||
export declare type StateFromReducersMapObject<M> = M extends ReducersMapObject ? { | ||
export type StateFromReducersMapObject<M> = M extends ReducersMapObject ? { | ||
[P in keyof M]: M[P] extends Reducer<infer S, any> ? S : never; | ||
@@ -51,3 +51,3 @@ } : never; | ||
*/ | ||
export declare type ReducerFromReducersMapObject<M> = M extends { | ||
export type ReducerFromReducersMapObject<M> = M extends { | ||
[P in keyof M]: infer R; | ||
@@ -60,3 +60,3 @@ } ? R extends Reducer<any, any> ? R : never : never; | ||
*/ | ||
export declare type ActionFromReducer<R> = R extends Reducer<any, infer A> ? A : never; | ||
export type ActionFromReducer<R> = R extends Reducer<any, infer A> ? A : never; | ||
/** | ||
@@ -67,2 +67,2 @@ * Infer action union type from a `ReducersMapObject`. | ||
*/ | ||
export declare type ActionFromReducersMapObject<M> = M extends ReducersMapObject ? ActionFromReducer<ReducerFromReducersMapObject<M>> : never; | ||
export type ActionFromReducersMapObject<M> = M extends ReducersMapObject ? ActionFromReducer<ReducerFromReducersMapObject<M>> : never; |
@@ -5,13 +5,2 @@ import { Action, AnyAction } from './actions'; | ||
/** | ||
* Extend the state | ||
* | ||
* This is used by store enhancers and store creators to extend state. | ||
* If there is no state extension, it just returns the state, as is, otherwise | ||
* it returns the state joined with its extension. | ||
* | ||
* Reference for future devs: | ||
* https://github.com/microsoft/TypeScript/issues/31751#issuecomment-498526919 | ||
*/ | ||
export declare type ExtendState<State, Extension> = [Extension] extends [never] ? State : State & Extension; | ||
/** | ||
* Internal "virtual" symbol used to make the `CombinedState` type unique. | ||
@@ -39,3 +28,3 @@ */ | ||
} | ||
export declare type CombinedState<S> = EmptyObject & S; | ||
export type CombinedState<S> = EmptyObject & S; | ||
/** | ||
@@ -46,3 +35,3 @@ * Recursively makes combined state objects partial. Only combined state _root | ||
*/ | ||
export declare type PreloadedState<S> = Required<S> extends EmptyObject ? S extends CombinedState<infer S1> ? { | ||
export type PreloadedState<S> = Required<S> extends EmptyObject ? S extends CombinedState<infer S1> ? { | ||
[K in keyof S1]?: S1[K] extends object ? PreloadedState<S1[K]> : S1[K]; | ||
@@ -82,2 +71,3 @@ } : S : { | ||
} | ||
export type ListenerCallback = () => void; | ||
declare global { | ||
@@ -93,3 +83,3 @@ interface SymbolConstructor { | ||
*/ | ||
export declare type Observable<T> = { | ||
export type Observable<T> = { | ||
/** | ||
@@ -112,3 +102,3 @@ * The minimal observable subscription method. | ||
*/ | ||
export declare type Observer<T> = { | ||
export type Observer<T> = { | ||
next?(value: T): void; | ||
@@ -124,5 +114,4 @@ }; | ||
* @template StateExt any extension to state from store enhancers | ||
* @template Ext any extensions to the store from store enhancers | ||
*/ | ||
export interface Store<S = any, A extends Action = AnyAction, StateExt = never, Ext = {}> { | ||
export interface Store<S = any, A extends Action = AnyAction, StateExt extends {} = {}> { | ||
/** | ||
@@ -160,3 +149,3 @@ * Dispatches an action. It is the only way to trigger a state change. | ||
*/ | ||
getState(): S; | ||
getState(): S & StateExt; | ||
/** | ||
@@ -186,3 +175,3 @@ * Adds a change listener. It will be called any time an action is | ||
*/ | ||
subscribe(listener: () => void): Unsubscribe; | ||
subscribe(listener: ListenerCallback): Unsubscribe; | ||
/** | ||
@@ -197,3 +186,3 @@ * Replaces the reducer currently used by the store to calculate the state. | ||
*/ | ||
replaceReducer<NewState, NewActions extends Action>(nextReducer: Reducer<NewState, NewActions>): Store<ExtendState<NewState, StateExt>, NewActions, StateExt, Ext> & Ext; | ||
replaceReducer(nextReducer: Reducer<S, A>): void; | ||
/** | ||
@@ -205,3 +194,3 @@ * Interoperability point for observable/reactive libraries. | ||
*/ | ||
[Symbol.observable](): Observable<S>; | ||
[Symbol.observable](): Observable<S & StateExt>; | ||
} | ||
@@ -220,4 +209,4 @@ /** | ||
export interface StoreCreator { | ||
<S, A extends Action, Ext = {}, StateExt = never>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
<S, A extends Action, Ext = {}, StateExt = never>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext>): Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, enhancer?: StoreEnhancer<Ext, StateExt>): Store<S, A, StateExt> & Ext; | ||
<S, A extends Action, Ext extends {} = {}, StateExt extends {} = {}>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>, enhancer?: StoreEnhancer<Ext>): Store<S, A, StateExt> & Ext; | ||
} | ||
@@ -245,4 +234,4 @@ /** | ||
*/ | ||
export declare type StoreEnhancer<Ext = {}, StateExt = never> = (next: StoreEnhancerStoreCreator<Ext, StateExt>) => StoreEnhancerStoreCreator<Ext, StateExt>; | ||
export declare type StoreEnhancerStoreCreator<Ext = {}, StateExt = never> = <S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>) => Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext; | ||
export type StoreEnhancer<Ext extends {} = {}, StateExt extends {} = {}> = <NextExt extends {}, NextStateExt extends {}>(next: StoreEnhancerStoreCreator<NextExt, NextStateExt>) => StoreEnhancerStoreCreator<NextExt & Ext, NextStateExt & StateExt>; | ||
export type StoreEnhancerStoreCreator<Ext extends {} = {}, StateExt extends {} = {}> = <S = any, A extends Action = AnyAction>(reducer: Reducer<S, A>, preloadedState?: PreloadedState<S>) => Store<S, A, StateExt> & Ext; | ||
export {}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
36
46
152435
3015