Redux utility library providing clean APIs for reducers, action types, action creators, and state reset functionality
npx @tessl/cli install tessl/npm-reduxsauce@2.0.0ReduxSauce provides aesthetic toppings for your Redux meal - clean, maintainable utilities that reduce boilerplate and improve readability in Redux applications. It offers four core utilities: createReducer for decluttering reducers, createTypes for DRY action type creation, createActions for simultaneous type and creator generation, and resettableReducer for higher-order state reset functionality.
npm install reduxsauceimport { createReducer, createTypes, createActions, resettableReducer, Types } from "reduxsauce";For CommonJS:
const { createReducer, createTypes, createActions, resettableReducer, Types } = require("reduxsauce");import { createReducer, createTypes, createActions, resettableReducer } from "reduxsauce";
// Create action types from a string
const Types = createTypes(`
LOGIN_REQUEST
LOGIN_SUCCESS
LOGIN_FAILURE
LOGOUT
`);
// Create both types and action creators
const { Types: ActionTypes, Creators } = createActions({
loginRequest: ['username', 'password'],
loginSuccess: ['user'],
loginFailure: ['error'],
logout: null
});
// Create a clean reducer
const INITIAL_STATE = { user: null, loading: false, error: null };
const loginSuccess = (state, action) => ({
...state,
user: action.user,
loading: false,
error: null
});
const loginFailure = (state, action) => ({
...state,
loading: false,
error: action.error
});
const reducer = createReducer(INITIAL_STATE, {
[ActionTypes.LOGIN_SUCCESS]: loginSuccess,
[ActionTypes.LOGIN_FAILURE]: loginFailure
});
// Make reducer resettable
const resettableAuthReducer = resettableReducer('RESET_AUTH', reducer);ReduxSauce is built around four key utilities that work together:
Generate Redux action type constants from whitespace-separated strings with optional prefixing.
/**
* Creates action type constants from a whitespace-separated string
* @param types - String containing whitespace-separated action names
* @param options - Optional configuration object
* @returns Object mapping type names to their string values
*/
function createTypes(types, options);
interface Options {
prefix?: string; // Prepends to all created types
}Usage Examples:
import { createTypes } from "reduxsauce";
// Basic usage
const Types = createTypes(`
LOGIN_REQUEST
LOGIN_SUCCESS
LOGIN_FAILURE
LOGOUT
`);
// Result: { LOGIN_REQUEST: 'LOGIN_REQUEST', LOGIN_SUCCESS: 'LOGIN_SUCCESS', ... }
// With prefix
const Types = createTypes('FETCH_USER UPDATE_USER', { prefix: 'AUTH_' });
// Result: { FETCH_USER: 'AUTH_FETCH_USER', UPDATE_USER: 'AUTH_UPDATE_USER' }Create both action types and action creators simultaneously with automatic type conversion and flexible parameter handling.
/**
* Creates both action types and action creators simultaneously
* @param config - Configuration object defining actions
* @param options - Optional configuration object
* @returns Object with Types and Creators properties
*/
function createActions(config, options);
interface CreatedActions {
Types: ActionTypes;
Creators: ActionCreators;
}
interface Options {
prefix?: string; // Prepends to all created types
}Config Value Types:
null: Creates type-only action creatorArray: Creates action creator with named parametersObject: Creates action creator with default valuesFunction: Uses custom action creator functionUsage Examples:
import { createActions } from "reduxsauce";
const { Types, Creators } = createActions({
// Type-only action
logout: null,
// Action with parameters
loginRequest: ['username', 'password'],
// Action with default values
updateSettings: { theme: 'light', notifications: true },
// Custom action creator
complexAction: (data, meta) => ({
type: 'COMPLEX_ACTION',
payload: data,
meta
})
});
// Usage
Creators.logout(); // { type: 'LOGOUT' }
Creators.loginRequest('user', 'pass'); // { type: 'LOGIN_REQUEST', username: 'user', password: 'pass' }
Creators.updateSettings({ theme: 'dark' }); // { type: 'UPDATE_SETTINGS', theme: 'dark', notifications: true }Create clean Redux reducers using object maps instead of switch statements, with support for default handlers.
/**
* Creates a Redux reducer from initial state and action handlers
* @param initialState - The initial state for this reducer
* @param handlers - Map of action types to handler functions
* @returns Redux reducer function
*/
function createReducer(initialState, handlers);
interface Handlers {
[actionType: string]: (state, action) => newState;
}Usage Examples:
import { createReducer, Types } from "reduxsauce";
const INITIAL_STATE = { count: 0, error: null };
// Handler functions
const increment = (state, action) => ({
...state,
count: state.count + (action.amount || 1)
});
const decrement = (state, action) => ({
...state,
count: state.count - (action.amount || 1)
});
const setError = (state, action) => ({
...state,
error: action.error
});
// Default handler for unmatched actions
const defaultHandler = (state, action) => {
console.log('Unhandled action:', action.type);
return state;
};
const reducer = createReducer(INITIAL_STATE, {
INCREMENT: increment,
DECREMENT: decrement,
SET_ERROR: setError,
[Types.DEFAULT]: defaultHandler // Special default handler
});Higher-order reducer that wraps existing reducers with reset capability, supporting both curried and direct usage patterns.
/**
* Creates a higher-order reducer that resets state on specific action
* @param typeToReset - Action type that triggers reset
* @param originalReducer - Optional original reducer to wrap (when not currying)
* @returns Enhanced reducer or curried function
*/
function resettableReducer(typeToReset, originalReducer);Usage Examples:
import { resettableReducer } from "reduxsauce";
// Curried usage - create resetter function first
const resetter = resettableReducer('RESET_AUTH');
const authReducer = (state = { user: null }, action) => {
// ... reducer logic
};
const resettableAuthReducer = resetter(authReducer);
// Direct usage - pass both parameters
const directResettableReducer = resettableReducer('RESET_STATE', myReducer);
// In combineReducers
import { combineReducers } from 'redux';
export default combineReducers({
auth: resettableReducer('RESET_AUTH')(authReducer),
profile: resettableReducer('RESET_PROFILE')(profileReducer),
settings: settingsReducer // not resettable
});// Pre-defined constants
const Types = {
DEFAULT: 'REDUXSAUCE.DEFAULT' // Used for default handlers in createReducer
};
// TypeScript interfaces (when using TypeScript)
interface Actions {
[action: string]: string[] | ActionTypes | ActionCreator | null;
}
interface ActionTypes {
[action: string]: string | number | DefaultActionTypes | null;
}
interface DefaultActionTypes {
[action: string]: string;
}
interface DefaultActionCreators {
[action: string]: (...args: any[]) => UnknownAction;
}
interface Handlers<S> {
[type: string]: (state: S, action: any) => S;
}
interface CreatedActions<T = DefaultActionTypes, C = DefaultActionCreators> {
Types: T;
Creators: C;
}ReduxSauce validates inputs and throws descriptive errors:
Common error patterns:
// These will throw errors
createTypes(''); // Error: valid types are required
createActions({}); // Error: empty objects are not supported
createReducer(undefined, {}); // Error: initial state is required
resettableReducer('', myReducer); // Error: A valid reset type is required