-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
94 lines (87 loc) · 2.77 KB
/
index.js
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
import { createModule } from 'saga-slice';
import { crudSaga } from './lib/sagas';
import { crudReducers, crudInitialState } from './lib/reducers';
import {
affirm,
isString,
isObject,
isFunction,
isNotEmpty,
isNotUndefined
} from './lib/helpers';
/**
* Creates a saga slice with opinionated CRUD functionality
* @function
* @arg {object} options Options to pass to saga helper
* @param {string} options.name Required. Slice name
* @param {string} options.singular Required. Singular resource name
* @param {string} options.plural Required. Plural resource name
* @param {object} options.sagaApi Required. Saga API instance
* @param {object} options.initialState Extra initial state values or overrides
* @param {object} options.reducers Extra reducers or overrides
* @param {function} options.sagas Extra sagas or overrides
*
* @return {SagaSlice} A saga slice module
*
* @example
*
* export default crudSlice({
* name: 'todos',
* singular: 'todo',
* plural: 'todos',
* sagaApi: createApis({ baseURL: '/api' }).sagaApi,
* initialState: { done: [], incomplete: [] },
* reducers: {
* setByStatus: (state, todos) => {
* state.done = todos.filter(t => t.status === 'done');
* state.incomplete = todos.filter(t => t.status === 'incomplete');
* }
* },
* sagas: (A) => {
* readAllDone: {
* saga* ({ payload: { data } }) {
* if (data) {
* yield put(A.setByStatus(Object.values(data)));
* }
* }
* }
* }
* })
*
*/
export const crudSlice = (opts) => {
const {
name,
initialState,
reducers,
sagas,
sagaApi,
takers
} = opts;
// Required
affirm(isNotEmpty(name) && isString(name), 'must provide a valid name');
affirm(isObject(sagaApi), 'must provide a valid sagaApi');
affirm(isFunction(sagaApi.get), 'must provide a valid sagaApi');
// Optional
[
[reducers, isObject(reducers), 'reducers must be an object'],
[initialState, isObject(initialState), 'initialState must be an object'],
[sagas, isFunction(sagas), 'sagas must be a function'],
[takers, isObject(takers) || isString(takers), 'takers must be an object or "takeEvery"'],
].forEach(([val, ...args]) => {
isNotUndefined(val) && affirm(...args);
})
return createModule({
name,
initialState: crudInitialState(initialState || {}),
reducers: crudReducers(reducers || {}),
sagas: crudSaga({
name,
sagaApi,
takers
}, sagas)
});
};
export * from './lib/api/index';
export * from './lib/reducers';
export * from './lib/sagas';