Skip to content

Commit 33f8259

Browse files
Implement new listener middleware pattern
1 parent 16b3346 commit 33f8259

File tree

3 files changed

+72
-56
lines changed

3 files changed

+72
-56
lines changed

packages/flow-client/src/app/redux/middleware/flow.middleware.ts

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { createListenerMiddleware, isAnyOf } from '@reduxjs/toolkit';
2+
import type { AppLogic } from '../../logic';
3+
import type { AppDispatch, RootState } from '../../store';
4+
import { flowApi } from '../api/flow.api';
5+
import { flowActions } from './flow.slice';
6+
7+
// Create the Node-RED sync middleware instance
8+
export const createRedListener = (logic: AppLogic) => {
9+
const nodeRedListener = createListenerMiddleware({
10+
extra: logic,
11+
});
12+
13+
return nodeRedListener;
14+
};
15+
16+
export const startRedListener = (
17+
listener: ReturnType<typeof createRedListener>
18+
) => {
19+
// Add a listener that responds to any flow state changes to sync with Node-RED
20+
listener.startListening.withTypes<RootState, AppDispatch, AppLogic>()({
21+
matcher: isAnyOf(
22+
// Flow entity actions
23+
flowActions.addFlowEntity,
24+
flowActions.updateFlowEntity,
25+
flowActions.removeFlowEntity,
26+
flowActions.addFlowEntities,
27+
flowActions.updateFlowEntities,
28+
flowActions.removeFlowEntities,
29+
// Flow node actions
30+
flowActions.addFlowNode,
31+
flowActions.updateFlowNode,
32+
flowActions.removeFlowNode,
33+
flowActions.addFlowNodes,
34+
flowActions.updateFlowNodes,
35+
flowActions.removeFlowNodes
36+
),
37+
effect: async (action, listenerApi) => {
38+
// debounce pattern
39+
listenerApi.cancelActiveListeners();
40+
await listenerApi.delay(1000);
41+
42+
try {
43+
const state = listenerApi.getState();
44+
const logic = listenerApi.extra;
45+
46+
// Convert our state to Node-RED format
47+
const nodeRedFlows = logic.flow.red.toNodeRed(state);
48+
49+
// Update flows in Node-RED
50+
await listenerApi.dispatch(
51+
flowApi.endpoints.updateFlows.initiate(nodeRedFlows)
52+
);
53+
} catch (error) {
54+
// Log any errors but don't crash the app
55+
console.error('Error updating Node-RED flows:', error);
56+
57+
// Could also dispatch an error action if needed:
58+
// listenerApi.dispatch(flowActions.setError('Failed to update Node-RED flows'));
59+
}
60+
},
61+
});
62+
};

packages/flow-client/src/app/redux/store.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Action, configureStore, ThunkAction } from '@reduxjs/toolkit';
22
import { setupListeners } from '@reduxjs/toolkit/query';
33
import {
4-
flowApi } from './modules/api/flow.api';
54
FLUSH,
65
PAUSE,
76
PERSIST,
@@ -11,9 +10,8 @@ import {
1110
REHYDRATE,
1211
} from 'redux-persist';
1312
import storage from 'redux-persist/lib/storage';
14-
1513
import type { AppLogic } from './logic';
16-
import { flowMiddleware } from './middleware/flow.middleware';
14+
import { flowApi } from './modules/api/flow.api';
1715
import { iconApi } from './modules/api/icon.api';
1816
import { nodeApi } from './modules/api/node.api'; // Import the nodeApi
1917
import {
@@ -26,12 +24,18 @@ import {
2624
flowReducer,
2725
FlowState,
2826
} from './modules/flow/flow.slice';
27+
import {
28+
createRedListener,
29+
startRedListener,
30+
} from './modules/flow/red.listener';
2931
import {
3032
PALETTE_NODE_FEATURE_KEY,
3133
paletteNodeReducer,
3234
} from './modules/palette/node.slice';
3335

3436
export const createStore = (logic: AppLogic) => {
37+
const redListener = createRedListener(logic);
38+
3539
const store = configureStore({
3640
reducer: {
3741
[flowApi.reducerPath]: flowApi.reducer,
@@ -73,11 +77,13 @@ export const createStore = (logic: AppLogic) => {
7377
nodeApi.middleware,
7478
iconApi.middleware,
7579
flowApi.middleware,
76-
flowMiddleware),
80+
redListener.middleware
81+
),
7782
devTools: process.env.NODE_ENV !== 'production',
7883
});
7984

8085
setupListeners(store.dispatch);
86+
startRedListener(redListener);
8187

8288
return store;
8389
};

0 commit comments

Comments
 (0)