Skip to content

Commit c687fb0

Browse files
committed
wip 5: remove action namespaces
1 parent 029545e commit c687fb0

File tree

11 files changed

+125
-135
lines changed

11 files changed

+125
-135
lines changed

devtools/client/src/redux/actions.ts

Lines changed: 0 additions & 83 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Events } from '@player-tools/devtools-common';
2+
import { ActionCreatorWithPayload, createAction } from '@reduxjs/toolkit';
3+
import { AnyAction } from 'redux';
4+
5+
/** Redux actions associated against all possible event types */
6+
type EventActions = {
7+
[key in Events.EventTypes]: ActionCreatorWithPayload<Events.ByType<key>, key>;
8+
};
9+
10+
/** Redux actions associated against all defined event types */
11+
export const Actions: EventActions = Object.fromEntries(
12+
Events.EventTypes.map((event) => [
13+
event,
14+
createAction<Events.ByType<typeof event>>(event),
15+
])
16+
) as EventActions;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { createAction } from '@reduxjs/toolkit';
2+
import type { Events } from '@player-tools/devtools-common';
3+
4+
export { Actions as EventActions } from './events';
5+
export * from './methods';
6+
7+
/** Explicit actions that don't correspond to a specific event or method */
8+
export const Actions = {
9+
// Explicit actions TODO: Is this level of redundancy okay?
10+
'selected-player': createAction<string | undefined>('selected-player'),
11+
'player-timeline-event': createAction<Events.TimelineEvents>(
12+
'player-timeline-event'
13+
),
14+
15+
// Reset actions
16+
'clear-selected-data-details': createAction('clear-selected-data-details'),
17+
'clear-console': createAction('clear-console'),
18+
'clear-logs': createAction('clear-logs'),
19+
'clear-store': createAction('clear-store'),
20+
};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {
2+
BACKGROUND_SOURCE,
3+
createLogger,
4+
Methods,
5+
} from '@player-tools/devtools-common';
6+
import { createAsyncThunk, type AsyncThunk } from '@reduxjs/toolkit';
7+
8+
const logger = createLogger(BACKGROUND_SOURCE);
9+
10+
/** Type describing an object containing async thunks for each Method defined */
11+
export type MethodThunks = {
12+
[key in Methods.Method['type']]: AsyncThunk<
13+
Methods.ByType<key>['result'],
14+
Methods.ByType<key>,
15+
any
16+
>;
17+
};
18+
19+
/** Signature for handling method requests */
20+
export type MethodHandler = <T extends Methods.MethodTypes>(
21+
method: Methods.ByType<T>
22+
) => Promise<Methods.ByType<T>['result']>;
23+
24+
/** Utility for building async thunks for all known method types */
25+
export const buildMethodThunks = (
26+
onMethodRequest: MethodHandler
27+
): MethodThunks =>
28+
Object.fromEntries(
29+
Methods.MethodTypes.map((method) => [
30+
method,
31+
createAsyncThunk<
32+
Methods.ByType<typeof method>['result'],
33+
Methods.ByType<typeof method>
34+
>(method, async (method) => {
35+
logger.log(`Requesting ${method.type}`, method.params);
36+
const data = (await onMethodRequest(method)) as Methods.ByType<
37+
typeof method.type
38+
>['result'];
39+
logger.log(`Response from ${method.type}`, data);
40+
return data;
41+
}),
42+
])
43+
) as MethodThunks;

devtools/client/src/redux/aliases.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Methods as RuntimeMethods, RUNTIME_SOURCE } from '@player-tools/devtools-common';
2-
import { Methods } from './actions';
1+
import { Methods as Methods, RUNTIME_SOURCE } from '@player-tools/devtools-common';
2+
import { MethodThunks } from './actions/methods';
33

44
export const GET_INFO_DETAILS = 'GET_INFO_DETAILS';
55
export const GET_CONFIG_DETAILS = 'GET_CONFIG_DETAILS';
@@ -10,8 +10,8 @@ export const START_PROFILER = 'START_PROFILER';
1010
export const STOP_PROFILER = 'STOP_PROFILER';
1111

1212

