Skip to content

Commit 162ca61

Browse files
authored
Merge pull request #640 from aabidsofi19/worker-actor
[WIP] Worker actors system
2 parents 601ffe1 + e5d9255 commit 162ca61

File tree

12 files changed

+661
-4
lines changed

12 files changed

+661
-4
lines changed

package-lock.json

Lines changed: 95 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@commitlint/cli": "^17.7.2",
4444
"@commitlint/config-conventional": "^17.7.0",
4545
"@mui/icons-material": "^5.15.11",
46+
"@reduxjs/toolkit": "^2.2.5",
4647
"@testing-library/react": "^14.1.2",
4748
"@types/jest": "^29.5.11",
4849
"@types/react": "^18.2.45",
@@ -76,10 +77,10 @@
7677
"@emotion/styled": "^11.11.0",
7778
"@mui/material": "^5.15.11",
7879
"@types/mui-datatables": "*",
80+
"@xstate/react": "^4.1.1",
7981
"mui-datatables": "*",
8082
"react": ">=17",
8183
"react-dom": ">=17",
82-
"@xstate/react": "^4.1.1",
8384
"xstate": "^5.13.0"
8485
},
8586
"peerDependenciesMeta": {

src/actors/index.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,28 @@ export {
88
selectValidationResults
99
} from './validators/dataValidator';
1010

11+
export * from './worker';
12+
13+
export {
14+
REDUX_COMMANDS,
15+
REDUX_EVENTS,
16+
reduxActor,
17+
reduxCommands,
18+
reduxEvents,
19+
type REXUX_ACTOR_EVENTS
20+
} from './reduxActor';
21+
22+
export {
23+
RTK_EVENTS,
24+
rtkQueryActor,
25+
rtkQueryActorCommands,
26+
rtkQueryActorEvents
27+
} from './rtkQueryActor';
28+
29+
export const REEE = 'xxx';
30+
1131
export {
32+
DeferEvents,
1233
XSTATE_DEBUG_EVENT,
1334
deadLetter,
1435
forwardToActors,

src/actors/reduxActor.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { assertEvent, sendTo, setup } from 'xstate';
2+
3+
import { Selector, Store, UnknownAction } from '@reduxjs/toolkit';
4+
5+
interface ReduxActorContext {
6+
store: Store;
7+
selectors: {
8+
[key: string]: Selector;
9+
};
10+
}
11+
12+
/* eslint-disable @typescript-eslint/no-explicit-any */
13+
type extraArgs = any[];
14+
15+
export const REDUX_COMMANDS = {
16+
DISPATCH: 'DISPATCH',
17+
GET_STATE: 'GET_STATE',
18+
GET_STATE_FROM_SELECTOR: 'GET_STATE_FROM_SELECTOR',
19+
SUBSCRIBE: 'SUBSCRIBE',
20+
UNSUBSCRIBE: 'UNSUBSCRIBE'
21+
};
22+
23+
export const REDUX_EVENTS = {
24+
REDUX_STATE_SNAPSHOT: 'REDUX_STATE_SNAPSHOT'
25+
};
26+
27+
export type REXUX_ACTOR_EVENTS =
28+
| { type: 'DISPATCH'; data: { action: UnknownAction } }
29+
| { type: 'SUBSCRIBE' }
30+
| { type: 'UNSUBSCRIBE' }
31+
| { type: 'REDUX_STATE_SNAPSHOT'; data: { snapshot: unknown } }
32+
| { type: 'GET_STATE'; returnAddress: string; data: { key: string } }
33+
| {
34+
type: 'GET_STATE_FROM_SELECTOR';
35+
returnAddress: string;
36+
data: { selector: string; extraArgs?: extraArgs };
37+
};
38+
39+
export const reduxEvents = {
40+
stateSnapshot: (snapshot: unknown) => ({
41+
type: 'STATE_SNAPSHOT',
42+
data: { snapshot }
43+
})
44+
};
45+
46+
export const reduxCommands = {
47+
dispatch: (action: UnknownAction) => ({
48+
type: 'DISPATCH',
49+
data: { action }
50+
}),
51+
52+
getState: (key: string, returnAddress: string) => ({
53+
type: 'GET_STATE',
54+
returnAddress,
55+
data: { key }
56+
}),
57+
58+
getStateFromSelector: (selector: string, returnAddress: string, extraArgs?: extraArgs) => ({
59+
type: 'GET_STATE_FROM_SELECTOR',
60+
returnAddress,
61+
data: { selector, extraArgs }
62+
})
63+
};
64+
65+
export const reduxActor = setup({
66+
types: {
67+
context: {} as ReduxActorContext,
68+
input: {} as ReduxActorContext,
69+
events: {} as REXUX_ACTOR_EVENTS
70+
}
71+
}).createMachine({
72+
initial: 'idle',
73+
context: ({ input }) => input,
74+
states: {
75+
idle: {
76+
on: {
77+
DISPATCH: {
78+
actions: [({ event, context }) => context.store.dispatch(event.data.action)]
79+
},
80+
GET_STATE_FROM_SELECTOR: {
81+
actions: sendTo(
82+
({ event }) => event.returnAddress,
83+
({ context, event }) => {
84+
assertEvent(event, 'GET_STATE_FROM_SELECTOR');
85+
const selector = context.selectors[event.data.selector];
86+
const snapshot = selector(context.store.getState(), ...(event.data.extraArgs || []));
87+
return reduxEvents.stateSnapshot(snapshot);
88+
}
89+
)
90+
}
91+
}
92+
}
93+
}
94+
});

0 commit comments

Comments
 (0)