Skip to content

Commit

Permalink
feat: replace redux with redux-toolkit
Browse files Browse the repository at this point in the history
  • Loading branch information
Arun Vishnu committed Aug 28, 2024
1 parent 9958564 commit c22e281
Show file tree
Hide file tree
Showing 8 changed files with 736 additions and 595 deletions.
1,056 changes: 583 additions & 473 deletions common/config/rush/pnpm-lock.yaml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/xarc-react-redux-observable/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
},
"dependencies": {
"@xarc/react-redux": "^1.1.5",
"@reduxjs/toolkit": "^2.2.7",
"redux-observable": "^1.2.0",
"rxjs": "^6.6.3",
"tslib": "^2.1.0"
Expand Down
34 changes: 15 additions & 19 deletions packages/xarc-react-redux-observable/src/common/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { createEpicMiddleware, Epic } from "redux-observable";

import {
applyMiddleware,
Reducer,
createStore,
ReduxFeature,
ReduxDecoratorParams,
ReduxFeatureDecorator
} from "@xarc/react-redux";
import { configureStore, Reducer, Middleware } from "@reduxjs/toolkit";
import { createEpicMiddleware, Epic, EpicMiddleware } from "redux-observable";
import { ReduxFeature, ReduxDecoratorParams, ReduxFeatureDecorator } from "@xarc/react-redux";

/**
* Options for creating a redux observable for use with redux feature
Expand All @@ -20,7 +13,7 @@ export type ReduxObservableOptions = {
};

/**
* adds decorator for redux observable support to the redux feature
* Adds decorator for redux observable support to the redux feature
*
* @param options redux observable options
* @returns redux decorator result
Expand All @@ -30,18 +23,21 @@ export function reduxObservableDecor(options: ReduxObservableOptions): ReduxFeat

return {
decorate(_reduxFeat: ReduxFeature, params: ReduxDecoratorParams) {
const epicMiddleware = createEpicMiddleware();
const observerMiddleware = applyMiddleware(epicMiddleware);
// Create the Redux Observable middleware
const epicMiddleware: EpicMiddleware<any, any, any, any> = createEpicMiddleware();

const store = createStore(
(params.reducers as Reducer<unknown, any>) || (x => x),
params.initialState,
observerMiddleware
);
// Configure the Redux store using Redux Toolkit's configureStore
const store = configureStore({
reducer: (params.reducers as Reducer<unknown, any>) || ((state) => state),
preloadedState: params.initialState,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(epicMiddleware as Middleware),
});

// Run the root epic
epicMiddleware.run(rootEpic);

return { store };
}
},
};
}
1 change: 1 addition & 0 deletions packages/xarc-react-redux-saga/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
},
"dependencies": {
"@xarc/react-redux": "^1.1.5",
"@reduxjs/toolkit": "^1.9.7",
"redux-saga": "^1.1.3",
"tslib": "^2.1.0"
},
Expand Down
20 changes: 7 additions & 13 deletions packages/xarc-react-redux-saga/src/common/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import createSagaMiddleware from "redux-saga";
import {
applyMiddleware,
Reducer,
createStore,
ReduxFeature,
ReduxDecoratorParams,
ReduxFeatureDecorator
} from "@xarc/react-redux";
import { configureStore, Reducer } from "@reduxjs/toolkit";
import { ReduxFeature, ReduxDecoratorParams, ReduxFeatureDecorator } from "@xarc/react-redux";

/**
* Redux saga options
Expand All @@ -30,11 +24,11 @@ export function reduxSagaDecor(options: ReduxSagaOption): ReduxFeatureDecorator
return {
decorate(_reduxFeat: ReduxFeature, params: ReduxDecoratorParams) {
const sagaMiddleware = createSagaMiddleware();
const store = createStore(
(params.reducers as Reducer<unknown, any>) || (x => x),
params.initialState,
applyMiddleware(sagaMiddleware)
);
const store = configureStore({
reducer: (params.reducers as Reducer<unknown, any>) || (x => x),
preloadedState: params.initialState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(sagaMiddleware)
});
sagaMiddleware.run(rootSaga);
return { store };
}
Expand Down
5 changes: 2 additions & 3 deletions packages/xarc-react-redux/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@
},
"dependencies": {
"@xarc/subapp": "^0.4.1",
"react-redux": ">= 8",
"redux": ">= 4",
"@reduxjs/toolkit": "^1.9.0",
"react-redux": "^8.0.1",
"tslib": "^2.1.0"
},
"devDependencies": {
Expand Down Expand Up @@ -56,7 +56,6 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.1",
"redux": "^4.2.0",
"sinon": "^14.0.0",
"sinon-chai": "^3.7.0",
"source-map-support": "^0.5.21",
Expand Down
76 changes: 44 additions & 32 deletions packages/xarc-react-redux/src/common/index.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
/* eslint-disable max-statements, complexity */

import { SubAppDef, SubAppFeatureFactory, SubAppFeature, FeatureDecorator } from "@xarc/subapp";
import { configureStore, combineReducers, Reducer, AnyAction, EnhancedStore } from "@reduxjs/toolkit";
import { Provider } from "react-redux";
import { combineReducers, createStore, Reducer } from "redux";
import { SubAppDef, SubAppFeatureFactory, SubAppFeature, FeatureDecorator } from "@xarc/subapp";

// Re-export necessary modules

//
// re-export redux as Redux etc
//
export * as Redux from "redux";
export { combineReducers, createStore, Reducer, bindActionCreators, applyMiddleware } from "redux";
export * as Redux from "@reduxjs/toolkit";
export { combineReducers, configureStore, Reducer, bindActionCreators } from "@reduxjs/toolkit";

//
// re-export react-redux as ReactRedux etc
//
// Re-export react-redux
export * as ReactRedux from "react-redux";
export { connect, Provider, batch, useSelector, useDispatch, useStore } from "react-redux";

/**
* redux decorator params
* Redux decorator params
*/
export type ReduxDecoratorParams = {
/** initial state */
/** initial state */
initialState: unknown;
/** reducers */
reducers: unknown;
};

/**
* redux decorator result
* Redux decorator result
*/
export type ReduxDecoratorResult = {
/** store if the decorator created one */
store: any;
store: EnhancedStore<any, AnyAction>;
};

/**
Expand All @@ -44,7 +41,7 @@ export type ReduxFeatureDecorator = FeatureDecorator<
>;

/**
* options for redux feature
* Options for redux feature
*/
export type ReduxFeatureOptions = {
/**
Expand All @@ -59,8 +56,7 @@ export type ReduxFeatureOptions = {
* This is needed for the redux feature to wrap subapp's component inside
* the Redux Provider component.
*/
React: Partial<{ createElement: unknown }>;

React: Partial<{ createElement: any }>;
/**
* Configure the redux store to use
*
Expand All @@ -78,8 +74,7 @@ export type ReduxFeatureOptions = {
* - If it's `true`, then the subapp module should export the named reducers as `reduxReducers`
* - If it's a function, then it's used as the reducer
*/
reducers?: Reducer<unknown, any> | Record<string, Reducer<unknown, any>> | boolean;

reducers?: Reducer<any, AnyAction> | Record<string, Reducer<any, AnyAction>> | boolean;
/**
* prepare redux initial state
*
Expand All @@ -88,19 +83,19 @@ export type ReduxFeatureOptions = {
*
* @returns Promise<{initialState: any}>
*/
prepare(initialState: any): Promise<any>;
prepare(initialState: any): Promise<{ initialState: any }>;
};

/**
* redux support for a subapp
* Redux support for a subapp
*/
export type ReduxFeature = SubAppFeature & {
options: ReduxFeatureOptions;
wrap: (_: any) => any;
Provider: typeof Provider;
createStore: typeof createStore;
configureStore: (reducer: Reducer<any, AnyAction>, initialState: any) => EnhancedStore<any, AnyAction>;
prepare: any;
_store: any;
_store?: EnhancedStore<any, AnyAction>;
};

/**
Expand Down Expand Up @@ -128,8 +123,13 @@ export function reduxFeature(options: ReduxFeatureOptions): SubAppFeatureFactory
);
};
redux.Provider = Provider;
redux.createStore = (reducer, initialState) => {
return createStore(reducer || (x => x), initialState);

// Updated configureStore method with correct typing and handling
redux.configureStore = (reducer, initialState) => {
return configureStore({
reducer: reducer || ((state) => state),
preloadedState: initialState,
});
};
redux.prepare = options.prepare;

Expand All @@ -149,9 +149,13 @@ export function reduxFeature(options: ReduxFeatureOptions): SubAppFeatureFactory
if (reducers === true) {
reducers = subapp._module.reduxReducers;
if (typeof reducers === "object") {
reducers = combineReducers(reducers) as Reducer<unknown, any>;
reducers = combineReducers(reducers) as Reducer<any, AnyAction>;
}
redux._store.replaceReducer(reducers);
}

// Ensure reducers is a valid Reducer before calling replaceReducer
if (typeof reducers === "function" || typeof reducers === "object") {
redux._store?.replaceReducer(reducers as Reducer<any, AnyAction>);
}
} else {
const props = csrData && (await csrData.getInitialState());
Expand All @@ -161,34 +165,42 @@ export function reduxFeature(options: ReduxFeatureOptions): SubAppFeatureFactory
}

if (typeof reducers === "object") {
reducers = combineReducers(reducers) as Reducer<unknown, any>;
reducers = combineReducers(reducers) as Reducer<any, AnyAction>;
}

initialState = (await options.prepare(props)).initialState;

if (decorators) {
for (const decor of decorators) {
const { store } = decor.decorate(redux as ReduxFeature, { reducers, initialState });
const { store } = decor.decorate(redux as ReduxFeature, {
reducers,
initialState,
});
if (store) {
redux._store = store;
}
}
}

if (!redux._store) {
redux._store = createStore((reducers as Reducer<unknown, any>) || (x => x), initialState);
const validReducer = (typeof reducers === "function" || typeof reducers === "object")
? reducers
: (state => state);

redux._store = redux.configureStore(validReducer as Reducer<any, AnyAction>, initialState);
}
}

return {
Component: () =>
this.wrap({
Component: input.Component || subapp._getExport()?.Component,
store: redux._store
store: redux._store!,
}),
props: initialState
props: initialState,
};
};

return subapp;
};

Expand Down
Loading

0 comments on commit c22e281

Please sign in to comment.