github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/webapp/javascript/redux/store.ts (about)

     1  import {
     2    persistStore,
     3    persistReducer,
     4    FLUSH,
     5    REHYDRATE,
     6    PAUSE,
     7    PERSIST,
     8    PURGE,
     9    REGISTER,
    10  } from 'redux-persist';
    11  
    12  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    13  // @ts-ignore: Until we rewrite FlamegraphRenderer in typescript this will do
    14  import ReduxQuerySync from 'redux-query-sync';
    15  import { configureStore, combineReducers, Middleware } from '@reduxjs/toolkit';
    16  
    17  import history from '../util/history';
    18  
    19  import settingsReducer from './reducers/settings';
    20  import userReducer from './reducers/user';
    21  import continuousReducer, {
    22    actions as continuousActions,
    23  } from './reducers/continuous';
    24  import tracingReducer, { actions as tracingActions } from './reducers/tracing';
    25  import serviceDiscoveryReducer from './reducers/serviceDiscovery';
    26  import adhocReducer from './reducers/adhoc';
    27  import uiStore, { persistConfig as uiPersistConfig } from './reducers/ui';
    28  
    29  const reducer = combineReducers({
    30    settings: settingsReducer,
    31    user: userReducer,
    32    serviceDiscovery: serviceDiscoveryReducer,
    33    ui: persistReducer(uiPersistConfig, uiStore),
    34    continuous: continuousReducer,
    35    tracing: tracingReducer,
    36    adhoc: adhocReducer,
    37  });
    38  
    39  // Most times we will display a (somewhat) user friendly message toast
    40  // But it's still useful to have the actual error logged to the console
    41  export const logErrorMiddleware: Middleware = () => (next) => (action) => {
    42    next(action);
    43    if (action?.error) {
    44      console.error(action.error);
    45    }
    46  };
    47  
    48  const store = configureStore({
    49    reducer,
    50    // https://github.com/reduxjs/redux-toolkit/issues/587#issuecomment-824927971
    51    middleware: (getDefaultMiddleware) =>
    52      getDefaultMiddleware({
    53        serializableCheck: {
    54          ignoredActionPaths: ['error'],
    55  
    56          // Based on this issue: https://github.com/rt2zz/redux-persist/issues/988
    57          // and this guide https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist
    58          ignoredActions: [
    59            FLUSH,
    60            REHYDRATE,
    61            PAUSE,
    62            PERSIST,
    63            PURGE,
    64            REGISTER,
    65            'adhoc/uploadFile/pending',
    66            'adhoc/uploadFile/fulfilled',
    67          ],
    68        },
    69      }).concat([logErrorMiddleware]),
    70  });
    71  
    72  export const persistor = persistStore(store);
    73  
    74  // This is a bi-directional sync between the query parameters and the redux store
    75  // It works as follows:
    76  // * When URL query changes, It will dispatch the action
    77  // * When the store changes (the field set in selector), the query param is updated
    78  // For more info see the implementation at
    79  // https://github.com/Treora/redux-query-sync/blob/master/src/redux-query-sync.js
    80  ReduxQuerySync({
    81    store,
    82    params: {
    83      from: {
    84        defaultValue: 'now-1h',
    85        selector: (state: RootState) => state.continuous.from,
    86        action: continuousActions.setFrom,
    87      },
    88      until: {
    89        defaultValue: 'now',
    90        selector: (state: RootState) => state.continuous.until,
    91        action: continuousActions.setUntil,
    92      },
    93      leftFrom: {
    94        defaultValue: 'now-1h',
    95        selector: (state: RootState) => state.continuous.leftFrom,
    96        action: continuousActions.setLeftFrom,
    97      },
    98      leftUntil: {
    99        defaultValue: 'now-30m',
   100        selector: (state: RootState) => state.continuous.leftUntil,
   101        action: continuousActions.setLeftUntil,
   102      },
   103      rightFrom: {
   104        defaultValue: 'now-30m',
   105        selector: (state: RootState) => state.continuous.rightFrom,
   106        action: continuousActions.setRightFrom,
   107      },
   108      rightUntil: {
   109        defaultValue: 'now',
   110        selector: (state: RootState) => state.continuous.rightUntil,
   111        action: continuousActions.setRightUntil,
   112      },
   113      query: {
   114        defaultvalue: '',
   115        selector: (state: RootState) => state.continuous.query,
   116        action: continuousActions.setQuery,
   117      },
   118      queryID: {
   119        defaultvalue: '',
   120        selector: (state: RootState) => state.tracing.queryID,
   121        action: tracingActions.setQueryID,
   122      },
   123      rightQuery: {
   124        defaultvalue: '',
   125        selector: (state: RootState) => state.continuous.rightQuery,
   126        action: continuousActions.setRightQuery,
   127      },
   128      leftQuery: {
   129        defaultvalue: '',
   130        selector: (state: RootState) => state.continuous.leftQuery,
   131        action: continuousActions.setLeftQuery,
   132      },
   133      maxNodes: {
   134        defaultValue: '0',
   135        selector: (state: RootState) => state.continuous.maxNodes,
   136        action: continuousActions.setMaxNodes,
   137      },
   138      groupBy: {
   139        defaultValue: '',
   140        selector: (state: RootState) =>
   141          state.continuous.tagExplorerView.groupByTag,
   142        action: continuousActions.setTagExplorerViewGroupByTag,
   143      },
   144      groupByValue: {
   145        defaultValue: '',
   146        selector: (state: RootState) =>
   147          state.continuous.tagExplorerView.groupByTagValue,
   148        action: continuousActions.setTagExplorerViewGroupByTagValue,
   149      },
   150    },
   151    initialTruth: 'location',
   152    replaceState: false,
   153    history,
   154  });
   155  export default store;
   156  
   157  // Infer the `RootState` and `AppDispatch` types from the store itself
   158  export type RootState = ReturnType<typeof store.getState>;
   159  // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
   160  export type AppDispatch = typeof store.dispatch;