Skip to content

Commit 05d63ec

Browse files
authored
Merge pull request #5 from myheritage/change-library-name-and-support-object-placeholders
Update library API
2 parents 7dd38c7 + fd4c909 commit 05d63ec

File tree

8 files changed

+335
-125
lines changed

8 files changed

+335
-125
lines changed

.babelrc

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"presets": ["@babel/preset-env", {"exclude": ["@babel/plugin-transform-typeof-symbol", "transform-regenerator"]}],
2+
"presets": ["@babel/preset-env"],
33
"env": {
44
"commonjs": {
55
"plugins": [
@@ -10,7 +10,7 @@
1010
"plugins": [
1111
["babel-plugin-transform-es2015-modules-umd", { "loose": true }]
1212
],
13-
"moduleId": "ReduxActionSelector"
13+
"moduleId": "ReduxSelectorAction"
1414
},
1515
"test": {
1616
"plugins": [

.eslintrc

+4-4
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
4
102102
],
103103
"indent-legacy": "off",
104-
"init-declarations": "error",
104+
"init-declarations": "off",
105105
"jsx-quotes": "error",
106106
"key-spacing": "error",
107107
"keyword-spacing": [
@@ -168,7 +168,7 @@
168168
"no-lonely-if": "error",
169169
"no-loop-func": "error",
170170
"no-loss-of-precision": "error",
171-
"no-mixed-operators": "error",
171+
"no-mixed-operators": "off",
172172
"no-mixed-requires": "error",
173173
"no-multi-assign": "error",
174174
"no-multi-spaces": "error",
@@ -215,7 +215,7 @@
215215
"no-ternary": "off",
216216
"no-throw-literal": "error",
217217
"no-undef-init": "error",
218-
"no-undefined": "error",
218+
"no-undefined": "off",
219219
"no-underscore-dangle": "error",
220220
"no-unmodified-loop-condition": "error",
221221
"no-unneeded-ternary": "error",
@@ -239,7 +239,7 @@
239239
"error",
240240
"never"
241241
],
242-
"object-property-newline": "error",
242+
"object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }],
243243
"object-shorthand": "error",
244244
"one-var": "off",
245245
"one-var-declaration-per-line": "error",

README.md

+103-44
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
# Redux Action Selector
1+
# Redux Selector Action
22
[![npm package][npm-badge]][npm]
33

44
Same Redux "selectors" but for actions, inspired by [reselect](https://github.com/reduxjs/reselect).
55

6-
* Action selectors can be dispatched as any other Redux action.
7-
* Action selectors accept store selectors to eventually inject their output to the given action creator.
8-
* Action selectors reduce the data your "containers" (components connected to redux store) need to pass.
6+
* Selector Actions can be dispatched as any other Redux action.
7+
* Selector Actions accept store selectors to eventually inject their output to the given action creator.
8+
* Selector Actions reduce the data your "containers" (components connected to redux store) need to pass.
99

10-
An action selector accepts a list of selectors and a regular action creator
10+
A selector-action creator accepts a list of selectors and a regular action creator
1111

1212
**container/actions.js**
1313

1414
```js
15-
import { createActionSelector, getPlaceholder } from 'redux-action-selector';
15+
import { createSelectorAction, getPlaceholder } from 'redux-selector-action';
1616

1717
const getCsrfToken = state => state.csrfToken;
1818
const getCurrency = state => state.currency;
1919
const getLang = state => state.lang;
2020

2121

22-
export const fetchOrder = createActionSelector(
22+
export const fetchOrder = createSelectorAction(
2323
getCsrfToken,
2424
getPlaceholder, // placeholder for order id
2525
getCurrency,
@@ -49,26 +49,44 @@ const mapDispatchToProps = dispatch => {
4949
}
5050
```
5151

52+
**index.js**
53+
54+
```js
55+
import { applyMiddleware, createStore, compose } from 'redux';
56+
import { reduxSelectorActionMiddleware } from 'redux-selector-action';
57+
import rootReducer from './reducers';
58+
import {fetchOrder} from './container/actions';
59+
60+
const middlewareEnhancer = applyMiddleware(reduxSelectorActionMiddleware);
61+
const composedEnhancers = compose(middlewareEnhancer);
62+
const initialState = undefined;
63+
64+
const store = createStore(rootReducer, initialState, composedEnhancers);
65+
66+
store.dispatch(fetchOrder(123));
67+
```
68+
5269
## Table of Contents
5370

5471
- [Installation](#installation)
55-
- [Motivation for Action Selectors](#motivation-for-action-selectors)
72+
- [Motivation for Selector Actions](#motivation-for-selector-actions)
5673
- [API](#api)
5774
- [`getPlaceholder`](#getplaceholder)
58-
- [`createActionSelector`](#createactionselectorselectors--selectors-resultfunc)
75+
- [`createSelectorAction`](#createactionselectorselectors--selectors-resultfunc)
76+
- [`reduxSelectorActionMiddleware`](#reduxselectoractionmiddleware)
5977
- [FAQ](#faq)
60-
- [Can I use this package without Reselect and Redux?](#q-can-i-use-this-package-without-reselect-and-redux)
78+
- [Can I use this package without Redux?](#q-can-i-use-this-package-without-redux)
79+
- [Can I use this package without Reselect?](#q-can-i-use-this-package-without-reselect)
6180
- [My action accepts many args that can't be injected, should I pass many getPlaceholders?](#q-my-action-accepts-many-args-that-cant-be-injected-should-i-pass-many-getplaceholders)
62-
- [My action accepts an options object which its props can be injected, how can I inject them?](#q-my-action-accepts-an-options-object-which-its-props-can-be-injected-how-can-i-inject-them)
63-
- [How can I test an action selector?](#q-how-can-i-test-an-action-selector)
81+
- [How can I test a selector action?](#q-how-can-i-test-a-selector-action)
6482
- [License](#license)
6583

6684

6785
## Installation
68-
npm install redux-action-selector
86+
npm install redux-selector-action
6987

7088

71-
## Motivation for Action Selectors
89+
## Motivation for Selector Actions
7290
Containers include in most cases some props, which they get just to pass to actions creators.
7391
In order to avoid redundant data (props) passed to those containers, there should be a way for actions to get their data from store.
7492
This way would let us create actions which accept only the data the container holds.
@@ -91,27 +109,21 @@ Let's fix this.
91109

92110
## API
93111

94-
### getPlaceholder()
95-
This is a built-in selector, which you can use as part of your action creator's selectors.
96-
Once you pass it as a dependency, instead of injecting the output of this selector,
97-
we save its position in the dependency list (selectors) for an arg, which will be sent once you call the action selector.
98-
99-
100-
### createActionSelector(...selectors | [...selectors], resultFunc)
112+
### createSelectorAction(...selectors | [...selectors], resultFunc)
101113

102114
This function accept a list of selectors, or an array of selectors, computes their output against the store's state, and inject them as arguments to the given `resultFunc`.
103115

104116
[`getPlaceholder`](#getplaceholder) selector will be handled separately.
105117

106118
```js
107-
import { createActionSelector, getPlaceholder } from 'redux-action-selector';
119+
import { createSelectorAction, getPlaceholder } from 'redux-selector-action';
108120
import {updateOrderCurrencyAction} from './actions';
109121

110122
const getCsrfToken = state => state.csrfToken;
111123
const getOrderId = state => state.orderId;
112124

113125
// We accept array of selectors too! choose your preferred way.
114-
export const updateOrderCurrency = createActionSelector(
126+
export const updateOrderCurrency = createSelectorAction(
115127
[getCsrfToken, getOrderId, getPlaceholder /* currency */],
116128
updateOrderCurrencyAction,
117129
);
@@ -120,37 +132,83 @@ export const updateOrderCurrency = createActionSelector(
120132
updateOrderCurrency('USD');
121133
```
122134

135+
### getPlaceholder()
136+
This is a built-in selector, which you can use as part of your action creator's selectors.
137+
Once you pass it as a dependency, instead of injecting the output of this selector,
138+
we save its position in the dependency list (selectors) for an arg, which will be sent once you call the selector action.
139+
140+
In case you have an action creator with an "options" argument (meaning an object which maps arg names to their values),
141+
you can use the following syntax:
142+
143+
```js
144+
import { createSelectorAction, getPlaceholder } from 'redux-selector-action';
145+
import { getCsrfToken, getCurrency, getLang } from './selectors';
146+
147+
export const fetchOrder = createSelectorAction(
148+
// Map the arg names to selectors, then your action creator will get their values:
149+
getPlaceholder({
150+
token: getCsrfToken,
151+
currency: getCurrency,
152+
lang: getLang,
153+
}),
154+
({token, orderId, currency, lang}) => ({
155+
type: 'fetch_order_request',
156+
payload: {
157+
// ...
158+
}
159+
})
160+
);
161+
162+
// fetchOrder({orderId: 123});
163+
```
164+
165+
### reduxSelectorActionMiddleware()
166+
This is a redux middleware which handles our build-in selector actions.
167+
In order to make everything work, you should add it to your store enhancers, the position does not matter.
168+
169+
```js
170+
import { applyMiddleware, createStore, compose } from 'redux';
171+
import { reduxSelectorActionMiddleware } from 'redux-selector-action';
172+
import rootReducer from './reducers';
173+
174+
const middlewareEnhancer = applyMiddleware(reduxSelectorActionMiddleware);
175+
const composedEnhancers = compose(middlewareEnhancer);
176+
const initialState = undefined;
177+
178+
const store = createStore(rootReducer, initialState, composedEnhancers);
179+
```
180+
123181
## FAQ
124182

125-
### Q: Can I use this package without Reselect and Redux?
183+
### Q: Can I use this package without Redux?
126184

127-
A: Yes. This package has no dependencies on any other package, even though it was designed to be used with Reselect and Redux.
185+
A: No. Even though this package has no dependency on Redux, it was designed to be used with Redux.
186+
It means we expect for example that our middleware will be called with Redux store api (store.getState(), store.dispatch()).
128187

129188

130-
### Q: My action accepts many args that can't be injected, should I pass many getPlaceholders?
189+
### Q: Can I use this package without Reselect?
131190

132-
A: Not necessarily. All args you pass to the created action selector will be injected to the placeholders.
133-
But if you pass more args than placeholders, then they will be appended too.
191+
A: Yes. This package has no dependency on Reselect, you can work with any selectors you want, eventually they are just functions that accept state.
134192

135193

136-
### Q: My action accepts an options object which its props can be injected, how can I inject them?
194+
### Q: My action accepts many args that can't be injected, should I pass many getPlaceholders?
137195

138-
A: We are working to support also objects (options argument), it will be available soon.
139-
At the meantime, you can extract them to be regular args if you wish to.
196+
A: Not necessarily. All args you pass to the created selector action will be injected to the placeholders.
197+
But if you pass more args than placeholders, then they will be appended too.
140198

141199

142-
### Q: How can I test an action selector?
200+
### Q: How can I test a selector action?
143201

144-
Every action selector keeps a reference to the given selectors and the action creator, as `.dependencies` and `.resultFunc` respectively.
202+
Every selector action keeps a reference to the given selectors and the action creator, as `.dependencies` and `.resultFunc` respectively.
145203

146-
For example if you have the following action selector:
204+
For example if you have the following selector action:
147205

148-
**src/actionSelectors.js**
206+
**src/selectorActions.js**
149207
```js
150208
export const getFirst = state => 1;
151209
export const getSecond = state => 2;
152210

153-
export const myActionSelector = createActionSelector(
211+
export const mySelectorAction = createSelectorAction(
154212
getFirst,
155213
getSecond,
156214
getPlaceholder,
@@ -160,19 +218,20 @@ export const myActionSelector = createActionSelector(
160218

161219
You can test it this way:
162220

163-
**test/actionSelectors.js**
221+
**test/selectorActions.js**
164222

165223
```js
224+
import { mySelectorAction } from '../src/selectorActions';
225+
166226
// test the selectors themselves...
167227
test("getFirst", () => { /* ... */ });
168228
test("getSecond", () => { /* ... */ });
169229

170-
test("myActionSelector", () => {
230+
test("mySelectorAction", () => {
171231
// check the dependencies are as expected
172-
assert(myActionSelector.dependencies).toEqual([getFirst, getSecond, getPlaceholder]);
173-
// check the the resultFunc output as expected
174-
assert(myActionSelector.resultFunc(1, 2, 3)).toMatchSnapshot();
175-
232+
assert(mySelectorAction.dependencies).toEqual([getFirst, getSecond, getPlaceholder]);
233+
// check the resultFunc output is as expected
234+
assert(mySelectorAction.resultFunc(1, 2, 3)).toMatchSnapshot();
176235
})
177236
```
178237

@@ -181,7 +240,7 @@ test("myActionSelector", () => {
181240

182241
[MIT](./LICENSE)
183242

184-
[npm-badge]: https://img.shields.io/npm/v/redux-action-selector.svg?style=flat-square
185-
[npm]: https://www.npmjs.org/package/redux-action-selector
243+
[npm-badge]: https://img.shields.io/npm/v/redux-selector-action.svg?style=flat-square
244+
[npm]: https://www.npmjs.org/package/redux-selector-action
186245

187246

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "redux-action-selector",
2+
"name": "redux-selector-action",
33
"version": "1.0.0",
4-
"description": "Action selectors for Redux.",
4+
"description": "Selector Actions for Redux.",
55
"main": "lib/index.js",
66
"jsnext:main": "es/index.js",
77
"module": "es/index.js",
@@ -10,7 +10,7 @@
1010
"compile:cjs": "better-npm-run compile:cjs",
1111
"compile:es": "babel -d es/ src/",
1212
"compile:umd": "better-npm-run compile:umd",
13-
"compile:umdmin": "uglifyjs dist/redux-action-selector.js -m -o dist/redux-action-selector.min.js",
13+
"compile:umdmin": "uglifyjs dist/redux-selector-action.js -m -o dist/redux-selector-action.min.js",
1414
"lint": "eslint src/ test/",
1515
"lint:fix": "eslint src/ test/ --fix",
1616
"prepublish": "npm run compile",
@@ -25,7 +25,7 @@
2525
}
2626
},
2727
"compile:umd": {
28-
"command": "mkdirp dist/ && babel -o dist/redux-action-selector.js src/",
28+
"command": "mkdirp dist/ && babel -o dist/redux-selector-action.js src/",
2929
"env": {
3030
"NODE_ENV": "umd"
3131
}
@@ -45,7 +45,7 @@
4545
},
4646
"repository": {
4747
"type": "git",
48-
"url": "git+https://github.com/myheritage/redux-action-selector.git"
48+
"url": "git+https://github.com/myheritage/redux-selector-action.git"
4949
},
5050
"keywords": [
5151
"react",
@@ -63,9 +63,9 @@
6363
],
6464
"license": "MIT",
6565
"bugs": {
66-
"url": "https://github.com/myheritage/redux-action-selector/issues"
66+
"url": "https://github.com/myheritage/redux-selector-action/issues"
6767
},
68-
"homepage": "https://github.com/myheritage/redux-action-selector#readme",
68+
"homepage": "https://github.com/myheritage/redux-selector-action#readme",
6969
"devDependencies": {
7070
"@babel/cli": "^7.10.5",
7171
"@babel/plugin-transform-modules-commonjs": "^7.10.4",

0 commit comments

Comments
 (0)