13-
export interface MethodAction<T extends RuntimeMethods.MethodTypes> {
14-
payload: RuntimeMethods.ByType<T>['params'];
13+
interface MethodAction<T extends Methods.MethodTypes> {
14+
payload: Methods.ByType<T>['params'];
1515
}
1616

1717
// Copied from webext redux library not allowed in flipper
@@ -26,13 +26,13 @@ const _alias = (aliases: any) => () => (next: any) => (action: any) => {
2626
};
2727

2828
/** Helper for building corresponding method action via supplied thunks */
29-
const alias = <T extends RuntimeMethods.MethodTypes>(type: T, methods: Methods.MethodThunks) => (action: MethodAction<T>) => methods[type]({
29+
const alias = <T extends Methods.MethodTypes>(type: T, methods: MethodThunks) => (action: MethodAction<T>) => methods[type]({
3030
type,
3131
params: action.payload,
3232
source: RUNTIME_SOURCE,
33-
} as RuntimeMethods.ByType<T>)
33+
} as Methods.ByType<T>)
3434

35-
export const buildAliases = (methods: Methods.MethodThunks) =>
35+
export const buildAliases = (methods: MethodThunks) =>
3636
_alias({
3737
GET_INFO_DETAILS: alias('player-runtime-info-request', methods),
3838
GET_CONFIG_DETAILS: alias('player-config-request', methods),
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { Events } from "@player-tools/devtools-common";
22
import { Dispatch } from "redux";
3-
import { Events as EventActions } from "./actions";
3+
import { EventActions } from "./actions";
44

55
/** Utility method to filter known events from a supplied message and dispatch the corresponding action */
66
export const dispatchEvents = (dispatch: Dispatch) => (message: any) => {
7-
if (Events.isEvent(message)) dispatch(EventActions.actions[message.type](message as any))
7+
if (Events.isEvent(message)) dispatch(EventActions[message.type](message as any))
88
}

devtools/client/src/redux/middleware.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createListenerMiddleware, isAnyOf } from "@reduxjs/toolkit";
2-
import { Actions, Events } from "./actions";
2+
import { Actions, EventActions } from "./actions";
33
import { GET_DATA_BINDING_DETAILS } from "./aliases";
44
import { type StoreState } from './state';
55

@@ -11,27 +11,26 @@ export const listenerMiddleware = createListenerMiddleware<StoreState>();
1111

1212
listenerMiddleware.startListening({
1313
matcher: isAnyOf(
14-
Events.actions['player-data-change-event'],
15-
Events.actions['player-log-event'],
16-
Events.actions['player-flow-start'],
14+
EventActions['player-data-change-event'],
15+
EventActions['player-log-event'],
16+
EventActions['player-flow-start'],
1717
),
1818
effect: (action, api) => {
1919
api.dispatch(Actions['player-timeline-event'](action.payload));
2020
},
2121
});
2222

2323
listenerMiddleware.startListening({
24-
actionCreator: Events.actions['runtime-init'],
24+
actionCreator: EventActions['runtime-init'],
2525
effect: (_, api) => {
26-
console.log("um")
2726
api.dispatch(Actions["clear-store"]())
2827
}
2928
})
3029

3130
listenerMiddleware.startListening({
3231
matcher: isAnyOf(
33-
Events.actions["player-init"],
34-
Events.actions["player-removed"],
32+
EventActions["player-init"],
33+
EventActions["player-removed"],
3534
),
3635
effect: (_, api) => {
3736
api.dispatch(Actions["selected-player"]())
@@ -40,8 +39,8 @@ listenerMiddleware.startListening({
4039

4140
listenerMiddleware.startListening({
4241
matcher: isAnyOf(
43-
Events.actions["player-flow-start"],
44-
Events.actions["player-data-change-event"],
42+
EventActions["player-flow-start"],
43+
EventActions["player-data-change-event"],
4544
),
4645
effect: (action, api) => {
4746
const { players } = api.getState();

devtools/client/src/redux/reducers.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import { ActionReducerMapBuilder, createReducer } from '@reduxjs/toolkit';
1+
import { type ActionReducerMapBuilder, createReducer } from '@reduxjs/toolkit';
22
import type { PlayersState } from './state';
3-
import { Actions, Events, Methods } from './actions';
3+
import { Actions, EventActions, type MethodThunks } from './actions';
44

55
const initialState = {
66
selectedPlayerId: null,
77
activePlayers: {},
88
} as PlayersState;
99

10-
// TODO: It'd be nice if methodThunks didn't have to be passed in - but it is kinda client dependent
11-
export const methodsReducer = (methods: Methods.MethodThunks) => (builder: ActionReducerMapBuilder<PlayersState>) => {
10+
const methodsReducer = (methods: MethodThunks) => (builder: ActionReducerMapBuilder<PlayersState>) => {
1211
builder.addCase(
1312
methods['player-runtime-info-request'].fulfilled,
1413
(state, action) => {
@@ -116,8 +115,8 @@ export const methodsReducer = (methods: Methods.MethodThunks) => (builder: Actio
116115
);
117116
};
118117

119-
export const eventsReducer = (builder: ActionReducerMapBuilder<PlayersState>) => {
120-
builder.addCase(Events.actions['player-init'], (state, action) => {
118+
const eventsReducer = (builder: ActionReducerMapBuilder<PlayersState>) => {
119+
builder.addCase(EventActions['player-init'], (state, action) => {
121120
const {
122121
payload: { version, playerID },
123122
} = action;
@@ -129,11 +128,11 @@ export const eventsReducer = (builder: ActionReducerMapBuilder<PlayersState>) =>
129128
state.version = version;
130129
});
131130

132-
builder.addCase(Events.actions['player-removed'], (state, action) => {
131+
builder.addCase(EventActions['player-removed'], (state, action) => {
133132
delete state.activePlayers[action.payload.playerID];
134133
});
135134

136-
builder.addCase(Events.actions['player-flow-start'], (state, action) => {
135+
builder.addCase(EventActions['player-flow-start'], (state, action) => {
137136
const {
138137
payload: { flow, playerID },
139138
} = action;
@@ -155,7 +154,7 @@ export const eventsReducer = (builder: ActionReducerMapBuilder<PlayersState>) =>
155154
};
156155
});
157156

158-
builder.addCase(Events.actions['player-view-update-event'], (state, action) => {
157+
builder.addCase(EventActions['player-view-update-event'], (state, action) => {
159158
const {
160159
payload: { playerID, update },
161160
} = action;
@@ -175,7 +174,7 @@ export const eventsReducer = (builder: ActionReducerMapBuilder<PlayersState>) =>
175174
});
176175
};
177176

178-
export const actionsReducer = (builder: ActionReducerMapBuilder<PlayersState>) => {
177+
const actionsReducer = (builder: ActionReducerMapBuilder<PlayersState>) => {
179178
builder.addCase(Actions['selected-player'], (state, action) => {
180179
if (action.payload) {
181180
state.selectedPlayerId = action.payload;
@@ -240,7 +239,7 @@ export const actionsReducer = (builder: ActionReducerMapBuilder<PlayersState>) =
240239
});
241240
};
242241

243-
export const playersReducer = (methods: Methods.MethodThunks) =>
242+
export const playersReducer = (methods: MethodThunks) =>
244243
createReducer<PlayersState>(initialState, (builder) => {
245244
actionsReducer(builder)
246245
eventsReducer(builder)

devtools/client/src/redux/store.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@ import {
77
ReducersMapObject,
88
} from '@reduxjs/toolkit';
99
import { StoreState } from './state';
10-
import { Methods } from './actions';
10+
import {
11+
type MethodThunks,
12+
type MethodHandler,
13+
buildMethodThunks,
14+
} from './actions';
1115
import { playersReducer } from './reducers';
1216
import { listenerMiddleware } from './middleware';
1317
import { buildAliases } from './aliases';
1418

1519
const createStore = (
16-
methodThunks: Methods.MethodThunks,
20+
methodThunks: MethodThunks,
1721
middleware?: Middleware<any, StoreState, Dispatch<AnyAction>>,
1822
reducers?: ReducersMapObject<StoreState, AnyAction>
1923
): EnhancedStore<
@@ -30,9 +34,9 @@ const createStore = (
3034
middleware: (getDefaultMiddleware) => {
3135
const m = getDefaultMiddleware()
3236
.prepend(buildAliases(methodThunks))
33-
.concat(listenerMiddleware.middleware)
37+
.concat(listenerMiddleware.middleware);
3438

35-
if (middleware) m.concat(middleware)
39+
if (middleware) m.concat(middleware);
3640

3741
return m;
3842
},
@@ -46,11 +50,16 @@ const createStore = (
4650
*/
4751
// TODO: Turn into store enhancer? Maybe remove middleware and additionalReducers?
4852
export const createDevtoolsStore = (
49-
onMethodRequest: Methods.MethodHandler,
53+
onMethodRequest: MethodHandler,
5054
middleware?: Middleware<any, StoreState, Dispatch<AnyAction>>,
5155
additionalReducers?: any
5256
): EnhancedStore<
5357
StoreState,
5458
any,
5559
Middleware<any, StoreState, Dispatch<AnyAction>>[]
56-
> => createStore(Methods.buildAsyncThunks(onMethodRequest), middleware, additionalReducers)
60+
> =>
61+
createStore(
62+
buildMethodThunks(onMethodRequest),
63+
middleware,
64+
additionalReducers
65+
);

0 commit comments

Comments
 (0)