import { enableES5 } from 'immer'
export * from 'redux'
export {
  default as createNextState,
  current,
  freeze,
  original,
  isDraft,
} from 'immer'
export type { Draft } from 'immer'
export { createSelector } from 'reselect'
export type {
  Selector,
  OutputParametricSelector,
  OutputSelector,
  ParametricSelector,
} from 'reselect'
export { createDraftSafeSelector } from './createDraftSafeSelector'
export type { ThunkAction, ThunkDispatch, ThunkMiddleware } from 'redux-thunk'

// We deliberately enable Immer's ES5 support, on the grounds that
// we assume RTK will be used with React Native and other Proxy-less
// environments.  In addition, that's how Immer 4 behaved, and since
// we want to ship this in an RTK minor, we should keep the same behavior.
enableES5()

export {
  // js
  configureStore,
} from './configureStore'
export type {
  // types
  ConfigureEnhancersCallback,
  ConfigureStoreOptions,
  EnhancedStore,
} from './configureStore'
export type { DevToolsEnhancerOptions } from './devtoolsExtension'
export {
  // js
  createAction,
  getType,
  isAction,
  isActionCreator,
  isFSA as isFluxStandardAction,
} from './createAction'
export type {
  // types
  PayloadAction,
  PayloadActionCreator,
  ActionCreatorWithNonInferrablePayload,
  ActionCreatorWithOptionalPayload,
  ActionCreatorWithPayload,
  ActionCreatorWithoutPayload,
  ActionCreatorWithPreparedPayload,
  PrepareAction,
} from './createAction'
export {
  // js
  createReducer,
} from './createReducer'
export type {
  // types
  Actions,
  CaseReducer,
  CaseReducers,
} from './createReducer'
export {
  // js
  createSlice,
} from './createSlice'

export type {
  // types
  CreateSliceOptions,
  Slice,
  CaseReducerActions,
  SliceCaseReducers,
  ValidateSliceCaseReducers,
  CaseReducerWithPrepare,
  SliceActionCreator,
} from './createSlice'
export type { ActionCreatorInvariantMiddlewareOptions } from './actionCreatorInvariantMiddleware'
export { createActionCreatorInvariantMiddleware } from './actionCreatorInvariantMiddleware'
export {
  // js
  createImmutableStateInvariantMiddleware,
  isImmutableDefault,
} from './immutableStateInvariantMiddleware'
export type {
  // types
  ImmutableStateInvariantMiddlewareOptions,
} from './immutableStateInvariantMiddleware'
export {
  // js
  createSerializableStateInvariantMiddleware,
  findNonSerializableValue,
  isPlain,
} from './serializableStateInvariantMiddleware'
export type {
  // types
  SerializableStateInvariantMiddlewareOptions,
} from './serializableStateInvariantMiddleware'
export {
  // js
  getDefaultMiddleware,
} from './getDefaultMiddleware'
export type {
  // types
  ActionReducerMapBuilder,
} from './mapBuilders'
export { MiddlewareArray, EnhancerArray } from './utils'

export { createEntityAdapter } from './entities/create_adapter'
export type {
  Dictionary,
  EntityState,
  EntityAdapter,
  EntitySelectors,
  EntityStateAdapter,
  EntityId,
  Update,
  IdSelector,
  Comparer,
} from './entities/models'

export {
  createAsyncThunk,
  unwrapResult,
  miniSerializeError,
} from './createAsyncThunk'
export type {
  AsyncThunk,
  AsyncThunkOptions,
  AsyncThunkAction,
  AsyncThunkPayloadCreatorReturnValue,
  AsyncThunkPayloadCreator,
  SerializedError,
} from './createAsyncThunk'

export {
  // js
  isAllOf,
  isAnyOf,
  isPending,
  isRejected,
  isFulfilled,
  isAsyncThunkAction,
  isRejectedWithValue,
} from './matchers'
export type {
  // types
  ActionMatchingAllOf,
  ActionMatchingAnyOf,
} from './matchers'

export { nanoid } from './nanoid'

export { default as isPlainObject } from './isPlainObject'

export type {
  ListenerEffect,
  ListenerMiddleware,
  ListenerEffectAPI,
  ListenerMiddlewareInstance,
  CreateListenerMiddlewareOptions,
  ListenerErrorHandler,
  TypedStartListening,
  TypedAddListener,
  TypedStopListening,
  TypedRemoveListener,
  UnsubscribeListener,
  UnsubscribeListenerOptions,
  ForkedTaskExecutor,
  ForkedTask,
  ForkedTaskAPI,
  AsyncTaskExecutor,
  SyncTaskExecutor,
  TaskCancelled,
  TaskRejected,
  TaskResolved,
  TaskResult,
} from './listenerMiddleware/index'
export type { AnyListenerPredicate } from './listenerMiddleware/types'

export {
  createListenerMiddleware,
  addListener,
  removeListener,
  clearAllListeners,
  TaskAbortError,
} from './listenerMiddleware/index'

export {
  SHOULD_AUTOBATCH,
  prepareAutoBatched,
  autoBatchEnhancer,
} from './autoBatchEnhancer'
export type { AutoBatchOptions } from './autoBatchEnhancer'

export type { ExtractDispatchExtensions as TSHelpersExtractDispatchExtensions } from './tsHelpers'
