0
# ReduxSauce
1
2
ReduxSauce 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.
3
4
## Package Information
5
6
- **Package Name**: reduxsauce
7
- **Package Type**: npm
8
- **Language**: JavaScript (with TypeScript definitions)
9
- **Installation**: `npm install reduxsauce`
10
11
## Core Imports
12
13
```javascript
14
import { createReducer, createTypes, createActions, resettableReducer, Types } from "reduxsauce";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { createReducer, createTypes, createActions, resettableReducer, Types } = require("reduxsauce");
21
```
22
23
## Basic Usage
24
25
```javascript
26
import { createReducer, createTypes, createActions, resettableReducer } from "reduxsauce";
27
28
// Create action types from a string
29
const Types = createTypes(`
30
LOGIN_REQUEST
31
LOGIN_SUCCESS
32
LOGIN_FAILURE
33
LOGOUT
34
`);
35
36
// Create both types and action creators
37
const { Types: ActionTypes, Creators } = createActions({
38
loginRequest: ['username', 'password'],
39
loginSuccess: ['user'],
40
loginFailure: ['error'],
41
logout: null
42
});
43
44
// Create a clean reducer
45
const INITIAL_STATE = { user: null, loading: false, error: null };
46
47
const loginSuccess = (state, action) => ({
48
...state,
49
user: action.user,
50
loading: false,
51
error: null
52
});
53
54
const loginFailure = (state, action) => ({
55
...state,
56
loading: false,
57
error: action.error
58
});
59
60
const reducer = createReducer(INITIAL_STATE, {
61
[ActionTypes.LOGIN_SUCCESS]: loginSuccess,
62
[ActionTypes.LOGIN_FAILURE]: loginFailure
63
});
64
65
// Make reducer resettable
66
const resettableAuthReducer = resettableReducer('RESET_AUTH', reducer);
67
```
68
69
## Architecture
70
71
ReduxSauce is built around four key utilities that work together:
72
73
- **createTypes**: Generates action type constants from strings, converting to SCREAMING_SNAKE_CASE
74
- **createActions**: Simultaneously creates action types and action creators with automatic camelCase to SCREAMING_SNAKE_CASE conversion
75
- **createReducer**: Replaces switch statements with clean object maps for reducer logic
76
- **resettableReducer**: Higher-order reducer that wraps existing reducers with reset capability
77
78
## Capabilities
79
80
### Action Type Creation
81
82
Generate Redux action type constants from whitespace-separated strings with optional prefixing.
83
84
```javascript { .api }
85
/**
86
* Creates action type constants from a whitespace-separated string
87
* @param types - String containing whitespace-separated action names
88
* @param options - Optional configuration object
89
* @returns Object mapping type names to their string values
90
*/
91
function createTypes(types, options);
92
93
interface Options {
94
prefix?: string; // Prepends to all created types
95
}
96
```
97
98
**Usage Examples:**
99
100
```javascript
101
import { createTypes } from "reduxsauce";
102
103
// Basic usage
104
const Types = createTypes(`
105
LOGIN_REQUEST
106
LOGIN_SUCCESS
107
LOGIN_FAILURE
108
LOGOUT
109
`);
110
// Result: { LOGIN_REQUEST: 'LOGIN_REQUEST', LOGIN_SUCCESS: 'LOGIN_SUCCESS', ... }
111
112
// With prefix
113
const Types = createTypes('FETCH_USER UPDATE_USER', { prefix: 'AUTH_' });
114
// Result: { FETCH_USER: 'AUTH_FETCH_USER', UPDATE_USER: 'AUTH_UPDATE_USER' }
115
```
116
117
### Action Creator Generation
118
119
Create both action types and action creators simultaneously with automatic type conversion and flexible parameter handling.
120
121
```javascript { .api }
122
/**
123
* Creates both action types and action creators simultaneously
124
* @param config - Configuration object defining actions
125
* @param options - Optional configuration object
126
* @returns Object with Types and Creators properties
127
*/
128
function createActions(config, options);
129
130
interface CreatedActions {
131
Types: ActionTypes;
132
Creators: ActionCreators;
133
}
134
135
interface Options {
136
prefix?: string; // Prepends to all created types
137
}
138
```
139
140
**Config Value Types:**
141
142
- `null`: Creates type-only action creator
143
- `Array`: Creates action creator with named parameters
144
- `Object`: Creates action creator with default values
145
- `Function`: Uses custom action creator function
146
147
**Usage Examples:**
148
149
```javascript
150
import { createActions } from "reduxsauce";
151
152
const { Types, Creators } = createActions({
153
// Type-only action
154
logout: null,
155
156
// Action with parameters
157
loginRequest: ['username', 'password'],
158
159
// Action with default values
160
updateSettings: { theme: 'light', notifications: true },
161
162
// Custom action creator
163
complexAction: (data, meta) => ({
164
type: 'COMPLEX_ACTION',
165
payload: data,
166
meta
167
})
168
});
169
170
// Usage
171
Creators.logout(); // { type: 'LOGOUT' }
172
Creators.loginRequest('user', 'pass'); // { type: 'LOGIN_REQUEST', username: 'user', password: 'pass' }
173
Creators.updateSettings({ theme: 'dark' }); // { type: 'UPDATE_SETTINGS', theme: 'dark', notifications: true }
174
```
175
176
### Reducer Creation
177
178
Create clean Redux reducers using object maps instead of switch statements, with support for default handlers.
179
180
```javascript { .api }
181
/**
182
* Creates a Redux reducer from initial state and action handlers
183
* @param initialState - The initial state for this reducer
184
* @param handlers - Map of action types to handler functions
185
* @returns Redux reducer function
186
*/
187
function createReducer(initialState, handlers);
188
189
interface Handlers {
190
[actionType: string]: (state, action) => newState;
191
}
192
```
193
194
**Usage Examples:**
195
196
```javascript
197
import { createReducer, Types } from "reduxsauce";
198
199
const INITIAL_STATE = { count: 0, error: null };
200
201
// Handler functions
202
const increment = (state, action) => ({
203
...state,
204
count: state.count + (action.amount || 1)
205
});
206
207
const decrement = (state, action) => ({
208
...state,
209
count: state.count - (action.amount || 1)
210
});
211
212
const setError = (state, action) => ({
213
...state,
214
error: action.error
215
});
216
217
// Default handler for unmatched actions
218
const defaultHandler = (state, action) => {
219
console.log('Unhandled action:', action.type);
220
return state;
221
};
222
223
const reducer = createReducer(INITIAL_STATE, {
224
INCREMENT: increment,
225
DECREMENT: decrement,
226
SET_ERROR: setError,
227
[Types.DEFAULT]: defaultHandler // Special default handler
228
});
229
```
230
231
### Resettable Reducer
232
233
Higher-order reducer that wraps existing reducers with reset capability, supporting both curried and direct usage patterns.
234
235
```javascript { .api }
236
/**
237
* Creates a higher-order reducer that resets state on specific action
238
* @param typeToReset - Action type that triggers reset
239
* @param originalReducer - Optional original reducer to wrap (when not currying)
240
* @returns Enhanced reducer or curried function
241
*/
242
function resettableReducer(typeToReset, originalReducer);
243
```
244
245
**Usage Examples:**
246
247
```javascript
248
import { resettableReducer } from "reduxsauce";
249
250
// Curried usage - create resetter function first
251
const resetter = resettableReducer('RESET_AUTH');
252
const authReducer = (state = { user: null }, action) => {
253
// ... reducer logic
254
};
255
const resettableAuthReducer = resetter(authReducer);
256
257
// Direct usage - pass both parameters
258
const directResettableReducer = resettableReducer('RESET_STATE', myReducer);
259
260
// In combineReducers
261
import { combineReducers } from 'redux';
262
263
export default combineReducers({
264
auth: resettableReducer('RESET_AUTH')(authReducer),
265
profile: resettableReducer('RESET_PROFILE')(profileReducer),
266
settings: settingsReducer // not resettable
267
});
268
```
269
270
## Types and Constants
271
272
```javascript { .api }
273
// Pre-defined constants
274
const Types = {
275
DEFAULT: 'REDUXSAUCE.DEFAULT' // Used for default handlers in createReducer
276
};
277
278
// TypeScript interfaces (when using TypeScript)
279
interface Actions {
280
[action: string]: string[] | ActionTypes | ActionCreator | null;
281
}
282
283
interface ActionTypes {
284
[action: string]: string | number | DefaultActionTypes | null;
285
}
286
287
interface DefaultActionTypes {
288
[action: string]: string;
289
}
290
291
interface DefaultActionCreators {
292
[action: string]: (...args: any[]) => UnknownAction;
293
}
294
295
interface Handlers<S> {
296
[type: string]: (state: S, action: any) => S;
297
}
298
299
interface CreatedActions<T = DefaultActionTypes, C = DefaultActionCreators> {
300
Types: T;
301
Creators: C;
302
}
303
```
304
305
## Error Handling
306
307
ReduxSauce validates inputs and throws descriptive errors:
308
309
- **createTypes**: Throws if types string is null/empty
310
- **createActions**: Throws if config is null/empty or contains invalid action creator types
311
- **createReducer**: Throws if initial state is undefined or handlers is not an object
312
- **resettableReducer**: Throws if reset type is not a string or original reducer is not a function
313
314
Common error patterns:
315
316
```javascript
317
// These will throw errors
318
createTypes(''); // Error: valid types are required
319
createActions({}); // Error: empty objects are not supported
320
createReducer(undefined, {}); // Error: initial state is required
321
resettableReducer('', myReducer); // Error: A valid reset type is required
322
```