Skip to content

Commit e60b74c

Browse files
authored
navigate from react-router available in redux-saga context (#922)
1 parent efb802b commit e60b74c

File tree

8 files changed

+27
-12
lines changed

8 files changed

+27
-12
lines changed

bootstrap/src/component/Entrypoint.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const Sink = (props) => {
1919
return <Module name={entrypoint}>{children}</Module>;
2020
};
2121

22-
const router = createBrowserRouter([{ path: "*", element: <Sink />, errorElement: <Yank /> }], { basename: "/" });
22+
export const router = createBrowserRouter([{ path: "*", element: <Sink />, errorElement: <Yank /> }], { basename: "/" });
2323

2424
const Entrypoint = (props) => {
2525
const entrypoint = useSelector(getEntrypoint);

bootstrap/src/component/Main.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { constants, getStore, manualCleanup } from "@lastui/rocker/platform";
88
import { getIsInitialized, getLanguage } from "../selector";
99
import setupStore from "../store";
1010

11-
import Entrypoint from "./Entrypoint";
11+
import Entrypoint, { router } from "./Entrypoint";
1212
import Globalisation from "./Globalisation";
1313

1414
const FullyInitializedGate = (props) => {
@@ -27,7 +27,7 @@ const Main = (props) => {
2727

2828
const manualInit = useCallback(() => {
2929
try {
30-
const store = setupStore(props.fetchContext, props.reduxMiddlewares);
30+
const store = setupStore(router, props.fetchContext, props.reduxMiddlewares);
3131
store.dispatch({
3232
type: constants.SET_LANGUAGE,
3333
payload: {

bootstrap/src/component/__tests__/Main.test.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const mockStore = configureStore([])((actions) => {
4747

4848
setStore(mockStore);
4949

50-
jest.mock("../../store", () => (fetchContext) => {
50+
jest.mock("../../store", () => (_router, fetchContext, _bootstrapMiddlewares) => {
5151
fetchContext();
5252
return mockStore;
5353
});

bootstrap/src/store/__test__/index.test.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,26 @@ import setupStore from "..";
33
describe("store", () => {
44
const ORIGINAL_NODE_ENV = process.env.NODE_ENV;
55

6+
const fetchContext = jest.fn();
7+
const mockRouter = { navigate: jest.fn() };
8+
9+
beforeAll(() => {
10+
mockRouter.navigate.mockClear();
11+
fetchContext.mockClear();
12+
});
13+
614
afterAll(() => {
715
process.env.NODE_ENV = ORIGINAL_NODE_ENV;
816
delete top.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
917
delete global.BUILD_ID;
1018
});
1119

1220
it("initialises properly", async () => {
13-
const fetchContext = jest.fn();
14-
const store = await setupStore(fetchContext);
21+
const store = await setupStore(mockRouter, fetchContext);
1522
expect(store).toBeDefined();
23+
24+
expect(fetchContext).toHaveBeenCalled();
25+
expect(mockRouter.navigate).toHaveBeenCalled();
1626
});
1727

1828
it("accepts middlewares provided via bootstrap", async () => {
@@ -21,8 +31,7 @@ describe("store", () => {
2131
spy(action);
2232
return next(action);
2333
};
24-
const fetchContext = jest.fn();
25-
const store = await setupStore(fetchContext, [customMiddleware]);
34+
const store = await setupStore(mockRouter, fetchContext, [customMiddleware]);
2635
expect(store).toBeDefined();
2736

2837
const action = { type: "test-probe" };
@@ -36,7 +45,7 @@ describe("store", () => {
3645
top.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__.mockReturnValue(() => {});
3746
process.env.NODE_ENV = "development";
3847
const fetchContext = jest.fn();
39-
const store = await setupStore(fetchContext, []);
48+
const store = await setupStore(mockRouter, fetchContext, []);
4049
expect(store).toBeDefined();
4150
expect(top.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__).toHaveBeenCalledWith(expect.objectContaining({ name: "rocker-xxx" }));
4251
});

bootstrap/src/store/index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@ import {
1515
import { runtimeReducer } from "../reducer";
1616
import { watchRefresh, watchFetchContext, watchBootstrap } from "../saga";
1717

18-
export default (fetchContext, bootstrapMiddlewares) => {
18+
export default (router, fetchContext, bootstrapMiddlewares) => {
1919
const dynamicMiddleware = createDynamicMiddleware();
2020
const loaderMiddleware = createLoaderMiddleware();
2121
const { sagaMiddleware, runSaga } = createSagaMiddleware({
2222
context: {
23+
async navigate(to, options) {
24+
await router.navigate(to, options);
25+
},
2326
async fetchContext() {
2427
const ctx = await fetchContext();
2528
return {

jest/__mocks__/platform.js

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ module.exports = {
4646
if (options?.context?.fetchContext) {
4747
options.context.fetchContext();
4848
}
49+
if (options?.context?.navigate) {
50+
options.context.navigate();
51+
}
4952
const channel = ReduxSaga.stdChannel();
5053
return {
5154
sagaMiddleware: (_store) => (next) => (action) => next(action),

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lastui/rocker",
3-
"version": "0.19.18",
3+
"version": "0.19.19",
44
"license": "Apache-2.0",
55
"author": "[email protected]",
66
"homepage": "https://github.com/lastui/rocker#readme",

webpack/config/module/development.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ config.plugins.push(
284284
fragment._source._sourceMapAsObject.sourcesContent.forEach((sourceCode) => {
285285
const ast = parser.parse(sourceCode, {
286286
sourceType: "module",
287-
plugins: ["jsx"],
287+
plugins: ["jsx", "typescript"],
288288
});
289289

290290
traverse(ast, {

0 commit comments

Comments
 (0)