All files / src/redux store.ts

67.66% Statements 90/133
62.5% Branches 5/8
75% Functions 3/4
67.66% Lines 90/133

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 1341x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x                         2x 2x 1x 1x 1x 1x 1x 1x 1x                                                               1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 33x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
import { configureStore, Middleware, isRejectedWithValue } from "@reduxjs/toolkit";
import { TypedUseSelectorHook, useSelector, useDispatch } from "react-redux";
 
import quickViewReducer from "./features/quickViewSlice";
import cartReducer from "./features/cartSlice";
import wishlistReducer from "./features/wishlistSlice";
import productDetailsReducer from "./features/productDetails";
import supportReducer from "./features/supportSlice";
import notificationsReducer from "./features/notificationsSlice";
 
// ============================================================================
// MIDDLEWARE
// ============================================================================
 
/**
 * Error tracking middleware
 * Logs rejected async thunks for debugging and potential error tracking
 */
const errorTrackingMiddleware: Middleware = () => (next) => (action) => {
  if (isRejectedWithValue(action)) {
    // Log to console in development
    if (process.env.NODE_ENV === "development") {
      console.error("Redux action rejected:", {
        type: action.type,
        payload: action.payload,
        error: action.error,
      });
    }

    // In production, this could send to an error tracking service
    // Example: errorTracker.captureException(action.payload);
  }
  return next(action);
};
 
/**
 * Action logger middleware (development only)
 * Logs actions and state changes for debugging
 */
/* eslint-disable no-console */
const actionLoggerMiddleware: Middleware = (store) => (next) => (action) => {
  if (process.env.NODE_ENV !== "development") {
    return next(action);
  }

  const typedAction = action as { type?: string; payload?: unknown };
  const actionType = typedAction.type;

  // Skip logging for frequent/noisy actions
  const noisyActions = [
    "notifications/fetchNotifications",
    "support/fetchStats",
  ];
  const shouldLog = typeof actionType === "string" && !noisyActions.some((prefix) =>
    actionType.startsWith(prefix)
  );

  if (shouldLog && typeof actionType === "string") {
    console.groupCollapsed(`%c${actionType}`, "color: #8B5CF6; font-weight: bold");
    console.log("Payload:", typedAction.payload);
    console.log("Previous State:", store.getState());
  }

  const result = next(action);

  if (shouldLog && typeof actionType === "string") {
    console.log("Next State:", store.getState());
    console.groupEnd();
  }

  return result;
};
/* eslint-enable no-console */
 
// ============================================================================
// STORE CONFIGURATION
// ============================================================================
 
export const store = configureStore({
  reducer: {
    quickViewReducer,
    cartReducer,
    wishlistReducer,
    productDetailsReducer,
    supportReducer,
    notificationsReducer,
  },
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        // Ignore these action types for serializable check
        ignoredActions: [
          "persist/PERSIST",
          "persist/REHYDRATE",
        ],
        // Ignore these paths in state
        ignoredPaths: [
          "supportReducer.chatbotMessages",
        ],
      },
      // Increase threshold for large state warnings in development
      immutableCheck: process.env.NODE_ENV === "development" ? { warnAfter: 128 } : true,
    }).concat(
      errorTrackingMiddleware,
      ...(process.env.NODE_ENV === "development" ? [actionLoggerMiddleware] : [])
    ),
  devTools: process.env.NODE_ENV !== "production" && {
    name: "Elite Events",
    trace: true,
    traceLimit: 25,
  },
});
 
// ============================================================================
// TYPES
// ============================================================================
 
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
 
// ============================================================================
// HOOKS
// ============================================================================
 
/**
 * Typed useSelector hook
 */
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
 
/**
 * Typed useDispatch hook
 */
export const useAppDispatch = () => useDispatch<AppDispatch>();